--- /dev/null
+inherit autotools
+
+do_stage () {
+ autotools_stage_all
+}
+
elf = True
if "GNU_HASH" in line:
sane = True
+ if "[mips32]" in line or "[mips64]" in line:
+ sane = True
if elf and not sane:
error_msg = "No GNU_HASH in the elf binary: '%s'" % path
missing = missing.rstrip(',')
messages = messages + "Please install following missing utilities: %s\n" % missing
+ if os.path.basename(os.readlink('/bin/sh')) == 'dash':
+ messages = messages + "Using dash as /bin/sh causes various subtle build problems, please use bash instead.\n"
+
omask = os.umask(022)
if omask & 0755:
messages = messages + "Please use a umask which allows a+rx and u+rwx\n"
md5=8bd2a92fb94faa1b4fc43865d40bd988
sha256=a317cd11719659892bdae6ec54ee2e37549d0df7d5bdce02036963acc2ad1486
+[http://divmod.org/trac/attachment/wiki/SoftwareReleases/Axiom-0.5.30.tar.gz?format=raw]
+md5=8f0b3a27770e487ad08f4fafdccc4495
+sha256=4a4217e70e01e11d357c2c2c23bc72d244a78fa40a401cca48cd5f0a619c7060
+
[http://search.cpan.org/CPAN/authors/id/D/DC/DCLINTON/Cache-Cache-1.05.tar.gz]
md5=09e4d37979c8f8ce2518e1d1ccd10d99
sha256=10106d94e0897c18cd5eb0b782c3212371c9785eba78a15f4623335e01dda23c
md5=caea8bcfc9c1d391e56d85e437005a5d
sha256=0875e553a17fe65e920ad810a67aa6faca582c53476d8dc75880a6b3da625d0b
+[http://directfb.org/downloads/Core/DirectFB-1.2.7.tar.gz]
+md5=59ca16f600e96c8c104a485ff7c322c6
+sha256=80ab8e34246a280bc380020cf331bcc0014cf816380cee3935ad455c108e661e
+
[http://www.directfb.org/downloads/Extras/DirectFB-examples-0.9.25.tar.gz]
md5=835e850fddba8d8214d39ddd0646c3e8
sha256=f83af60d53ab4319e5d71a4459cc10464ffd683efabacd6bd773bb807f8771fa
md5=0cdfb4dd248eada3dc35db4f8cf75f8d
sha256=c54e779a720841126e23d692de85243e23b0d94fb7792a958b96b5bd097a8b85
+[http://www.directfb.org/downloads/Extras/DirectFB-examples-1.2.0.tar.gz]
+md5=ce018f681b469a1d72ffc32650304b98
+sha256=830a1bd6775d8680523596a88a72fd8e4c6a74bf886d3e169b06d234a5cf7e3e
+
[http://media.djangoproject.com/releases/1.0/Django-1.0.tar.gz]
md5=84d0490e4126f31d1c23f640e1e86f2f
sha256=4c780b9e2906944ce02a9325b15f480d2bd4c0b12137f752aa4800c0f8563acf
md5=3bf4d8d285591a5b7f31170f9b87aba0
sha256=c196988f55fc6633d9f9f6d9ddc2ae9b4dfa1f300edf4cbbad865c06a8656df7
+[http://divmod.org/trac/attachment/wiki/SoftwareReleases/Epsilon-0.5.11.tar.gz?format=raw]
+md5=39710dfdeb42e51c953b17b6cded163e
+sha256=a5907a3b7584d63be30b3f79b0422b2b0778e73c053be9ac5a11004f1c9097dc
+
[http://search.cpan.org/CPAN/authors/id/P/PE/PEVANS/Error-0.17004.tar.gz]
md5=4dfca8732331a4f79c6803c3bc6b722f
sha256=f464f0068772c276b81a7345f6788bdc3a243c13de24563346043d049a5497ba
md5=7030996497f3cf012bc9e99b4ca3e920
sha256=be21e3d5fa2edd1f5ff5952f67e6574dae15a027b26415910dfe813902fd5985
+[http://downloads.sourceforge.net/freeimage/FreeImage3110.zip]
+md5=ad1db36414391417654ba7bf1c0277d3
+sha256=84021b8c0b86e5801479474ad9a99c18d121508ee16d363e02ddcbf24195340c
+
[http://www.urban.ne.jp/home/kanemori/zaurus/FreeNote_1.12.0.tar.gz]
md5=06b5aeb6cc97107090438a364f0ce89b
sha256=e6a0a5b674c4803bfd1ffda9660c29f4399294623ed095b0d1c554367c7db73c
md5=64f780e7f95c252eaaed0201c3d9a4ca
sha256=281234116b99b4c4b45fde038a435a0d26b7ee55beac0c351186b3f12c301659
+[http://divmod.org/trac/attachment/wiki/SoftwareReleases/Nevow-0.9.32.tar.gz?format=raw]
+md5=75828090af2b26f69fe4a7f148a400f6
+sha256=bc35ce187481db91f047055b3edbce49c14d291b1a2eb3e915e9c1c511620f9a
+
[http://downloads.sourceforge.net/numpy/Numeric-23.7.tar.gz]
md5=8054781c58ae9cf6fe498316860b5ea8
sha256=33225097777e84dfed251aee1265a9c0dd0976854e83f60e778a670027b12e7c
md5=56df2ae66db57932515a491c03bf514f
sha256=f3b2df3f4483752a42f1a775a1163da1f9e91bf5f19d302abc93544aca20d2cd
+[http://tmrc.mit.edu/mirror/twisted/Twisted/8.2/Twisted-8.2.0.tar.bz2]
+md5=c85f151999df3ecf04c49a781b4438d2
+sha256=e0602bb05e31f6100b6f9ab35cfa93ab9f7a1c50a351a0ddfcd236a923bddfb0
+
[http://search.cpan.org/CPAN/authors/id/G/GA/GAAS/URI-1.35.tar.gz]
md5=1a933b1114c41a25587ee59ba8376f7c
sha256=1684cb64a6bd24e019532ae2e5d4a962d43d9215623e9d4dc77536f118fbf31b
md5=e77887dbafc515c63feac84686bcb3bc
sha256=384437f3c4eb7d53ad27fdadce6cbc295ef16653b7f7739a480d91c784082ec9
+[http://www.apache.org/dist/apr/apr-1.3.2.tar.bz2]
+md5=a0631c63640176371dd4a5bf13beeee8
+sha256=bb0c58efdd252fcaf6f0ff06681d0ebecbecbaa3864047f32dec7f82d1c4994c
+
[http://www.apache.org/dist/apr/apr-1.3.3.tar.bz2]
md5=2090c21dee4f0eb1512604127dcd158f
sha256=d95f3b78366c86317043304864bb08cb836312c87ea7d142a4c02154e7e0dd37
md5=c3702668a640be1695956115857ec22e
sha256=8cd84eb2031a91572e1be2975f4171730a9be72c4cd88718c4c40ac7dc4fd7d3
+[http://www.apache.org/dist/apr/apr-util-1.3.4.tar.gz]
+md5=a10e2ca150ff07f484c724c36142211f
+sha256=3f07ffdb18fb853290c9b83e82cd5cae66b8fbc357bd391e846c0afdd24fed7e
+
[ftp://ftp.debian.org/debian/pool/main/a/apt/apt_0.5.28.6.tar.gz]
md5=26b37525371cdaaec552237e0667305d
sha256=57de084860870cccf510de62eb8ded252f5951a6e59e34a963d61d69de3aff10
md5=b12426fd72bedf00c389a7fb458275a8
sha256=5a4a5b82dd8f485b4fef941cc216eb052184cf138f72b512eb62d836b460acdb
+[http://downloads.sourceforge.net/bftpd/bftpd-2.3.tar.gz]
+md5=4ab1eb33135fa5eaaf050e6d3dd0b319
+sha256=0af27ca6c49f696c64bcfb3e50452cad240997993e0b7afb65624898d3d95ff2
+
[http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_480p_surround-fix.avi]
md5=ed7ed01e9aefba8ddd77c13332cec120
sha256=40d1cf5bc8e1b0e55dac7bb2e3fbc2aea05b6679444864781299b24db044634f
md5=9d22ee4dafa3a194457caf4706f9cf01
sha256=487a33a452f0edcf1f8bb8fc23dff5c7a82edec3f3f8b65632b6c945e961ee9b
+[ftp://ftp.gnu.org/gnu/binutils/binutils-2.19.1.tar.bz2]
+md5=09a8c5821a2dfdbb20665bc0bd680791
+sha256=3e8225b4d7ace0a2039de752e11fd6922d3b89a7259a292c347391c4788739f6
+
[ftp://ftp.gnu.org/gnu/binutils/binutils-2.19.tar.bz2]
md5=17a52219dee5a76c1a9d9b0bfd337d66
sha256=bd2ea10ffc2bf62a917b05f4fbe3d02212589c2bc177fa0c51a9c874d3da528a
md5=4f0bd19dd04a32eba6149b82b26c3f30
sha256=9e042fcf2d29a58bd60fe3743130095992c62da4c865d01e6fea2d8d6d20583a
+[http://www.kernel.org/pub/linux/bluetooth/bluez-4.29.tar.gz]
+md5=9198f428277693c16c212910996075b4
+sha256=4fe29e8b7c28e6802853867531307704a78f69f37a09d7565268141a2a462644
+
[http://www.kernel.org/pub/linux/bluetooth/bluez-4.7.tar.gz]
md5=2aa806940d2c841e57a9b2ab7302b750
sha256=ed384dea4f5f21157758fcd7db64db19ce0b410509c26630706e4a3c779287a0
md5=d113f2777e4f508faa8b674ece87a37b
sha256=f2b433270f22aad86f61cef61d95338aaa63dbe2f9468b9ed5defd1c01c9645f
+[http://busybox.net/downloads/fixes-1.13.2/busybox-1.13.2-depmod.patch]
+md5=7c9dfb5dcd66a1d6e837e72ad0cb05d4
+sha256=35e3854599a074ce1b47872ab1b97a625ed7d1ab3345b918f7f60524f5e390c5
+
+[http://busybox.net/downloads/fixes-1.13.2/busybox-1.13.2-init.patch]
+md5=7afb3a1b474742bc198b3c8450ab9a7e
+sha256=39a8efb5a50c56feb733e519365b4e188c25c0e925a1a63cc1ace9735a80100f
+
+[http://busybox.net/downloads/fixes-1.13.2/busybox-1.13.2-mdev.patch]
+md5=a72d169e9545e26257032e0e367feb95
+sha256=fd4a64c6a83e07586de0360258162c5bf431f164b3980301185743e4029940df
+
+[http://busybox.net/downloads/fixes-1.13.2/busybox-1.13.2-modprobe.patch]
+md5=6eeb6efcd71e57082d6654a9a6a368eb
+sha256=a02007661cf2f318a66468456f8fc8ae1177e12c3c66c59ff2de4d98863a388e
+
+[http://busybox.net/downloads/fixes-1.13.2/busybox-1.13.2-tar.patch]
+md5=90d093817855bc63ad16fbb8524f80df
+sha256=9427fa9b45f3c322bf4fe2463c99c972e6ae03df630899b38be4f29133708a0e
+
[http://www.busybox.net/downloads/busybox-1.13.2.tar.gz]
md5=aeb526108f13b91c02b115c8d86f9659
sha256=03fc9dbdc6f44afd2da55c0ab36646d2d063708cc35f3f4569b913b064f11d83
md5=53c44b73aa67d5e0282adfe928f3ba44
sha256=624381208d0faae6c123bc6198a59d6c4316cd4fffb1ba5aca206374f5a42df6
+[ftp://invisible-island.net/byacc/byacc-20081225.tgz]
+md5=b9715b9a2867c221176b597e8f73cbc9
+sha256=1364c7fe382de659e8b9841a1736b645345a460d2f4302303e80c02235a2a575
+
[http://downloads.sourceforge.net/bzflag/bzflag-1.10.6.20040515.tar.bz2]
md5=8e3e5fbef3cfa21079eb06269e6b3d8b
sha256=0329e3d0a59e9cc167733ed2b89a0dc2249725642a065cfd385bf1206fe30b19
md5=c8be31ffebdae0e007ea587a11994e75
sha256=64dfe89e56167bde80c6a18831b5a4259215c78c34ca16f4cb9fde10ffe54437
+[http://pypi.python.org/packages/source/C/ConfigObj/configobj-4.5.3.tar.gz]
+md5=6e2b37301439705831bd510d2a198431
+sha256=4276fcc96d81f0ba923f3a8c44c3cb55ac72c00fa79d35f1e3ccb4d410b3d7c5
+
[http://download.savannah.gnu.org/releases/confuse/confuse-2.5.tar.gz]
md5=4bc9b73d77ebd571ac834619ce0b3582
sha256=65451d8d6f5d4ca1dbd0700f3ef2ef257b52b542b3bab4bbeddd539f1c23f859
md5=094743343e062ea370fcd461aa48a7fe
sha256=bba3adf21a59f5836b1ba2615894e891627d9bcc863525f1892bc36e4e76124e
+[http://repo.moblin.org/connman/releases/connman-0.10.tar.gz]
+md5=094743343e062ea370fcd461aa48a7fe
+sha256=bba3adf21a59f5836b1ba2615894e891627d9bcc863525f1892bc36e4e76124e
+
[ftp://ftp.moblin.org/connman/releases/connman-0.2.tar.gz]
md5=bf48aa07d3c1e5fe272c7f139bc01fc9
sha256=eacc3c57cffb411b09d834d2225323cde5676165b5d2fc2a27b16cde98e3ba97
md5=c9a3b384f080ed4cdf139ce9377ef2c8
sha256=d7acac8bc0a38dfcab098137a76f5e9f4ce30ca86e82b26540502658e6b4e4a7
+[http://repo.moblin.org/connman/releases/connman-gnome-0.4.tar.gz]
+md5=c9a3b384f080ed4cdf139ce9377ef2c8
+sha256=d7acac8bc0a38dfcab098137a76f5e9f4ce30ca86e82b26540502658e6b4e4a7
+
[http://www.conserver.com/conserver-8.1.14.tar.gz]
md5=f7825728e5af8992ed4a99fb560a3df8
sha256=48a9e2f8a02054bc6740ae354433bfa1636a6e726f2d62af22752d7a6103410b
md5=537cda2dff7dfaf87660fee91b2cf78f
sha256=bd7ce3b854678209e8624698a4000d3e5337339c3825c58a4b3a0a2fbf1a7819
+[http://downloads.sourceforge.net/ddccontrol/ddccontrol-0.4.2.tar.bz2]
+md5=b0eb367f3bc0564bd577e38d0b4107fc
+sha256=986f3b4b27ec04e1da493de3aaab01cd5ea9566d7572c1a40b8d43cd7a491e84
+
+[http://downloads.sourceforge.net/ddccontrol/ddccontrol-db-20061014.tar.bz2]
+md5=91951918e5bc553c251776cdff8cea9c
+sha256=ff88f8e5122a2ab7b69a961f267f74d09ec7c54e90453ee80930edf66955c7b8
+
[http://downloads.sourceforge.net/ddclient/ddclient-3.6.3.tar.bz2]
md5=42a3a420e492c0111adc58ac08ff6d04
sha256=28be7102bde3bc9b39be2732b89da9fbab79b7ac3898075ed414a45258bb3026
md5=ec8690ff84b364d2df5b2443a01ba529
sha256=e0360be0eecee68649246c022825dd5422f895958ffa736886dd2a0b9ec7ebda
+[http://effbot.org/media/downloads/elementtree-1.2.7-20070827-preview.zip]
+md5=30e2fe5edd143f347e03a8baf5d60f8a
+sha256=5071431068c58c1f56dcc8fff37f8a213351f3b45c012d3adb640ec9418053ad
+
[http://distro.ibiblio.org/pub/linux/distributions/gentoo/distfiles/elfutils-0.108.tar.gz]
md5=fd318a634c8f67c7ac8a975f16965cc3
sha256=794070c8108a2d8b7c6890ba42edb37510cc845bf601517cf4a0ea5443dfde29
md5=1939de5fe43d12884d85fa5d7797e3c2
sha256=243dabf3c45530cac8be092f9a1d838a46b46a92d4138870423006ffd6ae4001
+[http://gdata-python-client.googlecode.com/files/gdata.py-1.2.4.tar.gz]
+md5=521f33a377d64f8a6505ba119415b787
+sha256=fc5ddb8f76b17abd728721a0e0177ea35f55a70106f44dc9010b22eceb06abde
+
[ftp://ftp.gnu.org/gnu/gdb/gdb-6.3.tar.gz]
md5=812de9e756d53c749ea5516d9ffa5905
sha256=c06bf9715436b3a28c189163aa5ca42b46af8286659827f033eaaf7d8b1fc342
md5=03a0f63b997ce7b83a1eeaa6b80f4388
sha256=a5d9fd696d7ee4a1c7679b5a688155bc1e0abbdf5f144d6762dbbee874df235f
+[http://jackaudio.org/downloads/jack-audio-connection-kit-0.116.2.tar.gz]
+md5=9c0ae9880e9b6e081f1a238fe6a28bd5
+sha256=ce6e1f61a3b003137af56b749e5ed4274584167c0877ea9ef2d83f47b11c8d3d
+
[http://downloads.sourceforge.net/jackit/jack-audio-connection-kit-0.99.0.tar.gz]
md5=a891a699010452258d77e59842ebe4a0
sha256=2096acc56c314e689faad0036bbc1d86dea1b9d9620f711d471de76b1dd6859e
md5=b4a4509ca3f546cfedd23aa6f99ab81d
sha256=b8c9d3a51f04bdecabbb4135079d408e02c98cdf3156bab8418a6830cb64b890
+[http://projects.linuxtogo.org/frs/download.php/226/kexecboot-0.5.tar.gz]
+md5=a937303d7ef3fc645f9dccf89e1494e2
+sha256=49c95d62e32b66c9f97e791f667afa82f0714bc0a0e0ad48df010f4f36de42ab
+
[http://gpe.linuxtogo.org/download/source/keylaunch-2.0.10.tar.gz]
md5=2d81de20b26eac5ad44b759eb412e8eb
sha256=38715fcc508740deb3f169a01092f03ea4ce92c9ec3c2589a9510534aa52a540
md5=15de3830b751818a54a42899bd3ae72c
sha256=5fdaf9af5ac4f75c0215d000b82b128fd054a582f81cc4f039a1e7fe69335ebb
+[http://libchamplain.pierlux.com/release/0.2.8/libchamplain-0.2.8.tar.gz]
+md5=fa4a620efa1a1c1036b6701b7d4dafe1
+sha256=01e17811a85e93e5158f5d721b9b1b249db44683735a172fa0debd9759d3175c
+
+[http://libchamplain.pierlux.com/release/0.2.8/libchamplain-gtk-0.2.8.tar.gz]
+md5=c3e62c1912c0dba013c8f3df28fc809d
+sha256=03d751bd836174e2d6766d8036fc72e130dd090b13256d40a58ba6ab659475ef
+
[http://gpephone.linuxtogo.org/download/gpephone/libchenabler-0.1/libchenabler-0.1.tar.gz]
md5=866fd13611a8de946428db1df9be8468
sha256=74def55ba6a61e966e0873a4081fd3dd65089b94b837810d3bc056221d7e41c7
md5=115dc5380ffdb03ec2e71ff9d6d97e72
sha256=50bfab6d4b1b9af37ca6832b979f5c891f2dd9259a68700b37214d7897927c17
+[http://www.mumpot.org/download/mumpot-0.4.tar.gz]
+md5=52d1e64c63d70604f13985f1f326a802
+sha256=302bea9f0903fecf13ee0e9c24ed090203f2c77f7164a2a0f68c35fc8e1b9f10
+
[http://www.dotaster.com/~shuu/linux/murasaki/0.8/8/murasaki-0.8.8.tar.gz]
md5=ea7afa7e0bd9cfa0df7c04a9b270df88
sha256=2033168723ffd612336acb8a64b33fcd91f7dedeaf78949d3dfce231cb962ce9
md5=139a1ed50a1a12e47b1f7deedf4f40c3
sha256=4310a3a526ae5461e17f57353fc29f71d13820a215eaa62c629190cc2a026173
+[http://downloads.pf.itd.nrl.navy.mil/olsr/nrlolsrdv7.8.1.tgz]
+md5=46291de38362acdcd335bcf259055046
+sha256=0e6b18e3bf77dd20395881535e3e7043bcd5171c220728310215d708f44f3b1c
+
[http://www.nlnetlabs.nl/downloads/nsd/nsd-2.0.0.tar.gz]
md5=a09542645b91ff60564b0f4db436af01
sha256=8f486c4ef4d3f60fba4e0f855399184ca557f03a747cae6adde4cc2dffc53ff2
md5=b374415d7f5d485993fa697ab9a678b4
sha256=3b46936339fe5c2dcb8fb2f9213fa36dcddefaa1e00d1d93b5640d8cc9898ca1
+[http://downloads.sourceforge.net/ogre/ogre-v1-6-1.tar.bz2]
+md5=6fbd72e81dd4c135a2cc4f78d596aeb4
+sha256=68b8978071f31615ad89119583e629ca7c3069ae0c2fb8f7c390c19807cce0bb
+
[http://www.olsr.org/releases/0.4/olsrd-0.4.10.tar.bz2]
md5=9807d4451e65cb4ec385155eef7bf3cf
sha256=af04bdd8abd85bb4715fd6011566054847c75fcbac5e5e9cdee80858ac2957d3
md5=10bab01d3c8856426cdf79f124fd4173
sha256=61fd2a9225aad67d4e21727a297e571ddd6a973b845646cf10b24a92b88467bc
+[ftp://ftp.kernel.org/pub/software/utils/pciutils/pciutils-3.1.2.tar.bz2]
+md5=46387fd7a18c33fbb5311fdb3ab9ea12
+sha256=f66e40b8df5a7b6a93c463b0fb734ea6451c5f0c2cc772f58640b6c7f0d69397
+
[http://downloads.sourceforge.net/pcmanfm/pcmanfm-0.3.0.1.tar.gz]
md5=ac676498175495a37bef0b41bca9ace9
sha256=1f7dec1a275774cb6eff9a491b74bbea7a2276140d640c15ed260c798c8334ed
md5=c252e5286b142afa54ca49829c51a33f
sha256=ec3159feae5324e78f7fc09f8f534bd6a3e7ed735144ee8a8e9e7871e77115e0
+[http://downloads.sourceforge.net/squashfs/squashfs3.3.tgz]
+md5=95c40fca0d886893631b5de14a0af25b
+sha256=8423027a1e7dc238d27ec227f47ce22d1317b4c9a0a9ee49a38b6e6f8da8a5c8
+
[http://heanet.dl.sourceforge.net/squashfs/squashfs3.3.tgz]
md5=95c40fca0d886893631b5de14a0af25b
sha256=8423027a1e7dc238d27ec227f47ce22d1317b4c9a0a9ee49a38b6e6f8da8a5c8
md5=c990186db06cf188cb267d12bc21e2da
sha256=f91445e5e1a02ee16f0bc1eb31a1cdfa53c4bb1e1cb4f76fae33436d472e9345
+[http://downloads.sourceforge.net/witty/wt-2.2.3.tar.gz]
+md5=2f4c34f1e092451d3c4d2e7f8c250015
+sha256=c6f692956d93765f12402a0b22617566decc52a9bb1a707b4e8d12affd1528d3
+
[http://downloads.sourceforge.net/wvware/wv-1.2.0.tar.gz]
md5=b6319d5e75611fe2210453b5feb82c0c
sha256=a76f44468e78591e6d510d326702e7c3999d2b9dd3ab8ab8c1c9811fd5b111e4
md5=4943ab7aa141af2c339266cd66b05c74
sha256=5cc1a53bb909922596bdd0fa967b654fe1bfbe0dcf1d34608f0b7c90e0c27867
+[http://downloads.sourceforge.net/zziplib/zziplib-0.13.49.tar.bz2]
+md5=5f7b88ebb2bcd7e8044328482d079661
+sha256=f57c4e33eb2cdd87a6c2f01bfa4794340fbe61ea1a1cfc7dac3b6671e1dd22af
+
[http://heanet.dl.sourceforge.net/zziplib/zziplib-0.13.49.tar.bz2]
md5=5f7b88ebb2bcd7e8044328482d079661
sha256=f57c4e33eb2cdd87a6c2f01bfa4794340fbe61ea1a1cfc7dac3b6671e1dd22af
PREFERRED_VERSION_gpe-announce ?= "0.13"
PREFERRED_VERSION_gpe-timesheet ?= "0.32"
PREFERRED_VERSION_gpe-irc ?= "0.08"
-PREFERRED_VERSION_starling ?= "0.2"
+PREFERRED_VERSION_starling ?= "0.9"
PREFERRED_VERSION_gpe-keylock ?= "0.12"
PREFERRED_VERSION_gpe-ownerinfo ?= "0.28"
PREFERRED_VERSION_gpe-question ?= "0.04"
PREFERRED_VERSION_alsa-lib ?= "1.0.15"
PREFERRED_VERSION_alsa-oss ?= "1.0.15"
PREFERRED_VERSION_alsa-plugins ?= "1.0.14"
-PREFERRED_VERSION_alsa-state ?= "0.1.0"
+PREFERRED_VERSION_alsa-state ?= "0.2.0"
PREFERRED_VERSION_alsa-utils ?= "1.0.15"
PREFERRED_VERSION_anthy ?= "7811"
PREFERRED_VERSION_anthy-native ?= "7811"
PREFERRED_VERSION_confuse ?= "2.5"
PREFERRED_VERSION_confuse-native ?= "2.5"
PREFERRED_VERSION_connect ?= "0.1"
-PREFERRED_VERSION_connman ?= "0.8"
+PREFERRED_VERSION_connman ?= "0.10"
PREFERRED_VERSION_conserver ?= "8.1.14"
PREFERRED_VERSION_console-tools ?= "0.3.2"
PREFERRED_VERSION_contacts ?= "0.7"
PREFERRED_VERSION_dvbtraffic ?= "0.0cvs20060814"
PREFERRED_VERSION_dviviewer ?= "1.0.2"
PREFERRED_VERSION_e2fsprogs ?= "1.38"
-PREFERRED_VERSION_e2fsprogs-libs ?= "1.42.2"
+PREFERRED_VERSION_e2fsprogs-libs ?= "1.41.2"
PREFERRED_VERSION_e2fsprogs-libs-native ?= "1.35"
PREFERRED_VERSION_e2fsprogs-native ?= "1.38"
PREFERRED_VERSION_e2tools ?= "0.0.16"
PREFERRED_VERSION_gpm ?= "1.20.1"
PREFERRED_VERSION_gpp ?= "2.21"
PREFERRED_VERSION_gpsbabel ?= "1.3.3"
-PREFERRED_VERSION_gpsd ?= "2.34"
+PREFERRED_VERSION_gpsd ?= "2.37"
PREFERRED_VERSION_gpsdrive ?= "2.10pre4"
PREFERRED_VERSION_gpstk ?= "1.2"
PREFERRED_VERSION_gqview ?= "2.1.1"
PREFERRED_VERSION_hfsplusutils ?= "1.0.4-4"
PREFERRED_VERSION_hfsutils ?= "3.2.6"
PREFERRED_VERSION_hibernate-script ?= "1.12"
-PREFERRED_VERSION_hicolor-icon-theme ?= "0.9"
+PREFERRED_VERSION_hicolor-icon-theme ?= "0.10"
PREFERRED_VERSION_hiker ?= "0.9.1"
PREFERRED_VERSION_hildon-base-lib ?= "0.11.1"
PREFERRED_VERSION_hildon-control-panel ?= "0.9.1-1.2"
PREFERRED_VERSION_python-lxml ?= "1.3.3"
PREFERRED_VERSION_python-mad ?= "0.6"
PREFERRED_VERSION_python-mysqldb ?= "1.2.1"
-PREFERRED_VERSION_python-native ?= "2.5.1"
+PREFERRED_VERSION_python-native ?= "2.6.1"
PREFERRED_VERSION_python-numarray ?= "1.1.1"
PREFERRED_VERSION_python-numeric ?= "23.7"
PREFERRED_VERSION_python-ogg ?= "1.3"
PREFERRED_VERSION_python-pyraf ?= "1.4"
PREFERRED_VERSION_python-pyreverse ?= "0.5.2"
PREFERRED_VERSION_python-pyrex ?= "0.9.8.4"
-PREFERRED_VERSION_python-pyrex-native ?= "0.9.8.4"
+PREFERRED_VERSION_python-pyrex-native ?= "0.9.8.5"
PREFERRED_VERSION_python-pyro ?= "3.7"
-PREFERRED_VERSION_python-pyserial ?= "2.2"
+PREFERRED_VERSION_python-pyserial ?= "2.4"
PREFERRED_VERSION_python-pytester ?= "0.6.0"
PREFERRED_VERSION_python-pythondaap ?= "0.4"
PREFERRED_VERSION_python-pyvisa ?= "1.1"
PREFERRED_VERSION_python-scons ?= "0.97"
PREFERRED_VERSION_python-scons-native ?= "0.97"
PREFERRED_VERSION_python-setuptools ?= "0.6c8"
-PREFERRED_VERSION_python-setuptools-native ?= "0.6c8"
+PREFERRED_VERSION_python-setuptools-native ?= "0.6c9"
PREFERRED_VERSION_python-sgmlop ?= "1.1"
PREFERRED_VERSION_python-simplejson ?= "1.7.1"
PREFERRED_VERSION_python-snmplib ?= "0.1.1"
PREFERRED_VERSION_uucp ?= "1.07"
PREFERRED_VERSION_v4l2apps ?= "20020317"
PREFERRED_VERSION_vala ?= "0.5.1"
-PREFERRED_VERSION_vala-native ?= "0.5.1"
+PREFERRED_VERSION_vala-native ?= "0.5.6"
PREFERRED_VERSION_vde ?= "2.0.2"
PREFERRED_VERSION_vectoroids ?= "1.1.0"
PREFERRED_VERSION_videoplayer ?= "0.1"
SRCREV_pn-clutter-box2d ?= "3197"
SRCREV_pn-clutter-cairo ?= "3210"
SRCREV_pn-clutter-gst ?= "3188"
+SRCREV_pn-clutter-gtk-0.6 ?= "2ba362a1a223c2b28541030a80aa11191615340a"
+SRCREV_pn-clutter-gtk-0.8 ?= "7d3c3230376e731c06c21afa9d8c1d44dbea27cd"
+SRCREV_pn-clutter-gtk ?= "70f4b0cbd568dfa265484a03be3bd08ad15ed12e"
SRCREV_pn-clutter ?= "3240"
SRCREV_pn-comic-reader ?= "54"
SRCREV_pn-connman ?= "103706c4f4da0c89f8b6f33cccdc3149f4ecc09a"
SRCREV_pn-exalt-daemon ?= "78"
SRCREV_pn-exalt-module ?= "78"
SRCREV_pn-ezx-boot-usb-native ?= "2371"
+SRCREV_pn-ezx-gen-blob ?= "2390"
SRCREV_pn-ezxd ?= "2074"
SRCREV_pn-elf2flt ?= "1786"
SRCREV_pn-epiphany ?= "7837"
SRCREV_pn-etk-theme-ninja ?= "5"
SRCREV_pn-fbgrab-viewer-native ?= "1943"
SRCREV_pn-flashrom ?= "3682"
-SRCREV_pn-frameworkd ?= "b10138017b9fcf4dac8d16f22a184c333ddab9ab"
+SRCREV_pn-frameworkd ?= "700ab8250582767628165b7cf6f671ef756ba56d"
SRCREV_pn-frameworkd-devel ?= "${SRCREV_pn-frameworkd}"
SRCREV_pn-fsod ?= "3fa5eb6f2edcf7c9f0fc2027fda47b91d9f0f136"
+SRCREV_pn-fso-abyss ?= "4afeacb21c3d4193289e2b7db549a91751d75195"
SRCREV_pn-fso-apm ?= "eb39ce7fb81bfa64e1a9eb5f142ca3d1065be3fa"
-SRCREV_pn-fso-gpsd ?= "15f75f335efb52dd50a22a05f47a0f63eb07378b"
+SRCREV_pn-fso-gpsd ?= "78fe48dffb923175bde9f0aabc3500a9264a57e0"
SRCREV_pn-fso-gsm0710muxd ?= "abcbcd7cc532a8834906de3fc24c8f8fe7643cd4"
-SRCREV_pn-fso-monitord ?= "31b4d3d1a40b1cc2cbe186e5ea80490a0c80b55f"
-SRCREV_pn-fso-sounds ?= "b24d3c2e66fee10a5e288101cd1b6f5bbd3da7e2"
+SRCREV_pn-fso-monitord ?= "6a7860dc09a18144e8e363e64b2eb881bba83728"
+SRCREV_pn-fso-sounds ?= "3d2cf5231cb0e81770a246530574142bd2b8bbff"
SRCREV_pn-fstests ?= "204"
SRCREV_pn-gconf-dbus ?= "641"
SRCREV_pn-gnuradio ?= "10302"
SRCREV_pn-linux-ixp4xx ?= "1085"
SRCREV_pn-linux-openmoko-2.6.24 ?= "fb42ce6724576fc173faf8abfb04aa2c36d213b7"
SRCREV_pn-linux-openmoko-2.6.28 ?= "34240a1c06ae36180dee695aa25bbae869b2aa26"
-SRCREV_pn-linux-openmoko-devel ?= "34240a1c06ae36180dee695aa25bbae869b2aa26"
+SRCREV_pn-linux-openmoko-devel ?= "498d0953423a504cd24d11a0307e0ec01b81b68d"
SRCREV_pn-linux-eten ?= "ab2d414f4f13816af0ec0401b608133ca946624a"
SRCREV_pn-llvm-gcc4 ?= "374"
SRCREV_pn-llvm-gcc4-cross ?= "374"
SRCREV_pn-openmoko-theme-standard2-qvga ?= "3425"
SRCREV_pn-openmoko-today2 ?= "4168"
SRCREV_pn-openmoko-today2-folders ?= "3704"
-SRCREV_pn-openmoko-toolchain-scripts ?= "4878"
+SRCREV_pn-openmoko-toolchain-scripts ?= "4913"
SRCREV_pn-openmoko-worldclock2 ?= "3365"
SRCREV_pn-openocd ?= "517"
SRCREV_pn-openocd-native ?= "517"
SRCREV_pn-paroli ?= "9279b50ed72a94100d7f0f49090043134302f2eb"
SRCREV_pn-portaudio-v19 ?= "1387"
SRCREV_pn-psplash ?= "249"
-SRCREV_pn-pty-forward-native ?= "4214"
+SRCREV_pn-pty-forward-native ?= "4907"
SRCREV_pn-pyefl-sudoku ?= "49"
SRCREV_pn-pygsm ?= "976477f6b403f422b4ea730f71ebf409f6671141"
SRCREV_pn-pylgrim ?= "20"
SRCREV_pn-pyneod ?= "41de4d538b50b27ab2a2f5aae1a180b880a05b6a"
SRCREV_pn-pyneog ?= "41de4d538b50b27ab2a2f5aae1a180b880a05b6a"
+SRCREV_pn-python-coherence ?= "1154"
SRCREV_pn-python-connexion ?= "1439"
SRCREV_pn-python-formencode ?= "3148"
SRCREV_pn-python-gsmd ?= "148"
SRCREV_pn-remoko ?= "121"
SRCREV_pn-remoko-server ?= "121"
SRCREV_pn-s3c24xx-gpio ?= "4130"
-SRCREV_pn-serial-forward ?= "4214"
+SRCREV_pn-serial-forward ?= "4907"
SRCREV_pn-settings-daemon ?= "2006"
SRCREV_pn-sjf2410-linux-native ?= "4268"
SRCREV_pn-socketcan-modules ?= "917"
SRCREV_pn-uclibc-initial ?= "24279"
SRCREV_pn-usbpath ?= "3172"
SRCREV_pn-usbpath-native ?= "3172"
-SRCREV_pn-vala-terminal ?= "502d62d7eb100f86380b0e78474cc360ad7944b5"
+SRCREV_pn-vala-terminal ?= "94117f453ce884e9c30b611fae6fc19f85f98f2b"
SRCREV_pn-webkit-gtk ?= "39964"
SRCREV_pn-webkit-qt ?= "28656"
SRCREV_pn-webkit-qtopia ?= "28656"
SRCREV_pn-wmiconfig ?= "4522"
SRCREV_pn-xoo ?= "1971"
SRCREV_pn-xserver-kdrive-glamo ?= "9b28d998424c77fbc057dd3a022ccbb122793a52"
-SRCREV_pn-zhone ?= "cedaa8a6dd70fc3e13bd8bcda7fe84019cf9ef54"
+SRCREV_pn-zhone ?= "f38cc52fbf11f7fe945797a6b8ade29ed479d924"
# Enlightenment Foundation Libraries
# Caution: This is not alphabetically, but (roughly) dependency-sorted.
#@DESCRIPTION: Machine configuration for the SA1100 based Sharp Zaurus SL-5000 and SL-5500 devices
TARGET_ARCH = "arm"
-
-MACHINE_KERNEL_VERSION ?= "2.6"
-require conf/machine/include/zaurus-${MACHINE_KERNEL_VERSION}.inc
require conf/machine/include/tune-strongarm.inc
-PREFERRED_PROVIDER_xserver ?= "xserver-kdrive"
+MACHINE_KERNEL_VERSION = "2.6"
+KERNEL_IMAGE_MAXSIZE = "1048576"
+KERNEL_IMAGETYPE = "zImage"
+SERIAL_CONSOLE = "115200 ttySA0"
+
+ROOT_FLASH_SIZE = "14"
+# actually 14680064, see EXTRA_IMAGECMD
+
+PREFERRED_PROVIDER_virtual/kernel = "linux-rp"
+PREFERRED_PROVIDER_virtual/xserver = "xserver-kdrive"
+
+XSERVER ?= "xserver-kdrive-fbdev"
EXTRA_IMAGECMD_jffs2 = "--pad=14680064 --little-endian --eraseblock=0x20000 -n"
+
IMAGE_LINGUAS ?= ""
IMAGE_FSTYPES ?= "jffs2 tar.gz"
-ROOT_FLASH_SIZE = "14"
-# actually 14680064, see EXTRA_IMAGECMD above
+PCMCIA_MANAGER ?= "pcmciautils"
-XSERVER ?= "xserver-kdrive-fbdev"
+GUI_MACHINE_CLASS = "smallscreen"
+MACHINE_FEATURES = "kernel26 apm alsa pcmcia irda usbgadget keyboard touchscreen screen vfat"
+
+require conf/machine/include/kexecboot.inc
SERIAL_CONSOLE = "115200 ttyS0 vt100"
USE_VT = "0"
-IMAGE_DEVICE_TABLES = "device_table-oldmmc.txt"
require conf/machine/include/LAB-settings.inc
#FIXME: this should be controlled by a userspace utility later.
module_autoload_g_ether = "g_ether"
-IMAGE_DEVICE_TABLES = "device_table-oldmmc.txt"
SERIAL_CONSOLE = "115200 ttyS0"
# we store kernel images in rootfs and only a minimal initramfs kernel in mtd1 for booting other kernels
DONT_CHECK_KERNELSIZE ?= "1"
+MACHINE_EXTRA_RRECOMMENDS_append = " kexecboot-cfg"
# Additionally, clamshell specific stuff in zaurus-clamshell.inc
TARGET_ARCH = "arm"
-PACKAGE_EXTRA_ARCHS_collie = ""
MACHINE_KERNEL_VERSION = "2.6"
ERASEBLOCKSIZE_akita = "0x20000"
EXTRA_IMAGECMD_jffs2 = "--little-endian --eraseblock=${ERASEBLOCKSIZE} --pad --faketime -n"
-IMAGE_CMD_jffs2 = "mkfs.jffs2 -x lzo --root=${IMAGE_ROOTFS} --output=${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.jffs2 ${EXTRA_IMAGECMD}"
-ZAURUS-UPDATER_collie = ""
ZAURUS-UPDATER = "zaurus-updater"
EXTRA_IMAGEDEPENDS += "${ZAURUS-UPDATER}"
SERIAL_CONSOLE = "115200 ttyS0"
-SERIAL_CONSOLE_collie = "115200 ttySA0"
PREFERRED_PROVIDER_virtual/kernel = "linux-rp"
PREFERRED_PROVIDER_virtual/xserver = "xserver-kdrive"
MACHINE_EXTRA_RRECOMMENDS_akita = "kernel-module-snd-soc-spitz kernel-module-pxa2xx-cs kernel-module-pcmcia"
MACHINE_EXTRA_RRECOMMENDS_spitz = "kernel-module-snd-soc-spitz"
MACHINE_EXTRA_RRECOMMENDS_poodle = "kernel-module-snd-soc-poodle kernel-module-pxa2xx-cs kernel-module-pcmcia"
-MACHINE_EXTRA_RRECOMMENDS_collie = "kernel-module-locomo-spi kernel-module-sa1100-cs kernel-module-mmc-block \
- kernel-module-collie-ts kernel-module-leds-locomo kernel-module-locomokbd kernel-module-mmc-spi \
- kernel-module-power"
GUI_MACHINE_CLASS = "bigscreen"
-GUI_MACHINE_CLASS_collie = "smallscreen"
GUI_MACHINE_CLASS_poodle = "smallscreen"
KERNEL_IMAGE_MAXSIZE = "1294336"
-KERNEL_IMAGE_MAXSIZE_collie = "1048576"
MACHINE_POSTPROCESS_COMMAND = "zaurus_make_installkit"
[ -f ${IMAGE_NAME}.rootfs.jffs2 ] && cp ${IMAGE_NAME}.rootfs.jffs2 ${IMAGE_NAME}-installkit/initrd.bin
fi
- # All zaurus machines except collie need updater.sh
- if [ "${MACHINE}" != "collie" ]; then
- cp updater.sh.${MACHINE} ${IMAGE_NAME}-installkit/updater.sh
- fi
+ cp updater.sh.${MACHINE} ${IMAGE_NAME}-installkit/updater.sh
+
tar czf ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}-installkit.tgz ${IMAGE_NAME}-installkit/
md5sum ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}-installkit.tgz > ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}-installkit.tgz.md5
--- /dev/null
+#@TYPE: Machine
+#@NAME: overo machine
+#@DESCRIPTION: Machine configuration for the Gumstix Overo
+
+include conf/machine/include/tune-cortexa8.inc
+
+TARGET_ARCH = "arm"
+MACHINE_FEATURES = "kernel26 screen apm usbgadget usbhost vfat alsa touchscreen"
+
+UBOOT_ENTRYPOINT = "0x80008000"
+UBOOT_LOADADDRESS = "0x80008000"
+UBOOT_MACHINE_overo = "omap3_overo_config"
+
+PREFERRED_PROVIDER_virtual/kernel = "linux-omap"
+
+KERNEL_IMAGETYPE = "uImage"
+SERIAL_CONSOLE = "115200 ttyS2"
+
+IMAGE_FSTYPES += "tar.bz2"
+EXTRA_IMAGEDEPENDS += " u-boot-omap3 x-load"
+
+PREFERRED_PROVIDER_virtual/xserver = "xserver-xorg"
+XSERVER = "xserver-xorg \
+ xf86-input-evdev \
+ xf86-input-mouse \
+ xf86-input-tslib \
+ xf86-video-omapfb \
+ xf86-input-keyboard"
+
+GUI_MACHINE_CLASS = "bigscreen"
+
+
+++ /dev/null
-#@TYPE: Machine
-#@NAME: OXE810(D)SE NAS devices
-#@DESCRIPTION: Machine configuration for Oxford OXE810(D)SE NAS devices http://www.oxsemi.com/products/storage/nas.html
-
-TARGET_ARCH = "arm"
-
-MACHINE_FEATURES = "kernel26 ext2 pci usbhost ethernet serial raid uboot"
-
-SERIAL_CONSOLE = "115200 ttyS0"
-
-PREFERRED_PROVIDER_virtual/kernel = "linux"
-
-KERNEL_IMAGETYPE = "uImage"
-
-PREFERRED_VERSION_u-boot = "1.1.2"
-UBOOT_LOADADDRESS = "0x48008000"
-UBOOT_ENTRYPOINT = "0x48008000"
-UBOOT_ARCH = "arm"
-
-require conf/machine/include/tune-arm926ejs.inc
--- /dev/null
+#@TYPE: Machine
+#@NAME: OXE810(D)SE NAS devices
+#@DESCRIPTION: Machine configuration for Oxford OXE810(D)SE NAS devices http://www.oxsemi.com/products/storage/nas.html
+
+TARGET_ARCH = "arm"
+
+MACHINE_FEATURES = "kernel26 ext2 pci usbhost ethernet serial raid uboot"
+
+SERIAL_CONSOLE = "115200 ttyS0"
+
+PREFERRED_PROVIDER_virtual/kernel = "linux"
+
+KERNEL_IMAGETYPE = "uImage"
+
+PREFERRED_VERSION_u-boot = "1.1.2"
+UBOOT_LOADADDRESS = "0x48008000"
+UBOOT_ENTRYPOINT = "0x48008000"
+UBOOT_ARCH = "arm"
+
+require conf/machine/include/tune-arm926ejs.inc
pushover \
python \
python-pybluez \
+ python-coherence \
qfish2 \
qmatrix \
qpe-nmap \
wifi-radar \
win4 \
wpa-gui \
+ wt \
x11vnc \
xf86-input-evdev \
xf86-input-keyboard \
# machine packages (machine specific (sub)packages)
-for machine in beagleboard omap3evm neuros-osd2 efika dht-walnut palmt650 omap5912osk ixp4xxle ixp4xxbe c7x0 poodle tosa akita spitz collie simpad om-gta01 om-gta02 a780 at91sam9263ek qemuarm h2200 h3900 h4000 hx4700 nokia800 dns323 mv2120 kuropro lspro tsx09 ts409 qemux86
+for machine in overo omap3-pandora beagleboard omap3evm neuros-osd2 efika dht-walnut palmt650 omap5912osk ixp4xxle ixp4xxbe c7x0 poodle tosa akita spitz collie simpad om-gta01 om-gta02 a780 at91sam9263ek qemuarm h2200 h3900 h4000 hx4700 nokia800 dns323 mv2120 kuropro lspro tsx09 ts409 qemux86
+
do
BUILD_MACHINE=$machine
BUILD_CLEAN="opkg-native qmake-native qmake2-native qt-x11-free python python-native python-pygtk gnome-icon-theme"
do_build
done
+for machine in collie h2200 hx4700 spitz akita tosa poodle c7x0
+do
+ BUILD_MACHINE=$machine
+ BUILD_TARGETS="linux-kexecboot \
+ "
+ do_build
+done
done
# build kexecboot kernels for supported machines
-for machine in poodle collie
+for machine in h2200 hx4700 c7x0 akita spitz poodle collie
do
BUILD_MACHINE=$machine
BUILD_TARGETS="linux-kexecboot"
done
-# Make uclibc initramfs-bootmenu-image for ipaqs, this should move to more generic klibc stuff, but till then:
-DO_UCLIBC=1
-for machine in h2200 h3900 h4000 h5000 hx4700
-do
- BUILD_MACHINE=$machine
- BUILD_TARGETS="initramfs-bootmenu-image"
-done
-DO_UCLIBC=0
-
# graphics, flash storage
-for machine in beagleboard omap3evm om-gta01 om-gta02 a780 at91sam9263ek qemuarm qemux86 h2200 h3900 h4000 h5000 poodle tosa hx4700 c7x0 spitz akita collie simpad
+for machine in overo omap3-pandora beagleboard omap3evm om-gta01 om-gta02 a780 at91sam9263ek qemuarm qemux86 h2200 h3900 h4000 h5000 poodle tosa hx4700 c7x0 spitz akita collie simpad
do
BUILD_CLEAN="base-files"
BUILD_MACHINE=$machine
done
# graphics, disk storage
-for machine in spitz beagleboard omap3evm
+for machine in spitz overo omap3-pandora beagleboard omap3evm
do
BUILD_CLEAN="base-files"
BUILD_MACHINE=$machine
done
# omap3 boards
-for machine in beagleboard omap3evm
+for machine in overo omap3-pandora beagleboard omap3evm
do
BUILD_MACHINE=$machine
BUILD_TARGETS="beagleboard-demo-image"
"armv7")
machines="" ;;
"armv7a")
- machines="beagleboard omap3evm omap3-pandora" ;;
+ machines="beagleboard omap3evm omap3-pandora overo" ;;
"avr32")
machines="atngw100 at32stk1000" ;;
"bfin")
echo " DONE"
cd ${BPWD}
-echo -n "Stripping source lines from Package files"
-for i in `find . -name Packages` ; do grep -v ^Source: $i|gzip -c9>$i.gz ;gunzip -c $i.gz>$i ; touch $i.sig ; done
-echo " DONE"
}
echo "Processing 'all' feed"
for i in $(find ../ -name "*.ipk"| grep -v unsorted) ; do basename $i ; done > files-sorted
fi
-#(cd ~/website/repo ; php update.php)
+( cd ~/website/repo-updater ; php update.php ; rm ../repo/feeds.db* ; cp feeds.db* ../repo )
+
+echo -n "Stripping source lines from Package files"
+for i in `find .. -name Packages` ; do grep -v ^Source: $i|gzip -c9>$i.gz ;gunzip -c $i.gz>$i ; touch $i.sig ; done
+echo " DONE"
+
+
cat files-remote files-local | sort | uniq -u >files-uniq
cat files-uniq files-local | sort | uniq -d > files-trans
+# Remove SGX files
+rm -f upload-queue/*3.00.*
+
# Copy over non-duplicate files
echo "Starting rsync..."
rsync -vz --copy-links --progress --files-from=files-trans upload-queue/ $REMOTEM:$REMOTED/unsorted/
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title>Feed browser</title>
+ <meta http-equiv="Content-Style-Type" content="text/css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <style type="text/css" media="all">@import "css/feed.css";</style>
+ <script language="javascript" type="text/javascript" src="scripts/js/repo.js"></script>
+ </head>
+ <body onLoad=" qs(); getLetter(); getSection();">
+ <div id="right">
+ <div id="searchletter"</div>
+ <form name="pkg_query" onsubmit="javascript:pkgQuery();return false"">
+ <fieldset>
+ <label for="name">Package name</label>
+ <input id="pkgsearch" type="text" name="pkgsearch" value="" />
+ <select name="arch">
+ <option value="" selected="selected">all architectures</option>
+ <option value="all">no arch</option>
+<?php
+
+foreach($archs_list as $architecture)
+{
+ echo "<option value='{$architecture['p_arch']}'";
+
+ if($architecture['p_arch'] == $arch)
+ {
+ echo ' selected="selected"';
+ }
+ echo ">{$architecture['p_arch']}</option>";
+}
+
+?>
+
+
+ </select>
+ <input type="submit" value="Search" />
+ </fieldset>
+ </form>
+ <div id="opkgoutput"><?php echo $ipkgoutput; ?></div>
+ </div>
+ <div id="left">
+ <h1>Sections list</h1>
+ <div id="sectionslist"></div>
+ </div>
+ </body>
+</html>
+++ /dev/null
-<?php
-
-/*
- * (c) Koen Kooi 2006, 2007
- * (c) Marcin Juszkiewicz 2006, 2007
- *
- * This php script is intended to do the following:
- *
- * - have searchable webfronted for the feed like packages.ubuntu.com
- *
- * ToDo:
- *
- * - search functionality
- * - provide feed-management functionality
- * - allow uploading of new software
- *
- *
- * 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.
- *
- * 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 Library General Public License along
- * with this library; see the file COPYING.LIB. If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- * USA.
- *
- */
-
-require_once 'includes/config.inc';
-require_once 'includes/functions.inc';
-
-if(!check_database())
-{
- die("Database not found and cannot be created.");
-}
-
-read_vars_from_get(array('name', 'arch', 'pkgsearch', 'letter', 'pkgname', 'section'));
-
-$ipkgoutput = '';
-
-if(!empty($section))
-{
- $ipkgoutput = searchsection($section);
-}
-elseif(!empty($letter))
-{
- $ipkgoutput = searchpkg("{$letter}%", $arch);
-}
-elseif(!empty($pkgname))
-{
- $ipkgoutput = pkgdetails($pkgname);
-}
-elseif(!empty($pkgsearch) OR !empty($arch))
-{
- $ipkgoutput = searchpkg("%{$pkgsearch}%", $arch);
-}
-
-$archs_list = get_arch_list();
-
-?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
- <head>
- <title>Feed browser</title>
- <meta http-equiv="Content-Style-Type" content="text/css" />
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <style type="text/css" media="all">@import "css/feed.css";</style>
- </head>
- <body >
- <div id="right">
- <?php echo searchletter(); ?>
- <form action="" method="get">
- <fieldset>
- <label for="name">Package name</label>
- <input type="text" name="pkgsearch" value="<?php echo $pkgsearch; ?>" />
- <select name="arch">
- <option value="" selected="selected">all architectures</option>
- <option value="all">no arch</option>
-<?php
-
-foreach($archs_list as $architecture)
-{
- echo "<option value='{$architecture['p_arch']}'";
-
- if($architecture['p_arch'] == $arch)
- {
- echo ' selected="selected"';
- }
- echo ">{$architecture['p_arch']}</option>";
-}
-
-?>
- </select>
- <input type="submit" value="Search" />
- </fieldset>
- </form>
- <?php echo $ipkgoutput; ?>
- </div>
- <div id="left">
- <h1>Sections list</h1>
- <?php echo sectionslist(); ?>
- </div>
- </body>
-</html>
--- /dev/null
+/* The following function creates an XMLHttpRequest object... */
+
+function createRequestObject(){
+ var request_o; //declare the variable to hold the object.
+ var browser = navigator.appName; //find the browser name
+ if(browser == "Microsoft Internet Explorer"){
+ /* Create the object using MSIE's method */
+ request_o = new ActiveXObject("Microsoft.XMLHTTP");
+ } else {
+ /* Create the object using other browser's method */
+ request_o = new XMLHttpRequest();
+ }
+ return request_o; //return the object
+}
+
+/* The variable http will hold our new XMLHttpRequest object. */
+var sectionHTTP = createRequestObject();
+var queryHTTP = createRequestObject();
+var http = createRequestObject();
+
+var qsParm = new Array();
+qsParm['pkgsearch'] = null;
+qsParm['arch'] = null;
+qsParm['section'] = null;
+qsParm['pkgname'] = null;
+
+
+function qs() {
+ var query = window.location.search.substring(1);
+ var parms = query.split('&');
+ for (var i=0; i<parms.length; i++) {
+ var pos = parms[i].indexOf('=');
+ if (pos > 0) {
+ var key = parms[i].substring(0,pos);
+ var val = parms[i].substring(pos+1);
+ qsParm[key] = val;
+ }
+ }
+ if (qsParm['pkgsearch']) {
+ document.getElementById('pkgsearch').value = qsParm['pkgsearch'];
+ pkgQuery();
+ }
+ if (qsParm['pkgname']) {
+ document.getElementById('pkgsearch').value = qsParm['pkgname'];
+ pkgQuery();
+ }
+ if (qsParm['section']) {
+ pkgQuery();
+ }
+
+}
+
+function pkgQuery() {
+ var action = 'pkgquery';
+ var params = '';
+
+ if (qsParm['pkgname']) {
+ action = 'pkgname';
+ params = '&pkgname=' + qsParm['pkgname'];
+ qsParm['pkgname'] = null;
+ }
+
+ if (document.getElementById('pkgsearch').value != "") {
+ params = params + '&pkgsearch=' + document.getElementById('pkgsearch').value;
+ } else {
+ if (qsParm['pkgsearch']) {
+ params = params + '&pkgsearch=' + qsParm['pkgsearch'];
+ }
+ }
+ if (qsParm['arch']) {
+ params = params + '&arch=' + qsParm['arch'];
+ qsParm['arch'] = null;
+ }
+ if (qsParm['section']) {
+ action = 'section';
+ params = params + '§ion=' + qsParm['section'];
+ qsParm['section'] = null;
+ }
+
+ params = '&action=' + action + params;
+
+ queryHTTP.open('post', 'section.php');
+ queryHTTP.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+ queryHTTP.onreadystatechange = queryProgress;
+ queryHTTP.send(params);
+
+}
+
+function getLetter() {
+ var params = 'action=searchletter';
+ http.open('post', 'section.php');
+ http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+ http.onreadystatechange = letterProgress;
+ http.send(params);
+
+}
+
+function getSection() {
+ var params = 'action=sectionslist';
+ sectionHTTP.open('post', 'section.php');
+ sectionHTTP.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+ sectionHTTP.onreadystatechange = sectionProgress;
+ sectionHTTP.send(params);
+
+}
+
+function letterProgress() {
+ if(http.readyState == 4){
+ var response = http.responseText;
+ document.getElementById('searchletter').innerHTML = response;
+
+ }
+}
+
+function sectionProgress() {
+ if(sectionHTTP.readyState == 4){
+ var response = sectionHTTP.responseText;
+ document.getElementById('sectionslist').innerHTML = response;
+
+ }
+}
+
+function queryProgress() {
+ document.getElementById('opkgoutput').innerHTML = "loading, please wait";
+ if(queryHTTP.readyState == 4){
+ var response = queryHTTP.responseText;
+ document.getElementById('opkgoutput').innerHTML = response;
+
+ }
+}
--- /dev/null
+<?php
+
+/*
+ * (c) Koen Kooi 2006, 2007, 2008, 2009
+ * (c) Marcin Juszkiewicz 2006, 2007
+ *
+ * This php script is intended to do the following:
+ *
+ * - have searchable webfronted for the feed like packages.ubuntu.com
+ *
+ * ToDo:
+ *
+ * - search functionality
+ * - provide feed-management functionality
+ * - allow uploading of new software
+ *
+ *
+ * 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.
+ *
+ * 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 Library General Public License along
+ * with this library; see the file COPYING.LIB. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ *
+ */
+
+require_once 'includes/config.inc';
+require_once 'includes/functions.inc';
+
+if(!check_database())
+{
+ die("Database not found and cannot be created.");
+}
+
+if (isset($_POST["action"]) && $_POST["action"] != "") {
+ $action = $_POST["action"];
+} else {
+ print "Invalid action: $action";
+ exit;
+}
+
+if (isset($_POST["pkgsearch"]) && $_POST["pkgsearch"] != "") {
+ $pkgsearch = $_POST["pkgsearch"];
+}
+
+if (isset($_POST["section"]) && $_POST["section"] != "") {
+ $section = $_POST["section"];
+}
+
+if (isset($_POST["arch"]) && $_POST["arch"] != "") {
+ $arch = $_POST["arch"];
+} else {
+ $arch = "";
+}
+
+if (isset($_POST["pkgname"]) && $_POST["pkgname"] != "") {
+ $pkgname = $_POST["pkgname"];
+}
+
+
+//print("$action");
+switch($action) {
+case "sectionslist":
+ echo sectionslist();
+ break;
+case "searchletter":
+ echo searchletter();
+ break;
+case "pkgquery":
+ echo searchpkg("%{$pkgsearch}%", $arch);
+ break;
+case "pkgname":
+ echo pkgdetails($pkgname);
+ break;
+case "section":
+ echo searchsection($section);
+ break;
+}
+?>
DESCRIPTION = "Task packages for the Angstrom distribution"
-PR = "r33"
+PR = "r34"
inherit task
RDEPENDS_${PN} = "\
matchbox-panel-manager \
mboxkbd-layouts-gui \
- gpe-su \
+ connman-gnome \
+ gpe-su \
gpe-conf \
gpe-package \
gpe-shield \
DESCRIPTION = "Enlightenment DR17 theme for Angstrom"
LICENSE = "MIT/BSD"
DEPENDS = "edje-native eet-native"
+RDEPENDS = "e-wm"
RRECOMMENDS_${PN} = "places"
-PR = "r3"
+PR = "r4"
SRC_URI = " \
file://e.src \
--- /dev/null
+Index: apr-util-1.3.4/apu-config.in
+===================================================================
+--- apr-util-1.3.4.orig/apu-config.in 2009-01-12 17:08:06.000000000 +0000
++++ apr-util-1.3.4/apu-config.in 2009-01-12 17:09:00.000000000 +0000
+@@ -134,14 +134,7 @@
+ exit 0
+ ;;
+ --includes)
+- if test "$location" = "installed"; then
+ flags="$flags -I$includedir $INCLUDES"
+- elif test "$location" = "source"; then
+- flags="$flags -I$APU_SOURCE_DIR/include $INCLUDES"
+- else
+- # this is for VPATH builds
+- flags="$flags -I$APU_BUILD_DIR/include -I$APU_SOURCE_DIR/include $INCLUDES"
+- fi
+ ;;
+ --ldflags)
+ flags="$flags $LDFLAGS"
+@@ -155,28 +148,10 @@
+ exit 0
+ ;;
+ --link-ld)
+- if test "$location" = "installed"; then
+- ### avoid using -L if libdir is a "standard" location like /usr/lib
+ flags="$flags -L$libdir -l$APRUTIL_LIBNAME"
+- else
+- flags="$flags -L$APU_BUILD_DIR -l$APRUTIL_LIBNAME"
+- fi
+ ;;
+ --link-libtool)
+- # If the LA_FILE exists where we think it should be, use it. If we're
+- # installed and the LA_FILE does not exist, assume to use -L/-l
+- # (the LA_FILE may not have been installed). If we're building ourselves,
+- # we'll assume that at some point the .la file be created.
+- if test -f "$LA_FILE"; then
+- flags="$flags $LA_FILE"
+- elif test "$location" = "installed"; then
+- ### avoid using -L if libdir is a "standard" location like /usr/lib
+- # Since the user is specifying they are linking with libtool, we
+- # *know* that -R will be recognized by libtool.
+- flags="$flags -L$libdir -R$libdir -l$APRUTIL_LIBNAME"
+- else
+- flags="$flags $LA_FILE"
+- fi
++ flags="$flags -l$APRUTIL_LIBNAME"
+ ;;
+ --apu-la-file)
+ if test -f "$LA_FILE"; then
-Index: apr-util-1.2.12/configure.in
+Index: apr-util-1.3.4/configure.in
===================================================================
---- apr-util-1.2.12.orig/configure.in 2008-03-08 19:15:00.000000000 +0000
-+++ apr-util-1.2.12/configure.in 2008-03-08 19:15:13.000000000 +0000
-@@ -8,13 +8,13 @@
+--- apr-util-1.3.4.orig/configure.in
++++ apr-util-1.3.4/configure.in
+@@ -8,14 +8,14 @@ AC_INIT(export_vars.sh.in)
AC_CONFIG_HEADER(include/private/apu_config.h)
AC_CONFIG_AUX_DIR(build)
-sinclude(build/find_apr.m4)
-sinclude(build/dbm.m4)
-sinclude(build/dbd.m4)
+-sinclude(build/dso.m4)
+#sinclude(build/apu-conf.m4)
+#sinclude(build/apu-iconv.m4)
+#sinclude(build/apu-hints.m4)
+#sinclude(build/find_apr.m4)
+#sinclude(build/dbm.m4)
+#sinclude(build/dbd.m4)
++#sinclude(build/dso.m4)
dnl Generate ./config.nice for reproducing runs of configure
dnl
--- /dev/null
+Index: apr-util-1.2.12/configure.in
+===================================================================
+--- apr-util-1.2.12.orig/configure.in 2008-03-08 19:15:00.000000000 +0000
++++ apr-util-1.2.12/configure.in 2008-03-08 19:15:13.000000000 +0000
+@@ -8,13 +8,13 @@
+ AC_CONFIG_HEADER(include/private/apu_config.h)
+ AC_CONFIG_AUX_DIR(build)
+
+-sinclude(build/apu-conf.m4)
+-sinclude(build/apu-iconv.m4)
+-sinclude(build/apu-hints.m4)
+-sinclude(build/apr_common.m4)
+-sinclude(build/find_apr.m4)
+-sinclude(build/dbm.m4)
+-sinclude(build/dbd.m4)
++#sinclude(build/apu-conf.m4)
++#sinclude(build/apu-iconv.m4)
++#sinclude(build/apu-hints.m4)
++#sinclude(build/apr_common.m4)
++#sinclude(build/find_apr.m4)
++#sinclude(build/dbm.m4)
++#sinclude(build/dbd.m4)
+
+ dnl Generate ./config.nice for reproducing runs of configure
+ dnl
DEPENDS = "apr expat gdbm"
LICENSE = "Apache License, Version 2.0"
-PR = "r2"
+PR = "r3"
+
+inherit autotools lib_package binconfig
# apache mirrors?
SRC_URI = "${APACHE_MIRROR}/apr/${P}.tar.gz \
--with-expat=${STAGING_DIR_HOST}${layout_prefix}"
-inherit autotools lib_package binconfig
-
OE_BINCONFIG_EXTRA_MANGLE = " -e 's:location=source:location=installed:'"
+EXTRA_OEMAKE = " LIBTOOL=\"${S}/${TARGET_PREFIX}libtool\" "
+
+export LIBTOOL="${S}/${TARGET_PREFIX}libtool"
do_configure_prepend() {
+ cp ${STAGING_BINDIR_NATIVE}/${TARGET_PREFIX}libtool ${S}/
cp ${STAGING_DATADIR}/apr/apr_rules.mk ${S}/build/rules.mk
+ echo "AC_PROG_LIBTOOL" >> ${S}/configure.in
+ libtoolize --force
}
do_stage() {
--- /dev/null
+DESCRIPTION = "Apache Portable Runtime (APR) companion library"
+SECTION = "libs"
+DEPENDS = "apr expat gdbm"
+LICENSE = "Apache License, Version 2.0"
+
+PR = "r5"
+
+SRC_URI = "${APACHE_MIRROR}/apr/${P}.tar.gz \
+ file://configfix.patch;patch=1 \
+ file://configure_fixes.patch;patch=1"
+
+EXTRA_OECONF = "--with-apr=${STAGING_BINDIR_CROSS}/apr-1-config \
+ --with-dbm=gdbm \
+ --with-gdbm=${STAGING_DIR_HOST}${layout_prefix} \
+ --without-sqlite2 \
+ --without-sqlite3 \
+ --with-expat=${STAGING_DIR_HOST}${layout_prefix}"
+
+
+inherit autotools_stage lib_package binconfig
+
+OE_BINCONFIG_EXTRA_MANGLE = " -e 's:location=source:location=installed:'"
+
+do_configure_prepend() {
+ cp ${STAGING_DATADIR}/apr/apr_rules.mk ${S}/build/rules.mk
+ echo "AC_PROG_LIBTOOL" >> ${S}/configure.in
+}
+
+do_configure_append() {
+ sed -i -e s:apr_builders=/usr/share/build-1:apr_builders=${STAGING_DATADIR}/build-1:g ${S}/build/rules.mk
+ sed -i /^LIBTOOL/d ${S}/build/rules.mk
+ echo LIBTOOL="${STAGING_BINDIR_NATIVE}/${TARGET_PREFIX}libtool --tag=CC" >> ${S}/build/rules.mk
+}
+
--- /dev/null
+Index: apr-1.3.3/build/buildcheck.sh
+===================================================================
+--- apr-1.3.3.orig/build/buildcheck.sh 2009-01-15 13:32:33.000000000 +0000
++++ apr-1.3.3/build/buildcheck.sh 2009-01-15 13:33:06.000000000 +0000
+@@ -32,35 +32,4 @@
+ echo "buildconf: autoconf version $ac_version (ok)"
+ fi
+
+-# Sample libtool --version outputs:
+-# ltmain.sh (GNU libtool) 1.3.3 (1.385.2.181 1999/07/02 15:49:11)
+-# ltmain.sh (GNU libtool 1.1361 2004/01/02 23:10:52) 1.5a
+-# output is multiline from 1.5 onwards
+-
+-# Require libtool 1.4 or newer
+-libtool=`build/PrintPath glibtool libtool libtool15 libtool14`
+-lt_pversion=`$libtool --version 2>/dev/null|sed -e 's/([^)]*)//g;s/^[^0-9]*//;s/[- ].*//g;q'`
+-if test -z "$lt_pversion"; then
+-echo "buildconf: libtool not found."
+-echo " You need libtool version 1.4 or newer installed"
+-echo " to build APR from SVN."
+-exit 1
+-fi
+-lt_version=`echo $lt_pversion|sed -e 's/\([a-z]*\)$/.\1/'`
+-IFS=.; set $lt_version; IFS=' '
+-lt_status="good"
+-if test "$1" = "1"; then
+- if test "$2" -lt "4"; then
+- lt_status="bad"
+- fi
+-fi
+-if test $lt_status = "good"; then
+- echo "buildconf: libtool version $lt_pversion (ok)"
+- exit 0
+-fi
+-
+-echo "buildconf: libtool version $lt_pversion found."
+-echo " You need libtool version 1.4 or newer installed"
+-echo " to build APR from SVN."
+-
+-exit 1
++exit 0
+\ No newline at end of file
--- /dev/null
+Index: apr-1.3.3/apr-config.in
+===================================================================
+--- apr-1.3.3.orig/apr-config.in 2009-01-12 15:16:31.000000000 +0000
++++ apr-1.3.3/apr-config.in 2009-01-12 15:19:25.000000000 +0000
+@@ -152,14 +152,7 @@
+ flags="$flags $LDFLAGS"
+ ;;
+ --includes)
+- if test "$location" = "installed"; then
+ flags="$flags -I$includedir $EXTRA_INCLUDES"
+- elif test "$location" = "source"; then
+- flags="$flags -I$APR_SOURCE_DIR/include $EXTRA_INCLUDES"
+- else
+- # this is for VPATH builds
+- flags="$flags -I$APR_BUILD_DIR/include -I$APR_SOURCE_DIR/include $EXTRA_INCLUDES"
+- fi
+ ;;
+ --srcdir)
+ echo $APR_SOURCE_DIR
+@@ -181,29 +167,14 @@
+ exit 0
+ ;;
+ --link-ld)
+- if test "$location" = "installed"; then
+- ### avoid using -L if libdir is a "standard" location like /usr/lib
+- flags="$flags -L$libdir -l${APR_LIBNAME}"
+- else
+- ### this surely can't work since the library is in .libs?
+- flags="$flags -L$APR_BUILD_DIR -l${APR_LIBNAME}"
+- fi
++ flags="$flags -l${APR_LIBNAME}"
+ ;;
+ --link-libtool)
+ # If the LA_FILE exists where we think it should be, use it. If we're
+ # installed and the LA_FILE does not exist, assume to use -L/-l
+ # (the LA_FILE may not have been installed). If we're building ourselves,
+ # we'll assume that at some point the .la file be created.
+- if test -f "$LA_FILE"; then
+- flags="$flags $LA_FILE"
+- elif test "$location" = "installed"; then
+- ### avoid using -L if libdir is a "standard" location like /usr/lib
+- # Since the user is specifying they are linking with libtool, we
+- # *know* that -R will be recognized by libtool.
+- flags="$flags -L$libdir -R$libdir -l${APR_LIBNAME}"
+- else
+- flags="$flags $LA_FILE"
+- fi
++ flags="$flags -l${APR_LIBNAME}"
+ ;;
+ --shlib-path-var)
+ echo "$SHLIBPATH_VAR"
---- /tmp/configure.in 2009-02-02 17:50:51.000000000 +0100
-+++ apr-1.2.12/configure.in 2009-02-02 17:54:55.000000000 +0100
-@@ -13,12 +13,11 @@
- dnl
- dnl Include our own M4 macros along with those for libtool
- dnl
--sinclude(build/apr_common.m4)
--sinclude(build/apr_network.m4)
--sinclude(build/apr_threads.m4)
--sinclude(build/apr_hints.m4)
--sinclude(build/libtool.m4)
--sinclude(build/ltsugar.m4)
-+#sinclude(build/apr_common.m4)
-+#sinclude(build/apr_network.m4)
-+#sinclude(build/apr_threads.m4)
-+#sinclude(build/apr_hints.m4)
-+#sinclude(build/libtool.m4)
+Index: apr-1.3.3/configure.in
+===================================================================
+--- apr-1.3.3.orig/configure.in
++++ apr-1.3.3/configure.in
+@@ -794,39 +794,6 @@ AC_CHECK_FUNCS([mmap munmap shm_open shm
+ create_area])
- dnl Hard-coded inclusion at the tail end of apr_private.h:
- AH_BOTTOM([
-@@ -197,8 +196,8 @@
+ APR_CHECK_DEFINE(MAP_ANON, sys/mman.h)
+-AC_CHECK_FILE(/dev/zero)
+-
+-# Not all systems can mmap /dev/zero (such as HP-UX). Check for that.
+-if test "$ac_cv_func_mmap" = "yes" &&
+- test "$ac_cv_file__dev_zero" = "yes"; then
+- AC_MSG_CHECKING(for mmap that can map /dev/zero)
+- AC_TRY_RUN([
+-#include <sys/types.h>
+-#include <sys/stat.h>
+-#include <fcntl.h>
+-#ifdef HAVE_SYS_MMAN_H
+-#include <sys/mman.h>
+-#endif
+- int main()
+- {
+- int fd;
+- void *m;
+- fd = open("/dev/zero", O_RDWR);
+- if (fd < 0) {
+- return 1;
+- }
+- m = mmap(0, sizeof(void*), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+- if (m == (void *)-1) { /* aka MAP_FAILED */
+- return 2;
+- }
+- if (munmap(m, sizeof(void*)) < 0) {
+- return 3;
+- }
+- return 0;
+- }], [], [ac_cv_file__dev_zero=no], [ac_cv_file__dev_zero=no])
+-
+- AC_MSG_RESULT($ac_cv_file__dev_zero)
+-fi
- if test "x$use_libtool" = "xyes"; then
- lt_compile='$(LIBTOOL) $(LTFLAGS) --mode=compile $(COMPILE) -o $@ -c $< && touch $@'
-- LT_VERSION="-version-info `$get_version libtool $version_hdr APR`"
-- link="\$(LIBTOOL) \$(LTFLAGS) --mode=link \$(LT_LDFLAGS) \$(COMPILE) ${LT_VERSION} \$(ALL_LDFLAGS) -o \$@"
-+ LV_VERSION="-version-info `$get_version libtool $version_hdr APR`"
-+ link="\$(LIBTOOL) \$(LTFLAGS) --mode=link \$(LV_LDFLAGS) \$(COMPILE) ${LV_VERSION} \$(ALL_LDFLAGS) -o \$@"
- so_ext='lo'
- lib_target='-rpath $(libdir) $(OBJECTS)'
- export_lib_target='-rpath \$(libdir) \$(OBJECTS)'
-@@ -225,7 +224,7 @@
- AC_SUBST(export_lib_target)
- AC_SUBST(shlibpath_var)
- AC_SUBST(LTFLAGS)
--AC_SUBST(LT_LDFLAGS)
-+AC_SUBST(LV_LDFLAGS)
+ # Now we determine which one is our anonymous shmem preference.
+ haveshmgetanon="0"
+@@ -1518,13 +1485,14 @@ else
+ bigendian=0
+ fi
- dnl ----------------------------- Checks for compiler flags
- nl='
-@@ -2132,10 +2131,10 @@
- # against installed versions of libapr instead of those just
- # built.
- case $host in
--*-apple-darwin*) LT_NO_INSTALL="" ;;
--*) LT_NO_INSTALL="-no-install" ;;
-+*-apple-darwin*) LV_NO_INSTALL="" ;;
-+*) LV_NO_INSTALL="-no-install" ;;
- esac
--AC_SUBST(LT_NO_INSTALL)
-+AC_SUBST(LV_NO_INSTALL)
+-APR_CHECK_SIZEOF_EXTENDED([#include <sys/types.h>
+-#include <sys/uio.h>],struct iovec,0)
+-if test "$ac_cv_sizeof_struct_iovec" = "0"; then
+- have_iovec=0
+-else
+- have_iovec=1
+-fi
++#APR_CHECK_SIZEOF_EXTENDED([#include <sys/types.h>
++##include <sys/uio.h>],struct iovec,0)
++#if test "$ac_cv_sizeof_struct_iovec" = "0"; then
++# have_iovec=0
++#else
++# have_iovec=1
++#fi
++have_iovec=1
- #
- # BSD/OS (BSDi) needs to use a different include syntax in the Makefiles
+ AC_SUBST(voidp_size)
+ AC_SUBST(short_value)
--- /dev/null
+DESCRIPTION = "Apache Portable Runtime (APR) library"
+SECTION = "libs"
+LICENSE = "Apache License, Version 2.0"
+
+PR = "r4"
+
+SRC_URI = "${APACHE_MIRROR}/apr/${P}.tar.bz2 \
+ file://configure_fixes.patch;patch=1 \
+ file://cleanup.patch;patch=1 \
+ file://configfix.patch;patch=1"
+
+inherit autotools lib_package binconfig
+
+OE_BINCONFIG_EXTRA_MANGLE = " -e 's:location=source:location=installed:'"
+
+do_configure_prepend() {
+ cd ${S}
+ ./buildconf
+}
+
+do_stage() {
+ autotools_stage_all
+ install -d ${STAGING_DATADIR}/apr
+ cp ${S}/build/apr_rules.mk ${STAGING_DATADIR}/apr/
+ sed -i s,apr_builddir=.*,apr_builddir=,g ${STAGING_DATADIR}/apr/apr_rules.mk
+ sed -i s,apr_builders=.*,apr_builders=,g ${STAGING_DATADIR}/apr/apr_rules.mk
+ sed -i s,LIBTOOL=.*,LIBTOOL=\$\(SHELL\)\ ${TARGET_PREFIX}libtool,g ${STAGING_DATADIR}/apr/apr_rules.mk
+ sed -i s,\$\(apr_builders\),${STAGING_DATADIR}/apr/,g ${STAGING_DATADIR}/apr/apr_rules.mk
+ cp ${S}/build/mkdir.sh ${STAGING_DATADIR}/apr/
+ cp ${S}/build/make_exports.awk ${STAGING_DATADIR}/apr/
+ cp ${S}/build/make_var_export.awk ${STAGING_DATADIR}/apr/
+}
--- /dev/null
+--- /tmp/configure.ac 2008-06-22 14:14:59.000000000 +0200
++++ binutils-2.18.50.0.7/configure.ac 2008-06-22 14:15:30.000000000 +0200
+@@ -561,7 +561,7 @@
+ noconfigdirs="$noconfigdirs target-libffi target-qthreads"
+ libgloss_dir=arm
+ ;;
+- arm*-*-linux-gnueabi)
++ arm*-*-linux-gnueabi | arm*-*-linux-uclibcgnueabi)
+ noconfigdirs="$noconfigdirs target-qthreads"
+ noconfigdirs="$noconfigdirs target-libobjc"
+ case ${with_newlib} in
+--- /tmp/configure 2008-06-22 14:17:11.000000000 +0200
++++ binutils-2.18.50.0.7/configure 2008-06-22 14:17:56.000000000 +0200
+@@ -2307,7 +2307,7 @@
+ noconfigdirs="$noconfigdirs target-libffi target-qthreads"
+ libgloss_dir=arm
+ ;;
+- arm*-*-linux-gnueabi)
++ arm*-*-linux-gnueabi | arm*-*-linux-uclibcgnueabi)
+ noconfigdirs="$noconfigdirs target-qthreads"
+ noconfigdirs="$noconfigdirs target-libobjc"
+ case ${with_newlib} in
--- /dev/null
+Adds support for Freescale Power architecture e300c2 and e300c3 cores.
+http://www.bitshrine.org/gpp/tc-fsl-x86lnx-e300c3-nptl-4.0.2-2.src.rpm
+
+Leon Woestenberg <leonw@mailcan.com>
+
+diff -uNr binutils-2.16.1.orig/gas/config/tc-ppc.c binutils-2.16.1/gas/config/tc-ppc.c
+--- binutils-2.16.1.orig/gas/config/tc-ppc.c 2005-03-02 13:24:01.000000000 +0000
++++ binutils-2.16.1/gas/config/tc-ppc.c 2006-07-04 11:45:24.000000000 +0100
+@@ -879,6 +879,10 @@
+ else
+ ppc_cpu |= PPC_OPCODE_SPE;
+ }
++ else if (strcmp (arg, "pmr") == 0)
++ {
++ ppc_cpu |= PPC_OPCODE_PMR;
++ }
+ /* -mppc64 and -m620 mean to assemble for the 64-bit PowerPC
+ 620. */
+ else if (strcmp (arg, "ppc64") == 0 || strcmp (arg, "620") == 0)
--- /dev/null
+# strip (and objcopy) fail to set the error code if there is no
+# output file name and the rename of the stripped (or copied) file
+# fails, yet the command fails to do anything. This fixes both
+# objcopy and strip.
+#
+# modification by bero: Ported to 2.16.91.0.6
+#
+#Signed-off-by: John Bowler <jbowler@acm.org>
+#Signed-off-by: Bernhard Rosenkraenzer <bero@arklinux.org>
+---
+# binutils/objcopy.c | 8 +++++---
+# 1 file changed, 5 insertions(+), 3 deletions(-)
+#
+Index: src/binutils/objcopy.c
+===================================================================
+--- src.orig/binutils/objcopy.c 2007-08-09 13:26:03.000000000 +0100
++++ src/binutils/objcopy.c 2007-08-09 16:36:12.000000000 +0100
+@@ -2787,8 +2787,9 @@ strip_main (int argc, char *argv[])
+ if (preserve_dates)
+ set_times (tmpname, &statbuf);
+ if (output_file != tmpname)
+- smart_rename (tmpname, output_file ? output_file : argv[i],
+- preserve_dates);
++ if (smart_rename (tmpname, output_file ? output_file : argv[i],
++ preserve_dates))
++ hold_status = 1;
+ status = hold_status;
+ }
+ else
+@@ -3411,7 +3412,8 @@ copy_main (int argc, char *argv[])
+ if (preserve_dates)
+ set_times (tmpname, &statbuf);
+ if (tmpname != output_filename)
+- smart_rename (tmpname, input_filename, preserve_dates);
++ if (smart_rename (tmpname, input_filename, preserve_dates))
++ status = 1;
+ }
+ else
+ unlink_if_ordinary (tmpname);
--- /dev/null
+Index: binutils/bfd/elf32-arm.c
+===================================================================
+RCS file: /cvs/src/src/bfd/elf32-arm.c,v
+retrieving revision 1.162
+retrieving revision 1.163
+diff -u -r1.162 -r1.163
+--- binutils/bfd/elf32-arm.c 23 Dec 2008 09:01:45 -0000 1.162
++++ binutils/bfd/elf32-arm.c 23 Dec 2008 11:46:17 -0000 1.163
+@@ -4608,6 +4608,10 @@
+ Elf_Internal_Shdr *hdr;
+ unsigned int i, localsyms;
+
++ /* PR 7093: Make sure that we are dealing with an arm elf binary. */
++ if (! is_arm_elf (abfd))
++ return;
++
+ if ((abfd->flags & DYNAMIC) != 0)
+ return;
+
--- /dev/null
+--- binutils-2.18.orig/configure
++++ binutils-2.18/configure
+@@ -2206,7 +2206,7 @@
+ am33_2.0-*-linux*)
+ noconfigdirs="$noconfigdirs ${libgcj} target-newlib target-libgloss"
+ ;;
+- sh-*-linux*)
++ sh*-*-linux*)
+ noconfigdirs="$noconfigdirs ${libgcj} target-newlib target-libgloss"
+ ;;
+ sh*-*-pe|mips*-*-pe|*arm-wince-pe)
+@@ -2504,7 +2504,7 @@
+ romp-*-*)
+ noconfigdirs="$noconfigdirs bfd binutils ld gas opcodes target-libgloss ${libgcj}"
+ ;;
+- sh-*-* | sh64-*-*)
++ sh*-*-* | sh64-*-*)
+ case "${host}" in
+ i[3456789]86-*-vsta) ;; # don't add gprof back in
+ i[3456789]86-*-go32*) ;; # don't add gprof back in
+--- binutils-2.18.orig/gprof/configure
++++ binutils-2.18/gprof/configure
+@@ -4124,6 +4124,11 @@
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
++linux-uclibc*)
++ lt_cv_deplibs_check_method=pass_all
++ lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so`
++ ;;
++
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
--- /dev/null
+#!/bin/sh -e
+## 001_ld_makefile_patch.dpatch
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Description: correct where ld scripts are installed
+## DP: Author: Chris Chimelis <chris@debian.org>
+## DP: Upstream status: N/A
+## DP: Date: ??
+
+if [ $# -ne 1 ]; then
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch}"
+
+case "$1" in
+ -patch) patch $patch_opts -p1 < $0;;
+ -unpatch) patch $patch_opts -p1 -R < $0;;
+ *)
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1;;
+esac
+
+exit 0
+
+@DPATCH@
+--- binutils-2.16.91.0.1/ld/Makefile.am
++++ binutils-2.16.91.0.1/ld/Makefile.am
+@@ -20,7 +20,7 @@
+ # We put the scripts in the directory $(scriptdir)/ldscripts.
+ # We can't put the scripts in $(datadir) because the SEARCH_DIR
+ # directives need to be different for native and cross linkers.
+-scriptdir = $(tooldir)/lib
++scriptdir = $(libdir)
+
+ EMUL = @EMUL@
+ EMULATION_OFILES = @EMULATION_OFILES@
+--- binutils-2.16.91.0.1/ld/Makefile.in
++++ binutils-2.16.91.0.1/ld/Makefile.in
+@@ -268,7 +268,7 @@
+ # We put the scripts in the directory $(scriptdir)/ldscripts.
+ # We can't put the scripts in $(datadir) because the SEARCH_DIR
+ # directives need to be different for native and cross linkers.
+-scriptdir = $(tooldir)/lib
++scriptdir = $(libdir)
+ BASEDIR = $(srcdir)/..
+ BFDDIR = $(BASEDIR)/bfd
+ INCDIR = $(BASEDIR)/include
--- /dev/null
+#!/bin/sh -e
+## 006_better_file_error.dpatch by David Kimdon <dwhedon@gordian.com>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Specify which filename is causing an error if the filename is a
+## DP: directory. (#45832)
+
+if [ $# -ne 1 ]; then
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch}"
+
+case "$1" in
+ -patch) patch $patch_opts -p1 < $0;;
+ -unpatch) patch $patch_opts -p1 -R < $0;;
+ *)
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1;;
+esac
+
+exit 0
+
+@DPATCH@
+diff -urNad /home/james/debian/packages/binutils/binutils-2.14.90.0.6/bfd/opncls.c binutils-2.14.90.0.6/bfd/opncls.c
+--- /home/james/debian/packages/binutils/binutils-2.14.90.0.6/bfd/opncls.c 2003-07-23 16:08:09.000000000 +0100
++++ binutils-2.14.90.0.6/bfd/opncls.c 2003-09-10 22:35:00.000000000 +0100
+@@ -150,6 +150,13 @@
+ {
+ bfd *nbfd;
+ const bfd_target *target_vec;
++ struct stat s;
++
++ if (stat (filename, &s) == 0)
++ if (S_ISDIR(s.st_mode)) {
++ bfd_set_error (bfd_error_file_not_recognized);
++ return NULL;
++ }
+
+ nbfd = _bfd_new_bfd ();
+ if (nbfd == NULL)
--- /dev/null
+#!/bin/sh -e
+## 012_check_ldrunpath_length.dpatch by Chris Chimelis <chris@debian.org>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Only generate an RPATH entry if LD_RUN_PATH is not empty, for
+## DP: cases where -rpath isn't specified. (#151024)
+
+if [ $# -ne 1 ]; then
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch}"
+
+case "$1" in
+ -patch) patch $patch_opts -p1 < $0;;
+ -unpatch) patch $patch_opts -p1 -R < $0;;
+ *)
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1;;
+esac
+
+exit 0
+
+@DPATCH@
+diff -urNad /home/james/debian/packages/binutils/new/binutils-2.15/ld/emultempl/elf32.em binutils-2.15/ld/emultempl/elf32.em
+--- /home/james/debian/packages/binutils/new/binutils-2.15/ld/emultempl/elf32.em 2004-05-21 23:12:58.000000000 +0100
++++ binutils-2.15/ld/emultempl/elf32.em 2004-05-21 23:12:59.000000000 +0100
+@@ -692,6 +692,8 @@
+ && command_line.rpath == NULL)
+ {
+ lib_path = (const char *) getenv ("LD_RUN_PATH");
++ if ((lib_path) && (strlen (lib_path) == 0))
++ lib_path = NULL;
+ if (gld${EMULATION_NAME}_search_needed (lib_path, &n,
+ force))
+ break;
+@@ -871,6 +873,8 @@
+ rpath = command_line.rpath;
+ if (rpath == NULL)
+ rpath = (const char *) getenv ("LD_RUN_PATH");
++ if ((rpath) && (strlen (rpath) == 0))
++ rpath = NULL;
+ if (! (bfd_elf_size_dynamic_sections
+ (output_bfd, command_line.soname, rpath,
+ command_line.filter_shlib,
--- /dev/null
+Source: Khem Raj <raj.khem@gmail.com>
+Disposition: submit upstream.
+
+Description:
+
+We do not need to have the libtool patch anymore for binutils after
+libtool has been updated upstream it include support for it. However
+for building gas natively on uclibc systems we have to link it with
+-lm so that it picks up missing symbols.
+
+/local/build_area/BUILD/arm_v5t_le_uclibc/binutils-2.17.50/objdir/libiberty/pic/libiberty.a(floatformat.o): In function `floatformat_from_double':
+floatformat.c:(.text+0x1ec): undefined reference to `frexp'
+floatformat.c:(.text+0x2f8): undefined reference to `ldexp'
+/local/build_area/BUILD/arm_v5t_le_uclibc/binutils-2.17.50/objdir/libiberty/pic/libiberty.a(floatformat.o): In function `floatformat_to_double':
+floatformat.c:(.text+0x38a): undefined reference to `ldexp'
+floatformat.c:(.text+0x3d2): undefined reference to `ldexp'
+floatformat.c:(.text+0x43e): undefined reference to `ldexp' floatformat.c:(.text+0x4e2): undefined reference to `ldexp'
+collect2: ld returned 1 exit status
+make[4]: *** [as-new] Error 1
+
+Index: binutils-2.17.50/gas/configure.tgt
+===================================================================
+--- binutils-2.17.50.orig/gas/configure.tgt
++++ binutils-2.17.50/gas/configure.tgt
+@@ -408,6 +408,12 @@ case ${generic_target} in
+ *-*-netware) fmt=elf em=netware ;;
+ esac
+
++case ${generic_target} in
++ arm-*-*uclibc*)
++ need_libm=yes
++ ;;
++esac
++
+ case ${cpu_type} in
+ alpha | arm | i386 | ia64 | mips | ns32k | pdp11 | ppc | sparc | z80 | z8k)
+ bfd_gas=yes
+
--- /dev/null
+require binutils_${PV}.bb
+require binutils-cross-sdk.inc
+PR = "r0"
--- /dev/null
+FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/binutils-${PV}"
+require binutils_${PV}.bb
+require binutils-cross.inc
+
--- /dev/null
+PR = "r0"
+
+require binutils.inc
+
+SRC_URI = "\
+ ${GNU_MIRROR}/binutils/binutils-${PV}.tar.bz2 \
+ file://binutils-2.16.91.0.6-objcopy-rename-errorcode.patch;patch=1 \
+ file://binutils-uclibc-100-uclibc-conf.patch;patch=1 \
+ file://110-arm-eabi-conf.patch;patch=1 \
+ file://binutils-uclibc-300-001_ld_makefile_patch.patch;patch=1 \
+ file://binutils-uclibc-300-006_better_file_error.patch;patch=1 \
+ file://binutils-uclibc-300-012_check_ldrunpath_length.patch;patch=1 \
+ file://binutils-uclibc-gas-needs-libm.patch;patch=1 \
+ file://binutils-arm-pr7093.patch;patch=1 \
+ "
+
+# powerpc patches
+SRC_URI += "file://binutils-2.16.1-e300c2c3.patch;patch=1"
+
--- /dev/null
+Index: bluez-4.27/tools/dfutool.c
+===================================================================
+--- bluez-4.27.orig/tools/dfutool.c
++++ bluez-4.27/tools/dfutool.c
+@@ -59,7 +59,7 @@
+ #endif
+
+ #ifdef NEED_USB_GET_BUSSES
+-static inline struct usb_bus *usb_get_busses(void)
++inline struct usb_bus *usb_get_busses(void)
+ {
+ return usb_busses;
+ }
+++ /dev/null
-DESCRIPTION = "Linux Bluetooth Stack Userland V4"
-SECTION = "libs"
-PRIORITY = "optional"
-DEPENDS = "gst-plugins-base alsa-lib libusb-compat libusb1 dbus-glib"
-HOMEPAGE = "http://www.bluez.org"
-LICENSE = "GPL"
-PR = "r1"
-
-SRC_URI = "\
- http://www.kernel.org/pub/linux/bluetooth/bluez-${PV}.tar.gz \
- file://sbc-thumb.patch;patch=1 \
- file://hid2hci_usb_init.patch;patch=1 \
-"
-S = "${WORKDIR}/bluez-${PV}"
-
-inherit autotools pkgconfig
-
-OE_LT_RPATH_ALLOW = "any"
-OE_LT_RPATH_ALLOW[export] = "1"
-
-EXTRA_OECONF = "\
- --enable-gstreamer \
- --enable-alsa \
- --disable-usb \
- --enable-netlink \
- --enable-tools \
- --enable-bccmd \
- --enable-hid2hci \
- --enable-dfutool \
- --enable-hidd \
- --enable-pandd \
- --enable-dund \
- --disable-cups \
- --enable-test \
- --enable-manpages \
- --enable-configfiles \
- --enable-initscripts \
- --disable-pcmciarules \
-"
-
-PACKAGES =+ "gst-plugin-bluez libasound-module-bluez"
-
-FILES_gst-plugin-bluez = "${libdir}/gstreamer-0.10/lib*.so"
-FILES_libasound-module-bluez = "${libdir}/alsa-lib/lib*.so"
-FILES_${PN} += "${libdir}/bluetooth/plugins/*.so"
-FILES_${PN}-dev += "\
- ${libdir}/bluetooth/plugins/*.la \
- ${libdir}/*/*.la \
-"
-FILES_${PN}-dbg += "\
- ${libdir}/bluetooth/plugins/.debug \
- ${libdir}/*/.debug \
-"
--- /dev/null
+DESCRIPTION = "Linux Bluetooth Stack Userland V4"
+SECTION = "libs"
+PRIORITY = "optional"
+DEPENDS = "gst-plugins-base alsa-lib libusb-compat libusb1 dbus-glib"
+HOMEPAGE = "http://www.bluez.org"
+LICENSE = "GPL"
+PR = "r2"
+
+SRC_URI = "\
+ http://www.kernel.org/pub/linux/bluetooth/bluez-${PV}.tar.gz \
+ file://fix-dfutool-usb-declaration-mismatch.patch;patch=1 \
+ file://sbc-thumb.patch;patch=1 \
+ file://hid2hci_usb_init.patch;patch=1 \
+"
+S = "${WORKDIR}/bluez-${PV}"
+
+inherit autotools pkgconfig
+
+OE_LT_RPATH_ALLOW = "any"
+OE_LT_RPATH_ALLOW[export] = "1"
+
+EXTRA_OECONF = "\
+ --enable-gstreamer \
+ --enable-alsa \
+ --disable-usb \
+ --enable-netlink \
+ --enable-tools \
+ --enable-bccmd \
+ --enable-hid2hci \
+ --enable-dfutool \
+ --enable-hidd \
+ --enable-pandd \
+ --enable-dund \
+ --disable-cups \
+ --enable-test \
+ --enable-manpages \
+ --enable-configfiles \
+ --enable-initscripts \
+ --disable-pcmciarules \
+"
+
+PACKAGES =+ "gst-plugin-bluez libasound-module-bluez"
+
+FILES_gst-plugin-bluez = "${libdir}/gstreamer-0.10/lib*.so"
+FILES_libasound-module-bluez = "${libdir}/alsa-lib/lib*.so"
+FILES_${PN} += "${libdir}/bluetooth/plugins/*.so"
+FILES_${PN}-dev += "\
+ ${libdir}/bluetooth/plugins/*.la \
+ ${libdir}/*/*.la \
+"
+FILES_${PN}-dbg += "\
+ ${libdir}/bluetooth/plugins/.debug \
+ ${libdir}/*/.debug \
+"
LICENSE="GPL"
-SRC_URI="http://www.coker.com.au/bonnie++/${PN}-${PV}.tgz"
+SRC_URI="http://www.coker.com.au/bonnie++/${PN}-${PV}.tgz \
+ file://gcc-4.3-fixes.patch;patch=1"
inherit autotools
--- /dev/null
+---
+ zcav.cpp | 1 +
+ 1 file changed, 1 insertion(+)
+
+Index: bonnie++-1.03a/zcav.cpp
+===================================================================
+--- bonnie++-1.03a.orig/zcav.cpp
++++ bonnie++-1.03a/zcav.cpp
+@@ -15,6 +15,7 @@ using namespace std;
+ #else
+ #include <vector.h>
+ #endif
++#include <string.h>
+
+ // Read the specified number of megabytes of data from the fd and return the
+ // amount of time elapsed in seconds.
DEPENDS = "boost-jam-native zlib"
PRIORITY = "optional"
LICENSE = "Boost Software License"
-PR = "r1"
+PR = "r2"
BOOST_VER = "${@"_".join(bb.data.getVar("PV",d,1).split("."))}"
BOOST_MAJ = "${@"_".join(bb.data.getVar("PV",d,1).split(".")[0:2])}"
PACKAGES += "${PN}"
RRECOMMENDS_${PN} += "${BOOST_PACKAGES}"
+# to avoid GNU_HASH QA errors added LDFLAGS to ARCH; a little bit dirty but at least it works
+TARGET_CC_ARCH += " ${LDFLAGS}"
+
# Oh yippee, a new build system, it's sooo cooool I could eat my own
# foot. inlining=on lets the compiler choose, I think. At least this
# stuff is documented...
include boost-36.inc
-DEFAULT_PREFERENCE = "-1"
-
-PR = "r4"
+PR = "r5"
SRC_URI = "${SOURCEFORGE_MIRROR}/boost/${BOOST_P}.tar.bz2 \
file://arm-intrinsics.patch;patch=1 \
#
# Automatically generated make config: don't edit
# Busybox version: 1.13.2
-# Fri Jan 23 17:02:44 2009
+# Sun Feb 8 17:22:39 2009
#
CONFIG_HAVE_DOT_CONFIG=y
# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set
# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set
CONFIG_SHOW_USAGE=y
-# CONFIG_FEATURE_VERBOSE_USAGE is not set
+CONFIG_FEATURE_VERBOSE_USAGE=y
CONFIG_FEATURE_COMPRESS_USAGE=y
# CONFIG_FEATURE_INSTALLER is not set
CONFIG_LOCALE_SUPPORT=y
CONFIG_FEATURE_EDITING=y
CONFIG_FEATURE_EDITING_MAX_LEN=1024
# CONFIG_FEATURE_EDITING_VI is not set
-CONFIG_FEATURE_EDITING_HISTORY=15
+CONFIG_FEATURE_EDITING_HISTORY=64
CONFIG_FEATURE_EDITING_SAVEHISTORY=y
CONFIG_FEATURE_TAB_COMPLETION=y
CONFIG_FEATURE_USERNAME_COMPLETION=y
CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY=y
# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set
CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y
-# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set
+CONFIG_FEATURE_TAR_LONG_OPTIONS=y
CONFIG_FEATURE_TAR_UNAME_GNAME=y
# CONFIG_UNCOMPRESS is not set
# CONFIG_UNLZMA is not set
CONFIG_FEATURE_DD_SIGNAL_HANDLING=y
# CONFIG_FEATURE_DD_IBS_OBS is not set
CONFIG_DF=y
-# CONFIG_FEATURE_DF_FANCY is not set
+CONFIG_FEATURE_DF_FANCY=y
CONFIG_DIRNAME=y
# CONFIG_DOS2UNIX is not set
# CONFIG_UNIX2DOS is not set
CONFIG_FALSE=y
# CONFIG_FOLD is not set
CONFIG_HEAD=y
-# CONFIG_FEATURE_FANCY_HEAD is not set
+CONFIG_FEATURE_FANCY_HEAD=y
# CONFIG_HOSTID is not set
CONFIG_ID=y
# CONFIG_INSTALL is not set
CONFIG_MKFIFO=y
CONFIG_MKNOD=y
CONFIG_MV=y
-# CONFIG_FEATURE_MV_LONG_OPTIONS is not set
-# CONFIG_NICE is not set
+CONFIG_FEATURE_MV_LONG_OPTIONS=y
+CONFIG_NICE=y
CONFIG_NOHUP=y
CONFIG_OD=y
# CONFIG_PRINTENV is not set
CONFIG_REALPATH=y
CONFIG_RM=y
CONFIG_RMDIR=y
-# CONFIG_FEATURE_RMDIR_LONG_OPTIONS is not set
+CONFIG_FEATURE_RMDIR_LONG_OPTIONS=y
CONFIG_SEQ=y
# CONFIG_SHA1SUM is not set
CONFIG_SLEEP=y
CONFIG_TAIL=y
CONFIG_FEATURE_FANCY_TAIL=y
CONFIG_TEE=y
-# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set
+CONFIG_FEATURE_TEE_USE_BLOCK_IO=y
CONFIG_TEST=y
# CONFIG_FEATURE_TEST_64 is not set
CONFIG_TOUCH=y
CONFIG_FEATURE_FIND_XDEV=y
CONFIG_FEATURE_FIND_MAXDEPTH=y
CONFIG_FEATURE_FIND_NEWER=y
-# CONFIG_FEATURE_FIND_INUM is not set
+CONFIG_FEATURE_FIND_INUM=y
CONFIG_FEATURE_FIND_EXEC=y
CONFIG_FEATURE_FIND_USER=y
CONFIG_FEATURE_FIND_GROUP=y
CONFIG_FEATURE_FIND_PAREN=y
CONFIG_FEATURE_FIND_SIZE=y
CONFIG_FEATURE_FIND_PRUNE=y
-# CONFIG_FEATURE_FIND_DELETE is not set
+CONFIG_FEATURE_FIND_DELETE=y
CONFIG_FEATURE_FIND_PATH=y
CONFIG_FEATURE_FIND_REGEX=y
# CONFIG_FEATURE_FIND_CONTEXT is not set
CONFIG_XARGS=y
# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set
CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y
-# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set
-# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set
+CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y
+CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y
#
# Init Utilities
CONFIG_INSMOD=y
CONFIG_RMMOD=y
CONFIG_LSMOD=y
-# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set
+CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT=y
CONFIG_MODPROBE=y
CONFIG_FEATURE_MODPROBE_BLACKLIST=y
# CONFIG_DEPMOD is not set
CONFIG_FEATURE_OSF_LABEL=y
CONFIG_FEATURE_FDISK_ADVANCED=y
# CONFIG_FINDFS is not set
-# CONFIG_FREERAMDISK is not set
+CONFIG_FREERAMDISK=y
CONFIG_FSCK_MINIX=y
CONFIG_MKFS_MINIX=y
# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set
CONFIG_MOUNT=y
# CONFIG_FEATURE_MOUNT_FAKE is not set
-# CONFIG_FEATURE_MOUNT_VERBOSE is not set
+CONFIG_FEATURE_MOUNT_VERBOSE=y
CONFIG_FEATURE_MOUNT_HELPERS=y
CONFIG_FEATURE_MOUNT_LABEL=y
CONFIG_FEATURE_MOUNT_NFS=y
CONFIG_RDATE=y
CONFIG_RDEV=y
CONFIG_READPROFILE=y
-# CONFIG_RTCWAKE is not set
+CONFIG_RTCWAKE=y
# CONFIG_SCRIPT is not set
# CONFIG_SETARCH is not set
CONFIG_SWAPONOFF=y
# CONFIG_DEVMEM is not set
# CONFIG_EJECT is not set
# CONFIG_FEATURE_EJECT_SCSI is not set
-# CONFIG_FBSPLASH is not set
+CONFIG_FBSPLASH=y
# CONFIG_INOTIFYD is not set
-# CONFIG_LAST is not set
-# CONFIG_FEATURE_LAST_SMALL is not set
+CONFIG_LAST=y
+CONFIG_FEATURE_LAST_SMALL=y
# CONFIG_FEATURE_LAST_FANCY is not set
CONFIG_LESS=y
CONFIG_FEATURE_LESS_MAXLINES=9999999
# CONFIG_FEATURE_MAKEDEVS_LEAF is not set
CONFIG_FEATURE_MAKEDEVS_TABLE=y
# CONFIG_MAN is not set
-# CONFIG_MICROCOM is not set
+CONFIG_MICROCOM=y
# CONFIG_MOUNTPOINT is not set
# CONFIG_MT is not set
# CONFIG_RAIDAUTORUN is not set
# CONFIG_FTPPUT is not set
# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set
CONFIG_HOSTNAME=y
-# CONFIG_HTTPD is not set
-# CONFIG_FEATURE_HTTPD_RANGES is not set
-# CONFIG_FEATURE_HTTPD_USE_SENDFILE is not set
-# CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP is not set
-# CONFIG_FEATURE_HTTPD_SETUID is not set
-# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set
-# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set
-# CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES is not set
-# CONFIG_FEATURE_HTTPD_CGI is not set
-# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set
-# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set
-# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set
-# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set
-# CONFIG_FEATURE_HTTPD_PROXY is not set
+CONFIG_HTTPD=y
+CONFIG_FEATURE_HTTPD_RANGES=y
+CONFIG_FEATURE_HTTPD_USE_SENDFILE=y
+CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP=y
+CONFIG_FEATURE_HTTPD_SETUID=y
+CONFIG_FEATURE_HTTPD_BASIC_AUTH=y
+CONFIG_FEATURE_HTTPD_AUTH_MD5=y
+CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES=y
+CONFIG_FEATURE_HTTPD_CGI=y
+CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR=y
+CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV=y
+CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y
+CONFIG_FEATURE_HTTPD_ERROR_PAGES=y
+CONFIG_FEATURE_HTTPD_PROXY=y
CONFIG_IFCONFIG=y
CONFIG_FEATURE_IFCONFIG_STATUS=y
# CONFIG_FEATURE_IFCONFIG_SLIP is not set
# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set
CONFIG_FEATURE_IFCONFIG_HW=y
-# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set
+CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS=y
# CONFIG_IFENSLAVE is not set
CONFIG_IFUPDOWN=y
CONFIG_IFUPDOWN_IFSTATE_PATH="/var/run/ifstate"
CONFIG_NC_SERVER=y
CONFIG_NC_EXTRA=y
CONFIG_NETSTAT=y
-# CONFIG_FEATURE_NETSTAT_WIDE is not set
-# CONFIG_FEATURE_NETSTAT_PRG is not set
+CONFIG_FEATURE_NETSTAT_WIDE=y
+CONFIG_FEATURE_NETSTAT_PRG=y
CONFIG_NSLOOKUP=y
CONFIG_PING=y
CONFIG_PING6=y
# CONFIG_TFTP_DEBUG is not set
CONFIG_TRACEROUTE=y
CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
-# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
-# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
+CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE=y
+CONFIG_FEATURE_TRACEROUTE_USE_ICMP=y
CONFIG_APP_UDHCPD=y
-# CONFIG_APP_DHCPRELAY is not set
+CONFIG_APP_DHCPRELAY=y
CONFIG_APP_DUMPLEASES=y
# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set
CONFIG_DHCPD_LEASES_FILE="/var/lib/misc/udhcpd.leases"
CONFIG_ASH_MATH_SUPPORT=y
# CONFIG_ASH_MATH_SUPPORT_64 is not set
CONFIG_ASH_GETOPTS=y
-# CONFIG_ASH_BUILTIN_ECHO is not set
+CONFIG_ASH_BUILTIN_ECHO=y
CONFIG_ASH_BUILTIN_PRINTF=y
CONFIG_ASH_BUILTIN_TEST=y
# CONFIG_ASH_CMDCMD is not set
# CONFIG_ASH_MAIL is not set
-CONFIG_ASH_OPTIMIZE_FOR_SIZE=y
+# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set
# CONFIG_ASH_RANDOM_SUPPORT is not set
CONFIG_ASH_EXPAND_PRMT=y
# CONFIG_HUSH is not set
#
# Automatically generated make config: don't edit
# Busybox version: 1.13.2
-# Fri Jan 23 16:57:40 2009
+# Sun Feb 8 17:22:39 2009
#
CONFIG_HAVE_DOT_CONFIG=y
# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set
# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set
CONFIG_SHOW_USAGE=y
-# CONFIG_FEATURE_VERBOSE_USAGE is not set
+CONFIG_FEATURE_VERBOSE_USAGE=y
CONFIG_FEATURE_COMPRESS_USAGE=y
# CONFIG_FEATURE_INSTALLER is not set
CONFIG_LOCALE_SUPPORT=y
CONFIG_FEATURE_EDITING=y
CONFIG_FEATURE_EDITING_MAX_LEN=1024
# CONFIG_FEATURE_EDITING_VI is not set
-CONFIG_FEATURE_EDITING_HISTORY=15
+CONFIG_FEATURE_EDITING_HISTORY=64
CONFIG_FEATURE_EDITING_SAVEHISTORY=y
CONFIG_FEATURE_TAB_COMPLETION=y
CONFIG_FEATURE_USERNAME_COMPLETION=y
CONFIG_FEATURE_TAR_CREATE=y
CONFIG_FEATURE_TAR_AUTODETECT=y
CONFIG_FEATURE_TAR_FROM=y
-# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set
+CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY=y
# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set
CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y
-# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set
+CONFIG_FEATURE_TAR_LONG_OPTIONS=y
CONFIG_FEATURE_TAR_UNAME_GNAME=y
# CONFIG_UNCOMPRESS is not set
# CONFIG_UNLZMA is not set
CONFIG_CP=y
CONFIG_CUT=y
CONFIG_DATE=y
-# CONFIG_FEATURE_DATE_ISOFMT is not set
+CONFIG_FEATURE_DATE_ISOFMT=y
CONFIG_DD=y
CONFIG_FEATURE_DD_SIGNAL_HANDLING=y
# CONFIG_FEATURE_DD_IBS_OBS is not set
CONFIG_DF=y
-# CONFIG_FEATURE_DF_FANCY is not set
+CONFIG_FEATURE_DF_FANCY=y
CONFIG_DIRNAME=y
# CONFIG_DOS2UNIX is not set
# CONFIG_UNIX2DOS is not set
CONFIG_FALSE=y
# CONFIG_FOLD is not set
CONFIG_HEAD=y
-# CONFIG_FEATURE_FANCY_HEAD is not set
+CONFIG_FEATURE_FANCY_HEAD=y
# CONFIG_HOSTID is not set
CONFIG_ID=y
# CONFIG_INSTALL is not set
CONFIG_MKFIFO=y
CONFIG_MKNOD=y
CONFIG_MV=y
-# CONFIG_FEATURE_MV_LONG_OPTIONS is not set
-# CONFIG_NICE is not set
+CONFIG_FEATURE_MV_LONG_OPTIONS=y
+CONFIG_NICE=y
CONFIG_NOHUP=y
CONFIG_OD=y
# CONFIG_PRINTENV is not set
CONFIG_REALPATH=y
CONFIG_RM=y
CONFIG_RMDIR=y
-# CONFIG_FEATURE_RMDIR_LONG_OPTIONS is not set
+CONFIG_FEATURE_RMDIR_LONG_OPTIONS=y
CONFIG_SEQ=y
# CONFIG_SHA1SUM is not set
CONFIG_SLEEP=y
CONFIG_TAIL=y
CONFIG_FEATURE_FANCY_TAIL=y
CONFIG_TEE=y
-# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set
+CONFIG_FEATURE_TEE_USE_BLOCK_IO=y
CONFIG_TEST=y
# CONFIG_FEATURE_TEST_64 is not set
CONFIG_TOUCH=y
# CONFIG_PIPE_PROGRESS is not set
CONFIG_RUN_PARTS=y
CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS=y
-# CONFIG_FEATURE_RUN_PARTS_FANCY is not set
+CONFIG_FEATURE_RUN_PARTS_FANCY=y
CONFIG_START_STOP_DAEMON=y
CONFIG_FEATURE_START_STOP_DAEMON_FANCY=y
CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS=y
CONFIG_DIFF=y
CONFIG_FEATURE_DIFF_BINARY=y
CONFIG_FEATURE_DIFF_DIR=y
-# CONFIG_FEATURE_DIFF_MINIMAL is not set
+CONFIG_FEATURE_DIFF_MINIMAL=y
# CONFIG_ED is not set
CONFIG_PATCH=y
CONFIG_SED=y
CONFIG_FEATURE_VI_YANKMARK=y
CONFIG_FEATURE_VI_SEARCH=y
CONFIG_FEATURE_VI_USE_SIGNALS=y
-# CONFIG_FEATURE_VI_DOT_CMD is not set
+CONFIG_FEATURE_VI_DOT_CMD=y
# CONFIG_FEATURE_VI_READONLY is not set
# CONFIG_FEATURE_VI_SETOPTS is not set
-# CONFIG_FEATURE_VI_SET is not set
+CONFIG_FEATURE_VI_SET=y
CONFIG_FEATURE_VI_WIN_RESIZE=y
CONFIG_FEATURE_VI_OPTIMIZE_CURSOR=y
CONFIG_FEATURE_ALLOW_EXEC=y
CONFIG_FEATURE_FIND_XDEV=y
CONFIG_FEATURE_FIND_MAXDEPTH=y
CONFIG_FEATURE_FIND_NEWER=y
-# CONFIG_FEATURE_FIND_INUM is not set
+CONFIG_FEATURE_FIND_INUM=y
CONFIG_FEATURE_FIND_EXEC=y
CONFIG_FEATURE_FIND_USER=y
CONFIG_FEATURE_FIND_GROUP=y
CONFIG_FEATURE_FIND_PAREN=y
CONFIG_FEATURE_FIND_SIZE=y
CONFIG_FEATURE_FIND_PRUNE=y
-# CONFIG_FEATURE_FIND_DELETE is not set
+CONFIG_FEATURE_FIND_DELETE=y
CONFIG_FEATURE_FIND_PATH=y
CONFIG_FEATURE_FIND_REGEX=y
# CONFIG_FEATURE_FIND_CONTEXT is not set
CONFIG_FEATURE_GREP_CONTEXT=y
CONFIG_XARGS=y
# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set
-# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set
-# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set
-# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set
+CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y
+CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y
+CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y
#
# Init Utilities
#
-# CONFIG_INIT is not set
-# CONFIG_FEATURE_USE_INITTAB is not set
-# CONFIG_FEATURE_KILL_REMOVED is not set
+CONFIG_INIT=y
+CONFIG_FEATURE_USE_INITTAB=y
+CONFIG_FEATURE_KILL_REMOVED=y
CONFIG_FEATURE_KILL_DELAY=0
# CONFIG_FEATURE_INIT_SCTTY is not set
# CONFIG_FEATURE_INIT_SYSLOG is not set
# CONFIG_FEATURE_EXTRA_QUIET is not set
# CONFIG_FEATURE_INIT_COREDUMPS is not set
-# CONFIG_FEATURE_INITRD is not set
-# CONFIG_HALT is not set
+CONFIG_FEATURE_INITRD=y
+CONFIG_HALT=y
# CONFIG_MESG is not set
#
# Login/Password Management Utilities
#
-# CONFIG_FEATURE_SHADOWPASSWDS is not set
+CONFIG_FEATURE_SHADOWPASSWDS=y
# CONFIG_USE_BB_PWD_GRP is not set
# CONFIG_USE_BB_SHADOW is not set
CONFIG_USE_BB_CRYPT=y
-# CONFIG_ADDGROUP is not set
-# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set
-# CONFIG_DELGROUP is not set
-# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set
-# CONFIG_FEATURE_CHECK_NAMES is not set
-# CONFIG_ADDUSER is not set
-# CONFIG_FEATURE_ADDUSER_LONG_OPTIONS is not set
-# CONFIG_DELUSER is not set
-# CONFIG_GETTY is not set
+CONFIG_ADDGROUP=y
+CONFIG_FEATURE_ADDUSER_TO_GROUP=y
+CONFIG_DELGROUP=y
+CONFIG_FEATURE_DEL_USER_FROM_GROUP=y
+CONFIG_FEATURE_CHECK_NAMES=y
+CONFIG_ADDUSER=y
+CONFIG_FEATURE_ADDUSER_LONG_OPTIONS=y
+CONFIG_DELUSER=y
+CONFIG_GETTY=y
CONFIG_FEATURE_UTMP=y
-# CONFIG_FEATURE_WTMP is not set
-# CONFIG_LOGIN is not set
+CONFIG_FEATURE_WTMP=y
+CONFIG_LOGIN=y
# CONFIG_PAM is not set
-# CONFIG_LOGIN_SCRIPTS is not set
-# CONFIG_FEATURE_NOLOGIN is not set
-# CONFIG_FEATURE_SECURETTY is not set
-# CONFIG_PASSWD is not set
-# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set
-# CONFIG_CRYPTPW is not set
-# CONFIG_CHPASSWD is not set
-# CONFIG_SU is not set
-# CONFIG_FEATURE_SU_SYSLOG is not set
-# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set
-# CONFIG_SULOGIN is not set
-# CONFIG_VLOCK is not set
+CONFIG_LOGIN_SCRIPTS=y
+CONFIG_FEATURE_NOLOGIN=y
+CONFIG_FEATURE_SECURETTY=y
+CONFIG_PASSWD=y
+CONFIG_FEATURE_PASSWD_WEAK_CHECK=y
+CONFIG_CRYPTPW=y
+CONFIG_CHPASSWD=y
+CONFIG_SU=y
+CONFIG_FEATURE_SU_SYSLOG=y
+CONFIG_FEATURE_SU_CHECKS_SHELLS=y
+CONFIG_SULOGIN=y
+CONFIG_VLOCK=y
#
# Linux Ext2 FS Progs
CONFIG_INSMOD=y
CONFIG_RMMOD=y
CONFIG_LSMOD=y
-# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set
+CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT=y
CONFIG_MODPROBE=y
CONFIG_FEATURE_MODPROBE_BLACKLIST=y
# CONFIG_DEPMOD is not set
# CONFIG_FEATURE_AIX_LABEL is not set
# CONFIG_FEATURE_SGI_LABEL is not set
# CONFIG_FEATURE_SUN_LABEL is not set
-# CONFIG_FEATURE_OSF_LABEL is not set
-# CONFIG_FEATURE_FDISK_ADVANCED is not set
+CONFIG_FEATURE_OSF_LABEL=y
+CONFIG_FEATURE_FDISK_ADVANCED=y
# CONFIG_FINDFS is not set
-# CONFIG_FREERAMDISK is not set
+CONFIG_FREERAMDISK=y
CONFIG_FSCK_MINIX=y
CONFIG_MKFS_MINIX=y
# Minix filesystem support
#
CONFIG_FEATURE_MINIX2=y
-# CONFIG_GETOPT is not set
+CONFIG_GETOPT=y
CONFIG_HEXDUMP=y
# CONFIG_FEATURE_HEXDUMP_REVERSE is not set
# CONFIG_HD is not set
# CONFIG_IPCRM is not set
# CONFIG_IPCS is not set
CONFIG_LOSETUP=y
-# CONFIG_MDEV is not set
-# CONFIG_FEATURE_MDEV_CONF is not set
-# CONFIG_FEATURE_MDEV_RENAME is not set
-# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set
-# CONFIG_FEATURE_MDEV_EXEC is not set
-# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set
+CONFIG_MDEV=y
+CONFIG_FEATURE_MDEV_CONF=y
+CONFIG_FEATURE_MDEV_RENAME=y
+CONFIG_FEATURE_MDEV_RENAME_REGEXP=y
+CONFIG_FEATURE_MDEV_EXEC=y
+CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y
CONFIG_MKSWAP=y
# CONFIG_FEATURE_MKSWAP_V0 is not set
CONFIG_MORE=y
# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set
CONFIG_MOUNT=y
# CONFIG_FEATURE_MOUNT_FAKE is not set
-# CONFIG_FEATURE_MOUNT_VERBOSE is not set
+CONFIG_FEATURE_MOUNT_VERBOSE=y
CONFIG_FEATURE_MOUNT_HELPERS=y
CONFIG_FEATURE_MOUNT_LABEL=y
CONFIG_FEATURE_MOUNT_NFS=y
CONFIG_PIVOT_ROOT=y
CONFIG_RDATE=y
CONFIG_RDEV=y
-# CONFIG_READPROFILE is not set
-# CONFIG_RTCWAKE is not set
+CONFIG_READPROFILE=y
+CONFIG_RTCWAKE=y
# CONFIG_SCRIPT is not set
# CONFIG_SETARCH is not set
CONFIG_SWAPONOFF=y
# CONFIG_FEATURE_SWAPON_PRI is not set
CONFIG_SWITCH_ROOT=y
CONFIG_UMOUNT=y
-# CONFIG_FEATURE_UMOUNT_ALL is not set
+CONFIG_FEATURE_UMOUNT_ALL=y
#
# Common options for mount/umount
# CONFIG_DEVMEM is not set
# CONFIG_EJECT is not set
# CONFIG_FEATURE_EJECT_SCSI is not set
-# CONFIG_FBSPLASH is not set
+CONFIG_FBSPLASH=y
# CONFIG_INOTIFYD is not set
-# CONFIG_LAST is not set
-# CONFIG_FEATURE_LAST_SMALL is not set
+CONFIG_LAST=y
+CONFIG_FEATURE_LAST_SMALL=y
# CONFIG_FEATURE_LAST_FANCY is not set
CONFIG_LESS=y
CONFIG_FEATURE_LESS_MAXLINES=9999999
# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set
# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set
# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set
-# CONFIG_MAKEDEVS is not set
+CONFIG_MAKEDEVS=y
# CONFIG_FEATURE_MAKEDEVS_LEAF is not set
-# CONFIG_FEATURE_MAKEDEVS_TABLE is not set
+CONFIG_FEATURE_MAKEDEVS_TABLE=y
# CONFIG_MAN is not set
-# CONFIG_MICROCOM is not set
+CONFIG_MICROCOM=y
# CONFIG_MOUNTPOINT is not set
# CONFIG_MT is not set
# CONFIG_RAIDAUTORUN is not set
-# CONFIG_READAHEAD is not set
+CONFIG_READAHEAD=y
# CONFIG_RUNLEVEL is not set
# CONFIG_RX is not set
# CONFIG_SETSID is not set
# CONFIG_FTPPUT is not set
# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set
CONFIG_HOSTNAME=y
-# CONFIG_HTTPD is not set
-# CONFIG_FEATURE_HTTPD_RANGES is not set
-# CONFIG_FEATURE_HTTPD_USE_SENDFILE is not set
-# CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP is not set
-# CONFIG_FEATURE_HTTPD_SETUID is not set
-# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set
-# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set
-# CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES is not set
-# CONFIG_FEATURE_HTTPD_CGI is not set
-# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set
-# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set
-# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set
-# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set
-# CONFIG_FEATURE_HTTPD_PROXY is not set
+CONFIG_HTTPD=y
+CONFIG_FEATURE_HTTPD_RANGES=y
+CONFIG_FEATURE_HTTPD_USE_SENDFILE=y
+CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP=y
+CONFIG_FEATURE_HTTPD_SETUID=y
+CONFIG_FEATURE_HTTPD_BASIC_AUTH=y
+CONFIG_FEATURE_HTTPD_AUTH_MD5=y
+CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES=y
+CONFIG_FEATURE_HTTPD_CGI=y
+CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR=y
+CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV=y
+CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y
+CONFIG_FEATURE_HTTPD_ERROR_PAGES=y
+CONFIG_FEATURE_HTTPD_PROXY=y
CONFIG_IFCONFIG=y
CONFIG_FEATURE_IFCONFIG_STATUS=y
# CONFIG_FEATURE_IFCONFIG_SLIP is not set
# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set
CONFIG_FEATURE_IFCONFIG_HW=y
-# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set
+CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS=y
# CONFIG_IFENSLAVE is not set
CONFIG_IFUPDOWN=y
CONFIG_IFUPDOWN_IFSTATE_PATH="/var/run/ifstate"
CONFIG_NC_SERVER=y
CONFIG_NC_EXTRA=y
CONFIG_NETSTAT=y
-# CONFIG_FEATURE_NETSTAT_WIDE is not set
-# CONFIG_FEATURE_NETSTAT_PRG is not set
+CONFIG_FEATURE_NETSTAT_WIDE=y
+CONFIG_FEATURE_NETSTAT_PRG=y
CONFIG_NSLOOKUP=y
CONFIG_PING=y
CONFIG_PING6=y
# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set
# CONFIG_TFTP_DEBUG is not set
CONFIG_TRACEROUTE=y
-# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
-# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
-# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
+CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
+CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE=y
+CONFIG_FEATURE_TRACEROUTE_USE_ICMP=y
CONFIG_APP_UDHCPD=y
-# CONFIG_APP_DHCPRELAY is not set
+CONFIG_APP_DHCPRELAY=y
CONFIG_APP_DUMPLEASES=y
# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set
CONFIG_DHCPD_LEASES_FILE="/var/lib/misc/udhcpd.leases"
# CONFIG_NMETER is not set
# CONFIG_PGREP is not set
CONFIG_PIDOF=y
-# CONFIG_FEATURE_PIDOF_SINGLE is not set
-# CONFIG_FEATURE_PIDOF_OMIT is not set
+CONFIG_FEATURE_PIDOF_SINGLE=y
+CONFIG_FEATURE_PIDOF_OMIT=y
# CONFIG_PKILL is not set
CONFIG_PS=y
CONFIG_FEATURE_PS_WIDE=y
CONFIG_ASH_MATH_SUPPORT=y
# CONFIG_ASH_MATH_SUPPORT_64 is not set
CONFIG_ASH_GETOPTS=y
-# CONFIG_ASH_BUILTIN_ECHO is not set
+CONFIG_ASH_BUILTIN_ECHO=y
CONFIG_ASH_BUILTIN_PRINTF=y
CONFIG_ASH_BUILTIN_TEST=y
# CONFIG_ASH_CMDCMD is not set
# CONFIG_ASH_MAIL is not set
-CONFIG_ASH_OPTIMIZE_FOR_SIZE=y
+# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set
# CONFIG_ASH_RANDOM_SUPPORT is not set
CONFIG_ASH_EXPAND_PRMT=y
# CONFIG_HUSH is not set
--- /dev/null
+diff -uNr busybox-1.13.2-orig/examples/udhcp/simple.script busybox-1.13.2/examples/udhcp/simple.script
+--- busybox-1.13.2-orig/examples/udhcp/simple.script 2009-02-04 11:08:13.000000000 -0500
++++ busybox-1.13.2/examples/udhcp/simple.script 2009-02-04 11:24:51.000000000 -0500
+@@ -8,22 +8,31 @@
+ [ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
+ [ -n "$subnet" ] && NETMASK="netmask $subnet"
+
++# return 0 if root is mounted on a network filesystem
++root_is_nfs() {
++ grep -qe '^/dev/root.*\(nfs\|smbfs\|ncp\|coda\) .*' /proc/mounts
++}
++
+ case "$1" in
+ deconfig)
+- /sbin/ifconfig $interface 0.0.0.0
++ if ! root_is_nfs ; then
++ /sbin/ifconfig $interface 0.0.0.0
++ fi
+ ;;
+
+ renew|bound)
+ /sbin/ifconfig $interface $ip $BROADCAST $NETMASK
+
+ if [ -n "$router" ] ; then
+- while route del default gw 0.0.0.0 dev $interface 2>/dev/null ; do
+- :
+- done
++ if ! root_is_nfs ; then
++ while route del default gw 0.0.0.0 dev $interface 2>/dev/null ; do
++ :
++ done
++ fi
+
+ metric=0
+ for i in $router ; do
+- route add default gw $i dev $interface metric $((metric++))
++ route add default gw $i dev $interface metric $((metric++)) 2>/dev/null
+ done
+ fi
+
require busybox.inc
-
-PR = "r9"
+PR = "r12"
SRC_URI = "\
http://www.busybox.net/downloads/busybox-${PV}.tar.gz \
+ http://busybox.net/downloads/fixes-1.13.2/busybox-1.13.2-depmod.patch;patch=1 \
+ http://busybox.net/downloads/fixes-1.13.2/busybox-1.13.2-init.patch;patch=1 \
+ http://busybox.net/downloads/fixes-1.13.2/busybox-1.13.2-mdev.patch;patch=1 \
+ http://busybox.net/downloads/fixes-1.13.2/busybox-1.13.2-modprobe.patch;patch=1 \
+ http://busybox.net/downloads/fixes-1.13.2/busybox-1.13.2-tar.patch;patch=1 \
\
file://udhcpscript.patch;patch=1 \
+ file://udhcpc-fix-nfsroot.patch;patch=1 \
file://B921600.patch;patch=1 \
- file://r24785.patch;patch=1;status=merged \
file://find-touchscreen.sh \
file://busybox-cron \
file://busybox-httpd \
install -m 0755 ${WORKDIR}/find-touchscreen.sh ${D}${sysconfdir}/mdev/
install -m 0755 ${WORKDIR}/mdev ${D}${sysconfdir}/init.d/
}
-
--- /dev/null
+PR = "r0"
+
+require byacc.inc
+
+inherit native
--- /dev/null
+DESCRIPTION = "Berkeley Yacc"
+SECTION = "devel"
+LICENSE = "public domain"
+
+SRC_URI = "ftp://invisible-island.net/byacc/byacc-${PV}.tgz"
+EXTRA_OECONF += "--program-transform-name='s,^,b,'"
+S = "${WORKDIR}/byacc-${PV}"
+
+inherit autotools
+
+do_configure() {
+ oe_runconf
+}
--- /dev/null
+PR = "r0"
+
+require byacc.inc
--- /dev/null
+require clutter-gtk.inc
+
+PV = "0.6.0+git${SRCREV}"
+
+DEPENDS += "clutter-0.6"
+
+SRC_URI = "git://git.clutter-project.org/clutter-gtk.git;protocol=git;branch=clutter-gtk-0-6"
+
+S = "${WORKDIR}/git"
--- /dev/null
+require clutter-gtk.inc
+
+PV = "0.8.0+git${SRCREV}"
+
+DEPENDS += "clutter"
+
+SRC_URI = "git://git.clutter-project.org/clutter-gtk.git;protocol=git;branch=clutter-gtk-0-8"
+
+S = "${WORKDIR}/git"
--- /dev/null
+DESCRIPTION = "Clutter GTK+"
+HOMEPAGE = "http://www.clutter-project.org/"
+LICENSE = "LGPL"
+
+DEPENDS = "gtk+"
+
+FILESPATH = "${FILE_DIRNAME}/clutter-gtk"
+
+PACKAGES =+ "${PN}-examples"
+FILES_${PN}-examples = "${bindir}/gtk-clutter-test ${bindir}/gtk-clutter-events ${bindir}/gtk-clutter-multistage"
+
+inherit autotools_stage pkgconfig gtk-doc
+
--- /dev/null
+require clutter-gst.inc
+
+PV = "0.9.0+git${SRCREV}"
+PR = "r0"
+
+SRC_URI = "git://git.clutter-project.org/clutter-gtk.git;protocol=git"
+
+S = "${WORKDIR}/git"
+
+DEPENDS = "clutter"
EXTRA_OECONF_omap3evm = "${BASE_CONF} --with-flavour=eglx --with-gles=2.0"
PACKAGE_ARCH_omap3evm = "${MACHINE_ARCH}"
+DEPENDS_overo = "${STDDEPENDS} libgles-omap3 tslib"
+EXTRA_OECONF_overo = "${BASE_CONF} --with-flavour=eglx --with-gles=2.0"
+PACKAGE_ARCH_overo = "${MACHINE_ARCH}"
+
DEPENDS_mx31ads = "${STDDEPENDS} libgles-mx31 tslib"
EXTRA_OECONF_mx31ads = "${BASE_CONF} --with-flavour=eglnative"
PACKAGE_ARCH_mx31ads = "${MACHINE_ARCH}"
SECTION = "libs/network"
LICENSE = "GPL"
DEPENDS = "gtk+ dbus"
-PR = "r1"
+PR = "r7"
-SRC_URI = "ftp://ftp.moblin.org/connman/releases/connman-gnome-${PV}.tar.gz"
+RRECOMMENDS_${PN} = "connman connman-plugin-ethernet connman-plugin-loopback connman-plugin-udhcp connman-plugin-wifi"
+
+SRC_URI = "http://repo.moblin.org/connman/releases/connman-gnome-${PV}.tar.gz \
+ file://phrase-lenght.diff;patch=1 \
+ file://connman-applet.desktop"
inherit autotools gtk-icon-cache
+do_install_append() {
+ install -d ${D}${datadir}/applications/
+ install ${WORKDIR}/connman-applet.desktop ${D}${datadir}/applications/
+}
+
ln -sf . include/connman
}
+do_compile_append() {
+ sed -i -e s:deny:allow:g src/connman-dbus.conf
+}
+
do_install_append() {
install -m 0755 ${WORKDIR}/connman ${D}${sysconfdir}/init.d/connman
}
require connman.inc
-PR = "r5"
+PR = "r6"
EXTRA_OECONF += "\
--disable-gtk-doc \
"
SRC_URI = "\
- http://ftp.moblin.org/connman/releases/connman-${PV}.tar.gz \
+ http://repo.moblin.org/connman/releases/connman-${PV}.tar.gz \
file://connman \
"
--- /dev/null
+[Desktop Entry]
+Encoding=UTF-8
+Name=Connection Manager
+Comment=Connection Manager applet
+Icon=stock_internet
+Exec=connman-applet
+Terminal=false
+Type=Application
+Categories=Network;GTK
+
--- /dev/null
+From: Marcel Holtmann <marcel@holtmann.org>
+Date: Fri, 30 Jan 2009 14:34:05 +0000 (+0100)
+Subject: Don't limit input field length for passphrases
+X-Git-Url: http://git.moblin.org/cgi-bin/gitweb/gitweb.cgi?p=projects%2Fconnman-gnome.git;a=commitdiff_plain;h=faa1dee0cea9bdf47d91f5665880dab335dd94b4
+
+Don't limit input field length for passphrases
+---
+
+diff --git a/applet/main.c b/applet/main.c
+index cf12a34..434e7c8 100644
+--- a/applet/main.c
++++ b/applet/main.c
+@@ -151,8 +151,8 @@ static void passphrase_dialog(const char *path, const char *name)
+ GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
+
+ entry = gtk_entry_new();
+- gtk_entry_set_max_length(GTK_ENTRY(entry), 16);
+- gtk_entry_set_width_chars(GTK_ENTRY(entry), 16);
++ gtk_entry_set_max_length(GTK_ENTRY(entry), 120);
++ gtk_entry_set_width_chars(GTK_ENTRY(entry), 20);
+ gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
+ gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
+ gtk_container_add(GTK_CONTAINER(vbox), entry);
SECTION = "base"
LICENSE = "GPL"
DESCRIPTION = "Allows you to set-up and manipulate the Linux console."
-PR = "r3"
+PR = "r4"
SRC_URI = "${SOURCEFORGE_MIRROR}/lct/console-tools-${PV}.tar.gz \
file://codepage.patch;patch=1 \
mv ${D}${bindir}/chvt ${D}${bindir}/chvt.${PN}
mv ${D}${bindir}/deallocvt ${D}${bindir}/deallocvt.${PN}
mv ${D}${bindir}/openvt ${D}${bindir}/openvt.${PN}
+ mv ${D}${bindir}/showkey ${D}${bindir}/showkey.${PN}
}
pkg_postinst_${PN} () {
update-alternatives --install ${bindir}/chvt chvt chvt.${PN} 100
update-alternatives --install ${bindir}/deallocvt deallocvt deallocvt.${PN} 100
update-alternatives --install ${bindir}/openvt openvt openvt.${PN} 100
+ update-alternatives --install ${bindir}/showkey showkey showkey.${PN} 100
}
pkg_prerm_${PN} () {
update-alternatives --remove chvt chvt.${PN}
update-alternatives --remove deallocvt deallocvt.${PN}
update-alternatives --remove openvt openvt.${PN}
+ update-alternatives --remove showkey showkey.${PN}
}
--- /dev/null
+DESCRIPTION = "ddccontrol - softwarewise change monitor settings"
+LICENSE = "GPLv2"
+HOMEPAGE = "http://sourceforge.net/projects/ddccontrol/"
+
+PR = "r0"
+
+inherit autotools
+
+SRC_URI = "${SOURCEFORGE_MIRROR}/ddccontrol/ddccontrol-db-${PV}.tar.bz2"
+
--- /dev/null
+DESCRIPTION = "ddccontrol - softwarewise change monitor settings"
+LICENSE = "GPLv2"
+HOMEPAGE = "http://sourceforge.net/projects/ddccontrol/"
+
+PR = "r0"
+
+inherit autotools
+
+DEPENDS = "pciutils libxml2 gtk+ ddccontrol-db"
+
+SRC_URI = "${SOURCEFORGE_MIRROR}/ddccontrol/ddccontrol-${PV}.tar.bz2"
+
+FILES_${PN}+= "${datadir}/icons/Bluecurve/48x48/apps/gddccontrol.png"
+++ /dev/null
-Index: DirectFB-1.1.1/directfb-internal.pc.in
-===================================================================
---- DirectFB-1.1.1.orig/directfb-internal.pc.in 2007-08-07 21:43:00.000000000 +0200
-+++ DirectFB-1.1.1/directfb-internal.pc.in 2008-07-17 21:00:47.424654304 +0200
-@@ -2,10 +2,10 @@
- exec_prefix=@exec_prefix@
- moduledir=@MODULEDIR@
- moduledirname=@MODULEDIRNAME@
--includedir=@INTERNALINCLUDEDIR@
-+includedir=@includedir@
-
- Name: DirectFB-Internal
- Description: Third party module support package for DirectFB.
- Version: @VERSION@
- Requires: directfb = @VERSION@
--Cflags: @DFB_INTERNAL_CFLAGS@ -I@INTERNALINCLUDEDIR@
-+Cflags: @DFB_INTERNAL_CFLAGS@ -I${includedir}/directfb -I${includedir}
-Index: DirectFB-1.1.1/directfb.pc.in
-===================================================================
---- DirectFB-1.1.1.orig/directfb.pc.in 2007-12-15 16:23:16.000000000 +0100
-+++ DirectFB-1.1.1/directfb.pc.in 2008-07-17 20:59:58.044985193 +0200
-@@ -9,4 +9,4 @@
- Requires: fusion direct
- Libs: -L${libdir} -ldirectfb @THREADLIB@ @OSX_LIBS@
- Libs.private: -L${libdir} @DYNLIB@ @ZLIB_LIBS@
--Cflags: @THREADFLAGS@ -I@INCLUDEDIR@
-+Cflags: @THREADFLAGS@ -I${includedir}/directfb
-Index: DirectFB-1.1.1/lib/fusion/fusion.pc.in
-===================================================================
---- DirectFB-1.1.1.orig/lib/fusion/fusion.pc.in 2007-08-07 21:43:00.000000000 +0200
-+++ DirectFB-1.1.1/lib/fusion/fusion.pc.in 2008-07-17 20:58:07.051338866 +0200
-@@ -8,4 +8,4 @@
- Version: @VERSION@
- Requires: direct
- Libs: -L${libdir} -lfusion
--Cflags: -I@INCLUDEDIR@
-+Cflags: -I${includedir}/directfb -I${includedir}
-Index: DirectFB-1.1.1/lib/voodoo/voodoo.pc.in
-===================================================================
---- DirectFB-1.1.1.orig/lib/voodoo/voodoo.pc.in 2007-08-07 21:43:00.000000000 +0200
-+++ DirectFB-1.1.1/lib/voodoo/voodoo.pc.in 2008-07-17 20:58:07.054671842 +0200
-@@ -8,4 +8,4 @@
- Version: @VERSION@
- Requires: direct
- Libs: -L${libdir} -lvoodoo
--Cflags: -I@INCLUDEDIR@
-+Cflags: -I${includedir}/directfb -I${includedir}
--- /dev/null
+---
+ configure.in | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+Index: DirectFB-1.2.7/configure.in
+===================================================================
+--- DirectFB-1.2.7.orig/configure.in
++++ DirectFB-1.2.7/configure.in
+@@ -1288,8 +1288,11 @@ fi
+
+ enable_tslib=no
+ if test "$checkfor_tslib" = "yes"; then
+- PKG_CHECK_MODULES([TSLIB], [tslib-0.0], [enable_tslib=yes], [enable_tslib=no,
+- AC_MSG_WARN([*** no tslib -- tslib driver will not be built.])])
++ PKG_CHECK_MODULES([TSLIB], [tslib-1.0 >= 1.0.0], [enable_tslib=yes], [enable_tslib=no])
++ if test "$enable_tslib" = "no"; then
++ PKG_CHECK_MODULES([TSLIB], [tslib-0.0], [enable_tslib=yes], [enable_tslib=no,
++ AC_MSG_WARN([*** no tslib -- tslib driver will not be built.])])
++ fi
+ fi
+
+ enable_ucb1x00_ts=no
--- /dev/null
+DESCRIPTION = "DirectFB extra providers"
+DEPENDS = "directfb"
+SECTION = "libs"
+LICENSE = "GPL"
+
+SRC_URI = " \
+ http://www.directfb.org/downloads/Extras/DirectFB-examples-${PV}.tar.gz \
+ "
+S = "${WORKDIR}/DirectFB-examples-${PV}"
+
+inherit autotools
+
+do_stage() {
+ autotools_stage_all
+}
+
+
require directfb.inc
RV = "1.2-0"
-PR = "r0"
+PR = "r1"
DEPENDS += "sysfsutils"
SRC_URI = " \
http://www.directfb.org/downloads/Old/DirectFB-${PV}.tar.gz \
- file://fix-pkgconfig-cflags.patch;patch=1 \
+ file://directfb-1.2.x-fix-pkgconfig-cflags.patch;patch=1 \
file://mkdfiff.patch;patch=1 \
file://dont-use-linux-config.patch;patch=1 \
file://ts_lib_autotools.patch;patch=1 \
--- /dev/null
+require directfb.inc
+
+RV = "1.2-0"
+PR = "r0"
+
+DEPENDS += "sysfsutils"
+
+SRC_URI = " \
+ http://directfb.org/downloads/Core/DirectFB-${PV}.tar.gz \
+ file://directfb-1.2.x-fix-pkgconfig-cflags.patch;patch=1 \
+ file://mkdfiff.patch;patch=1 \
+ file://dont-use-linux-config.patch;patch=1 \
+ file://ts_lib_autotools.patch;patch=1 \
+"
+
+EXTRA_OECONF = "\
+ --enable-freetype=yes \
+ --enable-zlib \
+ --with-gfxdrivers=none \
+ --disable-libmpeg3 \
+ --disable-sdl \
+ --disable-vnc \
+ --disable-x11 \
+"
+
+LDFLAGS_append = ""
+
+LEAD_SONAME = "libdirectfb-1.2.so.0"
--- /dev/null
+Index: DirectFB-1.1.1/directfb-internal.pc.in
+===================================================================
+--- DirectFB-1.1.1.orig/directfb-internal.pc.in 2007-08-07 21:43:00.000000000 +0200
++++ DirectFB-1.1.1/directfb-internal.pc.in 2008-07-17 21:00:47.424654304 +0200
+@@ -2,10 +2,10 @@
+ exec_prefix=@exec_prefix@
+ moduledir=@MODULEDIR@
+ moduledirname=@MODULEDIRNAME@
+-includedir=@INTERNALINCLUDEDIR@
++includedir=@includedir@
+
+ Name: DirectFB-Internal
+ Description: Third party module support package for DirectFB.
+ Version: @VERSION@
+ Requires: directfb = @VERSION@
+-Cflags: @DFB_INTERNAL_CFLAGS@ -I@INTERNALINCLUDEDIR@
++Cflags: @DFB_INTERNAL_CFLAGS@ -I${includedir}/directfb -I${includedir}
+Index: DirectFB-1.1.1/directfb.pc.in
+===================================================================
+--- DirectFB-1.1.1.orig/directfb.pc.in 2007-12-15 16:23:16.000000000 +0100
++++ DirectFB-1.1.1/directfb.pc.in 2008-07-17 20:59:58.044985193 +0200
+@@ -9,4 +9,4 @@
+ Requires: fusion direct
+ Libs: -L${libdir} -ldirectfb @THREADLIB@ @OSX_LIBS@
+ Libs.private: -L${libdir} @DYNLIB@ @ZLIB_LIBS@
+-Cflags: @THREADFLAGS@ -I@INCLUDEDIR@
++Cflags: @THREADFLAGS@ -I${includedir}/directfb
+Index: DirectFB-1.1.1/lib/fusion/fusion.pc.in
+===================================================================
+--- DirectFB-1.1.1.orig/lib/fusion/fusion.pc.in 2007-08-07 21:43:00.000000000 +0200
++++ DirectFB-1.1.1/lib/fusion/fusion.pc.in 2008-07-17 20:58:07.051338866 +0200
+@@ -8,4 +8,4 @@
+ Version: @VERSION@
+ Requires: direct
+ Libs: -L${libdir} -lfusion
+-Cflags: -I@INCLUDEDIR@
++Cflags: -I${includedir}/directfb -I${includedir}
+Index: DirectFB-1.1.1/lib/voodoo/voodoo.pc.in
+===================================================================
+--- DirectFB-1.1.1.orig/lib/voodoo/voodoo.pc.in 2007-08-07 21:43:00.000000000 +0200
++++ DirectFB-1.1.1/lib/voodoo/voodoo.pc.in 2008-07-17 20:58:07.054671842 +0200
+@@ -8,4 +8,4 @@
+ Version: @VERSION@
+ Requires: direct
+ Libs: -L${libdir} -lvoodoo
+-Cflags: -I@INCLUDEDIR@
++Cflags: -I${includedir}/directfb -I${includedir}
--- /dev/null
+Index: e/config/illume/e.src
+===================================================================
+--- e.orig/config/illume/e.src 2009-01-30 23:34:37.000000000 +0100
++++ e/config/illume/e.src 2009-01-30 23:34:54.000000000 +0100
+@@ -665,7 +665,7 @@
+ value "display_res_height" int: 1;
+ value "display_res_hz" int: 0;
+ value "display_res_rotation" int: 0;
+- value "screensaver_enable" int: 1;
++ value "screensaver_enable" int: 0;
+ value "screensaver_timeout" int: 30;
+ value "screensaver_interval" int: 5;
+ value "screensaver_blanking" int: 2;
DEPENDS = "eet evas ecore edje efreet edbus"
LICENSE = "MIT BSD"
PV = "0.16.999.050+svnr${SRCREV}"
-PR = "r2"
+PR = "r3"
inherit e update-alternatives
file://applications.menu \
file://gsm-segfault-fix.patch;patch=1;maxrev=37617 \
"
+
+SRC_URI_append_openmoko = " file://illume-disable-screensaver.patch;patch=1 "
+
S = "${WORKDIR}/e"
EXTRA_OECONF = "\
locales_dir = base_path_join(datadir, "i18n", "locales")
binary_locales_dir = base_path_join(libdir, "locale")
- do_split_packages(d, gconv_libdir, file_regex='^(.*)\.so$', output_pattern='eglibc-gconv-%s', description='gconv module for character set %s', extra_depends='eglibc-gconv')
+ def calc_gconv_deps(fn, pkg, file_regex, output_pattern, group):
+ deps = []
+ f = open(fn, "r")
+ c_re = re.compile('^copy "(.*)"')
+ i_re = re.compile('^include "(\w+)".*')
+ for l in f.readlines():
+ m = c_re.match(l) or i_re.match(l)
+ if m:
+ dp = legitimize_package_name('eglibc-gconv-%s' % m.group(1))
+ if not dp in deps:
+ deps.append(dp)
+ f.close()
+ if deps != []:
+ bb.data.setVar('RDEPENDS_%s' % pkg, " ".join(deps), d)
+ bb.data.setVar('RPROVIDES_%s' % pkg, 'glibc-gconv-%s' % group.lower(), d)
+
+ do_split_packages(d, gconv_libdir, file_regex='^(.*)\.so$', output_pattern='eglibc-gconv-%s', description='gconv module for character set %s', hook=calc_gconv_deps, extra_depends='eglibc-gconv')
+
+ def calc_charmap_deps(fn, pkg, file_regex, output_pattern, group):
+ deps = []
+ f = open(fn, "r")
+ c_re = re.compile('^copy "(.*)"')
+ i_re = re.compile('^include "(\w+)".*')
+ for l in f.readlines():
+ m = c_re.match(l) or i_re.match(l)
+ if m:
+ dp = legitimize_package_name('eglibc-charmap-%s' % m.group(1))
+ if not dp in deps:
+ deps.append(dp)
+ f.close()
+ if deps != []:
+ bb.data.setVar('RDEPENDS_%s' % pkg, " ".join(deps), d)
+ bb.data.setVar('RPROVIDES_%s' % pkg, 'glibc-charmap-%s' % group.lower(), d)
- do_split_packages(d, charmap_dir, file_regex='^(.*)\.gz$', output_pattern='eglibc-charmap-%s', description='character map for %s encoding', extra_depends='')
+ do_split_packages(d, charmap_dir, file_regex='^(.*)\.gz$', output_pattern='eglibc-charmap-%s', description='character map for %s encoding', hook=calc_charmap_deps, extra_depends='')
def calc_locale_deps(fn, pkg, file_regex, output_pattern, group):
deps = []
f.close()
if deps != []:
bb.data.setVar('RDEPENDS_%s' % pkg, " ".join(deps), d)
- bb.data.setVar('RPROVIDES_%s' % pkg, 'glibc-localedata-%s' % group, d)
+ bb.data.setVar('RPROVIDES_%s' % pkg, 'glibc-localedata-%s' % group.lower(), d)
do_split_packages(d, locales_dir, file_regex='(.*)', output_pattern='eglibc-localedata-%s', description='locale definition for %s', hook=calc_locale_deps, extra_depends='')
bb.data.setVar('PACKAGES', bb.data.getVar('PACKAGES', d) + ' eglibc-gconv', d)
GLIBC_EXTRA_OECONF ?= ""
INHIBIT_DEFAULT_DEPS = "1"
+ARM_INSTRUCTION_SET = "arm"
+
PACKAGES = "glibc catchsegv sln nscd ldd localedef glibc-utils glibc-dev glibc-doc glibc-locale libsegfault glibc-extra-nss glibc-thread-db glibc-pcprofile"
require eglibc.inc
+DEPENDS += "gperf-native"
DEFAULT_PREFERENCE = "1"
FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/eglibc-svn"
PV = "2.9"
-PR = "r0"
+PR = "r3"
SVN_REV="7430"
EGLIBC_BRANCH="eglibc-2_9"
SRC_URI = "svn://svn.eglibc.org/branches;module=eglibc-2_9;rev=${SVN_REV};proto=svn \
require eglibc.inc
+DEPENDS += "gperf-native"
SRCREV = "7542"
# DEFAULT_PREFERENCE = "-1"
FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/eglibc-svn"
PV = "2.9+svnr${SRCREV}"
-PR = "r0"
+PR = "r2"
EGLIBC_BRANCH="trunk"
SRC_URI = "svn://svn.eglibc.org;module=trunk \
file://eglibc-svn-arm-lowlevellock-include-tls.patch;patch=1 \
--- /dev/null
+DESCRIPTION = "Abyss is a GSM 07.10 muxer userspace daemon"
+HOMEPAGE = "http://www.freesmartphone.org/mediawiki/index.php/Implementations/Abyss"
+AUTHOR = "Michael 'Mickey' Lauer <mlauer@vanille-media.de>"
+SECTION = "console/network"
+DEPENDS = "vala-native dbus dbus-glib libgee"
+LICENSE = "GPL"
+PV = "0.2.0+gitr${SRCREV}"
+PR = "r0"
+
+SRC_URI = "${FREESMARTPHONE_GIT}/fso-abyss.git;protocol=git;branch=master"
+S = "${WORKDIR}/git"
+
+inherit autotools
+
+RDEPENDS = "dbus dbus-glib"
+RCONFLICTS = "gsm0710muxd fso-gsm0710muxd"
+
+FILES_${PN} += "${datadir} ${sysconfdir}"
--- /dev/null
+require gdbserver.inc
inherit gnome distutils-base gconf
-PR = "r3"
+PR = "r4"
SRC_URI += "file://ggz-unbreak-m4.patch;patch=1 \
"
LICENSE = "GPL/LGPL"
DEPENDS = "librsvg libwnck totem-pl-parser libgtop gnome-panel gnome-desktop eds-dbus python-pygtk gnome-python libgnomeprint libgnomeprintui"
-PR = "r3"
+PR = "r4"
inherit gnome distutils-base
LICENSE = "GPL/LGPL"
DEPENDS = "python-pygtk libwnck"
+PR = "r1"
+
inherit gnome distutils-base
SRC_URI += "file://acinclude.m4"
DEPENDS = "libgnomeui pyorbit python-pygtk"
RDEPENDS = "pyorbit"
-PR = "r1"
+PR = "r2"
inherit gnome distutils-base pkgconfig
--- /dev/null
+DESCRIPTION = "Libchamplain is a C library aimed to provide a Gtk+ widget to display rasterized maps. "
+LICENSE = "LGPL"
+DEPENDS = "libchamplain clutter-gtk-0.8"
+
+inherit gnome autotools_stage
+
+SRC_URI = "http://libchamplain.pierlux.com/release/${PV}/libchamplain-gtk-${PV}.tar.gz"
+
+
--- /dev/null
+DESCRIPTION = "Libchamplain is a C library aimed to provide a Gtk+ widget to display rasterized maps. "
+LICENSE = "LGPL"
+DEPENDS = "clutter-cairo libsoup-2.4 clutter gtk+"
+
+inherit gnome autotools_stage
+
+SRC_URI = "http://libchamplain.pierlux.com/release/${PV}/libchamplain-${PV}.tar.gz"
+
+FILES_${PN} += "${datadir}/champlain/error.svg"
+
DESCRIPTION = "Python Orbit bindings"
LICENSE = "LGPL"
-PR = "r0"
+PR = "r1"
inherit gnome distutils-base pkgconfig
--without-libtiff \
--with-libjpeg \
--with-libpng \
+ --disable-cups \
"
do_compile() {
require gtk+.inc
-PR = "r1"
+PR = "r3"
DEPENDS += "cairo jasper"
if (bb.data.getVar('DEBIAN_NAMES', d, 1)):
bb.data.setVar('PKG_${PN}', 'libgtk-2.0', d)
}
+
+RPROVIDES_${PN} = "libgailutil18"
+RCONFLICTS_${PN} = "libgailutil18"
+RREPLACES_${PN} = "libgailutil18"
+
#------------------------------------------------------
PV = "1.1"
-PR = "r3"
+PR = "r4"
# no languages for now
IMAGE_LINGUAS = ""
# additional apps
APPS_INSTALL = "\
-# tichy \
+ paroli \
gpe-gallery \
gpe-sketchbook \
gpe-filemanager \
- vagalume \
+ ${@base_conditional('ENTERPRISE_DISTRO', '1', '', 'vagalume', d)} \
starling \
"
echo "alias pico=nano" >>./etc/profile
echo "alias fso='cd /local/pkg/fso'" >>./etc/profile
echo "alias ipkg='opkg'" >>./etc/profile
+ echo "alias vim=vi" >>./etc/profile
+ echo "alias ll='ls -al'" >>./etc/profile
# nfs
mkdir -p ./local/pkg
echo >>./etc/fstab
--- /dev/null
+DESCRIPTION = "JACK is a low-latency audio server. It can \
+connect a number of different applications to an audio \
+device, as well as allowing them to share audio between \
+themselves."
+SECTION = "libs/multimedia"
+PRIORITY = "optional"
+LICENSE = "GPL LGPL"
+PR = "r0"
+
+DEPENDS = "alsa-lib"
+
+SRC_URI = "http://jackaudio.org/downloads/jack-audio-connection-kit-${PV}.tar.gz"
+S = "${WORKDIR}/jack-audio-connection-kit-${PV}"
+
+inherit autotools pkgconfig
+
+EXTRA_OECONF = "--enable-timestamps --disable-capabilities --disable-oldtrans \
+ --disable-portaudio --disable-coreaudio --enable-oss --enable-alsa"
+
+EXTRA_OEMAKE = 'transform="s,^,,"'
+LDFLAGS_append = " -ldl -L${STAGING_LIBDIR}"
+
+PACKAGES =+ "libjack jack-server jack-examples"
+
+FILES_libjack = "${libdir}/*.so.* ${libdir}/jack/*.so"
+FILES_jack-server = "${bindir}/jackd"
+FILES_jack-examples = "${bindir}/*"
+
+do_stage() {
+ autotools_stage_all
+}
+
--- /dev/null
+LICENSE = "GPL"
+SECTION = "base"
+DESCRIPTION = "Configuration file for kexecboot"
+
+PR = "r1"
+PACKAGE_ARCH = "${MACHINE_ARCH}"
+
+CMDLINE_CON = "console=ttyS0,115200n8 console=tty1 noinitrd"
+CMDLINE_CON_collie = "console=ttySA0,115200n8 console=tty1 noinitrd"
+CMDLINE_CON_qemuarm = "console=ttyAMA0,115200n8 console=tty1 noinitrd"
+
+CMDLINE_DEBUG = '${@base_conditional("DISTRO_TYPE", "release", "quiet", "debug",d)}'
+
+CMDLINE_MEM_collie = "mem=${mem}M"
+
+CMDLINE_ROTATE_spitz = "fbcon=rotate:1"
+CMDLINE_ROTATE_akita = "fbcon=rotate:1"
+CMDLINE_ROTATE_collie = "fbcon=rotate:1"
+CMDLINE_ROTATE_poodle = "fbcon=rotate:1"
+FILES_${PN} += "/boot/*"
+
+do_install () {
+ install -d ${D}/boot
+ echo "${CMDLINE_CON} ${CMDLINE_MEM} ${CMDLINE_ROTATE} ${CMDLINE_OTHER} ${CMDLINE_DEBUG}"> ${D}/boot/kernel-cmdline
+}
--- /dev/null
+LICENSE = "GPL"
+
+DEPENDS = "klibc"
+RDEPENDS = "kexec-static"
+
+inherit autotools
+
+# You can create your own *-img.h by doing
+# ./make-image-header.sh <file>.png HAND
+
+SRC_URI += "file://logo-img.h \
+ file://logo.png \
+ "
+
+export CC=${TARGET_PREFIX}klcc
+
+# standard oe cflags don't work with klcc
+export CFLAGS = ""
+export CPPFLAGS = ""
+export LDFLAGS = ""
+
+do_configure_prepend () {
+ install -m 0644 ${WORKDIR}/logo-img.h ${S}/res/
+ install -m 0644 ${WORKDIR}/logo.png ${S}/res/
+}
+
+do_install () {
+ install -d ${D}${bindir}
+ install -m 0755 kexecboot ${D}${bindir}/
+
+ install -d ${D}/proc
+ install -d ${D}/mnt
+}
+
+FILES_${PN} += " ${bindir}/kexecboot /init /proc /mnt"
+
+pkg_postinst_${PN} () {
+ ln -sf ${bindir}/kexecboot $D/init
+}
-LICENSE = "GPL"
-PR = "r4"
-DEPENDS = "klibc"
-RDEPENDS = "kexec-static"
-
-inherit autotools
-
-# You can create your own *-img.h by doing
-# ./make-image-header.sh <file>.png HAND
+PR = "r5"
SRC_URI = "http://projects.linuxtogo.org/~jay7/kexecboot-${PV}.tar.gz \
file://add-reboot-option.patch;patch=1 \
file://add-sleep.patch;patch=1 \
file://silent-output-hack.patch;patch=1 \
file://kexecboot-tosa.patch;patch=1 \
- file://fb-render-16bit.patch;patch=1 \
- file://logo-img.h \
- file://logo.png \
- "
+ file://fb-render-16bit.patch;patch=1"
S = "${WORKDIR}/kexecboot-${PV}"
-export CC=${TARGET_PREFIX}klcc
-
-# standard oe cflags don't work with klcc
-export CFLAGS = ""
-export CPPFLAGS = ""
-export LDFLAGS = ""
-
-do_configure_prepend () {
- install -m 0644 ${WORKDIR}/logo-img.h ${S}/res/
- install -m 0644 ${WORKDIR}/logo.png ${S}/res/
-}
-
-do_install () {
- install -d ${D}${bindir}
- install -m 0755 kexecboot ${D}${bindir}/
-
- install -d ${D}/proc
- install -d ${D}/mnt
-}
-
-FILES_${PN} += " ${bindir}/kexecboot /init /proc /mnt"
-
-pkg_postinst_${PN} () {
- ln -sf ${bindir}/kexecboot $D/init
-}
+require kexecboot.inc
--- /dev/null
+SRC_URI = "http://projects.linuxtogo.org/frs/download.php/226/kexecboot-${PV}.tar.gz \
+ "
+
+require kexecboot.inc
--- /dev/null
+PR = "r0"
+DEFAULT_PREFERENCE = "-1"
+
+SRC_URI = "git://git.linuxtogo.org/home/thesing/kexecboot.git;protocol=git "
+SRCREV = "8823a939a38a8a3287f90dee062e8ab8569f884f"
+
+# v0.5
+#tag=8823a939a38a8a3287f90dee062e8ab8569f884f
+
+# v0.4
+#tag=d7af5356df4f25203831403c69f1a263c163f31a
+
+S = "${WORKDIR}/git"
+
+require kexecboot.inc
+# We set PR here, since a change in the kexecboot recipe will need to get picked up by *all* the kernels:
+PR = "r12"
+
SRC_URI = "file://defconfig"
LOGO_SIZE = '${@base_conditional("GUI_MACHINE_CLASS", "bigscreen", "vga", "qvga", d)}'
DEFAULT_PREFERENCE_hx4700 = "1"
DEFAULT_PREFERENCE_h2200 = "1"
-PR = "r1"
-
SRC_URI = "${HANDHELDS_CVS};module=linux/kernel26;tag=${@'K' + bb.data.getVar('PV',d,1).replace('.', '-')} \
file://linux-2.6.git-9d20fdd58e74d4d26dc5216efaaa0f800c23dd3a.patch;patch=1 \
http://www.rpsys.net/openzaurus/patches/archive/export_atags-r0a.patch;patch=1 \
require linux-kexecboot.inc
-PR = "r6"
-
DEFAULT_PREFERENCE = "-1"
DEFAULT_PREFERENCE_collie = "-1"
DEFAULT_PREFERENCE_poodle = "1"
require linux-kexecboot.inc
-PR = "r10"
DEFAULT_PREFERENCE = "-1"
DEFAULT_PREFERENCE_qemuarm = "-1"
DEFAULT_PREFERENCE_qemux86 = "-1"
HOMEPAGE = "http://www.tcpdump.org/"
SECTION = "libs/network"
LICENSE = "BSD"
-DEPENDS = "flex-native bison-native"
+DEPENDS = "bluez-libs flex-native bison-native"
+
+PR = "r1"
# Don't forget to edit shared.patch to have the correct version number inside
SRC_URI = "http://www.tcpdump.org/release/libpcap-${PV}.tar.gz \
+++ /dev/null
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24.4
-# Fri Oct 17 14:41:04 2008
-#
-CONFIG_ARM=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-# CONFIG_GENERIC_GPIO is not set
-# CONFIG_GENERIC_TIME is not set
-# CONFIG_GENERIC_CLOCKEVENTS is not set
-CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_ZONE_DMA=y
-CONFIG_VECTORS_BASE=0xffff0000
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=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_USER_NS is not set
-# CONFIG_PID_NS is not set
-# CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
-# CONFIG_FAIR_GROUP_SCHED is not set
-CONFIG_SYSFS_DEPRECATED=y
-# CONFIG_RELAY is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
-# CONFIG_EMBEDDED is not set
-CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# 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_ANON_INODES=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
-# CONFIG_SLOB is not set
-CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-CONFIG_MODULES=y
-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 is not set
-CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
-# CONFIG_BLK_DEV_BSG is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-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"
-
-#
-# System Type
-#
-# CONFIG_ARCH_AAEC2000 is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_REALVIEW is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_NETX is not set
-# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_IOP13XX is not set
-# CONFIG_ARCH_IOP32X is not set
-# CONFIG_ARCH_IOP33X is not set
-# CONFIG_ARCH_IXP23XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
-# CONFIG_ARCH_MXC is not set
-# CONFIG_ARCH_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_DAVINCI is not set
-# CONFIG_ARCH_OMAP is not set
-CONFIG_ARCH_OXNAS=y
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
-
-#
-# Oxford Semiconductor NAS Options
-#
-# CONFIG_ARCH_OXNAS_FPGA is not set
-CONFIG_NOMINAL_PLL400_FREQ=733333333
-CONFIG_NOMINAL_RPSCLK_FREQ=25000000
-# CONFIG_OXNAS_VERSION_0X800 is not set
-CONFIG_OXNAS_VERSION_0X810=y
-# CONFIG_OXNAS_VERSION_0X850 is not set
-# CONFIG_ARCH_OXNAS_UART1 is not set
-CONFIG_ARCH_OXNAS_UART2=y
-# CONFIG_ARCH_OXNAS_UART2_MODEM is not set
-# CONFIG_ARCH_OXNAS_UART3 is not set
-# CONFIG_ARCH_OXNAS_PCI_REQGNT_0 is not set
-# CONFIG_ARCH_OXNAS_PCI_REQGNT_1 is not set
-# CONFIG_ARCH_OXNAS_PCI_REQGNT_2 is not set
-# CONFIG_ARCH_OXNAS_PCI_REQGNT_3 is not set
-# CONFIG_ARCH_OXNAS_PCI_CLKOUT_0 is not set
-# CONFIG_ARCH_OXNAS_PCI_CLKOUT_1 is not set
-# CONFIG_ARCH_OXNAS_PCI_CLKOUT_2 is not set
-# CONFIG_ARCH_OXNAS_PCI_CLKOUT_3 is not set
-# CONFIG_OXNAS_PCI_RESET is not set
-# CONFIG_OXNAS_SATA_POWER_1 is not set
-# CONFIG_OXNAS_SATA_POWER_2 is not set
-CONFIG_FORCE_MAX_ZONEORDER=10
-CONFIG_SRAM_NUM_PAGES=32
-CONFIG_SUPPORT_LEON=y
-CONFIG_LEON_PAGES=2
-CONFIG_LEON_COPRO=y
-CONFIG_LEON_OFFLOAD_TX=y
-# CONFIG_LEON_RESERVE_DMA_CHANNEL is not set
-CONFIG_LEON_OFFLOAD_TSO=y
-# CONFIG_LEON_START_EARLY is not set
-CONFIG_LEON_POWER_BUTTON_MONITOR=m
-CONFIG_OXNAS_POWER_BUTTON_GPIO=4
-CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
-CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO=32
-# CONFIG_OXNAS_DDR_MON is not set
-# CONFIG_OXNAS_AHB_MON is not set
-# CONFIG_OXNAS_CACHE_LOCKDOWN is not set
-# CONFIG_DO_MEM_TEST is not set
-# CONFIG_CRYPTO_OXAESLRW is not set
-CONFIG_DESCRIPTORS_PAGES=6
-CONFIG_ARCH_OXNAS_NUM_GMAC_DESCRIPTORS=192
-CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES=256
-CONFIG_TACHO_THERM_AND_FAN=m
-# CONFIG_GPIO_TEST is not set
-CONFIG_OXNAS_RTC=y
-# CONFIG_I2S is not set
-# CONFIG_DPE_TEST is not set
-# CONFIG_OXNAS_INSTRUMENT_COPIES is not set
-# CONFIG_OXNAS_DMA_COPIES is not set
-# CONFIG_OXNAS_AHB_MONITOR_MODULE is not set
-# CONFIG_OXNAS_USB_TEST_MODES is not set
-# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
-# CONFIG_OXNAS_LED_TEST is not set
-CONFIG_OXNAS_I2C_SDA=6
-CONFIG_OXNAS_I2C_SCL=7
-# CONFIG_OXNAS_USB_PORTA_POWER_CONTROL is not set
-# CONFIG_OXNAS_USB_PORTB_POWER_CONTROL is not set
-# CONFIG_OXNAS_USB_PORTC_POWER_CONTROL is not set
-# CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE is not set
-# CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE is not set
-# CONFIG_WDC_FAN_OXNAS800 is not set
-# CONFIG_OXNAS_MAP_SRAM is not set
-# CONFIG_OXNAS_SUID_INHERIT is not set
-# CONFIG_OXNAS_USB_HUB_SUPPORT is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_ARM926T=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5TJ=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_COPY_V4WB=y
-CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-
-#
-# Processor Features
-#
-CONFIG_ARM_THUMB=y
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-# CONFIG_OUTER_CACHE is not set
-
-#
-# Bus support
-#
-CONFIG_ARM_AMBA=y
-CONFIG_PCI=y
-CONFIG_PCI_SYSCALL=y
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-# CONFIG_TICK_ONESHOT is not set
-# CONFIG_PREEMPT is not set
-# CONFIG_NO_IDLE_HZ is not set
-CONFIG_HZ=100
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
-CONFIG_VIRT_TO_BUS=y
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE=""
-# CONFIG_XIP_KERNEL is not set
-# CONFIG_KEXEC is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-# CONFIG_VFP is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Power management options
-#
-# CONFIG_PM is not set
-CONFIG_SUSPEND_UP_POSSIBLE=y
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-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_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE 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=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
-# CONFIG_INET_LRO is not set
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_TCP_MD5SIG is not set
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-# CONFIG_NETLABEL is not set
-# CONFIG_NETWORK_SECMARK is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# Core Netfilter Configuration
-#
-# CONFIG_NETFILTER_NETLINK is not set
-# CONFIG_NF_CONNTRACK_ENABLED is not set
-# CONFIG_NF_CONNTRACK is not set
-# CONFIG_NETFILTER_XTABLES is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-# CONFIG_IP_DCCP is not set
-# CONFIG_IP_SCTP is not set
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE 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_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_EXT=y
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 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=y
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_CONNECTOR is not set
-# CONFIG_MTD is not set
-# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 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=10240
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-# CONFIG_MISC_DEVICES is not set
-# 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=y
-
-#
-# 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 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=y
-# 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=y
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_AIC94XX is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_ARCMSR is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_STEX is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_QLA_FC is not set
-# CONFIG_SCSI_QLA_ISCSI is not set
-# CONFIG_SCSI_LPFC is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_SRP is not set
-CONFIG_ATA=y
-# CONFIG_ATA_NONSTANDARD is not set
-# CONFIG_SATA_AHCI is not set
-# CONFIG_SATA_SVW is not set
-# CONFIG_ATA_PIIX is not set
-# CONFIG_SATA_MV is not set
-# CONFIG_SATA_NV is not set
-# CONFIG_PDC_ADMA is not set
-# CONFIG_SATA_QSTOR is not set
-# CONFIG_SATA_PROMISE is not set
-# CONFIG_SATA_SX4 is not set
-# CONFIG_SATA_SIL is not set
-# CONFIG_SATA_SIL24 is not set
-# CONFIG_SATA_SIS is not set
-# CONFIG_SATA_ULI is not set
-# CONFIG_SATA_VIA is not set
-# CONFIG_SATA_VITESSE is not set
-# CONFIG_SATA_INIC162X is not set
-CONFIG_SATA_OX810=y
-# CONFIG_SATA_OXNAS_SINGLE_SATA is not set
-# CONFIG_SATA_OXNAS_DISK_LIGHT is not set
-# CONFIG_PATA_ALI is not set
-# CONFIG_PATA_AMD is not set
-# CONFIG_PATA_ARTOP is not set
-# CONFIG_PATA_ATIIXP is not set
-# CONFIG_PATA_CMD640_PCI is not set
-# CONFIG_PATA_CMD64X is not set
-# CONFIG_PATA_CS5520 is not set
-# CONFIG_PATA_CS5530 is not set
-# CONFIG_PATA_CYPRESS is not set
-# CONFIG_PATA_EFAR is not set
-# CONFIG_ATA_GENERIC is not set
-# CONFIG_PATA_HPT366 is not set
-# CONFIG_PATA_HPT37X is not set
-# CONFIG_PATA_HPT3X2N is not set
-# CONFIG_PATA_HPT3X3 is not set
-# CONFIG_PATA_IT821X is not set
-# CONFIG_PATA_IT8213 is not set
-# CONFIG_PATA_JMICRON is not set
-# CONFIG_PATA_TRIFLEX is not set
-# CONFIG_PATA_MARVELL is not set
-# CONFIG_PATA_MPIIX is not set
-# CONFIG_PATA_OLDPIIX is not set
-# CONFIG_PATA_NETCELL is not set
-# CONFIG_PATA_NS87410 is not set
-# CONFIG_PATA_NS87415 is not set
-# CONFIG_PATA_OPTI is not set
-# CONFIG_PATA_OPTIDMA is not set
-# CONFIG_PATA_PDC_OLD is not set
-# CONFIG_PATA_RADISYS is not set
-# CONFIG_PATA_RZ1000 is not set
-# CONFIG_PATA_SC1200 is not set
-# CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
-# CONFIG_PATA_SIL680 is not set
-# CONFIG_PATA_SIS is not set
-# CONFIG_PATA_VIA is not set
-# CONFIG_PATA_WINBOND is not set
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=y
-# CONFIG_MD_RAID0 is not set
-CONFIG_MD_RAID1=y
-# CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID456 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_MD_FAULTY is not set
-CONFIG_BLK_DEV_DM=y
-# CONFIG_DM_DEBUG is not set
-CONFIG_DM_CRYPT=y
-# CONFIG_DM_SNAPSHOT is not set
-# CONFIG_DM_MIRROR is not set
-# CONFIG_DM_ZERO is not set
-# CONFIG_DM_MULTIPATH is not set
-# CONFIG_DM_DELAY is not set
-# CONFIG_DM_UEVENT is not set
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_FIREWIRE is not set
-# CONFIG_IEEE1394 is not set
-# CONFIG_I2O is not set
-CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
-# 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_ARCNET is not set
-# CONFIG_NET_ETHERNET is not set
-CONFIG_MII=y
-CONFIG_NETDEV_1000=y
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_E1000E is not set
-# CONFIG_IP1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_VIA_VELOCITY is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
-# CONFIG_QLA3XXX is not set
-# CONFIG_ATL1 is not set
-CONFIG_SYNOPSYS_GMAC=y
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-
-#
-# 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_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NET_FC is not set
-# CONFIG_SHAPER 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
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_POLLDEV is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# 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 is not set
-
-#
-# Hardware I/O ports
-#
-# CONFIG_SERIO is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_AMBA_PL010 is not set
-# CONFIG_SERIAL_AMBA_PL011 is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-CONFIG_UNIX98_PTYS=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=m
-# CONFIG_NVRAM is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_TCG_TPM is not set
-CONFIG_DEVPORT=y
-CONFIG_I2C=m
-CONFIG_I2C_BOARDINFO=y
-# CONFIG_I2C_CHARDEV is not set
-
-#
-# I2C Algorithms
-#
-CONFIG_I2C_ALGOBIT=m
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
-# CONFIG_I2C_ALGOOXSEMI is not set
-
-#
-# I2C Hardware Bus support
-#
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI1563 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_NFORCE2 is not set
-CONFIG_I2C_OXNAS_BITBASH=m
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_I2C_SIMTEC is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_TINY_USB is not set
-# CONFIG_I2C_VIA is not set
-# CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_VOODOO3 is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
-# CONFIG_DS1682 is not set
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 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
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
-# CONFIG_WATCHDOG is not set
-
-#
-# Sonics Silicon Backplane
-#
-CONFIG_SSB_POSSIBLE=y
-# CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_SM501 is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
-# CONFIG_USB_DABUSB is not set
-
-#
-# Graphics support
-#
-# CONFIG_DRM is not set
-# CONFIG_VGASTATE is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-# 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_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-# CONFIG_HID_SUPPORT is not set
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARCH_HAS_EHCI=y
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_DEVICE_CLASS=y
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_OTG is not set
-
-#
-# USB Host Controller Drivers
-#
-CONFIG_USB_EHCI_HCD=m
-# CONFIG_USB_EHCI_SPLIT_ISO is not set
-CONFIG_USB_EHCI_ROOT_HUB_TT=y
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-# CONFIG_USB_ISP116X_HCD is not set
-# CONFIG_USB_OHCI_HCD is not set
-# CONFIG_USB_UHCI_HCD is not set
-# CONFIG_USB_SL811_HCD is not set
-# CONFIG_USB_R8A66597_HCD is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# may also be needed; see USB_STORAGE Help for more information
-#
-CONFIG_USB_STORAGE=m
-# 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
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_ALAUDA is not set
-# CONFIG_USB_STORAGE_KARMA is not set
-# CONFIG_USB_LIBUSUAL is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_MON is not set
-
-#
-# USB port drivers
-#
-
-#
-# USB Serial Converter support
-#
-# 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_AUERSWALD 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_PHIDGET 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=m
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-# CONFIG_MMC is not set
-# CONFIG_NEW_LEDS is not set
-CONFIG_RTC_LIB=y
-CONFIG_RTC_CLASS=m
-
-#
-# 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=m
-# 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
-
-#
-# SPI RTC drivers
-#
-
-#
-# Platform RTC drivers
-#
-# CONFIG_RTC_DRV_CMOS is not set
-# CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_STK17TA8 is not set
-# CONFIG_RTC_DRV_DS1742 is not set
-# CONFIG_RTC_DRV_M48T86 is not set
-# CONFIG_RTC_DRV_M48T59 is not set
-# CONFIG_RTC_DRV_V3020 is not set
-
-#
-# on-CPU RTC drivers
-#
-# CONFIG_RTC_DRV_PL031 is not set
-# CONFIG_DMADEVICES is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-# CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-CONFIG_XFS_FS=y
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_SECURITY is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_GFS2_FS is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-CONFIG_FUSE_FS=y
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-CONFIG_NTFS_FS=m
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_RW is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-CONFIG_HFSPLUS_FS=m
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-CONFIG_NETWORK_FILESYSTEMS=y
-# CONFIG_NFS_FS is not set
-CONFIG_NFSD=m
-CONFIG_NFSD_V2_ACL=y
-CONFIG_NFSD_V3=y
-CONFIG_NFSD_V3_ACL=y
-# CONFIG_NFSD_V4 is not set
-CONFIG_NFSD_TCP=y
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
-CONFIG_NFS_ACL_SUPPORT=m
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_BIND34 is not set
-# 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=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-CONFIG_MAC_PARTITION=y
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-CONFIG_LDM_PARTITION=y
-# CONFIG_LDM_DEBUG is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-CONFIG_EFI_PARTITION=y
-# CONFIG_SYSV68_PARTITION is not set
-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 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=y
-# CONFIG_DLM is not set
-# CONFIG_INSTRUMENTATION is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_WARN_DEPRECATED=y
-CONFIG_ENABLE_MUST_CHECK=y
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_FRAME_POINTER=y
-# CONFIG_SAMPLES is not set
-# CONFIG_DEBUG_USER is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-CONFIG_SECURITY=y
-# CONFIG_SECURITY_NETWORK is not set
-# CONFIG_SECURITY_CAPABILITIES is not set
-CONFIG_SECURITY_TRUSTEES=y
-# CONFIG_SECURITY_TRUSTEES_DEBUG is not set
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=y
-CONFIG_CRYPTO_MANAGER=y
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_XCBC is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_PCBC=m
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_XTS is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
-CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-CONFIG_CRYPTO_ARC4=m
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_SEED is not set
-# CONFIG_CRYPTO_DEFLATE is not set
-CONFIG_CRYPTO_MICHAEL_MIC=m
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_TEST is not set
-# CONFIG_CRYPTO_AUTHENC is not set
-CONFIG_CRYPTO_HW=y
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-CONFIG_CRC_CCITT=y
-# CONFIG_CRC16 is not set
-# CONFIG_CRC_ITU_T is not set
-CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
+++ /dev/null
-diff -Nurd linux-2.6.24/.gitignore linux-2.6.24-oxe810/.gitignore
---- linux-2.6.24/.gitignore 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/.gitignore 1970-01-01 01:00:00.000000000 +0100
-@@ -1,54 +0,0 @@
--#
--# NOTE! Don't add files that are generated in specific
--# subdirectories here. Add them in the ".gitignore" file
--# in that subdirectory instead.
--#
--# Normal rules
--#
--.*
--*.o
--*.o.*
--*.a
--*.s
--*.ko
--*.so
--*.so.dbg
--*.mod.c
--*.i
--*.lst
--*.symtypes
--
--#
--# Top-level generic files
--#
--tags
--TAGS
--vmlinux*
--!vmlinux.lds.S
--System.map
--Module.symvers
--!.gitignore
--
--#
--# Generated include files
--#
--include/asm
--include/asm-*/asm-offsets.h
--include/config
--include/linux/autoconf.h
--include/linux/compile.h
--include/linux/version.h
--include/linux/utsrelease.h
--
--# stgit generated dirs
--patches-*
--
--# quilt's files
--patches
--series
--
--# cscope files
--cscope.*
--
--*.orig
--*.rej
-diff -Nurd linux-2.6.24/.mailmap linux-2.6.24-oxe810/.mailmap
---- linux-2.6.24/.mailmap 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/.mailmap 1970-01-01 01:00:00.000000000 +0100
-@@ -1,98 +0,0 @@
--#
--# This list is used by git-shortlog to fix a few botched name translations
--# in the git archive, either because the author's full name was messed up
--# and/or not always written the same way, making contributions from the
--# same person appearing not to be so or badly displayed.
--#
--# repo-abbrev: /pub/scm/linux/kernel/git/
--#
--
--Aaron Durbin <adurbin@google.com>
--Adam Oldham <oldhamca@gmail.com>
--Adam Radford <aradford@gmail.com>
--Adrian Bunk <bunk@stusta.de>
--Alan Cox <alan@lxorguk.ukuu.org.uk>
--Alan Cox <root@hraefn.swansea.linux.org.uk>
--Aleksey Gorelov <aleksey_gorelov@phoenix.com>
--Al Viro <viro@ftp.linux.org.uk>
--Al Viro <viro@zenIV.linux.org.uk>
--Andreas Herrmann <aherrman@de.ibm.com>
--Andrew Morton <akpm@osdl.org>
--Andrew Vasquez <andrew.vasquez@qlogic.com>
--Andy Adamson <andros@citi.umich.edu>
--Arnaud Patard <arnaud.patard@rtp-net.org>
--Arnd Bergmann <arnd@arndb.de>
--Axel Dyks <xl@xlsigned.net>
--Ben Gardner <bgardner@wabtec.com>
--Ben M Cahill <ben.m.cahill@intel.com>
--Björn Steinbrink <B.Steinbrink@gmx.de>
--Brian Avery <b.avery@hp.com>
--Brian King <brking@us.ibm.com>
--Christoph Hellwig <hch@lst.de>
--Corey Minyard <minyard@acm.org>
--David Brownell <david-b@pacbell.net>
--David Woodhouse <dwmw2@shinybook.infradead.org>
--Domen Puncer <domen@coderock.org>
--Douglas Gilbert <dougg@torque.net>
--Ed L. Cashin <ecashin@coraid.com>
--Evgeniy Polyakov <johnpol@2ka.mipt.ru>
--Felipe W Damasio <felipewd@terra.com.br>
--Felix Kuhling <fxkuehl@gmx.de>
--Felix Moeller <felix@derklecks.de>
--Filipe Lautert <filipe@icewall.org>
--Franck Bui-Huu <vagabon.xyz@gmail.com>
--Frank Zago <fzago@systemfabricworks.com>
--Greg Kroah-Hartman <greg@echidna.(none)>
--Greg Kroah-Hartman <gregkh@suse.de>
--Greg Kroah-Hartman <greg@kroah.com>
--Henk Vergonet <Henk.Vergonet@gmail.com>
--Henrik Kretzschmar <henne@nachtwindheim.de>
--Herbert Xu <herbert@gondor.apana.org.au>
--Jacob Shin <Jacob.Shin@amd.com>
--James Bottomley <jejb@mulgrave.(none)>
--James Bottomley <jejb@titanic.il.steeleye.com>
--James E Wilson <wilson@specifix.com>
--James Ketrenos <jketreno@io.(none)>
--Jean Tourrilhes <jt@hpl.hp.com>
--Jeff Garzik <jgarzik@pretzel.yyz.us>
--Jens Axboe <axboe@suse.de>
--Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
--John Stultz <johnstul@us.ibm.com>
--Juha Yrjola <at solidboot.com>
--Juha Yrjola <juha.yrjola@nokia.com>
--Juha Yrjola <juha.yrjola@solidboot.com>
--Kay Sievers <kay.sievers@vrfy.org>
--Kenneth W Chen <kenneth.w.chen@intel.com>
--Koushik <raghavendra.koushik@neterion.com>
--Leonid I Ananiev <leonid.i.ananiev@intel.com>
--Linas Vepstas <linas@austin.ibm.com>
--Matthieu CASTET <castet.matthieu@free.fr>
--Michael Buesch <mb@bu3sch.de>
--Michael Buesch <mbuesch@freenet.de>
--Michel Dänzer <michel@tungstengraphics.com>
--Mitesh shah <mshah@teja.com>
--Morten Welinder <terra@gnome.org>
--Morten Welinder <welinder@anemone.rentec.com>
--Morten Welinder <welinder@darter.rentec.com>
--Morten Welinder <welinder@troll.com>
--Nguyen Anh Quynh <aquynh@gmail.com>
--Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
--Patrick Mochel <mochel@digitalimplant.org>
--Peter A Jonsson <pj@ludd.ltu.se>
--Praveen BP <praveenbp@ti.com>
--Rajesh Shah <rajesh.shah@intel.com>
--Ralf Baechle <ralf@linux-mips.org>
--Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
--Rémi Denis-Courmont <rdenis@simphalempin.com>
--Rudolf Marek <R.Marek@sh.cvut.cz>
--Rui Saraiva <rmps@joel.ist.utl.pt>
--Sachin P Sant <ssant@in.ibm.com>
--Sam Ravnborg <sam@mars.ravnborg.org>
--Simon Kelley <simon@thekelleys.org.uk>
--Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr>
--Stephen Hemminger <shemminger@osdl.org>
--Tejun Heo <htejun@gmail.com>
--Thomas Graf <tgraf@suug.ch>
--Tony Luck <tony.luck@intel.com>
--Tsuneo Yoshioka <Tsuneo.Yoshioka@f-secure.com>
--Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
-diff -Nurd linux-2.6.24/Documentation/video4linux/CARDLIST.cx23885 linux-2.6.24-oxe810/Documentation/video4linux/CARDLIST.cx23885
---- linux-2.6.24/Documentation/video4linux/CARDLIST.cx23885 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/Documentation/video4linux/CARDLIST.cx23885 2008-06-11 17:47:23.000000000 +0200
-@@ -1,5 +1,5 @@
- 0 -> UNKNOWN/GENERIC [0070:3400]
- 1 -> Hauppauge WinTV-HVR1800lp [0070:7600]
-- 2 -> Hauppauge WinTV-HVR1800 [0070:7800,0070:7801]
-+ 2 -> Hauppauge WinTV-HVR1800 [0070:7800,0070:7801,0070:7809]
- 3 -> Hauppauge WinTV-HVR1250 [0070:7911]
- 4 -> DViCO FusionHDTV5 Express [18ac:d500]
-diff -Nurd linux-2.6.24/Makefile linux-2.6.24-oxe810/Makefile
---- linux-2.6.24/Makefile 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/Makefile 2008-06-11 17:50:34.000000000 +0200
-@@ -1,8 +1,8 @@
- VERSION = 2
- PATCHLEVEL = 6
- SUBLEVEL = 24
--EXTRAVERSION =
--NAME = Arr Matey! A Hairy Bilge Rat!
-+EXTRAVERSION = .4
-+NAME = Err Metey! A Heury Beelge-a Ret!
-
- # *DOCUMENTATION*
- # To see a list of typical targets execute "make help"
-@@ -190,8 +190,8 @@
- # Default value for CROSS_COMPILE is not to prefix executables
- # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
-
--ARCH ?= $(SUBARCH)
--CROSS_COMPILE ?=
-+ARCH ?= arm
-+CROSS_COMPILE ?= arm-linux-uclibcgnueabi-
-
- # Architecture as present in compile.h
- UTS_MACHINE := $(ARCH)
-diff -Nurd linux-2.6.24/arch/arm/Kconfig linux-2.6.24-oxe810/arch/arm/Kconfig
---- linux-2.6.24/arch/arm/Kconfig 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/Kconfig 2008-06-11 17:47:58.000000000 +0200
-@@ -409,6 +409,10 @@
- help
- Support for TI's OMAP platform (OMAP1 and OMAP2).
-
-+config ARCH_OXNAS
-+ bool "Oxford Semiconductor NAS SoC"
-+ help
-+ This enables support for Oxsemi NAS SoC
- endchoice
-
- source "arch/arm/mach-clps711x/Kconfig"
-@@ -461,6 +465,8 @@
-
- source "arch/arm/mach-versatile/Kconfig"
-
-+source "arch/arm/mach-oxnas/Kconfig"
-+
- source "arch/arm/mach-aaec2000/Kconfig"
-
- source "arch/arm/mach-realview/Kconfig"
-@@ -537,7 +543,7 @@
- bool
-
- config PCI
-- bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE
-+ bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE || ARCH_OXNAS
- help
- Find out whether you have a PCI motherboard. PCI is the name of a
- bus system, i.e. the way the CPU talks to the other stuff inside
-@@ -653,11 +659,13 @@
- to have accurate timekeeping with dynamic tick.
-
- config HZ
-- int
-+ int "Kernel timer tick rate"
- default 128 if ARCH_L7200
- default 200 if ARCH_EBSA110 || ARCH_S3C2410
- default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER
- default 100
-+ help
-+ Sets the number of timer tick interrupts per second
-
- config AEABI
- bool "Use the ARM EABI to compile the kernel"
-@@ -1010,7 +1018,7 @@
- if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \
- || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
- || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
-- || ARCH_IXP23XX
-+ || ARCH_IXP23XX || ARCH_OXNAS
- source "drivers/ide/Kconfig"
- endif
-
-diff -Nurd linux-2.6.24/arch/arm/Makefile linux-2.6.24-oxe810/arch/arm/Makefile
---- linux-2.6.24/arch/arm/Makefile 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/Makefile 2008-06-11 17:47:58.000000000 +0200
-@@ -127,6 +127,7 @@
- machine-$(CONFIG_ARCH_VERSATILE) := versatile
- machine-$(CONFIG_ARCH_IMX) := imx
- machine-$(CONFIG_ARCH_H720X) := h720x
-+ machine-$(CONFIG_ARCH_OXNAS) := oxnas
- machine-$(CONFIG_ARCH_AAEC2000) := aaec2000
- machine-$(CONFIG_ARCH_REALVIEW) := realview
- machine-$(CONFIG_ARCH_AT91) := at91
-diff -Nurd linux-2.6.24/arch/arm/configs/oxnas_810_eabi_dse_defconfig linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_dse_defconfig
---- linux-2.6.24/arch/arm/configs/oxnas_810_eabi_dse_defconfig 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_dse_defconfig 2008-06-11 17:47:52.000000000 +0200
-@@ -0,0 +1,1233 @@
-+#
-+# Automatically generated make config: don't edit
-+# Linux kernel version: 2.6.24.4
-+# Mon Jun 2 12:34:33 2008
-+#
-+CONFIG_ARM=y
-+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-+# CONFIG_GENERIC_GPIO is not set
-+# CONFIG_GENERIC_TIME is not set
-+# CONFIG_GENERIC_CLOCKEVENTS is not set
-+CONFIG_MMU=y
-+# CONFIG_NO_IOPORT is not set
-+CONFIG_GENERIC_HARDIRQS=y
-+CONFIG_STACKTRACE_SUPPORT=y
-+CONFIG_LOCKDEP_SUPPORT=y
-+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-+CONFIG_HARDIRQS_SW_RESEND=y
-+CONFIG_GENERIC_IRQ_PROBE=y
-+CONFIG_RWSEM_GENERIC_SPINLOCK=y
-+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-+CONFIG_GENERIC_HWEIGHT=y
-+CONFIG_GENERIC_CALIBRATE_DELAY=y
-+CONFIG_ZONE_DMA=y
-+CONFIG_VECTORS_BASE=0xffff0000
-+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-+
-+#
-+# General setup
-+#
-+CONFIG_EXPERIMENTAL=y
-+CONFIG_BROKEN_ON_SMP=y
-+CONFIG_INIT_ENV_ARG_LIMIT=32
-+CONFIG_LOCALVERSION=""
-+CONFIG_LOCALVERSION_AUTO=y
-+CONFIG_SWAP=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_USER_NS is not set
-+# CONFIG_PID_NS is not set
-+# CONFIG_AUDIT is not set
-+# CONFIG_IKCONFIG is not set
-+CONFIG_LOG_BUF_SHIFT=14
-+# CONFIG_CGROUPS is not set
-+# CONFIG_FAIR_GROUP_SCHED is not set
-+# CONFIG_FAIR_USER_SCHED is not set
-+# CONFIG_FAIR_CGROUP_SCHED is not set
-+CONFIG_SYSFS_DEPRECATED=y
-+# CONFIG_RELAY is not set
-+CONFIG_BLK_DEV_INITRD=y
-+CONFIG_INITRAMFS_SOURCE=""
-+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-+CONFIG_SYSCTL=y
-+# CONFIG_EMBEDDED is not set
-+CONFIG_UID16=y
-+CONFIG_SYSCTL_SYSCALL=y
-+CONFIG_KALLSYMS=y
-+# 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_ANON_INODES=y
-+CONFIG_EPOLL=y
-+CONFIG_SIGNALFD=y
-+CONFIG_EVENTFD=y
-+CONFIG_SHMEM=y
-+CONFIG_VM_EVENT_COUNTERS=y
-+CONFIG_SLAB=y
-+# CONFIG_SLUB is not set
-+# CONFIG_SLOB is not set
-+CONFIG_SLABINFO=y
-+CONFIG_RT_MUTEXES=y
-+# CONFIG_TINY_SHMEM is not set
-+CONFIG_BASE_SMALL=0
-+CONFIG_MODULES=y
-+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 is not set
-+CONFIG_BLOCK=y
-+# CONFIG_LBD is not set
-+# CONFIG_BLK_DEV_IO_TRACE is not set
-+# CONFIG_LSF is not set
-+# CONFIG_BLK_DEV_BSG is not set
-+
-+#
-+# IO Schedulers
-+#
-+CONFIG_IOSCHED_NOOP=y
-+CONFIG_IOSCHED_AS=y
-+CONFIG_IOSCHED_DEADLINE=y
-+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"
-+
-+#
-+# System Type
-+#
-+# CONFIG_ARCH_AAEC2000 is not set
-+# CONFIG_ARCH_INTEGRATOR is not set
-+# CONFIG_ARCH_REALVIEW is not set
-+# CONFIG_ARCH_VERSATILE is not set
-+# CONFIG_ARCH_AT91 is not set
-+# CONFIG_ARCH_CLPS7500 is not set
-+# CONFIG_ARCH_CLPS711X is not set
-+# CONFIG_ARCH_CO285 is not set
-+# CONFIG_ARCH_EBSA110 is not set
-+# CONFIG_ARCH_EP93XX is not set
-+# CONFIG_ARCH_FOOTBRIDGE is not set
-+# CONFIG_ARCH_NETX is not set
-+# CONFIG_ARCH_H720X is not set
-+# CONFIG_ARCH_IMX is not set
-+# CONFIG_ARCH_IOP13XX is not set
-+# CONFIG_ARCH_IOP32X is not set
-+# CONFIG_ARCH_IOP33X is not set
-+# CONFIG_ARCH_IXP23XX is not set
-+# CONFIG_ARCH_IXP2000 is not set
-+# CONFIG_ARCH_IXP4XX is not set
-+# CONFIG_ARCH_L7200 is not set
-+# CONFIG_ARCH_KS8695 is not set
-+# CONFIG_ARCH_NS9XXX is not set
-+# CONFIG_ARCH_MXC is not set
-+# CONFIG_ARCH_PNX4008 is not set
-+# CONFIG_ARCH_PXA is not set
-+# CONFIG_ARCH_RPC is not set
-+# CONFIG_ARCH_SA1100 is not set
-+# CONFIG_ARCH_S3C2410 is not set
-+# CONFIG_ARCH_SHARK is not set
-+# CONFIG_ARCH_LH7A40X is not set
-+# CONFIG_ARCH_DAVINCI is not set
-+# CONFIG_ARCH_OMAP is not set
-+CONFIG_ARCH_OXNAS=y
-+
-+#
-+# Boot options
-+#
-+
-+#
-+# Power management
-+#
-+
-+#
-+# Oxford Semiconductor NAS Options
-+#
-+# CONFIG_ARCH_OXNAS_FPGA is not set
-+CONFIG_NOMINAL_PLL400_FREQ=733333333
-+CONFIG_NOMINAL_RPSCLK_FREQ=25000000
-+# CONFIG_OXNAS_VERSION_0X800 is not set
-+CONFIG_OXNAS_VERSION_0X810=y
-+# CONFIG_OXNAS_VERSION_0X850 is not set
-+# CONFIG_ARCH_OXNAS_UART1 is not set
-+CONFIG_ARCH_OXNAS_UART2=y
-+# CONFIG_ARCH_OXNAS_UART2_MODEM is not set
-+# CONFIG_ARCH_OXNAS_UART3 is not set
-+# CONFIG_ARCH_OXNAS_PCI_REQGNT_0 is not set
-+# CONFIG_ARCH_OXNAS_PCI_REQGNT_1 is not set
-+# CONFIG_ARCH_OXNAS_PCI_REQGNT_2 is not set
-+# CONFIG_ARCH_OXNAS_PCI_REQGNT_3 is not set
-+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_0 is not set
-+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_1 is not set
-+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_2 is not set
-+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_3 is not set
-+# CONFIG_OXNAS_PCI_RESET is not set
-+CONFIG_FORCE_MAX_ZONEORDER=10
-+CONFIG_SRAM_NUM_PAGES=32
-+CONFIG_SUPPORT_LEON=y
-+CONFIG_LEON_PAGES=2
-+CONFIG_LEON_COPRO=y
-+CONFIG_LEON_OFFLOAD_TX=y
-+# CONFIG_LEON_RESERVE_DMA_CHANNEL is not set
-+CONFIG_LEON_OFFLOAD_TSO=y
-+# CONFIG_LEON_START_EARLY is not set
-+CONFIG_LEON_POWER_BUTTON_MONITOR=m
-+CONFIG_OXNAS_POWER_BUTTON_GPIO=4
-+CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
-+CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO=32
-+# CONFIG_OXNAS_DDR_MON is not set
-+# CONFIG_OXNAS_AHB_MON is not set
-+# CONFIG_OXNAS_CACHE_LOCKDOWN is not set
-+# CONFIG_DO_MEM_TEST is not set
-+# CONFIG_CRYPTO_OXAESLRW is not set
-+CONFIG_DESCRIPTORS_PAGES=6
-+CONFIG_ARCH_OXNAS_NUM_GMAC_DESCRIPTORS=192
-+CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES=256
-+CONFIG_TACHO_THERM_AND_FAN=m
-+# CONFIG_GPIO_TEST is not set
-+CONFIG_OXNAS_RTC=m
-+# CONFIG_I2S is not set
-+# CONFIG_DPE_TEST is not set
-+# CONFIG_OXNAS_INSTRUMENT_COPIES is not set
-+# CONFIG_OXNAS_DMA_COPIES is not set
-+# CONFIG_OXNAS_AHB_MONITOR_MODULE is not set
-+# CONFIG_OXNAS_USB_TEST_MODES is not set
-+# CONFIG_OXNAS_FRONT_LAMP_CONTROL is not set
-+# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
-+# CONFIG_OXNAS_LED_TEST is not set
-+CONFIG_OXNAS_I2C_SDA=6
-+CONFIG_OXNAS_I2C_SCL=7
-+# CONFIG_OXNAS_USB_PORTA_POWER_CONTROL is not set
-+# CONFIG_OXNAS_USB_PORTB_POWER_CONTROL is not set
-+# CONFIG_OXNAS_USB_PORTC_POWER_CONTROL is not set
-+# CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE is not set
-+# CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE is not set
-+# CONFIG_WDC_FAN_OXNAS800 is not set
-+# CONFIG_OXNAS_MAP_SRAM is not set
-+# CONFIG_OXNAS_SUID_INHERIT is not set
-+# CONFIG_OXNAS_USB_HUB_SUPPORT is not set
-+
-+#
-+# Processor Type
-+#
-+CONFIG_CPU_32=y
-+CONFIG_CPU_ARM926T=y
-+CONFIG_CPU_32v5=y
-+CONFIG_CPU_ABRT_EV5TJ=y
-+CONFIG_CPU_CACHE_VIVT=y
-+CONFIG_CPU_COPY_V4WB=y
-+CONFIG_CPU_TLB_V4WBI=y
-+CONFIG_CPU_CP15=y
-+CONFIG_CPU_CP15_MMU=y
-+
-+#
-+# Processor Features
-+#
-+CONFIG_ARM_THUMB=y
-+# CONFIG_CPU_ICACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-+# CONFIG_OUTER_CACHE is not set
-+
-+#
-+# Bus support
-+#
-+CONFIG_ARM_AMBA=y
-+CONFIG_PCI=y
-+CONFIG_PCI_SYSCALL=y
-+# CONFIG_ARCH_SUPPORTS_MSI is not set
-+CONFIG_PCI_LEGACY=y
-+# CONFIG_PCCARD is not set
-+
-+#
-+# Kernel Features
-+#
-+# CONFIG_TICK_ONESHOT is not set
-+# CONFIG_PREEMPT is not set
-+# CONFIG_NO_IDLE_HZ is not set
-+CONFIG_HZ=100
-+CONFIG_AEABI=y
-+# CONFIG_OABI_COMPAT is not set
-+# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPARSEMEM_STATIC is not set
-+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
-+CONFIG_SPLIT_PTLOCK_CPUS=4096
-+# CONFIG_RESOURCES_64BIT is not set
-+CONFIG_ZONE_DMA_FLAG=1
-+CONFIG_BOUNCE=y
-+CONFIG_VIRT_TO_BUS=y
-+CONFIG_ALIGNMENT_TRAP=y
-+
-+#
-+# Boot options
-+#
-+CONFIG_ZBOOT_ROM_TEXT=0x0
-+CONFIG_ZBOOT_ROM_BSS=0x0
-+CONFIG_CMDLINE=""
-+# CONFIG_XIP_KERNEL is not set
-+# CONFIG_KEXEC is not set
-+
-+#
-+# Floating point emulation
-+#
-+
-+#
-+# At least one emulation must be selected
-+#
-+# CONFIG_VFP is not set
-+
-+#
-+# Userspace binary formats
-+#
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_AOUT is not set
-+# CONFIG_BINFMT_MISC is not set
-+
-+#
-+# Power management options
-+#
-+# CONFIG_PM is not set
-+CONFIG_SUSPEND_UP_POSSIBLE=y
-+
-+#
-+# Networking
-+#
-+CONFIG_NET=y
-+
-+#
-+# Networking options
-+#
-+CONFIG_PACKET=y
-+CONFIG_PACKET_MMAP=y
-+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_NET_KEY is not set
-+CONFIG_INET=y
-+CONFIG_IP_MULTICAST=y
-+# CONFIG_IP_ADVANCED_ROUTER is not set
-+CONFIG_IP_FIB_HASH=y
-+# CONFIG_IP_PNP is not set
-+# CONFIG_NET_IPIP is not set
-+# CONFIG_NET_IPGRE is not set
-+# CONFIG_IP_MROUTE 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=y
-+CONFIG_INET_XFRM_MODE_TUNNEL=y
-+CONFIG_INET_XFRM_MODE_BEET=y
-+# CONFIG_INET_LRO is not set
-+CONFIG_INET_DIAG=y
-+CONFIG_INET_TCP_DIAG=y
-+# CONFIG_TCP_CONG_ADVANCED is not set
-+CONFIG_TCP_CONG_CUBIC=y
-+CONFIG_DEFAULT_TCP_CONG="cubic"
-+# CONFIG_TCP_MD5SIG is not set
-+# CONFIG_IP_VS is not set
-+# CONFIG_IPV6 is not set
-+# CONFIG_INET6_XFRM_TUNNEL is not set
-+# CONFIG_INET6_TUNNEL is not set
-+# CONFIG_NETLABEL is not set
-+# CONFIG_NETWORK_SECMARK is not set
-+CONFIG_NETFILTER=y
-+# CONFIG_NETFILTER_DEBUG is not set
-+
-+#
-+# Core Netfilter Configuration
-+#
-+# CONFIG_NETFILTER_NETLINK is not set
-+# CONFIG_NF_CONNTRACK_ENABLED is not set
-+# CONFIG_NF_CONNTRACK is not set
-+# CONFIG_NETFILTER_XTABLES is not set
-+
-+#
-+# IP: Netfilter Configuration
-+#
-+# CONFIG_IP_NF_QUEUE is not set
-+# CONFIG_IP_NF_IPTABLES is not set
-+# CONFIG_IP_NF_ARPTABLES is not set
-+# CONFIG_IP_DCCP is not set
-+# CONFIG_IP_SCTP is not set
-+# CONFIG_TIPC is not set
-+# CONFIG_ATM is not set
-+# CONFIG_BRIDGE 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_NET_SCHED is not set
-+
-+#
-+# Network testing
-+#
-+# CONFIG_NET_PKTGEN is not set
-+# CONFIG_HAMRADIO is not set
-+# CONFIG_IRDA is not set
-+# CONFIG_BT is not set
-+# CONFIG_AF_RXRPC is not set
-+
-+#
-+# Wireless
-+#
-+# CONFIG_CFG80211 is not set
-+CONFIG_WIRELESS_EXT=y
-+# CONFIG_MAC80211 is not set
-+# CONFIG_IEEE80211 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=y
-+# CONFIG_SYS_HYPERVISOR is not set
-+# CONFIG_CONNECTOR is not set
-+# CONFIG_MTD is not set
-+# CONFIG_PARPORT is not set
-+CONFIG_BLK_DEV=y
-+# CONFIG_BLK_CPQ_DA is not set
-+# CONFIG_BLK_CPQ_CISS_DA is not set
-+# CONFIG_BLK_DEV_DAC960 is not set
-+# CONFIG_BLK_DEV_UMEM is not set
-+# CONFIG_BLK_DEV_COW_COMMON is not set
-+CONFIG_BLK_DEV_LOOP=y
-+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-+# CONFIG_BLK_DEV_NBD is not set
-+# CONFIG_BLK_DEV_SX8 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=10240
-+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-+# CONFIG_CDROM_PKTCDVD is not set
-+# CONFIG_ATA_OVER_ETH is not set
-+# CONFIG_MISC_DEVICES is not set
-+# 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=y
-+
-+#
-+# 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 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=y
-+# 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=y
-+# CONFIG_ISCSI_TCP is not set
-+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-+# CONFIG_SCSI_3W_9XXX is not set
-+# CONFIG_SCSI_ACARD is not set
-+# CONFIG_SCSI_AACRAID is not set
-+# CONFIG_SCSI_AIC7XXX is not set
-+# CONFIG_SCSI_AIC7XXX_OLD is not set
-+# CONFIG_SCSI_AIC79XX is not set
-+# CONFIG_SCSI_AIC94XX is not set
-+# CONFIG_SCSI_DPT_I2O is not set
-+# CONFIG_SCSI_ADVANSYS is not set
-+# CONFIG_SCSI_ARCMSR is not set
-+# CONFIG_MEGARAID_NEWGEN is not set
-+# CONFIG_MEGARAID_LEGACY is not set
-+# CONFIG_MEGARAID_SAS is not set
-+# CONFIG_SCSI_HPTIOP is not set
-+# CONFIG_SCSI_DMX3191D is not set
-+# CONFIG_SCSI_FUTURE_DOMAIN is not set
-+# CONFIG_SCSI_IPS is not set
-+# CONFIG_SCSI_INITIO is not set
-+# CONFIG_SCSI_INIA100 is not set
-+# CONFIG_SCSI_STEX is not set
-+# CONFIG_SCSI_SYM53C8XX_2 is not set
-+# CONFIG_SCSI_IPR is not set
-+# CONFIG_SCSI_QLOGIC_1280 is not set
-+# CONFIG_SCSI_QLA_FC is not set
-+# CONFIG_SCSI_QLA_ISCSI is not set
-+# CONFIG_SCSI_LPFC is not set
-+# CONFIG_SCSI_DC395x is not set
-+# CONFIG_SCSI_DC390T is not set
-+# CONFIG_SCSI_NSP32 is not set
-+# CONFIG_SCSI_DEBUG is not set
-+# CONFIG_SCSI_SRP is not set
-+CONFIG_ATA=y
-+# CONFIG_ATA_NONSTANDARD is not set
-+# CONFIG_SATA_AHCI is not set
-+# CONFIG_SATA_SVW is not set
-+# CONFIG_ATA_PIIX is not set
-+# CONFIG_SATA_MV is not set
-+# CONFIG_SATA_NV is not set
-+# CONFIG_PDC_ADMA is not set
-+# CONFIG_SATA_QSTOR is not set
-+# CONFIG_SATA_PROMISE is not set
-+# CONFIG_SATA_SX4 is not set
-+# CONFIG_SATA_SIL is not set
-+# CONFIG_SATA_SIL24 is not set
-+# CONFIG_SATA_SIS is not set
-+# CONFIG_SATA_ULI is not set
-+# CONFIG_SATA_VIA is not set
-+# CONFIG_SATA_VITESSE is not set
-+# CONFIG_SATA_INIC162X is not set
-+CONFIG_SATA_OX810=y
-+# CONFIG_SATA_OXNAS_SINGLE_SATA is not set
-+# CONFIG_SATA_OXNAS_DISK_LIGHT is not set
-+# CONFIG_PATA_ALI is not set
-+# CONFIG_PATA_AMD is not set
-+# CONFIG_PATA_ARTOP is not set
-+# CONFIG_PATA_ATIIXP is not set
-+# CONFIG_PATA_CMD640_PCI is not set
-+# CONFIG_PATA_CMD64X is not set
-+# CONFIG_PATA_CS5520 is not set
-+# CONFIG_PATA_CS5530 is not set
-+# CONFIG_PATA_CYPRESS is not set
-+# CONFIG_PATA_EFAR is not set
-+# CONFIG_ATA_GENERIC is not set
-+# CONFIG_PATA_HPT366 is not set
-+# CONFIG_PATA_HPT37X is not set
-+# CONFIG_PATA_HPT3X2N is not set
-+# CONFIG_PATA_HPT3X3 is not set
-+# CONFIG_PATA_IT821X is not set
-+# CONFIG_PATA_IT8213 is not set
-+# CONFIG_PATA_JMICRON is not set
-+# CONFIG_PATA_TRIFLEX is not set
-+# CONFIG_PATA_MARVELL is not set
-+# CONFIG_PATA_MPIIX is not set
-+# CONFIG_PATA_OLDPIIX is not set
-+# CONFIG_PATA_NETCELL is not set
-+# CONFIG_PATA_NS87410 is not set
-+# CONFIG_PATA_NS87415 is not set
-+# CONFIG_PATA_OPTI is not set
-+# CONFIG_PATA_OPTIDMA is not set
-+# CONFIG_PATA_PDC_OLD is not set
-+# CONFIG_PATA_RADISYS is not set
-+# CONFIG_PATA_RZ1000 is not set
-+# CONFIG_PATA_SC1200 is not set
-+# CONFIG_PATA_SERVERWORKS is not set
-+# CONFIG_PATA_PDC2027X is not set
-+# CONFIG_PATA_SIL680 is not set
-+# CONFIG_PATA_SIS is not set
-+# CONFIG_PATA_VIA is not set
-+# CONFIG_PATA_WINBOND is not set
-+CONFIG_MD=y
-+CONFIG_BLK_DEV_MD=y
-+CONFIG_MD_LINEAR=y
-+# CONFIG_MD_RAID0 is not set
-+CONFIG_MD_RAID1=y
-+# CONFIG_MD_RAID10 is not set
-+# CONFIG_MD_RAID456 is not set
-+# CONFIG_MD_MULTIPATH is not set
-+# CONFIG_MD_FAULTY is not set
-+CONFIG_BLK_DEV_DM=y
-+# CONFIG_DM_DEBUG is not set
-+CONFIG_DM_CRYPT=y
-+# CONFIG_DM_SNAPSHOT is not set
-+# CONFIG_DM_MIRROR is not set
-+# CONFIG_DM_ZERO is not set
-+# CONFIG_DM_MULTIPATH is not set
-+# CONFIG_DM_DELAY is not set
-+# CONFIG_DM_UEVENT is not set
-+# CONFIG_FUSION is not set
-+
-+#
-+# IEEE 1394 (FireWire) support
-+#
-+# CONFIG_FIREWIRE is not set
-+# CONFIG_IEEE1394 is not set
-+# CONFIG_I2O is not set
-+CONFIG_NETDEVICES=y
-+# CONFIG_NETDEVICES_MULTIQUEUE is not set
-+# 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_ARCNET is not set
-+# CONFIG_NET_ETHERNET is not set
-+CONFIG_MII=y
-+CONFIG_NETDEV_1000=y
-+# CONFIG_ACENIC is not set
-+# CONFIG_DL2K is not set
-+# CONFIG_E1000 is not set
-+# CONFIG_E1000E is not set
-+# CONFIG_IP1000 is not set
-+# CONFIG_NS83820 is not set
-+# CONFIG_HAMACHI is not set
-+# CONFIG_YELLOWFIN is not set
-+# CONFIG_R8169 is not set
-+# CONFIG_SIS190 is not set
-+# CONFIG_SKGE is not set
-+# CONFIG_SKY2 is not set
-+# CONFIG_SK98LIN is not set
-+# CONFIG_VIA_VELOCITY is not set
-+# CONFIG_TIGON3 is not set
-+# CONFIG_BNX2 is not set
-+# CONFIG_QLA3XXX is not set
-+# CONFIG_ATL1 is not set
-+CONFIG_SYNOPSYS_GMAC=y
-+# CONFIG_NETDEV_10000 is not set
-+# CONFIG_TR is not set
-+
-+#
-+# Wireless LAN
-+#
-+# CONFIG_WLAN_PRE80211 is not set
-+# CONFIG_WLAN_80211 is not set
-+
-+#
-+# 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_FDDI is not set
-+# CONFIG_HIPPI is not set
-+# CONFIG_PPP is not set
-+# CONFIG_SLIP is not set
-+# CONFIG_NET_FC is not set
-+# CONFIG_SHAPER 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
-+
-+#
-+# Input device support
-+#
-+CONFIG_INPUT=y
-+# CONFIG_INPUT_FF_MEMLESS is not set
-+# CONFIG_INPUT_POLLDEV is not set
-+
-+#
-+# Userland interfaces
-+#
-+CONFIG_INPUT_MOUSEDEV=y
-+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-+# 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 is not set
-+
-+#
-+# Hardware I/O ports
-+#
-+# CONFIG_SERIO is not set
-+# CONFIG_GAMEPORT is not set
-+
-+#
-+# Character devices
-+#
-+CONFIG_VT=y
-+CONFIG_VT_CONSOLE=y
-+CONFIG_HW_CONSOLE=y
-+# CONFIG_VT_HW_CONSOLE_BINDING is not set
-+# CONFIG_SERIAL_NONSTANDARD is not set
-+
-+#
-+# Serial drivers
-+#
-+CONFIG_SERIAL_8250=y
-+CONFIG_SERIAL_8250_CONSOLE=y
-+CONFIG_SERIAL_8250_PCI=y
-+CONFIG_SERIAL_8250_NR_UARTS=4
-+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-+# CONFIG_SERIAL_8250_EXTENDED is not set
-+
-+#
-+# Non-8250 serial port support
-+#
-+# CONFIG_SERIAL_AMBA_PL010 is not set
-+# CONFIG_SERIAL_AMBA_PL011 is not set
-+CONFIG_SERIAL_CORE=y
-+CONFIG_SERIAL_CORE_CONSOLE=y
-+# CONFIG_SERIAL_JSM is not set
-+CONFIG_UNIX98_PTYS=y
-+# CONFIG_LEGACY_PTYS is not set
-+# CONFIG_IPMI_HANDLER is not set
-+CONFIG_HW_RANDOM=m
-+# CONFIG_NVRAM is not set
-+# CONFIG_R3964 is not set
-+# CONFIG_APPLICOM is not set
-+# CONFIG_RAW_DRIVER is not set
-+# CONFIG_TCG_TPM is not set
-+CONFIG_DEVPORT=y
-+CONFIG_I2C=m
-+CONFIG_I2C_BOARDINFO=y
-+# CONFIG_I2C_CHARDEV is not set
-+
-+#
-+# I2C Algorithms
-+#
-+CONFIG_I2C_ALGOBIT=m
-+# CONFIG_I2C_ALGOPCF is not set
-+# CONFIG_I2C_ALGOPCA is not set
-+# CONFIG_I2C_ALGOOXSEMI is not set
-+
-+#
-+# I2C Hardware Bus support
-+#
-+# CONFIG_I2C_ALI1535 is not set
-+# CONFIG_I2C_ALI1563 is not set
-+# CONFIG_I2C_ALI15X3 is not set
-+# CONFIG_I2C_AMD756 is not set
-+# CONFIG_I2C_AMD8111 is not set
-+# CONFIG_I2C_I801 is not set
-+# CONFIG_I2C_I810 is not set
-+# CONFIG_I2C_PIIX4 is not set
-+# CONFIG_I2C_NFORCE2 is not set
-+CONFIG_I2C_OXNAS_BITBASH=m
-+# CONFIG_I2C_OCORES is not set
-+# CONFIG_I2C_PARPORT_LIGHT is not set
-+# CONFIG_I2C_PROSAVAGE is not set
-+# CONFIG_I2C_SAVAGE4 is not set
-+# CONFIG_I2C_SIMTEC is not set
-+# CONFIG_I2C_SIS5595 is not set
-+# CONFIG_I2C_SIS630 is not set
-+# CONFIG_I2C_SIS96X is not set
-+# CONFIG_I2C_TAOS_EVM is not set
-+# CONFIG_I2C_STUB is not set
-+# CONFIG_I2C_TINY_USB is not set
-+# CONFIG_I2C_VIA is not set
-+# CONFIG_I2C_VIAPRO is not set
-+# CONFIG_I2C_VOODOO3 is not set
-+
-+#
-+# Miscellaneous I2C Chip support
-+#
-+# CONFIG_SENSORS_DS1337 is not set
-+# CONFIG_SENSORS_DS1374 is not set
-+# CONFIG_DS1682 is not set
-+# CONFIG_SENSORS_EEPROM is not set
-+# CONFIG_SENSORS_PCF8574 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
-+# CONFIG_I2C_DEBUG_BUS is not set
-+# CONFIG_I2C_DEBUG_CHIP is not set
-+
-+#
-+# SPI support
-+#
-+# CONFIG_SPI is not set
-+# CONFIG_SPI_MASTER is not set
-+# CONFIG_W1 is not set
-+# CONFIG_POWER_SUPPLY is not set
-+# CONFIG_HWMON is not set
-+# CONFIG_WATCHDOG is not set
-+
-+#
-+# Sonics Silicon Backplane
-+#
-+CONFIG_SSB_POSSIBLE=y
-+# CONFIG_SSB is not set
-+
-+#
-+# Multifunction device drivers
-+#
-+# CONFIG_MFD_SM501 is not set
-+
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
-+# CONFIG_DVB_CORE is not set
-+CONFIG_DAB=y
-+# CONFIG_USB_DABUSB is not set
-+
-+#
-+# Graphics support
-+#
-+# CONFIG_DRM is not set
-+# CONFIG_VGASTATE is not set
-+CONFIG_VIDEO_OUTPUT_CONTROL=m
-+# 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_VGA_CONSOLE is not set
-+CONFIG_DUMMY_CONSOLE=y
-+
-+#
-+# Sound
-+#
-+# CONFIG_SOUND is not set
-+# CONFIG_HID_SUPPORT is not set
-+CONFIG_USB_SUPPORT=y
-+CONFIG_USB_ARCH_HAS_HCD=y
-+CONFIG_USB_ARCH_HAS_OHCI=y
-+CONFIG_USB_ARCH_HAS_EHCI=y
-+CONFIG_USB=m
-+# CONFIG_USB_DEBUG is not set
-+
-+#
-+# Miscellaneous USB options
-+#
-+CONFIG_USB_DEVICEFS=y
-+CONFIG_USB_DEVICE_CLASS=y
-+# CONFIG_USB_DYNAMIC_MINORS is not set
-+# CONFIG_USB_OTG is not set
-+
-+#
-+# USB Host Controller Drivers
-+#
-+CONFIG_USB_EHCI_HCD=m
-+# CONFIG_USB_EHCI_SPLIT_ISO is not set
-+CONFIG_USB_EHCI_ROOT_HUB_TT=y
-+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-+# CONFIG_USB_ISP116X_HCD is not set
-+# CONFIG_USB_OHCI_HCD is not set
-+# CONFIG_USB_UHCI_HCD is not set
-+# CONFIG_USB_SL811_HCD is not set
-+# CONFIG_USB_R8A66597_HCD is not set
-+
-+#
-+# USB Device Class drivers
-+#
-+# CONFIG_USB_ACM is not set
-+# CONFIG_USB_PRINTER is not set
-+
-+#
-+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-+#
-+
-+#
-+# may also be needed; see USB_STORAGE Help for more information
-+#
-+CONFIG_USB_STORAGE=m
-+# 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
-+# CONFIG_USB_STORAGE_JUMPSHOT is not set
-+# CONFIG_USB_STORAGE_ALAUDA is not set
-+# CONFIG_USB_STORAGE_KARMA is not set
-+# CONFIG_USB_LIBUSUAL is not set
-+
-+#
-+# USB Imaging devices
-+#
-+# CONFIG_USB_MDC800 is not set
-+# CONFIG_USB_MICROTEK is not set
-+# CONFIG_USB_MON is not set
-+
-+#
-+# USB port drivers
-+#
-+
-+#
-+# USB Serial Converter support
-+#
-+# 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_AUERSWALD 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_PHIDGET 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=m
-+
-+#
-+# USB DSL modem support
-+#
-+
-+#
-+# USB Gadget Support
-+#
-+# CONFIG_USB_GADGET is not set
-+# CONFIG_MMC is not set
-+# CONFIG_NEW_LEDS is not set
-+CONFIG_RTC_LIB=y
-+CONFIG_RTC_CLASS=m
-+
-+#
-+# 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=m
-+# 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
-+
-+#
-+# SPI RTC drivers
-+#
-+
-+#
-+# Platform RTC drivers
-+#
-+# CONFIG_RTC_DRV_CMOS is not set
-+# CONFIG_RTC_DRV_DS1553 is not set
-+# CONFIG_RTC_DRV_STK17TA8 is not set
-+# CONFIG_RTC_DRV_DS1742 is not set
-+# CONFIG_RTC_DRV_M48T86 is not set
-+# CONFIG_RTC_DRV_M48T59 is not set
-+# CONFIG_RTC_DRV_V3020 is not set
-+
-+#
-+# on-CPU RTC drivers
-+#
-+# CONFIG_RTC_DRV_PL031 is not set
-+# CONFIG_DMADEVICES is not set
-+
-+#
-+# File systems
-+#
-+CONFIG_EXT2_FS=y
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XIP is not set
-+CONFIG_EXT3_FS=y
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT4DEV_FS is not set
-+CONFIG_JBD=y
-+# CONFIG_REISERFS_FS is not set
-+# CONFIG_JFS_FS is not set
-+CONFIG_FS_POSIX_ACL=y
-+CONFIG_XFS_FS=y
-+# CONFIG_XFS_QUOTA is not set
-+# CONFIG_XFS_SECURITY is not set
-+# CONFIG_XFS_POSIX_ACL is not set
-+# CONFIG_XFS_RT is not set
-+# CONFIG_GFS2_FS is not set
-+# CONFIG_OCFS2_FS is not set
-+# CONFIG_MINIX_FS is not set
-+# CONFIG_ROMFS_FS is not set
-+CONFIG_INOTIFY=y
-+CONFIG_INOTIFY_USER=y
-+# CONFIG_QUOTA is not set
-+CONFIG_DNOTIFY=y
-+# CONFIG_AUTOFS_FS is not set
-+# CONFIG_AUTOFS4_FS is not set
-+CONFIG_FUSE_FS=y
-+
-+#
-+# CD-ROM/DVD Filesystems
-+#
-+# CONFIG_ISO9660_FS is not set
-+# CONFIG_UDF_FS is not set
-+
-+#
-+# DOS/FAT/NT Filesystems
-+#
-+CONFIG_FAT_FS=y
-+CONFIG_MSDOS_FS=y
-+CONFIG_VFAT_FS=m
-+CONFIG_FAT_DEFAULT_CODEPAGE=437
-+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-+CONFIG_NTFS_FS=m
-+# CONFIG_NTFS_DEBUG is not set
-+# CONFIG_NTFS_RW is not set
-+
-+#
-+# Pseudo filesystems
-+#
-+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_ADFS_FS is not set
-+# CONFIG_AFFS_FS is not set
-+# CONFIG_HFS_FS is not set
-+CONFIG_HFSPLUS_FS=m
-+# CONFIG_BEFS_FS is not set
-+# CONFIG_BFS_FS is not set
-+# CONFIG_EFS_FS is not set
-+# CONFIG_CRAMFS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_HPFS_FS is not set
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UFS_FS is not set
-+CONFIG_NETWORK_FILESYSTEMS=y
-+# CONFIG_NFS_FS is not set
-+CONFIG_NFSD=m
-+CONFIG_NFSD_V2_ACL=y
-+CONFIG_NFSD_V3=y
-+CONFIG_NFSD_V3_ACL=y
-+# CONFIG_NFSD_V4 is not set
-+CONFIG_NFSD_TCP=y
-+CONFIG_LOCKD=m
-+CONFIG_LOCKD_V4=y
-+CONFIG_EXPORTFS=m
-+CONFIG_NFS_ACL_SUPPORT=m
-+CONFIG_NFS_COMMON=y
-+CONFIG_SUNRPC=m
-+# CONFIG_SUNRPC_BIND34 is not set
-+# 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=y
-+# CONFIG_ACORN_PARTITION is not set
-+# CONFIG_OSF_PARTITION is not set
-+# CONFIG_AMIGA_PARTITION is not set
-+# CONFIG_ATARI_PARTITION is not set
-+CONFIG_MAC_PARTITION=y
-+CONFIG_MSDOS_PARTITION=y
-+# CONFIG_BSD_DISKLABEL is not set
-+# CONFIG_MINIX_SUBPARTITION is not set
-+# CONFIG_SOLARIS_X86_PARTITION is not set
-+# CONFIG_UNIXWARE_DISKLABEL is not set
-+CONFIG_LDM_PARTITION=y
-+# CONFIG_LDM_DEBUG is not set
-+# CONFIG_SGI_PARTITION is not set
-+# CONFIG_ULTRIX_PARTITION is not set
-+# CONFIG_SUN_PARTITION is not set
-+# CONFIG_KARMA_PARTITION is not set
-+CONFIG_EFI_PARTITION=y
-+# CONFIG_SYSV68_PARTITION is not set
-+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 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=y
-+# CONFIG_DLM is not set
-+# CONFIG_INSTRUMENTATION is not set
-+
-+#
-+# Kernel hacking
-+#
-+# CONFIG_PRINTK_TIME is not set
-+CONFIG_ENABLE_WARN_DEPRECATED=y
-+CONFIG_ENABLE_MUST_CHECK=y
-+# CONFIG_MAGIC_SYSRQ is not set
-+# CONFIG_UNUSED_SYMBOLS is not set
-+# CONFIG_DEBUG_FS is not set
-+# CONFIG_HEADERS_CHECK is not set
-+# CONFIG_DEBUG_KERNEL is not set
-+CONFIG_DEBUG_BUGVERBOSE=y
-+CONFIG_FRAME_POINTER=y
-+# CONFIG_SAMPLES is not set
-+# CONFIG_DEBUG_USER is not set
-+
-+#
-+# Security options
-+#
-+# CONFIG_KEYS is not set
-+CONFIG_SECURITY=y
-+# CONFIG_SECURITY_NETWORK is not set
-+# CONFIG_SECURITY_CAPABILITIES is not set
-+CONFIG_SECURITY_TRUSTEES=y
-+# CONFIG_SECURITY_TRUSTEES_DEBUG is not set
-+CONFIG_CRYPTO=y
-+CONFIG_CRYPTO_ALGAPI=y
-+CONFIG_CRYPTO_BLKCIPHER=y
-+CONFIG_CRYPTO_MANAGER=y
-+# CONFIG_CRYPTO_HMAC is not set
-+# CONFIG_CRYPTO_XCBC is not set
-+# CONFIG_CRYPTO_NULL is not set
-+# CONFIG_CRYPTO_MD4 is not set
-+# CONFIG_CRYPTO_MD5 is not set
-+# CONFIG_CRYPTO_SHA1 is not set
-+# CONFIG_CRYPTO_SHA256 is not set
-+# CONFIG_CRYPTO_SHA512 is not set
-+# CONFIG_CRYPTO_WP512 is not set
-+# CONFIG_CRYPTO_TGR192 is not set
-+# CONFIG_CRYPTO_GF128MUL is not set
-+CONFIG_CRYPTO_ECB=m
-+CONFIG_CRYPTO_CBC=y
-+CONFIG_CRYPTO_PCBC=m
-+# CONFIG_CRYPTO_LRW is not set
-+# CONFIG_CRYPTO_XTS is not set
-+# CONFIG_CRYPTO_CRYPTD is not set
-+# CONFIG_CRYPTO_DES is not set
-+# CONFIG_CRYPTO_FCRYPT is not set
-+# CONFIG_CRYPTO_BLOWFISH is not set
-+# CONFIG_CRYPTO_TWOFISH is not set
-+# CONFIG_CRYPTO_SERPENT is not set
-+CONFIG_CRYPTO_AES=m
-+# CONFIG_CRYPTO_CAST5 is not set
-+# CONFIG_CRYPTO_CAST6 is not set
-+# CONFIG_CRYPTO_TEA is not set
-+CONFIG_CRYPTO_ARC4=m
-+# CONFIG_CRYPTO_KHAZAD is not set
-+# CONFIG_CRYPTO_ANUBIS is not set
-+# CONFIG_CRYPTO_SEED is not set
-+# CONFIG_CRYPTO_DEFLATE is not set
-+CONFIG_CRYPTO_MICHAEL_MIC=m
-+# CONFIG_CRYPTO_CRC32C is not set
-+# CONFIG_CRYPTO_CAMELLIA is not set
-+# CONFIG_CRYPTO_TEST is not set
-+# CONFIG_CRYPTO_AUTHENC is not set
-+CONFIG_CRYPTO_HW=y
-+
-+#
-+# Library routines
-+#
-+CONFIG_BITREVERSE=y
-+CONFIG_CRC_CCITT=y
-+# CONFIG_CRC16 is not set
-+# CONFIG_CRC_ITU_T is not set
-+CONFIG_CRC32=y
-+# CONFIG_CRC7 is not set
-+# CONFIG_LIBCRC32C is not set
-+CONFIG_PLIST=y
-+CONFIG_HAS_IOMEM=y
-+CONFIG_HAS_IOPORT=y
-+CONFIG_HAS_DMA=y
-diff -Nurd linux-2.6.24/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig
---- linux-2.6.24/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig 2008-06-11 17:47:52.000000000 +0200
-@@ -0,0 +1,901 @@
-+#
-+# Automatically generated make config: don't edit
-+# Linux kernel version: 2.6.24.4
-+# Thu May 15 10:43:48 2008
-+#
-+CONFIG_ARM=y
-+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-+# CONFIG_GENERIC_GPIO is not set
-+# CONFIG_GENERIC_TIME is not set
-+# CONFIG_GENERIC_CLOCKEVENTS is not set
-+CONFIG_MMU=y
-+# CONFIG_NO_IOPORT is not set
-+CONFIG_GENERIC_HARDIRQS=y
-+CONFIG_STACKTRACE_SUPPORT=y
-+CONFIG_LOCKDEP_SUPPORT=y
-+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-+CONFIG_HARDIRQS_SW_RESEND=y
-+CONFIG_GENERIC_IRQ_PROBE=y
-+CONFIG_RWSEM_GENERIC_SPINLOCK=y
-+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-+CONFIG_GENERIC_HWEIGHT=y
-+CONFIG_GENERIC_CALIBRATE_DELAY=y
-+CONFIG_ZONE_DMA=y
-+CONFIG_VECTORS_BASE=0xffff0000
-+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-+
-+#
-+# General setup
-+#
-+CONFIG_EXPERIMENTAL=y
-+CONFIG_BROKEN_ON_SMP=y
-+CONFIG_INIT_ENV_ARG_LIMIT=32
-+CONFIG_LOCALVERSION=""
-+CONFIG_LOCALVERSION_AUTO=y
-+CONFIG_SWAP=y
-+CONFIG_SYSVIPC=y
-+CONFIG_SYSVIPC_SYSCTL=y
-+# CONFIG_BSD_PROCESS_ACCT is not set
-+# CONFIG_USER_NS is not set
-+# CONFIG_PID_NS is not set
-+# CONFIG_IKCONFIG is not set
-+CONFIG_LOG_BUF_SHIFT=14
-+# CONFIG_CGROUPS is not set
-+CONFIG_FAIR_GROUP_SCHED=y
-+CONFIG_FAIR_USER_SCHED=y
-+# CONFIG_FAIR_CGROUP_SCHED is not set
-+CONFIG_SYSFS_DEPRECATED=y
-+# CONFIG_RELAY is not set
-+CONFIG_BLK_DEV_INITRD=y
-+CONFIG_INITRAMFS_SOURCE=""
-+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-+CONFIG_SYSCTL=y
-+# CONFIG_EMBEDDED is not set
-+CONFIG_UID16=y
-+CONFIG_SYSCTL_SYSCALL=y
-+CONFIG_KALLSYMS=y
-+# 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_ANON_INODES=y
-+CONFIG_EPOLL=y
-+CONFIG_SIGNALFD=y
-+CONFIG_EVENTFD=y
-+CONFIG_SHMEM=y
-+CONFIG_VM_EVENT_COUNTERS=y
-+CONFIG_SLAB=y
-+# CONFIG_SLUB is not set
-+# CONFIG_SLOB is not set
-+CONFIG_SLABINFO=y
-+CONFIG_RT_MUTEXES=y
-+# CONFIG_TINY_SHMEM is not set
-+CONFIG_BASE_SMALL=0
-+# CONFIG_MODULES is not set
-+CONFIG_BLOCK=y
-+# CONFIG_LBD is not set
-+# CONFIG_BLK_DEV_IO_TRACE is not set
-+# CONFIG_LSF is not set
-+# CONFIG_BLK_DEV_BSG is not set
-+
-+#
-+# IO Schedulers
-+#
-+CONFIG_IOSCHED_NOOP=y
-+CONFIG_IOSCHED_AS=y
-+CONFIG_IOSCHED_DEADLINE=y
-+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"
-+
-+#
-+# System Type
-+#
-+# CONFIG_ARCH_AAEC2000 is not set
-+# CONFIG_ARCH_INTEGRATOR is not set
-+# CONFIG_ARCH_REALVIEW is not set
-+# CONFIG_ARCH_VERSATILE is not set
-+# CONFIG_ARCH_AT91 is not set
-+# CONFIG_ARCH_CLPS7500 is not set
-+# CONFIG_ARCH_CLPS711X is not set
-+# CONFIG_ARCH_CO285 is not set
-+# CONFIG_ARCH_EBSA110 is not set
-+# CONFIG_ARCH_EP93XX is not set
-+# CONFIG_ARCH_FOOTBRIDGE is not set
-+# CONFIG_ARCH_NETX is not set
-+# CONFIG_ARCH_H720X is not set
-+# CONFIG_ARCH_IMX is not set
-+# CONFIG_ARCH_IOP13XX is not set
-+# CONFIG_ARCH_IOP32X is not set
-+# CONFIG_ARCH_IOP33X is not set
-+# CONFIG_ARCH_IXP23XX is not set
-+# CONFIG_ARCH_IXP2000 is not set
-+# CONFIG_ARCH_IXP4XX is not set
-+# CONFIG_ARCH_L7200 is not set
-+# CONFIG_ARCH_KS8695 is not set
-+# CONFIG_ARCH_NS9XXX is not set
-+# CONFIG_ARCH_MXC is not set
-+# CONFIG_ARCH_PNX4008 is not set
-+# CONFIG_ARCH_PXA is not set
-+# CONFIG_ARCH_RPC is not set
-+# CONFIG_ARCH_SA1100 is not set
-+# CONFIG_ARCH_S3C2410 is not set
-+# CONFIG_ARCH_SHARK is not set
-+# CONFIG_ARCH_LH7A40X is not set
-+# CONFIG_ARCH_DAVINCI is not set
-+# CONFIG_ARCH_OMAP is not set
-+CONFIG_ARCH_OXNAS=y
-+
-+#
-+# Boot options
-+#
-+
-+#
-+# Power management
-+#
-+
-+#
-+# Oxford Semiconductor NAS Options
-+#
-+# CONFIG_ARCH_OXNAS_FPGA is not set
-+CONFIG_NOMINAL_PLL400_FREQ=733333333
-+CONFIG_NOMINAL_RPSCLK_FREQ=25000000
-+# CONFIG_OXNAS_VERSION_0X800 is not set
-+CONFIG_OXNAS_VERSION_0X810=y
-+# CONFIG_OXNAS_VERSION_0X850 is not set
-+# CONFIG_ARCH_OXNAS_UART1 is not set
-+CONFIG_ARCH_OXNAS_UART2=y
-+# CONFIG_ARCH_OXNAS_UART2_MODEM is not set
-+# CONFIG_ARCH_OXNAS_UART3 is not set
-+# CONFIG_ARCH_OXNAS_PCI_REQGNT_0 is not set
-+# CONFIG_ARCH_OXNAS_PCI_REQGNT_1 is not set
-+# CONFIG_ARCH_OXNAS_PCI_REQGNT_2 is not set
-+# CONFIG_ARCH_OXNAS_PCI_REQGNT_3 is not set
-+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_0 is not set
-+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_1 is not set
-+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_2 is not set
-+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_3 is not set
-+# CONFIG_OXNAS_PCI_RESET is not set
-+CONFIG_FORCE_MAX_ZONEORDER=10
-+CONFIG_SRAM_NUM_PAGES=32
-+CONFIG_SUPPORT_LEON=y
-+CONFIG_LEON_PAGES=2
-+# CONFIG_LEON_COPRO is not set
-+# CONFIG_LEON_START_EARLY is not set
-+CONFIG_LEON_POWER_BUTTON_MONITOR=y
-+CONFIG_OXNAS_POWER_BUTTON_GPIO=4
-+CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
-+CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO=32
-+# CONFIG_OXNAS_DDR_MON is not set
-+# CONFIG_OXNAS_AHB_MON is not set
-+# CONFIG_OXNAS_CACHE_LOCKDOWN is not set
-+# CONFIG_DO_MEM_TEST is not set
-+# CONFIG_CRYPTO_OXAESLRW is not set
-+CONFIG_DESCRIPTORS_PAGES=6
-+CONFIG_ARCH_OXNAS_NUM_GMAC_DESCRIPTORS=192
-+CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES=256
-+# CONFIG_TACHO_THERM_AND_FAN is not set
-+# CONFIG_GPIO_TEST is not set
-+# CONFIG_OXNAS_RTC is not set
-+# CONFIG_I2S is not set
-+# CONFIG_DPE_TEST is not set
-+# CONFIG_OXNAS_INSTRUMENT_COPIES is not set
-+# CONFIG_OXNAS_DMA_COPIES is not set
-+# CONFIG_OXNAS_AHB_MONITOR_MODULE is not set
-+# CONFIG_OXNAS_USB_TEST_MODES is not set
-+# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
-+# CONFIG_OXNAS_LED_TEST is not set
-+CONFIG_OXNAS_I2C_SDA=6
-+CONFIG_OXNAS_I2C_SCL=7
-+# CONFIG_OXNAS_USB_PORTA_POWER_CONTROL is not set
-+# CONFIG_OXNAS_USB_PORTB_POWER_CONTROL is not set
-+# CONFIG_OXNAS_USB_PORTC_POWER_CONTROL is not set
-+# CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE is not set
-+# CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE is not set
-+# CONFIG_WDC_FAN_OXNAS800 is not set
-+# CONFIG_OXNAS_MAP_SRAM is not set
-+# CONFIG_OXNAS_SUID_INHERIT is not set
-+
-+#
-+# Processor Type
-+#
-+CONFIG_CPU_32=y
-+CONFIG_CPU_ARM926T=y
-+CONFIG_CPU_32v5=y
-+CONFIG_CPU_ABRT_EV5TJ=y
-+CONFIG_CPU_CACHE_VIVT=y
-+CONFIG_CPU_COPY_V4WB=y
-+CONFIG_CPU_TLB_V4WBI=y
-+CONFIG_CPU_CP15=y
-+CONFIG_CPU_CP15_MMU=y
-+
-+#
-+# Processor Features
-+#
-+CONFIG_ARM_THUMB=y
-+# CONFIG_CPU_ICACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-+# CONFIG_OUTER_CACHE is not set
-+
-+#
-+# Bus support
-+#
-+CONFIG_ARM_AMBA=y
-+CONFIG_PCI=y
-+CONFIG_PCI_SYSCALL=y
-+# CONFIG_ARCH_SUPPORTS_MSI is not set
-+CONFIG_PCI_LEGACY=y
-+# CONFIG_PCCARD is not set
-+
-+#
-+# Kernel Features
-+#
-+# CONFIG_TICK_ONESHOT is not set
-+# CONFIG_PREEMPT is not set
-+# CONFIG_NO_IDLE_HZ is not set
-+CONFIG_HZ=100
-+CONFIG_AEABI=y
-+# CONFIG_OABI_COMPAT is not set
-+# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPARSEMEM_STATIC is not set
-+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
-+CONFIG_SPLIT_PTLOCK_CPUS=4096
-+# CONFIG_RESOURCES_64BIT is not set
-+CONFIG_ZONE_DMA_FLAG=1
-+CONFIG_BOUNCE=y
-+CONFIG_VIRT_TO_BUS=y
-+CONFIG_ALIGNMENT_TRAP=y
-+
-+#
-+# Boot options
-+#
-+CONFIG_ZBOOT_ROM_TEXT=0x0
-+CONFIG_ZBOOT_ROM_BSS=0x0
-+CONFIG_CMDLINE=""
-+# CONFIG_XIP_KERNEL is not set
-+# CONFIG_KEXEC is not set
-+
-+#
-+# Floating point emulation
-+#
-+
-+#
-+# At least one emulation must be selected
-+#
-+CONFIG_VFP=y
-+
-+#
-+# Userspace binary formats
-+#
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_AOUT is not set
-+# CONFIG_BINFMT_MISC is not set
-+
-+#
-+# Power management options
-+#
-+# CONFIG_PM is not set
-+CONFIG_SUSPEND_UP_POSSIBLE=y
-+
-+#
-+# Networking
-+#
-+# CONFIG_NET 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_SYS_HYPERVISOR is not set
-+# CONFIG_MTD is not set
-+# CONFIG_PARPORT is not set
-+CONFIG_BLK_DEV=y
-+# CONFIG_BLK_CPQ_DA is not set
-+# CONFIG_BLK_CPQ_CISS_DA is not set
-+# CONFIG_BLK_DEV_DAC960 is not set
-+# CONFIG_BLK_DEV_UMEM is not set
-+# CONFIG_BLK_DEV_COW_COMMON is not set
-+CONFIG_BLK_DEV_LOOP=y
-+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-+# CONFIG_BLK_DEV_SX8 is not set
-+CONFIG_BLK_DEV_RAM=y
-+CONFIG_BLK_DEV_RAM_COUNT=1
-+CONFIG_BLK_DEV_RAM_SIZE=10240
-+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-+# CONFIG_CDROM_PKTCDVD is not set
-+# CONFIG_MISC_DEVICES is not set
-+# 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=y
-+
-+#
-+# 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 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=y
-+# CONFIG_SCSI_CONSTANTS is not set
-+# CONFIG_SCSI_LOGGING is not set
-+# CONFIG_SCSI_SCAN_ASYNC is not set
-+
-+#
-+# SCSI Transports
-+#
-+# CONFIG_SCSI_SPI_ATTRS is not set
-+# CONFIG_SCSI_FC_ATTRS is not set
-+# CONFIG_SCSI_SAS_LIBSAS is not set
-+# CONFIG_SCSI_SRP_ATTRS is not set
-+CONFIG_SCSI_LOWLEVEL=y
-+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-+# CONFIG_SCSI_3W_9XXX is not set
-+# CONFIG_SCSI_ACARD is not set
-+# CONFIG_SCSI_AACRAID is not set
-+# CONFIG_SCSI_AIC7XXX is not set
-+# CONFIG_SCSI_AIC7XXX_OLD is not set
-+# CONFIG_SCSI_AIC79XX is not set
-+# CONFIG_SCSI_AIC94XX is not set
-+# CONFIG_SCSI_DPT_I2O is not set
-+# CONFIG_SCSI_ADVANSYS is not set
-+# CONFIG_SCSI_ARCMSR is not set
-+# CONFIG_MEGARAID_NEWGEN is not set
-+# CONFIG_MEGARAID_LEGACY is not set
-+# CONFIG_MEGARAID_SAS is not set
-+# CONFIG_SCSI_HPTIOP is not set
-+# CONFIG_SCSI_DMX3191D is not set
-+# CONFIG_SCSI_FUTURE_DOMAIN is not set
-+# CONFIG_SCSI_IPS is not set
-+# CONFIG_SCSI_INITIO is not set
-+# CONFIG_SCSI_INIA100 is not set
-+# CONFIG_SCSI_STEX is not set
-+# CONFIG_SCSI_SYM53C8XX_2 is not set
-+# CONFIG_SCSI_IPR is not set
-+# CONFIG_SCSI_QLOGIC_1280 is not set
-+# CONFIG_SCSI_QLA_FC is not set
-+# CONFIG_SCSI_LPFC is not set
-+# CONFIG_SCSI_DC395x is not set
-+# CONFIG_SCSI_DC390T is not set
-+# CONFIG_SCSI_NSP32 is not set
-+# CONFIG_SCSI_DEBUG is not set
-+# CONFIG_SCSI_SRP is not set
-+CONFIG_ATA=y
-+# CONFIG_ATA_NONSTANDARD is not set
-+# CONFIG_SATA_AHCI is not set
-+# CONFIG_SATA_SVW is not set
-+# CONFIG_ATA_PIIX is not set
-+# CONFIG_SATA_MV is not set
-+# CONFIG_SATA_NV is not set
-+# CONFIG_PDC_ADMA is not set
-+# CONFIG_SATA_QSTOR is not set
-+# CONFIG_SATA_PROMISE is not set
-+# CONFIG_SATA_SX4 is not set
-+# CONFIG_SATA_SIL is not set
-+# CONFIG_SATA_SIL24 is not set
-+# CONFIG_SATA_SIS is not set
-+# CONFIG_SATA_ULI is not set
-+# CONFIG_SATA_VIA is not set
-+# CONFIG_SATA_VITESSE is not set
-+# CONFIG_SATA_INIC162X is not set
-+CONFIG_SATA_OX810=y
-+# CONFIG_SATA_OXNAS_SINGLE_SATA is not set
-+# CONFIG_SATA_OXNAS_DISK_LIGHT is not set
-+# CONFIG_PATA_ALI is not set
-+# CONFIG_PATA_AMD is not set
-+# CONFIG_PATA_ARTOP is not set
-+# CONFIG_PATA_ATIIXP is not set
-+# CONFIG_PATA_CMD640_PCI is not set
-+# CONFIG_PATA_CMD64X is not set
-+# CONFIG_PATA_CS5520 is not set
-+# CONFIG_PATA_CS5530 is not set
-+# CONFIG_PATA_CYPRESS is not set
-+# CONFIG_PATA_EFAR is not set
-+# CONFIG_ATA_GENERIC is not set
-+# CONFIG_PATA_HPT366 is not set
-+# CONFIG_PATA_HPT37X is not set
-+# CONFIG_PATA_HPT3X2N is not set
-+# CONFIG_PATA_HPT3X3 is not set
-+# CONFIG_PATA_IT821X is not set
-+# CONFIG_PATA_IT8213 is not set
-+# CONFIG_PATA_JMICRON is not set
-+# CONFIG_PATA_TRIFLEX is not set
-+# CONFIG_PATA_MARVELL is not set
-+# CONFIG_PATA_MPIIX is not set
-+# CONFIG_PATA_OLDPIIX is not set
-+# CONFIG_PATA_NETCELL is not set
-+# CONFIG_PATA_NS87410 is not set
-+# CONFIG_PATA_NS87415 is not set
-+# CONFIG_PATA_OPTI is not set
-+# CONFIG_PATA_OPTIDMA is not set
-+# CONFIG_PATA_PDC_OLD is not set
-+# CONFIG_PATA_RADISYS is not set
-+# CONFIG_PATA_RZ1000 is not set
-+# CONFIG_PATA_SC1200 is not set
-+# CONFIG_PATA_SERVERWORKS is not set
-+# CONFIG_PATA_PDC2027X is not set
-+# CONFIG_PATA_SIL680 is not set
-+# CONFIG_PATA_SIS is not set
-+# CONFIG_PATA_VIA is not set
-+# CONFIG_PATA_WINBOND is not set
-+CONFIG_MD=y
-+CONFIG_BLK_DEV_MD=y
-+CONFIG_MD_LINEAR=y
-+# CONFIG_MD_RAID0 is not set
-+CONFIG_MD_RAID1=y
-+# CONFIG_MD_RAID10 is not set
-+# CONFIG_MD_RAID456 is not set
-+# CONFIG_MD_MULTIPATH is not set
-+# CONFIG_MD_FAULTY is not set
-+CONFIG_BLK_DEV_DM=y
-+# CONFIG_DM_DEBUG is not set
-+# CONFIG_DM_CRYPT is not set
-+# CONFIG_DM_SNAPSHOT is not set
-+# CONFIG_DM_MIRROR is not set
-+# CONFIG_DM_ZERO is not set
-+# CONFIG_DM_MULTIPATH is not set
-+# CONFIG_DM_DELAY is not set
-+# CONFIG_DM_UEVENT is not set
-+# CONFIG_FUSION is not set
-+
-+#
-+# IEEE 1394 (FireWire) support
-+#
-+# CONFIG_FIREWIRE is not set
-+# CONFIG_IEEE1394 is not set
-+# CONFIG_I2O 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=y
-+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-+# 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 is not set
-+
-+#
-+# Hardware I/O ports
-+#
-+# CONFIG_SERIO is not set
-+# CONFIG_GAMEPORT is not set
-+
-+#
-+# Character devices
-+#
-+CONFIG_VT=y
-+CONFIG_VT_CONSOLE=y
-+CONFIG_HW_CONSOLE=y
-+# CONFIG_VT_HW_CONSOLE_BINDING is not set
-+# CONFIG_SERIAL_NONSTANDARD is not set
-+
-+#
-+# Serial drivers
-+#
-+CONFIG_SERIAL_8250=y
-+CONFIG_SERIAL_8250_CONSOLE=y
-+CONFIG_SERIAL_8250_PCI=y
-+CONFIG_SERIAL_8250_NR_UARTS=4
-+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-+# CONFIG_SERIAL_8250_EXTENDED is not set
-+
-+#
-+# Non-8250 serial port support
-+#
-+# CONFIG_SERIAL_AMBA_PL010 is not set
-+# CONFIG_SERIAL_AMBA_PL011 is not set
-+CONFIG_SERIAL_CORE=y
-+CONFIG_SERIAL_CORE_CONSOLE=y
-+# CONFIG_SERIAL_JSM is not set
-+CONFIG_UNIX98_PTYS=y
-+# CONFIG_LEGACY_PTYS is not set
-+# CONFIG_IPMI_HANDLER is not set
-+CONFIG_HW_RANDOM=y
-+# CONFIG_NVRAM is not set
-+# CONFIG_R3964 is not set
-+# CONFIG_APPLICOM is not set
-+# CONFIG_RAW_DRIVER is not set
-+# CONFIG_TCG_TPM is not set
-+CONFIG_DEVPORT=y
-+CONFIG_I2C=y
-+CONFIG_I2C_BOARDINFO=y
-+# CONFIG_I2C_CHARDEV is not set
-+
-+#
-+# I2C Algorithms
-+#
-+CONFIG_I2C_ALGOBIT=y
-+# CONFIG_I2C_ALGOPCF is not set
-+# CONFIG_I2C_ALGOPCA is not set
-+# CONFIG_I2C_ALGOOXSEMI is not set
-+
-+#
-+# I2C Hardware Bus support
-+#
-+# CONFIG_I2C_ALI1535 is not set
-+# CONFIG_I2C_ALI1563 is not set
-+# CONFIG_I2C_ALI15X3 is not set
-+# CONFIG_I2C_AMD756 is not set
-+# CONFIG_I2C_AMD8111 is not set
-+# CONFIG_I2C_I801 is not set
-+# CONFIG_I2C_I810 is not set
-+# CONFIG_I2C_PIIX4 is not set
-+# CONFIG_I2C_NFORCE2 is not set
-+CONFIG_I2C_OXNAS_BITBASH=y
-+# CONFIG_I2C_OCORES is not set
-+# CONFIG_I2C_PARPORT_LIGHT is not set
-+# CONFIG_I2C_PROSAVAGE is not set
-+# CONFIG_I2C_SAVAGE4 is not set
-+# CONFIG_I2C_SIMTEC is not set
-+# CONFIG_I2C_SIS5595 is not set
-+# CONFIG_I2C_SIS630 is not set
-+# CONFIG_I2C_SIS96X is not set
-+# CONFIG_I2C_TAOS_EVM is not set
-+# CONFIG_I2C_VIA is not set
-+# CONFIG_I2C_VIAPRO is not set
-+# CONFIG_I2C_VOODOO3 is not set
-+
-+#
-+# Miscellaneous I2C Chip support
-+#
-+# CONFIG_SENSORS_DS1337 is not set
-+# CONFIG_SENSORS_DS1374 is not set
-+# CONFIG_DS1682 is not set
-+# CONFIG_SENSORS_EEPROM is not set
-+# CONFIG_SENSORS_PCF8574 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
-+# CONFIG_I2C_DEBUG_BUS is not set
-+# CONFIG_I2C_DEBUG_CHIP is not set
-+
-+#
-+# SPI support
-+#
-+# CONFIG_SPI is not set
-+# CONFIG_SPI_MASTER is not set
-+# CONFIG_W1 is not set
-+# CONFIG_POWER_SUPPLY is not set
-+# CONFIG_HWMON is not set
-+# CONFIG_WATCHDOG is not set
-+
-+#
-+# Sonics Silicon Backplane
-+#
-+CONFIG_SSB_POSSIBLE=y
-+# CONFIG_SSB is not set
-+
-+#
-+# Multifunction device drivers
-+#
-+# CONFIG_MFD_SM501 is not set
-+
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
-+CONFIG_DAB=y
-+
-+#
-+# Graphics support
-+#
-+# CONFIG_DRM is not set
-+# CONFIG_VGASTATE is not set
-+CONFIG_VIDEO_OUTPUT_CONTROL=y
-+# 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_VGA_CONSOLE is not set
-+CONFIG_DUMMY_CONSOLE=y
-+
-+#
-+# Sound
-+#
-+# CONFIG_SOUND is not set
-+# CONFIG_HID_SUPPORT is not set
-+# CONFIG_USB_SUPPORT is not set
-+# CONFIG_MMC is not set
-+# CONFIG_NEW_LEDS 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=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_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
-+
-+#
-+# SPI RTC drivers
-+#
-+
-+#
-+# Platform RTC drivers
-+#
-+# CONFIG_RTC_DRV_CMOS is not set
-+# CONFIG_RTC_DRV_DS1553 is not set
-+# CONFIG_RTC_DRV_STK17TA8 is not set
-+# CONFIG_RTC_DRV_DS1742 is not set
-+# CONFIG_RTC_DRV_M48T86 is not set
-+# CONFIG_RTC_DRV_M48T59 is not set
-+# CONFIG_RTC_DRV_V3020 is not set
-+
-+#
-+# on-CPU RTC drivers
-+#
-+# CONFIG_RTC_DRV_PL031 is not set
-+# CONFIG_DMADEVICES is not set
-+
-+#
-+# File systems
-+#
-+CONFIG_EXT2_FS=y
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XIP is not set
-+CONFIG_EXT3_FS=y
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT4DEV_FS is not set
-+CONFIG_JBD=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_GFS2_FS is not set
-+# CONFIG_MINIX_FS is not set
-+# CONFIG_ROMFS_FS is not set
-+# CONFIG_INOTIFY is not set
-+# CONFIG_QUOTA is not set
-+# CONFIG_DNOTIFY is not set
-+# CONFIG_AUTOFS_FS is not set
-+# CONFIG_AUTOFS4_FS is not set
-+# CONFIG_FUSE_FS is not set
-+
-+#
-+# CD-ROM/DVD Filesystems
-+#
-+# CONFIG_ISO9660_FS is not set
-+# CONFIG_UDF_FS is not set
-+
-+#
-+# DOS/FAT/NT Filesystems
-+#
-+# CONFIG_MSDOS_FS is not set
-+# CONFIG_VFAT_FS is not set
-+# CONFIG_NTFS_FS is not set
-+
-+#
-+# Pseudo filesystems
-+#
-+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_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_CRAMFS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_HPFS_FS is not set
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UFS_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=y
-+# 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=y
-+# 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=y
-+# CONFIG_INSTRUMENTATION is not set
-+
-+#
-+# Kernel hacking
-+#
-+# CONFIG_PRINTK_TIME is not set
-+# CONFIG_ENABLE_WARN_DEPRECATED is not set
-+# CONFIG_ENABLE_MUST_CHECK is not set
-+# CONFIG_MAGIC_SYSRQ is not set
-+# CONFIG_UNUSED_SYMBOLS is not set
-+# CONFIG_DEBUG_FS is not set
-+# CONFIG_HEADERS_CHECK is not set
-+# CONFIG_DEBUG_KERNEL is not set
-+CONFIG_DEBUG_BUGVERBOSE=y
-+CONFIG_FRAME_POINTER=y
-+# CONFIG_SAMPLES is not set
-+# CONFIG_DEBUG_USER is not set
-+
-+#
-+# Security options
-+#
-+# CONFIG_KEYS is not set
-+# CONFIG_SECURITY is not set
-+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-+CONFIG_CRYPTO=y
-+CONFIG_CRYPTO_ALGAPI=y
-+CONFIG_CRYPTO_BLKCIPHER=y
-+CONFIG_CRYPTO_MANAGER=y
-+# CONFIG_CRYPTO_HMAC is not set
-+# CONFIG_CRYPTO_XCBC is not set
-+# CONFIG_CRYPTO_NULL is not set
-+# CONFIG_CRYPTO_MD4 is not set
-+# CONFIG_CRYPTO_MD5 is not set
-+# CONFIG_CRYPTO_SHA1 is not set
-+# CONFIG_CRYPTO_SHA256 is not set
-+# CONFIG_CRYPTO_SHA512 is not set
-+# CONFIG_CRYPTO_WP512 is not set
-+# CONFIG_CRYPTO_TGR192 is not set
-+# CONFIG_CRYPTO_GF128MUL is not set
-+# CONFIG_CRYPTO_ECB is not set
-+CONFIG_CRYPTO_CBC=y
-+# CONFIG_CRYPTO_PCBC is not set
-+# CONFIG_CRYPTO_LRW is not set
-+# CONFIG_CRYPTO_XTS is not set
-+# CONFIG_CRYPTO_CRYPTD is not set
-+# CONFIG_CRYPTO_DES is not set
-+# CONFIG_CRYPTO_FCRYPT is not set
-+# CONFIG_CRYPTO_BLOWFISH is not set
-+# CONFIG_CRYPTO_TWOFISH is not set
-+# CONFIG_CRYPTO_SERPENT is not set
-+# CONFIG_CRYPTO_AES is not set
-+# CONFIG_CRYPTO_CAST5 is not set
-+# CONFIG_CRYPTO_CAST6 is not set
-+# CONFIG_CRYPTO_TEA is not set
-+# CONFIG_CRYPTO_ARC4 is not set
-+# CONFIG_CRYPTO_KHAZAD is not set
-+# CONFIG_CRYPTO_ANUBIS is not set
-+# CONFIG_CRYPTO_SEED is not set
-+# CONFIG_CRYPTO_DEFLATE is not set
-+# CONFIG_CRYPTO_MICHAEL_MIC is not set
-+# CONFIG_CRYPTO_CRC32C is not set
-+# CONFIG_CRYPTO_CAMELLIA is not set
-+# CONFIG_CRYPTO_AUTHENC is not set
-+# CONFIG_CRYPTO_HW is not set
-+
-+#
-+# Library routines
-+#
-+CONFIG_BITREVERSE=y
-+CONFIG_CRC_CCITT=y
-+# CONFIG_CRC16 is not set
-+# CONFIG_CRC_ITU_T is not set
-+CONFIG_CRC32=y
-+# CONFIG_CRC7 is not set
-+# CONFIG_LIBCRC32C is not set
-+CONFIG_PLIST=y
-+CONFIG_HAS_IOMEM=y
-+CONFIG_HAS_IOPORT=y
-+CONFIG_HAS_DMA=y
-diff -Nurd linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig
---- linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig 2008-06-11 17:47:52.000000000 +0200
-@@ -0,0 +1,1096 @@
-+#
-+# Automatically generated make config: don't edit
-+# Linux kernel version: 2.6.24.4
-+# Mon Jun 2 12:33:10 2008
-+#
-+CONFIG_ARM=y
-+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-+# CONFIG_GENERIC_GPIO is not set
-+# CONFIG_GENERIC_TIME is not set
-+# CONFIG_GENERIC_CLOCKEVENTS is not set
-+CONFIG_MMU=y
-+# CONFIG_NO_IOPORT is not set
-+CONFIG_GENERIC_HARDIRQS=y
-+CONFIG_STACKTRACE_SUPPORT=y
-+CONFIG_LOCKDEP_SUPPORT=y
-+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-+CONFIG_HARDIRQS_SW_RESEND=y
-+CONFIG_GENERIC_IRQ_PROBE=y
-+CONFIG_RWSEM_GENERIC_SPINLOCK=y
-+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-+CONFIG_GENERIC_HWEIGHT=y
-+CONFIG_GENERIC_CALIBRATE_DELAY=y
-+CONFIG_ZONE_DMA=y
-+CONFIG_VECTORS_BASE=0xffff0000
-+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-+
-+#
-+# General setup
-+#
-+CONFIG_EXPERIMENTAL=y
-+CONFIG_BROKEN_ON_SMP=y
-+CONFIG_INIT_ENV_ARG_LIMIT=32
-+CONFIG_LOCALVERSION=""
-+CONFIG_LOCALVERSION_AUTO=y
-+CONFIG_SWAP=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_USER_NS is not set
-+# CONFIG_PID_NS is not set
-+# CONFIG_AUDIT is not set
-+# CONFIG_IKCONFIG is not set
-+CONFIG_LOG_BUF_SHIFT=14
-+# CONFIG_CGROUPS is not set
-+# CONFIG_FAIR_GROUP_SCHED is not set
-+# CONFIG_FAIR_USER_SCHED is not set
-+# CONFIG_FAIR_CGROUP_SCHED is not set
-+CONFIG_SYSFS_DEPRECATED=y
-+# CONFIG_RELAY is not set
-+CONFIG_BLK_DEV_INITRD=y
-+CONFIG_INITRAMFS_SOURCE=""
-+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-+CONFIG_SYSCTL=y
-+# CONFIG_EMBEDDED is not set
-+CONFIG_UID16=y
-+CONFIG_SYSCTL_SYSCALL=y
-+CONFIG_KALLSYMS=y
-+# 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_ANON_INODES=y
-+CONFIG_EPOLL=y
-+CONFIG_SIGNALFD=y
-+CONFIG_EVENTFD=y
-+CONFIG_SHMEM=y
-+CONFIG_VM_EVENT_COUNTERS=y
-+CONFIG_SLAB=y
-+# CONFIG_SLUB is not set
-+# CONFIG_SLOB is not set
-+CONFIG_SLABINFO=y
-+CONFIG_RT_MUTEXES=y
-+# CONFIG_TINY_SHMEM is not set
-+CONFIG_BASE_SMALL=0
-+CONFIG_MODULES=y
-+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 is not set
-+CONFIG_BLOCK=y
-+# CONFIG_LBD is not set
-+# CONFIG_BLK_DEV_IO_TRACE is not set
-+# CONFIG_LSF is not set
-+# CONFIG_BLK_DEV_BSG is not set
-+
-+#
-+# IO Schedulers
-+#
-+CONFIG_IOSCHED_NOOP=y
-+CONFIG_IOSCHED_AS=y
-+CONFIG_IOSCHED_DEADLINE=y
-+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"
-+
-+#
-+# System Type
-+#
-+# CONFIG_ARCH_AAEC2000 is not set
-+# CONFIG_ARCH_INTEGRATOR is not set
-+# CONFIG_ARCH_REALVIEW is not set
-+# CONFIG_ARCH_VERSATILE is not set
-+# CONFIG_ARCH_AT91 is not set
-+# CONFIG_ARCH_CLPS7500 is not set
-+# CONFIG_ARCH_CLPS711X is not set
-+# CONFIG_ARCH_CO285 is not set
-+# CONFIG_ARCH_EBSA110 is not set
-+# CONFIG_ARCH_EP93XX is not set
-+# CONFIG_ARCH_FOOTBRIDGE is not set
-+# CONFIG_ARCH_NETX is not set
-+# CONFIG_ARCH_H720X is not set
-+# CONFIG_ARCH_IMX is not set
-+# CONFIG_ARCH_IOP13XX is not set
-+# CONFIG_ARCH_IOP32X is not set
-+# CONFIG_ARCH_IOP33X is not set
-+# CONFIG_ARCH_IXP23XX is not set
-+# CONFIG_ARCH_IXP2000 is not set
-+# CONFIG_ARCH_IXP4XX is not set
-+# CONFIG_ARCH_L7200 is not set
-+# CONFIG_ARCH_KS8695 is not set
-+# CONFIG_ARCH_NS9XXX is not set
-+# CONFIG_ARCH_MXC is not set
-+# CONFIG_ARCH_PNX4008 is not set
-+# CONFIG_ARCH_PXA is not set
-+# CONFIG_ARCH_RPC is not set
-+# CONFIG_ARCH_SA1100 is not set
-+# CONFIG_ARCH_S3C2410 is not set
-+# CONFIG_ARCH_SHARK is not set
-+# CONFIG_ARCH_LH7A40X is not set
-+# CONFIG_ARCH_DAVINCI is not set
-+# CONFIG_ARCH_OMAP is not set
-+CONFIG_ARCH_OXNAS=y
-+
-+#
-+# Boot options
-+#
-+
-+#
-+# Power management
-+#
-+
-+#
-+# Oxford Semiconductor NAS Options
-+#
-+# CONFIG_ARCH_OXNAS_FPGA is not set
-+CONFIG_NOMINAL_PLL400_FREQ=733333333
-+CONFIG_NOMINAL_RPSCLK_FREQ=25000000
-+# CONFIG_OXNAS_VERSION_0X800 is not set
-+CONFIG_OXNAS_VERSION_0X810=y
-+# CONFIG_OXNAS_VERSION_0X850 is not set
-+# CONFIG_ARCH_OXNAS_UART1 is not set
-+CONFIG_ARCH_OXNAS_UART2=y
-+# CONFIG_ARCH_OXNAS_UART2_MODEM is not set
-+# CONFIG_ARCH_OXNAS_UART3 is not set
-+# CONFIG_ARCH_OXNAS_UART4 is not set
-+CONFIG_FORCE_MAX_ZONEORDER=10
-+CONFIG_SRAM_NUM_PAGES=32
-+CONFIG_SUPPORT_LEON=y
-+CONFIG_LEON_PAGES=2
-+CONFIG_LEON_COPRO=y
-+CONFIG_LEON_OFFLOAD_TX=y
-+# CONFIG_LEON_RESERVE_DMA_CHANNEL is not set
-+CONFIG_LEON_OFFLOAD_TSO=y
-+# CONFIG_LEON_START_EARLY is not set
-+CONFIG_LEON_POWER_BUTTON_MONITOR=m
-+CONFIG_OXNAS_POWER_BUTTON_GPIO=4
-+CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
-+CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO=28
-+# CONFIG_OXNAS_DDR_MON is not set
-+# CONFIG_OXNAS_AHB_MON is not set
-+# CONFIG_OXNAS_CACHE_LOCKDOWN is not set
-+# CONFIG_DO_MEM_TEST is not set
-+# CONFIG_CRYPTO_OXAESLRW is not set
-+CONFIG_DESCRIPTORS_PAGES=6
-+CONFIG_ARCH_OXNAS_NUM_GMAC_DESCRIPTORS=192
-+CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES=256
-+CONFIG_TACHO_THERM_AND_FAN=m
-+# CONFIG_GPIO_TEST is not set
-+CONFIG_OXNAS_RTC=m
-+# CONFIG_I2S is not set
-+# CONFIG_DPE_TEST is not set
-+# CONFIG_OXNAS_INSTRUMENT_COPIES is not set
-+# CONFIG_OXNAS_DMA_COPIES is not set
-+# CONFIG_OXNAS_AHB_MONITOR_MODULE is not set
-+# CONFIG_OXNAS_USB_TEST_MODES is not set
-+# CONFIG_OXNAS_FRONT_LAMP_CONTROL is not set
-+# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
-+# CONFIG_OXNAS_LED_TEST is not set
-+CONFIG_OXNAS_I2C_SDA=3
-+CONFIG_OXNAS_I2C_SCL=2
-+CONFIG_OXNAS_USB_PORTA_POWER_CONTROL=y
-+# CONFIG_OXNAS_USB_PORTB_POWER_CONTROL is not set
-+# CONFIG_OXNAS_USB_PORTC_POWER_CONTROL is not set
-+CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE=y
-+CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE=y
-+# CONFIG_WDC_FAN_OXNAS800 is not set
-+# CONFIG_OXNAS_MAP_SRAM is not set
-+# CONFIG_OXNAS_SUID_INHERIT is not set
-+# CONFIG_OXNAS_USB_HUB_SUPPORT is not set
-+
-+#
-+# Processor Type
-+#
-+CONFIG_CPU_32=y
-+CONFIG_CPU_ARM926T=y
-+CONFIG_CPU_32v5=y
-+CONFIG_CPU_ABRT_EV5TJ=y
-+CONFIG_CPU_CACHE_VIVT=y
-+CONFIG_CPU_COPY_V4WB=y
-+CONFIG_CPU_TLB_V4WBI=y
-+CONFIG_CPU_CP15=y
-+CONFIG_CPU_CP15_MMU=y
-+
-+#
-+# Processor Features
-+#
-+CONFIG_ARM_THUMB=y
-+# CONFIG_CPU_ICACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-+# CONFIG_OUTER_CACHE is not set
-+
-+#
-+# Bus support
-+#
-+CONFIG_ARM_AMBA=y
-+# CONFIG_PCI is not set
-+# CONFIG_PCI_SYSCALL is not set
-+# CONFIG_ARCH_SUPPORTS_MSI is not set
-+# CONFIG_PCCARD is not set
-+
-+#
-+# Kernel Features
-+#
-+# CONFIG_TICK_ONESHOT is not set
-+# CONFIG_PREEMPT is not set
-+# CONFIG_NO_IDLE_HZ is not set
-+CONFIG_HZ=100
-+CONFIG_AEABI=y
-+# CONFIG_OABI_COMPAT is not set
-+# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPARSEMEM_STATIC is not set
-+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
-+CONFIG_SPLIT_PTLOCK_CPUS=4096
-+# CONFIG_RESOURCES_64BIT is not set
-+CONFIG_ZONE_DMA_FLAG=1
-+CONFIG_BOUNCE=y
-+CONFIG_VIRT_TO_BUS=y
-+CONFIG_ALIGNMENT_TRAP=y
-+
-+#
-+# Boot options
-+#
-+CONFIG_ZBOOT_ROM_TEXT=0x0
-+CONFIG_ZBOOT_ROM_BSS=0x0
-+CONFIG_CMDLINE=""
-+# CONFIG_XIP_KERNEL is not set
-+# CONFIG_KEXEC is not set
-+
-+#
-+# Floating point emulation
-+#
-+
-+#
-+# At least one emulation must be selected
-+#
-+# CONFIG_VFP is not set
-+
-+#
-+# Userspace binary formats
-+#
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_AOUT is not set
-+# CONFIG_BINFMT_MISC is not set
-+
-+#
-+# Power management options
-+#
-+# CONFIG_PM is not set
-+CONFIG_SUSPEND_UP_POSSIBLE=y
-+
-+#
-+# Networking
-+#
-+CONFIG_NET=y
-+
-+#
-+# Networking options
-+#
-+CONFIG_PACKET=y
-+CONFIG_PACKET_MMAP=y
-+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_NET_KEY is not set
-+CONFIG_INET=y
-+CONFIG_IP_MULTICAST=y
-+# CONFIG_IP_ADVANCED_ROUTER is not set
-+CONFIG_IP_FIB_HASH=y
-+# CONFIG_IP_PNP is not set
-+# CONFIG_NET_IPIP is not set
-+# CONFIG_NET_IPGRE is not set
-+# CONFIG_IP_MROUTE 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=y
-+CONFIG_INET_XFRM_MODE_TUNNEL=y
-+CONFIG_INET_XFRM_MODE_BEET=y
-+# CONFIG_INET_LRO is not set
-+CONFIG_INET_DIAG=y
-+CONFIG_INET_TCP_DIAG=y
-+# CONFIG_TCP_CONG_ADVANCED is not set
-+CONFIG_TCP_CONG_CUBIC=y
-+CONFIG_DEFAULT_TCP_CONG="cubic"
-+# CONFIG_TCP_MD5SIG is not set
-+# CONFIG_IP_VS is not set
-+# CONFIG_IPV6 is not set
-+# CONFIG_INET6_XFRM_TUNNEL is not set
-+# CONFIG_INET6_TUNNEL is not set
-+# CONFIG_NETLABEL is not set
-+# CONFIG_NETWORK_SECMARK is not set
-+CONFIG_NETFILTER=y
-+# CONFIG_NETFILTER_DEBUG is not set
-+
-+#
-+# Core Netfilter Configuration
-+#
-+# CONFIG_NETFILTER_NETLINK is not set
-+# CONFIG_NF_CONNTRACK_ENABLED is not set
-+# CONFIG_NF_CONNTRACK is not set
-+# CONFIG_NETFILTER_XTABLES is not set
-+
-+#
-+# IP: Netfilter Configuration
-+#
-+# CONFIG_IP_NF_QUEUE is not set
-+# CONFIG_IP_NF_IPTABLES is not set
-+# CONFIG_IP_NF_ARPTABLES is not set
-+# CONFIG_IP_DCCP is not set
-+# CONFIG_IP_SCTP is not set
-+# CONFIG_TIPC is not set
-+# CONFIG_ATM is not set
-+# CONFIG_BRIDGE 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_NET_SCHED is not set
-+
-+#
-+# Network testing
-+#
-+# CONFIG_NET_PKTGEN is not set
-+# CONFIG_HAMRADIO is not set
-+# CONFIG_IRDA is not set
-+# CONFIG_BT is not set
-+# CONFIG_AF_RXRPC is not set
-+
-+#
-+# Wireless
-+#
-+# CONFIG_CFG80211 is not set
-+CONFIG_WIRELESS_EXT=y
-+# CONFIG_MAC80211 is not set
-+# CONFIG_IEEE80211 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=y
-+# CONFIG_SYS_HYPERVISOR is not set
-+# CONFIG_CONNECTOR is not set
-+# CONFIG_MTD is not set
-+# CONFIG_PARPORT is not set
-+CONFIG_BLK_DEV=y
-+# CONFIG_BLK_DEV_COW_COMMON is not set
-+CONFIG_BLK_DEV_LOOP=y
-+# CONFIG_BLK_DEV_CRYPTOLOOP 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=10240
-+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-+# CONFIG_CDROM_PKTCDVD is not set
-+# CONFIG_ATA_OVER_ETH is not set
-+# CONFIG_MISC_DEVICES is not set
-+# 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=y
-+
-+#
-+# 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 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=y
-+# 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=y
-+# CONFIG_ISCSI_TCP is not set
-+# CONFIG_SCSI_DEBUG is not set
-+CONFIG_ATA=y
-+# CONFIG_ATA_NONSTANDARD is not set
-+CONFIG_SATA_OX810=y
-+# CONFIG_SATA_OXNAS_SINGLE_SATA is not set
-+# CONFIG_SATA_OXNAS_DISK_LIGHT is not set
-+CONFIG_MD=y
-+CONFIG_BLK_DEV_MD=y
-+CONFIG_MD_LINEAR=y
-+# CONFIG_MD_RAID0 is not set
-+CONFIG_MD_RAID1=y
-+# CONFIG_MD_RAID10 is not set
-+# CONFIG_MD_RAID456 is not set
-+# CONFIG_MD_MULTIPATH is not set
-+# CONFIG_MD_FAULTY is not set
-+CONFIG_BLK_DEV_DM=y
-+# CONFIG_DM_DEBUG is not set
-+CONFIG_DM_CRYPT=y
-+# CONFIG_DM_SNAPSHOT is not set
-+# CONFIG_DM_MIRROR is not set
-+# CONFIG_DM_ZERO is not set
-+# CONFIG_DM_MULTIPATH is not set
-+# CONFIG_DM_DELAY is not set
-+# CONFIG_DM_UEVENT is not set
-+CONFIG_NETDEVICES=y
-+# CONFIG_NETDEVICES_MULTIQUEUE is not set
-+# 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_NET_ETHERNET is not set
-+CONFIG_MII=y
-+CONFIG_NETDEV_1000=y
-+CONFIG_SYNOPSYS_GMAC=y
-+# CONFIG_NETDEV_10000 is not set
-+
-+#
-+# Wireless LAN
-+#
-+# CONFIG_WLAN_PRE80211 is not set
-+# CONFIG_WLAN_80211 is not set
-+
-+#
-+# 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_SHAPER 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
-+
-+#
-+# Input device support
-+#
-+CONFIG_INPUT=y
-+# CONFIG_INPUT_FF_MEMLESS is not set
-+# CONFIG_INPUT_POLLDEV is not set
-+
-+#
-+# Userland interfaces
-+#
-+CONFIG_INPUT_MOUSEDEV=y
-+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-+# 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 is not set
-+
-+#
-+# Hardware I/O ports
-+#
-+# CONFIG_SERIO is not set
-+# CONFIG_GAMEPORT is not set
-+
-+#
-+# Character devices
-+#
-+CONFIG_VT=y
-+CONFIG_VT_CONSOLE=y
-+CONFIG_HW_CONSOLE=y
-+# CONFIG_VT_HW_CONSOLE_BINDING is not set
-+# CONFIG_SERIAL_NONSTANDARD is not set
-+
-+#
-+# Serial drivers
-+#
-+CONFIG_SERIAL_8250=y
-+CONFIG_SERIAL_8250_CONSOLE=y
-+CONFIG_SERIAL_8250_NR_UARTS=4
-+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-+# CONFIG_SERIAL_8250_EXTENDED is not set
-+
-+#
-+# Non-8250 serial port support
-+#
-+# CONFIG_SERIAL_AMBA_PL010 is not set
-+# CONFIG_SERIAL_AMBA_PL011 is not set
-+CONFIG_SERIAL_CORE=y
-+CONFIG_SERIAL_CORE_CONSOLE=y
-+CONFIG_UNIX98_PTYS=y
-+# CONFIG_LEGACY_PTYS is not set
-+# CONFIG_IPMI_HANDLER is not set
-+CONFIG_HW_RANDOM=m
-+# CONFIG_NVRAM is not set
-+# CONFIG_R3964 is not set
-+# CONFIG_RAW_DRIVER is not set
-+# CONFIG_TCG_TPM is not set
-+CONFIG_I2C=m
-+CONFIG_I2C_BOARDINFO=y
-+# CONFIG_I2C_CHARDEV is not set
-+
-+#
-+# I2C Algorithms
-+#
-+CONFIG_I2C_ALGOBIT=m
-+# CONFIG_I2C_ALGOPCF is not set
-+# CONFIG_I2C_ALGOPCA is not set
-+# CONFIG_I2C_ALGOOXSEMI is not set
-+
-+#
-+# I2C Hardware Bus support
-+#
-+CONFIG_I2C_OXNAS_BITBASH=m
-+# CONFIG_I2C_OCORES is not set
-+# CONFIG_I2C_PARPORT_LIGHT is not set
-+# CONFIG_I2C_SIMTEC is not set
-+# CONFIG_I2C_TAOS_EVM is not set
-+# CONFIG_I2C_STUB is not set
-+# CONFIG_I2C_TINY_USB is not set
-+
-+#
-+# Miscellaneous I2C Chip support
-+#
-+# CONFIG_SENSORS_DS1337 is not set
-+# CONFIG_SENSORS_DS1374 is not set
-+# CONFIG_DS1682 is not set
-+# CONFIG_SENSORS_EEPROM is not set
-+# CONFIG_SENSORS_PCF8574 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
-+# CONFIG_I2C_DEBUG_BUS is not set
-+# CONFIG_I2C_DEBUG_CHIP is not set
-+
-+#
-+# SPI support
-+#
-+# CONFIG_SPI is not set
-+# CONFIG_SPI_MASTER is not set
-+# CONFIG_W1 is not set
-+# CONFIG_POWER_SUPPLY is not set
-+# CONFIG_HWMON is not set
-+# CONFIG_WATCHDOG is not set
-+
-+#
-+# Sonics Silicon Backplane
-+#
-+CONFIG_SSB_POSSIBLE=y
-+# CONFIG_SSB is not set
-+
-+#
-+# Multifunction device drivers
-+#
-+# CONFIG_MFD_SM501 is not set
-+
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
-+# CONFIG_DVB_CORE is not set
-+CONFIG_DAB=y
-+# CONFIG_USB_DABUSB is not set
-+
-+#
-+# Graphics support
-+#
-+# CONFIG_VGASTATE is not set
-+CONFIG_VIDEO_OUTPUT_CONTROL=m
-+# 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_VGA_CONSOLE is not set
-+CONFIG_DUMMY_CONSOLE=y
-+
-+#
-+# Sound
-+#
-+# CONFIG_SOUND is not set
-+# CONFIG_HID_SUPPORT is not set
-+CONFIG_USB_SUPPORT=y
-+CONFIG_USB_ARCH_HAS_HCD=y
-+CONFIG_USB_ARCH_HAS_OHCI=y
-+CONFIG_USB_ARCH_HAS_EHCI=y
-+CONFIG_USB=m
-+# CONFIG_USB_DEBUG is not set
-+
-+#
-+# Miscellaneous USB options
-+#
-+CONFIG_USB_DEVICEFS=y
-+CONFIG_USB_DEVICE_CLASS=y
-+# CONFIG_USB_DYNAMIC_MINORS is not set
-+# CONFIG_USB_OTG is not set
-+
-+#
-+# USB Host Controller Drivers
-+#
-+CONFIG_USB_EHCI_HCD=m
-+# CONFIG_USB_EHCI_SPLIT_ISO is not set
-+CONFIG_USB_EHCI_ROOT_HUB_TT=y
-+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-+# CONFIG_USB_ISP116X_HCD is not set
-+# CONFIG_USB_OHCI_HCD is not set
-+# CONFIG_USB_SL811_HCD is not set
-+# CONFIG_USB_R8A66597_HCD is not set
-+
-+#
-+# USB Device Class drivers
-+#
-+# CONFIG_USB_ACM is not set
-+# CONFIG_USB_PRINTER is not set
-+
-+#
-+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-+#
-+
-+#
-+# may also be needed; see USB_STORAGE Help for more information
-+#
-+CONFIG_USB_STORAGE=m
-+# 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
-+# CONFIG_USB_STORAGE_JUMPSHOT is not set
-+# CONFIG_USB_STORAGE_ALAUDA is not set
-+# CONFIG_USB_STORAGE_KARMA is not set
-+# CONFIG_USB_LIBUSUAL is not set
-+
-+#
-+# USB Imaging devices
-+#
-+# CONFIG_USB_MDC800 is not set
-+# CONFIG_USB_MICROTEK is not set
-+# CONFIG_USB_MON is not set
-+
-+#
-+# USB port drivers
-+#
-+
-+#
-+# USB Serial Converter support
-+#
-+# 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_AUERSWALD 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_PHIDGET 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=m
-+
-+#
-+# USB DSL modem support
-+#
-+
-+#
-+# USB Gadget Support
-+#
-+# CONFIG_USB_GADGET is not set
-+# CONFIG_MMC is not set
-+CONFIG_NEW_LEDS=y
-+CONFIG_LEDS_CLASS=y
-+
-+#
-+# LED drivers
-+#
-+CONFIG_WDC_LEDS_OXNAS800=m
-+# CONFIG_OXNAS_WD810_LEDS is not set
-+
-+#
-+# LED Triggers
-+#
-+CONFIG_LEDS_TRIGGERS=y
-+# CONFIG_LEDS_TRIGGER_TIMER is not set
-+CONFIG_WDC_LEDS_TRIGGER_SATA_DISK=y
-+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
-+CONFIG_RTC_LIB=y
-+CONFIG_RTC_CLASS=m
-+
-+#
-+# 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=m
-+# 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
-+
-+#
-+# SPI RTC drivers
-+#
-+
-+#
-+# Platform RTC drivers
-+#
-+# CONFIG_RTC_DRV_CMOS is not set
-+# CONFIG_RTC_DRV_DS1553 is not set
-+# CONFIG_RTC_DRV_STK17TA8 is not set
-+# CONFIG_RTC_DRV_DS1742 is not set
-+# CONFIG_RTC_DRV_M48T86 is not set
-+# CONFIG_RTC_DRV_M48T59 is not set
-+# CONFIG_RTC_DRV_V3020 is not set
-+
-+#
-+# on-CPU RTC drivers
-+#
-+# CONFIG_RTC_DRV_PL031 is not set
-+# CONFIG_DMADEVICES is not set
-+
-+#
-+# File systems
-+#
-+CONFIG_EXT2_FS=y
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XIP is not set
-+CONFIG_EXT3_FS=y
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT4DEV_FS is not set
-+CONFIG_JBD=y
-+# CONFIG_REISERFS_FS is not set
-+# CONFIG_JFS_FS is not set
-+CONFIG_FS_POSIX_ACL=y
-+CONFIG_XFS_FS=y
-+# CONFIG_XFS_QUOTA is not set
-+# CONFIG_XFS_SECURITY is not set
-+# CONFIG_XFS_POSIX_ACL is not set
-+# CONFIG_XFS_RT is not set
-+# CONFIG_GFS2_FS is not set
-+# CONFIG_OCFS2_FS is not set
-+# CONFIG_MINIX_FS is not set
-+# CONFIG_ROMFS_FS is not set
-+CONFIG_INOTIFY=y
-+CONFIG_INOTIFY_USER=y
-+# CONFIG_QUOTA is not set
-+CONFIG_DNOTIFY=y
-+# CONFIG_AUTOFS_FS is not set
-+# CONFIG_AUTOFS4_FS is not set
-+CONFIG_FUSE_FS=y
-+
-+#
-+# CD-ROM/DVD Filesystems
-+#
-+# CONFIG_ISO9660_FS is not set
-+# CONFIG_UDF_FS is not set
-+
-+#
-+# DOS/FAT/NT Filesystems
-+#
-+CONFIG_FAT_FS=y
-+CONFIG_MSDOS_FS=y
-+CONFIG_VFAT_FS=m
-+CONFIG_FAT_DEFAULT_CODEPAGE=437
-+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-+CONFIG_NTFS_FS=m
-+# CONFIG_NTFS_DEBUG is not set
-+# CONFIG_NTFS_RW is not set
-+
-+#
-+# Pseudo filesystems
-+#
-+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_ADFS_FS is not set
-+# CONFIG_AFFS_FS is not set
-+# CONFIG_HFS_FS is not set
-+CONFIG_HFSPLUS_FS=m
-+# CONFIG_BEFS_FS is not set
-+# CONFIG_BFS_FS is not set
-+# CONFIG_EFS_FS is not set
-+# CONFIG_CRAMFS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_HPFS_FS is not set
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UFS_FS is not set
-+CONFIG_NETWORK_FILESYSTEMS=y
-+# CONFIG_NFS_FS is not set
-+CONFIG_NFSD=m
-+CONFIG_NFSD_V2_ACL=y
-+CONFIG_NFSD_V3=y
-+CONFIG_NFSD_V3_ACL=y
-+# CONFIG_NFSD_V4 is not set
-+CONFIG_NFSD_TCP=y
-+CONFIG_LOCKD=m
-+CONFIG_LOCKD_V4=y
-+CONFIG_EXPORTFS=m
-+CONFIG_NFS_ACL_SUPPORT=m
-+CONFIG_NFS_COMMON=y
-+CONFIG_SUNRPC=m
-+# CONFIG_SUNRPC_BIND34 is not set
-+# 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=y
-+# CONFIG_ACORN_PARTITION is not set
-+# CONFIG_OSF_PARTITION is not set
-+# CONFIG_AMIGA_PARTITION is not set
-+# CONFIG_ATARI_PARTITION is not set
-+CONFIG_MAC_PARTITION=y
-+CONFIG_MSDOS_PARTITION=y
-+# CONFIG_BSD_DISKLABEL is not set
-+# CONFIG_MINIX_SUBPARTITION is not set
-+# CONFIG_SOLARIS_X86_PARTITION is not set
-+# CONFIG_UNIXWARE_DISKLABEL is not set
-+CONFIG_LDM_PARTITION=y
-+# CONFIG_LDM_DEBUG is not set
-+# CONFIG_SGI_PARTITION is not set
-+# CONFIG_ULTRIX_PARTITION is not set
-+# CONFIG_SUN_PARTITION is not set
-+# CONFIG_KARMA_PARTITION is not set
-+CONFIG_EFI_PARTITION=y
-+# CONFIG_SYSV68_PARTITION is not set
-+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 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=y
-+# CONFIG_DLM is not set
-+# CONFIG_INSTRUMENTATION is not set
-+
-+#
-+# Kernel hacking
-+#
-+# CONFIG_PRINTK_TIME is not set
-+CONFIG_ENABLE_WARN_DEPRECATED=y
-+CONFIG_ENABLE_MUST_CHECK=y
-+# CONFIG_MAGIC_SYSRQ is not set
-+# CONFIG_UNUSED_SYMBOLS is not set
-+# CONFIG_DEBUG_FS is not set
-+# CONFIG_HEADERS_CHECK is not set
-+# CONFIG_DEBUG_KERNEL is not set
-+CONFIG_DEBUG_BUGVERBOSE=y
-+CONFIG_FRAME_POINTER=y
-+# CONFIG_SAMPLES is not set
-+# CONFIG_DEBUG_USER is not set
-+
-+#
-+# Security options
-+#
-+# CONFIG_KEYS is not set
-+CONFIG_SECURITY=y
-+# CONFIG_SECURITY_NETWORK is not set
-+# CONFIG_SECURITY_CAPABILITIES is not set
-+CONFIG_SECURITY_TRUSTEES=y
-+# CONFIG_SECURITY_TRUSTEES_DEBUG is not set
-+CONFIG_CRYPTO=y
-+CONFIG_CRYPTO_ALGAPI=y
-+CONFIG_CRYPTO_BLKCIPHER=y
-+CONFIG_CRYPTO_MANAGER=y
-+# CONFIG_CRYPTO_HMAC is not set
-+# CONFIG_CRYPTO_XCBC is not set
-+# CONFIG_CRYPTO_NULL is not set
-+# CONFIG_CRYPTO_MD4 is not set
-+# CONFIG_CRYPTO_MD5 is not set
-+# CONFIG_CRYPTO_SHA1 is not set
-+# CONFIG_CRYPTO_SHA256 is not set
-+# CONFIG_CRYPTO_SHA512 is not set
-+# CONFIG_CRYPTO_WP512 is not set
-+# CONFIG_CRYPTO_TGR192 is not set
-+# CONFIG_CRYPTO_GF128MUL is not set
-+CONFIG_CRYPTO_ECB=m
-+CONFIG_CRYPTO_CBC=y
-+CONFIG_CRYPTO_PCBC=m
-+# CONFIG_CRYPTO_LRW is not set
-+# CONFIG_CRYPTO_XTS is not set
-+# CONFIG_CRYPTO_CRYPTD is not set
-+# CONFIG_CRYPTO_DES is not set
-+# CONFIG_CRYPTO_FCRYPT is not set
-+# CONFIG_CRYPTO_BLOWFISH is not set
-+# CONFIG_CRYPTO_TWOFISH is not set
-+# CONFIG_CRYPTO_SERPENT is not set
-+CONFIG_CRYPTO_AES=m
-+# CONFIG_CRYPTO_CAST5 is not set
-+# CONFIG_CRYPTO_CAST6 is not set
-+# CONFIG_CRYPTO_TEA is not set
-+CONFIG_CRYPTO_ARC4=m
-+# CONFIG_CRYPTO_KHAZAD is not set
-+# CONFIG_CRYPTO_ANUBIS is not set
-+# CONFIG_CRYPTO_SEED is not set
-+# CONFIG_CRYPTO_DEFLATE is not set
-+CONFIG_CRYPTO_MICHAEL_MIC=m
-+# CONFIG_CRYPTO_CRC32C is not set
-+# CONFIG_CRYPTO_CAMELLIA is not set
-+# CONFIG_CRYPTO_TEST is not set
-+# CONFIG_CRYPTO_AUTHENC is not set
-+CONFIG_CRYPTO_HW=y
-+
-+#
-+# Library routines
-+#
-+CONFIG_BITREVERSE=y
-+CONFIG_CRC_CCITT=y
-+# CONFIG_CRC16 is not set
-+# CONFIG_CRC_ITU_T is not set
-+CONFIG_CRC32=y
-+# CONFIG_CRC7 is not set
-+# CONFIG_LIBCRC32C is not set
-+CONFIG_PLIST=y
-+CONFIG_HAS_IOMEM=y
-+CONFIG_HAS_IOPORT=y
-+CONFIG_HAS_DMA=y
-diff -Nurd linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig
---- linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig 2008-06-11 17:47:52.000000000 +0200
-@@ -0,0 +1,1108 @@
-+#
-+# Automatically generated make config: don't edit
-+# Linux kernel version: 2.6.24.4
-+# Thu Jun 5 16:08:07 2008
-+#
-+CONFIG_ARM=y
-+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-+# CONFIG_GENERIC_GPIO is not set
-+# CONFIG_GENERIC_TIME is not set
-+# CONFIG_GENERIC_CLOCKEVENTS is not set
-+CONFIG_MMU=y
-+# CONFIG_NO_IOPORT is not set
-+CONFIG_GENERIC_HARDIRQS=y
-+CONFIG_STACKTRACE_SUPPORT=y
-+CONFIG_LOCKDEP_SUPPORT=y
-+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-+CONFIG_HARDIRQS_SW_RESEND=y
-+CONFIG_GENERIC_IRQ_PROBE=y
-+CONFIG_RWSEM_GENERIC_SPINLOCK=y
-+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-+CONFIG_GENERIC_HWEIGHT=y
-+CONFIG_GENERIC_CALIBRATE_DELAY=y
-+CONFIG_ZONE_DMA=y
-+CONFIG_VECTORS_BASE=0xffff0000
-+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-+
-+#
-+# General setup
-+#
-+CONFIG_EXPERIMENTAL=y
-+CONFIG_BROKEN_ON_SMP=y
-+CONFIG_INIT_ENV_ARG_LIMIT=32
-+CONFIG_LOCALVERSION=""
-+CONFIG_LOCALVERSION_AUTO=y
-+CONFIG_SWAP=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_USER_NS is not set
-+# CONFIG_PID_NS is not set
-+# CONFIG_AUDIT is not set
-+# CONFIG_IKCONFIG is not set
-+CONFIG_LOG_BUF_SHIFT=14
-+# CONFIG_CGROUPS is not set
-+# CONFIG_FAIR_GROUP_SCHED is not set
-+CONFIG_SYSFS_DEPRECATED=y
-+# CONFIG_RELAY is not set
-+CONFIG_BLK_DEV_INITRD=y
-+CONFIG_INITRAMFS_SOURCE=""
-+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-+CONFIG_SYSCTL=y
-+# CONFIG_EMBEDDED is not set
-+CONFIG_UID16=y
-+CONFIG_SYSCTL_SYSCALL=y
-+CONFIG_KALLSYMS=y
-+# 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_ANON_INODES=y
-+CONFIG_EPOLL=y
-+CONFIG_SIGNALFD=y
-+CONFIG_EVENTFD=y
-+CONFIG_SHMEM=y
-+CONFIG_VM_EVENT_COUNTERS=y
-+CONFIG_SLAB=y
-+# CONFIG_SLUB is not set
-+# CONFIG_SLOB is not set
-+CONFIG_SLABINFO=y
-+CONFIG_RT_MUTEXES=y
-+# CONFIG_TINY_SHMEM is not set
-+CONFIG_BASE_SMALL=0
-+CONFIG_MODULES=y
-+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 is not set
-+CONFIG_BLOCK=y
-+# CONFIG_LBD is not set
-+# CONFIG_BLK_DEV_IO_TRACE is not set
-+# CONFIG_LSF is not set
-+# CONFIG_BLK_DEV_BSG is not set
-+
-+#
-+# IO Schedulers
-+#
-+CONFIG_IOSCHED_NOOP=y
-+CONFIG_IOSCHED_AS=y
-+CONFIG_IOSCHED_DEADLINE=y
-+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"
-+
-+#
-+# System Type
-+#
-+# CONFIG_ARCH_AAEC2000 is not set
-+# CONFIG_ARCH_INTEGRATOR is not set
-+# CONFIG_ARCH_REALVIEW is not set
-+# CONFIG_ARCH_VERSATILE is not set
-+# CONFIG_ARCH_AT91 is not set
-+# CONFIG_ARCH_CLPS7500 is not set
-+# CONFIG_ARCH_CLPS711X is not set
-+# CONFIG_ARCH_CO285 is not set
-+# CONFIG_ARCH_EBSA110 is not set
-+# CONFIG_ARCH_EP93XX is not set
-+# CONFIG_ARCH_FOOTBRIDGE is not set
-+# CONFIG_ARCH_NETX is not set
-+# CONFIG_ARCH_H720X is not set
-+# CONFIG_ARCH_IMX is not set
-+# CONFIG_ARCH_IOP13XX is not set
-+# CONFIG_ARCH_IOP32X is not set
-+# CONFIG_ARCH_IOP33X is not set
-+# CONFIG_ARCH_IXP23XX is not set
-+# CONFIG_ARCH_IXP2000 is not set
-+# CONFIG_ARCH_IXP4XX is not set
-+# CONFIG_ARCH_L7200 is not set
-+# CONFIG_ARCH_KS8695 is not set
-+# CONFIG_ARCH_NS9XXX is not set
-+# CONFIG_ARCH_MXC is not set
-+# CONFIG_ARCH_PNX4008 is not set
-+# CONFIG_ARCH_PXA is not set
-+# CONFIG_ARCH_RPC is not set
-+# CONFIG_ARCH_SA1100 is not set
-+# CONFIG_ARCH_S3C2410 is not set
-+# CONFIG_ARCH_SHARK is not set
-+# CONFIG_ARCH_LH7A40X is not set
-+# CONFIG_ARCH_DAVINCI is not set
-+# CONFIG_ARCH_OMAP is not set
-+CONFIG_ARCH_OXNAS=y
-+
-+#
-+# Boot options
-+#
-+
-+#
-+# Power management
-+#
-+
-+#
-+# Oxford Semiconductor NAS Options
-+#
-+# CONFIG_ARCH_OXNAS_FPGA is not set
-+CONFIG_NOMINAL_PLL400_FREQ=733333333
-+CONFIG_NOMINAL_RPSCLK_FREQ=25000000
-+# CONFIG_OXNAS_VERSION_0X800 is not set
-+CONFIG_OXNAS_VERSION_0X810=y
-+# CONFIG_OXNAS_VERSION_0X850 is not set
-+# CONFIG_ARCH_OXNAS_UART1 is not set
-+CONFIG_ARCH_OXNAS_UART2=y
-+# CONFIG_ARCH_OXNAS_UART2_MODEM is not set
-+# CONFIG_ARCH_OXNAS_UART3 is not set
-+# CONFIG_ARCH_OXNAS_UART4 is not set
-+CONFIG_OXNAS_SATA_POWER_1=y
-+CONFIG_OXNAS_SATA_POWER_GPIO_1=31
-+CONFIG_OXNAS_SATA_POWER_2=y
-+CONFIG_OXNAS_SATA_POWER_GPIO_2=32
-+CONFIG_FORCE_MAX_ZONEORDER=10
-+CONFIG_SRAM_NUM_PAGES=32
-+CONFIG_SUPPORT_LEON=y
-+CONFIG_LEON_PAGES=2
-+CONFIG_LEON_COPRO=y
-+CONFIG_LEON_OFFLOAD_TX=y
-+# CONFIG_LEON_RESERVE_DMA_CHANNEL is not set
-+CONFIG_LEON_OFFLOAD_TSO=y
-+# CONFIG_LEON_START_EARLY is not set
-+CONFIG_LEON_POWER_BUTTON_MONITOR=m
-+CONFIG_OXNAS_POWER_BUTTON_GPIO=0
-+CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
-+CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO=4
-+# CONFIG_OXNAS_DDR_MON is not set
-+# CONFIG_OXNAS_AHB_MON is not set
-+# CONFIG_OXNAS_CACHE_LOCKDOWN is not set
-+# CONFIG_DO_MEM_TEST is not set
-+# CONFIG_CRYPTO_OXAESLRW is not set
-+CONFIG_DESCRIPTORS_PAGES=6
-+CONFIG_ARCH_OXNAS_NUM_GMAC_DESCRIPTORS=192
-+CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES=256
-+CONFIG_TACHO_THERM_AND_FAN=m
-+# CONFIG_GPIO_TEST is not set
-+CONFIG_OXNAS_RTC=m
-+# CONFIG_I2S is not set
-+# CONFIG_DPE_TEST is not set
-+# CONFIG_OXNAS_INSTRUMENT_COPIES is not set
-+# CONFIG_OXNAS_DMA_COPIES is not set
-+# CONFIG_OXNAS_AHB_MONITOR_MODULE is not set
-+# CONFIG_OXNAS_USB_TEST_MODES is not set
-+# CONFIG_OXNAS_FRONT_LAMP_CONTROL is not set
-+# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
-+# CONFIG_OXNAS_LED_TEST is not set
-+CONFIG_OXNAS_I2C_SDA=3
-+CONFIG_OXNAS_I2C_SCL=2
-+CONFIG_OXNAS_USB_PORTA_POWER_CONTROL=y
-+# CONFIG_OXNAS_USB_PORTB_POWER_CONTROL is not set
-+# CONFIG_OXNAS_USB_PORTC_POWER_CONTROL is not set
-+CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE=y
-+CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE=y
-+# CONFIG_WDC_FAN_OXNAS800 is not set
-+# CONFIG_OXNAS_MAP_SRAM is not set
-+# CONFIG_OXNAS_SUID_INHERIT is not set
-+CONFIG_OXNAS_USB_HUB_SUPPORT=y
-+CONFIG_OXNAS_USB_CKOUT=y
-+CONFIG_OXNAS_USB_HUB_RESET_CONTROL=y
-+CONFIG_OXNAS_USB_HUB_RESET_GPIO=27
-+CONFIG_OXNAS_USB_HUB_RESET_ACTIVE_HIGH=0
-+CONFIG_OXNAS_USB_HUB_RESET_TOGGLE=y
-+CONFIG_OXNAS_USB_HUB_RESET_PERIOD_MS=100
-+
-+#
-+# Processor Type
-+#
-+CONFIG_CPU_32=y
-+CONFIG_CPU_ARM926T=y
-+CONFIG_CPU_32v5=y
-+CONFIG_CPU_ABRT_EV5TJ=y
-+CONFIG_CPU_CACHE_VIVT=y
-+CONFIG_CPU_COPY_V4WB=y
-+CONFIG_CPU_TLB_V4WBI=y
-+CONFIG_CPU_CP15=y
-+CONFIG_CPU_CP15_MMU=y
-+
-+#
-+# Processor Features
-+#
-+CONFIG_ARM_THUMB=y
-+# CONFIG_CPU_ICACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-+# CONFIG_OUTER_CACHE is not set
-+
-+#
-+# Bus support
-+#
-+CONFIG_ARM_AMBA=y
-+# CONFIG_PCI is not set
-+# CONFIG_PCI_SYSCALL is not set
-+# CONFIG_ARCH_SUPPORTS_MSI is not set
-+# CONFIG_PCCARD is not set
-+
-+#
-+# Kernel Features
-+#
-+# CONFIG_TICK_ONESHOT is not set
-+# CONFIG_PREEMPT is not set
-+# CONFIG_NO_IDLE_HZ is not set
-+CONFIG_HZ=100
-+CONFIG_AEABI=y
-+CONFIG_OABI_COMPAT=y
-+# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPARSEMEM_STATIC is not set
-+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
-+CONFIG_SPLIT_PTLOCK_CPUS=4096
-+# CONFIG_RESOURCES_64BIT is not set
-+CONFIG_ZONE_DMA_FLAG=1
-+CONFIG_BOUNCE=y
-+CONFIG_VIRT_TO_BUS=y
-+CONFIG_ALIGNMENT_TRAP=y
-+
-+#
-+# Boot options
-+#
-+CONFIG_ZBOOT_ROM_TEXT=0x0
-+CONFIG_ZBOOT_ROM_BSS=0x0
-+CONFIG_CMDLINE=""
-+# CONFIG_XIP_KERNEL is not set
-+# CONFIG_KEXEC is not set
-+
-+#
-+# Floating point emulation
-+#
-+
-+#
-+# At least one emulation must be selected
-+#
-+# CONFIG_FPE_NWFPE is not set
-+# CONFIG_FPE_FASTFPE is not set
-+# CONFIG_VFP is not set
-+
-+#
-+# Userspace binary formats
-+#
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_AOUT is not set
-+# CONFIG_BINFMT_MISC is not set
-+
-+#
-+# Power management options
-+#
-+# CONFIG_PM is not set
-+CONFIG_SUSPEND_UP_POSSIBLE=y
-+
-+#
-+# Networking
-+#
-+CONFIG_NET=y
-+
-+#
-+# Networking options
-+#
-+CONFIG_PACKET=y
-+CONFIG_PACKET_MMAP=y
-+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_NET_KEY is not set
-+CONFIG_INET=y
-+CONFIG_IP_MULTICAST=y
-+# CONFIG_IP_ADVANCED_ROUTER is not set
-+CONFIG_IP_FIB_HASH=y
-+# CONFIG_IP_PNP is not set
-+# CONFIG_NET_IPIP is not set
-+# CONFIG_NET_IPGRE is not set
-+# CONFIG_IP_MROUTE 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=y
-+CONFIG_INET_XFRM_MODE_TUNNEL=y
-+CONFIG_INET_XFRM_MODE_BEET=y
-+# CONFIG_INET_LRO is not set
-+CONFIG_INET_DIAG=y
-+CONFIG_INET_TCP_DIAG=y
-+# CONFIG_TCP_CONG_ADVANCED is not set
-+CONFIG_TCP_CONG_CUBIC=y
-+CONFIG_DEFAULT_TCP_CONG="cubic"
-+# CONFIG_TCP_MD5SIG is not set
-+# CONFIG_IP_VS is not set
-+# CONFIG_IPV6 is not set
-+# CONFIG_INET6_XFRM_TUNNEL is not set
-+# CONFIG_INET6_TUNNEL is not set
-+# CONFIG_NETLABEL is not set
-+# CONFIG_NETWORK_SECMARK is not set
-+CONFIG_NETFILTER=y
-+# CONFIG_NETFILTER_DEBUG is not set
-+
-+#
-+# Core Netfilter Configuration
-+#
-+# CONFIG_NETFILTER_NETLINK is not set
-+# CONFIG_NF_CONNTRACK_ENABLED is not set
-+# CONFIG_NF_CONNTRACK is not set
-+# CONFIG_NETFILTER_XTABLES is not set
-+
-+#
-+# IP: Netfilter Configuration
-+#
-+# CONFIG_IP_NF_QUEUE is not set
-+# CONFIG_IP_NF_IPTABLES is not set
-+# CONFIG_IP_NF_ARPTABLES is not set
-+# CONFIG_IP_DCCP is not set
-+# CONFIG_IP_SCTP is not set
-+# CONFIG_TIPC is not set
-+# CONFIG_ATM is not set
-+# CONFIG_BRIDGE 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_NET_SCHED is not set
-+
-+#
-+# Network testing
-+#
-+# CONFIG_NET_PKTGEN is not set
-+# CONFIG_HAMRADIO is not set
-+# CONFIG_IRDA is not set
-+# CONFIG_BT is not set
-+# CONFIG_AF_RXRPC is not set
-+
-+#
-+# Wireless
-+#
-+# CONFIG_CFG80211 is not set
-+CONFIG_WIRELESS_EXT=y
-+# CONFIG_MAC80211 is not set
-+# CONFIG_IEEE80211 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=y
-+# CONFIG_SYS_HYPERVISOR is not set
-+# CONFIG_CONNECTOR is not set
-+# CONFIG_MTD is not set
-+# CONFIG_PARPORT is not set
-+CONFIG_BLK_DEV=y
-+# CONFIG_BLK_DEV_COW_COMMON is not set
-+CONFIG_BLK_DEV_LOOP=y
-+# CONFIG_BLK_DEV_CRYPTOLOOP 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=10240
-+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-+# CONFIG_CDROM_PKTCDVD is not set
-+# CONFIG_ATA_OVER_ETH is not set
-+# CONFIG_MISC_DEVICES is not set
-+# 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=y
-+
-+#
-+# 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 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=y
-+# 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=y
-+# CONFIG_ISCSI_TCP is not set
-+# CONFIG_SCSI_DEBUG is not set
-+CONFIG_ATA=y
-+# CONFIG_ATA_NONSTANDARD is not set
-+CONFIG_SATA_OX810=y
-+# CONFIG_SATA_OXNAS_SINGLE_SATA is not set
-+# CONFIG_SATA_OXNAS_DISK_LIGHT is not set
-+CONFIG_MD=y
-+CONFIG_BLK_DEV_MD=y
-+CONFIG_MD_LINEAR=y
-+CONFIG_MD_RAID0=y
-+CONFIG_MD_RAID1=y
-+# CONFIG_MD_RAID10 is not set
-+# CONFIG_MD_RAID456 is not set
-+# CONFIG_MD_MULTIPATH is not set
-+# CONFIG_MD_FAULTY is not set
-+CONFIG_BLK_DEV_DM=y
-+# CONFIG_DM_DEBUG is not set
-+CONFIG_DM_CRYPT=y
-+# CONFIG_DM_SNAPSHOT is not set
-+# CONFIG_DM_MIRROR is not set
-+# CONFIG_DM_ZERO is not set
-+# CONFIG_DM_MULTIPATH is not set
-+# CONFIG_DM_DELAY is not set
-+# CONFIG_DM_UEVENT is not set
-+CONFIG_NETDEVICES=y
-+# CONFIG_NETDEVICES_MULTIQUEUE is not set
-+# 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_NET_ETHERNET is not set
-+CONFIG_MII=y
-+CONFIG_NETDEV_1000=y
-+CONFIG_SYNOPSYS_GMAC=y
-+# CONFIG_NETDEV_10000 is not set
-+
-+#
-+# Wireless LAN
-+#
-+# CONFIG_WLAN_PRE80211 is not set
-+# CONFIG_WLAN_80211 is not set
-+
-+#
-+# 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_SHAPER 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
-+
-+#
-+# Input device support
-+#
-+CONFIG_INPUT=y
-+# CONFIG_INPUT_FF_MEMLESS is not set
-+# CONFIG_INPUT_POLLDEV is not set
-+
-+#
-+# Userland interfaces
-+#
-+CONFIG_INPUT_MOUSEDEV=y
-+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-+# 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 is not set
-+
-+#
-+# Hardware I/O ports
-+#
-+# CONFIG_SERIO is not set
-+# CONFIG_GAMEPORT is not set
-+
-+#
-+# Character devices
-+#
-+CONFIG_VT=y
-+CONFIG_VT_CONSOLE=y
-+CONFIG_HW_CONSOLE=y
-+# CONFIG_VT_HW_CONSOLE_BINDING is not set
-+# CONFIG_SERIAL_NONSTANDARD is not set
-+
-+#
-+# Serial drivers
-+#
-+CONFIG_SERIAL_8250=y
-+CONFIG_SERIAL_8250_CONSOLE=y
-+CONFIG_SERIAL_8250_NR_UARTS=4
-+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-+# CONFIG_SERIAL_8250_EXTENDED is not set
-+
-+#
-+# Non-8250 serial port support
-+#
-+# CONFIG_SERIAL_AMBA_PL010 is not set
-+# CONFIG_SERIAL_AMBA_PL011 is not set
-+CONFIG_SERIAL_CORE=y
-+CONFIG_SERIAL_CORE_CONSOLE=y
-+CONFIG_UNIX98_PTYS=y
-+CONFIG_LEGACY_PTYS=y
-+CONFIG_LEGACY_PTY_COUNT=256
-+# CONFIG_IPMI_HANDLER is not set
-+CONFIG_HW_RANDOM=m
-+# CONFIG_NVRAM is not set
-+# CONFIG_R3964 is not set
-+# CONFIG_RAW_DRIVER is not set
-+# CONFIG_TCG_TPM is not set
-+CONFIG_I2C=m
-+CONFIG_I2C_BOARDINFO=y
-+# CONFIG_I2C_CHARDEV is not set
-+
-+#
-+# I2C Algorithms
-+#
-+CONFIG_I2C_ALGOBIT=m
-+# CONFIG_I2C_ALGOPCF is not set
-+# CONFIG_I2C_ALGOPCA is not set
-+# CONFIG_I2C_ALGOOXSEMI is not set
-+
-+#
-+# I2C Hardware Bus support
-+#
-+CONFIG_I2C_OXNAS_BITBASH=m
-+# CONFIG_I2C_OCORES is not set
-+# CONFIG_I2C_PARPORT_LIGHT is not set
-+# CONFIG_I2C_SIMTEC is not set
-+# CONFIG_I2C_TAOS_EVM is not set
-+# CONFIG_I2C_STUB is not set
-+# CONFIG_I2C_TINY_USB is not set
-+
-+#
-+# Miscellaneous I2C Chip support
-+#
-+# CONFIG_SENSORS_DS1337 is not set
-+# CONFIG_SENSORS_DS1374 is not set
-+# CONFIG_DS1682 is not set
-+# CONFIG_SENSORS_EEPROM is not set
-+# CONFIG_SENSORS_PCF8574 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
-+# CONFIG_I2C_DEBUG_BUS is not set
-+# CONFIG_I2C_DEBUG_CHIP is not set
-+
-+#
-+# SPI support
-+#
-+# CONFIG_SPI is not set
-+# CONFIG_SPI_MASTER is not set
-+# CONFIG_W1 is not set
-+# CONFIG_POWER_SUPPLY is not set
-+# CONFIG_HWMON is not set
-+# CONFIG_WATCHDOG is not set
-+
-+#
-+# Sonics Silicon Backplane
-+#
-+CONFIG_SSB_POSSIBLE=y
-+# CONFIG_SSB is not set
-+
-+#
-+# Multifunction device drivers
-+#
-+# CONFIG_MFD_SM501 is not set
-+
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
-+# CONFIG_DVB_CORE is not set
-+CONFIG_DAB=y
-+# CONFIG_USB_DABUSB is not set
-+
-+#
-+# Graphics support
-+#
-+# CONFIG_VGASTATE is not set
-+CONFIG_VIDEO_OUTPUT_CONTROL=m
-+# 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_VGA_CONSOLE is not set
-+CONFIG_DUMMY_CONSOLE=y
-+
-+#
-+# Sound
-+#
-+# CONFIG_SOUND is not set
-+# CONFIG_HID_SUPPORT is not set
-+CONFIG_USB_SUPPORT=y
-+CONFIG_USB_ARCH_HAS_HCD=y
-+CONFIG_USB_ARCH_HAS_OHCI=y
-+CONFIG_USB_ARCH_HAS_EHCI=y
-+CONFIG_USB=m
-+# CONFIG_USB_DEBUG is not set
-+
-+#
-+# Miscellaneous USB options
-+#
-+CONFIG_USB_DEVICEFS=y
-+CONFIG_USB_DEVICE_CLASS=y
-+# CONFIG_USB_DYNAMIC_MINORS is not set
-+# CONFIG_USB_OTG is not set
-+
-+#
-+# USB Host Controller Drivers
-+#
-+CONFIG_USB_EHCI_HCD=m
-+# CONFIG_USB_EHCI_SPLIT_ISO is not set
-+CONFIG_USB_EHCI_ROOT_HUB_TT=y
-+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-+# CONFIG_USB_ISP116X_HCD is not set
-+# CONFIG_USB_OHCI_HCD is not set
-+# CONFIG_USB_SL811_HCD is not set
-+# CONFIG_USB_R8A66597_HCD is not set
-+
-+#
-+# USB Device Class drivers
-+#
-+# CONFIG_USB_ACM is not set
-+# CONFIG_USB_PRINTER is not set
-+
-+#
-+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-+#
-+
-+#
-+# may also be needed; see USB_STORAGE Help for more information
-+#
-+CONFIG_USB_STORAGE=m
-+# 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
-+# CONFIG_USB_STORAGE_JUMPSHOT is not set
-+# CONFIG_USB_STORAGE_ALAUDA is not set
-+# CONFIG_USB_STORAGE_KARMA is not set
-+# CONFIG_USB_LIBUSUAL is not set
-+
-+#
-+# USB Imaging devices
-+#
-+# CONFIG_USB_MDC800 is not set
-+# CONFIG_USB_MICROTEK is not set
-+# CONFIG_USB_MON is not set
-+
-+#
-+# USB port drivers
-+#
-+
-+#
-+# USB Serial Converter support
-+#
-+# 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_AUERSWALD 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_PHIDGET 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=m
-+
-+#
-+# USB DSL modem support
-+#
-+
-+#
-+# USB Gadget Support
-+#
-+# CONFIG_USB_GADGET is not set
-+# CONFIG_MMC is not set
-+CONFIG_NEW_LEDS=y
-+CONFIG_LEDS_CLASS=y
-+
-+#
-+# LED drivers
-+#
-+# CONFIG_WDC_LEDS_OXNAS800 is not set
-+CONFIG_OXNAS_WD810_LEDS=m
-+
-+#
-+# LED Triggers
-+#
-+CONFIG_LEDS_TRIGGERS=y
-+# CONFIG_LEDS_TRIGGER_TIMER is not set
-+CONFIG_WDC_LEDS_TRIGGER_SATA_DISK=y
-+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
-+CONFIG_RTC_LIB=y
-+CONFIG_RTC_CLASS=m
-+
-+#
-+# 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=m
-+# 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
-+
-+#
-+# SPI RTC drivers
-+#
-+
-+#
-+# Platform RTC drivers
-+#
-+# CONFIG_RTC_DRV_CMOS is not set
-+# CONFIG_RTC_DRV_DS1553 is not set
-+# CONFIG_RTC_DRV_STK17TA8 is not set
-+# CONFIG_RTC_DRV_DS1742 is not set
-+# CONFIG_RTC_DRV_M48T86 is not set
-+# CONFIG_RTC_DRV_M48T59 is not set
-+# CONFIG_RTC_DRV_V3020 is not set
-+
-+#
-+# on-CPU RTC drivers
-+#
-+# CONFIG_RTC_DRV_PL031 is not set
-+# CONFIG_DMADEVICES is not set
-+
-+#
-+# File systems
-+#
-+CONFIG_EXT2_FS=y
-+# CONFIG_EXT2_FS_XATTR is not set
-+# CONFIG_EXT2_FS_XIP is not set
-+CONFIG_EXT3_FS=y
-+# CONFIG_EXT3_FS_XATTR is not set
-+# CONFIG_EXT4DEV_FS is not set
-+CONFIG_JBD=y
-+# CONFIG_REISERFS_FS is not set
-+# CONFIG_JFS_FS is not set
-+CONFIG_FS_POSIX_ACL=y
-+CONFIG_XFS_FS=y
-+CONFIG_XFS_QUOTA=y
-+# CONFIG_XFS_SECURITY is not set
-+# CONFIG_XFS_POSIX_ACL is not set
-+# CONFIG_XFS_RT is not set
-+# CONFIG_GFS2_FS is not set
-+# CONFIG_OCFS2_FS is not set
-+# CONFIG_MINIX_FS is not set
-+# CONFIG_ROMFS_FS is not set
-+CONFIG_INOTIFY=y
-+CONFIG_INOTIFY_USER=y
-+# CONFIG_QUOTA is not set
-+CONFIG_QUOTACTL=y
-+CONFIG_DNOTIFY=y
-+# CONFIG_AUTOFS_FS is not set
-+# CONFIG_AUTOFS4_FS is not set
-+CONFIG_FUSE_FS=y
-+
-+#
-+# CD-ROM/DVD Filesystems
-+#
-+# CONFIG_ISO9660_FS is not set
-+# CONFIG_UDF_FS is not set
-+
-+#
-+# DOS/FAT/NT Filesystems
-+#
-+CONFIG_FAT_FS=y
-+CONFIG_MSDOS_FS=y
-+CONFIG_VFAT_FS=m
-+CONFIG_FAT_DEFAULT_CODEPAGE=437
-+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-+CONFIG_NTFS_FS=m
-+# CONFIG_NTFS_DEBUG is not set
-+# CONFIG_NTFS_RW is not set
-+
-+#
-+# Pseudo filesystems
-+#
-+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_ADFS_FS is not set
-+# CONFIG_AFFS_FS is not set
-+# CONFIG_HFS_FS is not set
-+CONFIG_HFSPLUS_FS=m
-+# CONFIG_BEFS_FS is not set
-+# CONFIG_BFS_FS is not set
-+# CONFIG_EFS_FS is not set
-+# CONFIG_CRAMFS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_HPFS_FS is not set
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UFS_FS is not set
-+CONFIG_NETWORK_FILESYSTEMS=y
-+# CONFIG_NFS_FS is not set
-+CONFIG_NFSD=m
-+CONFIG_NFSD_V2_ACL=y
-+CONFIG_NFSD_V3=y
-+CONFIG_NFSD_V3_ACL=y
-+# CONFIG_NFSD_V4 is not set
-+CONFIG_NFSD_TCP=y
-+CONFIG_LOCKD=m
-+CONFIG_LOCKD_V4=y
-+CONFIG_EXPORTFS=m
-+CONFIG_NFS_ACL_SUPPORT=m
-+CONFIG_NFS_COMMON=y
-+CONFIG_SUNRPC=m
-+# CONFIG_SUNRPC_BIND34 is not set
-+# 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=y
-+# CONFIG_ACORN_PARTITION is not set
-+# CONFIG_OSF_PARTITION is not set
-+# CONFIG_AMIGA_PARTITION is not set
-+# CONFIG_ATARI_PARTITION is not set
-+CONFIG_MAC_PARTITION=y
-+CONFIG_MSDOS_PARTITION=y
-+# CONFIG_BSD_DISKLABEL is not set
-+# CONFIG_MINIX_SUBPARTITION is not set
-+# CONFIG_SOLARIS_X86_PARTITION is not set
-+# CONFIG_UNIXWARE_DISKLABEL is not set
-+CONFIG_LDM_PARTITION=y
-+# CONFIG_LDM_DEBUG is not set
-+# CONFIG_SGI_PARTITION is not set
-+# CONFIG_ULTRIX_PARTITION is not set
-+# CONFIG_SUN_PARTITION is not set
-+# CONFIG_KARMA_PARTITION is not set
-+CONFIG_EFI_PARTITION=y
-+# CONFIG_SYSV68_PARTITION is not set
-+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 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=y
-+# CONFIG_DLM is not set
-+# CONFIG_INSTRUMENTATION is not set
-+
-+#
-+# Kernel hacking
-+#
-+# CONFIG_PRINTK_TIME is not set
-+CONFIG_ENABLE_WARN_DEPRECATED=y
-+CONFIG_ENABLE_MUST_CHECK=y
-+# CONFIG_MAGIC_SYSRQ is not set
-+# CONFIG_UNUSED_SYMBOLS is not set
-+# CONFIG_DEBUG_FS is not set
-+# CONFIG_HEADERS_CHECK is not set
-+# CONFIG_DEBUG_KERNEL is not set
-+CONFIG_DEBUG_BUGVERBOSE=y
-+CONFIG_FRAME_POINTER=y
-+# CONFIG_SAMPLES is not set
-+# CONFIG_DEBUG_USER is not set
-+
-+#
-+# Security options
-+#
-+# CONFIG_KEYS is not set
-+CONFIG_SECURITY=y
-+# CONFIG_SECURITY_NETWORK is not set
-+# CONFIG_SECURITY_CAPABILITIES is not set
-+CONFIG_SECURITY_TRUSTEES=y
-+# CONFIG_SECURITY_TRUSTEES_DEBUG is not set
-+CONFIG_CRYPTO=y
-+CONFIG_CRYPTO_ALGAPI=y
-+CONFIG_CRYPTO_BLKCIPHER=y
-+CONFIG_CRYPTO_MANAGER=y
-+# CONFIG_CRYPTO_HMAC is not set
-+# CONFIG_CRYPTO_XCBC is not set
-+# CONFIG_CRYPTO_NULL is not set
-+# CONFIG_CRYPTO_MD4 is not set
-+# CONFIG_CRYPTO_MD5 is not set
-+# CONFIG_CRYPTO_SHA1 is not set
-+# CONFIG_CRYPTO_SHA256 is not set
-+# CONFIG_CRYPTO_SHA512 is not set
-+# CONFIG_CRYPTO_WP512 is not set
-+# CONFIG_CRYPTO_TGR192 is not set
-+# CONFIG_CRYPTO_GF128MUL is not set
-+CONFIG_CRYPTO_ECB=m
-+CONFIG_CRYPTO_CBC=y
-+CONFIG_CRYPTO_PCBC=m
-+# CONFIG_CRYPTO_LRW is not set
-+# CONFIG_CRYPTO_XTS is not set
-+# CONFIG_CRYPTO_CRYPTD is not set
-+# CONFIG_CRYPTO_DES is not set
-+# CONFIG_CRYPTO_FCRYPT is not set
-+# CONFIG_CRYPTO_BLOWFISH is not set
-+# CONFIG_CRYPTO_TWOFISH is not set
-+# CONFIG_CRYPTO_SERPENT is not set
-+CONFIG_CRYPTO_AES=m
-+# CONFIG_CRYPTO_CAST5 is not set
-+# CONFIG_CRYPTO_CAST6 is not set
-+# CONFIG_CRYPTO_TEA is not set
-+CONFIG_CRYPTO_ARC4=m
-+# CONFIG_CRYPTO_KHAZAD is not set
-+# CONFIG_CRYPTO_ANUBIS is not set
-+# CONFIG_CRYPTO_SEED is not set
-+# CONFIG_CRYPTO_DEFLATE is not set
-+CONFIG_CRYPTO_MICHAEL_MIC=m
-+# CONFIG_CRYPTO_CRC32C is not set
-+# CONFIG_CRYPTO_CAMELLIA is not set
-+# CONFIG_CRYPTO_TEST is not set
-+# CONFIG_CRYPTO_AUTHENC is not set
-+CONFIG_CRYPTO_HW=y
-+
-+#
-+# Library routines
-+#
-+CONFIG_BITREVERSE=y
-+CONFIG_CRC_CCITT=y
-+# CONFIG_CRC16 is not set
-+# CONFIG_CRC_ITU_T is not set
-+CONFIG_CRC32=y
-+# CONFIG_CRC7 is not set
-+# CONFIG_LIBCRC32C is not set
-+CONFIG_PLIST=y
-+CONFIG_HAS_IOMEM=y
-+CONFIG_HAS_IOPORT=y
-+CONFIG_HAS_DMA=y
-diff -Nurd linux-2.6.24/arch/arm/kernel/armksyms.c linux-2.6.24-oxe810/arch/arm/kernel/armksyms.c
---- linux-2.6.24/arch/arm/kernel/armksyms.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/kernel/armksyms.c 2008-06-11 17:47:43.000000000 +0200
-@@ -114,9 +114,15 @@
- EXPORT_SYMBOL(__strncpy_from_user);
-
- #ifdef CONFIG_MMU
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+EXPORT_SYMBOL(__copy_from_user_alt);
-+EXPORT_SYMBOL(__copy_to_user_alt);
-+EXPORT_SYMBOL(__clear_user_alt);
-+#else // CONFIG_OXNAS_INSTRUMENT_COPIES
- EXPORT_SYMBOL(__copy_from_user);
- EXPORT_SYMBOL(__copy_to_user);
- EXPORT_SYMBOL(__clear_user);
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
-
- EXPORT_SYMBOL(__get_user_1);
- EXPORT_SYMBOL(__get_user_2);
-diff -Nurd linux-2.6.24/arch/arm/kernel/bios32.c linux-2.6.24-oxe810/arch/arm/kernel/bios32.c
---- linux-2.6.24/arch/arm/kernel/bios32.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/kernel/bios32.c 2008-06-11 17:47:43.000000000 +0200
-@@ -616,7 +616,7 @@
- }
- }
-
--char * __init pcibios_setup(char *str)
-+char * __devinit pcibios_setup(char *str)
- {
- if (!strcmp(str, "debug")) {
- debug_pci = 1;
-diff -Nurd linux-2.6.24/arch/arm/kernel/calls.S linux-2.6.24-oxe810/arch/arm/kernel/calls.S
---- linux-2.6.24/arch/arm/kernel/calls.S 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/kernel/calls.S 2008-06-11 17:47:43.000000000 +0200
-@@ -362,6 +362,7 @@
- /* 350 */ CALL(sys_timerfd)
- CALL(sys_eventfd)
- CALL(sys_fallocate)
-+ CALL(sys_samba_reserve)
- #ifndef syscalls_counted
- .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
- #define syscalls_counted
-diff -Nurd linux-2.6.24/arch/arm/kernel/head.S linux-2.6.24-oxe810/arch/arm/kernel/head.S
---- linux-2.6.24/arch/arm/kernel/head.S 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/kernel/head.S 2008-06-11 17:47:43.000000000 +0200
-@@ -59,6 +59,34 @@
- #define KERNEL_END _end
- #endif
-
-+#ifdef CONFIG_OXNAS_MAP_SRAM
-+ .macro course_pgtbl, rd
-+ ldr \rd, =(__virt_to_phys(KERNEL_RAM_ADDR - 0x4400))
-+ .endm
-+
-+ .globl SMALL_AP
-+ .equ SMALL_AP, 0xAA
-+
-+ .globl COURSE_DOMAIN
-+ .equ COURSE_DOMAIN, 0x04
-+
-+ .globl SRAM_CODE_START
-+ .globl CODE_COPY_LEN
-+
-+#ifdef CONFIG_SUPPORT_LEON
-+ /*
-+ * Allow 2 pages after GMAC/DMA descriptors for ARM/Leon TSO workspace
-+ * May have to change if Leon code is built to use more Tx descriptors, but
-+ * current 2 pages is easily enough for 54 descriptors
-+ */
-+ .equ SRAM_CODE_START, SRAM_PA+((CONFIG_DESCRIPTORS_PAGES+2)*4096)
-+ .equ CODE_COPY_LEN, ((CONFIG_SRAM_NUM_PAGES-CONFIG_LEON_PAGES-(CONFIG_DESCRIPTORS_PAGES+2))*4096)
-+#else // CONFIG_SUPPORT_LEON
-+ .equ SRAM_CODE_START, SRAM_PA+(CONFIG_DESCRIPTORS_PAGES*4096)
-+ .equ CODE_COPY_LEN, ((CONFIG_SRAM_NUM_PAGES-CONFIG_DESCRIPTORS_PAGES)*4096)
-+#endif // CONFIG_SUPPORT_LEON
-+#endif // CONFIG_OXNAS_MAP_SRAM
-+
- /*
- * Kernel startup entry point.
- * ---------------------------
-@@ -82,6 +110,27 @@
- ENTRY(stext)
- msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
- @ and irqs disabled
-+
-+#ifdef CONFIG_OXNAS_CACHE_LOCKDOWN
-+ /*
-+ * Lock down ICache - do not care what ends up in locked down ways -
-+ * eventually context switch etc will flush out anything that gets loaded
-+ * next
-+ */
-+ mrc p15,0,r2,c9,c0,1
-+ orr r2,r2,#CONFIG_OXNAS_CACHE_I_MASK
-+ mcr p15,0,r2,c9,c0,1
-+
-+ /*
-+ * Lock down DCache - do not care what ends up in locked down ways -
-+ * eventually context switch etc will flush out anything that gets loaded
-+ * next
-+ */
-+ mrc p15,0,r2,c9,c0,0
-+ orr r2,r2,#CONFIG_OXNAS_CACHE_D_MASK
-+ mcr p15,0,r2,c9,c0,0
-+#endif // CONFIG_OXNAS_CACHE_LOCKDOWN
-+
- mrc p15, 0, r9, c0, c0 @ get processor id
- bl __lookup_processor_type @ r5=procinfo r9=cpuid
- movs r10, r5 @ invalid processor (r5=0)?
-@@ -231,7 +280,33 @@
- teq r0, r6
- bne 1b
-
-- ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags
-+ ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mmuflags
-+
-+#ifdef CONFIG_OXNAS_MAP_SRAM
-+ /*
-+ * Create the contents of the first descriptor in the course table which
-+ * is to describe the first MB of the kernel with 256 4K small descriptors.
-+ * The descriptors' are composed of the top 20 bits of the physical
-+ * address plus the appropriate AP, cacheable and bufferable flags
-+ */
-+ mov r3, #PHYS_OFFSET
-+ mov r3, r3, lsr #12
-+ mov r3, r3, lsl #12
-+ mov r6, #SMALL_AP @ TBC: AP values
-+ orr r3, r3, r6, lsl #4
-+ orr r3, r3, #0xe @ Cachable, bufferable and small desc
-+
-+ /*
-+ * Fill all 256 entries in the course page table with descriptors for
-+ * contiguous pages
-+ */
-+ course_pgtbl r0
-+ add r6, r0, #0x0400
-+1: str r3, [r0], #4
-+ add r3, r3, #1 << 12
-+ teq r0, r6
-+ bne 1b
-+#endif // CONFIG_OXNAS_MAP_SRAM
-
- /*
- * Create identity mapping for first MB of kernel to
-@@ -243,12 +318,26 @@
- orr r3, r7, r6, lsl #20 @ flags + kernel base
- str r3, [r4, r6, lsl #2] @ identity mapping
-
-+#ifdef CONFIG_OXNAS_MAP_SRAM
-+ /*
-+ * Write a course descriptor pointing to the small page mapping table
-+ * setup to map the first MB of kernel with 4K small pages
-+ */
-+ course_pgtbl r6
-+ mov r0, #COURSE_DOMAIN @ TBC SBZ, Domain etc
-+ orr r6, r6, r0, lsl #2
-+ orr r6, r6, #1 @ Course descriptor identifier
-+
-+ add r0, r4, #(KERNEL_START & 0xff000000) >> 18
-+ str r6, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
-+#else // CONFIG_OXNAS_MAP_SRAM
- /*
- * Now setup the pagetables for our kernel direct
- * mapped region.
- */
- add r0, r4, #(KERNEL_START & 0xff000000) >> 18
- str r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
-+#endif // CONFIG_OXNAS_MAP_SRAM
- ldr r6, =(KERNEL_END - 1)
- add r0, r0, #4
- add r6, r4, r6, lsr #18
-@@ -276,6 +365,64 @@
- bls 1b
- #endif
-
-+#ifdef CONFIG_OXNAS_COPY_CODE_TO_SRAM
-+ /*
-+ * Copy smallest/most-used kernel code into SRAM
-+ */
-+
-+ /* Get start of kernel code to copy */
-+ ldr r0, =(_text)
-+ mvn r3, #0xff000000
-+ and r0, r0, r3
-+ mov r6, #PHYS_OFFSET
-+ mov r3, #0xff000000
-+ and r6, r6, r3
-+ orr r0, r0, r6
-+
-+ /* Get start of SRAM region to copy into */
-+ ldr r3, =(SRAM_CODE_START)
-+
-+ /* Get amount of code to copy */
-+ ldr r6, =(CODE_COPY_LEN)
-+
-+ /* NB r7 is corrupted here, but opt. debug code below needs it */
-+ add r6, r0, r6
-+1: ldr r7, [r0], #4
-+ str r7, [r3], #4
-+ teq r0, r6
-+ bne 1b
-+
-+ /*
-+ * Map SRAM resident code into kernel virtual address space by altering
-+ * course page table entries covering the smallest/most-used code
-+ */
-+
-+ /* Get the address of the first page table entry to modify */
-+ course_pgtbl r3
-+ ldr r0, =(_text)
-+ sub r0, r0, #PAGE_OFFSET
-+ add r3, r3, r0, lsr #10
-+
-+ /* Get the address after the last entry in the page table to be altered */
-+ ldr r6, =(CODE_COPY_LEN)
-+ add r6, r3, r6, lsr #10
-+
-+ /* Form the first small descriptor contents */
-+ ldr r0, =(SRAM_CODE_START)
-+ mov r0, r0, lsr #12
-+ mov r0, r0, lsl #12
-+ mov r7, #SMALL_AP
-+ orr r0, r0, r7, lsl #4
-+ orr r0, r0, #0xe
-+
-+ /* Modify the page table entries for all SRAM pages filled with code */
-+1: str r0, [r3], #4
-+ add r0, r0, #1 << 12
-+ teq r3, r6
-+ bne 1b
-+
-+#else // CONFIG_OXNAS_COPY_CODE_TO_SRAM
-+#ifndef CONFIG_ARCH_OXNAS
- /*
- * Then map first 1MB of ram in case it contains our boot params.
- */
-@@ -285,6 +432,8 @@
- orr r6, r6, #(PHYS_OFFSET & 0x00f00000)
- .endif
- str r6, [r0]
-+#endif // !CONFIG_ARCH_OXNAS
-+#endif // CONFIG_OXNAS_COPY_CODE_TO_SRAM
-
- #ifdef CONFIG_DEBUG_LL
- ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
-diff -Nurd linux-2.6.24/arch/arm/kernel/process.c linux-2.6.24-oxe810/arch/arm/kernel/process.c
---- linux-2.6.24/arch/arm/kernel/process.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/kernel/process.c 2008-06-11 17:47:43.000000000 +0200
-@@ -117,7 +117,7 @@
- void (*pm_idle)(void);
- EXPORT_SYMBOL(pm_idle);
-
--void (*pm_power_off)(void);
-+void (*pm_power_off)(void) = arch_poweroff;
- EXPORT_SYMBOL(pm_power_off);
-
- void (*arm_pm_restart)(char str) = arm_machine_restart;
-diff -Nurd linux-2.6.24/arch/arm/kernel/vmlinux.lds.S linux-2.6.24-oxe810/arch/arm/kernel/vmlinux.lds.S
---- linux-2.6.24/arch/arm/kernel/vmlinux.lds.S 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/kernel/vmlinux.lds.S 2008-06-11 17:47:43.000000000 +0200
-@@ -86,8 +86,659 @@
- #endif
- }
-
-- .text : { /* Real text segment */
-- _text = .; /* Text and read-only data */
-+ .text : { /* Real text segment */
-+ _text = .; /* Text and read-only data */
-+ *(.text.arm926_dma_clean_range)
-+ *(.text.arm926_dma_inv_range)
-+ *(.text.arm926_dma_flush_range)
-+ *(.text.__irq_svc)
-+ *(.text.__arch_copy_to_user)
-+ *(.text.__arch_copy_from_user)
-+ *(.text.__kmalloc)
-+ *(.text.OXNAS_unmask_irq)
-+ *(.text.local_bh_enable)
-+ *(.text.do_level_IRQ)
-+ *(.text.__memzero)
-+ *(.text.irq_exit)
-+ *(.text.__do_irq)
-+ *(.text.pfifo_fast_dequeue)
-+ *(.text.preempt_return)
-+ *(.text.cpu_arm926_switch_mm)
-+ *(.text.check_irq_lock)
-+ *(.text.tcp_init_tso_segs)
-+ *(.text.kfree_skbmem)
-+ *(.text.consistent_sync)
-+ *(.text.__alloc_skb)
-+ *(.text.skb_release_data)
-+ *(.text.OXNAS_mask_irq)
-+ *(.text.Ldiv0)
-+ *(.text.__do_softirq)
-+ *(.text.kmem_cache_free)
-+ *(.text.__kfree_skb)
-+ *(.text.kmem_cache_alloc)
-+ *(.text.radix_tree_lookup)
-+ *(.text.kfree)
-+ *(.text.asm_do_IRQ)
-+ *(.text.skb_clone)
-+ *(.text.qdisc_restart)
-+ *(.text.sock_wfree)
-+ *(.text.unlock_page)
-+ *(.text.tcp_cwnd_validate)
-+ *(.text.free_hot_cold_page)
-+ *(.text.memcpy)
-+ *(.text.velocity_free_tx_buf)
-+ *(.text.wake_up_bit)
-+ *(.text.cond_resched)
-+ *(.text.pfifo_fast_enqueue)
-+ *(.text.raise_softirq_irqoff)
-+ *(.text.tcp_push_one)
-+ *(.text.__modsi3)
-+ *(.text.update_send_head)
-+ *(.text.tcp_set_skb_tso_segs)
-+ *(.text.tcp_snd_test)
-+ *(.text.svc_preempt)
-+ *(.text.__tcp_select_window)
-+ *(.text.dev_queue_xmit)
-+ *(.text.oxnas_gettimeoffset)
-+ *(.text.__wake_up_bit)
-+ *(.text.mod_timer)
-+ *(.text.do_simple_IRQ)
-+ *(.text.velocity_xmit)
-+ *(.text.ip_output)
-+ *(.text.net_tx_action)
-+ *(.text.ip_queue_xmit)
-+ *(.text.tcp_cong_avoid)
-+ *(.text.sk_reset_timer)
-+ *(.text.velocity_intr)
-+ *(.text.pci_dma_sync_single_for_device)
-+ *(.text.process_backlog)
-+ *(.text.tcp_v4_send_check)
-+ *(.text.tcp_transmit_skb)
-+ *(.text.file_send_actor)
-+ *(.text.tcp_current_mss)
-+ *(.text.__netif_rx_schedule)
-+ *(.text.__muldi3)
-+ *(.text.release_sock)
-+ *(.text.do_softirq)
-+ *(.text.pfifo_fast_reset)
-+ *(.text.netif_rx)
-+ *(.text.kernel_sendmsg)
-+ *(.text.rt_hash_code)
-+ *(.text.mod_page_state_offset)
-+ *(.text.preempt_schedule)
-+ *(.text.inet_sendmsg)
-+ *(.text.page_waitqueue)
-+ *(.text.bictcp_acked)
-+ *(.text.__sk_dst_check)
-+ *(.text.blk_rq_map_sg)
-+ *(.text.tcp_mtu_to_mss)
-+ *(.text.__delay)
-+ *(.text.sock_sendmsg)
-+ *(.text.sock_sendpage)
-+ *(.text.ip_local_deliver)
-+ *(.text.bio_add_page)
-+ *(.text.tcp_sendmsg)
-+ *(.text.sock_no_sendpage)
-+ *(.text.__remove_from_page_cache)
-+ *(.text.net_rx_action)
-+ *(.text.eth_type_trans)
-+ *(.text.find_get_page)
-+ *(.text.netif_receive_skb)
-+ *(.text.verify_chain)
-+ *(.text.radix_tree_delete)
-+ *(.text.mpage_readpages)
-+ *(.text.velocity_rx_refill)
-+ *(.text.mpage_end_io_read)
-+ *(.text.radix_tree_insert)
-+ *(.text.ip_rcv)
-+ *(.text.register_gifconf)
-+ *(.text.dma_mmap)
-+ *(.text.tcp_rtt_estimator)
-+ *(.text.ox800sata_get_bbp_base)
-+ *(.text.mark_page_accessed)
-+ *(.text.update_process_times)
-+ *(.text.__pagevec_free)
-+ *(.text.read_page_state_offset)
-+ *(.text.__bio_add_page)
-+ *(.text.__pagevec_lru_add)
-+ *(.text.ox800sata_scr_read)
-+ *(.text.bio_add_pc_page)
-+ *(.text.__rcu_pending)
-+ *(.text.free_sg_entry)
-+ *(.text.put_page)
-+ *(.text.lock_timer_base)
-+ *(.text.radix_tree_tagged)
-+ *(.text.__lshrdi3)
-+ *(.text.lock_sock)
-+ *(.text.__udivsi3)
-+ *(.text.zone_watermark_ok)
-+ *(.text.klist_children_put)
-+ *(.text.sock_aio_dtor)
-+ *(.text.ata_qc_prep)
-+ *(.text.oxnas_dma_free)
-+ *(.text.rcu_pending)
-+ *(.text.free_cold_page)
-+ *(.text.get_page_from_freelist)
-+ *(.text.alloc_sg_entry)
-+ *(.text.ret_fast_syscall)
-+ *(.text.add_to_page_cache)
-+ *(.text.__mod_timer)
-+ *(.text.velocity_free_td_ring)
-+ *(.text.__do_div64)
-+ *(.text.remove_mapping)
-+ *(.text.fast_work_pending)
-+ *(.text.cond_resched_softirq)
-+ *(.text.tcp_v4_rcv)
-+ *(.text.kernel_recvmsg)
-+ *(.text.isolate_lru_pages)
-+ *(.text.klist_children_get)
-+ *(.text.sys_getpid)
-+ *(.text.mempool_free_slab)
-+ *(.text.kobject_get)
-+ *(.text.__tcp_push_pending_frames)
-+ *(.text.sk_stop_timer)
-+ *(.text.bictcp_state)
-+ *(.text.tcp_check_space)
-+ *(.text.kmem_cache_zalloc)
-+ *(.text.get_device)
-+ *(.text.work_pending)
-+ *(.text.tcp_ack)
-+ *(.text.do_edge_IRQ)
-+ *(.text.page_referenced)
-+ *(.text.profile_tick)
-+ *(.text.ox800sata_get_link_base)
-+ *(.text.__pagevec_release_nonlru)
-+ *(.text.blk_recount_segments)
-+ *(.text.__mod_page_state_offset)
-+ *(.text.linear_mergeable_bvec)
-+ *(.text.recalc_task_prio)
-+ *(.text.mempool_kmalloc)
-+ *(.text.do_mpage_readpage)
-+ *(.text.ksoftirqd)
-+ *(.text.__generic_unplug_device)
-+ *(.text.rt_cpu_seq_start)
-+ *(.text.bio_alloc)
-+ *(.text.tasklet_action)
-+ *(.text.effective_prio)
-+ *(.text.OXNAS_timer_interrupt)
-+ *(.text.__wake_up_common)
-+ *(.text.free_poll_entry)
-+ *(.text.vector_swi)
-+ *(.text.do_sock_read)
-+ *(.text.alloc_sg_controller)
-+ *(.text.tcp_rcv_established)
-+ *(.text.oxnas_dma_set_callback)
-+ *(.text.run_local_timers)
-+ *(.text.sock_rmalloc)
-+ *(.text.__rmqueue)
-+ *(.text.ox800sata_bmdma_start)
-+ *(.text.fget_light)
-+ *(.text.queue_work)
-+ *(.text.mempool_alloc_slab)
-+ *(.text.__wake_up)
-+ *(.text.default_idle)
-+ *(.text.fput)
-+ *(.text.add_wait_queue)
-+ *(.text.memcpy_toiovec)
-+ *(.text.rw_verify_area)
-+ *(.text.internal_add_timer)
-+ *(.text.hrtimer_run_queues)
-+ *(.text.tcp_v4_do_rcv)
-+ *(.text.raise_softirq)
-+ *(.text.del_timer)
-+ *(.text.try_to_wake_up)
-+ *(.text.__do_page_cache_readahead)
-+ *(.text.__alloc_pages)
-+ *(.text.sock_aio_read)
-+ *(.text.timer_tick)
-+ *(.text.ox800sata_check_status)
-+ *(.text.do_generic_mapping_read)
-+ *(.text.__ox800sata_scr_read)
-+ *(.text.elv_queue_empty)
-+ *(.text.do_select)
-+ *(.text.free_pages_bulk)
-+ *(.text.remove_wait_queue)
-+ *(.text.dma_bh)
-+ *(.text.__irq_usr)
-+ *(.text.vfs_read)
-+ *(.text.run_timer_softirq)
-+ *(.text.radix_tree_preload)
-+ *(.text.ptrace_getrn)
-+ *(.text.tcp_dsack_set)
-+ *(.text.__switch_to)
-+ *(.text.bio_hw_segments)
-+ *(.text.__const_udelay)
-+ *(.text.nr_running)
-+ *(.text.oxnas_dma_device_set_prd)
-+ *(.text.kref_put)
-+ *(.text.enqueue_task)
-+ *(.text.dequeue_task)
-+ *(.text.elv_next_request)
-+ *(.text.profile_hit)
-+ *(.text.slab_destroy)
-+ *(.text.schedule)
-+ *(.text.end_that_request_first)
-+ *(.text.cfq_find_next_crq)
-+ *(.text.__freed_request)
-+ *(.text.adjtime_adjustment)
-+ *(.text.bictcp_cong_avoid)
-+ *(.text.kthread_should_stop)
-+ *(.text.__activate_task)
-+ *(.text.account_system_time)
-+ *(.text.bio_fs_destructor)
-+ *(.text.mempool_alloc)
-+ *(.text.elv_set_request)
-+ *(.text.schedule_work)
-+ *(.text.wake_up_state)
-+ *(.text.encode_control_status)
-+ *(.text.alloc_skb_from_cache)
-+ *(.text.qdisc_lock_tree)
-+ *(.text.kref_get)
-+ *(.text.init_timer)
-+ *(.text.oxnas_dma_is_active)
-+ *(.text.shrink_slab)
-+ *(.text.poll_freewait)
-+ *(.text.sys_fstat64)
-+ *(.text.__pollwait)
-+ *(.text.cfq_queue_empty)
-+ *(.text.linear_issue_flush)
-+ *(.text.__tasklet_schedule)
-+ *(.text.ox800sata_get_io_base)
-+ *(.text.deactivate_task)
-+ *(.text.cleanup_rbuf)
-+ *(.text.nr_free_zone_pages)
-+ *(.text.ip_route_input)
-+ *(.text.__lock_page)
-+ *(.text.sock_poll)
-+ *(.text.__pskb_trim_head)
-+ *(.text.sys_read)
-+ *(.text.__arch_copy_to_user)
-+ *(.text.generic_make_request)
-+ *(.text.scsi_end_request)
-+ *(.text.bio_init)
-+ *(.text.pipefs_delete_dentry)
-+ *(.text.ox800sata_post_set_mode)
-+ *(.text.sock_common_recvmsg)
-+ *(.text.put_device)
-+ *(.text.tcp_syn_build_options)
-+ *(.text.scheduler_tick)
-+ *(.text.__sys_trace)
-+ *(.text.ox800sata_qc_new)
-+ *(.text.elv_latter_request)
-+ *(.text.do_sync_read)
-+ *(.text.ox800sata_spot_the_end)
-+ *(.text.get_dirty_limits)
-+ *(.text.bio_phys_segments)
-+ *(.text.vfs_fstat)
-+ *(.text.scsi_finish_command)
-+ *(.text.wake_up_process)
-+ *(.text.wdc_ledtrig_sata_activity)
-+ *(.text.__elv_add_request)
-+ *(.text.sock_common_setsockopt)
-+ *(.text.elv_may_queue)
-+ *(.text.rb_first)
-+ *(.text.dnotify_parent)
-+ *(.text.get_writeback_state)
-+ *(.text.__blk_put_request)
-+ *(.text.sock_mmap)
-+ *(.text.throttle_vm_writeout)
-+ *(.text.drive_stat_acct)
-+ *(.text.dlci_ioctl_set)
-+ *(.text.sys_send)
-+ *(.text.default_wake_function)
-+ *(.text.cfq_resort_rr_list)
-+ *(.text.bio_put)
-+ *(.text.scsi_done)
-+ *(.text.kobject_put)
-+ *(.text.release_pages)
-+ *(.text.ata_qc_issue)
-+ *(.text.cfq_dispatch_insert)
-+ *(.text.run_workqueue)
-+ *(.text.delayed_work_timer_fn)
-+ *(.text.scsi_init_cmd_errh)
-+ *(.text.alloc_sock_iocb)
-+ *(.text.blk_done_softirq)
-+ *(.text.do_timer)
-+ *(.text.scsi_10_lba_len)
-+ *(.text.scsi_device_unbusy)
-+ *(.text.bio_get_nr_vecs)
-+ *(.text.cfq_find_cfq_hash)
-+ *(.text.ata_dev_select)
-+ *(.text.blk_remove_plug)
-+ *(.text.end_that_request_last)
-+ *(.text.shrink_dcache_memory)
-+ *(.text.elv_put_request)
-+ *(.text.sys_sendto)
-+ *(.text.scsi_put_command)
-+ *(.text._clear_bit_le)
-+ *(.text.ata_rwcmd_protocol)
-+ *(.text.kobject_cleanup)
-+ *(.text.do_sendfile)
-+ *(.text.worker_thread)
-+ *(.text.elv_dispatch_sort)
-+ *(.text.tcp_fast_parse_options)
-+ *(.text.ox800sata_irq_on)
-+ *(.text.scsi_request_fn)
-+ *(.text.ox800sata_irq_handler)
-+ *(.text.nr_context_switches)
-+ *(.text.oxnas_dma_request)
-+ *(.text.sys_sendfile64)
-+ *(.text.cfq_add_crq_rb)
-+ *(.text.ata_scsi_queuecmd)
-+ *(.text.sock_def_readable)
-+ *(.text.inet_sendpage)
-+ *(.text.cfq_set_request)
-+ *(.text.init_request_from_bio)
-+ *(.text.tcp_v4_conn_request)
-+ *(.text.requeue_task)
-+ *(.text.cache_alloc_refill)
-+ *(.text.scsi_get_command)
-+ *(.text.blk_complete_request)
-+ *(.text.scsi_add_timer)
-+ *(.text.sk_stream_rfree)
-+ *(.text.__umodsi3)
-+ *(.text.ox800sata_tf_load)
-+ *(.text.tcp_recvmsg)
-+ *(.text.cfq_insert_request)
-+ *(.text.tcp_sendpage)
-+ *(.text.bio_alloc_bioset)
-+ *(.text.__tcp_ack_snd_check)
-+ *(.text.kthread_bind)
-+ *(.text.scsi_delete_timer)
-+ *(.text.ox800sata_dev_config)
-+ *(.text.add_wait_queue_exclusive)
-+ *(.text.ox800sata_bmdma_setup)
-+ *(.text.ox800sata_exec_command)
-+ *(.text.clear_queue_congested)
-+ *(.text.generic_file_sendfile)
-+ *(.text.get_io_context)
-+ *(.text.swap_buf_le16)
-+ *(.text._set_bit_be)
-+ *(.text.led_trigger_event)
-+ *(.text.current_io_context)
-+ *(.text.bio_free)
-+ *(.text.pipe_poll)
-+ *(.text.freed_request)
-+ *(.text.cfq_choose_req)
-+ *(.text.ox800sata_RAID_faults)
-+ *(.text.rb_prev)
-+ *(.text.blk_run_queue)
-+ *(.text.mpage_alloc)
-+ *(.text.__get_zone_counts)
-+ *(.text.mpage_bio_submit)
-+ *(.text.generic_fillattr)
-+ *(.text.kswapd)
-+ *(.text.preempt_schedule_irq)
-+ *(.text.mempool_free)
-+ *(.text.elv_dequeue_request)
-+ *(.text.add_interrupt_randomness)
-+ *(.text.poll_initwait)
-+ *(.text.__put_user_bad)
-+ *(.text.vfs_getattr)
-+ *(.text.scsi_free_sgtable)
-+ *(.text.laptop_sync_completion)
-+ *(.text.submit_bio)
-+ *(.text.sock_from_file)
-+ *(.text.add_disk_randomness)
-+ *(.text.scsi_kill_request)
-+ *(.text.free_hot_page)
-+ *(.text.bio_endio)
-+ *(.text.scsi_dispatch_cmd)
-+ *(.text.oxnas_dma_start)
-+ *(.text.cfq_remove_request)
-+ *(.text.do_gettimeofday)
-+ *(.text.skb_copy_datagram_iovec)
-+ *(.text.ext3_get_blocks_handle)
-+ *(.text.__down_read_trylock)
-+ *(.text.cfq_activate_request)
-+ *(.text.recalc_sigpending)
-+ *(.text.ext3_readpage)
-+ *(.text.ox800sata_dev_select)
-+ *(.text.ret_to_user)
-+ *(.text.elv_completed_request)
-+ *(.text.read_cache_page)
-+ *(.text.touch_atime)
-+ *(.text.cfq_update_next_crq)
-+ *(.text.no_work_pending)
-+ *(.text.recalc_sigpending_tsk)
-+ *(.text.end_that_request_chunk)
-+ *(.text.cp_new_stat64)
-+ *(.text.rb_next)
-+ *(.text.__wake_up_sync)
-+ *(.text.subsys_create_file)
-+ *(.text.rcu_needs_cpu)
-+ *(.text.sys_select)
-+ *(.text.oxnas_dma_device_set)
-+ *(.text.ata_sg_init)
-+ *(.text.__put_user_8)
-+ *(.text.ox800sata_port_disable)
-+ *(.text.scsi_next_command)
-+ *(.text.__scsi_done)
-+ *(.text.ata_scsi_qc_complete)
-+ *(.text.__wake_up_locked)
-+ *(.text.lru_add_drain)
-+ *(.text.bio_check_pages_dirty)
-+ *(.text.cascade)
-+ *(.text.tcp_poll)
-+ *(.text.oxnas_dma_set_common)
-+ *(.text.__pagevec_release)
-+ *(.text.ata_scsi_translate)
-+ *(.text.oxnas_dma_interrupt)
-+ *(.text.sys_newfstat)
-+ *(.text.tcp_send_delayed_ack)
-+ *(.text.scsi_decide_disposition)
-+ *(.text.ox800sata_qc_free)
-+ *(.text.scsi_softirq_done)
-+ *(.text.netlink_group_mask)
-+ *(.text.__brelse)
-+ *(.text.do_sock_write)
-+ *(.text.mempool_create_node)
-+ *(.text.ox800sata_qc_issue)
-+ *(.text.__scsi_release_request)
-+ *(.text.blockable_page_cache_readahead)
-+ *(.text.get_index)
-+ *(.text.walk_page_buffers)
-+ *(.text.__queue_work)
-+ *(.text.ret_from_fork)
-+ *(.text.mb_cache_shrink_fn)
-+ *(.text.sys_socketcall)
-+ *(.text.blk_congestion_wait)
-+ *(.text.put_io_context)
-+ *(.text.elevator_find)
-+ *(.text._set_bit_le)
-+ *(.text.generic_write_checks)
-+ *(.text.datagram_poll)
-+ *(.text.ext3_block_to_path)
-+ *(.text.scsi_prep_fn)
-+ *(.text.fget)
-+ *(.text.blk_plug_device)
-+ *(.text.disk_round_stats)
-+ *(.text.get_request)
-+ *(.text.page_cache_readahead)
-+ *(.text.__bread)
-+ *(.text.tcp_rcv_space_adjust)
-+ *(.text.ox800sata_tf_read)
-+ *(.text.add_timer_randomness)
-+ *(.text.sockfd_lookup_light)
-+ *(.text.__find_get_block)
-+ *(.text.split_page)
-+ *(.text.cfq_dispatch_requests)
-+ *(.text.cfq_kick_queue)
-+ *(.text.cfq_may_queue)
-+ *(.text.cfq_put_request)
-+ *(.text.get_request_wait)
-+ *(.text.default_callback)
-+ *(.text.cpu_arm926_set_pte)
-+ *(.text.tcp_event_data_recv)
-+ *(.text.ata_scsi_qc_new)
-+ *(.text.SetRoundingMode)
-+ *(.text.make_ahead_window)
-+ *(.text.inotify_inode_queue_event)
-+ *(.text.__make_request)
-+ *(.text.finish_wait)
-+ *(.text.cfq_completed_request)
-+ *(.text.__cfq_slice_expired)
-+ *(.text.sd_init_command)
-+ *(.text.find_lock_page)
-+ *(.text.pipefs_get_sb)
-+ *(.text.ata_qc_new_init)
-+ *(.text.task_timeslice)
-+ *(.text.sk_dst_check)
-+ *(.text.set_queue_congested)
-+ *(.text.prepare_to_wait)
-+ *(.text.sys_write)
-+ *(.text.swap_io_context)
-+ *(.text.sys_alarm)
-+ *(.text.mempool_resize)
-+ *(.text.__cond_resched)
-+ *(.text.scsi_16_lba_len)
-+ *(.text.autoremove_wake_function)
-+ *(.text.inotify_dentry_parent_queue_event)
-+ *(.text.cfq_init_prio_data)
-+ *(.text.group_send_sig_info)
-+ *(.text.ata_qc_issue_prot)
-+ *(.text.cfq_put_queue)
-+ *(.text.__set_irq_handler)
-+ *(.text.__generic_file_aio_read)
-+ *(.text.ox800sata_eng_timeout)
-+ *(.text.rb_erase)
-+ *(.text.generic_file_aio_read)
-+ *(.text.default_llseek)
-+ *(.text.blk_unplug_work)
-+ *(.text.linear_make_request)
-+ *(.text.elv_insert)
-+ *(.text.velocity_init_registers)
-+ *(.text.vfs_permission)
-+ *(.text.alloc_inode)
-+ *(.text.mii_ethtool_sset)
-+ *(.text.blk_rq_map_kern)
-+ *(.text.tcp_urg)
-+ *(.text.__ata_qc_complete)
-+ *(.text.io_schedule_timeout)
-+ *(.text.run_posix_cpu_timers)
-+ *(.text.ox800sata_irq_clear)
-+ *(.text.put_tty_driver)
-+ *(.text.free_sg_controller)
-+ *(.text.__sk_stream_mem_reclaim)
-+ *(.text.elv_merge)
-+ *(.text.scsi_run_queue)
-+ *(.text.elv_former_request)
-+ *(.text.blk_requeue_request)
-+ *(.text.__end_that_request_first)
-+ *(.text.ext3_get_block)
-+ *(.text.ox800sata_phy_reset)
-+ *(.text.schedule_timeout)
-+ *(.text.grab_cache_page_nowait)
-+ *(.text.bio_map_kern_endio)
-+ *(.text.__up_read)
-+ *(.text.tcp_data_queue)
-+ *(.text.set_bdev_super)
-+ *(.text.ext3_readpages)
-+ *(.text.scsi_exit_queue)
-+ *(.text.ext3_get_branch)
-+ *(.text.cfq_forced_dispatch_cfqqs)
-+ *(.text.bioset_free)
-+ *(.text.blk_execute_rq_nowait)
-+ *(.text.scsi_eh_wakeup)
-+ *(.text.tcp_delack_timer)
-+ *(.text.shrink_icache_memory)
-+ *(.text.mpage_end_io_write)
-+ *(.text.scsi_io_completion)
-+ *(.text.verify_iovec)
-+ *(.text.credit_entropy_store)
-+ *(.text.blk_unplug_timeout)
-+ *(.text.work_resched)
-+ *(.text.sys_sendfile)
-+ *(.text.do_bad_IRQ)
-+ *(.text.sd_rw_intr)
-+ *(.text.set_task_comm)
-+ *(.text.blk_do_ordered)
-+ *(.text.rb_last)
-+ *(.text.drop_buffers)
-+ *(.text.ata_scsi_rw_xlat)
-+ *(.text.oxnas_dma_shutdown)
-+ *(.text.__group_send_sig_info)
-+ *(.text.led_trigger_set_default)
-+ *(.text.blk_queue_bounce)
-+ *(.text.cfq_var_store)
-+ *(.text.rb_insert_color)
-+ *(.text.__remove_hrtimer)
-+ *(.text.sys_sysinfo)
-+ *(.text.tcp_simple_retransmit)
-+ *(.text.it_real_fn)
-+ *(.text.sk_send_sigurg)
-+ *(.text.sys_statfs64_wrapper)
-+ *(.text.alloc_page_buffers)
-+ *(.text.bio_pair_release)
-+ *(.text.__dequeue_signal)
-+ *(.text.kblockd_schedule_work)
-+ *(.text.wakeup_kswapd)
-+ *(.text.process_timeout)
-+ *(.text.__getblk)
-+ *(.text.blk_get_request)
-+ *(.text.sync_buffer)
-+ *(.text.sk_stream_mem_schedule)
-+ *(.text.vfs_stat)
-+ *(.text.rb_replace_node)
-+ *(.text.signal_wake_up)
-+ *(.text.ata_std_ports)
-+ *(.text.tcp_send_ack)
-+ *(.text.send_signal)
-+ *(.text._atomic_dec_and_lock)
-+ *(.text.set_bh_page)
-+ *(.text.mutex_trylock)
-+ *(.text.sys_sigaltstack_wrapper)
-+ *(.text.sig_ignored)
-+ *(.text.net_family_write_lock)
-+ *(.text.radix_tree_node_alloc)
-+ *(.text.may_open)
-+ *(.text.account_user_time)
-+ *(.text.udp_seq_start)
-+ *(.text.ll_front_merge_fn)
-+ *(.text.laptop_flush)
-+ *(.text.__tasklet_hi_schedule)
-+ *(.text.__und_usr)
-+ *(.text.do_signal)
-+ *(.text.wake_bit_function)
-+ *(.text.mutex_lock_interruptible)
-+ *(.text.cfq_merged_request)
-+ *(.text.scsi_init_cmd_from_req)
-+ *(.text.elv_requeue_request)
-+ *(.text.force_sigsegv)
-+ *(.text.elv_merge_requests)
-+ *(.text.cp_new_stat)
-+ *(.text.prepare_to_wait_exclusive)
-+ *(.text.ioc_set_batching)
-+ *(.text.check_kill_permission)
-+ *(.text.scsi_queue_insert)
-+ *(.text.__csum_ipv6_magic)
-+ *(.text.wb_kupdate)
-+ *(.text.__down_write_trylock)
-+ *(.text.elv_register_queue)
-+ *(.text.sys_getitimer)
-+ *(.text.ox800sata_pio_task)
-+ *(.text.hrtimer_try_to_cancel)
-+ *(.text.find_pid)
-+ *(.text.oxnas_dma_raw_isactive)
-+ *(.text.cmp_ex)
-+ *(.text.__mpage_writepage)
-+ *(.text.sk_stream_wait_memory)
-+ *(.text.sys_sched_yield)
-+ *(.text.background_writeout)
-+ *(.text.rotate_reclaimable_page)
-+ *(.text.do_sigaction)
-+ *(.text.sock_def_write_space)
-+ *(.text.sched_exit)
-+ *(.text.inode_change_ok)
-+ *(.text.wait_for_completion_interruptible)
-+ *(.text.device_initialize)
-+ *(.text.journal_set_revoke)
-+ *(.text.try_to_free_pages)
-+ *(.text.tcp_write_timer)
-+ *(.text.dev_ioctl)
-+ *(.text.skb_copy_expand)
-+ *(.text.invalidate_complete_page)
-+ *(.text.*)
- __exception_text_start = .;
- *(.exception.text)
- __exception_text_end = .;
-diff -Nurd linux-2.6.24/arch/arm/lib/Makefile linux-2.6.24-oxe810/arch/arm/lib/Makefile
---- linux-2.6.24/arch/arm/lib/Makefile 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/lib/Makefile 2008-06-11 17:47:47.000000000 +0200
-@@ -29,6 +29,10 @@
- endif
- endif
-
-+ifeq ($(CONFIG_OXNAS_DMA_COPIES),y)
-+ lib-y += oxnas_copies.o
-+endif
-+
- lib-$(CONFIG_MMU) += $(mmu-y)
-
- ifeq ($(CONFIG_CPU_32v3),y)
-diff -Nurd linux-2.6.24/arch/arm/lib/clear_user.S linux-2.6.24-oxe810/arch/arm/lib/clear_user.S
---- linux-2.6.24/arch/arm/lib/clear_user.S 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/lib/clear_user.S 2008-06-11 17:47:47.000000000 +0200
-@@ -18,7 +18,11 @@
- * : sz - number of bytes to clear
- * Returns : number of bytes NOT cleared
- */
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+ENTRY(__clear_user_alt)
-+#else // CONFIG_OXNAS_INSTRUMENT_COPIES
- ENTRY(__clear_user)
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
- stmfd sp!, {r1, lr}
- mov r2, #0
- cmp r1, #4
-diff -Nurd linux-2.6.24/arch/arm/lib/copy_from_user.S linux-2.6.24-oxe810/arch/arm/lib/copy_from_user.S
---- linux-2.6.24/arch/arm/lib/copy_from_user.S 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/lib/copy_from_user.S 2008-06-11 17:47:47.000000000 +0200
-@@ -83,7 +83,12 @@
-
- .text
-
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+ENTRY(__copy_from_user_alt)
-+#else // CONFIG_OXNAS_INSTRUMENT_COPIES
-+.section ".text.__copy_from_user"
- ENTRY(__copy_from_user)
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
-
- #include "copy_template.S"
-
-diff -Nurd linux-2.6.24/arch/arm/lib/copy_to_user.S linux-2.6.24-oxe810/arch/arm/lib/copy_to_user.S
---- linux-2.6.24/arch/arm/lib/copy_to_user.S 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/lib/copy_to_user.S 2008-06-11 17:47:47.000000000 +0200
-@@ -86,7 +86,12 @@
-
- .text
-
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+ENTRY(__copy_to_user_alt)
-+#else // CONFIG_OXNAS_INSTRUMENT_COPIES
-+.section ".text.__copy_to_user"
- ENTRY(__copy_to_user)
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
-
- #include "copy_template.S"
-
-diff -Nurd linux-2.6.24/arch/arm/lib/memcpy.S linux-2.6.24-oxe810/arch/arm/lib/memcpy.S
---- linux-2.6.24/arch/arm/lib/memcpy.S 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/lib/memcpy.S 2008-06-11 17:47:47.000000000 +0200
-@@ -53,6 +53,7 @@
-
- /* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
-
-+.section ".text.memcpy"
- ENTRY(memcpy)
-
- #include "copy_template.S"
-diff -Nurd linux-2.6.24/arch/arm/lib/memzero.S linux-2.6.24-oxe810/arch/arm/lib/memzero.S
---- linux-2.6.24/arch/arm/lib/memzero.S 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/lib/memzero.S 2008-06-11 17:47:47.000000000 +0200
-@@ -30,6 +30,7 @@
- * memzero again.
- */
-
-+.section ".text.__memzero"
- ENTRY(__memzero)
- mov r2, #0 @ 1
- ands r3, r0, #3 @ 1 unaligned?
-diff -Nurd linux-2.6.24/arch/arm/lib/oxnas_copies.c linux-2.6.24-oxe810/arch/arm/lib/oxnas_copies.c
---- linux-2.6.24/arch/arm/lib/oxnas_copies.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/lib/oxnas_copies.c 2008-06-11 17:47:47.000000000 +0200
-@@ -0,0 +1,261 @@
-+/*
-+ * linux/arch/arm/lib/nas_copies.c
-+ *
-+ * Copyright (C) 2006 Oxford Semiconductor Ltd
-+ *
-+ * 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 <linux/compiler.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/mm.h>
-+#include <linux/pagemap.h>
-+#include <asm/scatterlist.h>
-+#include <asm/semaphore.h>
-+#include <asm/arch/dma.h>
-+
-+static DECLARE_MUTEX(copy_mutex);
-+static __DECLARE_SEMAPHORE_GENERIC(callback_semaphore, 0);
-+
-+static void dma_callback(
-+ oxnas_dma_channel_t *channel,
-+ oxnas_callback_arg_t arg,
-+ oxnas_dma_callback_status_t error_code,
-+ u16 checksum,
-+ int interrupt_count)
-+{
-+ up(&callback_semaphore);
-+}
-+
-+unsigned long oxnas_copy_from_user(void *to, const void __user *from, unsigned long count)
-+{
-+ int pages_mapped, i;
-+ unsigned long transfered = 0;
-+ struct page *pages[2];
-+ oxnas_dma_channel_t *channel;
-+ unsigned long uaddr = (unsigned long)from;
-+ unsigned long end_page = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
-+ unsigned long start_page = uaddr >> PAGE_SHIFT;
-+ int nr_pages = end_page - start_page;
-+//printk("F 0x%08lx 0x%08lx %lu -> %lu, %lu, %d\n", (unsigned long)to, (unsigned long)from, count, start_page, end_page, nr_pages);
-+
-+ might_sleep();
-+
-+ BUG_ON(nr_pages > 2);
-+
-+ // Only support a single concurrent copy operation, as only using a single
-+ // DMA channel for now
-+ while (down_interruptible(©_mutex));
-+
-+ // Get kernel mappings for the user pages
-+ down_read(¤t->mm->mmap_sem);
-+ pages_mapped = get_user_pages(current, current->mm, uaddr, nr_pages, 0, 0, pages, NULL);
-+ up_read(¤t->mm->mmap_sem);
-+
-+ if (pages_mapped != nr_pages) {
-+ // Didn't get mappings for all pages requested, so release any we did get
-+ for (i=0; i < pages_mapped; ++i) {
-+ page_cache_release(pages[i]);
-+ }
-+ pages_mapped = 0;
-+ }
-+
-+ if (pages_mapped) {
-+ int i;
-+ struct scatterlist sl;
-+ struct scatterlist gl[2];
-+
-+ // Fill gathering DMA descriptors
-+ gl[0].page = pages[0];
-+ gl[0].offset = uaddr & ~PAGE_MASK;
-+ if (pages_mapped > 1) {
-+ gl[0].length = PAGE_SIZE - gl[0].offset;
-+ gl[1].offset = 0;
-+ gl[1].page = pages[1];
-+ gl[1].length = count - gl[0].length;
-+ } else {
-+ gl[0].length = count;
-+ }
-+
-+ // Create DMA mappings for all the user pages
-+ for (i=0; i < pages_mapped; ++i) {
-+ gl[i].dma_address = dma_map_single(0, page_address(gl[i].page) + gl[i].offset, gl[i].length, DMA_TO_DEVICE);
-+ }
-+
-+ // Create a DMA mapping for the kernel memory range
-+ sl.dma_address = dma_map_single(0, to, count, DMA_FROM_DEVICE);
-+ sl.length = count;
-+
-+ // Allocate a DMA channel
-+ channel = oxnas_dma_request(1);
-+ BUG_ON(channel == OXNAS_DMA_CHANNEL_NUL);
-+
-+ // Do DMA from user to kernel memory
-+ oxnas_dma_set_sg(
-+ channel,
-+ gl,
-+ pages_mapped,
-+ &sl,
-+ 1,
-+ OXNAS_DMA_MODE_INC,
-+ OXNAS_DMA_MODE_INC,
-+ 0);
-+
-+ // Using notification callback
-+ oxnas_dma_set_callback(channel, dma_callback, OXNAS_DMA_CALLBACK_ARG_NUL);
-+ oxnas_dma_start(channel);
-+
-+ // Sleep until transfer complete
-+ while (down_interruptible(&callback_semaphore));
-+ oxnas_dma_set_callback(channel, OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
-+ transfered += count;
-+
-+ // Release the DMA channel
-+ oxnas_dma_free(channel);
-+
-+ // Release kernel DMA mapping
-+ dma_unmap_single(0, sl.length, count, DMA_FROM_DEVICE);
-+ // Release user DMA mappings
-+ for (i=0; i < pages_mapped; ++i) {
-+ dma_unmap_single(0, gl[i].dma_address, gl[i].length, DMA_TO_DEVICE);
-+ }
-+
-+ // Release user pages
-+ for (i=0; i < pages_mapped; ++i) {
-+ page_cache_release(pages[i]);
-+ }
-+ }
-+
-+ up(©_mutex);
-+
-+ return count - transfered;
-+}
-+
-+//unsigned long oxnas_copy_to_user(void __user *to, const void *from, unsigned long count)
-+//{
-+// int pages_mapped, i;
-+// unsigned long transfered = 0;
-+// struct page *pages[2];
-+// oxnas_dma_channel_t *channel;
-+// unsigned long uaddr = (unsigned long)to;
-+// unsigned long end_page = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
-+// unsigned long start_page = uaddr >> PAGE_SHIFT;
-+// int nr_pages = end_page - start_page;
-+////printk("T 0x%08lx 0x%08lx %lu -> %lu, %lu, %d\n", (unsigned long)to, (unsigned long)from, count, start_page, end_page, nr_pages);
-+//
-+// might_sleep();
-+//
-+// BUG_ON(nr_pages > 2);
-+//
-+// // Only support a single concurrent copy operation, as only using a single
-+// // DMA channel for now
-+// while (down_interruptible(©_mutex));
-+//
-+// // Get kernel mappings for the user pages
-+// down_read(¤t->mm->mmap_sem);
-+// pages_mapped = get_user_pages(current, current->mm, uaddr, nr_pages, 1, 0, pages, NULL);
-+// up_read(¤t->mm->mmap_sem);
-+//
-+// if (pages_mapped != nr_pages) {
-+// // Didn't get mapping for all the pages we requested, so release any
-+// // user page mappings we did get
-+// for (i=0; i < pages_mapped; ++i) {
-+// page_cache_release(pages[i]);
-+// }
-+// pages_mapped = 0;
-+// }
-+//
-+// if (pages_mapped) {
-+// int i;
-+// struct scatterlist gl;
-+// struct scatterlist sl[2];
-+//
-+// // Fill scattering DMA descriptors for writing to user space
-+// sl[0].page = pages[0];
-+// sl[0].offset = uaddr & ~PAGE_MASK;
-+// if (pages_mapped > 1) {
-+// sl[0].length = PAGE_SIZE - sl[0].offset;
-+// sl[1].offset = 0;
-+// sl[1].page = pages[1];
-+// sl[1].length = count - sl[0].length;
-+// } else {
-+// sl[0].length = count;
-+// }
-+//
-+// // Create DMA mappings for all the user pages
-+// for (i=0; i < pages_mapped; ++i) {
-+// sl[i].__address = page_address(sl[i].page) + sl[i].offset;
-+// sl[i].dma_address = dma_map_single(0, sl[i].__address, sl[i].length, DMA_FROM_DEVICE);
-+// }
-+//
-+// // Create a DMA mapping for the kernel memory range
-+// gl.dma_address = dma_map_single(0, (void*)from, count, DMA_TO_DEVICE);
-+// gl.length = count;
-+//
-+//// {
-+//////flush_cache_all();
-+//// // Do copy with CPU to test
-+//// const char* src = from;
-+//////printk("T Copying...\n");
-+//// for (i=0; i < pages_mapped; ++i) {
-+//// void* kadr = kmap(sl[i].page) + sl[i].offset;
-+//// memcpy(kadr, src, sl[i].length);
-+//// kunmap(sl[i].page);
-+//// src += sl[i].length;
-+//// transfered += sl[i].length;
-+//// }
-+//// }
-+//
-+//flush_cache_all();
-+// // Allocate a DMA channel
-+// channel = oxnas_dma_request(1);
-+// BUG_ON(channel == OXNAS_DMA_CHANNEL_NUL);
-+//
-+// // Do DMA from kernel to user memory
-+// oxnas_dma_set_sg(
-+// channel,
-+// &gl,
-+// 1,
-+// sl,
-+// pages_mapped,
-+// OXNAS_DMA_MODE_INC,
-+// OXNAS_DMA_MODE_INC,
-+// 0);
-+// oxnas_dma_start(channel);
-+// while (oxnas_dma_is_active(channel));
-+// transfered += count;
-+//
-+// // Release the DMA channel
-+// oxnas_dma_free(channel);
-+////flush_cache_all();
-+//
-+// // Release kernel DMA mapping
-+// dma_unmap_single(0, gl.dma_address, count, DMA_TO_DEVICE);
-+// // Release user DMA mappings
-+// for (i=0; i < pages_mapped; ++i) {
-+// dma_unmap_single(0, sl[i].dma_address, sl[i].length, DMA_FROM_DEVICE);
-+// }
-+//
-+// // Release user pages
-+// for (i=0; i < pages_mapped; ++i) {
-+// SetPageDirty(pages[i]);
-+// page_cache_release(pages[i]);
-+// }
-+// }
-+//
-+// up(©_mutex);
-+//
-+// return count - transfered;
-+//}
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/Kconfig linux-2.6.24-oxe810/arch/arm/mach-oxnas/Kconfig
---- linux-2.6.24/arch/arm/mach-oxnas/Kconfig 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/Kconfig 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,574 @@
-+if ARCH_OXNAS
-+
-+menu "Oxford Semiconductor NAS Options"
-+
-+config ARCH_OXNAS_FPGA
-+ bool "FPGA platform"
-+ default n
-+ help
-+ This enables support for Oxsemi NAS SoC FPGA development platform
-+
-+config OXNAS_CORE_CLK
-+ int "Integrator core module processor clock frequency in MHz"
-+ depends on ARCH_OXNAS_FPGA
-+ default 175
-+ help
-+ Maximum reliable frequency 175MHz
-+
-+config OXNAS_CORE_BUS_CLK_DIV
-+ int "Integrator core module bus clock divider"
-+ depends on ARCH_OXNAS_FPGA
-+ default 4
-+ help
-+ Must be greater than 0
-+
-+config NOMINAL_PLL400_FREQ
-+ int "The master clock frequency of the Soc"
-+ default 400000000
-+ help
-+ The PLL400 clock is divided by 2 to drive the ARM clock and by
-+ 4 to drive the AHB clock
-+
-+config NOMINAL_RPSCLK_FREQ
-+ int "The input clock frequency to the RPS"
-+ default 25000000
-+ help
-+ The RPS clock feeds into a prescaler and from there feeds the
-+ RPS timers
-+
-+choice
-+ prompt "OXNAS system type"
-+ default OXNAS_VERSION_0X800
-+
-+config OXNAS_VERSION_0X800
-+ bool "0X800"
-+ select ARM_AMBA
-+ help
-+ Support for the 0X800 SoC
-+
-+config OXNAS_VERSION_0X810
-+ bool "0X810"
-+ select ARM_AMBA
-+ help
-+ Support for the 0X810 SoC
-+
-+config OXNAS_VERSION_0X850
-+ bool "0X850"
-+ help
-+ Support for the 0X850 SoC
-+endchoice
-+
-+config ARCH_OXNAS_UART1
-+ bool "Support UART1"
-+ default n
-+ help
-+ This enables UART1 to be accessible to Linux.
-+ UARTs will be mapped to ttySn numbers from UART1 to UART4, only
-+ including those UARTs selected to be present
-+
-+config ARCH_OXNAS_UART1_MODEM
-+ bool "Support UART1 modem control lines"
-+ depends on ARCH_OXNAS_UART1
-+ default n
-+ help
-+ Multiplex the modem control lines from UART1 onto external pins
-+
-+config ARCH_OXNAS_UART2
-+ bool "Support UART2"
-+ default n
-+ help
-+ This enables UART2 to be accessible to Linux
-+ UARTs will be mapped to ttySn numbers from UART1 to UART4, only
-+ including those UARTs selected to be present
-+
-+config ARCH_OXNAS_UART2_MODEM
-+ bool "Support UART2 modem control lines"
-+ depends on ARCH_OXNAS_UART2
-+ default n
-+ help
-+ Multiplex the modem control lines from UART2 onto external pins
-+
-+config ARCH_OXNAS_UART3
-+ bool "Support UART3"
-+ default n
-+ help
-+ This enables UAR3 to be accessible to Linux
-+ UARTs will be mapped to ttySn numbers from UART1 to UART4, only
-+ including those UARTs selected to be present
-+
-+config ARCH_OXNAS_UART3_MODEM
-+ bool "Support UART3 modem control lines"
-+ depends on ARCH_OXNAS_UART3
-+ default n
-+ help
-+ Multiplex the modem control lines from UART3 onto external pins
-+
-+config ARCH_OXNAS_UART4
-+ bool "Support UART4"
-+ depends on !PCI
-+ default n
-+ help
-+ This enables UART4 to be accessible to Linux
-+ UARTs will be mapped to ttySn numbers from UART1 to UART4, only
-+ including those UARTs selected to be present
-+ UART4 always has its modem control lines available on external pins
-+ when selected (overlaying PCI functions)
-+
-+config ARCH_OXNAS_PCI_REQGNT_0
-+ bool "Enable req/gnt for PCI device 0"
-+ depends on PCI
-+ default n
-+ help
-+
-+config ARCH_OXNAS_PCI_REQGNT_1
-+ bool "Enable req/gnt for PCI device 1"
-+ depends on PCI
-+ default n
-+ help
-+
-+config ARCH_OXNAS_PCI_REQGNT_2
-+ bool "Enable req/gnt for PCI device 2"
-+ depends on PCI
-+ default n
-+ help
-+
-+config ARCH_OXNAS_PCI_REQGNT_3
-+ bool "Enable req/gnt for PCI device 3"
-+ depends on PCI
-+ default n
-+ help
-+
-+config ARCH_OXNAS_PCI_CLKOUT_0
-+ bool "Enable PCI clock output 0"
-+ depends on PCI
-+ default n
-+ help
-+
-+config ARCH_OXNAS_PCI_CLKOUT_1
-+ bool "Enable PCI clock output 1"
-+ depends on PCI
-+ default n
-+ help
-+
-+config ARCH_OXNAS_PCI_CLKOUT_2
-+ bool "Enable PCI clock output 2"
-+ depends on PCI
-+ default n
-+ help
-+
-+config ARCH_OXNAS_PCI_CLKOUT_3
-+ bool "Enable PCI clock output 3"
-+ depends on PCI
-+ default n
-+ help
-+
-+config OXNAS_PCI_RESET
-+ bool "Allow PCI reset to be toggled after power up"
-+ depends on PCI
-+ default n
-+ help
-+ The SoC requires that the PCI bus reset be toggled after the
-+ rest of the SoC has emerged from reset
-+
-+config OXNAS_PCI_RESET_GPIO
-+ int "GPIO line connected to PCI reset"
-+ depends on OXNAS_PCI_RESET
-+ default 12
-+ help
-+ The PCI bus requires a separate reset to be asserted after the
-+ reset of the SoC has emerged from reset. This defines the GPIO
-+ line which is connected to the PCI reset
-+
-+config OXNAS_SATA_POWER_1
-+ bool "Allow control of SATA 1 disk power via GPIO"
-+ default n
-+ help
-+ Allow SATA disk 1 power to be turned off via GPIO lines
-+
-+config OXNAS_SATA_POWER_GPIO_1
-+ int "GPIO line connected to SATA power control for disk 1"
-+ depends on OXNAS_SATA_POWER_1
-+ default 15
-+ help
-+ The GPIO line that controls SATA disk 1 power
-+
-+config OXNAS_SATA_POWER_2
-+ bool "Allow control of SATA disk 2 power via GPIO"
-+ default n
-+ help
-+ Allow SATA disk 2 power to be turned off via GPIO lines
-+
-+config OXNAS_SATA_POWER_GPIO_2
-+ int "GPIO line connected to SATA power control for disk 2"
-+ depends on OXNAS_SATA_POWER_2
-+ default 18
-+ help
-+ The GPIO line that controls SATA disk 2 power
-+
-+config FORCE_MAX_ZONEORDER
-+ int "Max order of zoned buddy allocator"
-+ default 11
-+ help
-+ The value to be assigned to MAX_ORDER
-+
-+config SRAM_NUM_PAGES
-+ int "The number of SRAM memory pages present in the system"
-+ default 8
-+ help
-+ Determines the number of pages of SRAM that are assumed to exist in the
-+ system memory map
-+
-+config SUPPORT_LEON
-+ bool "Include support for Leon"
-+ default n
-+
-+config LEON_PAGES
-+ int "The number of 4K pages of SRAM to reserve for the LEON program"
-+ depends on SUPPORT_LEON
-+ default 2
-+ help
-+ Determines the number of 4K pages of SRAM that are reserved for the
-+ LEON program
-+
-+config LEON_COPRO
-+ bool "Load LEON networking acceleration program"
-+ depends on SUPPORT_LEON && OXNAS_VERSION_0X810
-+ default n
-+
-+config LEON_OFFLOAD_TX
-+ bool "Whether network Tx operations should be offloaded to the LEON"
-+ depends on LEON_COPRO
-+ default n
-+
-+config LEON_RESERVE_DMA_CHANNEL
-+ bool "Whether to reserve the last DMA channel for the CoPro's use"
-+ depends on LEON_OFFLOAD_TX
-+ default n
-+
-+config LEON_OFFLOAD_TSO
-+ bool "Whether network TSO operations should be offloaded to the LEON"
-+ depends on LEON_OFFLOAD_TX
-+ default n
-+
-+config LEON_START_EARLY
-+ bool "Load LEON early startup program"
-+ depends on SUPPORT_LEON
-+ default n
-+ help
-+ For situations where the LEON is to run some code unrelated to
-+ its normal network acceleration functions, this options causes
-+ the LEON code to be loaded and the LEON started early in the
-+ boot process
-+
-+config LEON_POWER_BUTTON_MONITOR
-+ tristate "Load LEON power button monitoring program"
-+ depends on SUPPORT_LEON
-+ default n
-+ help
-+ Support powering down the system via a GPIO button and when the
-+ system is powered down load a LEON program that will monitor the
-+ button for attempts to power the system back on
-+
-+config OXNAS_POWER_BUTTON_GPIO
-+ int "GPIO line connected to power button"
-+ depends on LEON_POWER_BUTTON_MONITOR
-+ default 33
-+ help
-+ Specifies the GPIO line to which the power button is connected
-+
-+config USER_RECOVERY_BUTTON_MONITOR
-+ tristate "Load user recovery button monitoring program"
-+ default n
-+ help
-+ Support User recovery of the system via a GPIO button. When the
-+ system is power cycled after the use of this button, the admin
-+ password and network settings are set to factory values.
-+
-+config OXNAS_USER_RECOVERY_BUTTON_GPIO
-+ int "GPIO line connected to user recovery button"
-+ depends on USER_RECOVERY_BUTTON_MONITOR
-+ default 32
-+ help
-+ Specifies the GPIO line to which the user recovery button is
-+ connected.
-+
-+config OXNAS_DDR_MON
-+ bool "Poll the DDR core bus monitors from timer tick interrupt"
-+ default n
-+
-+config OXNAS_AHB_MON
-+ bool "Include support for AHB monitors"
-+ default n
-+
-+config OXNAS_MONITOR_SUBSAMPLE
-+ int "Jiffy subsample factor for AHB monitor sampling"
-+ depends on OXNAS_AHB_MON || OXNAS_DDR_MON
-+ default 10
-+ help
-+ The factor by which to subsample the jiffy count to produce AHB monitor
-+ sampling events
-+
-+config OXNAS_CACHE_LOCKDOWN
-+ bool "Allow locking down part of the caches"
-+ default n
-+
-+config OXNAS_CACHE_I_MASK
-+ int "Bit mask for I cache lockdown"
-+ depends on OXNAS_CACHE_LOCKDOWN
-+ default 0
-+ help
-+ Allowable values are:
-+ 0 - No ways locked down
-+ 1 - One way locked down
-+ 3 - Two ways locked down
-+ 7 - Three ways locked down
-+
-+config OXNAS_CACHE_D_MASK
-+ int "Bit mask for D cache lockdown"
-+ depends on OXNAS_CACHE_LOCKDOWN
-+ default 0
-+ help
-+ Allowable values are:
-+ 0 - No ways locked down
-+ 1 - One way locked down
-+ 3 - Two ways locked down
-+ 7 - Three ways locked down
-+
-+config DO_MEM_TEST
-+ bool "Perform memory copy throughput test during boot"
-+ default 0
-+
-+config CRYPTO_OXAESLRW
-+ tristate "LRW-AES hardware support"
-+ help
-+ Driver for controlling the Ox-Semi OX800 cipher core for LRW-AES
-+ encryption
-+
-+config DESCRIPTORS_PAGES
-+ int "The number of SRAM memory pages to reserve for DMA descriptors"
-+ default 1
-+ help
-+ Determines the number of pages of SRAM that are reserved for DMA
-+ descriptors
-+
-+config ARCH_OXNAS_NUM_GMAC_DESCRIPTORS
-+ int "The number of GMAC descriptors to allocate"
-+ default 112
-+
-+config ARCH_OXNAS_MAX_SATA_SG_ENTRIES
-+ int "The max. number of SG DMA descriptors to use in the single transfer"
-+ default 64
-+
-+config TACHO_THERM_AND_FAN
-+ tristate "Include support for the temperature sensing, and automatic fan control"
-+ default n
-+
-+config GPIO_TEST
-+ tristate "Device driver for exercising GPIO block."
-+ default n
-+ help
-+ Connect the I2C serial lines (SCLK, SCS, and SDT) together to run test
-+
-+config OXNAS_RTC
-+ tristate "Probe for m41t00 RTC"
-+ select I2C
-+ select I2C_ALGOBIT
-+ select I2C_OXNAS_BITBASH
-+ select RTC_CLASS
-+ select RTC_DRV_DS1307
-+ default n
-+ help
-+ The M41T00 RTC provides basic time save and restore.
-+ The device is probed for on the OXNAS bit-bash I2C bus.
-+
-+config I2S
-+ tristate "I2S test interface"
-+ default n
-+ help
-+ Say Y here to use i2s
-+ This support is also available as a module. If so, the module will be
-+ called i2s.
-+
-+config PCI_OXNAS_CARDBUS
-+ bool "Switches from a PCI/Mini-PCI bus to a Cardbus bus."
-+ depends on PCI && ARCH_OXNAS_FPGA
-+ ---help---
-+ This option limits scanning of the bus to omit the Via SATA interface.
-+ This makes the bus compatible with cardbus cards that expect to be the
-+ only PCI device on the bus.
-+
-+config DPE_TEST
-+ tristate "Test the DPE core"
-+ default n
-+
-+config OXNAS_EARLY_PRINTK
-+ bool "Whether to output to printascii from printk"
-+ depends on DEBUG_LL
-+ help
-+ If both CONFIG_DEBUG_LL and this option are selected, then each printk
-+ call will duplicate the message in a call to printascii to get very
-+ early console output
-+
-+config OXNAS_INSTRUMENT_COPIES
-+ bool "Instrument copy_to_user and copy_from_user"
-+ default n
-+
-+config OXNAS_INSTRUMENT_COPIES_THRESHOLD
-+ int "The threshold above which copies will be instrumented"
-+ depends on OXNAS_INSTRUMENT_COPIES
-+ default 0
-+
-+config OXNAS_INSTRUMENT_COPIES_TIME
-+ bool "Whether to print copy timing to console"
-+ depends on OXNAS_INSTRUMENT_COPIES
-+ default n
-+
-+config OXNAS_INSTRUMENT_COPIES_GPIO
-+ bool "Whether to toggle a GPIO around copies"
-+ depends on OXNAS_INSTRUMENT_COPIES
-+ default n
-+
-+config OXNAS_DMA_COPIES
-+ bool "Whether to use DMA for larger user-kernel copies"
-+ default n
-+
-+config OXNAS_DMA_COPY_THRESHOLD
-+ int "The threshold above which DMA will be used for copies"
-+ depends on OXNAS_DMA_COPIES
-+ default 1024
-+
-+config OXNAS_AHB_MONITOR_MODULE
-+ tristate "Creates a loadable module to control the AHB monitors"
-+ default n
-+ help
-+ This module publishes the current values of the AHB
-+ monitors in the /proc filing system.
-+ The monitors can be controlled by writing into this
-+ filing system
-+
-+config OXNAS_USB_TEST_MODES
-+ tristate "Create a loadable module to control the USB port test modes"
-+ default n
-+ help
-+ This module reports the port status and allows setting
-+ of the test mode in the port register via the /proc
-+ filing system.
-+
-+config OXNAS_FRONT_LAMP_CONTROL
-+ tristate "Front Panel LED control system"
-+ depends on LEDS_CLASS
-+ default n
-+ help
-+ This module reports drives a number of GPIOs as PWM signals to drive
-+ front panel LEDs. The pattern displayed is dependent on system state.
-+
-+config LEDS_TRIGGER_SATA_DISK
-+ tristate "Front Panel SATA disk activity lamp control system"
-+ default n
-+ help
-+ This module reports drives the SATA disk activity lamp.
-+
-+config OXNAS_LED_TEST
-+ bool "Exercise the WD LEDs"
-+ default n
-+
-+config OXNAS_I2C_SDA
-+ int "I2C bit-bash data line"
-+ default 2
-+
-+config OXNAS_I2C_SCL
-+ int "I2C bit-bash clock line"
-+ default 3
-+
-+config OXNAS_USB_PORTA_POWER_CONTROL
-+ bool "Support USB port A power control lines"
-+ default n
-+ help
-+ Whether to support power switch out and monitor in via GPIOs
-+ for USB port A
-+
-+config OXNAS_USB_PORTB_POWER_CONTROL
-+ bool "Support USB port B power control lines"
-+ default n
-+ help
-+ Whether to support power switch out and monitor in via GPIOs
-+ for USB port B
-+
-+config OXNAS_USB_PORTC_POWER_CONTROL
-+ bool "Support USB port C power control lines"
-+ default n
-+ help
-+ Whether to support power switch out and monitor in via GPIOs
-+ for USB port C
-+
-+config OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE
-+ bool "Set USB power monitor input polarity to negative"
-+ default n
-+ help
-+ n - Positive polarity
-+ y - Negative polarity
-+
-+config OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE
-+ bool "Set USB power switch output polarity to negative"
-+ default n
-+ help
-+ n - Positive polarity
-+ y - Negative polarity
-+
-+config WDC_FAN_OXNAS800
-+ tristate "WD NetCenter/2NC Fan control driver"
-+ default n
-+ help
-+ This driver allows user-mode applications to control the cooling
-+ fan on Western Digital's NetCenter/2NC platform.
-+
-+config OXNAS_MAP_SRAM
-+ bool "Allow part of kernel to be mapped into SRAM"
-+ default n
-+
-+config OXNAS_COPY_CODE_TO_SRAM
-+ bool "Copy part of kernel to SRAM"
-+ depends on OXNAS_MAP_SRAM
-+ default n
-+
-+config OXNAS_SUID_INHERIT
-+ bool "Make SUID be inherited by subdirectories"
-+ default n
-+
-+config OXNAS_USB_HUB_SUPPORT
-+ bool "Enable support for on-board USB hub"
-+ default n
-+
-+config OXNAS_USB_CKOUT
-+ bool "Enable output of 12MHz USB clock on GPIO 10"
-+ depends on OXNAS_USB_HUB_SUPPORT
-+ default n
-+
-+config OXNAS_USB_HUB_RESET_CONTROL
-+ bool "Control the USB hub reset line"
-+ depends on OXNAS_USB_HUB_SUPPORT
-+ default n
-+
-+config OXNAS_USB_HUB_RESET_GPIO
-+ int "The GPIO connected to the USB hub reset"
-+ depends on OXNAS_USB_HUB_RESET_CONTROL
-+ default 27
-+
-+config OXNAS_USB_HUB_RESET_ACTIVE_HIGH
-+ int "Set to 1 for active high, 0 for active low reset"
-+ depends on OXNAS_USB_HUB_RESET_CONTROL
-+ default 1
-+
-+config OXNAS_USB_HUB_RESET_TOGGLE
-+ bool "Select to toggle reset, do not select to just deassert reset"
-+ depends on OXNAS_USB_HUB_RESET_CONTROL
-+ default y
-+
-+config OXNAS_USB_HUB_RESET_PERIOD_MS
-+ int "The period for which the USB hub reset should be asserted in milliseconds"
-+ depends on OXNAS_USB_HUB_RESET_TOGGLE
-+ default 100
-+
-+endmenu
-+
-+endif
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/Makefile linux-2.6.24-oxe810/arch/arm/mach-oxnas/Makefile
---- linux-2.6.24/arch/arm/mach-oxnas/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/Makefile 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,43 @@
-+#
-+# Makefile for the linux kernel.
-+#
-+
-+# Object file lists.
-+
-+obj-y := oxnas.o irq.o time.o dma.o pci.o ahb_mon.o leon.o samba_reserve.o
-+
-+obj-$(CONFIG_SYNOPSYS_GMAC) += gmac.o
-+
-+gmac-objs := gmac-napi.o gmac_ethtool.o gmac_phy.o gmac_desc.o gmac_offload.o
-+
-+obj-$(CONFIG_OXNAS_IBW) += ibw.o
-+
-+obj-$(CONFIG_TACHO_THERM_AND_FAN) += thermAndFan.o
-+
-+obj-$(CONFIG_I2S) += i2s.o
-+
-+obj-$(CONFIG_CRYPTO_OXAESLRW) += cipher.o
-+
-+obj-$(CONFIG_GPIO_TEST) += gpioTest.o
-+
-+obj-$(CONFIG_I2S) += i2s.o
-+
-+obj-$(CONFIG_DPE_TEST) += dpe_test.o
-+
-+obj-$(CONFIG_OXNAS_AHB_MONITOR_MODULE) += oxnas-ahb-monitor.o
-+
-+obj-$(CONFIG_OXNAS_USB_TEST_MODES) += usb-test-mode.o
-+
-+obj-$(CONFIG_LEON_POWER_BUTTON_MONITOR) += power_button.o
-+
-+obj-$(CONFIG_USER_RECOVERY_BUTTON_MONITOR) += user_recovery_button.o
-+
-+obj-$(CONFIG_OXNAS_FRONT_LAMP_CONTROL) += leds.o
-+
-+obj-$(CONFIG_WDC_FAN_OXNAS800) += wdc-fan.o
-+
-+obj-$(CONFIG_WDC_LEDS_OXNAS800) += wdc-leds.o
-+
-+obj-$(CONFIG_OXNAS_WD810_LEDS) += oxnas-wd810-leds.o
-+
-+obj-$(CONFIG_WDC_LEDS_TRIGGER_SATA_DISK) += wdc-ledtrig-sata.o
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/Makefile.boot linux-2.6.24-oxe810/arch/arm/mach-oxnas/Makefile.boot
---- linux-2.6.24/arch/arm/mach-oxnas/Makefile.boot 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/Makefile.boot 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,3 @@
-+initrd_phys-$(CONFIG_ARCH_OXNAS) := 0x48200000
-+params_phys-$(CONFIG_ARCH_OXNAS) := 0x48000100
-+zreladdr-$(CONFIG_ARCH_OXNAS) := 0x48008000
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/README linux-2.6.24-oxe810/arch/arm/mach-oxnas/README
---- linux-2.6.24/arch/arm/mach-oxnas/README 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/README 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,85 @@
-+
-+usb-test-modes
-+
-+This is best built as a module which may be inserted into a running
-+Linux system only when needed.
-+The module can be built as part of the standard kernel module build
-+if the correct options are chosen in the config.
-+
-+
-+How to use:
-+
-+copy the usb-test-mode.ko file somewhere convenient on the NAS and
-+insert the module into the system using
-+'modprobe usb-test-mode.ko'
-+
-+It should report successfull loading or an error message. Assuming it is
-+successful /proc will have an 'usb_test_mode' entry (verify with ls).
-+
-+Actions:
-+read the current port status:
-+cat /proc/usb_test_mode/read
-+
-+set port 1 into test mode 4:
-+echo 4 > /proc/usb_test_mode/write1
-+
-+
-+When testing is completed the module can be removed from the linux
-+system using:
-+rmmod usb_test_mode
-+
-+ahb_mon
-+
-+This should be built as a module.
-+
-+How to use:
-+
-+insert the module into a working system by typing
-+'modprobe oxnas-ahb-monitor'
-+
-+When successfully installed a directory entry will appear in /proc for
-+oxnas-ahb-monitor. In the directory will be a writeable file for each
-+AHB monitor and a control file. There will also be a readable file for
-+obtaining the counts stored in all the ahb monitors.
-+
-+
-+Actions:
-+set a monitor to a limited range, burst mode etc using
-+low addres, high address, mode, burst mode, burst mask, hprot, hprot mask
-+
-+Use the echo command to set data into the /proc/oxnas-ahb-monitor an example is
-+the following script to observe the activities of the ARM processor on the GMAC
-+core when pinging a remote machine:
-+---------------------------
-+#!/bin/sh -x
-+#
-+
-+# start montoring of ARM data bus to MAC
-+# format is "low high mode burst mask hprot mask"
-+# mode - 1 write 2 read 3 read write.
-+
-+echo 2 > /proc/oxnas-test/control
-+
-+echo 0 > /proc/oxnas-test/control
-+
-+
-+echo "0x40400000,0x405fffff,3,0,0,0,0" > /proc/oxnas-test/ARM_Data
-+echo "0x40400000,0x405fffff,3,0,0,0,0" > /proc/oxnas-test/Arm_Inst
-+echo "0,4,3,0,0,0,0" > /proc/oxnas-test/CoPro
-+echo "0,4,3,0,0,0,0" > /proc/oxnas-test/DMA_A
-+echo "0,4,3,0,0,0,0" > /proc/oxnas-test/DMA_B
-+echo "0,4,3,0,0,0,0" > /proc/oxnas-test/GMAC
-+echo "0,4,3,0,0,0,0" > /proc/oxnas-test/PCI
-+echo "0,4,3,0,0,0,0" > /proc/oxnas-test/USBHS
-+
-+echo 1 > /proc/oxnas-test/control
-+
-+ping -c 1 172.31.0.102
-+
-+echo 0 > /proc/oxnas-test/control
-+--------------------------------------
-+
-+When testing is commplete the module can be removed using
-+rmmod oxnas-ahb-monitor
-+
-+
-Files linux-2.6.24/arch/arm/mach-oxnas/ThermCalc.xls and linux-2.6.24-oxe810/arch/arm/mach-oxnas/ThermCalc.xls differ
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/ahb_mon.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/ahb_mon.c
---- linux-2.6.24/arch/arm/mach-oxnas/ahb_mon.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/ahb_mon.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,177 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/ahb_mon.c
-+ *
-+ * 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 <linux/kernel.h>
-+#include <asm/io.h>
-+#include <asm/arch/hardware.h>
-+
-+#ifdef CONFIG_OXNAS_AHB_MON
-+static void start_ahb_monitors(void)
-+{
-+ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_D + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_I + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_A + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_B + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_LEON + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_USB + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_MAC + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_PCI + AHB_MON_MODE_REG_OFFSET);
-+}
-+
-+void init_ahb_monitors(
-+ AHB_MON_HWRITE_T ahb_mon_hwrite,
-+ unsigned hburst_mask,
-+ unsigned hburst_match,
-+ unsigned hprot_mask,
-+ unsigned hprot_match)
-+{
-+ u32 hburst_mask_value = (hburst_mask & ((1 << AHB_MON_HBURST_MASK_NUM_BITS) - 1));
-+ u32 hburst_match_value = (hburst_match & ((1 << AHB_MON_HBURST_MATCH_NUM_BITS) - 1));
-+ u32 hprot_mask_value = (hprot_mask & ((1 << AHB_MON_HPROT_MASK_NUM_BITS) - 1));
-+ u32 hprot_match_value = (hprot_match & ((1 << AHB_MON_HPROT_MATCH_NUM_BITS) - 1));
-+
-+ u32 hburst_reg_value = (hburst_mask_value << AHB_MON_HBURST_MASK_BIT) | (hburst_match_value << AHB_MON_HBURST_MATCH_BIT);
-+ u32 hprot_reg_value = (hprot_mask_value << AHB_MON_HPROT_MASK_BIT) | (hprot_match_value << AHB_MON_HPROT_MATCH_BIT);
-+
-+printk("$Ghburst reg value = 0x%08x\n", hburst_reg_value);
-+printk("$Ghprot reg value = 0x%08x\n", hprot_reg_value);
-+
-+ // Reset all the counters and set their operating mode
-+ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_D + AHB_MON_MODE_REG_OFFSET);
-+ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_ARM_D + AHB_MON_HWRITE_REG_OFFSET);
-+ writel(0UL, AHB_MON_ARM_D + AHB_MON_HADDR_LOW_REG_OFFSET);
-+ writel(~0UL, AHB_MON_ARM_D + AHB_MON_HADDR_HIGH_REG_OFFSET);
-+ writel(hburst_reg_value, AHB_MON_ARM_D + AHB_MON_HBURST_REG_OFFSET);
-+ writel(hprot_reg_value, AHB_MON_ARM_D + AHB_MON_HPROT_REG_OFFSET);
-+
-+ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_I + AHB_MON_MODE_REG_OFFSET);
-+ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_ARM_I + AHB_MON_HWRITE_REG_OFFSET);
-+ writel(0UL, AHB_MON_ARM_I + AHB_MON_HADDR_LOW_REG_OFFSET);
-+ writel(~0UL, AHB_MON_ARM_I + AHB_MON_HADDR_HIGH_REG_OFFSET);
-+ writel(hburst_reg_value, AHB_MON_ARM_I + AHB_MON_HBURST_REG_OFFSET);
-+ writel(hprot_reg_value, AHB_MON_ARM_I + AHB_MON_HPROT_REG_OFFSET);
-+
-+ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_A + AHB_MON_MODE_REG_OFFSET);
-+ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_DMA_A + AHB_MON_HWRITE_REG_OFFSET);
-+ writel(0UL, AHB_MON_DMA_A + AHB_MON_HADDR_LOW_REG_OFFSET);
-+ writel(~0UL, AHB_MON_DMA_A + AHB_MON_HADDR_HIGH_REG_OFFSET);
-+ writel(hburst_reg_value, AHB_MON_DMA_A + AHB_MON_HBURST_REG_OFFSET);
-+ writel(hprot_reg_value, AHB_MON_DMA_A + AHB_MON_HPROT_REG_OFFSET);
-+
-+ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_B + AHB_MON_MODE_REG_OFFSET);
-+ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_DMA_B + AHB_MON_HWRITE_REG_OFFSET);
-+ writel(0UL, AHB_MON_DMA_B + AHB_MON_HADDR_LOW_REG_OFFSET);
-+ writel(~0UL, AHB_MON_DMA_B + AHB_MON_HADDR_HIGH_REG_OFFSET);
-+ writel(hburst_reg_value, AHB_MON_DMA_B + AHB_MON_HBURST_REG_OFFSET);
-+ writel(hprot_reg_value, AHB_MON_DMA_B + AHB_MON_HPROT_REG_OFFSET);
-+
-+ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_LEON + AHB_MON_MODE_REG_OFFSET);
-+ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_LEON + AHB_MON_HWRITE_REG_OFFSET);
-+ writel(0UL, AHB_MON_LEON + AHB_MON_HADDR_LOW_REG_OFFSET);
-+ writel(~0UL, AHB_MON_LEON + AHB_MON_HADDR_HIGH_REG_OFFSET);
-+ writel(hburst_reg_value, AHB_MON_LEON + AHB_MON_HBURST_REG_OFFSET);
-+ writel(hprot_reg_value, AHB_MON_LEON + AHB_MON_HPROT_REG_OFFSET);
-+
-+ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_USB + AHB_MON_MODE_REG_OFFSET);
-+ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_USB + AHB_MON_HWRITE_REG_OFFSET);
-+ writel(0UL, AHB_MON_USB + AHB_MON_HADDR_LOW_REG_OFFSET);
-+ writel(~0UL, AHB_MON_USB + AHB_MON_HADDR_HIGH_REG_OFFSET);
-+ writel(hburst_reg_value, AHB_MON_USB + AHB_MON_HBURST_REG_OFFSET);
-+ writel(hprot_reg_value, AHB_MON_USB + AHB_MON_HPROT_REG_OFFSET);
-+
-+ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_MAC + AHB_MON_MODE_REG_OFFSET);
-+ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_MAC + AHB_MON_HWRITE_REG_OFFSET);
-+ writel(0UL, AHB_MON_MAC + AHB_MON_HADDR_LOW_REG_OFFSET);
-+ writel(~0UL, AHB_MON_MAC + AHB_MON_HADDR_HIGH_REG_OFFSET);
-+ writel(hburst_reg_value, AHB_MON_MAC + AHB_MON_HBURST_REG_OFFSET);
-+ writel(hprot_reg_value, AHB_MON_MAC + AHB_MON_HPROT_REG_OFFSET);
-+
-+ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_PCI + AHB_MON_MODE_REG_OFFSET);
-+ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_PCI + AHB_MON_HWRITE_REG_OFFSET);
-+ writel(0UL, AHB_MON_PCI + AHB_MON_HADDR_LOW_REG_OFFSET);
-+ writel(~0UL, AHB_MON_PCI + AHB_MON_HADDR_HIGH_REG_OFFSET);
-+ writel(hburst_reg_value, AHB_MON_PCI + AHB_MON_HBURST_REG_OFFSET);
-+ writel(hprot_reg_value, AHB_MON_PCI + AHB_MON_HPROT_REG_OFFSET);
-+
-+ // Start all the counters
-+ start_ahb_monitors();
-+}
-+
-+void restart_ahb_monitors(void)
-+{
-+ // Reset the counters
-+ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_D + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_I + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_A + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_B + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_LEON + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_USB + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_MAC + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_PCI + AHB_MON_MODE_REG_OFFSET);
-+
-+ // Start the counters
-+ start_ahb_monitors();
-+}
-+
-+void read_ahb_monitors(void)
-+{
-+ // Prepare the counters for reading
-+ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_D + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_I + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_A + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_B + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_LEON + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_USB + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_MAC + AHB_MON_MODE_REG_OFFSET);
-+ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_PCI + AHB_MON_MODE_REG_OFFSET);
-+
-+ // Read the counters
-+ printk("ARM-D: B=%u, T=%u, W=%u\n", readl(AHB_MON_ARM_D + AHB_MON_CYCLES_REG_OFFSET),
-+ readl(AHB_MON_ARM_D + AHB_MON_TRANSFERS_REG_OFFSET),
-+ readl(AHB_MON_ARM_D + AHB_MON_WAITS_REG_OFFSET));
-+
-+ printk("ARM-I: B=%u, T=%u, W=%u\n", readl(AHB_MON_ARM_I + AHB_MON_CYCLES_REG_OFFSET),
-+ readl(AHB_MON_ARM_I + AHB_MON_TRANSFERS_REG_OFFSET),
-+ readl(AHB_MON_ARM_I + AHB_MON_WAITS_REG_OFFSET));
-+
-+ printk("DMA-A: B=%u, T=%u, W=%u\n", readl(AHB_MON_DMA_A + AHB_MON_CYCLES_REG_OFFSET),
-+ readl(AHB_MON_DMA_A + AHB_MON_TRANSFERS_REG_OFFSET),
-+ readl(AHB_MON_DMA_A + AHB_MON_WAITS_REG_OFFSET));
-+
-+ printk("DMA-B: B=%u, T=%u, W=%u\n", readl(AHB_MON_DMA_B + AHB_MON_CYCLES_REG_OFFSET),
-+ readl(AHB_MON_DMA_B + AHB_MON_TRANSFERS_REG_OFFSET),
-+ readl(AHB_MON_DMA_B + AHB_MON_WAITS_REG_OFFSET));
-+
-+ printk("LEON: B=%u, T=%u, W=%u\n", readl(AHB_MON_LEON + AHB_MON_CYCLES_REG_OFFSET),
-+ readl(AHB_MON_LEON + AHB_MON_TRANSFERS_REG_OFFSET),
-+ readl(AHB_MON_LEON + AHB_MON_WAITS_REG_OFFSET));
-+
-+ printk("USB: B=%u, T=%u, W=%u\n", readl(AHB_MON_USB + AHB_MON_CYCLES_REG_OFFSET),
-+ readl(AHB_MON_USB + AHB_MON_TRANSFERS_REG_OFFSET),
-+ readl(AHB_MON_USB + AHB_MON_WAITS_REG_OFFSET));
-+
-+ printk("MAC: B=%u, T=%u, W=%u\n", readl(AHB_MON_MAC + AHB_MON_CYCLES_REG_OFFSET),
-+ readl(AHB_MON_MAC + AHB_MON_TRANSFERS_REG_OFFSET),
-+ readl(AHB_MON_MAC + AHB_MON_WAITS_REG_OFFSET));
-+
-+ printk("PCI: B=%u, T=%u, W=%u\n", readl(AHB_MON_PCI + AHB_MON_CYCLES_REG_OFFSET),
-+ readl(AHB_MON_PCI + AHB_MON_TRANSFERS_REG_OFFSET),
-+ readl(AHB_MON_PCI + AHB_MON_WAITS_REG_OFFSET));
-+}
-+#endif // CONFIG_OXNAS_AHB_MON
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/cipher.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/cipher.c
---- linux-2.6.24/arch/arm/mach-oxnas/cipher.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/cipher.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,362 @@
-+/* linux/arch/arm/mach-oxnas/cipher.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 <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/device.h>
-+#include <linux/string.h>
-+#include <linux/sysdev.h>
-+#include <linux/highmem.h>
-+#include <asm/semaphore.h>
-+#include <asm/arch/cipher.h>
-+#include <asm/io.h>
-+#include <asm/arch/hardware.h>
-+#include <linux/dma-mapping.h>
-+#include <asm/arch/dma.h>
-+#include <asm-arm/page.h>
-+
-+
-+#if 0
-+#define DPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
-+#define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
-+#else
-+#define DPRINTK(fmt, args...)
-+#define VPRINTK(fmt, args...)
-+#endif
-+
-+//#define CIPHER_USE_SG_DMA
-+
-+/*****************************************************************************/
-+
-+typedef struct ox800_aeslrw_driver ox800_aeslrw_driver_t;
-+
-+struct ox800_aeslrw_driver {
-+ struct device dev;
-+ struct semaphore core;
-+ int result;
-+ u8 cipher_key[OX800DPE_KEYSIZE];
-+ u8 tweak_key[OX800DPE_KEYSIZE];
-+};
-+
-+static ox800_aeslrw_driver_t ox800_aeslrw_driver;
-+
-+
-+/*****************************************************************************/
-+
-+/**
-+ * Sets the keys only if they have changed.
-+ * @param cipher_key 16 byte array that is the cipher key
-+ * @param tweak_key 16 byte array that is the I-Value tweak key
-+ */
-+static void ox800_aeslrw_setkeys(u8* cipher_key, u8* tweak_key)
-+{
-+ VPRINTK(KERN_INFO"\n");
-+
-+ /*
-+ * changing the keys can take a long time as the core will
-+ * compute internal values based on the keys
-+ */
-+ if (memcmp(&(ox800_aeslrw_driver.cipher_key[0]), cipher_key, OX800DPE_KEYSIZE) ||
-+ memcmp(&(ox800_aeslrw_driver.tweak_key[0]), tweak_key, OX800DPE_KEYSIZE) )
-+ {
-+ u32* key;
-+ unsigned int i;
-+
-+ DPRINTK(KERN_INFO"cipher key =");
-+ for (i = 0; i < OX800DPE_KEYSIZE; ++i)
-+ DPRINTK("%02x", cipher_key[i]);
-+ DPRINTK("\n");
-+ DPRINTK(KERN_INFO"tweak key =");
-+ for (i = 0; i < OX800DPE_KEYSIZE; ++i)
-+ DPRINTK("%02x", tweak_key[i]);
-+ DPRINTK("\n");
-+
-+ /* update stored values */
-+ memcpy(&(ox800_aeslrw_driver.cipher_key[0]), cipher_key, OX800DPE_KEYSIZE);
-+ memcpy(&(ox800_aeslrw_driver.tweak_key[0]), tweak_key, OX800DPE_KEYSIZE);
-+
-+ /* update hardware values */
-+ key = (u32* )cipher_key;
-+ writel(key[0], OX800DPE_KEY00 );
-+ writel(key[1], OX800DPE_KEY01 );
-+ writel(key[2], OX800DPE_KEY02 );
-+ writel(key[3], OX800DPE_KEY03 );
-+
-+ key = (u32* )tweak_key;
-+ writel(key[0], OX800DPE_KEY10 );
-+ writel(key[1], OX800DPE_KEY11 );
-+ writel(key[2], OX800DPE_KEY12 );
-+ writel(key[3], OX800DPE_KEY13 );
-+ }
-+}
-+
-+/**
-+ * Generic LRW-AES en/decryption
-+ * @param encrypt non-zero to encrypt, zero to decrypt
-+ * @param in Source of data
-+ * @param out Location to place en/decrypted data
-+ * @param nents Number of entries in scatter list, in and out must have the same
-+ * number of entries
-+ * @param iv 8 byte array containing the I-Value
-+ * @return error code or 0 for success
-+ */
-+static int ox800_aeslrw_gencrypt( u8 encrypt,
-+ struct scatterlist* in,
-+ struct scatterlist* out,
-+ unsigned int nents,
-+ u8 iv[])
-+{
-+ oxnas_dma_channel_t* dma_in;
-+ oxnas_dma_channel_t* dma_out;
-+ struct scatterlist* out_;
-+ char same_buffer;
-+ int status = 0;
-+
-+ /* get dma resources (non blocking) */
-+ dma_in = oxnas_dma_request(0);
-+ dma_out = oxnas_dma_request(0);
-+
-+ VPRINTK("dma in %d out %d \n",
-+ dma_in->channel_number_,
-+ dma_out->channel_number_);
-+
-+ if ((dma_in) && (dma_out)) {
-+ u32 reg;
-+
-+ // shouldn't be busy or full
-+ reg = readl( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ printk("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ printk("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ printk("rx not empty after abort toggle");
-+
-+ /* check to see if the destination buffer is the same as the source */
-+ same_buffer = (in->page == out->page);
-+
-+ /* map transfers */
-+ if (same_buffer) {
-+ dma_map_sg(NULL, in, nents, DMA_BIDIRECTIONAL);
-+ out_ = in;
-+ } else {
-+ /* map transfers */
-+ dma_map_sg(NULL, in, nents, DMA_TO_DEVICE);
-+ dma_map_sg(NULL, out, nents, DMA_FROM_DEVICE);
-+ out_ = out;
-+ }
-+#ifdef CIPHER_USE_SG_DMA
-+ /* setup DMA transfers */
-+ oxnas_dma_device_set_sg(
-+ dma_in,
-+ OXNAS_DMA_TO_DEVICE,
-+ in,
-+ nents,
-+ &oxnas_dpe_rx_dma_settings,
-+ OXNAS_DMA_MODE_INC);
-+
-+ oxnas_dma_device_set_sg(
-+ dma_out,
-+ OXNAS_DMA_FROM_DEVICE,
-+ out_,
-+ nents,
-+ &oxnas_dpe_tx_dma_settings,
-+ OXNAS_DMA_MODE_INC);
-+
-+#else
-+ oxnas_dma_device_set(
-+ dma_in,
-+ OXNAS_DMA_TO_DEVICE,
-+ (unsigned char* )sg_dma_address(in),
-+ sg_dma_len(in),
-+ &oxnas_dpe_rx_dma_settings,
-+ OXNAS_DMA_MODE_INC,
-+ 1 /*paused */ );
-+
-+ oxnas_dma_device_set(
-+ dma_out,
-+ OXNAS_DMA_FROM_DEVICE,
-+ (unsigned char* )sg_dma_address(out_),
-+ sg_dma_len(out_),
-+ &oxnas_dpe_tx_dma_settings,
-+ OXNAS_DMA_MODE_INC,
-+ 1 /*paused */ );
-+#endif
-+
-+ /* set dma callbacks */
-+ oxnas_dma_set_callback(
-+ dma_in,
-+ OXNAS_DMA_CALLBACK_ARG_NUL,
-+ OXNAS_DMA_CALLBACK_ARG_NUL);
-+
-+ oxnas_dma_set_callback(
-+ dma_out,
-+ OXNAS_DMA_CALLBACK_ARG_NUL,
-+ OXNAS_DMA_CALLBACK_ARG_NUL);
-+
-+
-+ /* set for AES LRW encryption or decryption */
-+ writel( (encrypt ? OX800DPE_CTL_DIRECTION_ENC : 0 ) |
-+ OX800DPE_CTL_MODE_LRW_AES,
-+ OX800DPE_CONTROL);
-+ wmb();
-+
-+ /* write in I-value */
-+ writel(*((u32* )&(iv[0])), OX800DPE_DATA_LRW0 );
-+ writel(*((u32* )&(iv[4])), OX800DPE_DATA_LRW1 );
-+
-+ wmb();
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & readl( OX800DPE_STATUS )) );
-+
-+ /* start dma */
-+ oxnas_dma_start(dma_out);
-+ oxnas_dma_start(dma_in);
-+
-+ /* wait (once for each channel) */
-+ while ( oxnas_dma_is_active( dma_out ) ||
-+ oxnas_dma_is_active( dma_in ) )
-+ {
-+ schedule();
-+ }
-+
-+ /* free any allocated dma channels */
-+ oxnas_dma_free( dma_in );
-+ oxnas_dma_free( dma_out );
-+
-+ /* unmap transfers */
-+ if (same_buffer) {
-+ dma_unmap_sg(NULL, in, nents, DMA_BIDIRECTIONAL);
-+ } else {
-+ dma_unmap_sg(NULL, in, nents, DMA_TO_DEVICE);
-+ dma_unmap_sg(NULL, out, nents, DMA_FROM_DEVICE);
-+ }
-+
-+ status = ox800_aeslrw_driver.result;
-+ } else {
-+ /* free any allocated dma channels */
-+ if (dma_in)
-+ oxnas_dma_free( dma_in );
-+ if (dma_out)
-+ oxnas_dma_free( dma_out );
-+ status = -EBUSY;
-+ }
-+ /* return an indication of success */
-+ return status;
-+}
-+
-+/**
-+ * Performs LRW-AES encryption.
-+ * @param in Source of data
-+ * @param out Location to place encrypted data
-+ * @param nents Number of entries in scatter list, in and out must have the same
-+ * number of entries
-+ * @param iv I-Value
-+ * @param cipher_key 16 byte array that is the cipher key
-+ * @param tweak_key 16 byte array that is the I-Value tweak key
-+ * @return error code or 0 for success
-+ */
-+int ox800_aeslrw_encrypt( struct scatterlist* in,
-+ struct scatterlist* out,
-+ unsigned int nents,
-+ u8* iv,
-+ u8* cipher_key,
-+ u8* tweak_key)
-+{
-+ int localresult;
-+
-+ VPRINTK(KERN_INFO"in %p, out %p, nents %d, iv %08x%08x, ckey %p, tkey %p\n",
-+ in, out, nents, *((u32* )(&iv[4])), *((u32* )(&iv[0])), cipher_key, tweak_key );
-+
-+ /* get cipher core */
-+ while( down_interruptible(&ox800_aeslrw_driver.core) ) ;
-+
-+ VPRINTK(KERN_INFO"got core\n");
-+
-+ ox800_aeslrw_setkeys(cipher_key, tweak_key);
-+ localresult = ox800_aeslrw_gencrypt( 1, in, out, nents, iv);
-+
-+ up(&ox800_aeslrw_driver.core);
-+ VPRINTK(KERN_INFO"released\n");
-+
-+ return localresult;
-+}
-+
-+/**
-+ * Performs LRW-AES decryption.
-+ * @param in Source of data
-+ * @param out Location to place decrypted data
-+ * @param nents Number of entries in scatter list, in and out must have the same
-+ * number of entries
-+ * @param iv I-Value
-+ * @param cipher_key 16 byte array that is the cipher key
-+ * @param tweak_key 16 byte array that is the I-Value tweak key
-+ * @return error code or 0 for success
-+ */
-+int ox800_aeslrw_decrypt( struct scatterlist* in,
-+ struct scatterlist* out,
-+ unsigned int nents,
-+ u8* iv,
-+ u8* cipher_key,
-+ u8* tweak_key)
-+{
-+ int localresult;
-+
-+ VPRINTK(KERN_INFO"in %p, out %p, nents %d, iv %08x%08x, ckey %p, tkey%p\n",
-+ in, out, nents, *((u32* )(&iv[4])), *((u32* )(&iv[0])), cipher_key, tweak_key );
-+
-+ /* get cipher core */
-+ while( down_interruptible(&ox800_aeslrw_driver.core) ) ;
-+
-+ VPRINTK(KERN_INFO"got core\n");
-+
-+ ox800_aeslrw_setkeys(cipher_key, tweak_key);
-+ localresult = ox800_aeslrw_gencrypt( 0, in, out, nents, iv);
-+
-+ up(&ox800_aeslrw_driver.core);
-+ VPRINTK(KERN_INFO"released core \n");
-+
-+ return localresult;
-+}
-+
-+/**
-+ * module initialisation
-+ * @return success is 0
-+ */
-+static int __init ox800_aeslrw_init( void )
-+{
-+ VPRINTK(KERN_INFO"\n");
-+
-+ /* Enable the clock to the DPE block */
-+ writel(1UL << SYS_CTRL_CKEN_DPE_BIT, SYS_CTRL_CKEN_SET_CTRL);
-+
-+ /* Bring out of reset */
-+ writel(1UL << SYS_CTRL_RSTEN_DPE_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+
-+ /* initialise in unlocked state */
-+ init_MUTEX(&ox800_aeslrw_driver.core);
-+
-+ return 0;
-+}
-+
-+/**
-+ * module cleanup
-+ */
-+static void __exit ox800_aeslrw_exit( void )
-+{
-+}
-+
-+/**
-+ * macros to register intiialisation and exit functions with kernal
-+ */
-+module_init(ox800_aeslrw_init);
-+module_exit(ox800_aeslrw_exit);
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/dma.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/dma.c
---- linux-2.6.24/arch/arm/mach-oxnas/dma.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/dma.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,2849 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/dma.c
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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 <asm/dma.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/arch/hardware.h>
-+#include <linux/bitops.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/dmapool.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/delay.h>
-+#include <asm/arch/desc_alloc.h>
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+#include <asm/checksum.h>
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+//#define DMA_DEBUG
-+
-+#ifdef OXNAS_DMA_TEST
-+#define DMA_DEBUG
-+static void dma_test(unsigned long length);
-+#endif // OXNAS_DMA_TEST
-+
-+#ifdef OXNAS_DMA_SG_TEST
-+#define DMA_DEBUG
-+static void dma_sg_test(void);
-+#endif // OXNAS_DMA_SG_TEST
-+
-+#ifdef OXNAS_DMA_SG_TEST_2
-+#define DMA_DEBUG
-+static void dma_sg_test2(void);
-+#endif // OXNAS_DMA_SG_TEST_2
-+
-+#ifdef DMA_DEBUG
-+#define DBG(args...) printk(args)
-+#else
-+#define DBG(args...) do { } while(0)
-+#endif
-+
-+// Normal (non-SG) registers
-+#define DMA_REGS_PER_CHANNEL 8
-+
-+#define DMA_CTRL_STATUS 0x0
-+#define DMA_BASE_SRC_ADR 0x4
-+#define DMA_BASE_DST_ADR 0x8
-+#define DMA_BYTE_CNT 0xC
-+#define DMA_CURRENT_SRC_ADR 0x10
-+#define DMA_CURRENT_DST_ADR 0x14
-+#define DMA_CURRENT_BYTE_CNT 0x18
-+#define DMA_INTR_ID 0x1C
-+#define DMA_INTR_CLEAR_REG (DMA_CURRENT_SRC_ADR)
-+
-+// 8 quad-sized registers per channel arranged contiguously
-+#define DMA_CALC_REG_ADR(channel, register) (DMA_BASE + ((channel) << 5) + (register))
-+
-+#define DMA_CTRL_STATUS_FAIR_SHARE_ARB (1 << 0)
-+#define DMA_CTRL_STATUS_IN_PROGRESS (1 << 1)
-+#define DMA_CTRL_STATUS_SRC_DREQ_MASK (0x0000003C)
-+#define DMA_CTRL_STATUS_SRC_DREQ_SHIFT 2
-+#define DMA_CTRL_STATUS_DEST_DREQ_MASK (0x000003C0)
-+#define DMA_CTRL_STATUS_DEST_DREQ_SHIFT 6
-+#define DMA_CTRL_STATUS_INTR (1 << 10)
-+#define DMA_CTRL_STATUS_NXT_FREE (1 << 11)
-+#define DMA_CTRL_STATUS_RESET (1 << 12)
-+#define DMA_CTRL_STATUS_DIR_MASK (0x00006000)
-+#define DMA_CTRL_STATUS_DIR_SHIFT 13
-+#define DMA_CTRL_STATUS_SRC_ADR_MODE (1 << 15)
-+#define DMA_CTRL_STATUS_DEST_ADR_MODE (1 << 16)
-+#define DMA_CTRL_STATUS_TRANSFER_MODE_A (1 << 17)
-+#define DMA_CTRL_STATUS_TRANSFER_MODE_B (1 << 18)
-+#define DMA_CTRL_STATUS_SRC_WIDTH_MASK (0x00380000)
-+#define DMA_CTRL_STATUS_SRC_WIDTH_SHIFT 19
-+#define DMA_CTRL_STATUS_DEST_WIDTH_MASK (0x01C00000)
-+#define DMA_CTRL_STATUS_DEST_WIDTH_SHIFT 22
-+#define DMA_CTRL_STATUS_PAUSE (1 << 25)
-+#define DMA_CTRL_STATUS_INTERRUPT_ENABLE (1 << 26)
-+#define DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED (1 << 27)
-+#define DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED (1 << 28)
-+#define DMA_CTRL_STATUS_STARVE_LOW_PRIORITY (1 << 29)
-+#define DMA_CTRL_STATUS_INTR_CLEAR_ENABLE (1 << 30)
-+
-+#define DMA_BYTE_CNT_MASK ((1 << 21) - 1)
-+#define DMA_BYTE_CNT_INC4_SET_MASK (1 << 28)
-+#define DMA_BYTE_CNT_HPROT_MASK (1 << 29)
-+#define DMA_BYTE_CNT_WR_EOT_MASK (1 << 30)
-+#define DMA_BYTE_CNT_RD_EOT_MASK (1 << 31)
-+
-+#define DMA_INTR_ID_GET_NUM_CHANNELS(reg_contents) (((reg_contents) >> 16) & 0xFF)
-+#define DMA_INTR_ID_GET_VERSION(reg_contents) (((reg_contents) >> 24) & 0xFF)
-+#define DMA_INTR_ID_INT_BIT 0
-+#define DMA_INTR_ID_INT_NUM_BITS (MAX_OXNAS_DMA_CHANNELS)
-+#define DMA_INTR_ID_INT_MASK (((1 << DMA_INTR_ID_INT_NUM_BITS) - 1) << DMA_INTR_ID_INT_BIT)
-+
-+#define DMA_HAS_V4_INTR_CLEAR(version) ((version) > 3)
-+
-+// H/W scatter gather controller registers
-+#define OXNAS_DMA_NUM_SG_REGS 4
-+
-+#define DMA_SG_CONTROL 0x0
-+#define DMA_SG_STATUS 0x04
-+#define DMA_SG_REQ_PTR 0x08
-+#define DMA_SG_RESETS 0x0C
-+
-+#define DMA_SG_CALC_REG_ADR(channel, register) ((DMA_SG_BASE) + ((channel) << 4) + (register))
-+
-+// SG DMA controller control register field definitions
-+#define DMA_SG_CONTROL_START_BIT 0
-+#define DMA_SG_CONTROL_QUEUING_ENABLE_BIT 1
-+#define DMA_SG_CONTROL_HBURST_ENABLE_BIT 2
-+
-+// SG DMA controller status register field definitions
-+#define DMA_SG_STATUS_ERROR_CODE_BIT 0
-+#define DMA_SG_STATUS_ERROR_CODE_NUM_BITS 6
-+#define DMA_SG_STATUS_BUSY_BIT 7
-+
-+// SG DMA controller sub-block resets register field definitions
-+#define DMA_SG_RESETS_CONTROL_BIT 0
-+#define DMA_SG_RESETS_ARBITER_BIT 1
-+#define DMA_SG_RESETS_AHB_BIT 2
-+
-+// oxnas_dma_sg_info_t qualifier field definitions
-+#define OXNAS_DMA_SG_QUALIFIER_BIT 0
-+#define OXNAS_DMA_SG_QUALIFIER_NUM_BITS 16
-+#define OXNAS_DMA_SG_DST_EOT_BIT 16
-+#define OXNAS_DMA_SG_DST_EOT_NUM_BITS 2
-+#define OXNAS_DMA_SG_SRC_EOT_BIT 20
-+#define OXNAS_DMA_SG_SRC_EOT_NUM_BITS 2
-+#define OXNAS_DMA_SG_CHANNEL_BIT 24
-+#define OXNAS_DMA_SG_CHANNEL_NUM_BITS 8
-+
-+// Valid address bits mask
-+#define OXNAS_DMA_ADR_MASK ((1UL << (MEM_MAP_ALIAS_SHIFT)) - 1)
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+#define OXNAS_DMA_CSUM_ADR_MASK ((OXNAS_DMA_ADR_MASK) | (1UL << (OXNAS_DMA_CSUM_ENABLE_ADR_BIT)))
-+#else
-+#define OXNAS_DMA_CSUM_ADR_MASK (OXNAS_DMA_ADR_MASK)
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+/* The available buses to which the DMA controller is attached */
-+typedef enum oxnas_dma_transfer_bus
-+{
-+ OXNAS_DMA_SIDE_A,
-+ OXNAS_DMA_SIDE_B
-+} oxnas_dma_transfer_bus_t;
-+
-+/* Direction of data flow between the DMA controller's pair of interfaces */
-+typedef enum oxnas_dma_transfer_direction
-+{
-+ OXNAS_DMA_A_TO_A,
-+ OXNAS_DMA_B_TO_A,
-+ OXNAS_DMA_A_TO_B,
-+ OXNAS_DMA_B_TO_B
-+} oxnas_dma_transfer_direction_t;
-+
-+/* The available data widths */
-+typedef enum oxnas_dma_transfer_width
-+{
-+ OXNAS_DMA_TRANSFER_WIDTH_8BITS,
-+ OXNAS_DMA_TRANSFER_WIDTH_16BITS,
-+ OXNAS_DMA_TRANSFER_WIDTH_32BITS
-+} oxnas_dma_transfer_width_t;
-+
-+/* The mode of the DMA transfer */
-+typedef enum oxnas_dma_transfer_mode
-+{
-+ OXNAS_DMA_TRANSFER_MODE_SINGLE,
-+ OXNAS_DMA_TRANSFER_MODE_BURST
-+} oxnas_dma_transfer_mode_t;
-+
-+/* The available transfer targets */
-+typedef enum oxnas_dma_dreq
-+{
-+ OXNAS_DMA_DREQ_PATA = 0,
-+ OXNAS_DMA_DREQ_SATA = 0,
-+ OXNAS_DMA_DREQ_DPE_RX = 1,
-+ OXNAS_DMA_DREQ_DPE_TX = 2,
-+ OXNAS_DMA_DREQ_AUDIO_TX = 5,
-+ OXNAS_DMA_DREQ_AUDIO_RX = 6,
-+ OXNAS_DMA_DREQ_MEMORY = 15
-+} oxnas_dma_dreq_t;
-+
-+/* Pre-defined settings for known DMA devices */
-+oxnas_dma_device_settings_t oxnas_pata_dma_settings = {
-+ .address_ = 0,
-+ .fifo_size_ = 16,
-+ .dreq_ = OXNAS_DMA_DREQ_PATA,
-+ .read_eot_policy_ = OXNAS_DMA_EOT_FINAL,
-+ .write_eot_policy_ = OXNAS_DMA_EOT_FINAL,
-+ .bus_ = OXNAS_DMA_SIDE_A,
-+ .width_ = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
-+ .transfer_mode_ = OXNAS_DMA_TRANSFER_MODE_BURST,
-+ .address_mode_ = OXNAS_DMA_MODE_FIXED,
-+ .address_really_fixed_ = 0
-+};
-+
-+oxnas_dma_device_settings_t oxnas_sata_dma_settings = {
-+ .address_ = SATA_DATA_BASE_PA,
-+ .fifo_size_ = 16,
-+ .dreq_ = OXNAS_DMA_DREQ_SATA,
-+ .read_eot_policy_ = OXNAS_DMA_EOT_FINAL,
-+ .write_eot_policy_ = OXNAS_DMA_EOT_FINAL,
-+ .bus_ = OXNAS_DMA_SIDE_A,
-+ .width_ = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
-+ .transfer_mode_ = OXNAS_DMA_TRANSFER_MODE_BURST,
-+ .address_mode_ = OXNAS_DMA_MODE_FIXED,
-+ .address_really_fixed_ = 0
-+};
-+
-+oxnas_dma_device_settings_t oxnas_dpe_rx_dma_settings = {
-+ .address_ = DPE_BASE_PA,
-+ .fifo_size_ = 16,
-+ .dreq_ = OXNAS_DMA_DREQ_DPE_RX,
-+ .read_eot_policy_ = OXNAS_DMA_EOT_FINAL,
-+ .write_eot_policy_ = OXNAS_DMA_EOT_FINAL,
-+ .bus_ = OXNAS_DMA_SIDE_A,
-+ .width_ = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
-+ .transfer_mode_ = OXNAS_DMA_TRANSFER_MODE_BURST,
-+ .address_mode_ = OXNAS_DMA_MODE_FIXED,
-+ .address_really_fixed_ = 0
-+};
-+
-+oxnas_dma_device_settings_t oxnas_dpe_tx_dma_settings = {
-+ .address_ = DPE_BASE_PA,
-+ .fifo_size_ = 16,
-+ .dreq_ = OXNAS_DMA_DREQ_DPE_TX,
-+ .read_eot_policy_ = OXNAS_DMA_EOT_FINAL,
-+ .write_eot_policy_ = OXNAS_DMA_EOT_FINAL,
-+ .bus_ = OXNAS_DMA_SIDE_A,
-+ .width_ = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
-+ .transfer_mode_ = OXNAS_DMA_TRANSFER_MODE_BURST,
-+ .address_mode_ = OXNAS_DMA_MODE_FIXED,
-+ .address_really_fixed_ = 0
-+};
-+
-+/* For use with normal memory to memory transfers as the settings for the source
-+ * of the transfer */
-+oxnas_dma_device_settings_t oxnas_ram_only_src_dma_settings = {
-+ .address_ = 0,
-+ .fifo_size_ = 0,
-+ .dreq_ = OXNAS_DMA_DREQ_MEMORY,
-+ .read_eot_policy_ = OXNAS_DMA_EOT_FINAL, // Won't interfere with checksumming transfers, as csum only latched if high order address bit set
-+ .write_eot_policy_ = OXNAS_DMA_EOT_NONE,
-+ .bus_ = OXNAS_DMA_SIDE_A, // Maximise performance with src on side A while dst in on side B
-+ .width_ = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
-+ .transfer_mode_ = OXNAS_DMA_TRANSFER_MODE_BURST,
-+ .address_mode_ = OXNAS_DMA_MODE_FIXED,
-+ .address_really_fixed_ = 1
-+};
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+/* For use with checksumming transfers as the settings for the source of the
-+ * transfer */
-+oxnas_dma_device_settings_t oxnas_ram_csum_src_dma_settings = {
-+ .address_ = 0,
-+ .fifo_size_ = 0,
-+ .dreq_ = OXNAS_DMA_DREQ_MEMORY,
-+ .read_eot_policy_ = OXNAS_DMA_EOT_FINAL, // To enable checksum accumulation
-+ .write_eot_policy_ = OXNAS_DMA_EOT_NONE,
-+ .bus_ = OXNAS_DMA_SIDE_A, // Checksumming happens on read from side A only
-+ .width_ = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
-+ .transfer_mode_ = OXNAS_DMA_TRANSFER_MODE_BURST,
-+ .address_mode_ = OXNAS_DMA_MODE_FIXED,
-+ .address_really_fixed_ = 1
-+};
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+/* For use in all occasions not covered by oxnas_ram_only_src_dma_settings and
-+ * oxnas_ram_csum_src_dma_settings */
-+oxnas_dma_device_settings_t oxnas_ram_generic_dma_settings = {
-+ .address_ = 0,
-+ .fifo_size_ = 0,
-+ .dreq_ = OXNAS_DMA_DREQ_MEMORY,
-+ .read_eot_policy_ = OXNAS_DMA_EOT_NONE, // Don't interfere with any checksumming transfers
-+ .write_eot_policy_ = OXNAS_DMA_EOT_NONE,
-+ .bus_ = OXNAS_DMA_SIDE_B,
-+ .width_ = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
-+ .transfer_mode_ = OXNAS_DMA_TRANSFER_MODE_BURST,
-+ .address_mode_ = OXNAS_DMA_MODE_FIXED,
-+ .address_really_fixed_ = 1
-+};
-+
-+static oxnas_dma_controller_t dma_controller;
-+
-+/**
-+ * Acquisition of a SG DMA descriptor list entry
-+ * If called from non-atomic context the call could block.
-+ */
-+static oxnas_dma_sg_entry_t* alloc_sg_entry(int in_atomic)
-+{
-+ oxnas_dma_sg_entry_t* entry = 0;
-+ if (in_atomic) {
-+ if (down_trylock(&dma_controller.sg_entry_sem_)) {
-+ return (oxnas_dma_sg_entry_t*)0;
-+ }
-+ } else {
-+ // Wait for an entry to be available
-+ while (down_interruptible(&dma_controller.sg_entry_sem_));
-+ }
-+
-+ // Serialise while manipulating free list
-+ spin_lock_bh(&dma_controller.alloc_spinlock_);
-+
-+ // It's an error if there isn't a buffer available at this point
-+ BUG_ON(!dma_controller.sg_entry_head_);
-+
-+ // Unlink the head entry on the free list and return it to caller
-+ entry = dma_controller.sg_entry_head_;
-+ dma_controller.sg_entry_head_ = dma_controller.sg_entry_head_->next_;
-+ --dma_controller.sg_entry_available_;
-+
-+ // Finished manipulating free list
-+ spin_unlock_bh(&dma_controller.alloc_spinlock_);
-+
-+ return entry;
-+}
-+
-+static void free_sg_entry(oxnas_dma_sg_entry_t* entry)
-+{
-+ // Serialise while manipulating free list
-+ spin_lock(&dma_controller.alloc_spinlock_);
-+
-+ // Insert the freed buffer at the head of the free list
-+ entry->next_ = dma_controller.sg_entry_head_;
-+ dma_controller.sg_entry_head_ = entry;
-+ ++dma_controller.sg_entry_available_;
-+
-+ // Finished manipulating free list
-+ spin_unlock(&dma_controller.alloc_spinlock_);
-+
-+ // Make freed buffer available for allocation
-+ up(&dma_controller.sg_entry_sem_);
-+}
-+
-+void oxnas_dma_free_sg_entries(oxnas_dma_sg_entry_t* entries)
-+{
-+ while (entries) {
-+ oxnas_dma_sg_entry_t* next = entries->next_;
-+ free_sg_entry(entries);
-+ entries = next;
-+ }
-+}
-+
-+/**
-+ * This implementation is not the most efficient, as it could result in alot
-+ * of alloc's only to decide to free them all as not sufficient available, but
-+ * in practice we would hope there will not be much contention for entries
-+ */
-+int oxnas_dma_alloc_sg_entries(
-+ oxnas_dma_sg_entry_t **entries,
-+ unsigned required,
-+ int in_atomic)
-+{
-+ if (likely(required)) {
-+ oxnas_dma_sg_entry_t* prev;
-+ oxnas_dma_sg_entry_t* entry;
-+ unsigned acquired = 0;
-+
-+ *entries = alloc_sg_entry(in_atomic);
-+ if (!*entries) {
-+ return 1;
-+ }
-+
-+ (*entries)->next_ = 0;
-+ prev = *entries;
-+
-+ while (++acquired < required) {
-+ entry = alloc_sg_entry(in_atomic);
-+ if (!entry) {
-+ // Did not acquire the entry
-+ oxnas_dma_free_sg_entries(*entries);
-+ return 1;
-+ }
-+ entry->next_ = 0;
-+ prev->next_ = entry;
-+ prev = entry;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+/**
-+ * Blocking acquisition of the checksum engine
-+ */
-+static inline int alloc_csum_engine(int in_atomic)
-+{
-+#ifdef CONFIG_LEON_RESERVE_DMA_CHANNEL
-+ // Checksum engine is allocated exclusively to the CoPro
-+ return 1;
-+#else
-+ if (in_atomic) {
-+ return down_trylock(&dma_controller.csum_engine_sem_);
-+ } else {
-+ while (1) {
-+ if (!down_interruptible(&dma_controller.csum_engine_sem_)) {
-+ return 0;
-+ }
-+ }
-+ }
-+#endif // CONFIG_LEON_RESERVE_DMA_CHANNEL
-+}
-+
-+static inline void free_csum_engine(void)
-+{
-+ up(&dma_controller.csum_engine_sem_);
-+}
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+/**
-+ * Optionally blocking acquisition of a DMA channel
-+ * May be invoked either at task or softirq level
-+ */
-+oxnas_dma_channel_t* oxnas_dma_request(int block)
-+{
-+ oxnas_dma_channel_t* channel = OXNAS_DMA_CHANNEL_NUL;
-+ while (channel == OXNAS_DMA_CHANNEL_NUL) {
-+ if (block) {
-+ // Wait for a channel to be available
-+ if (down_interruptible(&dma_controller.channel_sem_)) {
-+ // Awoken by signal
-+ continue;
-+ }
-+ } else {
-+ // Non-blocking test of whether a channel is available
-+ if (down_trylock(&dma_controller.channel_sem_)) {
-+ // No channel available so return to user immediately
-+ break;
-+ }
-+ }
-+
-+ // Serialise while manipulating free list
-+ spin_lock_bh(&dma_controller.channel_alloc_spinlock_);
-+
-+ // It's an error if there isn't a channel available at this point
-+ BUG_ON(!dma_controller.channel_head_);
-+
-+ // Unlink the head entry on the free list and return it to caller
-+ channel = dma_controller.channel_head_;
-+ dma_controller.channel_head_ = dma_controller.channel_head_->next_;
-+
-+ // Finished manipulating free list
-+ spin_unlock_bh(&dma_controller.channel_alloc_spinlock_);
-+ }
-+ return channel;
-+}
-+
-+/**
-+ * May be invoked either at task or softirq level
-+ */
-+void oxnas_dma_free(oxnas_dma_channel_t* channel)
-+{
-+ if (oxnas_dma_is_active(channel)) {
-+ printk(KERN_WARNING "oxnas_dma_free() Freeing channel %u while active\n", channel->channel_number_);
-+ }
-+
-+ // Serialise while manipulating free list
-+ spin_lock_bh(&dma_controller.channel_alloc_spinlock_);
-+
-+ // Insert the freed buffer at the head of the free list
-+ channel->next_ = dma_controller.channel_head_;
-+ dma_controller.channel_head_ = channel;
-+
-+ // Finished manipulating free list
-+ spin_unlock_bh(&dma_controller.channel_alloc_spinlock_);
-+
-+ // Make freed buffer available for allocation
-+ up(&dma_controller.channel_sem_);
-+}
-+
-+/** Shared between all DMA interrupts and run with interrupts enabled, thus any
-+ * access to shared data structures must be sync'ed
-+ */
-+static irqreturn_t oxnas_dma_interrupt(int irq, void *dev_id)
-+{
-+ oxnas_dma_channel_t *channel = 0;
-+ unsigned channel_number = 0;
-+ int need_bh = 0;
-+
-+DBG("oxnas_dma_interrupt() from interrupt line %u\n", irq);
-+
-+ // Only acknowledge interrupts from the channel directly responsible for the
-+ // RPS interrupt line which caused the ISR to be entered, to get around the
-+ // problem that the SG-DMA controller can only filter DMA interrupts exter-
-+ // nally to the DMA controller, i.e. the DMA controller interrupt status
-+ // register always shows all active interrupts for all channels, regardless
-+ // of whether the SG-DMA controller is filtering them
-+
-+ // Find the DMA channel that can generate interrupts on the RPS interrupt
-+ // line which caused the ISR to be invoked.
-+ if (likely(irq == DMA_INTERRUPT_4)) {
-+ channel = &dma_controller.channels_[4];
-+ } else {
-+ channel = &dma_controller.channels_[irq - DMA_INTERRUPT_0];
-+ }
-+ channel_number = channel->channel_number_;
-+DBG("RPS interrupt %u from channel %u\n", irq, channel_number);
-+
-+ // Non-SG transfers have no completion status, so initialise
-+ // channel's error code to no-error. If transfer turns out to
-+ // have been SG, this status will be overwritten
-+ channel->error_code_ = OXNAS_DMA_ERROR_CODE_NONE;
-+
-+ // Must finish in bottom half if checksumming or need to invoke callback
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ need_bh = channel->checksumming_ ||
-+#else // CONFIG_OXNAS_VERSION_0X800
-+ need_bh =
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+ (channel->notification_callback_ != OXNAS_DMA_CALLBACK_NUL);
-+
-+ // Cope with the DMA controller's ability to have a pair of chained
-+ // transfers which have both completed, which causes the interrupt request
-+ // to stay active until both have been acknowledged, which is causing the SG
-+ // controller problems
-+ while (readl(DMA_CALC_REG_ADR(0, DMA_INTR_ID)) & (1 << channel_number)) {
-+DBG("Ack'ing interrupt for channel %u\n", channel_number);
-+ // Write to the interrupt clear register to clear interrupt
-+ writel(0, DMA_CALC_REG_ADR(channel_number, DMA_INTR_CLEAR_REG));
-+
-+ // Record how many interrupts are awaiting service
-+ atomic_inc(&channel->interrupt_count_);
-+ }
-+DBG("Left int ack'ing loop\n");
-+
-+ // If was a SG transfer, record the completion status
-+ if (channel->v_sg_info_->v_srcEntries_) {
-+ // Record the SG transfer completion status
-+ u32 error_code = readl(DMA_SG_CALC_REG_ADR(channel_number, DMA_SG_STATUS));
-+ channel->error_code_ =
-+ ((error_code >> DMA_SG_STATUS_ERROR_CODE_BIT) &
-+ ((1UL << DMA_SG_STATUS_ERROR_CODE_NUM_BITS) - 1));
-+
-+ if (channel->auto_sg_entries_) {
-+ // Must finish in bottom half if we are to manage the SG entries
-+DBG("ISR channel %d is auto SG\n", channel->channel_number_);
-+ need_bh = 1;
-+ } else {
-+DBG("ISR channel %d not auto SG\n", channel->channel_number_);
-+ // Zeroise SG DMA descriptor info
-+ channel->v_sg_info_->p_srcEntries_ = 0;
-+ channel->v_sg_info_->v_srcEntries_ = 0;
-+ channel->v_sg_info_->p_dstEntries_ = 0;
-+ channel->v_sg_info_->v_dstEntries_ = 0;
-+ }
-+
-+DBG("Return SG controller to idle, error_code = 0x%08x\n", error_code);
-+ // Return the SG DMA controller to the IDLE state and clear any SG
-+ // controller error interrupt
-+ writel(1, DMA_SG_CALC_REG_ADR(channel_number, DMA_SG_STATUS));
-+ }
-+
-+ // Can we finish w/o invoking bottom half?
-+ if (likely(!need_bh)) {
-+DBG("ISR channel %d do not call bh\n", channel->channel_number_);
-+ atomic_set(&channel->interrupt_count_, 0);
-+ atomic_set(&channel->active_count_, 0);
-+ } else {
-+DBG("Marking channel %d as requiring its bottom half to run\n", channel_number);
-+ // Set a flag for the channel to cause its bottom half to be run
-+ set_bit(channel_number, (void*)&dma_controller.run_bh_);
-+
-+DBG("Scheduling tasklet\n");
-+ // Signal the bottom half to perform the notifications
-+ tasklet_schedule(&dma_controller.tasklet_);
-+ }
-+
-+DBG("Returning\n");
-+ return IRQ_HANDLED;
-+}
-+
-+static void fake_interrupt(int channel)
-+{
-+ // Set a flag to cause the bottom half handler to be run for the channel
-+ set_bit(channel, (void*)&dma_controller.run_bh_);
-+
-+ // Signal the bottom half to perform the notifications
-+ tasklet_schedule(&dma_controller.tasklet_);
-+}
-+
-+static void dma_bh(unsigned long data)
-+{
-+ // Check for any bottom halves having become ready to run
-+ u32 run_bh = atomic_read(&dma_controller.run_bh_);
-+ while (run_bh) {
-+ unsigned i;
-+
-+ // Free any checksumming or SG resources
-+ u32 temp_run_bh = run_bh;
-+ for (i = 0; i < dma_controller.numberOfChannels_; i++, temp_run_bh >>= 1) {
-+ if (temp_run_bh & 1) {
-+ oxnas_dma_channel_t* channel = &dma_controller.channels_[i];
-+DBG("Bottom halve for channel %u\n", channel->channel_number_);
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ // If this channel computed a checksum
-+ if (unlikely(channel->checksumming_)) {
-+ // Read the result of the checksum calculation, clearing the
-+ // result in the process
-+ channel->checksum_ = readl(DMA_CHECKSUM_BASE);
-+ channel->checksumming_ = 0;
-+
-+ // Relinquish ownership of the checksum engine
-+ free_csum_engine();
-+ }
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+ if (channel->auto_sg_entries_) {
-+ // Free SG DMA source descriptor resources
-+ oxnas_dma_sg_entry_t* sg_entry = channel->v_sg_info_->v_srcEntries_;
-+DBG("Freeing SG resources for channel %d\n", channel->channel_number_);
-+ while (sg_entry) {
-+ oxnas_dma_sg_entry_t* next = sg_entry->v_next_;
-+ free_sg_entry(sg_entry);
-+ sg_entry = next;
-+ }
-+
-+ // Free SG DMA destination descriptor resources
-+ sg_entry = channel->v_sg_info_->v_dstEntries_;
-+ while (sg_entry) {
-+ oxnas_dma_sg_entry_t* next = sg_entry->v_next_;
-+ free_sg_entry(sg_entry);
-+ sg_entry = next;
-+ }
-+
-+ // Zeroise SG DMA source descriptor info
-+ channel->v_sg_info_->p_srcEntries_ = 0;
-+ channel->v_sg_info_->v_srcEntries_ = 0;
-+ channel->v_sg_info_->p_dstEntries_ = 0;
-+ channel->v_sg_info_->v_dstEntries_ = 0;
-+ }
-+ }
-+ }
-+
-+ // Mark that we have serviced the bottom halves. None of the channels
-+ // we have just serviced can interrupt again until their active flags
-+ // are cleared below
-+ atomic_sub(run_bh, &dma_controller.run_bh_);
-+
-+ // Notify all listeners of transfer completion
-+ for (i = 0; i < dma_controller.numberOfChannels_; i++, run_bh >>= 1) {
-+ if (run_bh & 1) {
-+ int interrupt_count;
-+ oxnas_dma_channel_t* channel = &dma_controller.channels_[i];
-+
-+ // Clear the count of received interrupts for the channel now
-+ // that we have serviced them all
-+ interrupt_count = atomic_read(&channel->interrupt_count_);
-+ atomic_sub(interrupt_count, &channel->interrupt_count_);
-+
-+ // Decrement the count of active transfers, by the number of
-+ // interrupts we've seen. This must occur before we inform any
-+ // listeners who are awaiting completion notification. Should
-+ // only decrement if greater than zero, in case we see spurious
-+ // interrupt events - we can't be fully safe against this sort
-+ // of broken h/w, but we can at least stop the count underflowing
-+ // active_count_ is only shared with thread level code, so read
-+ // and decrement don't need to be atomic
-+ if (atomic_read(&channel->active_count_)) {
-+ atomic_dec(&channel->active_count_);
-+ }
-+
-+ // If there is a callback registered, notify the user that the
-+ // transfer is complete
-+ if (channel->notification_callback_ != OXNAS_DMA_CALLBACK_NUL) {
-+DBG("Notifying channel %u, %d outstanding interrupts\n", channel->channel_number_, interrupt_count);
-+ (*channel->notification_callback_)(
-+ &dma_controller.channels_[i],
-+ channel->notification_arg_,
-+ channel->error_code_,
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ channel->checksum_,
-+#else // CONFIG_OXNAS_VERSION_0X800
-+ 0,
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+ interrupt_count);
-+ }
-+ }
-+ }
-+
-+ // Check for any more bottom halves having become ready to run
-+ run_bh = atomic_read(&dma_controller.run_bh_);
-+ }
-+}
-+
-+void __init oxnas_dma_init()
-+{
-+ unsigned i;
-+ unsigned long intId;
-+ oxnas_dma_sg_info_t *v_info;
-+ dma_addr_t p_info;
-+
-+ // Ensure the DMA block is properly reset
-+ writel(1UL << SYS_CTRL_RSTEN_DMA_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+ writel(1UL << SYS_CTRL_RSTEN_DMA_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+
-+ // Ensure the SG-DMA block is properly reset
-+ writel(1UL << SYS_CTRL_RSTEN_SGDMA_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+ writel(1UL << SYS_CTRL_RSTEN_SGDMA_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+
-+ // Enable the clock to the DMA block
-+ writel(1UL << SYS_CTRL_CKEN_DMA_BIT, SYS_CTRL_CKEN_SET_CTRL);
-+
-+ // Initialise the DMA controller
-+ atomic_set(&dma_controller.run_bh_, 0);
-+ spin_lock_init(&dma_controller.spinlock_);
-+ spin_lock_init(&dma_controller.alloc_spinlock_);
-+ spin_lock_init(&dma_controller.channel_alloc_spinlock_);
-+ sema_init(&dma_controller.csum_engine_sem_, 1);
-+
-+ // Initialise channel allocation management
-+ dma_controller.channel_head_ = 0;
-+ sema_init(&dma_controller.channel_sem_, 0);
-+ // Initialise SRAM buffer management
-+ dma_controller.sg_entry_head_ = 0;
-+ sema_init(&dma_controller.sg_entry_sem_, 0);
-+ dma_controller.sg_entry_available_ = 0;
-+
-+ tasklet_init(&dma_controller.tasklet_, dma_bh, 0);
-+
-+ // Discover the number of channels available
-+ intId = readl(DMA_CALC_REG_ADR(0, DMA_INTR_ID));
-+ dma_controller.numberOfChannels_ = DMA_INTR_ID_GET_NUM_CHANNELS(intId);
-+ if (dma_controller.numberOfChannels_ > MAX_OXNAS_DMA_CHANNELS) {
-+ printk(KERN_WARNING "DMA: Too many DMA channels");
-+ dma_controller.numberOfChannels_ = MAX_OXNAS_DMA_CHANNELS;
-+ }
-+
-+ dma_controller.version_ = DMA_INTR_ID_GET_VERSION(intId);
-+ printk(KERN_INFO "Number of DMA channels = %u, version = %u\n",
-+ dma_controller.numberOfChannels_, dma_controller.version_);
-+
-+ if (!DMA_HAS_V4_INTR_CLEAR(dma_controller.version_)) {
-+ panic("DMA: Trying to use v4+ interrupt clearing on DMAC version without support\n");
-+ }
-+
-+#ifdef CONFIG_LEON_RESERVE_DMA_CHANNEL
-+ // Reserve the last DMA channel for the CoPro's use
-+ --dma_controller.numberOfChannels_;
-+#endif // CONFIG_LEON_RESERVE_DMA_CHANNEL
-+
-+ // Allocate coherent memory for array sg_info structs
-+ dma_controller.v_sg_infos_ = (oxnas_dma_sg_info_t*)DMA_DESC_ALLOC_START;
-+ dma_controller.p_sg_infos_ = DMA_DESC_ALLOC_START_PA;
-+
-+ if (!dma_controller.v_sg_infos_) {
-+ panic("DMA: Coherent alloc of SG info struct array");
-+ }
-+
-+ {
-+ // Initialise list of DMA descriptors
-+ unsigned long sg_info_alloc_size = (dma_controller.numberOfChannels_ * sizeof(oxnas_dma_sg_info_t));
-+ unsigned num_sg_entries = (DMA_DESC_ALLOC_SIZE - sg_info_alloc_size) / sizeof(oxnas_dma_sg_entry_t);
-+ oxnas_dma_sg_entry_t* entry_v = (oxnas_dma_sg_entry_t*)(DMA_DESC_ALLOC_START + sg_info_alloc_size);
-+ oxnas_dma_sg_entry_t* entry_p = (oxnas_dma_sg_entry_t*)(DMA_DESC_ALLOC_START_PA + sg_info_alloc_size);
-+printk("Allocating %u SRAM generic DMA descriptors\n", num_sg_entries);
-+ for (i=0; i < num_sg_entries; ++i, ++entry_v, ++entry_p) {
-+ entry_v->paddr_ = (dma_addr_t)entry_p;
-+ free_sg_entry(entry_v);
-+ }
-+ }
-+
-+ // Initialise all available DMA channels
-+ v_info = dma_controller.v_sg_infos_;
-+ p_info = dma_controller.p_sg_infos_;
-+ for (i=0; i < dma_controller.numberOfChannels_; i++) {
-+ oxnas_dma_channel_t *channel = &dma_controller.channels_[i];
-+
-+ channel->channel_number_ = i;
-+ channel->notification_callback_ = OXNAS_DMA_CALLBACK_NUL;
-+ channel->notification_arg_ = OXNAS_DMA_CALLBACK_ARG_NUL;
-+
-+ // Setup physical and virtual addresses of the SG info struct for this
-+ // channel
-+ channel->v_sg_info_ = v_info++;
-+ channel->p_sg_info_ = p_info;
-+ p_info += sizeof(oxnas_dma_sg_info_t);
-+
-+ // Initialise heads of src and dst SG lists to null
-+ channel->v_sg_info_->p_srcEntries_ = 0;
-+ channel->v_sg_info_->p_dstEntries_ = 0;
-+ channel->v_sg_info_->v_srcEntries_ = 0;
-+ channel->v_sg_info_->v_dstEntries_ = 0;
-+
-+ channel->error_code_ = 0;
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ channel->checksumming_ = 0;
-+ channel->checksum_ = 0;
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+ // Initialise the atomic variable that records the number of interrupts
-+ // for the channel that are awaiting service
-+ atomic_set(&channel->interrupt_count_, 0);
-+
-+ // Initialise the atomic variable maintaining the count of in-progress
-+ // transfers for the channel. Currently can be a maximum of two, as
-+ // the hardware can only queue details for a pair of transfers
-+ atomic_set(&channel->active_count_, 0);
-+
-+ // The binary semaphore for the default callback used when abort
-+ // requested without a user-registered callback being available
-+ sema_init(&channel->default_semaphore_, 0);
-+
-+ // Add channel to free list
-+ oxnas_dma_free(channel);
-+ }
-+
-+ // Connect the dma interrupt handler
-+ dma_controller.channels_[0].rps_interrupt_ = DMA_INTERRUPT_0;
-+ if (request_irq(DMA_INTERRUPT_0, &oxnas_dma_interrupt, 0, "DMA 0", 0)) {
-+ panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_0);
-+ }
-+ dma_controller.channels_[1].rps_interrupt_ = DMA_INTERRUPT_1;
-+ if (request_irq(DMA_INTERRUPT_1, &oxnas_dma_interrupt, 0, "DMA 1", 0)) {
-+ panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_1);
-+ }
-+ dma_controller.channels_[2].rps_interrupt_ = DMA_INTERRUPT_2;
-+ if (request_irq(DMA_INTERRUPT_2, &oxnas_dma_interrupt, 0, "DMA 2", 0)) {
-+ panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_2);
-+ }
-+ dma_controller.channels_[3].rps_interrupt_ = DMA_INTERRUPT_3;
-+ if (request_irq(DMA_INTERRUPT_3, &oxnas_dma_interrupt, 0, "DMA 3", 0)) {
-+ panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_3);
-+ }
-+#ifndef CONFIG_LEON_RESERVE_DMA_CHANNEL
-+ dma_controller.channels_[4].rps_interrupt_ = DMA_INTERRUPT_4;
-+ if (request_irq(DMA_INTERRUPT_4, &oxnas_dma_interrupt, 0, "DMA 4", 0)) {
-+ panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_4);
-+ }
-+#endif // CONFIG_LEON_RESERVE_DMA_CHANNEL
-+
-+#ifdef OXNAS_DMA_OVERALL_TEST_LOOPS
-+ {
-+ int j;
-+ for (j=0; j < OXNAS_DMA_OVERALL_TEST_LOOPS; ++j) {
-+#ifdef OXNAS_DMA_TEST
-+ {
-+ int i;
-+ for (i=0; i < OXNAS_DMA_TEST_ITERATIONS; ++i) {
-+ dma_test(512);
-+ }
-+ }
-+#endif // OXNAS_DMA_TEST
-+#ifdef OXNAS_DMA_SG_TEST
-+ {
-+ int i;
-+ for (i=0; i < OXNAS_DMA_SG_TEST_ITERATIONS; ++i) {
-+ dma_sg_test();
-+ }
-+ }
-+#endif // OXNAS_DMA_SG_TEST
-+#ifdef OXNAS_DMA_SG_TEST_2
-+ {
-+ int i;
-+ for (i=0; i < OXNAS_DMA_SG_TEST_ITERATIONS; ++i) {
-+ dma_sg_test2();
-+ }
-+ }
-+#endif // OXNAS_DMA_SG_TEST_2
-+#ifdef OXNAS_DMA_TEST
-+ {
-+ int i;
-+ for (i=0; i < OXNAS_DMA_TEST_AFTER_SG_ITERATIONS; ++i) {
-+ dma_test(512);
-+ }
-+ }
-+#endif // OXNAS_DMA_TEST
-+ }
-+ }
-+#endif // OXNAS_DMA_OVERALL_TEST_LOOPS
-+}
-+
-+void oxnas_dma_shutdown()
-+{
-+ dma_controller.sg_entry_head_ = 0;
-+}
-+
-+int oxnas_dma_is_active(oxnas_dma_channel_t* channel)
-+{
-+ return atomic_read(&channel->active_count_);
-+}
-+
-+/**
-+ * Get the transfer status directly from the hardware, so for instance the
-+ * end of a transfer can be polled for within interrupt context.
-+ *
-+ * NB If this function indicates the channel is inactive, it does NOT imply that
-+ * it can be reused. Reuse is only possible when oxnas_dma_is_active() returns
-+ * the inactive state
-+ */
-+int oxnas_dma_raw_isactive(oxnas_dma_channel_t* channel)
-+{
-+ unsigned long ctrl_status = readl(DMA_CALC_REG_ADR(channel->channel_number_, DMA_CTRL_STATUS));
-+ return ctrl_status & DMA_CTRL_STATUS_IN_PROGRESS;
-+}
-+
-+/**
-+ * Get the SG transfer status directly from the hardware, so for instance the
-+ * end of a SG transfer can be polled for within interrupt context.
-+ *
-+ * NB If this function indicates the channel is inactive, it does NOT imply that
-+ * it can be reused. Reuse is only possible when oxnas_dma_is_active() returns
-+ * the inactive state
-+ */
-+int oxnas_dma_raw_sg_isactive(oxnas_dma_channel_t* channel)
-+{
-+ // Record the SG channel status
-+ u32 status = readl(DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_STATUS));
-+ return status & (1UL << DMA_SG_STATUS_BUSY_BIT);
-+}
-+
-+int oxnas_dma_get_raw_direction(oxnas_dma_channel_t* channel)
-+{
-+ unsigned long ctrl_status = readl(DMA_CALC_REG_ADR(channel->channel_number_, DMA_CTRL_STATUS));
-+ return (ctrl_status & DMA_CTRL_STATUS_DIR_MASK) >> DMA_CTRL_STATUS_DIR_SHIFT;
-+}
-+
-+static unsigned long encode_control_status(
-+ oxnas_dma_device_settings_t *src_settings,
-+ oxnas_dma_device_settings_t *dst_settings,
-+ int paused)
-+{
-+ unsigned long ctrl_status;
-+ oxnas_dma_transfer_direction_t direction;
-+
-+ ctrl_status = paused ? DMA_CTRL_STATUS_PAUSE : 0; // Paused if requested
-+ ctrl_status |= (DMA_CTRL_STATUS_INTERRUPT_ENABLE | // Interrupts enabled
-+ DMA_CTRL_STATUS_FAIR_SHARE_ARB | // High priority
-+ DMA_CTRL_STATUS_INTR_CLEAR_ENABLE); // Use new interrupt clearing register
-+ ctrl_status |= (src_settings->dreq_ << DMA_CTRL_STATUS_SRC_DREQ_SHIFT); // Source dreq
-+ ctrl_status |= (dst_settings->dreq_ << DMA_CTRL_STATUS_DEST_DREQ_SHIFT); // Destination dreq
-+
-+ // Setup the transfer direction and burst/single mode for the two DMA busses
-+ if (src_settings->bus_ == OXNAS_DMA_SIDE_A) {
-+ // Set the burst/single mode for bus A based on src device's settings
-+ if (src_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
-+ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_A;
-+ } else {
-+ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_A;
-+ }
-+
-+ if (dst_settings->bus_ == OXNAS_DMA_SIDE_A) {
-+ direction = OXNAS_DMA_A_TO_A;
-+ } else {
-+ direction = OXNAS_DMA_A_TO_B;
-+
-+ // Set the burst/single mode for bus B based on dst device's settings
-+ if (dst_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
-+ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_B;
-+ } else {
-+ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_B;
-+ }
-+ }
-+ } else {
-+ // Set the burst/single mode for bus B based on src device's settings
-+ if (src_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
-+ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_B;
-+ } else {
-+ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_B;
-+ }
-+
-+ if (dst_settings->bus_ == OXNAS_DMA_SIDE_A) {
-+ direction = OXNAS_DMA_B_TO_A;
-+
-+ // Set the burst/single mode for bus A based on dst device's settings
-+ if (dst_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
-+ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_A;
-+ } else {
-+ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_A;
-+ }
-+ } else {
-+ direction = OXNAS_DMA_B_TO_B;
-+ }
-+ }
-+ ctrl_status |= (direction << DMA_CTRL_STATUS_DIR_SHIFT);
-+
-+ // Setup source address mode fixed or increment
-+ if (src_settings->address_mode_ == OXNAS_DMA_MODE_FIXED) {
-+ // Fixed address
-+ ctrl_status &= ~(DMA_CTRL_STATUS_SRC_ADR_MODE);
-+
-+ // Set up whether fixed address is _really_ fixed
-+ if (src_settings->address_really_fixed_) {
-+ ctrl_status |= DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
-+ } else {
-+ ctrl_status &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
-+ }
-+ } else {
-+ // Incrementing address
-+ ctrl_status |= DMA_CTRL_STATUS_SRC_ADR_MODE;
-+ ctrl_status &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
-+ }
-+
-+ // Setup destination address mode fixed or increment
-+ if (dst_settings->address_mode_ == OXNAS_DMA_MODE_FIXED) {
-+ // Fixed address
-+ ctrl_status &= ~(DMA_CTRL_STATUS_DEST_ADR_MODE);
-+
-+ // Set up whether fixed address is _really_ fixed
-+ if (dst_settings->address_really_fixed_) {
-+ ctrl_status |= DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
-+ } else {
-+ ctrl_status &= ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
-+ }
-+ } else {
-+ // Incrementing address
-+ ctrl_status |= DMA_CTRL_STATUS_DEST_ADR_MODE;
-+ ctrl_status &= ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
-+ }
-+
-+ // Set up the width of the transfers on the DMA buses
-+ ctrl_status |= (src_settings->width_ << DMA_CTRL_STATUS_SRC_WIDTH_SHIFT);
-+ ctrl_status |= (dst_settings->width_ << DMA_CTRL_STATUS_DEST_WIDTH_SHIFT);
-+
-+ // Setup the priority arbitration scheme
-+ ctrl_status &= ~DMA_CTRL_STATUS_STARVE_LOW_PRIORITY; // !Starve low priority
-+
-+ return ctrl_status;
-+}
-+
-+static unsigned long encode_eot(
-+ oxnas_dma_device_settings_t* src_settings,
-+ oxnas_dma_device_settings_t* dst_settings,
-+ unsigned long length,
-+ int isFinalTransfer)
-+{
-+ // Write the length, with EOT configuration and enable INC4 tranfers and
-+ // HPROT. HPROT will delay data reaching memory for a few clock cycles, but
-+ // most unlikely to cause a problem for the CPU.
-+ unsigned long encoded = length |
-+ DMA_BYTE_CNT_INC4_SET_MASK | // Always enable INC4 transfers
-+ DMA_BYTE_CNT_HPROT_MASK; // Always enable HPROT assertion
-+
-+ // Encode the EOT setting for the src device based on its policy
-+ encoded &= ~DMA_BYTE_CNT_RD_EOT_MASK;
-+ switch (src_settings->read_eot_policy_) {
-+ case OXNAS_DMA_EOT_FINAL:
-+ if (!isFinalTransfer) {
-+ break;
-+ }
-+ // Fall through in case of final transfer and EOT required for final
-+ // transfer
-+ case OXNAS_DMA_EOT_ALL:
-+ encoded |= DMA_BYTE_CNT_RD_EOT_MASK;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ // Encode the EOT setting for the dst device based on its policy
-+ encoded &= ~DMA_BYTE_CNT_WR_EOT_MASK;
-+ switch (dst_settings->write_eot_policy_) {
-+ case OXNAS_DMA_EOT_FINAL:
-+ if (!isFinalTransfer) {
-+ break;
-+ }
-+ // Fall through in case of final transfer and EOT required for final
-+ // transfer
-+ case OXNAS_DMA_EOT_ALL:
-+ encoded |= DMA_BYTE_CNT_WR_EOT_MASK;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return encoded;
-+}
-+
-+static unsigned long encode_start(unsigned long ctrl_status)
-+{
-+ ctrl_status &= ~DMA_CTRL_STATUS_PAUSE;
-+ return ctrl_status;
-+}
-+
-+static void oxnas_dma_set_common_lowlevel(
-+ oxnas_dma_channel_t *channel,
-+ unsigned long ctrl_status,
-+ dma_addr_t src_address,
-+ dma_addr_t dst_address,
-+ unsigned long lengthAndEOT)
-+{
-+ unsigned channel_number = channel->channel_number_;
-+
-+ spin_lock(&dma_controller.spinlock_);
-+
-+ // Write the control/status value to the DMAC
-+ writel(ctrl_status, DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
-+
-+ // Ensure control/status word makes it to the DMAC before we write address/length info
-+ wmb();
-+
-+ // Write the source addresses to the DMAC
-+ writel(src_address, DMA_CALC_REG_ADR(channel_number, DMA_BASE_SRC_ADR));
-+
-+ // Write the destination addresses to the DMAC
-+ writel(dst_address, DMA_CALC_REG_ADR(channel_number, DMA_BASE_DST_ADR));
-+
-+ // Write the length, with EOT configuration for the single transfer
-+ writel(lengthAndEOT, DMA_CALC_REG_ADR(channel_number, DMA_BYTE_CNT));
-+
-+ // Ensure adr/len info makes it to DMAC before later modifications to
-+ // control/status register due to starting the transfer, which happens in
-+ // oxnas_dma_start()
-+ wmb();
-+
-+ spin_unlock(&dma_controller.spinlock_);
-+
-+ // Increase count of in-progress transfers on this channel
-+ atomic_inc(&channel->active_count_);
-+}
-+
-+static int oxnas_dma_set_common(
-+ oxnas_dma_channel_t* channel,
-+ unsigned long length,
-+ oxnas_dma_device_settings_t *src_settings,
-+ oxnas_dma_device_settings_t *dst_settings,
-+ int isFinalTransfer,
-+ int paused)
-+{
-+ int status = 0;
-+
-+ if (length > MAX_OXNAS_DMA_TRANSFER_LENGTH) {
-+ printk(KERN_WARNING "oxnas_dma_set_common() length exceeds hardware allowed maximum\n");
-+ status = 1;
-+ } else {
-+ oxnas_dma_set_common_lowlevel(
-+ channel,
-+ encode_control_status(src_settings, dst_settings, paused),
-+ (dma_addr_t)src_settings->address_,
-+ (dma_addr_t)dst_settings->address_,
-+ encode_eot(src_settings, dst_settings, length, isFinalTransfer));
-+ }
-+ return status;
-+}
-+
-+int oxnas_dma_set(
-+ oxnas_dma_channel_t *channel,
-+ unsigned char *src_adr, // Physical address
-+ unsigned long length,
-+ unsigned char *dst_adr, // Physical address
-+ oxnas_dma_mode_t src_mode,
-+ oxnas_dma_mode_t dst_mode,
-+ int do_checksum,
-+ int paused)
-+{
-+ if (oxnas_dma_is_active(channel)) {
-+ printk(KERN_WARNING "oxnas_dma_set() Trying to use channel %u while active\n", channel->channel_number_);
-+ }
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ if (do_checksum) {
-+ // Arbitrate for ownership of the checksum engine
-+ if (alloc_csum_engine()) {
-+ // Did not obtain the csum engine, so return will failure status
-+ return 1;
-+ }
-+ }
-+#else // CONFIG_OXNAS_VERSION_0X800
-+ BUG_ON(do_checksum);
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+ {
-+ // Assemble complete memory settings, accounting for csum generation if
-+ // required
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ oxnas_dma_device_settings_t src_settings =
-+ do_checksum ? oxnas_ram_csum_src_dma_settings :
-+ oxnas_ram_only_src_dma_settings;
-+#else // CONFIG_OXNAS_VERSION_0X800
-+ oxnas_dma_device_settings_t src_settings = oxnas_ram_only_src_dma_settings;
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+ oxnas_dma_device_settings_t dst_settings = oxnas_ram_generic_dma_settings;
-+
-+ // Assemble the source address
-+ src_settings.address_ = (unsigned long)src_adr;
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ if (do_checksum) {
-+ // Record that we are checksumming, so that the result is read on
-+ // completion
-+ channel->checksumming_ = 1;
-+
-+ // To checksum set the high order address bit to enable the engine
-+ src_settings.address_ |= (1UL << OXNAS_DMA_CSUM_ENABLE_ADR_BIT);
-+ }
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+ // Ensure only use the valid src address bits are used
-+ src_settings.address_ &= OXNAS_DMA_CSUM_ADR_MASK;
-+ src_settings.address_mode_ = src_mode;
-+
-+ // Ensure only use the valid dst address bits are used
-+ dst_settings.address_ = ((unsigned long)dst_adr) & OXNAS_DMA_ADR_MASK;
-+ dst_settings.address_mode_ = dst_mode;
-+
-+ return oxnas_dma_set_common(channel, length, &src_settings, &dst_settings, 1, paused);
-+ }
-+}
-+
-+int oxnas_dma_device_set(
-+ oxnas_dma_channel_t *channel,
-+ oxnas_dma_direction_t direction,
-+ unsigned char *mem_adr, // Physical address
-+ unsigned long length,
-+ oxnas_dma_device_settings_t *device_settings,
-+ oxnas_dma_mode_t mem_mode,
-+ int paused)
-+{
-+ oxnas_dma_device_settings_t mem_settings;
-+
-+ if (oxnas_dma_is_active(channel)) {
-+ printk(KERN_WARNING "oxnas_dma_device_set() Trying to use channel %u while active\n", channel->channel_number_);
-+ }
-+
-+ // Assemble complete memory settings, ensuring addresses do not affect the
-+ // checksum enabling high order adr bit
-+ mem_settings = oxnas_ram_generic_dma_settings;
-+ mem_settings.address_ = ((unsigned long)mem_adr) & OXNAS_DMA_ADR_MASK;
-+ mem_settings.address_mode_ = mem_mode;
-+
-+ device_settings->address_ &= OXNAS_DMA_ADR_MASK;
-+
-+ return oxnas_dma_set_common(
-+ channel,
-+ length,
-+ (direction == OXNAS_DMA_TO_DEVICE) ? &mem_settings : device_settings,
-+ (direction == OXNAS_DMA_FROM_DEVICE) ? &mem_settings : device_settings,
-+ 1,
-+ paused);
-+}
-+
-+int oxnas_dma_device_pair_set(
-+ oxnas_dma_channel_t* channel,
-+ unsigned long length,
-+ oxnas_dma_device_settings_t *src_device_settings,
-+ oxnas_dma_device_settings_t *dst_device_settings,
-+ int paused)
-+{
-+ if (oxnas_dma_is_active(channel)) {
-+ printk(KERN_WARNING "oxnas_dma_device_pair_set() Trying to use channel %u while active\n", channel->channel_number_);
-+ }
-+
-+ // Ensure addresses do not affect the checksum enabling high order adr bit
-+ src_device_settings->address_ &= OXNAS_DMA_ADR_MASK;
-+ dst_device_settings->address_ &= OXNAS_DMA_ADR_MASK;
-+ return oxnas_dma_set_common(channel, length, src_device_settings, dst_device_settings, 1, paused);
-+}
-+
-+static int oxnas_dma_set_sg_common(
-+ oxnas_dma_channel_t* channel,
-+ struct scatterlist* src_sg,
-+ unsigned src_sg_count,
-+ struct scatterlist* dst_sg,
-+ unsigned dst_sg_count,
-+ oxnas_dma_device_settings_t* src_settings,
-+ oxnas_dma_device_settings_t* dst_settings,
-+ int in_atomic)
-+{
-+ int i;
-+ int failed = 0;
-+ oxnas_dma_sg_entry_t *sg_entry;
-+ oxnas_dma_sg_entry_t *previous_entry;
-+
-+ // Get reference to this channel's top level SG DMA descriptor structure
-+ oxnas_dma_sg_info_t *sg_info = channel->v_sg_info_;
-+
-+ // SG entries have not been provided
-+ channel->auto_sg_entries_ = 1;
-+
-+ // Initialise list pointers to zero
-+ sg_info->v_srcEntries_ = 0;
-+ sg_info->p_srcEntries_ = 0;
-+ sg_info->v_dstEntries_ = 0;
-+ sg_info->p_dstEntries_ = 0;
-+
-+ sg_entry = 0;
-+ previous_entry = 0;
-+ for (i=0; i < src_sg_count; i++) {
-+ // Is this entry contiguous with the previous one and would the combined
-+ // lengths not exceed the maximum that the hardware is capable of
-+#if 0
-+ if (previous_entry &&
-+ ((previous_entry->addr_ + previous_entry->length_) == (src_sg[i].dma_address & OXNAS_DMA_CSUM_ADR_MASK)) &&
-+ ((previous_entry->length_ + src_sg[i].length) <= MAX_OXNAS_DMA_TRANSFER_LENGTH)) {
-+ // Yes, so coalesce the pair
-+ previous_entry->length_ += src_sg[i].length;
-+ } else
-+#endif
-+ {
-+ // Allocate space for SG list entry from coherent DMA pool
-+ oxnas_dma_sg_entry_t *new_sg_entry = alloc_sg_entry(in_atomic);
-+ if (!new_sg_entry) {
-+ failed = 1;
-+ break;
-+ }
-+ sg_entry = new_sg_entry;
-+
-+ if (previous_entry) {
-+ // Link the previous SG list entry forward to this one
-+ previous_entry->v_next_ = sg_entry;
-+ previous_entry->p_next_ = sg_entry->paddr_;
-+ } else {
-+ // Create a link from the SG info structure to the first SG list entry
-+ sg_info->v_srcEntries_ = sg_entry;
-+ sg_info->p_srcEntries_ = sg_entry->paddr_;
-+ }
-+ previous_entry = sg_entry;
-+
-+ // Fill in the SG list entry with start address, ensuring only valid
-+ // address bits are used, preserving the checksum enabling flag
-+ sg_entry->addr_ = src_sg[i].dma_address & OXNAS_DMA_CSUM_ADR_MASK;
-+
-+ // Fill in the length, checking that it does not exceed the hardware
-+ // allowed maximum
-+ sg_entry->length_ = (src_sg[i].length <= MAX_OXNAS_DMA_TRANSFER_LENGTH) ? src_sg[i].length : 0;
-+ if (!sg_entry->length_) {
-+ printk(KERN_WARNING "oxnas_dma_set_sg_common() Source entry too long, zeroing\n");
-+ }
-+ }
-+ }
-+ if (sg_entry) {
-+ // Mark the end of the source SG list with nulls
-+ sg_entry->p_next_ = 0;
-+ sg_entry->v_next_ = 0;
-+ }
-+
-+ if (failed) {
-+ // Failed to allocate all SG src entries, so free those we did get
-+ oxnas_dma_sg_entry_t* sg_entry = sg_info->v_srcEntries_;
-+ while (sg_entry) {
-+ oxnas_dma_sg_entry_t* next = sg_entry->v_next_;
-+ free_sg_entry(sg_entry);
-+ sg_entry = next;
-+ }
-+ channel->v_sg_info_->p_srcEntries_ = 0;
-+ channel->v_sg_info_->v_srcEntries_ = 0;
-+ return 1;
-+ }
-+
-+ // Assemble destination descriptors
-+ sg_entry = 0;
-+ previous_entry = 0;
-+ for (i=0; i < dst_sg_count; i++) {
-+ // Is this entry contiguous with the previous one?
-+#if 0
-+ if (previous_entry &&
-+ ((previous_entry->addr_ + previous_entry->length_) == (dst_sg[i].dma_address & OXNAS_DMA_CSUM_ADR_MASK)) &&
-+ ((previous_entry->length_ + dst_sg[i].length) <= MAX_OXNAS_DMA_TRANSFER_LENGTH)) {
-+ // Yes, so coalesce the pair
-+ previous_entry->length_ += dst_sg[i].length;
-+ } else
-+#endif
-+ {
-+ // Allocate space for SG list entry from coherent DMA pool
-+ oxnas_dma_sg_entry_t *new_sg_entry = alloc_sg_entry(in_atomic);
-+ if (!new_sg_entry) {
-+ failed = 1;
-+ break;
-+ }
-+ sg_entry = new_sg_entry;
-+
-+ if (previous_entry) {
-+ // Link the previous SG list entry forward to this one
-+ previous_entry->v_next_ = sg_entry;
-+ previous_entry->p_next_ = sg_entry->paddr_;
-+ } else {
-+ // Create a link from the SG info structure to the first SG list entry
-+ sg_info->v_dstEntries_ = sg_entry;
-+ sg_info->p_dstEntries_ = sg_entry->paddr_;
-+ }
-+ previous_entry = sg_entry;
-+
-+ // Fill in the SG list entry with start address, ensuring address
-+ // does not affect the checksum enabling high order adr bit
-+ sg_entry->addr_ = dst_sg[i].dma_address & OXNAS_DMA_ADR_MASK;
-+
-+ // Fill in the length, checking that it does not exceed the hardware
-+ // allowed maximum
-+ sg_entry->length_ = (dst_sg[i].length <= MAX_OXNAS_DMA_TRANSFER_LENGTH) ? dst_sg[i].length : 0;
-+ if (!sg_entry->length_) {
-+ printk(KERN_WARNING "oxnas_dma_set_sg_common() Destination entry too long, zeroing\n");
-+ }
-+ }
-+ }
-+ if (sg_entry) {
-+ // Mark the end of the destination SG list with nulls
-+ sg_entry->p_next_ = 0;
-+ sg_entry->v_next_ = 0;
-+ }
-+
-+ if (failed) {
-+ // Failed to allocate all SG dst entries, so free those we did obtain
-+ oxnas_dma_sg_entry_t* sg_entry = sg_info->v_dstEntries_;
-+ while (sg_entry) {
-+ oxnas_dma_sg_entry_t* next = sg_entry->v_next_;
-+ free_sg_entry(sg_entry);
-+ sg_entry = next;
-+ }
-+ sg_info->p_dstEntries_ = 0;
-+ sg_info->v_dstEntries_ = 0;
-+
-+ // Free all the SG src entries which we did sucessfully obtain
-+ sg_entry = sg_info->v_srcEntries_;
-+ while (sg_entry) {
-+ oxnas_dma_sg_entry_t* next = sg_entry->v_next_;
-+ free_sg_entry(sg_entry);
-+ sg_entry = next;
-+ }
-+ sg_info->p_srcEntries_ = 0;
-+ sg_info->v_srcEntries_ = 0;
-+ return 1;
-+ }
-+
-+ sg_info->qualifer_ = ((channel->channel_number_ << OXNAS_DMA_SG_CHANNEL_BIT) |
-+ (src_settings->read_eot_policy_ << OXNAS_DMA_SG_SRC_EOT_BIT) |
-+ (dst_settings->write_eot_policy_ << OXNAS_DMA_SG_DST_EOT_BIT) |
-+ (1 << OXNAS_DMA_SG_QUALIFIER_BIT));
-+
-+ // Flags are the same for source and destination for each SG transfer component
-+ sg_info->control_ = encode_control_status(src_settings, dst_settings, 0);
-+
-+ // Increase count of in-progress transfers on this channel
-+ atomic_inc(&channel->active_count_);
-+
-+ return 0;
-+}
-+
-+int oxnas_dma_set_sg(
-+ oxnas_dma_channel_t* channel,
-+ struct scatterlist* src_sg,
-+ unsigned src_sg_count,
-+ struct scatterlist* dst_sg,
-+ unsigned dst_sg_count,
-+ oxnas_dma_mode_t src_mode,
-+ oxnas_dma_mode_t dst_mode,
-+ int do_checksum,
-+ int in_atomic)
-+{
-+ if (oxnas_dma_is_active(channel)) {
-+ printk(KERN_WARNING "oxnas_dma_set_sg() Trying to use channel %u while active\n", channel->channel_number_);
-+ }
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ if (do_checksum) {
-+ // Arbitrate for ownership of the checksum engine
-+ if (alloc_csum_engine()) {
-+ // Failed to obtain csum engine, so return with failure status
-+ return 1;
-+ }
-+ }
-+#else // CONFIG_OXNAS_VERSION_0X800
-+ BUG_ON(do_checksum);
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+ {
-+ // Assemble complete memory settings, accounting for csum generation if
-+ // required
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ oxnas_dma_device_settings_t src_settings =
-+ do_checksum ? oxnas_ram_csum_src_dma_settings :
-+ oxnas_ram_only_src_dma_settings;
-+#else // CONFIG_OXNAS_VERSION_0X800
-+ oxnas_dma_device_settings_t src_settings = oxnas_ram_only_src_dma_settings;
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+ oxnas_dma_device_settings_t dst_settings = oxnas_ram_generic_dma_settings;
-+
-+ // Normal adr bits not used for SG transfers
-+ src_settings.address_ = 0;
-+ src_settings.address_mode_ = src_mode;
-+
-+ // Normal adr bits not used for SG transfers
-+ dst_settings.address_ = 0;
-+ dst_settings.address_mode_ = dst_mode;
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ if (do_checksum) {
-+ // Record that we are checksumming, so that the result is read on
-+ // completion
-+ channel->checksumming_ = 1;
-+
-+ // The high order address bit enabling the checksum engine will be
-+ // set by the caller in the passed scatterlist entries, for those
-+ // entries which are required to contribute to the checksum
-+ // calculation
-+ }
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+ return oxnas_dma_set_sg_common(
-+ channel,
-+ src_sg,
-+ src_sg_count,
-+ dst_sg,
-+ dst_sg_count,
-+ &src_settings,
-+ &dst_settings,
-+ in_atomic);
-+ }
-+}
-+
-+int oxnas_dma_device_set_sg(
-+ oxnas_dma_channel_t* channel,
-+ oxnas_dma_direction_t direction,
-+ struct scatterlist* mem_sg,
-+ unsigned mem_sg_count,
-+ oxnas_dma_device_settings_t* device_settings,
-+ oxnas_dma_mode_t mem_mode,
-+ int in_atomic)
-+{
-+ int i;
-+ struct scatterlist *sg;
-+ struct scatterlist dev_sg;
-+
-+ oxnas_dma_device_settings_t mem_settings;
-+
-+ if (oxnas_dma_is_active(channel)) {
-+ printk(KERN_WARNING "oxnas_dma_device_set_sg() Trying to use channel %u while active\n", channel->channel_number_);
-+ }
-+
-+ // Assemble complete memory settings
-+ mem_settings = oxnas_ram_generic_dma_settings;
-+ mem_settings.address_ = 0; // Not used for SG transfers
-+ mem_settings.address_mode_ = mem_mode;
-+
-+ // Need to total all memory transfer lengths and assign as device single transfer length
-+ dev_sg.dma_address = device_settings->address_;
-+ for (i=0, sg=mem_sg, dev_sg.length = 0; i < mem_sg_count; i++, sg++) {
-+ dev_sg.length += sg->length;
-+ }
-+
-+ return oxnas_dma_set_sg_common(
-+ channel,
-+ (direction == OXNAS_DMA_TO_DEVICE) ? mem_sg : &dev_sg,
-+ (direction == OXNAS_DMA_TO_DEVICE) ? mem_sg_count : 1,
-+ (direction == OXNAS_DMA_FROM_DEVICE) ? mem_sg : &dev_sg,
-+ (direction == OXNAS_DMA_FROM_DEVICE) ? mem_sg_count : 1,
-+ (direction == OXNAS_DMA_TO_DEVICE) ? &mem_settings : device_settings,
-+ (direction == OXNAS_DMA_FROM_DEVICE) ? &mem_settings : device_settings,
-+ in_atomic);
-+}
-+
-+static int oxnas_dma_set_prd_common(
-+ oxnas_dma_channel_t *channel,
-+ struct ata_prd *src_prd,
-+ struct ata_prd *dst_prd,
-+ oxnas_dma_device_settings_t *src_settings,
-+ oxnas_dma_device_settings_t *dst_settings,
-+ oxnas_dma_sg_entry_t *sg_entries)
-+{
-+ int i;
-+ int failed = 0;
-+ oxnas_dma_sg_entry_t *sg_entry, *previous_entry, *next_entry;
-+ u32 eot;
-+ u32 tot_src_len = 0, tot_dst_len = 0;
-+
-+ // Get reference to this channel's top level SG DMA descriptor structure
-+ oxnas_dma_sg_info_t *sg_info = channel->v_sg_info_;
-+
-+ // SG entries have been provided
-+ channel->auto_sg_entries_ = 0;
-+
-+ // Initialise list pointers to zero
-+ sg_info->v_srcEntries_ = 0;
-+ sg_info->p_srcEntries_ = 0;
-+ sg_info->v_dstEntries_ = 0;
-+ sg_info->p_dstEntries_ = 0;
-+
-+ // Get pointer to first available SG entry
-+ sg_entry = previous_entry = 0;
-+ next_entry = sg_entries;
-+ i=0;
-+ do {
-+ u32 addr;
-+ u32 length;
-+ u32 flags_len;
-+
-+ addr = src_prd[i].addr;
-+ flags_len = le32_to_cpu(src_prd[i++].flags_len);
-+ length = flags_len & ~ATA_PRD_EOT;
-+ eot = flags_len & ATA_PRD_EOT;
-+
-+ // Zero length field means 64KB
-+ if (!length) length = 0x10000;
-+
-+ // Accumulate the total length of all source elements
-+ tot_src_len += length;
-+
-+ // Is this entry contiguous with the previous one and would the combined
-+ // lengths not exceed the maximum that the hardware is capable of
-+#if 0
-+ if (previous_entry &&
-+ ((previous_entry->addr_ + previous_entry->length_) == (addr & OXNAS_DMA_CSUM_ADR_MASK)) &&
-+ ((previous_entry->length_ + length) <= MAX_OXNAS_DMA_TRANSFER_LENGTH)) {
-+ // Yes, so coalesce the pair
-+ previous_entry->length_ += length;
-+ } else
-+#endif
-+ {
-+ // Get the next available SG entry
-+ if (!next_entry) {
-+ failed = 1;
-+ break;
-+ }
-+ sg_entry = next_entry;
-+
-+ if (previous_entry) {
-+ // Link the previous SG list entry forward to this one
-+ previous_entry->v_next_ = sg_entry;
-+ previous_entry->p_next_ = sg_entry->paddr_;
-+ } else {
-+ // Create a link from the SG info structure to the first SG list entry
-+ sg_info->v_srcEntries_ = sg_entry;
-+ sg_info->p_srcEntries_ = sg_entry->paddr_;
-+ }
-+ previous_entry = sg_entry;
-+
-+ // Fill in the SG list entry with start address, ensuring only valid
-+ // address bits are used, preserving the checksum enabling flag
-+ sg_entry->addr_ = addr & OXNAS_DMA_CSUM_ADR_MASK;
-+
-+ // Fill in the length, checking that it does not exceed the hardware
-+ // allowed maximum
-+ if (length > MAX_OXNAS_DMA_TRANSFER_LENGTH) {
-+ printk(KERN_WARNING "oxnas_dma_set_prd_common() Source entry too long (0x%x), zeroing\n", length);
-+ sg_entry->length_ = 0;
-+ } else {
-+ sg_entry->length_ = length;
-+ }
-+
-+ // Get pointer to next available SG entry
-+ next_entry = sg_entry->next_;
-+ }
-+ } while (!eot);
-+ if (sg_entry) {
-+ // Mark the end of the source SG list with nulls
-+ sg_entry->p_next_ = 0;
-+ sg_entry->v_next_ = 0;
-+ }
-+
-+ if (failed) {
-+ // Failed to allocate all SG src entries
-+ channel->v_sg_info_->p_srcEntries_ = 0;
-+ channel->v_sg_info_->v_srcEntries_ = 0;
-+ printk(KERN_WARNING "Too few SG entries to satisfy source requirements\n");
-+ return 1;
-+ }
-+
-+ // Assemble destination descriptors
-+ sg_entry = previous_entry = 0;
-+ i=0;
-+ do {
-+ u32 addr;
-+ u32 length;
-+ u32 flags_len;
-+
-+ addr = dst_prd[i].addr;
-+ flags_len = le32_to_cpu(dst_prd[i++].flags_len);
-+ length = flags_len & ~ATA_PRD_EOT;
-+ eot = flags_len & ATA_PRD_EOT;
-+
-+ // Zero length field means 64KB
-+ if (!length) length = 0x10000;
-+
-+ // Accumulate the total length of all destination elements
-+ tot_dst_len += length;
-+
-+ // Is this entry contiguous with the previous one?
-+#if 0
-+ if (previous_entry &&
-+ ((previous_entry->addr_ + previous_entry->length_) == (addr & OXNAS_DMA_CSUM_ADR_MASK)) &&
-+ ((previous_entry->length_ + length) <= MAX_OXNAS_DMA_TRANSFER_LENGTH)) {
-+ // Yes, so coalesce the pair
-+ previous_entry->length_ += length;
-+ } else
-+#endif
-+ {
-+ // Get the next available SG entry
-+ if (!next_entry) {
-+ failed = 1;
-+ break;
-+ }
-+ sg_entry = next_entry;
-+
-+ if (previous_entry) {
-+ // Link the previous SG list entry forward to this one
-+ previous_entry->v_next_ = sg_entry;
-+ previous_entry->p_next_ = sg_entry->paddr_;
-+ } else {
-+ // Create a link from the SG info structure to the first SG list entry
-+ sg_info->v_dstEntries_ = sg_entry;
-+ sg_info->p_dstEntries_ = sg_entry->paddr_;
-+ }
-+ previous_entry = sg_entry;
-+
-+ // Fill in the SG list entry with start address, ensuring address
-+ // does not affect the checksum enabling high order adr bit
-+ sg_entry->addr_ = addr & OXNAS_DMA_ADR_MASK;
-+
-+ // Fill in the length, checking that it does not exceed the hardware
-+ // allowed maximum
-+ if (length > MAX_OXNAS_DMA_TRANSFER_LENGTH) {
-+ printk(KERN_WARNING "oxnas_dma_set_prd_common() Destination entry too long (0x%x), zeroing\n", length);
-+ sg_entry->length_ = 0;
-+ } else {
-+ sg_entry->length_ = length;
-+ }
-+
-+ // Get pointer to next available SG entry
-+ next_entry = sg_entry->next_;
-+ }
-+ } while (!eot);
-+ if (sg_entry) {
-+ // Mark the end of the destination SG list with nulls
-+ sg_entry->p_next_ = 0;
-+ sg_entry->v_next_ = 0;
-+ }
-+
-+ if (failed) {
-+ // Failed to allocate all SG dst entries
-+ sg_info->p_dstEntries_ = 0;
-+ sg_info->v_dstEntries_ = 0;
-+ sg_info->p_srcEntries_ = 0;
-+ sg_info->v_srcEntries_ = 0;
-+ printk(KERN_WARNING "Too few SG entries to satisfy destination requirements\n");
-+ return 1;
-+ }
-+
-+ // Fill in length of single device SG entry from the total length of all the
-+ // memory SG entries
-+ if ((sg_entry = sg_info->v_srcEntries_) && !sg_entry->v_next_) {
-+ sg_entry->length_ = tot_dst_len;
-+ } else if ((sg_entry = sg_info->v_dstEntries_) && !sg_entry->v_next_) {
-+ sg_entry->length_ = tot_src_len;
-+ }
-+
-+ sg_info->qualifer_ = ((channel->channel_number_ << OXNAS_DMA_SG_CHANNEL_BIT) |
-+ (src_settings->read_eot_policy_ << OXNAS_DMA_SG_SRC_EOT_BIT) |
-+ (dst_settings->write_eot_policy_ << OXNAS_DMA_SG_DST_EOT_BIT) |
-+ (1 << OXNAS_DMA_SG_QUALIFIER_BIT));
-+
-+ // Flags are the same for source and destination for each SG transfer component
-+ sg_info->control_ = encode_control_status(src_settings, dst_settings, 0);
-+
-+ // Increase count of in-progress transfers on this channel
-+ atomic_inc(&channel->active_count_);
-+
-+ return 0;
-+}
-+
-+int oxnas_dma_device_set_prd(
-+ oxnas_dma_channel_t *channel,
-+ oxnas_dma_direction_t direction,
-+ struct ata_prd *mem_prd,
-+ oxnas_dma_device_settings_t *device_settings,
-+ oxnas_dma_mode_t mem_mode,
-+ oxnas_dma_sg_entry_t *sg_entries)
-+{
-+ struct ata_prd dev_prd;
-+ oxnas_dma_device_settings_t mem_settings;
-+
-+ if (unlikely(oxnas_dma_is_active(channel))) {
-+ printk(KERN_WARNING "oxnas_dma_device_set_prd() Trying to use channel %u while active\n", channel->channel_number_);
-+ }
-+
-+ // Assemble complete memory settings
-+ mem_settings = oxnas_ram_generic_dma_settings;
-+ mem_settings.address_ = 0; // Not used for SG transfers
-+ mem_settings.address_mode_ = mem_mode;
-+
-+ // Device has only a single SG entry whose length will be assigned once
-+ // all the memory transfer lengths have been accumulated
-+ dev_prd.addr = device_settings->address_;
-+ dev_prd.flags_len = ATA_PRD_EOT;
-+
-+ return oxnas_dma_set_prd_common(
-+ channel,
-+ (direction == OXNAS_DMA_TO_DEVICE) ? mem_prd : &dev_prd,
-+ (direction == OXNAS_DMA_FROM_DEVICE) ? mem_prd : &dev_prd,
-+ (direction == OXNAS_DMA_TO_DEVICE) ? &mem_settings : device_settings,
-+ (direction == OXNAS_DMA_FROM_DEVICE) ? &mem_settings : device_settings,
-+ sg_entries);
-+}
-+
-+void oxnas_dma_set_callback(oxnas_dma_channel_t* channel, oxnas_dma_callback_t callback, oxnas_callback_arg_t arg)
-+{
-+#if defined(OXNAS_DMA_TEST) || defined(OXNAS_DMA_SG_TEST)
-+printk("Registering callback 0x%08x for channel %u\n", (unsigned)callback, channel->channel_number_);
-+#endif // defined(OXNAS_DMA_TEST) || defined(OXNAS_DMA_SG_TEST)
-+ channel->notification_callback_ = callback;
-+ channel->notification_arg_ = arg;
-+}
-+
-+static void default_callback(
-+ oxnas_dma_channel_t* channel,
-+ oxnas_callback_arg_t arg,
-+ oxnas_dma_callback_status_t status,
-+ u16 checksum,
-+ int interrupt_count)
-+{
-+ up(&channel->default_semaphore_);
-+}
-+
-+void oxnas_dma_abort(
-+ oxnas_dma_channel_t *channel,
-+ int in_atomic)
-+{
-+ u32 ctrl_status;
-+ unsigned channel_number = channel->channel_number_;
-+ int must_wait = 0;
-+ int callback_registered = 0;
-+
-+ // Assert reset for the channel
-+ spin_lock(&dma_controller.spinlock_);
-+ ctrl_status = readl(DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
-+ ctrl_status |= DMA_CTRL_STATUS_RESET;
-+ writel(ctrl_status, DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
-+ spin_unlock(&dma_controller.spinlock_);
-+
-+ // Wait for the channel to become idle - should be quick as should finish
-+ // after the next AHB single or burst transfer
-+ while (readl(DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS)) & DMA_CTRL_STATUS_IN_PROGRESS);
-+
-+ // Deassert reset for the channel
-+ spin_lock(&dma_controller.spinlock_);
-+ ctrl_status = readl(DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
-+ ctrl_status &= ~DMA_CTRL_STATUS_RESET;
-+ writel(ctrl_status, DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
-+ spin_unlock(&dma_controller.spinlock_);
-+
-+ // If no user callback is registered, we need to wait here for the DMA
-+ // channel to become inactive, i.e. for the ISR to be called and the
-+ // channel software returned to the idle state
-+ if (channel->notification_callback_ == OXNAS_DMA_CALLBACK_NUL) {
-+ must_wait = 1;
-+ if (!in_atomic) {
-+ // If the callers is not calling us from atomic context we can
-+ // register our own callback and sleep until it is invoked
-+ oxnas_dma_set_callback(channel, default_callback, OXNAS_DMA_CALLBACK_ARG_NUL);
-+ callback_registered = 1;
-+ }
-+ }
-+
-+ // Fake an interrupt to cause the channel to be cleaned up by running the
-+ // DMA bottom half tasklet
-+ fake_interrupt(channel_number);
-+
-+ if (must_wait) {
-+ if (callback_registered) {
-+ // Sleep until the channel becomes inactive
-+ down_interruptible(&channel->default_semaphore_);
-+
-+ // Deregister the callback
-+ oxnas_dma_set_callback(channel, OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
-+ } else {
-+ // If we reach here we are in an atomic context and thus must not do
-+ // anything that might cause us to sleep
-+ // NB. Possible problem here if we're atomic because someone has
-+ // called spin_lock_bh(); I'm concerned that calling do_softirq()
-+ // under these circumstances might cause issues, althought the net-
-+ // working code calls do_softirq() and doesn't appear to worry
-+ if (local_softirq_pending()) {
-+ // If an interrupt has not arrived and caused the tasklet to
-+ // have been run already, cause it to run now.
-+ do_softirq();
-+ }
-+
-+ // The tasklet should have run by this point and cleaned up the channel
-+ BUG_ON(oxnas_dma_is_active(channel));
-+ }
-+ }
-+}
-+
-+void oxnas_dma_start(oxnas_dma_channel_t* channel)
-+{
-+ // Are there SG lists setup for this channel?
-+ if (channel->v_sg_info_->v_srcEntries_) {
-+#ifdef OXNAS_DMA_SG_TEST_DUMP_DESCRIPTORS
-+ // Print the desciptor contents for debugging
-+ oxnas_dma_sg_entry_t* d = channel->v_sg_info_->v_srcEntries_;
-+ printk("qualifer_ = 0x%08lx, control_ = 0x%lx\n", channel->v_sg_info_->qualifer_, channel->v_sg_info_->control_);
-+ printk("Source Descriptors:\n");
-+ while (d) {
-+ printk("v_addr=0x%08x, p_addr=0x%08x, addr_=0x%08x, length_=0x%08lx, next=0x%08x\n", (u32)d, (u32)d->paddr_, d->addr_, d->length_, d->p_next_);
-+ d = d->v_next_;
-+ }
-+ printk("Destination Descriptors:\n");
-+ d = channel->v_sg_info_->v_dstEntries_;
-+ while (d) {
-+ printk("v_addr=0x%08x, p_addr=0x%08x, addr_=0x%08x, length_=0x%08lx, next=0x%08x\n", (u32)d, (u32)d->paddr_, d->addr_, d->length_, d->p_next_);
-+ d = d->v_next_;
-+ }
-+#endif // OXNAS_DMA_SG_TEST_DUMP_DESCRIPTORS
-+
-+ // Write to the SG-DMA channel's reset register to reset the control
-+ // in case the previous SG-DMA transfer failed in some way, thus
-+ // leaving the SG-DMA controller hung up part way through processing
-+ // its SG list. The reset bits are self-clearing
-+ writel(1UL << DMA_SG_RESETS_CONTROL_BIT, DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_RESETS));
-+
-+ // Write the pointer to the SG info struct into the Request Pointer reg.
-+ writel(channel->p_sg_info_, DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_REQ_PTR));
-+
-+#ifdef OXNAS_DMA_SG_TEST
-+printk("p_sg_info_ = 0x%08x written to 0x%08x\n", (u32)channel->p_sg_info_, DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_REQ_PTR));
-+printk("*(DMA_SG_CONTROL) = 0x%08x\n", readl(DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_CONTROL)));
-+printk("*(DMA_SG_STATUS) = 0x%08x\n", readl(DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_STATUS)));
-+printk("*(DMA_SG_REQ_PTR) = 0x%08x\n", readl(DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_REQ_PTR)));
-+#endif // OXNAS_DMA_SG_TEST
-+
-+ // Start the transfer
-+ writel((1UL << DMA_SG_CONTROL_START_BIT) |
-+ (1UL << DMA_SG_CONTROL_QUEUING_ENABLE_BIT) |
-+ (1UL << DMA_SG_CONTROL_HBURST_ENABLE_BIT),
-+ DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_CONTROL));
-+ } else {
-+ // Single transfer mode, so unpause the DMA controller channel
-+ spin_lock(&dma_controller.spinlock_);
-+ writel(encode_start(readl(DMA_CALC_REG_ADR(channel->channel_number_, DMA_CTRL_STATUS))),
-+ DMA_CALC_REG_ADR(channel->channel_number_, DMA_CTRL_STATUS));
-+ spin_unlock(&dma_controller.spinlock_);
-+ }
-+}
-+
-+void oxnas_dma_dump_registers()
-+{
-+ unsigned long* adr = (unsigned long*)DMA_CALC_REG_ADR(0, 0);
-+ unsigned long* end = (adr + DMA_REGS_PER_CHANNEL);
-+ int i;
-+
-+ printk("oxnas_dma_dump_registers(), adr= 0x%08lx, end=0x%08lx\n", (unsigned long)adr, (unsigned long)(adr + (DMA_REGS_PER_CHANNEL * dma_controller.numberOfChannels_)));
-+
-+ for (i=0; i < dma_controller.numberOfChannels_; i++) {
-+ for (; adr < end; adr++) {
-+ printk("0x%08lx\n", *adr);
-+ }
-+ printk("SG-Debug: 0x%08x\n", readl(DMA_SG_CALC_REG_ADR(i, DMA_SG_RESETS)));
-+ printk("-----------------------\n");
-+ end += DMA_REGS_PER_CHANNEL;
-+ }
-+ printk("oxnas_dma_dump_registers() - end\n");
-+}
-+
-+void oxnas_dma_dump_registers_single(int channel_number)
-+{
-+ unsigned long* adr = (unsigned long*)DMA_CALC_REG_ADR(channel_number, 0);
-+ unsigned long* end = (adr + DMA_REGS_PER_CHANNEL);
-+
-+ printk("DMA channel %d regs:\n", channel_number);
-+ for (; adr < end; adr++) {
-+ printk("0x%08lx\n", *adr);
-+ }
-+}
-+
-+#if defined(OXNAS_DMA_TEST) || defined(OXNAS_DMA_SG_TEST)
-+static __DECLARE_SEMAPHORE_GENERIC(callback_semaphore, 0); // Binary semaphore for testing
-+
-+static void dma_callback(
-+ oxnas_dma_channel_t *channel,
-+ oxnas_callback_arg_t arg,
-+ oxnas_dma_callback_status_t error_code,
-+ u16 checksum,
-+ int interrupt_count)
-+{
-+ printk("dma_callback() for channel %u, arg = 0x%lx, status = 0x%04x, checksum = 0x%04hx, interrupt_count = %d\n", channel->channel_number_, (unsigned long)arg, error_code, checksum, interrupt_count);
-+ up(&callback_semaphore);
-+}
-+
-+#include <linux/dma-mapping.h>
-+#include <linux/slab.h>
-+
-+#ifdef OXNAS_DMA_TEST
-+static void dma_test(unsigned long length)
-+{
-+ void* memory1;
-+ void* memory2;
-+ unsigned long* ptr;
-+ unsigned long quads;
-+ int i;
-+ unsigned long* end;
-+ dma_addr_t dma_address1;
-+ dma_addr_t dma_address2;
-+ oxnas_dma_channel_t* channels[MAX_OXNAS_DMA_CHANNELS];
-+
-+ printk("*************************************************************\n");
-+ printk(" \n");
-+ printk("Simple DMA Test, length = %lu, number of channel = %u\n", length, MAX_OXNAS_DMA_CHANNELS);
-+ printk(" \n");
-+ printk("*************************************************************\n");
-+
-+ for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
-+ channels[i] = oxnas_dma_request(0);
-+ if (channels[i] == OXNAS_DMA_CHANNEL_NUL) {
-+ printk("No DMA channels[%d] obtained\n", i);
-+ } else {
-+ printk("Obtained DMA channels[%d] %u, isActive=%d\n", i, channels[i]->channel_number_, oxnas_dma_is_active(channels[i]));
-+ }
-+ }
-+
-+ // Allocate some DMA coherent memory
-+ printk("Calling kmalloc()\n");
-+ memory1 = kmalloc(length, GFP_KERNEL | GFP_DMA);
-+ memory2 = kmalloc(length, GFP_KERNEL | GFP_DMA);
-+
-+ // Test each available DMA channel
-+ for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
-+ int j;
-+
-+ // Fill each memory area with a different pattern
-+ ptr = (unsigned long*)memory1;
-+ quads = length/sizeof(unsigned long);
-+ for (j=0; j < quads; j++) {
-+ *ptr++ = 0xdeadbeef;
-+ }
-+ ptr = (unsigned long*)memory2;
-+ for (j=0; j < quads; j++) {
-+ *ptr++ = 0xc001babe;
-+ }
-+
-+ printk("Before:\n");
-+ ptr = (unsigned long*)memory1;
-+ end = (unsigned long*)(memory1 + length);
-+ while (ptr < end) {
-+ for (j=0; j < 8; j++) {
-+ printk("0x%08lx ", *ptr++);
-+ }
-+ printk("\n");
-+ }
-+ printk("---------------------------------------------------------\n");
-+ ptr = (unsigned long*)memory2;
-+ end = (unsigned long*)(memory2 + length);
-+ while (ptr < end) {
-+ for (j=0; j < 8; j++) {
-+ printk("0x%08lx ", *ptr++);
-+ }
-+ printk("\n");
-+ }
-+
-+ // Get a consistent DMA mapping for the memory to be DMAed from - causing a
-+ // flush from the CPU's cache to the memory
-+ dma_address1 = dma_map_single(0, memory1, length, DMA_TO_DEVICE);
-+ if (dma_mapping_error(dma_address1)) {
-+ printk("Consistent DMA mapping 1 failed\n");
-+ }
-+
-+ // Get a consistent DMA mapping for the memory to be DMAed to - causing a
-+ // flush and invalidation of any entries in the CPU's cache covering the
-+ // memory region
-+ dma_address2 = dma_map_single(0, memory2, length, DMA_BIDIRECTIONAL);
-+ if (dma_mapping_error(dma_address2)) {
-+ printk("Consistent DMA mapping 2 failed\n");
-+ }
-+
-+ // Setup up DMA from first half to second half on memory, using physical addresses
-+ printk("Calling oxnas_dma_set(), memory1 = 0x%08lx, memory2 = 0x%08lx\n", (unsigned long)memory1, (unsigned long)memory2);
-+ oxnas_dma_set(
-+ channels[i],
-+ (unsigned char*)dma_address1,
-+ length,
-+ (unsigned char*)dma_address2,
-+ OXNAS_DMA_MODE_INC,
-+ OXNAS_DMA_MODE_INC,
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ 1, // Calculate checksum over source data
-+#else // CONFIG_OXNAS_VERSION_0X800
-+ 0,
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+ 1); // Paused
-+
-+ // Using notification callback
-+ oxnas_dma_set_callback(channels[i], dma_callback, OXNAS_DMA_CALLBACK_ARG_NUL);
-+
-+//printk("Before starting status = 0x%08x, intId = 0x%08x\n", readl(DMA_CALC_REG_ADR(channels[i]->channel_number_, DMA_CTRL_STATUS)), readl(DMA_CALC_REG_ADR(0, DMA_INTR_ID)));
-+ // Start the transfer
-+ printk("oxnas_dma_start() for channel %u\n", channels[i]->channel_number_);
-+ oxnas_dma_start(channels[i]);
-+
-+// Poll for transfer completion
-+//while (oxnas_dma_raw_isactive(channels[i])) {
-+// printk(".");
-+//}
-+//printk("Found channel inactive, status = 0x%08x, intId = 0x%08x\n", readl(DMA_CALC_REG_ADR(channels[i]->channel_number_, DMA_CTRL_STATUS)), readl(DMA_CALC_REG_ADR(0, DMA_INTR_ID)));
-+
-+ printk("Waiting for channel to be inactive\n");
-+
-+ // Sleep until transfer completed
-+ while (down_interruptible(&callback_semaphore));
-+ oxnas_dma_set_callback(channels[i], OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
-+
-+ // Release the consistent DMA mappings
-+ dma_unmap_single(0, dma_address1, length, DMA_TO_DEVICE);
-+ dma_unmap_single(0, dma_address2, length, DMA_BIDIRECTIONAL);
-+
-+ printk("After:\n");
-+ ptr = (unsigned long*)memory1;
-+ end = (unsigned long*)(memory1 + length);
-+ while (ptr < end) {
-+ for (j=0; j < 8; j++) {
-+ printk("0x%08lx ", *ptr++);
-+ }
-+ printk("\n");
-+ }
-+ printk("---------------------------------------------------------\n");
-+ ptr = (unsigned long*)memory2;
-+ end = (unsigned long*)(memory2 + length);
-+ while (ptr < end) {
-+ for (j=0; j < 8; j++) {
-+ printk("0x%08lx ", *ptr++);
-+ }
-+ printk("\n");
-+ }
-+ }
-+
-+ // Deallocate the memory
-+ printk("Calling kfree()\n");
-+ kfree(memory1);
-+ kfree(memory2);
-+ printk("Returned from kfree()\n");
-+
-+ for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
-+ oxnas_dma_free(channels[i]);
-+ }
-+
-+ for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
-+ channels[i] = oxnas_dma_request(0);
-+ if (channels[i] == OXNAS_DMA_CHANNEL_NUL) {
-+ printk("No DMA channels[%d] obtained\n", i);
-+ } else {
-+ printk("Obtained DMA channels[%d] %u, isActive=%d\n", i, channels[i]->channel_number_, oxnas_dma_is_active(channels[i]));
-+ }
-+ }
-+
-+ for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
-+ oxnas_dma_free(channels[i]);
-+ }
-+}
-+#endif // OXNAS_DMA_TEST
-+
-+#ifdef OXNAS_DMA_SG_TEST
-+static void dma_sg_test(void)
-+{
-+ int i;
-+ struct scatterlist* src_scatterlist = 0;
-+ struct scatterlist* dst_scatterlist = 0;
-+ const int num_src_buffers = 8;
-+ const int num_dst_buffers = 3;
-+ unsigned long src_fill_value = 0;
-+ unsigned long total_src_len = 0;
-+ int channel_number;
-+ oxnas_dma_channel_t* channels[MAX_OXNAS_DMA_CHANNELS];
-+
-+ printk("*************************************************************\n");
-+ printk(" \n");
-+ printk("Scatter-Gather DMA Test\n");
-+ printk(" \n");
-+ printk("*************************************************************\n");
-+
-+ for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
-+ channels[i] = oxnas_dma_request(0);
-+ if (channels[i] == OXNAS_DMA_CHANNEL_NUL) {
-+ printk("No DMA channels[%d] obtained\n", i);
-+ } else {
-+ printk("Obtained DMA channels[%d] %u, isActive=%d\n", i, channels[i]->channel_number_, oxnas_dma_is_active(channels[i]));
-+ }
-+ }
-+
-+ for (channel_number=0; channel_number < MAX_OXNAS_DMA_CHANNELS; ++channel_number) {
-+ if (num_src_buffers) {
-+ printk("Allocating source SG list and entry buffers\n");
-+ // Allocate scatterlist and memory for source buffers - store virtual buffer
-+ // addresses in scatterlist.offset for convenience. Include some contiguous
-+ // entries to test coalescing
-+ src_scatterlist = (struct scatterlist*)kmalloc(sizeof(struct scatterlist) * num_src_buffers, GFP_KERNEL);
-+ src_scatterlist[0].offset = (unsigned int)kmalloc(8*1024, GFP_KERNEL | GFP_DMA);
-+ src_scatterlist[0].__address = (char*)(8*1024); // Real allocation length
-+ src_scatterlist[0].length = 8*1024;
-+ src_scatterlist[0].page = (struct page*)0xdeadbeef; // Fill value
-+ src_scatterlist[1].offset = (unsigned int)kmalloc(8, GFP_KERNEL | GFP_DMA);
-+ src_scatterlist[1].__address = (char*)8; // Real allocation length
-+ src_scatterlist[1].length = 8;
-+ src_scatterlist[1].page = (struct page*)0xc001babe; // Fill value
-+ src_scatterlist[2].offset = (unsigned int)kmalloc(48*1024, GFP_KERNEL | GFP_DMA);
-+ src_scatterlist[2].__address = (char*)(48*1024); // Real allocation length
-+ src_scatterlist[2].length = 16*1024;
-+ src_scatterlist[2].page = (struct page*)0x22222222; // Fill value
-+ src_scatterlist[3].offset = src_scatterlist[2].offset + src_scatterlist[2].length;
-+ src_scatterlist[3].__address = (char*)0; // No allocation
-+ src_scatterlist[3].length = 16*1024;
-+ src_scatterlist[3].page = (struct page*)0x33333333; // Fill value
-+ src_scatterlist[4].offset = src_scatterlist[3].offset + src_scatterlist[3].length;
-+ src_scatterlist[4].__address = (char*)0; // No allocation
-+ src_scatterlist[4].length = 16*1024;
-+ src_scatterlist[4].page = (struct page*)0x44444444; // Fill value
-+ src_scatterlist[5].offset = (unsigned int)kmalloc(64, GFP_KERNEL | GFP_DMA);
-+ src_scatterlist[5].__address = (char*)64; // Real allocation length
-+ src_scatterlist[5].length = 64;
-+ src_scatterlist[5].page = (struct page*)0x55555555; // Fill value
-+ src_scatterlist[6].offset = (unsigned int)kmalloc(256, GFP_KERNEL | GFP_DMA);
-+ src_scatterlist[6].__address = (char*)256; // Real allocation length
-+ src_scatterlist[6].length = 128;
-+ src_scatterlist[6].page = (struct page*)0x66666666; // Fill value
-+ src_scatterlist[7].offset = src_scatterlist[6].offset + src_scatterlist[6].length;
-+ src_scatterlist[7].__address = (char*)0; // No allocation
-+ src_scatterlist[7].length = 128;
-+ src_scatterlist[7].page = (struct page*)0x77777777; // Fill value
-+ }
-+
-+ // Fill source memory buffers with stuff
-+ for (i=0; i < num_src_buffers; i++) {
-+ unsigned long* ptr = (unsigned long*)src_scatterlist[i].offset;
-+ int quads = src_scatterlist[i].length/sizeof(unsigned long);
-+ int j=0;
-+ printk("Filling source buffer %u\n", i);
-+ src_fill_value = (unsigned long)(src_scatterlist[i].page);
-+ for (; j < quads; j++) {
-+ *ptr++ = src_fill_value;
-+ }
-+ }
-+
-+ #ifdef OXNAS_DMA_SG_TEST_DUMP_BUFFERS
-+ // Print before contents of source buffers
-+ printk("Source Before:\n");
-+ for (i=0; i < num_src_buffers; i++) {
-+ unsigned long* ptr = (unsigned long*)src_scatterlist[i].offset;
-+ unsigned long* end = (unsigned long*)(src_scatterlist[i].offset + src_scatterlist[i].length);
-+ printk("Buffer %d\n", i);
-+ while (ptr < end) {
-+ int j=0;
-+ for (; j < 8; j++) {
-+ printk("0x%08lx ", *ptr++);
-+ }
-+ printk("\n");
-+ }
-+ }
-+ #endif // OXNAS_DMA_SG_TEST_DUMP_BUFFERS
-+
-+ // Get a consistent DMA mapping for the memory to be DMAed from - causing a
-+ // flush from the CPU's cache to the memory
-+ for (i=0; i < num_src_buffers; i++) {
-+ printk("Creating DMA mappings for source entry buffer %u\n", i);
-+ src_scatterlist[i].dma_address = dma_map_single(0, (void*)src_scatterlist[i].offset, src_scatterlist[i].length, DMA_TO_DEVICE);
-+ if (dma_mapping_error(src_scatterlist[i].dma_address)) {
-+ printk("Consistent source DMA mapping %d failed\n", i);
-+ }
-+
-+ // Set the checksum enabling high order address bit
-+ src_scatterlist[i].dma_address |= (1UL << OXNAS_DMA_CSUM_ENABLE_ADR_BIT);
-+ }
-+
-+ // Allocate scatterlist and memory for destination buffers - store virtual
-+ // buffer addresses in scatterlist.offset for convenience
-+ if (num_dst_buffers) {
-+ unsigned long dst_length;
-+ unsigned long offset;
-+
-+ printk("Allocating destination SG list and entry buffers\n");
-+ total_src_len = 0;
-+ for (i=0; i < num_src_buffers; i++) {
-+ total_src_len += src_scatterlist[i].length;
-+ }
-+
-+ // Following will only work if no remainder due to divide
-+ dst_length = total_src_len / num_dst_buffers;
-+ dst_scatterlist = (struct scatterlist*)kmalloc(sizeof(struct scatterlist) * num_dst_buffers, GFP_KERNEL);
-+
-+ // First destination segment owns the buffer
-+ dst_scatterlist[0].offset = (unsigned int)kmalloc(total_src_len, GFP_KERNEL | GFP_DMA);
-+ dst_scatterlist[0].__address = (char*)total_src_len; // Real allocation length
-+ dst_scatterlist[0].length = dst_length;
-+
-+ offset = dst_length;
-+ for (i=1; i < num_dst_buffers; i++) {
-+ dst_scatterlist[i].offset = dst_scatterlist[0].offset + offset;
-+ dst_scatterlist[i].__address = 0; // No allocation
-+ dst_scatterlist[i].length = dst_length;
-+
-+ offset += dst_length;
-+ }
-+ }
-+
-+ // Fill destination memory buffers with zero
-+ for (i=0; i < num_dst_buffers; i++) {
-+ unsigned long* ptr = (unsigned long*)dst_scatterlist[i].offset;
-+ int quads = dst_scatterlist[i].length/sizeof(unsigned long);
-+ int j=0;
-+ printk("Filling destination buffer %u\n", i);
-+ for (; j < quads; j++) {
-+ *ptr++ = 0x000000;
-+ }
-+ }
-+
-+ //#ifdef OXNAS_DMA_SG_TEST_DUMP_BUFFERS
-+ // // Print before contents of destination buffers
-+ // printk("Destination Before:\n");
-+ // for (i=0; i < num_dst_buffers; i++) {
-+ // unsigned long* ptr = (unsigned long*)dst_scatterlist[i].offset;
-+ // unsigned long* end = (unsigned long*)(dst_scatterlist[i].offset + dst_scatterlist[i].length);
-+ // printk("Buffer %d\n", i);
-+ // while (ptr < end) {
-+ // int j=0;
-+ // for (; j < 8; j++) {
-+ // printk("0x%08lx ", *ptr++);
-+ // }
-+ // printk("\n");
-+ // }
-+ // }
-+ //#endif // OXNAS_DMA_SG_TEST_DUMP_BUFFERS
-+
-+ // Get a consistent DMA mapping for the memory to be DMAed to - causing an
-+ // invalidate to the CPU's cache
-+ for (i=0; i < num_dst_buffers; i++) {
-+ printk("Creating DMA mappings for destination entry buffer %u\n", i);
-+ dst_scatterlist[i].dma_address = dma_map_single(0, (void*)dst_scatterlist[i].offset, dst_scatterlist[i].length, DMA_BIDIRECTIONAL);
-+ if (dma_mapping_error(dst_scatterlist[i].dma_address)) {
-+ printk("Consistent destination DMA mapping %d failed\n", i);
-+ }
-+ }
-+
-+ // Setup up SG DMA transfer
-+ printk("Setting up transfer\n");
-+ oxnas_dma_set_sg(
-+ channels[channel_number],
-+ src_scatterlist,
-+ num_src_buffers,
-+ dst_scatterlist,
-+ num_dst_buffers,
-+ OXNAS_DMA_MODE_INC,
-+ OXNAS_DMA_MODE_INC,
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ 1); // Compute checksum
-+#else // CONFIG_OXNAS_VERSION_0X800
-+ 0);
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+ // Using second DMA channel requested
-+ oxnas_dma_set_callback(channels[channel_number], dma_callback, OXNAS_DMA_CALLBACK_ARG_NUL);
-+
-+ // Start the transfer
-+ printk("Starting the transfer\n");
-+ oxnas_dma_start(channels[channel_number]);
-+
-+ // Sleep until transfer completed
-+ printk("Waiting for transfer to complete...\n");
-+
-+ while (down_interruptible(&callback_semaphore));
-+ oxnas_dma_set_callback(channels[channel_number], OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
-+
-+ // Release the consistent DMA mappings for the source buffers
-+ for (i=0; i < num_src_buffers; i++) {
-+ printk("Releasing DMA mappings for source entry buffer %u\n", i);
-+ // Ensure the checksum enabling high order address bit is not set, as
-+ // this would confuse the DMA mapping release function
-+ src_scatterlist[i].dma_address &= ~(1UL << OXNAS_DMA_CSUM_ENABLE_ADR_BIT);
-+ dma_unmap_single(0, src_scatterlist[i].dma_address, src_scatterlist[i].length, DMA_TO_DEVICE);
-+ }
-+
-+ // Release the consistent DMA mappings for the destination buffers
-+ for (i=0; i < num_dst_buffers; i++) {
-+ printk("Releasing DMA mappings for destination entry buffer %u\n", i);
-+ dma_unmap_single(0, dst_scatterlist[i].dma_address, dst_scatterlist[i].length, DMA_BIDIRECTIONAL);
-+ }
-+
-+ {
-+ u32 sw_csum = 0;
-+ for (i=0; i < num_src_buffers; i++) {
-+ sw_csum = csum_partial((u8*)src_scatterlist[i].offset, src_scatterlist[i].length, sw_csum);
-+ }
-+ printk("S/W generated src csum = 0x%04hx\n", csum_fold(sw_csum));
-+
-+ sw_csum = 0;
-+ for (i=0; i < num_dst_buffers; i++) {
-+ sw_csum = csum_partial((u8*)dst_scatterlist[i].offset, dst_scatterlist[i].length, sw_csum);
-+ }
-+ printk("S/W generated dst csum = 0x%04hx\n", csum_fold(sw_csum));
-+ }
-+
-+ #ifdef OXNAS_DMA_SG_TEST_DUMP_BUFFERS
-+ // // Print after contents of source buffers
-+ // printk("Source After:\n");
-+ // for (i=0; i < num_src_buffers; i++) {
-+ // unsigned long* ptr = (unsigned long*)src_scatterlist[i].offset;
-+ // unsigned long* end = (unsigned long*)(src_scatterlist[i].offset + src_scatterlist[i].length);
-+ // printk("Buffer %d\n", i);
-+ // while (ptr < end) {
-+ // int j=0;
-+ // for (; j < 8; j++) {
-+ // printk("0x%08lx ", *ptr++);
-+ // }
-+ // printk("\n");
-+ // }
-+ // }
-+
-+ // Print after contents of destination buffers
-+ printk("Destination After:\n");
-+ for (i=0; i < num_dst_buffers; i++) {
-+ unsigned long* ptr = (unsigned long*)dst_scatterlist[i].offset;
-+ unsigned long* end = (unsigned long*)(dst_scatterlist[i].offset + dst_scatterlist[i].length);
-+ printk("Buffer %d\n", i);
-+ while (ptr < end) {
-+ int j=0;
-+ for (; j < 8; j++) {
-+ printk("0x%08lx ", *ptr++);
-+ }
-+ printk("\n");
-+ }
-+ }
-+ #endif // OXNAS_DMA_SG_TEST_DUMP_BUFFERS
-+
-+ // Free the memory for the source buffers
-+ for (i=0; i < num_src_buffers; i++) {
-+ // Check that unique allocation made for this entry
-+ if (src_scatterlist[i].__address) {
-+ printk("Freeing source SG entry buffer, adr = 0x%08x, len = 0x%08x\n", src_scatterlist[i].offset, (u32)src_scatterlist[i].__address);
-+ kfree((void*)src_scatterlist[i].offset);
-+ }
-+ }
-+
-+ // Free the memory for the source scatterlist
-+ if (src_scatterlist) {
-+ printk("Freeing source SG scatter list structure\n");
-+ kfree(src_scatterlist);
-+ }
-+
-+ // Free the memory for the destination buffers
-+ for (i=0; i < num_dst_buffers; i++) {
-+ if (dst_scatterlist[i].__address) {
-+ printk("Freeing destination SG entry, adr = 0x%08x, len = 0x%08x\n", dst_scatterlist[i].offset, (u32)dst_scatterlist[i].__address);
-+ kfree((void*)dst_scatterlist[i].offset);
-+ }
-+ }
-+
-+ // Free the memory for the destination scatterlist
-+ if (dst_scatterlist) {
-+ printk("Freeing source SG scatter list structure\n");
-+ kfree(dst_scatterlist);
-+ }
-+ }
-+
-+ for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
-+ oxnas_dma_free(channels[i]);
-+ }
-+}
-+#endif // OXNAS_DMA_SG_TEST
-+
-+#ifdef OXNAS_DMA_SG_TEST_2
-+static void dma_sg_test2()
-+{
-+ /** Include initial 2 bytes of pad that real network buffers would contain
-+ in order to ensure that IP header and TCP/UDP header are quad aligned */
-+ static const unsigned char bad_src_data0[] = {
-+ 0xff, 0xff, 0x00, 0xa0, 0xd2, 0x05, 0x06, 0xec, 0x00, 0xcf, 0x52, 0x49, 0xc3, 0x03, 0x08, 0x00,
-+ 0x45, 0x00, 0x05, 0xb4, 0x99, 0x45, 0x40, 0x00, 0x40, 0x06, 0x42, 0xf5, 0xac, 0x1f, 0x00, 0x65,
-+ 0xac, 0x1f, 0x00, 0x66
-+ };
-+
-+ static const unsigned char bad_src_data1[] = {
-+ 0x04, 0x00, 0x13, 0x89, 0x02, 0x8a, 0x5c, 0x83, 0x52, 0xde, 0xc7, 0x0c, 0x80, 0x19, 0x0b, 0x68,
-+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0xff, 0xff, 0xb3, 0x9d, 0x3f, 0x82, 0xf0, 0xff,
-+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
-+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
-+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31
-+ };
-+
-+ /** Include initial 2 bytes of pad that real network buffers would contain
-+ in order to ensure that IP header and TCP/UDP header are quad aligned */
-+ static const unsigned char good_src_data0[] = {
-+ 0xff, 0xff, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5
-+ };
-+
-+ static const unsigned char good_src_data1[] = {
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5
-+ };
-+
-+ static const int src_offset = 2; // To jump IP quad align padding
-+ static const int dst_buffer_size = 512;
-+
-+ const unsigned char *src_data0 = bad_src_data0;
-+ const unsigned char *src_data1 = bad_src_data1;
-+ unsigned long src_data0_len = sizeof(bad_src_data0);
-+ unsigned long src_data1_len = sizeof(bad_src_data1);
-+ int channel_number;
-+ oxnas_dma_channel_t* channels[MAX_OXNAS_DMA_CHANNELS];
-+ int i;
-+
-+// const unsigned char *src_data0 = good_src_data0;
-+// const unsigned char *src_data1 = good_src_data1;
-+// unsigned long src_data0_len = sizeof(good_src_data0);
-+// unsigned long src_data1_len = sizeof(good_src_data1);
-+
-+ printk("*************************************************************\n");
-+ printk(" \n");
-+ printk("Scatter-Gather DMA Test 2\n");
-+ printk(" \n");
-+ printk("*************************************************************\n");
-+
-+ printk("seg0 0x%08x, %lu\n", (u32)src_data0, src_data0_len);
-+ printk("seg1 0x%08x, %lu\n", (u32)src_data1, src_data1_len);
-+
-+ for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
-+ channels[i] = oxnas_dma_request(0);
-+ if (channels[i] == OXNAS_DMA_CHANNEL_NUL) {
-+ printk("No DMA channels[%d] obtained\n", i);
-+ } else {
-+ printk("Obtained DMA channels[%d] %u, isActive=%d\n", i, channels[i]->channel_number_, oxnas_dma_is_active(channels[i]));
-+ }
-+ }
-+
-+ // Test each available DMA channel
-+ for (channel_number=0; channel_number < MAX_OXNAS_DMA_CHANNELS; ++channel_number) {
-+
-+ struct scatterlist* src_scatterlist = (struct scatterlist*)kmalloc(sizeof(struct scatterlist) * 2, GFP_KERNEL);
-+
-+ unsigned long total_src_length = src_data0_len + src_data1_len;
-+ src_scatterlist[0].offset = (unsigned int)kmalloc(total_src_length, GFP_KERNEL | GFP_DMA) + src_offset;
-+ src_scatterlist[0].length = src_data0_len - src_offset;
-+ memcpy((u8*)src_scatterlist[0].offset, src_data0, src_scatterlist[0].length);
-+
-+ src_scatterlist[1].offset = src_scatterlist[0].offset + src_scatterlist[0].length;
-+ src_scatterlist[1].length = src_data1_len;
-+ memcpy((u8*)src_scatterlist[1].offset, src_data1, src_scatterlist[1].length);
-+
-+ unsigned long total_dst_length = total_src_length - src_offset; // Excludes initial IP quad alignment pad
-+ unsigned num_dst_buffers = total_dst_length / dst_buffer_size;
-+ if ((num_dst_buffers * dst_buffer_size) < total_dst_length) {
-+ ++num_dst_buffers;
-+ }
-+ printk("total_src_length = %lu, src_offset = %u, total_dst_length = %lu, dst_buffer_size = %u, num_dst_buffers = %u\n", total_src_length, src_offset, total_dst_length, dst_buffer_size, num_dst_buffers);
-+ struct scatterlist* dst_scatterlist = (struct scatterlist*)kmalloc(sizeof(struct scatterlist) * num_dst_buffers, GFP_KERNEL);
-+
-+ int i;
-+ unsigned long remainder = total_dst_length;
-+ for (i=0; i < num_dst_buffers; ++i) {
-+ dst_scatterlist[i].offset = (unsigned int)kmalloc(dst_buffer_size, GFP_KERNEL | GFP_DMA);
-+ dst_scatterlist[i].length = (remainder < dst_buffer_size) ? remainder : dst_buffer_size;
-+ remainder -= dst_scatterlist[i].length;
-+ }
-+
-+ int j;
-+ for (j=0; j < OXNAS_DMA_SG_TEST2_ITERATIONS; ++j) {
-+ src_scatterlist[0].dma_address = dma_map_single(0, (void*)src_scatterlist[0].offset, src_scatterlist[0].length, DMA_TO_DEVICE);
-+ if (dma_mapping_error(src_scatterlist[0].dma_address)) {
-+ printk("Consistent source DMA mapping 0 failed\n");
-+ }
-+ // Set the checksum enabling high order address bit
-+ //src_scatterlist[0].dma_address |= (1UL << OXNAS_DMA_CSUM_ENABLE_ADR_BIT);
-+
-+ src_scatterlist[1].dma_address = dma_map_single(0, (void*)src_scatterlist[1].offset, src_scatterlist[1].length, DMA_TO_DEVICE);
-+ if (dma_mapping_error(src_scatterlist[1].dma_address)) {
-+ printk("Consistent source DMA mapping 1 failed\n");
-+ }
-+ // Set the checksum enabling high order address bit
-+ src_scatterlist[1].dma_address |= (1UL << OXNAS_DMA_CSUM_ENABLE_ADR_BIT);
-+
-+ printk("num_dst_buffers = %u\n", num_dst_buffers);
-+ for (i=0; i < num_dst_buffers; i++) {
-+ memset((void*)dst_scatterlist[i].offset, 0, dst_scatterlist[i].length);
-+
-+ dst_scatterlist[i].dma_address = dma_map_single(0, (void*)dst_scatterlist[i].offset, dst_scatterlist[i].length, DMA_BIDIRECTIONAL);
-+ if (dma_mapping_error(dst_scatterlist[i].dma_address)) {
-+ printk("Consistent destination DMA mapping %d failed\n", i);
-+ }
-+ }
-+
-+ // Setup up SG DMA transfer
-+ printk("Setting up transfer\n");
-+ oxnas_dma_set_sg(
-+ channels[channel_number],
-+ src_scatterlist,
-+ 2,
-+ dst_scatterlist,
-+ num_dst_buffers,
-+ OXNAS_DMA_MODE_INC,
-+ OXNAS_DMA_MODE_INC,
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ 1); // Compute checksum
-+#else // CONFIG_OXNAS_VERSION_0X800
-+ 0);
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+ // Using second DMA channel requested
-+ oxnas_dma_set_callback(channels[channel_number], dma_callback, OXNAS_DMA_CALLBACK_ARG_NUL);
-+
-+ // Start the transfer
-+ printk("Starting the transfer\n");
-+ oxnas_dma_start(channels[channel_number]);
-+
-+ // Sleep until transfer completed
-+ printk("Waiting for transfer to complete...\n");
-+ while (down_interruptible(&callback_semaphore));
-+ oxnas_dma_set_callback(channels[channel_number], OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
-+
-+ printk("Error code = %u\n", channels[channel_number]->error_code_);
-+
-+ // Release the consistent DMA mappings for the source buffers
-+ for (i=0; i < 2; i++) {
-+ // Ensure the checksum enabling high order address bit is not set, as
-+ // this would confuse the DMA mapping release function
-+ src_scatterlist[i].dma_address &= ~(1UL << OXNAS_DMA_CSUM_ENABLE_ADR_BIT);
-+ dma_unmap_single(0, src_scatterlist[i].dma_address, src_scatterlist[i].length, DMA_TO_DEVICE);
-+ }
-+
-+ // Release the consistent DMA mappings for the destination buffers
-+ for (i=0; i < num_dst_buffers; i++) {
-+ printk("Releasing DMA mappings for destination entry buffer %u\n", i);
-+ dma_unmap_single(0, dst_scatterlist[i].dma_address, dst_scatterlist[i].length, DMA_BIDIRECTIONAL);
-+ }
-+
-+ u32 sw_csum = 0;
-+ //sw_csum = csum_partial((u8*)src_scatterlist[0].offset, src_scatterlist[0].length, 0);
-+ sw_csum = csum_partial((u8*)src_scatterlist[1].offset, src_scatterlist[1].length, sw_csum);
-+ printk("S/W generated src csum = 0x%04hx\n", csum_fold(sw_csum));
-+
-+ sw_csum = 0;
-+ unsigned offset = src_scatterlist[0].length;
-+ //unsigned offset = 0;
-+ for (i=0; i < num_dst_buffers; i++) {
-+ sw_csum = csum_partial((u8*)dst_scatterlist[i].offset + offset, dst_scatterlist[i].length - offset, sw_csum);
-+ offset = 0;
-+ }
-+ printk("S/W generated dst csum = 0x%04hx\n", csum_fold(sw_csum));
-+ }
-+
-+ for (i=0; i < num_dst_buffers; ++i) {
-+ kfree((void*)dst_scatterlist[i].offset);
-+ }
-+ kfree(dst_scatterlist);
-+
-+ kfree((void*)(src_scatterlist[0].offset - src_offset));
-+ kfree(src_scatterlist);
-+ }
-+
-+ for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
-+ oxnas_dma_free(channels[i]);
-+ }
-+}
-+#endif // OXNAS_DMA_SG_TEST_2
-+#endif // defined(OXNAS_DMA_TEST) || defined(OXNAS_DMA_SG_TEST)
-+
-+EXPORT_SYMBOL(oxnas_dma_request);
-+EXPORT_SYMBOL(oxnas_dma_free);
-+EXPORT_SYMBOL(oxnas_dma_set_callback);
-+EXPORT_SYMBOL(oxnas_dma_set_common);
-+EXPORT_SYMBOL(oxnas_dma_is_active);
-+EXPORT_SYMBOL(oxnas_dma_raw_isactive);
-+EXPORT_SYMBOL(oxnas_dma_set);
-+EXPORT_SYMBOL(oxnas_dma_device_set);
-+EXPORT_SYMBOL(oxnas_dma_abort);
-+EXPORT_SYMBOL(oxnas_dma_dump_registers);
-+EXPORT_SYMBOL(oxnas_dma_dump_registers_single);
-+EXPORT_SYMBOL(oxnas_dma_start);
-+
-+EXPORT_SYMBOL(oxnas_pata_dma_settings);
-+EXPORT_SYMBOL(oxnas_sata_dma_settings);
-+EXPORT_SYMBOL(oxnas_dpe_rx_dma_settings);
-+EXPORT_SYMBOL(oxnas_dpe_tx_dma_settings);
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/dpe_test.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/dpe_test.c
---- linux-2.6.24/arch/arm/mach-oxnas/dpe_test.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/dpe_test.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,3051 @@
-+/*
-+ * /arch/=arm/mach-oxnas/dpe-test.c
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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
-+ */
-+
-+/**
-+ * Test driver for the cipher core
-+ *
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/device.h>
-+#include <linux/string.h>
-+#include <linux/sysdev.h>
-+#include <linux/fs.h>
-+#include <asm/arch/cipher.h>
-+#include <asm/io.h>
-+#include <asm/arch/hardware.h>
-+#include <linux/dma-mapping.h>
-+#include <asm/arch/dma.h>
-+
-+/***************************************************************************
-+* CONSTANTS
-+***************************************************************************/
-+#define DRIVER_AUTHOR "Oxford Semiconductor Inc."
-+#define DRIVER_DESC "Cipher block testing"
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR(DRIVER_AUTHOR);
-+MODULE_DESCRIPTION(DRIVER_DESC);
-+
-+// uses /dev/dv940led
-+#define DEVICE_NAME "ox800dpetst"
-+MODULE_SUPPORTED_DEVICE(DEVICE_NAME);
-+
-+#define FAILED(reason) {printk(KERN_ERR"%s failed %s\n",__FUNCTION__,reason);++failed;}
-+/**************************************************************************
-+* PROTOTYPES
-+**************************************************************************/
-+#if 0
-+static u32 READL(int a) {u32 v = readl(a);printk("0x%08x <- [0x%08x]\n",v,a);return v;}
-+static void WRITEL(int v,int a){printk("0x%08x -> [0x%08x]\n",v,a);writel(v,a);}
-+#else
-+static u32 READL(int a) {u32 v = readl(a);return v;}
-+static void WRITEL(int v,int a){writel(v,a);}
-+#endif
-+/**************************************************************************
-+* STRUCTURES
-+**************************************************************************/
-+typedef int (ox800dpe_test_t)(void) ;
-+
-+/**************************************************************************
-+* FUCTIONS
-+* prefix all with "ox800dpe"
-+**************************************************************************/
-+
-+/*************************************************************************/
-+static int test1(void) {
-+ int failed = 0;
-+ u32 reg;
-+
-+ // authenticate
-+ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for encryption
-+ reg = OX800DPE_CTL_DIRECTION_ENC | OX800DPE_CTL_MODE_ECB_AES;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ reg = READL( OX800DPE_STATUS );
-+ // shouldn't be busy
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle even with incomplete data");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx not empty before data input ");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx fifo filling without data");
-+
-+
-+ // key no 1
-+ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
-+ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
-+ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
-+ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ // 1st data set
-+ WRITEL(be32_to_cpu( 0x00112233), OX800DPE_DATA_IN0 );
-+
-+ /* in fifo no longer empty */
-+ reg = READL( OX800DPE_STATUS );
-+ if ( (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx fifo still empty after data input")
-+
-+ WRITEL(be32_to_cpu( 0x44556677), OX800DPE_DATA_IN1 );
-+ WRITEL(be32_to_cpu( 0x8899aabb), OX800DPE_DATA_IN2 );
-+
-+ // shouldn't be busy as not enough data
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("core lept into action before putting in all the data");
-+
-+ WRITEL(be32_to_cpu( 0xccddeeff), OX800DPE_DATA_IN3 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ /* output should be full */
-+ if ( !(reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still empty after encrypting data ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ /* check output */
-+ {
-+ u32 data[4];
-+
-+ data[0] = READL( OX800DPE_DATA_OUT0 );
-+ data[1] = READL( OX800DPE_DATA_OUT1 );
-+ data[2] = READL( OX800DPE_DATA_OUT2 );
-+ data[3] = READL( OX800DPE_DATA_OUT3 );
-+
-+ if ((data[0] != cpu_to_be32(0x69c4e0d8)) ||
-+ (data[1] != cpu_to_be32(0x6a7b0430)) ||
-+ (data[2] != cpu_to_be32(0xd8cdb780)) ||
-+ (data[3] != cpu_to_be32(0x70b4c55a)))
-+ {
-+ FAILED("encryption output incorrect");
-+ printk("%08x%08x%08x%08x\n",data[0],data[1],data[2],data[3]);
-+ }
-+ }
-+
-+ /* output should be empty again */
-+ reg = READL( OX800DPE_STATUS );
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after data read");
-+
-+ return failed;
-+
-+}
-+
-+/*************************************************************************/
-+static int test2(void) {
-+ int failed = 0;
-+ u32 reg;
-+ oxnas_dma_channel_t* dma_in;
-+ oxnas_dma_channel_t* dma_out;
-+ dma_addr_t in_address;
-+ dma_addr_t out_address;
-+
-+ u32* data_in;
-+ u32* data_out;
-+
-+ // setup dmas
-+ dma_in = oxnas_dma_request(1);
-+ dma_out = oxnas_dma_request(1);
-+
-+ // get some dma accessable memory
-+ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+
-+ // fill with input and non expected output
-+ data_in[0] = be32_to_cpu( 0x00112233);
-+ data_in[1] = be32_to_cpu( 0x44556677);
-+ data_in[2] = be32_to_cpu( 0x8899aabb);
-+ data_in[3] = be32_to_cpu( 0xccddeeff);
-+ data_out[0] = ~0;
-+ data_out[1] = ~0;
-+ data_out[2] = ~0;
-+ data_out[3] = ~0;
-+
-+ // map the dma regons
-+ in_address = dma_map_single(
-+ 0,
-+ data_in,
-+ 4 * sizeof(u32),
-+ DMA_TO_DEVICE);
-+
-+ // map the dma regons
-+ out_address = dma_map_single(
-+ 0,
-+ data_out,
-+ 4 * sizeof(u32),
-+ DMA_FROM_DEVICE);
-+
-+ // setup the transfers
-+ oxnas_dma_device_set(
-+ dma_in,
-+ OXNAS_DMA_TO_DEVICE,
-+ (char*)in_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_rx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ oxnas_dma_device_set(
-+ dma_out,
-+ OXNAS_DMA_FROM_DEVICE,
-+ (char*)out_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_tx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ // don't authenticate
-+ WRITEL(0 ,OX800IBW_STATUS);
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for encryption
-+ reg = OX800DPE_CTL_DIRECTION_ENC | OX800DPE_CTL_MODE_ECB_AES;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ reg = READL( OX800DPE_STATUS );
-+ // shouldn't be busy
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle even with incomplete data");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx not empty before data input ");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx fifo filling without data");
-+
-+
-+ // key no 1
-+ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
-+ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
-+ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
-+ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ // start dma transfers
-+ oxnas_dma_start(dma_out);
-+ oxnas_dma_start(dma_in);
-+
-+ /* wait until done */
-+ while( oxnas_dma_is_active( dma_out ) );
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ /* output should be empty */
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after fetching ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+ /* check output */
-+ if ((data_out[0] != cpu_to_be32(0x69c4e0d8)) ||
-+ (data_out[1] != cpu_to_be32(0x6a7b0430)) ||
-+ (data_out[2] != cpu_to_be32(0xd8cdb780)) ||
-+ (data_out[3] != cpu_to_be32(0x70b4c55a)))
-+ {
-+ FAILED("encryption output incorrect");
-+ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+ }
-+
-+ // free dmas
-+ oxnas_dma_free( dma_in );
-+ oxnas_dma_free( dma_out );
-+
-+ kfree(data_in);
-+ kfree(data_out);
-+
-+ return failed;
-+
-+}
-+
-+
-+/*************************************************************************/
-+static int test3(void) {
-+ int failed = 0;
-+ u32 reg;
-+ oxnas_dma_channel_t* dma_in;
-+ oxnas_dma_channel_t* dma_out;
-+ dma_addr_t in_address;
-+ dma_addr_t out_address;
-+
-+ u32* data_in;
-+ u32* data_out;
-+
-+ // setup dmas
-+ dma_in = oxnas_dma_request(1);
-+ dma_out = oxnas_dma_request(1);
-+
-+ // get some dma accessable memory
-+ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+
-+ // fill with input and non expected output
-+ data_in[0] = be32_to_cpu( 0x69c4e0d8);
-+ data_in[1] = be32_to_cpu( 0x6a7b0430);
-+ data_in[2] = be32_to_cpu( 0xd8cdb780);
-+ data_in[3] = be32_to_cpu( 0x70b4c55a);
-+ data_out[0] = ~0;
-+ data_out[1] = ~0;
-+ data_out[2] = ~0;
-+ data_out[3] = ~0;
-+
-+ // map the dma regons
-+ in_address = dma_map_single(
-+ 0,
-+ data_in,
-+ 4 * sizeof(u32),
-+ DMA_TO_DEVICE);
-+
-+ // map the dma regons
-+ out_address = dma_map_single(
-+ 0,
-+ data_out,
-+ 4 * sizeof(u32),
-+ DMA_FROM_DEVICE);
-+
-+ // setup the transfers
-+ oxnas_dma_device_set(
-+ dma_in,
-+ OXNAS_DMA_TO_DEVICE,
-+ (char*)in_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_rx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ oxnas_dma_device_set(
-+ dma_out,
-+ OXNAS_DMA_FROM_DEVICE,
-+ (char*)out_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_tx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ // authenticate
-+ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for decryption
-+ reg = OX800DPE_CTL_MODE_ECB_AES;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ reg = READL( OX800DPE_STATUS );
-+ // shouldn't be busy
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle even with incomplete data");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx not empty before data input ");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx fifo filling without data");
-+
-+
-+ // key no 1
-+ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
-+ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
-+ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
-+ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ // start dma transfers
-+ oxnas_dma_start(dma_out);
-+ oxnas_dma_start(dma_in);
-+
-+ /* wait until dma done */
-+ while( oxnas_dma_is_active( dma_out ) );
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ /* output should be empty */
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after fetching ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+ /* check output */
-+ if ((data_out[0] != cpu_to_be32(0x00112233)) ||
-+ (data_out[1] != cpu_to_be32(0x44556677)) ||
-+ (data_out[2] != cpu_to_be32(0x8899aabb)) ||
-+ (data_out[3] != cpu_to_be32(0xccddeeff)))
-+ {
-+ FAILED("encryption output incorrect");
-+ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+ }
-+
-+ // free dmas
-+ oxnas_dma_free( dma_in );
-+ oxnas_dma_free( dma_out );
-+
-+ kfree(data_in);
-+ kfree(data_out);
-+
-+ return failed;
-+
-+}
-+
-+/*************************************************************************/
-+static int test4(void) {
-+ int failed = 0;
-+ u32 reg;
-+ oxnas_dma_channel_t* dma_out;
-+ dma_addr_t out_address;
-+
-+ u32* data_out;
-+
-+ // setup dmas
-+ dma_out = oxnas_dma_request(1);
-+
-+ // get some dma accessable memory
-+ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+
-+ // fill with non expected output
-+ data_out[0] = ~0;
-+ data_out[1] = ~0;
-+ data_out[2] = ~0;
-+ data_out[3] = ~0;
-+
-+ // map the dma regons
-+ out_address = dma_map_single(
-+ 0,
-+ data_out,
-+ 4 * sizeof(u32),
-+ DMA_FROM_DEVICE);
-+
-+ oxnas_dma_device_set(
-+ dma_out,
-+ OXNAS_DMA_FROM_DEVICE,
-+ (char*)out_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_tx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+ // don't authenticate
-+ WRITEL(0 ,OX800IBW_STATUS);
-+
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for decryption
-+ reg = OX800DPE_CTL_PRIMARY_IS_KEY3 | OX800DPE_CTL_MODE_ECB_AES;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ reg = READL( OX800DPE_STATUS );
-+ // shouldn't be busy
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle even with incomplete data");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx not empty before data input ");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx fifo filling without data");
-+
-+
-+ // key no 1
-+ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY20 );
-+ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY21 );
-+ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY22 );
-+ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY23 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ // start dma transfers
-+ oxnas_dma_start(dma_out);
-+
-+ // 1st data set
-+ WRITEL(be32_to_cpu( 0x69c4e0d8), OX800DPE_DATA_IN0 );
-+ WRITEL(be32_to_cpu( 0x6a7b0430), OX800DPE_DATA_IN1 );
-+ WRITEL(be32_to_cpu( 0xd8cdb780), OX800DPE_DATA_IN2 );
-+ WRITEL(be32_to_cpu( 0x70b4c55a), OX800DPE_DATA_IN3 );
-+
-+ /* wait until done */
-+ while( oxnas_dma_is_active( dma_out ) );
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ /* output should be empty */
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after fetching ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+
-+ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+ /* check output */
-+ if ((data_out[0] != cpu_to_be32(0x00112233)) ||
-+ (data_out[1] != cpu_to_be32(0x44556677)) ||
-+ (data_out[2] != cpu_to_be32(0x8899aabb)) ||
-+ (data_out[3] != cpu_to_be32(0xccddeeff)))
-+ {
-+ FAILED("encryption output incorrect");
-+ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+ }
-+
-+ // free dmas
-+ oxnas_dma_free( dma_out );
-+ kfree(data_out);
-+
-+ return failed;
-+
-+}
-+
-+/*************************************************************************/
-+static int test5(void) {
-+ int failed = 0;
-+ u32 reg;
-+ oxnas_dma_channel_t* dma_in;
-+ dma_addr_t in_address;
-+
-+ u32* data_in;
-+
-+ // setup dmas
-+ dma_in = oxnas_dma_request(1);
-+
-+ // get some dma accessable memory
-+ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+
-+ // fill with input and non expected output
-+ data_in[0] = be32_to_cpu( 0x00112233);
-+ data_in[1] = be32_to_cpu( 0x44556677);
-+ data_in[2] = be32_to_cpu( 0x8899aabb);
-+ data_in[3] = be32_to_cpu( 0xccddeeff);
-+
-+ // map the dma regons
-+ in_address = dma_map_single(
-+ 0,
-+ data_in,
-+ 4 * sizeof(u32),
-+ DMA_TO_DEVICE);
-+
-+ // setup the transfers
-+ oxnas_dma_device_set(
-+ dma_in,
-+ OXNAS_DMA_TO_DEVICE,
-+ (char*)in_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_rx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+ // don't authenticate
-+ WRITEL(0 ,OX800IBW_STATUS);
-+
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for encryption
-+ reg = OX800DPE_CTL_DIRECTION_ENC |
-+ OX800DPE_CTL_MODE_ECB_AES |
-+ OX800DPE_CTL_PRIMARY_IS_KEY3 ;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ reg = READL( OX800DPE_STATUS );
-+ // shouldn't be busy
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle even with incomplete data");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx not empty before data input ");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx fifo filling without data");
-+
-+
-+ // key no 1
-+ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY20 );
-+ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY21 );
-+ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY22 );
-+ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY23 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ // start dma transfers
-+ oxnas_dma_start(dma_in);
-+
-+ /* wait until done */
-+ while( oxnas_dma_is_active( dma_in ) );
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ /* output should be full */
-+ if ( !(reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still empty after encrypting data ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+
-+ /* check output */
-+ {
-+ u32 data[4];
-+
-+ data[0] = READL( OX800DPE_DATA_OUT0 );
-+ data[1] = READL( OX800DPE_DATA_OUT1 );
-+ data[2] = READL( OX800DPE_DATA_OUT2 );
-+ data[3] = READL( OX800DPE_DATA_OUT3 );
-+
-+ if ((data[0] != cpu_to_be32(0x69c4e0d8)) ||
-+ (data[1] != cpu_to_be32(0x6a7b0430)) ||
-+ (data[2] != cpu_to_be32(0xd8cdb780)) ||
-+ (data[3] != cpu_to_be32(0x70b4c55a)))
-+ {
-+ FAILED("encryption output incorrect");
-+ printk("%08x%08x%08x%08x\n",data[0],data[1],data[2],data[3]);
-+ }
-+ }
-+
-+ /* output should be empty again */
-+ reg = READL( OX800DPE_STATUS );
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after data read");
-+
-+ // free dmas
-+ kfree(data_in);
-+
-+ oxnas_dma_free( dma_in );
-+
-+ return failed;
-+
-+}
-+
-+/*************************************************************************/
-+static int test6(void) {
-+ int failed = 0;
-+ u32 reg;
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+ // don't authenticate
-+ WRITEL(0 ,OX800IBW_STATUS);
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for key encryption
-+ reg = OX800DPE_CTL_DIRECTION_ENC |
-+ OX800DPE_CTL_ENCRYPT_KEY |
-+ OX800DPE_CTL_MODE_ECB_AES;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ // shouldn't be busy
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle even with incomplete data");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx not empty before data input ");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx fifo filling without data");
-+
-+ // data to be encrypted to form a key
-+ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_DATA_IN0 );
-+ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_DATA_IN1 );
-+ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_DATA_IN2 );
-+ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_DATA_IN3 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ /* output should be empty */
-+ reg = READL( OX800DPE_STATUS );
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after fetching ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ {
-+ u32 data[4];
-+
-+ data[0] = READL( OX800DPE_KEY00 );
-+ data[1] = READL( OX800DPE_KEY01 );
-+ data[2] = READL( OX800DPE_KEY02 );
-+ data[3] = READL( OX800DPE_KEY03 );
-+
-+ if ((data[0] != cpu_to_be32(0x4791b833)) ||
-+ (data[1] != cpu_to_be32(0x7e2d8a69)) ||
-+ (data[2] != cpu_to_be32(0x290233f1)) ||
-+ (data[3] != cpu_to_be32(0xf3dff5a9)))
-+ {
-+ FAILED("encrypted key incorrect");
-+ printk("%08x%08x%08x%08x\n",data[0],data[1],data[2],data[3]);
-+ }
-+ }
-+
-+ return failed;
-+
-+}
-+
-+
-+/*************************************************************************/
-+static int test7(void) {
-+ int failed = 0;
-+ u32 reg;
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // authenticate
-+ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+
-+ // setup for key encryption
-+ reg = OX800DPE_CTL_DIRECTION_ENC |
-+ OX800DPE_CTL_ENCRYPT_KEY |
-+ OX800DPE_CTL_MODE_ECB_AES;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ // shouldn't be busy
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle even with incomplete data");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx not empty before data input ");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx fifo filling without data");
-+
-+ // data to be encrypted to form a key
-+ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_DATA_IN0 );
-+ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_DATA_IN1 );
-+ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_DATA_IN2 );
-+ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_DATA_IN3 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ /* output should be empty */
-+ reg = READL( OX800DPE_STATUS );
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after fetching ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ {
-+ u32 data[4];
-+
-+ data[0] = READL( OX800DPE_KEY00 );
-+ data[1] = READL( OX800DPE_KEY01 );
-+ data[2] = READL( OX800DPE_KEY02 );
-+ data[3] = READL( OX800DPE_KEY03 );
-+
-+ if ((data[0] != cpu_to_be32(0x4791b833)) ||
-+ (data[1] != cpu_to_be32(0x7e2d8a69)) ||
-+ (data[2] != cpu_to_be32(0x290233f1)) ||
-+ (data[3] != cpu_to_be32(0xf3dff5a9)))
-+ {
-+ FAILED("encrypted key incorrect");
-+ printk("%08x%08x%08x%08x\n",data[0],data[1],data[2],data[3]);
-+ }
-+ }
-+
-+ return failed;
-+
-+}
-+
-+
-+
-+/**********************************************************************/
-+/* CBC tests */
-+/**********************************************************************/
-+
-+static int test8(void) {
-+ int failed = 0;
-+ u32 reg;
-+ oxnas_dma_channel_t* dma_in;
-+ oxnas_dma_channel_t* dma_out;
-+ dma_addr_t in_address;
-+ dma_addr_t out_address;
-+
-+ u32* data_in;
-+ u32* data_out;
-+
-+ // setup dmas
-+ dma_in = oxnas_dma_request(1);
-+ dma_out = oxnas_dma_request(1);
-+
-+ // get some dma accessable memory
-+ data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+ data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+
-+ // fill with input and non expected output
-+ data_in[0] = be32_to_cpu( 0x00112233);
-+ data_in[1] = be32_to_cpu( 0x44556677);
-+ data_in[2] = be32_to_cpu( 0x8899aabb);
-+ data_in[3] = be32_to_cpu( 0xccddeeff);
-+ data_in[4] = be32_to_cpu( 0x00112233);
-+ data_in[5] = be32_to_cpu( 0x44556677);
-+ data_in[6] = be32_to_cpu( 0x8899aabb);
-+ data_in[7] = be32_to_cpu( 0xccddeeff);
-+ data_out[0] = ~0;
-+ data_out[1] = ~0;
-+ data_out[2] = ~0;
-+ data_out[3] = ~0;
-+ data_out[4] = ~0;
-+ data_out[5] = ~0;
-+ data_out[6] = ~0;
-+ data_out[7] = ~0;
-+
-+ // map the dma regons
-+ in_address = dma_map_single(
-+ 0,
-+ data_in,
-+ 8 * sizeof(u32),
-+ DMA_TO_DEVICE);
-+
-+ // map the dma regons
-+ out_address = dma_map_single(
-+ 0,
-+ data_out,
-+ 8 * sizeof(u32),
-+ DMA_FROM_DEVICE);
-+
-+ // setup the transfers
-+ oxnas_dma_device_set(
-+ dma_in,
-+ OXNAS_DMA_TO_DEVICE,
-+ (char*)in_address,
-+ 8 * sizeof(u32),
-+ &oxnas_dpe_rx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ oxnas_dma_device_set(
-+ dma_out,
-+ OXNAS_DMA_FROM_DEVICE,
-+ (char*)out_address,
-+ 8 * sizeof(u32),
-+ &oxnas_dpe_tx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+ // don't authenticate
-+ WRITEL(0 ,OX800IBW_STATUS);
-+
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for encryption
-+ reg = OX800DPE_CTL_DIRECTION_ENC |
-+ OX800DPE_CTL_MODE_CBC_AES;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ reg = READL( OX800DPE_STATUS );
-+ // shouldn't be busy
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle even with incomplete data");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx not empty before data input ");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx fifo filling without data");
-+
-+
-+ // key no 1
-+ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
-+ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
-+ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
-+ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ // setup initialisation vector
-+ WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC0 );
-+ WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC1 );
-+
-+ // start dma transfers
-+ oxnas_dma_start(dma_out);
-+ oxnas_dma_start(dma_in);
-+
-+ /* wait until dma done */
-+ while( oxnas_dma_is_active( dma_out ) );
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ /* output should be empty */
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after fetching ");
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ dma_unmap_single(0, in_address, 8 * sizeof(u32), DMA_TO_DEVICE);
-+ dma_unmap_single(0, out_address, 8 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+ /* check output */
-+ if ((data_out[0] != cpu_to_be32(0x69c4e0d8)) ||
-+ (data_out[1] != cpu_to_be32(0x6a7b0430)) ||
-+ (data_out[2] != cpu_to_be32(0xd8cdb780)) ||
-+ (data_out[3] != cpu_to_be32(0x70b4c55a)) ||
-+
-+ (data_out[4] != cpu_to_be32(0x7d7786be)) ||
-+ (data_out[5] != cpu_to_be32(0x32d059a6)) ||
-+ (data_out[6] != cpu_to_be32(0x0ca8021a)) ||
-+ (data_out[7] != cpu_to_be32(0x65dd9f09)))
-+ {
-+ FAILED("encryption output incorrect");
-+ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+ printk("%08x%08x%08x%08x\n",data_out[4],data_out[5],data_out[6],data_out[7]);
-+ }
-+
-+ // free dmas
-+ oxnas_dma_free( dma_in );
-+ oxnas_dma_free( dma_out );
-+
-+ kfree(data_in);
-+ kfree(data_out);
-+
-+ return failed;
-+
-+}
-+
-+
-+/*************************************************************************/
-+static int test9(void) {
-+ int failed = 0;
-+ u32 reg;
-+ oxnas_dma_channel_t* dma_in;
-+ oxnas_dma_channel_t* dma_out;
-+ dma_addr_t in_address;
-+ dma_addr_t out_address;
-+
-+ u32* data_in;
-+ u32* data_out;
-+
-+ // setup dmas
-+ dma_in = oxnas_dma_request(1);
-+ dma_out = oxnas_dma_request(1);
-+
-+ // get some dma accessable memory
-+ data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+ data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+
-+ // fill with input and non expected output
-+ data_in[0] = be32_to_cpu( 0x69c4e0d8);
-+ data_in[1] = be32_to_cpu( 0x6a7b0430);
-+ data_in[2] = be32_to_cpu( 0xd8cdb780);
-+ data_in[3] = be32_to_cpu( 0x70b4c55a);
-+ data_in[4] = be32_to_cpu( 0x7d7786be);
-+ data_in[5] = be32_to_cpu( 0x32d059a6);
-+ data_in[6] = be32_to_cpu( 0x0ca8021a);
-+ data_in[7] = be32_to_cpu( 0x65dd9f09);
-+ data_out[0] = ~0;
-+ data_out[1] = ~0;
-+ data_out[2] = ~0;
-+ data_out[3] = ~0;
-+ data_out[4] = ~0;
-+ data_out[5] = ~0;
-+ data_out[6] = ~0;
-+ data_out[7] = ~0;
-+
-+ // map the dma regons
-+ in_address = dma_map_single(
-+ 0,
-+ data_in,
-+ 8 * sizeof(u32),
-+ DMA_TO_DEVICE);
-+
-+ // map the dma regons
-+ out_address = dma_map_single(
-+ 0,
-+ data_out,
-+ 8 * sizeof(u32),
-+ DMA_FROM_DEVICE);
-+
-+ // setup the transfers
-+ oxnas_dma_device_set(
-+ dma_in,
-+ OXNAS_DMA_TO_DEVICE,
-+ (char*)in_address,
-+ 8 * sizeof(u32),
-+ &oxnas_dpe_rx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ oxnas_dma_device_set(
-+ dma_out,
-+ OXNAS_DMA_FROM_DEVICE,
-+ (char*)out_address,
-+ 8 * sizeof(u32),
-+ &oxnas_dpe_tx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ // authenticate
-+ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for decryption
-+ reg = OX800DPE_CTL_MODE_CBC_AES;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ reg = READL( OX800DPE_STATUS );
-+ // shouldn't be busy
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle even with incomplete data");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx not empty before data input ");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx fifo filling without data");
-+
-+
-+ // key no 1
-+ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
-+ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
-+ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
-+ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ // setup initialisation vector
-+ WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC0 );
-+ WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC1 );
-+
-+ // start dma transfers
-+ oxnas_dma_start(dma_out);
-+ oxnas_dma_start(dma_in);
-+
-+ /* wait until done */
-+ while( oxnas_dma_is_active( dma_out ) );
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ /* output should be empty */
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after fetching ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ dma_unmap_single(0, in_address, 8 * sizeof(u32), DMA_TO_DEVICE);
-+ dma_unmap_single(0, out_address, 8 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+ /* check output */
-+ if ((data_out[0] != cpu_to_be32(0x00112233)) ||
-+ (data_out[1] != cpu_to_be32(0x44556677)) ||
-+ (data_out[2] != cpu_to_be32(0x8899aabb)) ||
-+ (data_out[3] != cpu_to_be32(0xccddeeff)) ||
-+ (data_out[4] != cpu_to_be32(0x00112233)) ||
-+ (data_out[5] != cpu_to_be32(0x44556677)) ||
-+ (data_out[6] != cpu_to_be32(0x8899aabb)) ||
-+ (data_out[7] != cpu_to_be32(0xccddeeff)))
-+ {
-+ FAILED("encryption output incorrect");
-+ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+ printk("%08x%08x%08x%08x\n",data_out[4],data_out[5],data_out[6],data_out[7]);
-+ }
-+
-+ // free dmas
-+ oxnas_dma_free( dma_in );
-+ oxnas_dma_free( dma_out );
-+
-+ kfree(data_in);
-+ kfree(data_out);
-+
-+ return failed;
-+
-+}
-+
-+/*************************************************************************/
-+static int test10(void) {
-+ int failed = 0;
-+ u32 reg;
-+ oxnas_dma_channel_t* dma_in;
-+ oxnas_dma_channel_t* dma_out;
-+ dma_addr_t in_address;
-+ dma_addr_t out_address;
-+
-+ u32* data_in;
-+ u32* data_out;
-+
-+ // setup dmas
-+ dma_in = oxnas_dma_request(1);
-+ dma_out = oxnas_dma_request(1);
-+
-+ // get some dma accessable memory
-+ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+
-+ // fill with input and non expected output
-+ data_in[0] = be32_to_cpu( 0x00112233);
-+ data_in[1] = be32_to_cpu( 0x44556677);
-+ data_in[2] = be32_to_cpu( 0x8899aabb);
-+ data_in[3] = be32_to_cpu( 0xccddeeff);
-+ data_out[0] = ~0;
-+ data_out[1] = ~0;
-+ data_out[2] = ~0;
-+ data_out[3] = ~0;
-+
-+ // map the dma regons
-+ in_address = dma_map_single(
-+ 0,
-+ data_in,
-+ 4 * sizeof(u32),
-+ DMA_TO_DEVICE);
-+
-+ // map the dma regons
-+ out_address = dma_map_single(
-+ 0,
-+ data_out,
-+ 4 * sizeof(u32),
-+ DMA_FROM_DEVICE);
-+
-+ // setup the transfers
-+ oxnas_dma_device_set(
-+ dma_in,
-+ OXNAS_DMA_TO_DEVICE,
-+ (char*)in_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_rx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ oxnas_dma_device_set(
-+ dma_out,
-+ OXNAS_DMA_FROM_DEVICE,
-+ (char*)out_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_tx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ // don't authenticate
-+ WRITEL(0 ,OX800IBW_STATUS);
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for encryption
-+ reg = OX800DPE_CTL_DIRECTION_ENC |
-+ OX800DPE_CTL_MODE_CBC_AES;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ reg = READL( OX800DPE_STATUS );
-+ // shouldn't be busy
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle even with incomplete data");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx not empty before data input ");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx fifo filling without data");
-+
-+
-+ // key no 1
-+ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
-+ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
-+ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
-+ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ // setup initialisation vector
-+ WRITEL(be32_to_cpu(~0), OX800DPE_DATA_CBC0 );
-+ WRITEL(be32_to_cpu(~0), OX800DPE_DATA_CBC1 );
-+
-+ // start dma transfers
-+ oxnas_dma_start(dma_out);
-+ oxnas_dma_start(dma_in);
-+
-+ /* wait until done */
-+ while( oxnas_dma_is_active( dma_out ) );
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ /* output should be empty */
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after fetching ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+ /* check output */
-+ if ((data_out[0] != cpu_to_be32(0x0bde5b88)) ||
-+ (data_out[1] != cpu_to_be32(0x114ac430)) ||
-+ (data_out[2] != cpu_to_be32(0x134e99ee)) ||
-+ (data_out[3] != cpu_to_be32(0xd3557046)))
-+ {
-+ FAILED("encryption output incorrect");
-+ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+ }
-+
-+ // free dmas
-+ oxnas_dma_free( dma_in );
-+ oxnas_dma_free( dma_out );
-+
-+ kfree(data_in);
-+ kfree(data_out);
-+
-+ return failed;
-+
-+}
-+
-+
-+/*************************************************************************/
-+static int test11(void) {
-+ int failed = 0;
-+ u32 reg;
-+ oxnas_dma_channel_t* dma_in;
-+ oxnas_dma_channel_t* dma_out;
-+ dma_addr_t in_address;
-+ dma_addr_t out_address;
-+
-+ u32* data_in;
-+ u32* data_out;
-+
-+ // setup dmas
-+ dma_in = oxnas_dma_request(1);
-+ dma_out = oxnas_dma_request(1);
-+
-+ // get some dma accessable memory
-+ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+
-+ // fill with input and non expected output
-+ data_in[0] = be32_to_cpu( 0x69c4e0d8);
-+ data_in[1] = be32_to_cpu( 0x6a7b0430);
-+ data_in[2] = be32_to_cpu( 0xd8cdb780);
-+ data_in[3] = be32_to_cpu( 0x70b4c55a);
-+ data_out[0] = ~0;
-+ data_out[1] = ~0;
-+ data_out[2] = ~0;
-+ data_out[3] = ~0;
-+
-+ // map the dma regons
-+ in_address = dma_map_single(
-+ 0,
-+ data_in,
-+ 4 * sizeof(u32),
-+ DMA_TO_DEVICE);
-+
-+ // map the dma regons
-+ out_address = dma_map_single(
-+ 0,
-+ data_out,
-+ 4 * sizeof(u32),
-+ DMA_FROM_DEVICE);
-+
-+ // setup the transfers
-+ oxnas_dma_device_set(
-+ dma_in,
-+ OXNAS_DMA_TO_DEVICE,
-+ (char*)in_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_rx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ oxnas_dma_device_set(
-+ dma_out,
-+ OXNAS_DMA_FROM_DEVICE,
-+ (char*)out_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_tx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ // authenticate
-+ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for decryption
-+ reg = OX800DPE_CTL_MODE_CBC_AES;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ reg = READL( OX800DPE_STATUS );
-+ // shouldn't be busy
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle even with incomplete data");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx not empty before data input ");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx fifo filling without data");
-+
-+
-+ // key no 1
-+ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
-+ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
-+ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
-+ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ // setup initialisation vector
-+ WRITEL(be32_to_cpu(~0), OX800DPE_DATA_CBC0 );
-+ WRITEL(be32_to_cpu(~0), OX800DPE_DATA_CBC1 );
-+
-+ // start dma transfers
-+ oxnas_dma_start(dma_out);
-+ oxnas_dma_start(dma_in);
-+
-+ /* wait until done */
-+ while( oxnas_dma_is_active( dma_out ) );
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ /* output should be empty */
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after fetching ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+ /* check output */
-+ if ((data_out[0] != cpu_to_be32(0x00112233)) ||
-+ (data_out[1] != cpu_to_be32(0x44556677)) ||
-+ (data_out[2] != cpu_to_be32(0x8899aab4)) ||
-+ (data_out[3] != cpu_to_be32(0x33221100)))
-+ {
-+ FAILED("encryption output incorrect");
-+ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+ }
-+
-+ // free dmas
-+ oxnas_dma_free( dma_in );
-+ oxnas_dma_free( dma_out );
-+
-+ kfree(data_in);
-+ kfree(data_out);
-+
-+ return failed;
-+
-+}
-+
-+/*************************************************************************/
-+static int test12(void) {
-+ int failed = 0;
-+ u32 reg;
-+ oxnas_dma_channel_t* dma_in;
-+ oxnas_dma_channel_t* dma_out;
-+ dma_addr_t in_address;
-+ dma_addr_t out_address;
-+
-+ u32* data_in;
-+ u32* data_out;
-+
-+ // setup dmas
-+ dma_in = oxnas_dma_request(1);
-+ dma_out = oxnas_dma_request(1);
-+
-+ // get some dma accessable memory
-+ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+
-+ // fill with input and non expected output
-+ data_in[0] = be32_to_cpu( 0x00112233);
-+ data_in[1] = be32_to_cpu( 0x44556677);
-+ data_in[2] = be32_to_cpu( 0x8899aabb);
-+ data_in[3] = be32_to_cpu( 0xccddeeff);
-+ data_out[0] = ~0;
-+ data_out[1] = ~0;
-+ data_out[2] = ~0;
-+ data_out[3] = ~0;
-+
-+ // map the dma regons
-+ in_address = dma_map_single(
-+ 0,
-+ data_in,
-+ 4 * sizeof(u32),
-+ DMA_TO_DEVICE);
-+
-+ // map the dma regons
-+ out_address = dma_map_single(
-+ 0,
-+ data_out,
-+ 4 * sizeof(u32),
-+ DMA_FROM_DEVICE);
-+
-+ // setup the transfers
-+ oxnas_dma_device_set(
-+ dma_in,
-+ OXNAS_DMA_TO_DEVICE,
-+ (char*)in_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_rx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ oxnas_dma_device_set(
-+ dma_out,
-+ OXNAS_DMA_FROM_DEVICE,
-+ (char*)out_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_tx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ // don't authenticate
-+ WRITEL(0 ,OX800IBW_STATUS);
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for encryption
-+ reg = OX800DPE_CTL_DIRECTION_ENC |
-+ OX800DPE_CTL_MODE_CBC_AES;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ reg = READL( OX800DPE_STATUS );
-+ // shouldn't be busy
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle even with incomplete data");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx not empty before data input ");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx fifo filling without data");
-+
-+
-+ // key no 1
-+ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
-+ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
-+ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
-+ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ // setup initialisation vector
-+ WRITEL(be32_to_cpu(1), OX800DPE_DATA_CBC0 );
-+ WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC1 );
-+
-+ // start dma transfers
-+ oxnas_dma_start(dma_out);
-+ oxnas_dma_start(dma_in);
-+
-+ /* wait until done */
-+ while( oxnas_dma_is_active( dma_out ) );
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ /* output should be empty */
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after fetching ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+
-+
-+
-+
-+ /* check output */
-+ if ((data_out[0] != 0x850d2506) ||
-+ (data_out[1] != 0xd71056c7) ||
-+ (data_out[2] != 0xe62c220f) ||
-+ (data_out[3] != 0xc3dedaf9))
-+ {
-+ FAILED("encryption output incorrect");
-+ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+ }
-+
-+ // free dmas
-+ oxnas_dma_free( dma_in );
-+ oxnas_dma_free( dma_out );
-+
-+ kfree(data_in);
-+ kfree(data_out);
-+
-+ return failed;
-+
-+}
-+
-+
-+/*************************************************************************/
-+static int test13(void) {
-+ int failed = 0;
-+ u32 reg;
-+ oxnas_dma_channel_t* dma_in;
-+ oxnas_dma_channel_t* dma_out;
-+ dma_addr_t in_address;
-+ dma_addr_t out_address;
-+
-+ u32* data_in;
-+ u32* data_out;
-+
-+ // setup dmas
-+ dma_in = oxnas_dma_request(1);
-+ dma_out = oxnas_dma_request(1);
-+
-+ // get some dma accessable memory
-+ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+
-+ // fill with input and non expected output
-+ data_in[0] = 0x850d2506;
-+ data_in[1] = 0xd71056c7;
-+ data_in[2] = 0xe62c220f;
-+ data_in[3] = 0xc3dedaf9;
-+ data_out[0] = ~0;
-+ data_out[1] = ~0;
-+ data_out[2] = ~0;
-+ data_out[3] = ~0;
-+
-+ // map the dma regons
-+ in_address = dma_map_single(
-+ 0,
-+ data_in,
-+ 4 * sizeof(u32),
-+ DMA_TO_DEVICE);
-+
-+ // map the dma regons
-+ out_address = dma_map_single(
-+ 0,
-+ data_out,
-+ 4 * sizeof(u32),
-+ DMA_FROM_DEVICE);
-+
-+ // setup the transfers
-+ oxnas_dma_device_set(
-+ dma_in,
-+ OXNAS_DMA_TO_DEVICE,
-+ (char*)in_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_rx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ oxnas_dma_device_set(
-+ dma_out,
-+ OXNAS_DMA_FROM_DEVICE,
-+ (char*)out_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_tx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ // authenticate
-+ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for decryption
-+ reg = OX800DPE_CTL_MODE_CBC_AES;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ reg = READL( OX800DPE_STATUS );
-+ // shouldn't be busy
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle even with incomplete data");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx not empty before data input ");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx fifo filling without data");
-+
-+
-+ // key no 1
-+ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
-+ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
-+ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
-+ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ // setup initialisation vector
-+ WRITEL(be32_to_cpu(1), OX800DPE_DATA_CBC0 );
-+ WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC1 );
-+
-+ // start dma transfers
-+ oxnas_dma_start(dma_out);
-+ oxnas_dma_start(dma_in);
-+
-+ /* wait until done */
-+ while( oxnas_dma_is_active( dma_out ) );
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ /* output should be empty */
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after fetching ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+ /* check output */
-+ if ((data_out[0] != cpu_to_be32(0x00112233)) ||
-+ (data_out[1] != cpu_to_be32(0x44556677)) ||
-+ (data_out[2] != cpu_to_be32(0x8899aabb)) ||
-+ (data_out[3] != cpu_to_be32(0xccddeeff)))
-+ {
-+ FAILED("encryption output incorrect");
-+ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+ }
-+
-+ // free dmas
-+ oxnas_dma_free( dma_in );
-+ oxnas_dma_free( dma_out );
-+
-+ kfree(data_in);
-+ kfree(data_out);
-+
-+ return failed;
-+
-+}
-+
-+
-+/**********************************************************************/
-+/* LRW tests */
-+/**********************************************************************/
-+
-+static int test14(void) {
-+ int failed = 0;
-+ u32 reg;
-+ oxnas_dma_channel_t* dma_in;
-+ oxnas_dma_channel_t* dma_out;
-+ dma_addr_t in_address;
-+ dma_addr_t out_address;
-+
-+ u32* data_in;
-+ u32* data_out;
-+
-+ // setup dmas
-+ dma_in = oxnas_dma_request(1);
-+ dma_out = oxnas_dma_request(1);
-+
-+ // get some dma accessable memory
-+ data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+ data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+
-+ // fill with input and non expected output
-+ data_in[0] = be32_to_cpu( 0x30313233);
-+ data_in[1] = be32_to_cpu( 0x34353637);
-+ data_in[2] = be32_to_cpu( 0x38394142);
-+ data_in[3] = be32_to_cpu( 0x43444546);
-+ data_in[4] = be32_to_cpu( 0x30313233);
-+ data_in[5] = be32_to_cpu( 0x34353637);
-+ data_in[6] = be32_to_cpu( 0x38394142);
-+ data_in[7] = be32_to_cpu( 0x43444546);
-+ data_out[0] = ~0;
-+ data_out[1] = ~0;
-+ data_out[2] = ~0;
-+ data_out[3] = ~0;
-+ data_out[4] = ~0;
-+ data_out[5] = ~0;
-+ data_out[6] = ~0;
-+ data_out[7] = ~0;
-+
-+ // map the dma regons
-+ in_address = dma_map_single(
-+ 0,
-+ data_in,
-+ 8 * sizeof(u32),
-+ DMA_TO_DEVICE);
-+
-+ // map the dma regons
-+ out_address = dma_map_single(
-+ 0,
-+ data_out,
-+ 8 * sizeof(u32),
-+ DMA_FROM_DEVICE);
-+
-+ // setup the transfers
-+ oxnas_dma_device_set(
-+ dma_in,
-+ OXNAS_DMA_TO_DEVICE,
-+ (char*)in_address,
-+ 8 * sizeof(u32),
-+ &oxnas_dpe_rx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ oxnas_dma_device_set(
-+ dma_out,
-+ OXNAS_DMA_FROM_DEVICE,
-+ (char*)out_address,
-+ 8 * sizeof(u32),
-+ &oxnas_dpe_tx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ // don't authenticate
-+ WRITEL(0 ,OX800IBW_STATUS);
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for encryption
-+ reg = OX800DPE_CTL_DIRECTION_ENC |
-+ OX800DPE_CTL_MODE_LRW_AES;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ // key no 1
-+ WRITEL(be32_to_cpu( 0x4562ac25), OX800DPE_KEY00 );
-+ WRITEL(be32_to_cpu( 0xf828176d), OX800DPE_KEY01 );
-+ WRITEL(be32_to_cpu( 0x4c268414), OX800DPE_KEY02 );
-+ WRITEL(be32_to_cpu( 0xb5680185), OX800DPE_KEY03 );
-+
-+ // key no 2
-+ WRITEL(be32_to_cpu( 0x258e2a05), OX800DPE_KEY10 );
-+ WRITEL(be32_to_cpu( 0xe73e9d03), OX800DPE_KEY11 );
-+ WRITEL(be32_to_cpu( 0xee5a830c), OX800DPE_KEY12 );
-+ WRITEL(be32_to_cpu( 0xcc094c87), OX800DPE_KEY13 );
-+
-+ // setup index
-+ WRITEL(0, OX800DPE_DATA_LRW0 );
-+ WRITEL(0, OX800DPE_DATA_LRW1 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ // start dma transfers
-+ oxnas_dma_start(dma_out);
-+ oxnas_dma_start(dma_in);
-+
-+ /* wait until dma done */
-+ while( oxnas_dma_is_active( dma_out ) );
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ /* output should be empty */
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after fetching ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ dma_unmap_single(0, in_address, 8 * sizeof(u32), DMA_TO_DEVICE);
-+ dma_unmap_single(0, out_address, 8 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+ /*
-+ check output.
-+ note: first 4 quads contain unwanted data used to set
-+ tweek location to 1, they are not checked.
-+ */
-+ if ((data_out[4] != cpu_to_be32(0xf1b273cd)) ||
-+ (data_out[5] != cpu_to_be32(0x65a3df5f)) ||
-+ (data_out[6] != cpu_to_be32(0xe95d4892)) ||
-+ (data_out[7] != cpu_to_be32(0x54634eb8)))
-+ {
-+ FAILED("encryption output incorrect");
-+ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+ printk("%08x%08x%08x%08x\n",data_out[4],data_out[5],data_out[6],data_out[7]);
-+ }
-+
-+ // free dmas
-+ oxnas_dma_free( dma_in );
-+ oxnas_dma_free( dma_out );
-+
-+ kfree(data_in);
-+ kfree(data_out);
-+
-+ return failed;
-+
-+}
-+
-+
-+/*************************************************************************/
-+static int test15(void) {
-+ int failed = 0;
-+ u32 reg;
-+ oxnas_dma_channel_t* dma_in;
-+ oxnas_dma_channel_t* dma_out;
-+ dma_addr_t in_address;
-+ dma_addr_t out_address;
-+
-+ u32* data_in;
-+ u32* data_out;
-+
-+ // setup dmas
-+ dma_in = oxnas_dma_request(1);
-+ dma_out = oxnas_dma_request(1);
-+
-+ // get some dma accessable memory
-+ data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+ data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+
-+ // fill with input and non expected output
-+ data_in[0] = be32_to_cpu( 0xf1b273cd);
-+ data_in[1] = be32_to_cpu( 0x65a3df5f);
-+ data_in[2] = be32_to_cpu( 0xe95d4892);
-+ data_in[3] = be32_to_cpu( 0x54634eb8);
-+ data_in[4] = be32_to_cpu( 0xf1b273cd);
-+ data_in[5] = be32_to_cpu( 0x65a3df5f);
-+ data_in[6] = be32_to_cpu( 0xe95d4892);
-+ data_in[7] = be32_to_cpu( 0x54634eb8);
-+ data_out[0] = ~0;
-+ data_out[1] = ~0;
-+ data_out[2] = ~0;
-+ data_out[3] = ~0;
-+ data_out[4] = ~0;
-+ data_out[5] = ~0;
-+ data_out[6] = ~0;
-+ data_out[7] = ~0;
-+
-+ // map the dma regons
-+ in_address = dma_map_single(
-+ 0,
-+ data_in,
-+ 8 * sizeof(u32),
-+ DMA_TO_DEVICE);
-+
-+ // map the dma regons
-+ out_address = dma_map_single(
-+ 0,
-+ data_out,
-+ 8 * sizeof(u32),
-+ DMA_FROM_DEVICE);
-+
-+ // setup the transfers
-+ oxnas_dma_device_set(
-+ dma_in,
-+ OXNAS_DMA_TO_DEVICE,
-+ (char*)in_address,
-+ 8 * sizeof(u32),
-+ &oxnas_dpe_rx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ oxnas_dma_device_set(
-+ dma_out,
-+ OXNAS_DMA_FROM_DEVICE,
-+ (char*)out_address,
-+ 8 * sizeof(u32),
-+ &oxnas_dpe_tx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ // authenticate
-+ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for decryption
-+ reg = OX800DPE_CTL_MODE_LRW_AES |
-+ OX800DPE_CTL_PRIMARY_IS_KEY3;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ // key no 1
-+ WRITEL(be32_to_cpu( 0x4562ac25), OX800DPE_KEY20 );
-+ WRITEL(be32_to_cpu( 0xf828176d), OX800DPE_KEY21 );
-+ WRITEL(be32_to_cpu( 0x4c268414), OX800DPE_KEY22 );
-+ WRITEL(be32_to_cpu( 0xb5680185), OX800DPE_KEY23 );
-+
-+ // key no 2
-+ WRITEL(be32_to_cpu( 0x258e2a05), OX800DPE_KEY10 );
-+ WRITEL(be32_to_cpu( 0xe73e9d03), OX800DPE_KEY11 );
-+ WRITEL(be32_to_cpu( 0xee5a830c), OX800DPE_KEY12 );
-+ WRITEL(be32_to_cpu( 0xcc094c87), OX800DPE_KEY13 );
-+
-+ // setup index
-+ WRITEL(0, OX800DPE_DATA_LRW0 );
-+ WRITEL(0, OX800DPE_DATA_LRW1 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ // start dma transfers
-+ oxnas_dma_start(dma_out);
-+ oxnas_dma_start(dma_in);
-+
-+ /* wait until done */
-+ while( oxnas_dma_is_active( dma_out ) );
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ /* output should be empty */
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after fetching ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ dma_unmap_single(0, in_address, 8 * sizeof(u32), DMA_TO_DEVICE);
-+ dma_unmap_single(0, out_address, 8 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+ /* check output */
-+ if ((data_out[4] != cpu_to_be32(0x30313233)) ||
-+ (data_out[5] != cpu_to_be32(0x34353637)) ||
-+ (data_out[6] != cpu_to_be32(0x38394142)) ||
-+ (data_out[7] != cpu_to_be32(0x43444546)))
-+ {
-+ FAILED("encryption output incorrect");
-+ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+ printk("%08x%08x%08x%08x\n",data_out[4],data_out[5],data_out[6],data_out[7]);
-+ }
-+
-+ // free dmas
-+ oxnas_dma_free( dma_in );
-+ oxnas_dma_free( dma_out );
-+
-+ kfree(data_in);
-+ kfree(data_out);
-+
-+ return failed;
-+
-+}
-+
-+/*************************************************************************/
-+static int test16(void) {
-+ int failed = 0;
-+ u32 reg;
-+ oxnas_dma_channel_t* dma_in;
-+ oxnas_dma_channel_t* dma_out;
-+ dma_addr_t in_address;
-+ dma_addr_t out_address;
-+
-+ u32* data_in;
-+ u32* data_out;
-+
-+ // setup dmas
-+ dma_in = oxnas_dma_request(1);
-+ dma_out = oxnas_dma_request(1);
-+
-+ // get some dma accessable memory
-+ data_in = (u32*)kmalloc( 12 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+ data_out = (u32*)kmalloc( 12 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+
-+ // fill with input and non expected output
-+ data_in[8 ] = be32_to_cpu( 0x30313233);
-+ data_in[9 ] = be32_to_cpu( 0x34353637);
-+ data_in[10] = be32_to_cpu( 0x38394142);
-+ data_in[11] = be32_to_cpu( 0x43444546);
-+ data_out[0] = ~0;
-+ data_out[1] = ~0;
-+ data_out[2] = ~0;
-+ data_out[3] = ~0;
-+ data_out[4] = ~0;
-+ data_out[5] = ~0;
-+ data_out[6] = ~0;
-+ data_out[7] = ~0;
-+ data_out[8] = ~0;
-+ data_out[9] = ~0;
-+ data_out[10] = ~0;
-+ data_out[11] = ~0;
-+
-+ // map the dma regons
-+ in_address = dma_map_single(
-+ 0,
-+ data_in,
-+ 12 * sizeof(u32),
-+ DMA_TO_DEVICE);
-+
-+ // map the dma regons
-+ out_address = dma_map_single(
-+ 0,
-+ data_out,
-+ 12 * sizeof(u32),
-+ DMA_FROM_DEVICE);
-+
-+ // setup the transfers
-+ oxnas_dma_device_set(
-+ dma_in,
-+ OXNAS_DMA_TO_DEVICE,
-+ (char*)in_address,
-+ 12 * sizeof(u32),
-+ &oxnas_dpe_rx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ oxnas_dma_device_set(
-+ dma_out,
-+ OXNAS_DMA_FROM_DEVICE,
-+ (char*)out_address,
-+ 12 * sizeof(u32),
-+ &oxnas_dpe_tx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ // don't authenticate
-+ WRITEL(0 ,OX800IBW_STATUS);
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for encryption
-+ reg = OX800DPE_CTL_DIRECTION_ENC |
-+ OX800DPE_CTL_PRIMARY_IS_KEY3 |
-+ OX800DPE_CTL_MODE_LRW_AES;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ // key no 1
-+ WRITEL(be32_to_cpu( 0x59704714), OX800DPE_KEY20 );
-+ WRITEL(be32_to_cpu( 0xf557478c), OX800DPE_KEY21 );
-+ WRITEL(be32_to_cpu( 0xd779e80f), OX800DPE_KEY22 );
-+ WRITEL(be32_to_cpu( 0x54887944), OX800DPE_KEY23 );
-+
-+ // key no 2
-+ WRITEL(be32_to_cpu( 0x0d48f0b7), OX800DPE_KEY10 );
-+ WRITEL(be32_to_cpu( 0xb15a53ea), OX800DPE_KEY11 );
-+ WRITEL(be32_to_cpu( 0x1caa6b29), OX800DPE_KEY12 );
-+ WRITEL(be32_to_cpu( 0xc2cafbaf), OX800DPE_KEY13 );
-+
-+ // setup index
-+ WRITEL(0, OX800DPE_DATA_LRW0 );
-+ WRITEL(0, OX800DPE_DATA_LRW1 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ // start dma transfers
-+ oxnas_dma_start(dma_out);
-+ oxnas_dma_start(dma_in);
-+
-+ /* wait until dma done */
-+ while( oxnas_dma_is_active( dma_out ) );
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ /* output should be empty */
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after fetching ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ dma_unmap_single(0, in_address, 12 * sizeof(u32), DMA_TO_DEVICE);
-+ dma_unmap_single(0, out_address, 12 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+ /*
-+ check output.
-+ note: first 4 quads contain unwanted data used to set
-+ tweek location to 1, they are not checked.
-+ */
-+ if ((data_out[ 8] != cpu_to_be32(0x00c82bae)) ||
-+ (data_out[ 9] != cpu_to_be32(0x95bbcde5)) ||
-+ (data_out[10] != cpu_to_be32(0x274f0769)) ||
-+ (data_out[11] != cpu_to_be32(0xb260e136)))
-+ {
-+ FAILED("encryption output incorrect");
-+ printk("%08x%08x%08x%08x\n",data_out[8],data_out[9],data_out[10],data_out[11]);
-+ }
-+
-+ // free dmas
-+ oxnas_dma_free( dma_in );
-+ oxnas_dma_free( dma_out );
-+
-+ kfree(data_in);
-+ kfree(data_out);
-+
-+ return failed;
-+
-+}
-+
-+
-+/*************************************************************************/
-+static int test17(void) {
-+ int failed = 0;
-+ u32 reg;
-+ oxnas_dma_channel_t* dma_in;
-+ oxnas_dma_channel_t* dma_out;
-+ dma_addr_t in_address;
-+ dma_addr_t out_address;
-+
-+ u32* data_in;
-+ u32* data_out;
-+
-+ // setup dmas
-+ dma_in = oxnas_dma_request(1);
-+ dma_out = oxnas_dma_request(1);
-+
-+ // get some dma accessable memory
-+ data_in = (u32*)kmalloc( 12 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+ data_out = (u32*)kmalloc( 12 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+
-+ // fill with input and non expected output
-+ data_in[ 8] = be32_to_cpu( 0x00c82bae);
-+ data_in[ 9] = be32_to_cpu( 0x95bbcde5);
-+ data_in[10] = be32_to_cpu( 0x274f0769);
-+ data_in[11] = be32_to_cpu( 0xb260e136);
-+ data_out[ 0] = ~0;
-+ data_out[ 1] = ~0;
-+ data_out[ 2] = ~0;
-+ data_out[ 3] = ~0;
-+ data_out[ 4] = ~0;
-+ data_out[ 5] = ~0;
-+ data_out[ 6] = ~0;
-+ data_out[ 7] = ~0;
-+ data_out[ 8] = ~0;
-+ data_out[ 9] = ~0;
-+ data_out[10] = ~0;
-+ data_out[11] = ~0;
-+
-+ // map the dma regons
-+ in_address = dma_map_single(
-+ 0,
-+ data_in,
-+ 12 * sizeof(u32),
-+ DMA_TO_DEVICE);
-+
-+ // map the dma regons
-+ out_address = dma_map_single(
-+ 0,
-+ data_out,
-+ 12 * sizeof(u32),
-+ DMA_FROM_DEVICE);
-+
-+ // setup the transfers
-+ oxnas_dma_device_set(
-+ dma_in,
-+ OXNAS_DMA_TO_DEVICE,
-+ (char*)in_address,
-+ 12 * sizeof(u32),
-+ &oxnas_dpe_rx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ oxnas_dma_device_set(
-+ dma_out,
-+ OXNAS_DMA_FROM_DEVICE,
-+ (char*)out_address,
-+ 12 * sizeof(u32),
-+ &oxnas_dpe_tx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ // authenticate
-+ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for decryption
-+ reg = OX800DPE_CTL_MODE_LRW_AES ;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ // key no 1
-+ WRITEL(be32_to_cpu( 0x59704714), OX800DPE_KEY00 );
-+ WRITEL(be32_to_cpu( 0xf557478c), OX800DPE_KEY01 );
-+ WRITEL(be32_to_cpu( 0xd779e80f), OX800DPE_KEY02 );
-+ WRITEL(be32_to_cpu( 0x54887944), OX800DPE_KEY03 );
-+
-+ // key no 2
-+ WRITEL(be32_to_cpu( 0x0d48f0b7), OX800DPE_KEY10 );
-+ WRITEL(be32_to_cpu( 0xb15a53ea), OX800DPE_KEY11 );
-+ WRITEL(be32_to_cpu( 0x1caa6b29), OX800DPE_KEY12 );
-+ WRITEL(be32_to_cpu( 0xc2cafbaf), OX800DPE_KEY13 );
-+
-+ // setup index
-+ WRITEL(0, OX800DPE_DATA_LRW0 );
-+ WRITEL(0, OX800DPE_DATA_LRW1 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ // start dma transfers
-+ oxnas_dma_start(dma_out);
-+ oxnas_dma_start(dma_in);
-+
-+ /* wait until done */
-+ while( oxnas_dma_is_active( dma_out ) );
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ /* output should be empty */
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after fetching ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ dma_unmap_single(0, in_address, 12 * sizeof(u32), DMA_TO_DEVICE);
-+ dma_unmap_single(0, out_address, 12 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+ /* check output */
-+ if ((data_out[ 8] != cpu_to_be32(0x30313233)) ||
-+ (data_out[ 9] != cpu_to_be32(0x34353637)) ||
-+ (data_out[10] != cpu_to_be32(0x38394142)) ||
-+ (data_out[11] != cpu_to_be32(0x43444546)))
-+ {
-+ FAILED("encryption output incorrect");
-+ printk("%08x%08x%08x%08x\n",data_out[8],data_out[9],data_out[10],data_out[11]);
-+ }
-+
-+ // free dmas
-+ oxnas_dma_free( dma_in );
-+ oxnas_dma_free( dma_out );
-+
-+ kfree(data_in);
-+ kfree(data_out);
-+
-+ return failed;
-+
-+}
-+
-+/*************************************************************************/
-+static int test18(void) {
-+ int failed = 0;
-+ u32 reg;
-+ oxnas_dma_channel_t* dma_in;
-+ oxnas_dma_channel_t* dma_out;
-+ dma_addr_t in_address;
-+ dma_addr_t out_address;
-+
-+ u32* data_in;
-+ u32* data_out;
-+
-+ // setup dmas
-+ dma_in = oxnas_dma_request(1);
-+ dma_out = oxnas_dma_request(1);
-+
-+ // get some dma accessable memory
-+ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+
-+ // fill with input and non expected output
-+ data_in[0] = be32_to_cpu( 0x30313233);
-+ data_in[1] = be32_to_cpu( 0x34353637);
-+ data_in[2] = be32_to_cpu( 0x38394142);
-+ data_in[3] = be32_to_cpu( 0x43444546);
-+ data_out[0] = ~0;
-+ data_out[1] = ~0;
-+ data_out[2] = ~0;
-+ data_out[3] = ~0;
-+
-+ // map the dma regons
-+ in_address = dma_map_single(
-+ 0,
-+ data_in,
-+ 4 * sizeof(u32),
-+ DMA_TO_DEVICE);
-+
-+ // map the dma regons
-+ out_address = dma_map_single(
-+ 0,
-+ data_out,
-+ 4 * sizeof(u32),
-+ DMA_FROM_DEVICE);
-+
-+ // setup the transfers
-+ oxnas_dma_device_set(
-+ dma_in,
-+ OXNAS_DMA_TO_DEVICE,
-+ (char*)in_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_rx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ oxnas_dma_device_set(
-+ dma_out,
-+ OXNAS_DMA_FROM_DEVICE,
-+ (char*)out_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_tx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ // don't authenticate
-+ WRITEL(0 ,OX800IBW_STATUS);
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for encryption
-+ reg = OX800DPE_CTL_DIRECTION_ENC |
-+ OX800DPE_CTL_MODE_LRW_AES;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ // key no 1
-+ WRITEL(be32_to_cpu( 0xd82a9134), OX800DPE_KEY00 );
-+ WRITEL(be32_to_cpu( 0xb26a5650), OX800DPE_KEY01 );
-+ WRITEL(be32_to_cpu( 0x30fe69e2), OX800DPE_KEY02 );
-+ WRITEL(be32_to_cpu( 0x377f9847), OX800DPE_KEY03 );
-+
-+ // key no 2
-+ WRITEL(be32_to_cpu( 0xcdf90b16), OX800DPE_KEY10 );
-+ WRITEL(be32_to_cpu( 0x0c648fb6), OX800DPE_KEY11 );
-+ WRITEL(be32_to_cpu( 0xb00d0d1b), OX800DPE_KEY12 );
-+ WRITEL(be32_to_cpu( 0xae85871f), OX800DPE_KEY13 );
-+
-+ // setup index
-+ WRITEL(0x10000000, OX800DPE_DATA_LRW0 );
-+ WRITEL(0, OX800DPE_DATA_LRW1 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ // start dma transfers
-+ oxnas_dma_start(dma_out);
-+ oxnas_dma_start(dma_in);
-+
-+ /* wait until dma done */
-+ while( oxnas_dma_is_active( dma_out ) );
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ /* output should be empty */
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after fetching ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+ /*
-+ check output.
-+ */
-+ if ((data_out[0] != cpu_to_be32(0x76322183)) ||
-+ (data_out[1] != cpu_to_be32(0xed8ff182)) ||
-+ (data_out[2] != cpu_to_be32(0xf9596203)) ||
-+ (data_out[3] != cpu_to_be32(0x690e5e01)))
-+ {
-+ FAILED("encryption output incorrect");
-+ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+ }
-+
-+ // free dmas
-+ oxnas_dma_free( dma_in );
-+ oxnas_dma_free( dma_out );
-+
-+ kfree(data_in);
-+ kfree(data_out);
-+
-+ return failed;
-+
-+}
-+
-+
-+/*************************************************************************/
-+static int test19(void) {
-+ int failed = 0;
-+ u32 reg;
-+ oxnas_dma_channel_t* dma_in;
-+ oxnas_dma_channel_t* dma_out;
-+ dma_addr_t in_address;
-+ dma_addr_t out_address;
-+
-+ u32* data_in;
-+ u32* data_out;
-+
-+ // setup dmas
-+ dma_in = oxnas_dma_request(1);
-+ dma_out = oxnas_dma_request(1);
-+
-+ // get some dma accessable memory
-+ data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+ data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+
-+ // fill with input and non expected output
-+ data_in[0] = be32_to_cpu( 0x76322183);
-+ data_in[1] = be32_to_cpu( 0xed8ff182);
-+ data_in[2] = be32_to_cpu( 0xf9596203);
-+ data_in[3] = be32_to_cpu( 0x690e5e01);
-+ data_out[0] = ~0;
-+ data_out[1] = ~0;
-+ data_out[2] = ~0;
-+ data_out[3] = ~0;
-+
-+ // map the dma regons
-+ in_address = dma_map_single(
-+ 0,
-+ data_in,
-+ 4 * sizeof(u32),
-+ DMA_TO_DEVICE);
-+
-+ // map the dma regons
-+ out_address = dma_map_single(
-+ 0,
-+ data_out,
-+ 4 * sizeof(u32),
-+ DMA_FROM_DEVICE);
-+
-+ // setup the transfers
-+ oxnas_dma_device_set(
-+ dma_in,
-+ OXNAS_DMA_TO_DEVICE,
-+ (char*)in_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_rx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ oxnas_dma_device_set(
-+ dma_out,
-+ OXNAS_DMA_FROM_DEVICE,
-+ (char*)out_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_tx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ // authenticate
-+ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for decryption
-+ reg = OX800DPE_CTL_MODE_LRW_AES |
-+ OX800DPE_CTL_PRIMARY_IS_KEY3;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ // key no 1
-+ WRITEL(be32_to_cpu( 0xd82a9134), OX800DPE_KEY20 );
-+ WRITEL(be32_to_cpu( 0xb26a5650), OX800DPE_KEY21 );
-+ WRITEL(be32_to_cpu( 0x30fe69e2), OX800DPE_KEY22 );
-+ WRITEL(be32_to_cpu( 0x377f9847), OX800DPE_KEY23 );
-+
-+ // key no 2
-+ WRITEL(be32_to_cpu( 0xcdf90b16), OX800DPE_KEY10 );
-+ WRITEL(be32_to_cpu( 0x0c648fb6), OX800DPE_KEY11 );
-+ WRITEL(be32_to_cpu( 0xb00d0d1b), OX800DPE_KEY12 );
-+ WRITEL(be32_to_cpu( 0xae85871f), OX800DPE_KEY13 );
-+
-+ // setup index
-+ WRITEL(0x10000000, OX800DPE_DATA_LRW0 );
-+ WRITEL(0, OX800DPE_DATA_LRW1 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ // start dma transfers
-+ oxnas_dma_start(dma_out);
-+ oxnas_dma_start(dma_in);
-+
-+ /* wait until done */
-+ while( oxnas_dma_is_active( dma_out ) );
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ /* output should be empty */
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after fetching ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+ /* check output */
-+ if ((data_out[0] != cpu_to_be32(0x30313233)) ||
-+ (data_out[1] != cpu_to_be32(0x34353637)) ||
-+ (data_out[2] != cpu_to_be32(0x38394142)) ||
-+ (data_out[3] != cpu_to_be32(0x43444546)))
-+ {
-+ FAILED("encryption output incorrect");
-+ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+ }
-+
-+ // free dmas
-+ oxnas_dma_free( dma_in );
-+ oxnas_dma_free( dma_out );
-+
-+ kfree(data_in);
-+ kfree(data_out);
-+
-+ return failed;
-+
-+}
-+
-+/*************************************************************************/
-+static int test20(void) {
-+ int failed = 0;
-+ u32 reg;
-+ oxnas_dma_channel_t* dma_in;
-+ oxnas_dma_channel_t* dma_out;
-+ dma_addr_t in_address;
-+ dma_addr_t out_address;
-+
-+ u32* data_in;
-+ u32* data_out;
-+
-+ // setup dmas
-+ dma_in = oxnas_dma_request(1);
-+ dma_out = oxnas_dma_request(1);
-+
-+ // get some dma accessable memory
-+ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+
-+ // fill with input and non expected output
-+ data_in[0] = be32_to_cpu( 0x30313233);
-+ data_in[1] = be32_to_cpu( 0x34353637);
-+ data_in[2] = be32_to_cpu( 0x38394142);
-+ data_in[3] = be32_to_cpu( 0x43444546);
-+ data_out[0] = ~0;
-+ data_out[1] = ~0;
-+ data_out[2] = ~0;
-+ data_out[3] = ~0;
-+
-+ // map the dma regons
-+ in_address = dma_map_single(
-+ 0,
-+ data_in,
-+ 4 * sizeof(u32),
-+ DMA_TO_DEVICE);
-+
-+ // map the dma regons
-+ out_address = dma_map_single(
-+ 0,
-+ data_out,
-+ 4 * sizeof(u32),
-+ DMA_FROM_DEVICE);
-+
-+ // setup the transfers
-+ oxnas_dma_device_set(
-+ dma_in,
-+ OXNAS_DMA_TO_DEVICE,
-+ (char*)in_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_rx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ oxnas_dma_device_set(
-+ dma_out,
-+ OXNAS_DMA_FROM_DEVICE,
-+ (char*)out_address,
-+ 4 * sizeof(u32),
-+ &oxnas_dpe_tx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ // don't authenticate
-+ WRITEL(0 ,OX800IBW_STATUS);
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for encryption
-+ reg = OX800DPE_CTL_DIRECTION_ENC |
-+ OX800DPE_CTL_MODE_LRW_AES;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ // key no 1
-+ WRITEL(be32_to_cpu( 0x4562ac25), OX800DPE_KEY00 );
-+ WRITEL(be32_to_cpu( 0xf828176d), OX800DPE_KEY01 );
-+ WRITEL(be32_to_cpu( 0x4c268414), OX800DPE_KEY02 );
-+ WRITEL(be32_to_cpu( 0xb5680185), OX800DPE_KEY03 );
-+
-+ // key no 2
-+ WRITEL(be32_to_cpu( 0x258e2a05), OX800DPE_KEY10 );
-+ WRITEL(be32_to_cpu( 0xe73e9d03), OX800DPE_KEY11 );
-+ WRITEL(be32_to_cpu( 0xee5a830c), OX800DPE_KEY12 );
-+ WRITEL(be32_to_cpu( 0xcc094c87), OX800DPE_KEY13 );
-+
-+ // setup index
-+ WRITEL(0x00000000, OX800DPE_DATA_LRW0 );
-+ WRITEL(0x00000008, OX800DPE_DATA_LRW1 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ // start dma transfers
-+ oxnas_dma_start(dma_out);
-+ oxnas_dma_start(dma_in);
-+
-+ /* wait until dma done */
-+ while( oxnas_dma_is_active( dma_out ) );
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ /* output should be empty */
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after fetching ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
-+ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+ /*
-+ check output.
-+ */
-+ if ((data_out[0] == 0xc0a37fda) )
-+ {
-+ FAILED("encryption output indicates most significant bit is ignored.");
-+ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
-+ }
-+
-+ // free dmas
-+ oxnas_dma_free( dma_in );
-+ oxnas_dma_free( dma_out );
-+
-+ kfree(data_in);
-+ kfree(data_out);
-+
-+ return failed;
-+
-+}
-+
-+
-+/*************************************************************************/
-+static int test21(void) {
-+ int failed = 0;
-+ u32 reg;
-+ oxnas_dma_channel_t* dma_in;
-+ oxnas_dma_channel_t* dma_out;
-+ dma_addr_t in_address;
-+ dma_addr_t out_address;
-+
-+ u32* data_in;
-+ u32* data_out;
-+
-+ // setup dmas
-+ dma_in = oxnas_dma_request(1);
-+ dma_out = oxnas_dma_request(1);
-+
-+ // get some dma accessable memory (512B + 16B
-+ data_in = (u32*)kmalloc( 132 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+ data_out = (u32*)kmalloc( 132 * sizeof(u32), GFP_KERNEL|GFP_DMA);
-+
-+ // fill with input and non expected output
-+ data_in[128] = be32_to_cpu( 0x30313233);
-+ data_in[129] = be32_to_cpu( 0x34353637);
-+ data_in[130] = be32_to_cpu( 0x38394142);
-+ data_in[131] = be32_to_cpu( 0x43444546);
-+ data_out[128] = ~0;
-+ data_out[129] = ~0;
-+ data_out[130] = ~0;
-+ data_out[131] = ~0;
-+
-+ // map the dma regons
-+ in_address = dma_map_single(
-+ 0,
-+ data_in,
-+ 132 * sizeof(u32),
-+ DMA_TO_DEVICE);
-+
-+ // map the dma regons
-+ out_address = dma_map_single(
-+ 0,
-+ data_out,
-+ 132 * sizeof(u32),
-+ DMA_FROM_DEVICE);
-+
-+ // setup the transfers
-+ oxnas_dma_device_set(
-+ dma_in,
-+ OXNAS_DMA_TO_DEVICE,
-+ (char*)in_address,
-+ 132 * sizeof(u32),
-+ &oxnas_dpe_rx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ oxnas_dma_device_set(
-+ dma_out,
-+ OXNAS_DMA_FROM_DEVICE,
-+ (char*)out_address,
-+ 132 * sizeof(u32),
-+ &oxnas_dpe_tx_dma_settings,
-+ OXNAS_DMA_MODE_INC, 1);
-+
-+ // authenticate
-+ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
-+
-+ // toggle cleardown bit to start
-+ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
-+ WRITEL(0 ,OX800DPE_CONTROL);
-+
-+ // shouldn't be busy or full
-+ reg = READL( OX800DPE_STATUS );
-+ if (! (reg & OX800DPE_STAT_IDLE) )
-+ FAILED("not idle after abort toggle");
-+ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
-+ FAILED("tx fifo not empty after abort toggle");
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx not empty after abort toggle");
-+
-+ // setup for decryption
-+ reg = OX800DPE_CTL_DIRECTION_ENC |
-+ OX800DPE_CTL_MODE_LRW_AES ;
-+ WRITEL(reg ,OX800DPE_CONTROL);
-+
-+ // key no 1
-+ WRITEL(be32_to_cpu( 0xd82a9134), OX800DPE_KEY00 );
-+ WRITEL(be32_to_cpu( 0xb26a5650), OX800DPE_KEY01 );
-+ WRITEL(be32_to_cpu( 0x30fe69e2), OX800DPE_KEY02 );
-+ WRITEL(be32_to_cpu( 0x377f9847), OX800DPE_KEY03 );
-+
-+ // key no 2
-+ WRITEL(be32_to_cpu( 0xcdf90b16), OX800DPE_KEY10 );
-+ WRITEL(be32_to_cpu( 0x0c648fb6), OX800DPE_KEY11 );
-+ WRITEL(be32_to_cpu( 0xb00d0d1b), OX800DPE_KEY12 );
-+ WRITEL(be32_to_cpu( 0xae85871f), OX800DPE_KEY13 );
-+
-+ // setup index
-+ WRITEL(0x0fffffff, OX800DPE_DATA_LRW0 );
-+ WRITEL(0x00000000, OX800DPE_DATA_LRW1 );
-+
-+ /* wait until done */
-+ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
-+
-+ // start dma transfers
-+ oxnas_dma_start(dma_out);
-+ oxnas_dma_start(dma_in);
-+
-+ /* wait until done */
-+ while( oxnas_dma_is_active( dma_out ) );
-+
-+ reg = READL( OX800DPE_STATUS );
-+
-+ /* output should be empty */
-+ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
-+ FAILED("tx still full after fetching ");
-+
-+ /* in empty */
-+ if (! (reg & OX800DPE_STAT_RX_SPACE) )
-+ FAILED("rx still full after encrypting data ");
-+
-+ dma_unmap_single(0, in_address, 132 * sizeof(u32), DMA_TO_DEVICE);
-+ dma_unmap_single(0, out_address, 132 * sizeof(u32), DMA_FROM_DEVICE);
-+
-+ /* check output */
-+ if ((data_out[128] != cpu_to_be32(0x76322183)) ||
-+ (data_out[129] != cpu_to_be32(0xed8ff182)) ||
-+ (data_out[130] != cpu_to_be32(0xf9596203)) ||
-+ (data_out[131] != cpu_to_be32(0x690e5e01)))
-+ {
-+ FAILED("encryption output incorrect");
-+ printk("%08x%08x%08x%08x\n",data_out[128],data_out[129],data_out[130],data_out[131]);
-+ }
-+
-+ // free dmas
-+ oxnas_dma_free( dma_in );
-+ oxnas_dma_free( dma_out );
-+
-+ kfree(data_in);
-+ kfree(data_out);
-+
-+ return failed;
-+
-+}
-+
-+
-+/*****************************************************************************/
-+#define NOCIPHERTESTS 21
-+static ox800dpe_test_t* tests[NOCIPHERTESTS] = {
-+ /* ordinary AES tests */
-+ test1,
-+ test2,
-+ test3,
-+ test4,
-+ test5,
-+ test6,
-+ test7,
-+
-+ /* CBC AES tests */
-+ test8,
-+ test9,
-+ test10,
-+ test11,
-+ test12,
-+ test13,
-+
-+ /* LRW AES tests */
-+ test14,
-+ test15,
-+ test16,
-+ test17,
-+ test18,
-+ test19,
-+ test20,
-+ test21
-+
-+} ;
-+
-+
-+static int __init ox800dpe_init(void)
-+{
-+ int i;
-+ int result;
-+ printk("*******************************************************************\n");
-+ printk("* CIPHER CORE TESTING START *\n");
-+ printk("*******************************************************************\n");
-+
-+ /* Enable the clock to the DPE block */
-+ writel(1UL << SYS_CTRL_CKEN_DPE_BIT, SYS_CTRL_CKEN_SET_CTRL);
-+
-+ /* Bring out of reset */
-+ writel(1UL << SYS_CTRL_RSTEN_DPE_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+
-+
-+
-+
-+ for (i = 0; i < NOCIPHERTESTS; ++i)
-+ {
-+ printk("\nTest %d start\n",i+1);
-+ result = (tests[i])();
-+ if (result)
-+ printk("Test %d failed with %d faults.\n",i+1,result);
-+ else
-+ printk("Test %d passed\n",i+1);
-+
-+ }
-+
-+ printk("*******************************************************************\n");
-+ printk("* CIPHER CORE TESTING END *\n");
-+ printk("*******************************************************************\n");
-+
-+ return 0;
-+}
-+
-+
-+
-+/***************************************************************************/
-+module_init(ox800dpe_init);
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac-napi.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac-napi.c
---- linux-2.6.24/arch/arm/mach-oxnas/gmac-napi.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac-napi.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,3637 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac.c
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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 <linux/crc32.h>
-+#include <linux/version.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/delay.h>
-+#include <linux/in.h>
-+#include <net/ip.h>
-+#include <linux/tcp.h>
-+#include <linux/udp.h>
-+#include <asm/io.h>
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/irqs.h>
-+
-+#ifdef CONFIG_LEON_COPRO
-+#include <asm/arch/leon-program.h>
-+#endif // CONFIG_LEON_COPRO
-+
-+//#define GMAC_DEBUG
-+#undef GMAC_DEBUG
-+
-+#include "gmac.h"
-+#include "gmac_ethtool.h"
-+#include "gmac_phy.h"
-+#include "gmac_desc.h"
-+#include "gmac_reg.h"
-+
-+//#define DUMP_REGS_ON_GMAC_UP
-+
-+#define MAX_GMAC_UNITS 1
-+
-+#define ALLOW_AUTONEG
-+
-+//#define ALLOW_OX800_1000M
-+
-+//#define SUPPORT_IPV6
-+
-+#ifdef CONFIG_LEON_COPRO
-+//#define TEST_COPRO
-+#define COPRO_RX_MITIGATION 0 /* No Rx mitigation in CoPro */
-+#define COPRO_RX_MITIGATION_FRAMES 5
-+#define COPRO_RX_MITIGATION_USECS 500
-+
-+#define COPRO_TX_QUEUE_NUM_ENTRIES 4
-+#define COPRO_CMD_QUEUE_NUM_ENTRIES 6
-+#define COPRO_MAX_QUEUED_TX_SKBS 16
-+#endif // CONFIG_LEON_COPRO
-+
-+#ifdef CONFIG_LEON_OFFLOAD_TX
-+#define NUM_RX_DMA_DESCRIPTORS NUM_GMAC_DMA_DESCRIPTORS
-+#define NUM_TX_DMA_DESCRIPTORS 0
-+#else
-+#define NUM_RX_DMA_DESCRIPTORS (NUM_GMAC_DMA_DESCRIPTORS / 2)
-+#define NUM_TX_DMA_DESCRIPTORS (NUM_GMAC_DMA_DESCRIPTORS - NUM_RX_DMA_DESCRIPTORS)
-+#endif // CONFIG_LEON_OFFLOAD_TX
-+
-+#if (((NUM_RX_DMA_DESCRIPTORS) + (NUM_TX_DMA_DESCRIPTORS)) > (NUM_GMAC_DMA_DESCRIPTORS))
-+#error "GMAC TX+RX descriptors exceed allocation"
-+#endif
-+
-+#define DESC_SINCE_REFILL_LIMIT ((NUM_RX_DMA_DESCRIPTORS) / 4)
-+
-+static const u32 MAC_BASE_OFFSET = 0x0000;
-+static const u32 DMA_BASE_OFFSET = 0x1000;
-+
-+static const int MIN_PACKET_SIZE = 68;
-+static const int NORMAL_PACKET_SIZE = 1500;
-+static const int MAX_JUMBO = 9000;
-+
-+#define RX_BUFFER_SIZE 796 // Must be multiple of 4, If not defined will size buffer to hold a single MTU-sized packet
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+static const int EXTRA_RX_SKB_SPACE = 24; // Has extra 2 bytes of Rx payload csum
-+#else // CONFIG_OXNAS_VERSION_0X800
-+static const int EXTRA_RX_SKB_SPACE = 22; // Ethernet header 14, VLAN 4, CRC 4
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+// The amount of header to copy from a receive packet into the skb buffer
-+static const int GMAC_HLEN = 66;
-+
-+#define GMAC_ALLOC_ORDER 0
-+static const int GMAC_ALLOC_SIZE = ((1 << GMAC_ALLOC_ORDER) * PAGE_SIZE);
-+
-+static const u32 AUTO_NEGOTIATION_WAIT_TIMEOUT_MS = 5000;
-+
-+static const u32 NAPI_POLL_WEIGHT = 64;
-+static const u32 NAPI_OOM_POLL_INTERVAL_MS = 50;
-+
-+static const int WATCHDOG_TIMER_INTERVAL = 500*HZ/1000;
-+
-+#define AUTO_NEG_MS_WAIT 500
-+static const int AUTO_NEG_INTERVAL = (AUTO_NEG_MS_WAIT)*HZ/1000;
-+static const int START_RESET_INTERVAL = 50*HZ/1000;
-+static const int RESET_INTERVAL = 10*HZ/1000;
-+
-+static const int GMAC_RESET_TIMEOUT_MS = 10000;
-+
-+static int debug = 0;
-+
-+MODULE_AUTHOR("Brian Clarke (Oxford Semiconductor Ltd)");
-+MODULE_DESCRIPTION("GMAC Network Driver");
-+MODULE_LICENSE("GPL");
-+MODULE_VERSION("v2.0");
-+
-+/* Ethernet MAC adr to assign to interface */
-+static int mac_adr[] = { 0x00, 0x30, 0xe0, 0x00, 0x00, 0x00 };
-+module_param_array(mac_adr, int, NULL, S_IRUGO);
-+
-+/* PHY type kernel cmdline options */
-+static int phy_is_rgmii = 0;
-+module_param(phy_is_rgmii, int, S_IRUGO);
-+
-+/* Parse netdev kernel cmdline options */
-+static int __init do_setup(char *str)
-+{
-+ int i;
-+ int ints[5]; // Hold arg count and four args
-+ u32 mac_hi = 0;
-+ u32 mac_lo = 0;
-+
-+ /* Get the netdev bootargs parameters */
-+ get_options(str, sizeof(ints)/sizeof(int), ints);
-+ for (i=1; i<=ints[0]; i++) {
-+ switch (i) {
-+ case 3:
-+ mac_hi = ints[i];
-+ break;
-+ case 4:
-+ mac_lo = ints[i];
-+ break;
-+ }
-+ }
-+
-+ /* Break down the mac adr into its components */
-+ for (i=0; i < sizeof(mac_adr)/sizeof(int); i++) {
-+ if (i < sizeof(u32)) {
-+ mac_adr[i] = ((mac_hi >> (((sizeof(u32)-1)-i)*8)) & 0xff);
-+ } else {
-+ mac_adr[i] = ((mac_lo >> (((sizeof(u32)+1)-i)*8)) & 0xff);
-+ }
-+ }
-+
-+ return 0;
-+}
-+__setup("netdev=",do_setup);
-+
-+#ifdef DUMP_REGS_ON_GMAC_UP
-+static void dump_mac_regs(u32 macBase, u32 dmaBase)
-+{
-+ int n = 0;
-+
-+ for (n=0; n<0x60; n+=4) {
-+ printk(KERN_INFO "MAC Register %08x (%08x) = %08x\n", n, macBase+n, readl(macBase+n));
-+ }
-+
-+ for (n=0; n<0x60; n+=4) {
-+ printk(KERN_INFO "DMA Register %08x (%08x) = %08x\n", n, dmaBase+n, readl(dmaBase+n));
-+ }
-+}
-+#endif // DUMP_REGS_ON_GMAC_UP
-+
-+#ifdef CONFIG_LEON_COPRO
-+static struct semaphore copro_update_semaphore;
-+
-+static void copro_update_callback(volatile gmac_cmd_que_ent_t* entry)
-+{
-+ up(&copro_update_semaphore);
-+}
-+
-+static struct semaphore copro_start_semaphore;
-+
-+static void copro_start_callback(volatile gmac_cmd_que_ent_t* entry)
-+{
-+ up(&copro_start_semaphore);
-+}
-+
-+static struct semaphore copro_rx_enable_semaphore;
-+
-+static void copro_rx_enable_callback(volatile gmac_cmd_que_ent_t* entry)
-+{
-+ up(&copro_rx_enable_semaphore);
-+}
-+#endif // CONFIG_LEON_COPRO
-+
-+static void gmac_int_en_set(
-+ gmac_priv_t *priv,
-+ u32 mask)
-+{
-+ unsigned long irq_flags = 0;
-+
-+#ifdef CONFIG_LEON_COPRO
-+ int cmd_queue_result = -1;
-+ while (cmd_queue_result) {
-+ if (in_irq())
-+ spin_lock(&priv->cmd_que_lock_);
-+ else
-+ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
-+
-+ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_INT_EN_SET, mask, 0);
-+
-+ if (in_irq())
-+ spin_unlock(&priv->cmd_que_lock_);
-+ else
-+ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
-+ }
-+
-+ // Interrupt the CoPro so it sees the new command
-+ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+#else
-+ if (in_irq())
-+ spin_lock(&priv->cmd_que_lock_);
-+ else
-+ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
-+
-+ dma_reg_set_mask(priv, DMA_INT_ENABLE_REG, mask);
-+
-+ if (in_irq())
-+ spin_unlock(&priv->cmd_que_lock_);
-+ else
-+ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
-+#endif // CONFIG_LEON_COPRO
-+}
-+
-+#ifdef CONFIG_LEON_COPRO
-+static struct semaphore copro_int_clr_semaphore;
-+static unsigned long copro_int_clr_return;
-+
-+static void copro_int_clr_callback(volatile gmac_cmd_que_ent_t* entry)
-+{
-+ copro_int_clr_return = entry->operand_;
-+ up(&copro_int_clr_semaphore);
-+}
-+#endif // CONFIG_LEON_COPRO
-+
-+static void gmac_int_en_clr(
-+ gmac_priv_t *priv,
-+ u32 mask,
-+ u32 *new_value,
-+ int in_atomic)
-+{
-+#ifdef CONFIG_LEON_COPRO
-+ unsigned long irq_flags = 0;
-+
-+ int cmd_queue_result = -1;
-+ while (cmd_queue_result) {
-+ if (in_irq())
-+ spin_lock(&priv->cmd_que_lock_);
-+ else
-+ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
-+
-+ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_INT_EN_CLR, mask, copro_int_clr_callback);
-+
-+ if (in_irq())
-+ spin_unlock(&priv->cmd_que_lock_);
-+ else
-+ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
-+ }
-+
-+ // Interrupt the CoPro so it sees the new command
-+ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+
-+ if (new_value) {
-+ // Wait until the CoPro acknowledges that it has stopped
-+ if (in_atomic) {
-+ while (down_trylock(&copro_int_clr_semaphore)) {
-+ udelay(100);
-+ }
-+ } else {
-+ down_interruptible(&copro_int_clr_semaphore);
-+ }
-+ *new_value = copro_int_clr_return;
-+ }
-+#else
-+ unsigned long temp;
-+ unsigned long irq_flags = 0;
-+
-+ if (in_irq())
-+ spin_lock(&priv->cmd_que_lock_);
-+ else
-+ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
-+
-+ temp = dma_reg_clear_mask(priv, DMA_INT_ENABLE_REG, mask);
-+
-+ if (in_irq())
-+ spin_unlock(&priv->cmd_que_lock_);
-+ else
-+ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
-+
-+ if (new_value) {
-+ *new_value = temp;
-+ }
-+#endif
-+}
-+
-+/**
-+ * May be invoked from either ISR or process context, so locking must be
-+ * invoked appropriate to the return from in_irq()
-+ */
-+static void change_rx_enable(
-+ gmac_priv_t *priv,
-+ u32 start,
-+ int waitForAck,
-+ int in_atomic)
-+{
-+#ifdef CONFIG_LEON_COPRO
-+ unsigned long irq_flags = 0;
-+ int cmd_queue_result = -1;
-+
-+ while (cmd_queue_result) {
-+ if (in_irq())
-+ spin_lock(&priv->cmd_que_lock_);
-+ else
-+ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
-+
-+ // Request the CoPro to start/stop GMAC receiver
-+ cmd_queue_result =
-+ cmd_que_queue_cmd(&priv->cmd_queue_,
-+ GMAC_CMD_CHANGE_RX_ENABLE,
-+ start,
-+ waitForAck ? copro_rx_enable_callback : 0);
-+
-+ if (in_irq())
-+ spin_unlock(&priv->cmd_que_lock_);
-+ else
-+ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
-+ }
-+
-+ // Interrupt the CoPro so it sees the new command
-+ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+
-+ if (waitForAck) {
-+ // Wait until the CoPro acknowledges that the receiver has been stopped
-+ if (in_atomic) {
-+ while (down_trylock(&copro_rx_enable_semaphore)) {
-+ udelay(100);
-+ }
-+ } else {
-+ down_interruptible(&copro_rx_enable_semaphore);
-+ }
-+ }
-+#else // CONFIG_LEON_COPRO
-+ start ? dma_reg_set_mask(priv, DMA_OP_MODE_REG, 1UL << DMA_OP_MODE_SR_BIT) :
-+ dma_reg_clear_mask(priv, DMA_OP_MODE_REG, 1UL << DMA_OP_MODE_SR_BIT);
-+#endif // CONFIG_LEON_COPRO
-+}
-+
-+/**
-+ * Invoked from the watchdog timer action routine which runs as softirq, so
-+ * must disable interrupts when obtaining locks
-+ */
-+static void change_gig_mode(gmac_priv_t *priv)
-+{
-+ unsigned int is_gig = priv->mii.using_1000;
-+
-+#ifdef CONFIG_LEON_COPRO
-+ unsigned long irq_flags = 0;
-+ int cmd_queue_result = -1;
-+
-+ while (cmd_queue_result) {
-+ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
-+ // Request the CoPro to change gigabit mode
-+ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_CHANGE_GIG_MODE, is_gig, 0);
-+ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
-+ }
-+
-+ // Interrupt the CoPro so it sees the new command
-+ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+#else // CONFIG_LEON_COPRO
-+ static const int MAX_TRIES = 1000;
-+ int tries = 0;
-+
-+ // Mask to extract the transmit status field from the status register
-+ u32 ts_mask = ((1UL << DMA_STATUS_TS_NUM_BITS) - 1) << DMA_STATUS_TS_BIT;
-+
-+ // Must stop transmission in order to change store&forward mode
-+ dma_reg_clear_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
-+
-+ // Transmission only stops after current Tx frame has completed trans-
-+ // mission, so wait for the Tx state machine to enter the stopped state
-+ while ((dma_reg_read(priv, DMA_STATUS_REG) & ts_mask) != (DMA_STATUS_TS_STOPPED << DMA_STATUS_TS_BIT)) {
-+ mdelay(1);
-+ if (unlikely(++tries == MAX_TRIES)) {
-+ break;
-+ }
-+ }
-+
-+ if (unlikely(tries == MAX_TRIES)) {
-+ printk(KERN_WARNING "Timed out of wait for Tx to stop\n");
-+ }
-+
-+ if (is_gig) {
-+ mac_reg_clear_mask(priv, MAC_CONFIG_REG, (1UL << MAC_CONFIG_PS_BIT));
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ // In gigabit mode the OX800 cannot support the required data rate to
-+ // the GMAC, so must use store&forward and OX800 doesn't support Tx
-+ // checksumming in the GMAC
-+ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+ } else {
-+ mac_reg_set_mask(priv, MAC_CONFIG_REG, (1UL << MAC_CONFIG_PS_BIT));
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ dma_reg_clear_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+ }
-+
-+ // Re-start transmission after store&forward change applied
-+ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
-+#endif // CONFIG_LEON_COPRO
-+}
-+
-+/**
-+ * Invoked from the watchdog timer action routine which runs as softirq, so
-+ * must disable interrupts when obtaining locks
-+ */
-+static void change_pause_mode(gmac_priv_t *priv)
-+{
-+#ifdef CONFIG_LEON_COPRO
-+ unsigned int enable_pause = priv->mii.using_pause;
-+ unsigned long irq_flags = 0;
-+ int cmd_queue_result = -1;
-+
-+ while (cmd_queue_result) {
-+ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
-+ // Request the CoPro to change pause mode
-+ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_CHANGE_PAUSE_MODE, enable_pause, 0);
-+ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
-+ }
-+
-+ // Interrupt the CoPro so it sees the new command
-+ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+#else // CONFIG_LEON_COPRO
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+ unsigned int enable_pause = priv->mii.using_pause;
-+
-+ if (enable_pause) {
-+ mac_reg_set_mask(priv, MAC_FLOW_CNTL_REG, (1UL << MAC_FLOW_CNTL_TFE_BIT));
-+ } else {
-+ mac_reg_clear_mask(priv, MAC_FLOW_CNTL_REG, (1UL << MAC_FLOW_CNTL_TFE_BIT));
-+ }
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+#endif // CONFIG_LEON_COPRO
-+}
-+
-+static void refill_rx_ring(struct net_device *dev)
-+{
-+ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+ int filled = 0;
-+
-+ if (unlikely(priv->rx_buffers_per_page)) {
-+ // Receive into pages
-+ struct page *page = 0;
-+ int offset = 0;
-+ dma_addr_t phys_adr = 0;
-+
-+ // While there are empty RX descriptor ring slots
-+ while (1) {
-+ int available;
-+ int desc;
-+ rx_frag_info_t frag_info;
-+
-+ // Have we run out of space in the current page?
-+ if (offset + NET_IP_ALIGN + priv->rx_buffer_size_ > GMAC_ALLOC_SIZE) {
-+ page = 0;
-+ offset = 0;
-+ }
-+
-+ if (!page) {
-+ // Start a new page
-+ available = available_for_write(&priv->rx_gmac_desc_list_info);
-+ if (available < priv->rx_buffers_per_page) {
-+ break;
-+ }
-+
-+ // Allocate a page to hold a received packet
-+ page = alloc_pages(GFP_ATOMIC, GMAC_ALLOC_ORDER);
-+ if (unlikely(page == NULL)) {
-+ printk(KERN_WARNING "refill_rx_ring() Could not alloc page\n");
-+ break;
-+ }
-+
-+ // Get a consistent DMA mapping for the entire page that will be
-+ // DMAed to - causing an invalidation of any entries in the CPU's
-+ // cache covering the memory region
-+ phys_adr = dma_map_page(0, page, 0, GMAC_ALLOC_SIZE, DMA_FROM_DEVICE);
-+ BUG_ON(dma_mapping_error(phys_adr));
-+ } else {
-+ // Using the current page again
-+ get_page(page);
-+ }
-+
-+ // Ensure IP header is quad aligned
-+ offset += NET_IP_ALIGN;
-+ frag_info.page = page;
-+ frag_info.length = priv->rx_buffer_size_;
-+ frag_info.phys_adr = phys_adr + offset;
-+
-+ // Try to associate a descriptor with the fragment info
-+ desc = set_rx_descriptor(priv, &frag_info);
-+ if (desc >= 0) {
-+ filled = 1;
-+ } else {
-+ // Failed to associate the descriptor, so release the DMA mapping
-+ // for the socket buffer
-+ dma_unmap_page(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
-+
-+ // No more RX descriptor ring entries to refill
-+ break;
-+ }
-+
-+ // Account for the space used in the current page
-+ offset += frag_info.length;
-+
-+ // Start next packet on a cacheline boundary
-+ offset = SKB_DATA_ALIGN(offset);
-+ }
-+ } else {
-+ // Preallocate MTU-sized SKBs
-+ while (1) {
-+ struct sk_buff *skb;
-+ rx_frag_info_t frag_info;
-+ int desc;
-+
-+ if (!available_for_write(&priv->rx_gmac_desc_list_info)) {
-+ break;
-+ }
-+
-+ // Allocate a new skb for the descriptor ring which is large enough
-+ // for any packet received from the link
-+ skb = dev_alloc_skb(priv->rx_buffer_size_ + NET_IP_ALIGN);
-+ if (!skb) {
-+ // Can't refill any more RX descriptor ring entries
-+ break;
-+ } else {
-+ // Despite what the comments in the original code from Synopsys
-+ // claimed, the GMAC DMA can cope with non-quad aligned buffers
-+ // - it will always perform quad transfers but zero/ignore the
-+ // unwanted bytes.
-+ skb_reserve(skb, NET_IP_ALIGN);
-+ }
-+
-+ // Get a consistent DMA mapping for the memory to be DMAed to
-+ // causing invalidation of any entries in the CPU's cache covering
-+ // the memory region
-+ frag_info.page = (struct page*)skb;
-+ frag_info.length = skb_tailroom(skb);
-+ frag_info.phys_adr = dma_map_single(0, skb->tail, frag_info.length, DMA_FROM_DEVICE);
-+ BUG_ON(dma_mapping_error(frag_info.phys_adr));
-+
-+ // Associate the skb with the descriptor
-+ desc = set_rx_descriptor(priv, &frag_info);
-+ if (desc >= 0) {
-+ filled = 1;
-+ } else {
-+ // No, so release the DMA mapping for the socket buffer
-+ dma_unmap_single(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
-+
-+ // Free the socket buffer
-+ dev_kfree_skb(skb);
-+
-+ // No more RX descriptor ring entries to refill
-+ break;
-+ }
-+ }
-+ }
-+
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+ if (likely(filled)) {
-+ // Issue a RX poll demand to restart RX descriptor processing and DFF
-+ // mode does not automatically restart descriptor processing after a
-+ // descriptor unavailable event
-+ dma_reg_write(priv, DMA_RX_POLL_REG, 0);
-+ }
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+}
-+
-+static inline void set_phy_type_rgmii(void)
-+{
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+ // Use sysctrl to switch MAC link lines into either (G)MII or RGMII mode
-+ u32 reg_contents = readl(SYS_CTRL_GMAC_CTRL);
-+ reg_contents |= (1UL << SYS_CTRL_GMAC_RGMII);
-+ writel(reg_contents, SYS_CTRL_RSTEN_SET_CTRL);
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+}
-+
-+static void initialise_phy(gmac_priv_t* priv)
-+{
-+ switch (priv->phy_type) {
-+ case PHY_TYPE_VITESSE_VSC8201XVZ:
-+ {
-+ // Allow s/w to override mode/duplex pin settings
-+ u32 acsr = priv->mii.mdio_read(priv->netdev, priv->mii.phy_id, VSC8201_MII_ACSR);
-+
-+ printk(KERN_INFO "%s: PHY is Vitesse VSC8201XVZ\n", priv->netdev->name);
-+ acsr |= (1UL << VSC8201_MII_ACSR_MDPPS_BIT);
-+ priv->mii.mdio_write(priv->netdev, priv->mii.phy_id, VSC8201_MII_ACSR, acsr);
-+ }
-+ break;
-+ case PHY_TYPE_REALTEK_RTL8211BGR:
-+ printk(KERN_INFO "%s: PHY is Realtek RTL8211BGR\n", priv->netdev->name);
-+ set_phy_type_rgmii();
-+ break;
-+ case PHY_TYPE_LSI_ET1011C:
-+ case PHY_TYPE_LSI_ET1011C2:
-+ {
-+ u32 phy_reg;
-+
-+ printk(KERN_INFO "%s: PHY is LSI ET1011C\n", priv->netdev->name);
-+
-+ // Configure clocks
-+ phy_reg = priv->mii.mdio_read(priv->netdev, priv->mii.phy_id, ET1011C_MII_CONFIG);
-+ phy_reg &= ~(((1UL << ET1011C_MII_CONFIG_IFMODESEL_NUM_BITS) - 1) << ET1011C_MII_CONFIG_IFMODESEL);
-+ phy_reg |= (ET1011C_MII_CONFIG_IFMODESEL_GMII_MII << ET1011C_MII_CONFIG_IFMODESEL);
-+ phy_reg |= ((1UL << ET1011C_MII_CONFIG_SYSCLKEN) |
-+ (1UL << ET1011C_MII_CONFIG_TXCLKEN) |
-+ (1UL << ET1011C_MII_CONFIG_TBI_RATESEL) |
-+ (1UL << ET1011C_MII_CONFIG_CRS_TX_EN));
-+ priv->mii.mdio_write(priv->netdev, priv->mii.phy_id, ET1011C_MII_CONFIG, phy_reg);
-+
-+ // Enable Tx/Rx LED
-+ phy_reg = priv->mii.mdio_read(priv->netdev, priv->mii.phy_id, ET1011C_MII_LED2);
-+ phy_reg &= ~(((1UL << ET1011C_MII_LED2_LED_NUM_BITS) - 1) << ET1011C_MII_LED2_LED_TXRX);
-+ phy_reg |= (ET1011C_MII_LED2_LED_TXRX_ACTIVITY << ET1011C_MII_LED2_LED_TXRX);
-+ priv->mii.mdio_write(priv->netdev, priv->mii.phy_id, ET1011C_MII_LED2, phy_reg);
-+ }
-+ break;
-+ case PHY_TYPE_ICPLUS_IP1001:
-+ printk(KERN_INFO "%s: PHY is ICPlus 1001\n", priv->netdev->name);
-+ break;
-+ }
-+}
-+
-+static struct kobj_type ktype_gmac_link_state = {
-+ .release = 0,
-+ .sysfs_ops = 0,
-+ .default_attrs = 0,
-+};
-+
-+static int gmac_link_state_hotplug_filter(struct kset* kset, struct kobject* kobj) {
-+ return get_ktype(kobj) == &ktype_gmac_link_state;
-+}
-+
-+static const char* gmac_link_state_hotplug_name(struct kset* kset, struct kobject* kobj) {
-+ return "gmac_link_state";
-+}
-+
-+static struct kset_uevent_ops gmac_link_state_uevent_ops = {
-+ .filter = gmac_link_state_hotplug_filter,
-+ .name = gmac_link_state_hotplug_name,
-+ .uevent = NULL,
-+};
-+
-+static int gmac_link_state_init_sysfs(gmac_priv_t* priv)
-+{
-+ int err = 0;
-+
-+ /* Prepare the sysfs interface for use */
-+ kobject_set_name(&priv->link_state_kset.kobj, "gmac_link_state");
-+ priv->link_state_kset.ktype = &ktype_gmac_link_state;
-+
-+ err = subsystem_register(&priv->link_state_kset);
-+ if (err)
-+ return err;
-+
-+ /* Setup hotplugging */
-+ priv->link_state_kset.uevent_ops = &gmac_link_state_uevent_ops;
-+
-+ /* Setup the heirarchy, the name will be set on detection */
-+ kobject_init(&priv->link_state_kobject);
-+ priv->link_state_kobject.kset = kset_get(&priv->link_state_kset);
-+ priv->link_state_kobject.parent = &priv->link_state_kset.kobj;
-+
-+ /* Build the sysfs entry */
-+ kobject_set_name(&priv->link_state_kobject, "gmac_link_state-1");
-+ return kobject_add(&priv->link_state_kobject);
-+}
-+
-+static void work_handler(struct work_struct *ws) {
-+ gmac_priv_t *priv = container_of(ws, gmac_priv_t, link_state_change_work);
-+
-+ kobject_uevent(&priv->link_state_kobject, priv->link_state ? KOBJ_ONLINE : KOBJ_OFFLINE);
-+}
-+
-+static void link_state_change_callback(
-+ int link_state,
-+ void *arg)
-+{
-+ gmac_priv_t* priv = (gmac_priv_t*)arg;
-+
-+ priv->link_state = link_state;
-+ schedule_work(&priv->link_state_change_work);
-+}
-+
-+static void start_watchdog_timer(gmac_priv_t* priv)
-+{
-+ priv->watchdog_timer.expires = jiffies + WATCHDOG_TIMER_INTERVAL;
-+ priv->watchdog_timer_shutdown = 0;
-+ mod_timer(&priv->watchdog_timer, priv->watchdog_timer.expires);
-+}
-+
-+static void delete_watchdog_timer(gmac_priv_t* priv)
-+{
-+ // Ensure link/PHY state watchdog timer won't be invoked again
-+ priv->watchdog_timer_shutdown = 1;
-+ del_timer_sync(&priv->watchdog_timer);
-+}
-+
-+static inline int is_auto_negotiation_in_progress(gmac_priv_t* priv)
-+{
-+ return !(phy_read(priv->netdev, priv->phy_addr, MII_BMSR) & BMSR_ANEGCOMPLETE);
-+}
-+
-+static void watchdog_timer_action(unsigned long arg)
-+{
-+ typedef enum watchdog_state {
-+ WDS_IDLE,
-+ WDS_RESETTING,
-+ WDS_NEGOTIATING
-+ } watchdog_state_t;
-+
-+ static int state = WDS_IDLE;
-+
-+ gmac_priv_t* priv = (gmac_priv_t*)arg;
-+ unsigned long new_timeout = jiffies + WATCHDOG_TIMER_INTERVAL;
-+#ifndef ARMULATING
-+ int ready;
-+ int duplex_changed;
-+ int gigabit_changed;
-+ int pause_changed;
-+
-+ // Interpret the PHY/link state.
-+ if (priv->phy_force_negotiation || (state == WDS_RESETTING)) {
-+ mii_check_link(&priv->mii);
-+ ready = 0;
-+ } else {
-+ duplex_changed = mii_check_media_ex(&priv->mii, 1, priv->mii_init_media, &gigabit_changed, &pause_changed, link_state_change_callback, priv);
-+ priv->mii_init_media = 0;
-+ ready = netif_carrier_ok(priv->netdev);
-+ }
-+
-+ if (!ready) {
-+ if (priv->phy_force_negotiation) {
-+ if (netif_carrier_ok(priv->netdev)) {
-+ state = WDS_RESETTING;
-+ } else {
-+ state = WDS_IDLE;
-+ }
-+
-+ priv->phy_force_negotiation = 0;
-+ }
-+
-+ // May be a good idea to restart everything here, in an attempt to clear
-+ // out any fault conditions
-+ if ((state == WDS_NEGOTIATING) && is_auto_negotiation_in_progress(priv)) {
-+ new_timeout = jiffies + AUTO_NEG_INTERVAL;
-+ } else {
-+ switch (state) {
-+ case WDS_IDLE:
-+ // Reset the PHY to get it into a known state
-+ start_phy_reset(priv);
-+ new_timeout = jiffies + START_RESET_INTERVAL;
-+ state = WDS_RESETTING;
-+ break;
-+ case WDS_RESETTING:
-+ if (!is_phy_reset_complete(priv)) {
-+ new_timeout = jiffies + RESET_INTERVAL;
-+ } else {
-+ // Force or auto-negotiate PHY mode
-+ set_phy_negotiate_mode(priv->netdev);
-+
-+ // Set PHY specfic features
-+ initialise_phy(priv);
-+
-+ state = WDS_NEGOTIATING;
-+ new_timeout = jiffies + AUTO_NEG_INTERVAL;
-+ }
-+ break;
-+ default:
-+ DBG(1, KERN_ERR "watchdog_timer_action() %s: Unexpected state\n", priv->netdev->name);
-+ state = WDS_IDLE;
-+ break;
-+ }
-+ }
-+ } else {
-+ state = WDS_IDLE;
-+ if (duplex_changed) {
-+ priv->mii.full_duplex ? mac_reg_set_mask(priv, MAC_CONFIG_REG, (1UL << MAC_CONFIG_DM_BIT)) :
-+ mac_reg_clear_mask(priv, MAC_CONFIG_REG, (1UL << MAC_CONFIG_DM_BIT));
-+ }
-+
-+ if (gigabit_changed) {
-+ change_gig_mode(priv);
-+ }
-+
-+ if (pause_changed) {
-+ change_pause_mode(priv);
-+ }
-+ }
-+#endif // !ARMULATING
-+
-+ // Re-trigger the timer, unless some other thread has requested it be stopped
-+ if (!priv->watchdog_timer_shutdown) {
-+ // Restart the timer
-+ mod_timer(&priv->watchdog_timer, new_timeout);
-+ }
-+}
-+
-+static int inline is_ip_packet(unsigned short eth_protocol)
-+{
-+ return (eth_protocol == ETH_P_IP)
-+#ifdef SUPPORT_IPV6
-+ || (eth_protocol == ETH_P_IPV6)
-+#endif // SUPPORT_IPV6
-+ ;
-+}
-+
-+static int inline is_ipv4_packet(unsigned short eth_protocol)
-+{
-+ return eth_protocol == ETH_P_IP;
-+}
-+
-+#ifdef SUPPORT_IPV6
-+static int inline is_ipv6_packet(unsigned short eth_protocol)
-+{
-+ return eth_protocol == ETH_P_IPV6;
-+}
-+#endif // SUPPORT_IPV6
-+
-+static int inline is_hw_checksummable(unsigned short protocol)
-+{
-+ return (protocol == IPPROTO_TCP) || (protocol == IPPROTO_UDP)
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+ || (protocol == IPPROTO_ICMP)
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+ ;
-+}
-+
-+static u32 unmap_rx_page(
-+ gmac_priv_t *priv,
-+ dma_addr_t phys_adr)
-+{
-+ u32 offset = phys_adr & ~PAGE_MASK;
-+ u32 next_offset = offset + priv->rx_buffer_size_;
-+ next_offset = SKB_DATA_ALIGN(next_offset);
-+ next_offset += NET_IP_ALIGN;
-+
-+ // If this is the last packet in a page
-+ if (next_offset > GMAC_ALLOC_SIZE) {
-+ // Release the DMA mapping for the page
-+ dma_unmap_page(0, phys_adr & PAGE_MASK, GMAC_ALLOC_SIZE, DMA_FROM_DEVICE);
-+ }
-+
-+ return offset;
-+}
-+
-+#define FCS_LEN 4 // Ethernet CRC length
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+#define HW_CSUM_LEN 2 // The OX800 H/W appending partial csum length
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+static inline int get_desc_len(
-+ u32 desc_status,
-+ int last)
-+{
-+ int length = get_rx_length(desc_status);
-+
-+ if (last) {
-+ length -= FCS_LEN;
-+#if defined(CONFIG_OXNAS_VERSION_0X800) && defined(USE_RX_CSUM)
-+ length -= HW_CSUM_LEN;
-+#endif // CONFIG_OXNAS_VERSION_0X800 && USE_RX_CSUM
-+ }
-+
-+ return length;
-+}
-+
-+static int process_rx_packet_skb(gmac_priv_t *priv)
-+{
-+ int desc;
-+ int last;
-+ u32 desc_status = 0;
-+ rx_frag_info_t frag_info;
-+ int packet_len;
-+ struct sk_buff *skb;
-+ int valid;
-+ int ip_summed;
-+
-+ desc = get_rx_descriptor(priv, &last, &desc_status, &frag_info);
-+ if (desc < 0) {
-+ return 0;
-+ }
-+
-+ // Release the DMA mapping for the received data
-+ dma_unmap_single(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
-+
-+ // Get the packet data length
-+ packet_len = get_desc_len(desc_status, last);
-+
-+ // Get pointer to the SKB
-+ skb = (struct sk_buff*)frag_info.page;
-+
-+ // Is the packet entirely contained within the descriptors and without errors?
-+ valid = !(desc_status & (1UL << RDES0_ES_BIT));
-+
-+ if (unlikely(!valid)) {
-+ goto not_valid_skb;
-+ }
-+
-+ ip_summed = CHECKSUM_NONE;
-+
-+#ifdef USE_RX_CSUM
-+ // Has the h/w flagged an IP header checksum failure?
-+ valid = !(desc_status & (1UL << RDES0_IPC_BIT));
-+
-+ if (likely(valid)) {
-+ // Determine whether Ethernet frame contains an IP packet -
-+ // only bother with Ethernet II frames, but do cope with
-+ // 802.1Q VLAN tag presence
-+ int vlan_offset = 0;
-+ unsigned short eth_protocol = ntohs(((struct ethhdr*)skb->data)->h_proto);
-+ int is_ip = is_ip_packet(eth_protocol);
-+
-+ if (!is_ip) {
-+ // Check for VLAN tag
-+ if (eth_protocol == ETH_P_8021Q) {
-+ // Extract the contained protocol type from after
-+ // the VLAN tag
-+ eth_protocol = ntohs(*(unsigned short*)(skb->data + ETH_HLEN));
-+ is_ip = is_ip_packet(eth_protocol);
-+
-+ // Adjustment required to skip the VLAN stuff and
-+ // get to the IP header
-+ vlan_offset = 4;
-+ }
-+ }
-+
-+ // Only offload checksum calculation for IP packets
-+ if (is_ip) {
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ u16 payload_length = 0;
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+ struct iphdr* ipv4_header = 0;
-+
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+ if (unlikely(desc_status & (1UL << RDES0_PCE_BIT))) {
-+ valid = 0;
-+ } else
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+ if (is_ipv4_packet(eth_protocol)) {
-+ ipv4_header = (struct iphdr*)(skb->data + ETH_HLEN + vlan_offset);
-+
-+ // H/W can only checksum non-fragmented IP packets
-+ if (!(ipv4_header->frag_off & htons(IP_MF | IP_OFFSET))) {
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ switch (ipv4_header->protocol) {
-+ case IPPROTO_TCP:
-+ // Compute TCP pseudo-header checksum
-+ payload_length = ntohs(ipv4_header->tot_len) - (ipv4_header->ihl*4);
-+ break;
-+ case IPPROTO_UDP:
-+ {
-+ struct udphdr* udp_header = (struct udphdr*)((u8*)ipv4_header + (ipv4_header->ihl*4));
-+ payload_length = ntohs(udp_header->len);
-+ }
-+ break;
-+ default:
-+ // Not supporting any other than TCP/UDP
-+ break;
-+ }
-+#else // CONFIG_OXNAS_VERSION_0X800
-+ if (is_hw_checksummable(ipv4_header->protocol)) {
-+ ip_summed = CHECKSUM_UNNECESSARY;
-+ }
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+ }
-+ }
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+ else {
-+#ifdef SUPPORT_IPV6
-+ struct ipv6hdr* ipv6_header = (struct ipv6hdr*)(skb->data + ETH_HLEN + vlan_offset);
-+
-+ if (is_hw_checksummable(ipv6_header->nexthdr)) {
-+ ip_summed = CHECKSUM_UNNECESSARY;
-+ }
-+#endif // SUPPORT_IPV6
-+ }
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ if (payload_length) {
-+ // Get the hardware generated payload checksum from
-+ // the end of the received packet, reverse the 1's
-+ // complement operation that the h/w applies and add
-+ // to the pseudo-header checksum, in network order
-+ u16 hw_csum = ~(*(u16*)(skb->data + packet_len + FCS_LEN));
-+
-+ // Calculate checksum of pseudo header and payload
-+ if (csum_tcpudp_magic(
-+ ipv4_header->saddr,
-+ ipv4_header->daddr,
-+ payload_length,
-+ ipv4_header->protocol,
-+ hw_csum)) {
-+ // Bad checksum, so indicate in descriptor status
-+ desc_status |= (1UL << RDES0_IPC_BIT);
-+ valid = 0;
-+ } else {
-+ ip_summed = CHECKSUM_UNNECESSARY;
-+ }
-+ }
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+ }
-+ }
-+
-+ if (unlikely(!valid)) {
-+ goto not_valid_skb;
-+ }
-+#endif // USE_RX_CSUM
-+
-+ // Increase the skb's data pointer to account for the RX packet that has
-+ // been DMAed into it
-+ skb_put(skb, packet_len);
-+
-+ // Set the device for the skb
-+ skb->dev = priv->netdev;
-+
-+ // Set packet protocol
-+ skb->protocol = eth_type_trans(skb, priv->netdev);
-+
-+ // Record whether h/w checksumed the packet
-+ skb->ip_summed = ip_summed;
-+
-+ // Send the packet up the network stack
-+ netif_receive_skb(skb);
-+
-+ // Update receive statistics
-+ priv->netdev->last_rx = jiffies;
-+ ++priv->stats.rx_packets;
-+ priv->stats.rx_bytes += packet_len;
-+
-+ return 1;
-+
-+not_valid_skb:
-+ dev_kfree_skb(skb);
-+
-+ DBG(2, KERN_WARNING "process_rx_packet() %s: Received packet has bad desc_status = 0x%08x\n", priv->netdev->name, desc_status);
-+
-+ // Update receive statistics from the descriptor status
-+ if (is_rx_collision_error(desc_status)) {
-+ DBG(20, KERN_INFO "process_rx_packet() %s: Collision (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+ ++priv->stats.collisions;
-+ }
-+ if (is_rx_crc_error(desc_status)) {
-+ DBG(20, KERN_INFO "process_rx_packet() %s: CRC error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+ ++priv->stats.rx_crc_errors;
-+ ++priv->stats.rx_errors;
-+ }
-+ if (is_rx_frame_error(desc_status)) {
-+ DBG(20, KERN_INFO "process_rx_packet() %s: frame error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+ ++priv->stats.rx_frame_errors;
-+ ++priv->stats.rx_errors;
-+ }
-+ if (is_rx_length_error(desc_status)) {
-+ DBG(20, KERN_INFO "process_rx_packet() %s: Length error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+ ++priv->stats.rx_length_errors;
-+ ++priv->stats.rx_errors;
-+ }
-+ if (is_rx_csum_error(desc_status)) {
-+ DBG(20, KERN_INFO "process_rx_packet() %s: Checksum error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+ ++priv->stats.rx_frame_errors;
-+ ++priv->stats.rx_errors;
-+ }
-+
-+ return 0;
-+}
-+
-+static int process_rx_packet(gmac_priv_t *priv)
-+{
-+ struct sk_buff *skb = NULL;
-+ int last;
-+ u32 desc_status;
-+ rx_frag_info_t frag_info;
-+ int desc;
-+ u32 offset;
-+ int desc_len;
-+ unsigned char *packet;
-+ int valid;
-+ int desc_used = 0;
-+ int hlen = 0;
-+ int partial_len = 0;
-+ int first = 1;
-+
-+ // Check that there is at least one Rx descriptor available. Cache the
-+ // descriptor information so we don't have to touch the uncached/unbuffered
-+ // descriptor memory more than necessary when we come to use that descriptor
-+ if (!rx_available_for_read(&priv->rx_gmac_desc_list_info, &desc_status)) {
-+ return 0;
-+ }
-+
-+ // Attempt to allocate an skb before we change anything on the Rx descriptor ring
-+ skb = dev_alloc_skb(GMAC_HLEN + NET_IP_ALIGN);
-+ if (unlikely(skb == NULL)) {
-+ return 0;
-+ }
-+
-+ // Align IP header start in header storage
-+ skb_reserve(skb, NET_IP_ALIGN);
-+
-+ // Process all descriptors associated with the packet
-+ while (1) {
-+ int prev_len;
-+
-+ // First call to get_rx_descriptor() will use the status read from the
-+ // first descriptor by the call to rx_available_for_read() above
-+ while ((desc = get_rx_descriptor(priv, &last, &desc_status, &frag_info)) < 0) {
-+ // We are part way through processing a multi-descriptor packet
-+ // and the GMAC hasn't finished with the next descriptor for the
-+ // packet yet, so have to poll until it becomes available
-+ desc_status = 0;
-+ udelay(1);
-+ }
-+
-+ // We've consumed a descriptor
-+ ++desc_used;
-+
-+ if (!frag_info.page) {
-+ panic("process_rx_packet() %s: Found RX descriptor without attached page\n", priv->netdev->name);
-+ }
-+
-+ // If this is the last packet in the page, release the DMA mapping
-+ offset = unmap_rx_page(priv, frag_info.phys_adr);
-+ if (!first) {
-+ // The buffer adr of descriptors associate with middle or last
-+ // parts of a packet have ls 2 bits of buffer adr ignored by GMAC DMA
-+ offset &= ~0x3;
-+ }
-+
-+ // Get the length of the packet excluding CRC, h/w csum etc.
-+ prev_len = partial_len;
-+ partial_len = get_desc_len(desc_status, last);
-+ desc_len = partial_len - prev_len;
-+
-+ // Get a pointer to the start of the packet data received into page
-+ packet = page_address(frag_info.page) + offset;
-+
-+ // Is the packet entirely contained within the desciptors and without errors?
-+ valid = !(desc_status & (1UL << RDES0_ES_BIT));
-+
-+ if (unlikely(!valid)) {
-+ goto not_valid;
-+ }
-+
-+ if (first) {
-+ // Store headers in skb buffer
-+ hlen = min(GMAC_HLEN, desc_len);
-+
-+ // Copy header into skb buffer
-+ memcpy(skb->data, packet, hlen);
-+ skb->tail += hlen;
-+
-+ if (desc_len > hlen) {
-+ // Point skb frags array at remaining packet data in pages
-+ skb_shinfo(skb)->nr_frags = 1;
-+ skb_shinfo(skb)->frags[0].page = frag_info.page;
-+ skb_shinfo(skb)->frags[0].page_offset = offset + hlen;
-+ skb_shinfo(skb)->frags[0].size = desc_len - hlen;
-+ } else {
-+ // Entire packet now in skb buffer so don't require page anymore
-+ put_page(frag_info.page);
-+ }
-+
-+ first = 0;
-+ } else {
-+ // Store intermediate descriptor data into packet
-+ int frag_index = skb_shinfo(skb)->nr_frags;
-+ skb_shinfo(skb)->frags[frag_index].page = frag_info.page;
-+ skb_shinfo(skb)->frags[frag_index].page_offset = offset;
-+ skb_shinfo(skb)->frags[frag_index].size = desc_len;
-+ ++skb_shinfo(skb)->nr_frags;
-+ }
-+
-+ if (last) {
-+ int ip_summed = CHECKSUM_NONE;
-+
-+ // Update total packet length skb metadata
-+ skb->len = partial_len;
-+ skb->data_len = skb->len - hlen;
-+ skb->truesize = skb->len + sizeof(struct sk_buff);
-+
-+#ifdef USE_RX_CSUM
-+ // Has the h/w flagged an IP header checksum failure?
-+ valid = !(desc_status & (1UL << RDES0_IPC_BIT));
-+
-+ // Are we offloading RX checksuming?
-+ if (likely(valid)) {
-+ // Determine whether Ethernet frame contains an IP packet -
-+ // only bother with Ethernet II frames, but do cope with
-+ // 802.1Q VLAN tag presence
-+ int vlan_offset = 0;
-+ unsigned short eth_protocol = ntohs(((struct ethhdr*)skb->data)->h_proto);
-+ int is_ip = is_ip_packet(eth_protocol);
-+
-+ if (!is_ip) {
-+ // Check for VLAN tag
-+ if (eth_protocol == ETH_P_8021Q) {
-+ // Extract the contained protocol type from after
-+ // the VLAN tag
-+ eth_protocol = ntohs(*(unsigned short*)(skb->data + ETH_HLEN));
-+ is_ip = is_ip_packet(eth_protocol);
-+
-+ // Adjustment required to skip the VLAN stuff and
-+ // get to the IP header
-+ vlan_offset = 4;
-+ }
-+ }
-+
-+ // Only offload checksum calculation for IP packets
-+ if (is_ip) {
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ u16 payload_length = 0;
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+ struct iphdr* ipv4_header = 0;
-+
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+ if (unlikely(desc_status & (1UL << RDES0_PCE_BIT))) {
-+ valid = 0;
-+ } else
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+ if (is_ipv4_packet(eth_protocol)) {
-+ ipv4_header = (struct iphdr*)(skb->data + ETH_HLEN + vlan_offset);
-+
-+ // H/W can only checksum non-fragmented IP packets
-+ if (!(ipv4_header->frag_off & htons(IP_MF | IP_OFFSET))) {
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ switch (ipv4_header->protocol) {
-+ case IPPROTO_TCP:
-+ // Compute TCP pseudo-header checksum
-+ payload_length = ntohs(ipv4_header->tot_len) - (ipv4_header->ihl*4);
-+ break;
-+ case IPPROTO_UDP:
-+ {
-+ struct udphdr* udp_header = (struct udphdr*)((u8*)ipv4_header + (ipv4_header->ihl*4));
-+ payload_length = ntohs(udp_header->len);
-+ }
-+ break;
-+ default:
-+ // Not supporting any other than TCP/UDP
-+ break;
-+ }
-+#else // CONFIG_OXNAS_VERSION_0X800
-+ if (is_hw_checksummable(ipv4_header->protocol)) {
-+ ip_summed = CHECKSUM_UNNECESSARY;
-+ }
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+ }
-+ }
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+ else {
-+#ifdef SUPPORT_IPV6
-+ struct ipv6hdr* ipv6_header = (struct ipv6hdr*)(skb->data + ETH_HLEN + vlan_offset);
-+
-+ if (is_hw_checksummable(ipv6_header->nexthdr)) {
-+ ip_summed = CHECKSUM_UNNECESSARY;
-+ }
-+#endif // SUPPORT_IPV6
-+ }
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ if (payload_length) {
-+ // Get the hardware generated payload checksum from
-+ // the end of the received packet, reverse the 1's
-+ // complement operation that the h/w applies and add
-+ // to the pseudo-header checksum, in network order
-+ u16 hw_csum = ~(*(u16*)(packet + desc_len + FCS_LEN));
-+
-+ // Calculate checksum of pseudo header and payload
-+ if (csum_tcpudp_magic(
-+ ipv4_header->saddr,
-+ ipv4_header->daddr,
-+ payload_length,
-+ ipv4_header->protocol,
-+ hw_csum)) {
-+ // Bad checksum, so indicate in descriptor status
-+ desc_status |= (1UL << RDES0_IPC_BIT);
-+ valid = 0;
-+ } else {
-+ ip_summed = CHECKSUM_UNNECESSARY;
-+ }
-+ }
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+ }
-+ }
-+
-+ if (unlikely(!valid)) {
-+ goto not_valid;
-+ }
-+#endif // USE_RX_CSUM
-+
-+ // Initialise other required skb header fields
-+ skb->dev = priv->netdev;
-+ skb->protocol = eth_type_trans(skb, priv->netdev);
-+
-+ // Record whether h/w checksumed the packet
-+ skb->ip_summed = ip_summed;
-+
-+ // Send the skb up the network stack
-+ netif_receive_skb(skb);
-+
-+ // Update receive statistics
-+ priv->netdev->last_rx = jiffies;
-+ ++priv->stats.rx_packets;
-+ priv->stats.rx_bytes += partial_len;
-+
-+ break;
-+ }
-+
-+ // Want next call to get_rx_descriptor() to read status from descriptor
-+ desc_status = 0;
-+ }
-+ return desc_used;
-+
-+not_valid:
-+ if (!skb_shinfo(skb)->nr_frags) {
-+ // Free the page as it wasn't attached to the skb
-+ put_page(frag_info.page);
-+ }
-+
-+ dev_kfree_skb(skb);
-+
-+ DBG(2, KERN_WARNING "process_rx_packet() %s: Received packet has bad desc_status = 0x%08x\n", priv->netdev->name, desc_status);
-+
-+ // Update receive statistics from the descriptor status
-+ if (is_rx_collision_error(desc_status)) {
-+ DBG(20, KERN_INFO "process_rx_packet() %s: Collision (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+ ++priv->stats.collisions;
-+ }
-+ if (is_rx_crc_error(desc_status)) {
-+ DBG(20, KERN_INFO "process_rx_packet() %s: CRC error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+ ++priv->stats.rx_crc_errors;
-+ ++priv->stats.rx_errors;
-+ }
-+ if (is_rx_frame_error(desc_status)) {
-+ DBG(20, KERN_INFO "process_rx_packet() %s: frame error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+ ++priv->stats.rx_frame_errors;
-+ ++priv->stats.rx_errors;
-+ }
-+ if (is_rx_length_error(desc_status)) {
-+ DBG(20, KERN_INFO "process_rx_packet() %s: Length error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+ ++priv->stats.rx_length_errors;
-+ ++priv->stats.rx_errors;
-+ }
-+ if (is_rx_csum_error(desc_status)) {
-+ DBG(20, KERN_INFO "process_rx_packet() %s: Checksum error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
-+ ++priv->stats.rx_frame_errors;
-+ ++priv->stats.rx_errors;
-+ }
-+
-+ return desc_used;
-+}
-+
-+/*
-+ * NAPI receive polling method
-+ */
-+static int poll(
-+ struct napi_struct *napi,
-+ int budget)
-+{
-+ gmac_priv_t *priv = container_of(napi, gmac_priv_t, napi_struct);
-+ struct net_device *dev = priv->netdev;
-+ int rx_work_limit = budget;
-+ int work_done = 0;
-+ int continue_polling;
-+ int finished;
-+ int available;
-+ int desc_since_refill = 0;
-+
-+ finished = 0;
-+ do {
-+ u32 status;
-+
-+ // While there are receive polling jobs to be done
-+ while (rx_work_limit) {
-+ int desc_used;
-+
-+ if (unlikely(priv->rx_buffers_per_page)) {
-+ desc_used = process_rx_packet(priv);
-+ } else {
-+ desc_used = process_rx_packet_skb(priv);
-+ }
-+
-+ if (!desc_used) {
-+ break;
-+ }
-+
-+ // Increment count of processed packets
-+ ++work_done;
-+
-+ // Decrement our remaining budget
-+ if (rx_work_limit > 0) {
-+ --rx_work_limit;
-+ }
-+
-+ // Rx overflows seem to upset the GMAC, so try to ensure we never see them
-+ desc_since_refill += desc_used;
-+ if (desc_since_refill >= DESC_SINCE_REFILL_LIMIT) {
-+ desc_since_refill = 0;
-+ refill_rx_ring(dev);
-+ }
-+ }
-+
-+ if (rx_work_limit) {
-+ // We have unused budget remaining, but apparently no Rx packets to
-+ // process
-+ available = 0;
-+
-+ // Clear any RI status so we don't immediately get reinterrupted
-+ // when we leave polling, due to either a new RI event, or a left
-+ // over interrupt from one of the RX descriptors we've already
-+ // processed
-+ status = dma_reg_read(priv, DMA_STATUS_REG);
-+ if (status & (1UL << DMA_STATUS_RI_BIT)) {
-+ // Ack the RI, including the normal summary sticky bit
-+ dma_reg_write(priv, DMA_STATUS_REG, ((1UL << DMA_STATUS_RI_BIT) |
-+ (1UL << DMA_STATUS_NIS_BIT)));
-+
-+ // Must check again for available RX descriptors, in case the RI
-+ // status came from a new RX descriptor
-+ available = rx_available_for_read(&priv->rx_gmac_desc_list_info, 0);
-+ }
-+
-+ if (!available) {
-+ // We have budget left but no Rx packets to process so stop
-+ // polling
-+ continue_polling = 0;
-+ finished = 1;
-+ }
-+ } else {
-+ // If we have consumed all our budget, don't cancel the
-+ // poll, the NAPI instructure assumes we won't
-+ continue_polling = 1;
-+
-+ // Must leave poll() routine as no budget left
-+ finished = 1;
-+ }
-+ } while (!finished);
-+
-+ // Attempt to fill any empty slots in the RX ring
-+ refill_rx_ring(dev);
-+
-+ // Decrement the budget even if we didn't process any packets
-+ if (!work_done) {
-+ work_done = 1;
-+ }
-+
-+ if (!continue_polling) {
-+ // No more received packets to process so return to interrupt mode
-+ netif_rx_complete(dev, napi);
-+
-+ // Enable interrupts caused by received packets that may have been
-+ // disabled in the ISR before entering polled mode
-+ gmac_int_en_set(priv, (1UL << DMA_INT_ENABLE_RI_BIT) |
-+ (1UL << DMA_INT_ENABLE_RU_BIT) |
-+ (1UL << DMA_INT_ENABLE_OV_BIT));
-+ }
-+
-+ return work_done;
-+}
-+
-+#if defined(CONFIG_LEON_COPRO) && defined(CONFIG_LEON_OFFLOAD_TX)
-+static void copro_fill_tx_job(
-+ volatile gmac_tx_que_ent_t *job,
-+ struct sk_buff *skb)
-+{
-+ int i;
-+ int nr_frags = skb_shinfo(skb)->nr_frags;
-+ unsigned short flags = 0;
-+ dma_addr_t hdr_dma_address;
-+
-+ // if too many fragments call sbk_linearize()
-+ // and take the CPU memory copies hit
-+ if (nr_frags > COPRO_NUM_TX_FRAGS_DIRECT) {
-+ int err;
-+ printk(KERN_WARNING "Fill: linearizing socket buffer as required %d frags and have only %d\n", nr_frags, COPRO_NUM_TX_FRAGS_DIRECT);
-+ err = skb_linearize(skb);
-+ if (err) {
-+ panic("Fill: No free memory");
-+ }
-+
-+ // update nr_frags
-+ nr_frags = skb_shinfo(skb)->nr_frags;
-+ }
-+
-+ // Get a DMA mapping of the packet's data
-+ hdr_dma_address = dma_map_single(0, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
-+ BUG_ON(dma_mapping_error(hdr_dma_address));
-+
-+ // Allocate storage for remainder of fragments and create DMA mappings
-+ // Get a DMA mapping for as many fragments as will fit into the first level
-+ // fragment info. storage within the job structure
-+ for (i=0; i < nr_frags; ++i) {
-+ struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
-+ job->frag_ptr_[i] = dma_map_page(0, frag->page, frag->page_offset, frag->size, DMA_TO_DEVICE);
-+ job->frag_len_[i] = frag->size;
-+ }
-+
-+ // Is h/w checksumming and possibly TSO required
-+ if (likely((skb->ip_summed == CHECKSUM_PARTIAL) &&
-+ (ntohs(skb->protocol) == ETH_P_IP))) {
-+ flags |= (1UL << TX_JOB_FLAGS_ACCELERATE_BIT);
-+ }
-+
-+ // Fill the job description with information about the packet
-+ job->skb_ = (u32)skb;
-+ job->len_ = skb->len;
-+ job->data_len_ = skb->data_len;
-+ job->ethhdr_ = hdr_dma_address;
-+ job->iphdr_ = hdr_dma_address + (skb_network_header(skb) - skb->data);
-+ job->iphdr_csum_ = ((struct iphdr*)skb_network_header(skb))->check;
-+ job->tso_segs_ = skb_shinfo(skb)->gso_segs;
-+ job->tso_size_ = skb_shinfo(skb)->gso_size;
-+ job->flags_ = flags;
-+ job->statistics_ = 0;
-+}
-+
-+static void copro_free_tx_resources(volatile gmac_tx_que_ent_t* job)
-+{
-+ int i;
-+ struct sk_buff* skb = (struct sk_buff*)job->skb_;
-+ int nr_frags = skb_shinfo(skb)->nr_frags;
-+
-+ // This should never happen, since we check space when we filled
-+ // the job in copro_fill_tx_job
-+ if (nr_frags > COPRO_NUM_TX_FRAGS_DIRECT) {
-+ panic("Free: Insufficient fragment storage, required %d, have only %d", nr_frags, COPRO_NUM_TX_FRAGS_DIRECT);
-+ }
-+
-+ // Release the DMA mapping for the data directly referenced by the SKB
-+ dma_unmap_single(0, job->ethhdr_, skb_headlen(skb), DMA_TO_DEVICE);
-+
-+ // Release the DMA mapping for any fragments in the first level fragment
-+ // info. storage within the job structure
-+ for (i=0; (i < nr_frags) && (i < COPRO_NUM_TX_FRAGS_DIRECT); ++i) {
-+ dma_unmap_page(0, job->frag_ptr_[i], job->frag_len_[i], DMA_TO_DEVICE);
-+ }
-+
-+ // Inform the network stack that we've finished with the packet
-+ dev_kfree_skb_irq(skb);
-+}
-+
-+static void copro_process_pending_tx_skbs(
-+ struct net_device *dev,
-+ volatile gmac_tx_que_ent_t *job)
-+{
-+ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+
-+ // Process pending SKBs, oldest first
-+ do {
-+ // Get the oldest pending SKB
-+ struct sk_buff *skb;
-+ struct list_head *entry = priv->copro_tx_skb_list_.next;
-+ BUG_ON(!entry);
-+ list_del(entry);
-+
-+ skb = list_entry(entry, struct sk_buff, cb);
-+ BUG_ON(!skb);
-+
-+ // Keep track of how many entries are in the pending SKB list
-+ --priv->copro_tx_skb_list_count_;
-+
-+ // Fill the Tx offload job with the network packet's details
-+ copro_fill_tx_job(job, skb);
-+
-+ // Enqueue the new Tx offload job with the CoPro
-+ tx_que_new_job(dev, job);
-+
-+ if (list_empty(&priv->copro_tx_skb_list_)) {
-+ // No more pending SKBs
-+ break;
-+ }
-+ } while ((job = tx_que_get_idle_job(dev)));
-+}
-+
-+static void finish_xmit(struct net_device *dev)
-+{
-+ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+ volatile gmac_tx_que_ent_t *job;
-+
-+ // Process all available completed jobs
-+ while ((job = tx_que_get_finished_job(dev))) {
-+ int aborted;
-+ int carrier;
-+ int collisions;
-+ u32 statistics = job->statistics_;
-+
-+ copro_free_tx_resources(job);
-+
-+ // Accumulate TX statistics returned by CoPro in the job structure
-+ priv->stats.tx_bytes += (statistics & TX_JOB_STATS_BYTES_MASK) >> TX_JOB_STATS_BYTES_BIT;
-+ priv->stats.tx_packets += (statistics & TX_JOB_STATS_PACKETS_MASK) >> TX_JOB_STATS_PACKETS_BIT;
-+ aborted = (statistics & TX_JOB_STATS_ABORT_MASK) >> TX_JOB_STATS_ABORT_BIT;
-+ carrier = (statistics & TX_JOB_STATS_CARRIER_MASK) >> TX_JOB_STATS_CARRIER_BIT;
-+ collisions = (statistics & TX_JOB_STATS_COLLISION_MASK) >> TX_JOB_STATS_COLLISION_BIT;
-+ priv->stats.tx_aborted_errors += aborted;
-+ priv->stats.tx_carrier_errors += carrier;
-+ priv->stats.collisions += collisions;
-+ priv->stats.tx_errors += (aborted + carrier);
-+ }
-+
-+ // Process any queued pending SKBs for which resources are available
-+ if (priv->copro_tx_skb_list_count_ && (job = tx_que_get_idle_job(dev))) {
-+ copro_process_pending_tx_skbs(dev, job);
-+
-+ // Record start of transmission, so timeouts will work once they're
-+ // implemented
-+ dev->trans_start = jiffies;
-+
-+ // Interrupt the CoPro to cause it to examine the Tx offload queue
-+ wmb();
-+ writel(1UL << COPRO_SEM_INT_TX, SYS_CTRL_SEMA_SET_CTRL);
-+ }
-+
-+ // If the network stack's Tx queue was stopped and we now have resources
-+ // to process more Tx offload jobs
-+ if (netif_queue_stopped(dev) &&
-+ !tx_que_is_full(&priv->tx_queue_) &&
-+ !priv->copro_tx_skb_list_count_) {
-+ // Restart the network stack's TX queue
-+ netif_wake_queue(dev);
-+ }
-+}
-+#else
-+static void finish_xmit(struct net_device *dev)
-+{
-+ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+ unsigned descriptors_freed = 0;
-+ u32 desc_status = 0;
-+
-+ // Handle transmit descriptors for the completed packet transmission
-+ while (1) {
-+ struct sk_buff *skb;
-+ tx_frag_info_t fragment;
-+ int buffer_owned;
-+ int desc_index;
-+
-+ // Get tx descriptor content, accumulating status for all buffers
-+ // contributing to each packet
-+ desc_index = get_tx_descriptor(priv, &skb, &desc_status, &fragment, &buffer_owned);
-+
-+ if (desc_index < 0) {
-+ // No more completed Tx packets
-+ break;
-+ }
-+
-+ // Only unmap DMA buffer if descriptor owned the buffer
-+ if (buffer_owned) {
-+ // Release the DMA mapping for the buffer
-+ dma_unmap_single(0, fragment.phys_adr, fragment.length, DMA_TO_DEVICE);
-+ }
-+
-+ // When all buffers contributing to a packet have been processed
-+ if (skb) {
-+ // Check the status of the transmission
-+ if (likely(is_tx_valid(desc_status))) {
-+ priv->stats.tx_bytes += skb->len;
-+ priv->stats.tx_packets++;
-+ } else {
-+ priv->stats.tx_errors++;
-+ if (is_tx_aborted(desc_status)) {
-+ ++priv->stats.tx_aborted_errors;
-+ }
-+ if (is_tx_carrier_error(desc_status)) {
-+ ++priv->stats.tx_carrier_errors;
-+ }
-+ }
-+
-+ if (unlikely(is_tx_collision_error(desc_status))) {
-+ ++priv->stats.collisions;
-+ }
-+
-+ // Inform the network stack that packet transmission has finished
-+ dev_kfree_skb_irq(skb);
-+
-+ // Start accumulating status for the next packet
-+ desc_status = 0;
-+ }
-+
-+ // Track how many descriptors we make available, so we know
-+ // if we need to re-start of network stack's TX queue processing
-+ ++descriptors_freed;
-+ }
-+
-+ // If the TX queue is stopped, there may be a pending TX packet waiting to
-+ // be transmitted
-+ if (unlikely(netif_queue_stopped(dev))) {
-+ // No locking with hard_start_xmit() required, as queue is already
-+ // stopped so hard_start_xmit() won't touch the h/w
-+
-+ // If any TX descriptors have been freed and there is an outstanding TX
-+ // packet waiting to be queued due to there not having been a TX
-+ // descriptor available when hard_start_xmit() was presented with an skb
-+ // by the network stack
-+ if (priv->tx_pending_skb) {
-+ // Construct the GMAC specific DMA descriptor
-+ if (set_tx_descriptor(priv,
-+ priv->tx_pending_skb,
-+ priv->tx_pending_fragments,
-+ priv->tx_pending_fragment_count,
-+ priv->tx_pending_skb->ip_summed == CHECKSUM_PARTIAL) >= 0) {
-+ // No TX packets now outstanding
-+ priv->tx_pending_skb = 0;
-+ priv->tx_pending_fragment_count = 0;
-+
-+ // We have used one of the TX descriptors freed by transmission
-+ // completion processing having occured above
-+ --descriptors_freed;
-+
-+ // Issue a TX poll demand to restart TX descriptor processing, as we
-+ // have just added one, in case it had found there were no more
-+ // pending transmission
-+ dma_reg_write(priv, DMA_TX_POLL_REG, 0);
-+ }
-+ }
-+
-+ // If there are TX descriptors available we should restart the TX queue
-+ if (descriptors_freed) {
-+ // The TX queue had been stopped by hard_start_xmit() due to lack of
-+ // TX descriptors, so restart it now that we've freed at least one
-+ netif_wake_queue(dev);
-+ }
-+ }
-+}
-+#endif // CONFIG_LEON_COPRO && CONFIG_LEON_OFFLOAD_TX
-+
-+#ifndef CONFIG_LEON_COPRO
-+static void process_non_dma_ints(u32 raw_status)
-+{
-+ printk(KERN_ERR "Found GPI/GMI/GLI interrupt\n");
-+}
-+#endif // !CONFIG_LEON_COPRO
-+
-+#ifdef CONFIG_LEON_COPRO
-+static void copro_fwd_intrs_handler(
-+ void *dev_id,
-+ u32 status)
-+{
-+ struct net_device *dev = (struct net_device *)dev_id;
-+ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+ int restart_watchdog = 0;
-+ int restart_tx = 0;
-+ int poll_tx = 0;
-+
-+ // Test for normal receive interrupt
-+ if (status & (1UL << DMA_STATUS_RI_BIT)) {
-+ if (netif_rx_schedule_prep(dev, &priv->napi_struct)) {
-+ // Tell system we have work to be done
-+ __netif_rx_schedule(dev, &priv->napi_struct);
-+ } else {
-+ printk(KERN_ERR "copro_fwd_intrs_handler() %s: RX interrupt while in poll\n", dev->name);
-+ }
-+ }
-+
-+ // Test for unavailable RX buffers - CoPro should have disabled
-+ if (unlikely(status & (1UL << DMA_STATUS_RU_BIT))) {
-+ DBG(30, KERN_INFO "int_handler() %s: RX buffer unavailable\n", dev->name);
-+ // Accumulate receive statistics
-+ ++priv->stats.rx_over_errors;
-+ ++priv->stats.rx_errors;
-+ }
-+
-+ // Test for Rx overflow - CoPro should have disabled
-+ if (unlikely(status & (1UL << DMA_STATUS_OVF_BIT))) {
-+ DBG(30, KERN_INFO "int_handler() %s: Rx overflow\n", dev->name);
-+ // Accumulate receive statistics
-+ ++priv->stats.rx_fifo_errors;
-+ ++priv->stats.rx_errors;
-+ }
-+
-+ // Test for normal TX interrupt
-+ if (status & ((1UL << DMA_STATUS_TI_BIT) |
-+ (1UL << DMA_STATUS_ETI_BIT))) {
-+#ifndef CONFIG_LEON_OFFLOAD_TX
-+ // Finish packet transmision started by start_xmit
-+ finish_xmit(dev);
-+#endif // !CONFIG_LEON_OFFLOAD_TX
-+ }
-+
-+ // Test for abnormal transmitter interrupt where there may be completed
-+ // packets waiting to be processed
-+ if (unlikely(status & ((1UL << DMA_STATUS_TJT_BIT) |
-+ (1UL << DMA_STATUS_UNF_BIT)))) {
-+#ifndef CONFIG_LEON_OFFLOAD_TX
-+ // Complete processing of any TX packets closed by the DMA
-+ finish_xmit(dev);
-+#endif // !CONFIG_LEON_OFFLOAD_TX
-+
-+ if (status & (1UL << DMA_STATUS_TJT_BIT)) {
-+ // A transmit jabber timeout causes the transmitter to enter the
-+ // stopped state
-+ DBG(50, KERN_INFO "int_handler() %s: TX jabber timeout\n", dev->name);
-+ restart_tx = 1;
-+ } else {
-+ DBG(51, KERN_INFO "int_handler() %s: TX underflow\n", dev->name);
-+ }
-+
-+ // Issue a TX poll demand in an attempt to restart TX descriptor
-+ // processing
-+ poll_tx = 1;
-+ }
-+
-+ // Test for any of the error states which we deal with directly within
-+ // this interrupt service routine.
-+ if (unlikely(status & ((1UL << DMA_STATUS_ERI_BIT) |
-+ (1UL << DMA_STATUS_RWT_BIT) |
-+ (1UL << DMA_STATUS_RPS_BIT) |
-+ (1UL << DMA_STATUS_TPS_BIT) |
-+ (1UL << DMA_STATUS_FBE_BIT)))) {
-+ // Test for early RX interrupt
-+ if (status & (1UL << DMA_STATUS_ERI_BIT)) {
-+ // Don't expect to see this, as never enable it
-+ DBG(30, KERN_WARNING "int_handler() %s: Early RX \n", dev->name);
-+ }
-+
-+ if (status & (1UL << DMA_STATUS_RWT_BIT)) {
-+ DBG(30, KERN_INFO "int_handler() %s: RX watchdog timeout\n", dev->name);
-+ // Accumulate receive statistics
-+ ++priv->stats.rx_frame_errors;
-+ ++priv->stats.rx_errors;
-+ restart_watchdog = 1;
-+ }
-+
-+ if (status & (1UL << DMA_STATUS_RPS_BIT)) {
-+ // Mask to extract the receive status field from the status register
-+// u32 rs_mask = ((1UL << DMA_STATUS_RS_NUM_BITS) - 1) << DMA_STATUS_RS_BIT;
-+// u32 rs = (status & rs_mask) >> DMA_STATUS_RS_BIT;
-+// printk("int_handler() %s: RX process stopped 0x%x\n", dev->name, rs);
-+ ++priv->stats.rx_errors;
-+ restart_watchdog = 1;
-+
-+ // Restart the receiver
-+ DBG(35, KERN_INFO "int_handler() %s: Restarting receiver\n", dev->name);
-+ change_rx_enable(priv, 1, 0, 1);
-+ }
-+
-+ if (status & (1UL << DMA_STATUS_TPS_BIT)) {
-+ // Mask to extract the transmit status field from the status register
-+// u32 ts_mask = ((1UL << DMA_STATUS_TS_NUM_BITS) - 1) << DMA_STATUS_TS_BIT;
-+// u32 ts = (status & ts_mask) >> DMA_STATUS_TS_BIT;
-+// printk("int_handler() %s: TX process stopped 0x%x\n", dev->name, ts);
-+ ++priv->stats.tx_errors;
-+ restart_watchdog = 1;
-+ restart_tx = 1;
-+ }
-+
-+ // Test for pure error interrupts
-+ if (status & (1UL << DMA_STATUS_FBE_BIT)) {
-+ // Mask to extract the bus error status field from the status register
-+// u32 eb_mask = ((1UL << DMA_STATUS_EB_NUM_BITS) - 1) << DMA_STATUS_EB_BIT;
-+// u32 eb = (status & eb_mask) >> DMA_STATUS_EB_BIT;
-+// printk("int_handler() %s: Bus error 0x%x\n", dev->name, eb);
-+ restart_watchdog = 1;
-+ }
-+
-+ if (restart_watchdog) {
-+ // Restart the link/PHY state watchdog immediately, which will
-+ // attempt to restart the system
-+ mod_timer(&priv->watchdog_timer, jiffies);
-+ restart_watchdog = 0;
-+ }
-+ }
-+
-+ if (unlikely(restart_tx)) {
-+ // Restart the transmitter, causes am implicit Tx descriptor list poll
-+ DBG(35, KERN_INFO "int_handler() %s: Restarting transmitter\n", dev->name);
-+#ifndef CONFIG_LEON_OFFLOAD_TX
-+ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
-+#endif // !CONFIG_LEON_OFFLOAD_TX
-+ poll_tx = 0;
-+ }
-+
-+ if (unlikely(poll_tx)) {
-+ // Issue a TX poll demand in an attempt to restart TX descriptor
-+ // processing
-+ DBG(33, KERN_INFO "int_handler() %s: Issuing Tx poll demand\n", dev->name);
-+#ifndef CONFIG_LEON_OFFLOAD_TX
-+ dma_reg_write(priv, DMA_TX_POLL_REG, 0);
-+#endif // !CONFIG_LEON_OFFLOAD_TX
-+ }
-+}
-+#else // CONFIG_LEON_COPRO
-+static irqreturn_t int_handler(int int_num, void* dev_id)
-+{
-+ struct net_device *dev = (struct net_device *)dev_id;
-+ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+ u32 int_enable;
-+ int rx_polling;
-+ u32 raw_status;
-+ u32 status;
-+
-+ /** Read the interrupt enable register to determine if we're in rx poll mode
-+ * Id like to get rid of this read, if a more efficient way of determining
-+ * whether we are polling is available */
-+ spin_lock(&priv->cmd_que_lock_);
-+ int_enable = dma_reg_read(priv, DMA_INT_ENABLE_REG);
-+ spin_unlock(&priv->cmd_que_lock_);
-+
-+ rx_polling = !(int_enable & (1UL << DMA_INT_ENABLE_RI_BIT));
-+
-+ // Get interrupt status
-+ raw_status = dma_reg_read(priv, DMA_STATUS_REG);
-+
-+ // MMC, PMT and GLI interrupts are not masked by the interrupt enable
-+ // register, so must deal with them on the raw status
-+ if (unlikely(raw_status & ((1UL << DMA_STATUS_GPI_BIT) |
-+ (1UL << DMA_STATUS_GMI_BIT) |
-+ (1UL << DMA_STATUS_GLI_BIT)))) {
-+ process_non_dma_ints(raw_status);
-+ }
-+
-+ // Get status of enabled interrupt sources
-+ status = raw_status & int_enable;
-+
-+ while (status) {
-+ // Whether the link/PHY watchdog timer should be restarted
-+ int restart_watchdog = 0;
-+ int restart_tx = 0;
-+ int poll_tx = 0;
-+ u32 int_disable_mask = 0;
-+
-+ // Test for RX interrupt resulting from sucessful reception of a packet-
-+ // must do this before ack'ing, else otherwise can get into trouble with
-+ // the sticky summary bits when we try to disable further RI interrupts
-+ if (status & (1UL << DMA_STATUS_RI_BIT)) {
-+//printk("RI ");
-+ // Disable interrupts caused by received packets as henceforth
-+ // we shall poll for packet reception
-+ int_disable_mask |= (1UL << DMA_INT_ENABLE_RI_BIT);
-+
-+ // Do NAPI compatible receive processing for RI interrupts
-+ if (likely(netif_rx_schedule_prep(dev, &priv->napi_struct))) {
-+ // Remember that we are polling, so we ignore RX events for the
-+ // remainder of the ISR
-+ rx_polling = 1;
-+
-+ // Tell system we have work to be done
-+ __netif_rx_schedule(dev, &priv->napi_struct);
-+ } else {
-+ printk(KERN_ERR "int_handler() %s: RX interrupt while in poll\n", dev->name);
-+ }
-+ }
-+
-+ // Test for unavailable RX buffers - must do this before ack'ing, else
-+ // otherwise can get into trouble with the sticky summary bits
-+ if (unlikely(status & (1UL << DMA_STATUS_RU_BIT))) {
-+ printk(/*DBG(30, KERN_INFO */"int_handler() %s: RX buffer unavailable\n", dev->name);
-+ // Accumulate receive statistics
-+ ++priv->stats.rx_over_errors;
-+ ++priv->stats.rx_errors;
-+
-+ // Disable RX buffer unavailable reporting, so we don't get swamped
-+ int_disable_mask |= (1UL << DMA_INT_ENABLE_RU_BIT);
-+ }
-+
-+ if (unlikely(status & (1UL << DMA_STATUS_OVF_BIT))) {
-+ printk(/*DBG(30, KERN_INFO */"int_handler() %s: RX overflow\n", dev->name);
-+ // Accumulate receive statistics
-+ ++priv->stats.rx_fifo_errors;
-+ ++priv->stats.rx_errors;
-+
-+ // Disable RX overflow reporting, so we don't get swamped
-+ int_disable_mask |= (1UL << DMA_INT_ENABLE_OV_BIT);
-+ }
-+
-+ // Do any interrupt disabling with a single register write
-+ if (int_disable_mask) {
-+ gmac_int_en_clr(priv, int_disable_mask, 0);
-+
-+ // Update our record of the current interrupt enable status
-+ int_enable &= ~int_disable_mask;
-+ }
-+
-+ // The broken GMAC interrupt mechanism with its sticky summary bits
-+ // means that we have to ack all asserted interrupts here; we can't not
-+ // ack the RI interrupt source as we might like to (in order that the
-+ // poll() routine could examine the status) because if it was asserted
-+ // prior to being masked above, then the summary bit(s) would remain
-+ // asserted and cause an immediate re-interrupt.
-+ dma_reg_write(priv, DMA_STATUS_REG, status | ((1UL << DMA_STATUS_NIS_BIT) |
-+ (1UL << DMA_STATUS_AIS_BIT)));
-+
-+ // Test for normal TX interrupt
-+ if (status & ((1UL << DMA_STATUS_TI_BIT) |
-+ (1UL << DMA_STATUS_ETI_BIT))) {
-+ // Finish packet transmision started by start_xmit
-+ finish_xmit(dev);
-+ }
-+
-+ // Test for abnormal transmitter interrupt where there may be completed
-+ // packets waiting to be processed
-+ if (unlikely(status & ((1UL << DMA_STATUS_TJT_BIT) |
-+ (1UL << DMA_STATUS_UNF_BIT)))) {
-+ // Complete processing of any TX packets closed by the DMA
-+ finish_xmit(dev);
-+
-+ if (status & (1UL << DMA_STATUS_TJT_BIT)) {
-+ // A transmit jabber timeout causes the transmitter to enter the
-+ // stopped state
-+ DBG(50, KERN_INFO "int_handler() %s: TX jabber timeout\n", dev->name);
-+ restart_tx = 1;
-+ } else {
-+ DBG(51, KERN_INFO "int_handler() %s: TX underflow\n", dev->name);
-+ }
-+
-+ // Issue a TX poll demand in an attempt to restart TX descriptor
-+ // processing
-+ poll_tx = 1;
-+ }
-+
-+ // Test for any of the error states which we deal with directly within
-+ // this interrupt service routine.
-+ if (unlikely(status & ((1UL << DMA_STATUS_ERI_BIT) |
-+ (1UL << DMA_STATUS_RWT_BIT) |
-+ (1UL << DMA_STATUS_RPS_BIT) |
-+ (1UL << DMA_STATUS_TPS_BIT) |
-+ (1UL << DMA_STATUS_FBE_BIT)))) {
-+ // Test for early RX interrupt
-+ if (status & (1UL << DMA_STATUS_ERI_BIT)) {
-+ // Don't expect to see this, as never enable it
-+ DBG(30, KERN_WARNING "int_handler() %s: Early RX \n", dev->name);
-+ }
-+
-+ if (status & (1UL << DMA_STATUS_RWT_BIT)) {
-+ DBG(30, KERN_INFO "int_handler() %s: RX watchdog timeout\n", dev->name);
-+ // Accumulate receive statistics
-+ ++priv->stats.rx_frame_errors;
-+ ++priv->stats.rx_errors;
-+ restart_watchdog = 1;
-+ }
-+
-+ if (status & (1UL << DMA_STATUS_RPS_BIT)) {
-+ // Mask to extract the receive status field from the status register
-+ u32 rs_mask = ((1UL << DMA_STATUS_RS_NUM_BITS) - 1) << DMA_STATUS_RS_BIT;
-+ u32 rs = (status & rs_mask) >> DMA_STATUS_RS_BIT;
-+ printk(/*DBG(30, KERN_INFO */"int_handler() %s: RX process stopped 0x%x\n", dev->name, rs);
-+ ++priv->stats.rx_errors;
-+ restart_watchdog = 1;
-+
-+ // Restart the receiver
-+ printk(/*DBG(35, KERN_INFO */"int_handler() %s: Restarting receiver\n", dev->name);
-+ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SR_BIT));
-+ }
-+
-+ if (status & (1UL << DMA_STATUS_TPS_BIT)) {
-+ // Mask to extract the transmit status field from the status register
-+// u32 ts_mask = ((1UL << DMA_STATUS_TS_NUM_BITS) - 1) << DMA_STATUS_TS_BIT;
-+// u32 ts = (status & ts_mask) >> DMA_STATUS_TS_BIT;
-+// DBG(30, KERN_INFO "int_handler() %s: TX process stopped 0x%x\n", dev->name, ts);
-+ ++priv->stats.tx_errors;
-+ restart_watchdog = 1;
-+ restart_tx = 1;
-+ }
-+
-+ // Test for pure error interrupts
-+ if (status & (1UL << DMA_STATUS_FBE_BIT)) {
-+ // Mask to extract the bus error status field from the status register
-+// u32 eb_mask = ((1UL << DMA_STATUS_EB_NUM_BITS) - 1) << DMA_STATUS_EB_BIT;
-+// u32 eb = (status & eb_mask) >> DMA_STATUS_EB_BIT;
-+// DBG(30, KERN_INFO "int_handler() %s: Bus error 0x%x\n", dev->name, eb);
-+ restart_watchdog = 1;
-+ }
-+
-+ if (restart_watchdog) {
-+ // Restart the link/PHY state watchdog immediately, which will
-+ // attempt to restart the system
-+ mod_timer(&priv->watchdog_timer, jiffies);
-+ restart_watchdog = 0;
-+ }
-+ }
-+
-+ if (unlikely(restart_tx)) {
-+ // Restart the transmitter
-+ DBG(35, KERN_INFO "int_handler() %s: Restarting transmitter\n", dev->name);
-+ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
-+ }
-+
-+ if (unlikely(poll_tx)) {
-+ // Issue a TX poll demand in an attempt to restart TX descriptor
-+ // processing
-+ DBG(33, KERN_INFO "int_handler() %s: Issuing Tx poll demand\n", dev->name);
-+ dma_reg_write(priv, DMA_TX_POLL_REG, 0);
-+ }
-+
-+ // Read the record of current interrupt requests again, in case some
-+ // more arrived while we were processing
-+ raw_status = dma_reg_read(priv, DMA_STATUS_REG);
-+
-+ // MMC, PMT and GLI interrupts are not masked by the interrupt enable
-+ // register, so must deal with them on the raw status
-+ if (unlikely(raw_status & ((1UL << DMA_STATUS_GPI_BIT) |
-+ (1UL << DMA_STATUS_GMI_BIT) |
-+ (1UL << DMA_STATUS_GLI_BIT)))) {
-+ process_non_dma_ints(raw_status);
-+ }
-+
-+ // Get status of enabled interrupt sources.
-+ status = raw_status & int_enable;
-+ }
-+
-+ return IRQ_HANDLED;
-+}
-+#endif // CONFIG_LEON_COPRO
-+
-+#ifdef CONFIG_LEON_COPRO
-+static struct semaphore copro_stop_semaphore;
-+
-+static void copro_stop_callback(volatile gmac_cmd_que_ent_t* entry)
-+{
-+ up(&copro_stop_semaphore);
-+}
-+#endif // CONFIG_LEON_COPRO
-+
-+static void gmac_down(struct net_device *dev)
-+{
-+ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+ int desc;
-+ u32 int_enable;
-+#ifdef CONFIG_LEON_COPRO
-+ tx_que_t *tx_queue = &priv->tx_queue_;
-+ int cmd_queue_result;
-+#endif // CONFIG_LEON_COPRO
-+
-+ // Stop NAPI
-+ napi_disable(&priv->napi_struct);
-+
-+ // Stop further TX packets being delivered to hard_start_xmit();
-+ netif_stop_queue(dev);
-+ netif_carrier_off(dev);
-+
-+ // Disable all GMAC interrupts and wait for change to be acknowledged
-+ gmac_int_en_clr(priv, ~0UL, &int_enable, 0);
-+
-+#ifdef CONFIG_LEON_COPRO
-+ // Tell the CoPro to stop network offload operations
-+ cmd_queue_result = -1;
-+ while (cmd_queue_result) {
-+ spin_lock(&priv->cmd_que_lock_);
-+ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_STOP, 0, copro_stop_callback);
-+ spin_unlock(&priv->cmd_que_lock_);
-+ }
-+
-+ // Interrupt the CoPro so it sees the new command
-+ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+
-+ // Wait until the CoPro acknowledges the STOP command
-+ down_interruptible(&copro_stop_semaphore);
-+
-+ // Wait until the CoPro acknowledges that it has completed stopping
-+ down_interruptible(&priv->copro_stop_complete_semaphore_);
-+
-+ // Clear out the Tx offload job queue, deallocating associated resources
-+ while (tx_que_not_empty(tx_queue)) {
-+ // Free any dynamic fragment ptr/len storage
-+ /** @todo */
-+ tx_que_inc_r_ptr(tx_queue);
-+ }
-+
-+ // Reinitialise the Tx offload queue metadata
-+ tx_que_init(
-+ &priv->tx_queue_,
-+ (gmac_tx_que_ent_t*)descriptors_phys_to_virt(priv->copro_params_.tx_que_head_),
-+ priv->copro_tx_que_num_entries_);
-+
-+ // Empty the pending SKB queue
-+ while (!list_empty(&priv->copro_tx_skb_list_)) {
-+ struct sk_buff *skb;
-+
-+ // Remove the first entry on the list
-+ struct list_head *entry = priv->copro_tx_skb_list_.next;
-+ BUG_ON(!entry);
-+ list_del(entry);
-+
-+ // Get pointer to SKB from it's list_head member
-+ skb = list_entry(entry, struct sk_buff, cb);
-+ BUG_ON(!skb);
-+
-+ // Inform the network stack that we've finished with the packet
-+ dev_kfree_skb(skb);
-+ }
-+ priv->copro_tx_skb_list_count_ = 0;
-+#endif // CONFIG_LEON_COPRO
-+
-+#ifndef CONFIG_LEON_OFFLOAD_TX
-+ // Stop transmitter, take ownership of all tx descriptors
-+ dma_reg_clear_mask(priv, DMA_OP_MODE_REG, 1UL << DMA_OP_MODE_ST_BIT);
-+ if (priv->desc_vaddr) {
-+ tx_take_ownership(&priv->tx_gmac_desc_list_info);
-+ }
-+#endif // !CONFIG_LEON_OFFLOAD_TX
-+
-+ // Stop receiver, waiting until it's really stopped and then take ownership
-+ // of all rx descriptors
-+ change_rx_enable(priv, 0, 1, 0);
-+
-+ if (priv->desc_vaddr) {
-+ rx_take_ownership(&priv->rx_gmac_desc_list_info);
-+ }
-+
-+ // Stop all timers
-+ delete_watchdog_timer(priv);
-+
-+ if (priv->desc_vaddr) {
-+ // Free receive descriptors
-+ do {
-+ int first_last = 0;
-+ rx_frag_info_t frag_info;
-+
-+ desc = get_rx_descriptor(priv, &first_last, 0, &frag_info);
-+ if (desc >= 0) {
-+ if (unlikely(priv->rx_buffers_per_page)) {
-+ // If this is the last packet in the page, release the DMA mapping
-+ unmap_rx_page(priv, frag_info.phys_adr);
-+ put_page(frag_info.page);
-+ } else {
-+ // Release the DMA mapping for the packet buffer
-+ dma_unmap_single(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
-+
-+ // Free the skb
-+ dev_kfree_skb((struct sk_buff *)frag_info.page);
-+ }
-+ }
-+ } while (desc >= 0);
-+
-+ // Free transmit descriptors
-+ do {
-+ struct sk_buff *skb;
-+ tx_frag_info_t frag_info;
-+ int buffer_owned;
-+
-+ desc = get_tx_descriptor(priv, &skb, 0, &frag_info, &buffer_owned);
-+ if (desc >= 0) {
-+ if (buffer_owned) {
-+ // Release the DMA mapping for the packet buffer
-+ dma_unmap_single(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
-+ }
-+
-+ if (skb) {
-+ // Free the skb
-+ dev_kfree_skb(skb);
-+ }
-+ }
-+ } while (desc >= 0);
-+
-+ // Free any resources associated with the buffers of a pending packet
-+ if (priv->tx_pending_fragment_count) {
-+ tx_frag_info_t *frag_info = priv->tx_pending_fragments;
-+
-+ while (priv->tx_pending_fragment_count--) {
-+ dma_unmap_single(0, frag_info->phys_adr, frag_info->length, DMA_FROM_DEVICE);
-+ ++frag_info;
-+ }
-+ }
-+
-+ // Free the socket buffer of a pending packet
-+ if (priv->tx_pending_skb) {
-+ dev_kfree_skb(priv->tx_pending_skb);
-+ priv->tx_pending_skb = 0;
-+ }
-+ }
-+
-+ // Power down the PHY
-+ phy_powerdown(dev);
-+}
-+
-+static int stop(struct net_device *dev)
-+{
-+ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+
-+ gmac_down(dev);
-+
-+#ifdef CONFIG_LEON_COPRO
-+ shutdown_copro();
-+
-+ if (priv->shared_copro_params_) {
-+ // Free the DMA coherent parameter space
-+ dma_free_coherent(0, sizeof(copro_params_t), priv->shared_copro_params_, priv->shared_copro_params_pa_);
-+ priv->shared_copro_params_ = 0;
-+ }
-+
-+ // Disable semaphore register from causing ARM interrupts
-+ *((volatile unsigned long*)SYS_CTRL_SEMA_MASKA_CTRL) = 0;
-+ *((volatile unsigned long*)SYS_CTRL_SEMA_MASKB_CTRL) = 0;
-+
-+ // Release interrupts lines used by semaphore register interrupts
-+ if (priv->copro_a_irq_alloced_) {
-+ free_irq(priv->copro_a_irq_, dev);
-+ priv->copro_a_irq_alloced_ = 0;
-+ }
-+ if (priv->copro_b_irq_alloced_) {
-+ free_irq(priv->copro_b_irq_, dev);
-+ priv->copro_b_irq_alloced_ = 0;
-+ }
-+#endif // CONFIG_LEON_COPRO
-+
-+ // Free the shadow descriptor memory
-+ kfree(priv->tx_desc_shadow_);
-+ priv->tx_desc_shadow_ = 0;
-+
-+ kfree(priv->rx_desc_shadow_);
-+ priv->rx_desc_shadow_ = 0;
-+
-+ // Release the IRQ
-+ if (priv->have_irq) {
-+ free_irq(dev->irq, dev);
-+ priv->have_irq = 0;
-+ }
-+
-+ // Disable the clock to the MAC block
-+ writel(1UL << SYS_CTRL_CKEN_MAC_BIT, SYS_CTRL_CKEN_CLR_CTRL);
-+
-+ // Free the sysfs resources
-+ kobject_del(&priv->link_state_kobject);
-+ subsystem_unregister(&priv->link_state_kset);
-+
-+ return 0;
-+}
-+
-+static void hw_set_mac_address(struct net_device *dev, unsigned char* addr)
-+{
-+ u32 mac_lo;
-+ u32 mac_hi;
-+
-+ mac_lo = (u32)addr[0];
-+ mac_lo |= ((u32)addr[1] << 8);
-+ mac_lo |= ((u32)addr[2] << 16);
-+ mac_lo |= ((u32)addr[3] << 24);
-+
-+ mac_hi = (u32)addr[4];
-+ mac_hi |= ((u32)addr[5] << 8);
-+
-+ mac_reg_write(netdev_priv(dev), MAC_ADR0_LOW_REG, mac_lo);
-+ mac_reg_write(netdev_priv(dev), MAC_ADR0_HIGH_REG, mac_hi);
-+}
-+
-+static int set_mac_address(struct net_device *dev, void *p)
-+{
-+ struct sockaddr *addr = p;
-+
-+ if (!is_valid_ether_addr(addr->sa_data)) {
-+ return -EADDRNOTAVAIL;
-+ }
-+
-+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
-+ hw_set_mac_address(dev, addr->sa_data);
-+
-+ return 0;
-+}
-+
-+static void multicast_hash(struct dev_mc_list *dmi, u32 *hash_lo, u32 *hash_hi)
-+{
-+ u32 crc = ether_crc_le(dmi->dmi_addrlen, dmi->dmi_addr);
-+ u32 mask = 1 << ((crc >> 26) & 0x1F);
-+
-+ if (crc >> 31) {
-+ *hash_hi |= mask;
-+ } else {
-+ *hash_lo |= mask;
-+ }
-+}
-+
-+static void set_multicast_list(struct net_device *dev)
-+{
-+ gmac_priv_t* priv = netdev_priv(dev);
-+ u32 hash_lo=0;
-+ u32 hash_hi=0;
-+ u32 mode = 0;
-+ int i;
-+
-+ // Disable promiscuous mode and uni/multi-cast matching
-+ mac_reg_write(priv, MAC_FRAME_FILTER_REG, mode);
-+
-+ // Disable all perfect match registers
-+ for (i=0; i < NUM_PERFECT_MATCH_REGISTERS; ++i) {
-+ mac_adrhi_reg_write(priv, i, 0);
-+ }
-+
-+ // Promiscuous mode overrides all-multi which overrides other filtering
-+ if (dev->flags & IFF_PROMISC) {
-+ mode |= (1 << MAC_FRAME_FILTER_PR_BIT);
-+ } else if (dev->flags & IFF_ALLMULTI) {
-+ mode |= (1 << MAC_FRAME_FILTER_PM_BIT);
-+ } else {
-+ struct dev_mc_list *dmi;
-+
-+ if (dev->mc_count <= NUM_PERFECT_MATCH_REGISTERS) {
-+ // Use perfect matching registers
-+ for (i=0, dmi = dev->mc_list; dmi; dmi = dmi->next, ++i) {
-+ u32 addr;
-+
-+ addr = dmi->dmi_addr[0];
-+ addr |= (u32)dmi->dmi_addr[1] << 8;
-+ addr |= (u32)dmi->dmi_addr[2] << 16;
-+ addr |= (u32)dmi->dmi_addr[3] << 24;
-+ mac_adrlo_reg_write(priv, i, addr);
-+
-+ addr = dmi->dmi_addr[4];
-+ addr |= (u32)dmi->dmi_addr[5] << 8;
-+ addr |= (1 << MAC_ADR1_HIGH_AE_BIT);
-+ mac_adrhi_reg_write(priv, i, addr);
-+ }
-+ } else {
-+ // Use hashing
-+ mode |= (1 << MAC_FRAME_FILTER_HUC_BIT);
-+ mode |= (1 << MAC_FRAME_FILTER_HMC_BIT);
-+
-+ for (dmi = dev->mc_list; dmi; dmi = dmi->next) {
-+ multicast_hash(dmi, &hash_lo, &hash_hi);
-+ }
-+ }
-+ }
-+
-+ // Update the filtering rules
-+ mac_reg_write(priv, MAC_FRAME_FILTER_REG, mode);
-+
-+ // Update the filtering hash table
-+ mac_reg_write(priv, MAC_HASH_LOW_REG, hash_lo);
-+ mac_reg_write(priv, MAC_HASH_HIGH_REG, hash_hi);
-+}
-+
-+static int gmac_up(struct net_device *dev)
-+{
-+ int status = 0;
-+ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+ u32 reg_contents;
-+#ifdef CONFIG_LEON_COPRO
-+ int cmd_queue_result;
-+#endif // CONFIG_LEON_COPRO
-+
-+ // Reset the entire GMAC
-+ dma_reg_write(priv, DMA_BUS_MODE_REG, 1UL << DMA_BUS_MODE_SWR_BIT);
-+
-+ // Ensure reset is performed before testing for completion
-+ wmb();
-+
-+ // Wait for the reset operation to complete
-+ status = -EIO;
-+ printk(KERN_INFO "Resetting GMAC\n");
-+ for (;;) {
-+ if (!(dma_reg_read(priv, DMA_BUS_MODE_REG) & (1UL << DMA_BUS_MODE_SWR_BIT))) {
-+ status = 0;
-+ break;
-+ }
-+ }
-+
-+ // Did the GMAC reset operation fail?
-+ if (status) {
-+ printk(KERN_ERR "open() %s: GMAC reset failed\n", dev->name);
-+ goto gmac_up_err_out;
-+ }
-+ printk(KERN_INFO "GMAC reset complete\n");
-+
-+ /* Initialise MAC config register contents
-+ */
-+ reg_contents = 0;
-+ if (!priv->mii.using_1000) {
-+ DBG(1, KERN_INFO "open() %s: PHY in 10/100Mb mode\n", dev->name);
-+ reg_contents |= (1UL << MAC_CONFIG_PS_BIT);
-+ } else {
-+ DBG(1, KERN_INFO "open() %s: PHY in 1000Mb mode\n", dev->name);
-+ }
-+ if (priv->mii.full_duplex) {
-+ reg_contents |= (1UL << MAC_CONFIG_DM_BIT);
-+ }
-+
-+#ifdef USE_RX_CSUM
-+ reg_contents |= (1UL << MAC_CONFIG_IPC_BIT);
-+#endif // USE_RX_CSUM
-+
-+ if (priv->jumbo_) {
-+ // Allow passage of jumbo frames through both transmitter and receiver
-+ reg_contents |= ((1UL << MAC_CONFIG_JE_BIT) |
-+ (1UL << MAC_CONFIG_JD_BIT) |
-+ (1UL << MAC_CONFIG_WD_BIT));
-+ }
-+
-+ // Enable transmitter and receiver
-+ reg_contents |= ((1UL << MAC_CONFIG_TE_BIT) |
-+ (1UL << MAC_CONFIG_RE_BIT));
-+
-+ // Select the minimum IFG - I found that 80 bit times caused very poor
-+ // IOZone performance, so stcik with the 96 bit times default
-+ reg_contents |= (0UL << MAC_CONFIG_IFG_BIT);
-+
-+ // Write MAC config setup to the GMAC
-+ mac_reg_write(priv, MAC_CONFIG_REG, reg_contents);
-+
-+ /* Initialise MAC VLAN register contents
-+ */
-+ reg_contents = 0;
-+ mac_reg_write(priv, MAC_VLAN_TAG_REG, reg_contents);
-+
-+ // Initialise the hardware's record of our primary MAC address
-+ hw_set_mac_address(dev, dev->dev_addr);
-+
-+ // Initialise multicast and promiscuous modes
-+ set_multicast_list(dev);
-+
-+ // Disable all MMC interrupt sources
-+ mac_reg_write(priv, MMC_RX_MASK_REG, ~0UL);
-+ mac_reg_write(priv, MMC_TX_MASK_REG, ~0UL);
-+
-+ // Remember how large the unified descriptor array is to be
-+ priv->total_num_descriptors = NUM_TX_DMA_DESCRIPTORS + NUM_RX_DMA_DESCRIPTORS;
-+
-+ // Initialise the structures managing the TX descriptor list
-+ init_tx_desc_list(&priv->tx_gmac_desc_list_info,
-+ priv->desc_vaddr,
-+ priv->tx_desc_shadow_,
-+ NUM_TX_DMA_DESCRIPTORS);
-+
-+ // Initialise the structures managing the RX descriptor list
-+ init_rx_desc_list(&priv->rx_gmac_desc_list_info,
-+ priv->desc_vaddr + NUM_TX_DMA_DESCRIPTORS,
-+ priv->rx_desc_shadow_,
-+ NUM_RX_DMA_DESCRIPTORS,
-+ priv->rx_buffer_size_);
-+
-+ // Reset record of pending Tx packet
-+ priv->tx_pending_skb = 0;
-+ priv->tx_pending_fragment_count = 0;
-+
-+#ifndef CONFIG_LEON_OFFLOAD_TX
-+ // Write the physical DMA consistent address of the start of the tx descriptor array
-+ dma_reg_write(priv, DMA_TX_DESC_ADR_REG, priv->desc_dma_addr);
-+#endif // !CONFIG_LEON_OFFLOAD_TX
-+
-+ // Write the physical DMA consistent address of the start of the rx descriptor array
-+ dma_reg_write(priv, DMA_RX_DESC_ADR_REG, priv->desc_dma_addr +
-+ (priv->tx_gmac_desc_list_info.num_descriptors * sizeof(gmac_dma_desc_t)));
-+
-+ // Initialise the GMAC DMA bus mode register
-+ dma_reg_write(priv, DMA_BUS_MODE_REG, ((1UL << DMA_BUS_MODE_FB_BIT) | // Force bursts
-+ (8UL << DMA_BUS_MODE_PBL_BIT) | // AHB burst size
-+ (1UL << DMA_BUS_MODE_DA_BIT))); // Round robin Rx/Tx
-+
-+ // Prepare receive descriptors
-+ refill_rx_ring(dev);
-+
-+ // Clear any pending interrupt requests
-+ dma_reg_write(priv, DMA_STATUS_REG, dma_reg_read(priv, DMA_STATUS_REG));
-+
-+ /* Initialise flow control register contents
-+ */
-+ // Enable Rx flow control
-+ reg_contents = (1UL << MAC_FLOW_CNTL_RFE_BIT);
-+
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+ if (priv->mii.using_pause) {
-+ // Enable Tx flow control
-+ reg_contents |= (1UL << MAC_FLOW_CNTL_TFE_BIT);
-+ }
-+
-+ // Set the duration of the pause frames generated by the transmitter when
-+ // the Rx fifo fill threshold is exceeded
-+ reg_contents |= ((0x100UL << MAC_FLOW_CNTL_PT_BIT) | // Pause for 256 slots
-+ (0x1UL << MAC_FLOW_CNTL_PLT_BIT));
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+
-+ // Write flow control setup to the GMAC
-+ mac_reg_write(priv, MAC_FLOW_CNTL_REG, reg_contents);
-+
-+ /* Initialise operation mode register contents
-+ */
-+ // Initialise the GMAC DMA operation mode register. Set Tx/Rx FIFO thresholds
-+ // to make best use of our limited SDRAM bandwidth when operating in gigabit
-+ reg_contents = ((DMA_OP_MODE_TTC_256 << DMA_OP_MODE_TTC_BIT) | // Tx threshold
-+ (1UL << DMA_OP_MODE_FUF_BIT) | // Forward Undersized good Frames
-+ (DMA_OP_MODE_RTC_128 << DMA_OP_MODE_RTC_BIT) | // Rx threshold 128 bytes
-+ (1UL << DMA_OP_MODE_OSF_BIT)); // Operate on 2nd frame
-+
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+ // Enable hardware flow control
-+ reg_contents |= (1UL << DMA_OP_MODE_EFC_BIT);
-+
-+ // Set threshold for enabling hardware flow control at (full-4KB) to give
-+ // space for upto two in-flight std MTU packets to arrive after pause frame
-+ // has been sent.
-+ reg_contents |= ((0UL << DMA_OP_MODE_RFA2_BIT) |
-+ (3UL << DMA_OP_MODE_RFA_BIT));
-+
-+ // Set threshold for disabling hardware flow control (-7KB)
-+ reg_contents |= ((1UL << DMA_OP_MODE_RFD2_BIT) |
-+ (2UL << DMA_OP_MODE_RFD_BIT));
-+
-+ // Don't flush Rx frames from FIFO just because there's no descriptor available
-+ reg_contents |= (1UL << DMA_OP_MODE_DFF_BIT);
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+
-+ // Write settings to operation mode register
-+ dma_reg_write(priv, DMA_OP_MODE_REG, reg_contents);
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ // Use store&forward when operating in gigabit mode, as OX800 does not have
-+ // sufficient SDRAM bandwidth to support gigabit Tx without it and OX800
-+ // does not support Tx checksumming in the GMAC
-+ if (priv->mii.using_1000) {
-+ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
-+ } else {
-+ dma_reg_clear_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
-+ }
-+#else // CONFIG_OXNAS_VERSION_0X800
-+ // GMAC requires store&forward in order to compute Tx checksums
-+ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+ // Ensure setup is complete, before enabling TX and RX
-+ wmb();
-+
-+#ifdef CONFIG_LEON_COPRO
-+ // Update the CoPro's parameters with the current MTU
-+ priv->copro_params_.mtu_ = dev->mtu;
-+
-+ // Only attempt to write to uncached/unbuffered shared parameter storage if
-+ // CoPro is started and thus storage has been allocated
-+ if (priv->shared_copro_params_) {
-+ // Fill the CoPro parameter block
-+ memcpy(priv->shared_copro_params_, &priv->copro_params_, sizeof(copro_params_t));
-+ }
-+
-+ // Make sure the CoPro parameter block updates have made it to memory (which
-+ // is uncached/unbuffered, so just compiler issues to overcome)
-+ wmb();
-+
-+ // Tell the CoPro to re-read parameters
-+ cmd_queue_result = -1;
-+ while (cmd_queue_result) {
-+ spin_lock(&priv->cmd_que_lock_);
-+ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_UPDATE_PARAMS, 0, copro_update_callback);
-+ spin_unlock(&priv->cmd_que_lock_);
-+ }
-+
-+ // Interrupt the CoPro so it sees the new command
-+ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+
-+ // Wait until the CoPro acknowledges that the update of parameters is complete
-+ down_interruptible(&copro_update_semaphore);
-+
-+ // Tell the CoPro to begin network offload operations
-+ cmd_queue_result = -1;
-+ while (cmd_queue_result) {
-+ spin_lock(&priv->cmd_que_lock_);
-+ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_START, 0, copro_start_callback);
-+ spin_unlock(&priv->cmd_que_lock_);
-+ }
-+
-+ // Interrupt the CoPro so it sees the new command
-+ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+
-+ // Wait until the CoPro acknowledges that it has started
-+ down_interruptible(&copro_start_semaphore);
-+#endif // CONFIG_LEON_COPRO
-+
-+ // Start NAPI
-+ napi_enable(&priv->napi_struct);
-+
-+ // Start the transmitter and receiver
-+#ifndef CONFIG_LEON_OFFLOAD_TX
-+ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
-+#endif // !LEON_OFFLOAD_TX
-+ change_rx_enable(priv, 1, 0, 0);
-+
-+ // Enable interesting GMAC interrupts
-+ gmac_int_en_set(priv, ((1UL << DMA_INT_ENABLE_NI_BIT) |
-+ (1UL << DMA_INT_ENABLE_AI_BIT) |
-+ (1UL << DMA_INT_ENABLE_FBE_BIT) |
-+ (1UL << DMA_INT_ENABLE_RI_BIT) |
-+ (1UL << DMA_INT_ENABLE_RU_BIT) |
-+ (1UL << DMA_INT_ENABLE_OV_BIT) |
-+ (1UL << DMA_INT_ENABLE_RW_BIT) |
-+ (1UL << DMA_INT_ENABLE_RS_BIT) |
-+ (1UL << DMA_INT_ENABLE_TI_BIT) |
-+ (1UL << DMA_INT_ENABLE_UN_BIT) |
-+ (1UL << DMA_INT_ENABLE_TJ_BIT) |
-+ (1UL << DMA_INT_ENABLE_TS_BIT)));
-+
-+ // (Re)start the link/PHY state monitoring timer
-+ start_watchdog_timer(priv);
-+
-+ // Allow the network stack to call hard_start_xmit()
-+ netif_start_queue(dev);
-+
-+#ifdef DUMP_REGS_ON_GMAC_UP
-+ dump_mac_regs(priv->macBase, priv->dmaBase);
-+#endif // DUMP_REGS_ON_GMAC_UP
-+
-+ return status;
-+
-+gmac_up_err_out:
-+ stop(dev);
-+
-+ return status;
-+}
-+
-+static void set_rx_packet_info(struct net_device *dev)
-+{
-+ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+ int max_packet_buffer_size = dev->mtu + EXTRA_RX_SKB_SPACE;
-+
-+ if (max_packet_buffer_size > max_descriptor_length()) {
-+#ifndef RX_BUFFER_SIZE
-+ priv->rx_buffer_size_ = max_packet_buffer_size;
-+#else // !RX_BUFFER_SIZE
-+ priv->rx_buffer_size_ = RX_BUFFER_SIZE;
-+#endif // ! RX_BUFFER_SIZE
-+ priv->rx_buffers_per_page = GMAC_ALLOC_SIZE / (priv->rx_buffer_size_ + NET_IP_ALIGN);
-+ } else {
-+ priv->rx_buffer_size_ = max_packet_buffer_size;
-+ priv->rx_buffers_per_page = 0;
-+ }
-+}
-+
-+static int change_mtu(struct net_device *dev, int new_mtu)
-+{
-+ int status = 0;
-+ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+ int original_mtu = dev->mtu;
-+
-+ // Check that new MTU is within supported range
-+ if ((new_mtu < MIN_PACKET_SIZE) || (new_mtu > MAX_JUMBO)) {
-+ DBG(1, KERN_WARNING "change_mtu() %s: Invalid MTU %d\n", dev->name, new_mtu);
-+ status = -EINVAL;
-+ } else {
-+ // Put MAC/PHY into quiesent state, causing all current buffers to be
-+ // deallocated and the PHY to powerdown
-+ gmac_down(dev);
-+
-+ // Record the new MTU, so bringing the MAC back up will allocate
-+ // resources to suit the new MTU
-+ dev->mtu = new_mtu;
-+
-+ // Set length etc. of rx packets
-+ set_rx_packet_info(dev);
-+
-+ // Reset the PHY to get it into a known state and ensure we have TX/RX
-+ // clocks to allow the GMAC reset to complete
-+ if (phy_reset(priv->netdev)) {
-+ DBG(1, KERN_ERR "change_mtu() %s: Failed to reset PHY\n", dev->name);
-+ status = -EIO;
-+ } else {
-+ // Set PHY specfic features
-+ initialise_phy(priv);
-+
-+ // Record whether jumbo frames should be enabled
-+ priv->jumbo_ = (dev->mtu > NORMAL_PACKET_SIZE);
-+
-+ // Force or auto-negotiate PHY mode
-+ priv->phy_force_negotiation = 1;
-+
-+ // Reallocate buffers with new MTU
-+ gmac_up(dev);
-+ }
-+ }
-+
-+ // If there was a failure
-+ if (status) {
-+ // Return the MTU to its original value
-+ DBG(1, KERN_INFO "change_mtu() Failed, returning MTU to original value\n");
-+ dev->mtu = original_mtu;
-+ }
-+
-+ return status;
-+}
-+
-+#ifdef TEST_COPRO
-+DECLARE_MUTEX_LOCKED(start_sem);
-+DECLARE_MUTEX_LOCKED(heartbeat_sem);
-+
-+void start_callback(volatile gmac_cmd_que_ent_t* entry)
-+{
-+ printk("START callback, operand = 0x%08x\n", entry->operand_);
-+ up(&start_sem);
-+}
-+
-+void heartbeat_callback(volatile gmac_cmd_que_ent_t* entry)
-+{
-+ printk("Heartbeat callback, operand = 0x%08x\n", entry->operand_);
-+ up(&heartbeat_sem);
-+}
-+
-+static void test_copro(gmac_priv_t* priv)
-+{
-+ unsigned long irq_flags;
-+
-+ spin_lock(&priv->cmd_que_lock_);
-+ cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_STOP, 0, 0);
-+ spin_unlock(&priv->cmd_que_lock_);
-+ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+ mdelay(500);
-+
-+ spin_lock(&priv->cmd_que_lock_);
-+ cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_START, 0, start_callback);
-+ spin_unlock(&priv->cmd_que_lock_);
-+ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+ mdelay(500);
-+
-+ spin_lock(&priv->cmd_que_lock_);
-+ cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_HEARTBEAT, 0, heartbeat_callback);
-+ spin_unlock(&priv->cmd_que_lock_);
-+ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+ mdelay(500);
-+
-+ printk("Waiting for start ack...\n");
-+ down_interruptible(&start_sem);
-+ printk("Start ack received\n");
-+
-+ printk("Waiting for heartbeat ack...\n");
-+ down_interruptible(&heartbeat_sem);
-+ printk("Heartbeat ack received\n");
-+}
-+#endif // TEST_COPRO
-+
-+#ifdef CONFIG_LEON_COPRO
-+#define SEM_INT_FWD 8
-+#define SEM_INT_ACK 16
-+#define SEM_INT_TX 17
-+#define SEM_INT_STOP_ACK 18
-+
-+#define SEM_INTA_MASK (1UL << SEM_INT_FWD)
-+#define SEM_INTB_MASK ((1UL << SEM_INT_ACK) | (1UL << SEM_INT_TX) | (1UL << SEM_INT_STOP_ACK))
-+
-+static irqreturn_t copro_sema_intr(int irq, void *dev_id)
-+{
-+ struct net_device *dev = (struct net_device *)dev_id;
-+ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+ u32 asserted;
-+ u32 fwd_intrs_status = 0;
-+ int is_fwd_intr;
-+
-+ // Read the contents of semaphore A register
-+ asserted = (*((volatile unsigned long*)SYS_CTRL_SEMA_STAT) & SEM_INTA_MASK);
-+
-+ while (asserted) {
-+ // Extract any forwarded interrupts info
-+ is_fwd_intr = asserted & (1UL << SEM_INT_FWD);
-+ if (is_fwd_intr) {
-+ fwd_intrs_status = ((volatile gmac_fwd_intrs_t*)descriptors_phys_to_virt(priv->copro_params_.fwd_intrs_mailbox_))->status_;
-+ }
-+
-+ // Clear any interrupts directed at the ARM
-+ *((volatile unsigned long*)SYS_CTRL_SEMA_CLR_CTRL) = asserted;
-+
-+ if (is_fwd_intr) {
-+ // Process any forwarded GMAC interrupts
-+ copro_fwd_intrs_handler(dev_id, fwd_intrs_status);
-+ }
-+
-+ // Stay in interrupt routine if interrupt has been re-asserted
-+ asserted = (*((volatile unsigned long*)SYS_CTRL_SEMA_STAT) & SEM_INTA_MASK);
-+ }
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t copro_semb_intr(int irq, void *dev_id)
-+{
-+ struct net_device *dev = (struct net_device *)dev_id;
-+ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+ u32 asserted;
-+
-+ // Read the contents of semaphore B register
-+ asserted = (*((volatile unsigned long*)SYS_CTRL_SEMA_STAT) & SEM_INTB_MASK);
-+
-+ while (asserted) {
-+ // Clear any interrupts directed at the ARM
-+ *((volatile unsigned long*)SYS_CTRL_SEMA_CLR_CTRL) = asserted;
-+
-+ // Process any outstanding command acknowledgements
-+ if (asserted & (1UL << SEM_INT_ACK)) {
-+ while (!cmd_que_dequeue_ack(&priv->cmd_queue_));
-+ }
-+
-+ // Process STOP completion signal
-+ if (asserted & (1UL << SEM_INT_STOP_ACK)) {
-+ up(&priv->copro_stop_complete_semaphore_);
-+ }
-+
-+#ifdef CONFIG_LEON_OFFLOAD_TX
-+ // Process any completed TX offload jobs
-+ if (asserted & (1UL << SEM_INT_TX)) {
-+ finish_xmit(dev);
-+ }
-+#endif // CONFIG_LEON_OFFLOAD_TX
-+
-+ // Stay in interrupt routine if interrupt has been re-asserted
-+ asserted = (*((volatile unsigned long*)SYS_CTRL_SEMA_STAT) & SEM_INTB_MASK);
-+ }
-+
-+ return IRQ_HANDLED;
-+}
-+#endif // CONFIG_LEON_COPRO
-+
-+static int open(struct net_device *dev)
-+{
-+ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+ int status;
-+
-+ // Ensure the MAC block is properly reset
-+ writel(1UL << SYS_CTRL_RSTEN_MAC_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+ writel(1UL << SYS_CTRL_RSTEN_MAC_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+
-+ // Enable the clock to the MAC block
-+ writel(1UL << SYS_CTRL_CKEN_MAC_BIT, SYS_CTRL_CKEN_SET_CTRL);
-+
-+ // Ensure reset and clock operations are complete
-+ wmb();
-+
-+ // Reset the PHY to get it into a known state and ensure we have TX/RX clocks
-+ // to allow the GMAC reset to complete
-+ if (phy_reset(priv->netdev)) {
-+ DBG(1, KERN_ERR "open() %s: Failed to reset PHY\n", dev->name);
-+ status = -EIO;
-+ goto open_err_out;
-+ }
-+
-+ // Set PHY specfic features
-+ initialise_phy(priv);
-+
-+ // Check that the MAC address is valid. If it's not, refuse to bring the
-+ // device up
-+ if (!is_valid_ether_addr(dev->dev_addr)) {
-+ DBG(1, KERN_ERR "open() %s: MAC address invalid\n", dev->name);
-+ status = -EINVAL;
-+ goto open_err_out;
-+ }
-+
-+#ifdef CONFIG_LEON_COPRO
-+ // Register ISRs for the semaphore register interrupt sources, which will
-+ // originate from the CoPro
-+ if (request_irq(priv->copro_a_irq_, &copro_sema_intr, 0, "SEMA", dev)) {
-+ panic("open: Failed to allocate semaphore A %u\n", priv->copro_a_irq_);
-+ status = -ENODEV;
-+ goto open_err_out;
-+ }
-+ priv->copro_a_irq_alloced_ = 1;
-+
-+ if (request_irq(priv->copro_b_irq_, &copro_semb_intr, 0, "SEMB", dev)) {
-+ panic("open: Failed to allocate semaphore B %u\n", priv->copro_b_irq_);
-+ status = -ENODEV;
-+ goto open_err_out;
-+ }
-+ priv->copro_b_irq_alloced_ = 1;
-+#else // CONFIG_LEON_COPRO
-+ // Allocate the IRQ
-+ if (request_irq(dev->irq, &int_handler, 0, dev->name, dev)) {
-+ DBG(1, KERN_ERR "open() %s: Failed to allocate irq %d\n", dev->name, dev->irq);
-+ status = -ENODEV;
-+ goto open_err_out;
-+ }
-+ priv->have_irq = 1;
-+#endif // CONFIG_LEON_COPRO
-+
-+ // Need a consistent DMA mapping covering all the memory occupied by DMA
-+ // unified descriptor array, as both CPU and DMA engine will be reading and
-+ // writing descriptor fields.
-+ priv->desc_vaddr = (gmac_dma_desc_t*)GMAC_DESC_ALLOC_START;
-+ priv->desc_dma_addr = GMAC_DESC_ALLOC_START_PA;
-+
-+ if (!priv->desc_vaddr) {
-+ DBG(1, KERN_ERR "open() %s: Failed to allocate consistent memory for DMA descriptors\n", dev->name);
-+ status = -ENOMEM;
-+ goto open_err_out;
-+ }
-+
-+ // Allocate memory to hold shadow of GMAC descriptors
-+ if (!(priv->tx_desc_shadow_ = kmalloc(NUM_TX_DMA_DESCRIPTORS * sizeof(gmac_dma_desc_t), GFP_KERNEL))) {
-+ DBG(1, KERN_ERR "open() %s: Failed to allocate memory for Tx descriptor shadows\n", dev->name);
-+ status = -ENOMEM;
-+ goto open_err_out;
-+ }
-+ if (!(priv->rx_desc_shadow_ = kmalloc(NUM_RX_DMA_DESCRIPTORS * sizeof(gmac_dma_desc_t), GFP_KERNEL))) {
-+ DBG(1, KERN_ERR "open() %s: Failed to allocate memory for Rx descriptor shadows\n", dev->name);
-+ status = -ENOMEM;
-+ goto open_err_out;
-+ }
-+
-+ // Record whether jumbo frames should be enabled
-+ priv->jumbo_ = (dev->mtu > NORMAL_PACKET_SIZE);
-+
-+ set_rx_packet_info(dev);
-+
-+#ifdef CONFIG_LEON_COPRO
-+ // Allocate SRAM for the command queue entries
-+ priv->copro_params_.cmd_que_head_ = DESCRIPTORS_BASE_PA + DESCRIPTORS_SIZE;
-+
-+ priv->copro_params_.cmd_que_tail_ =
-+ (u32)((gmac_cmd_que_ent_t*)(priv->copro_params_.cmd_que_head_) + priv->copro_cmd_que_num_entries_);
-+ priv->copro_params_.fwd_intrs_mailbox_ = priv->copro_params_.cmd_que_tail_;
-+ priv->copro_params_.tx_que_head_ = priv->copro_params_.fwd_intrs_mailbox_ + sizeof(gmac_fwd_intrs_t);
-+ priv->copro_params_.tx_que_tail_ =
-+ (u32)((gmac_tx_que_ent_t*)(priv->copro_params_.tx_que_head_) + priv->copro_tx_que_num_entries_);
-+ priv->copro_params_.free_start_ = priv->copro_params_.tx_que_tail_;
-+
-+ // Set RX interrupt mitigation behaviour
-+ priv->copro_params_.rx_mitigation_ = COPRO_RX_MITIGATION;
-+ priv->copro_params_.rx_mitigation_frames_ = COPRO_RX_MITIGATION_FRAMES;
-+ priv->copro_params_.rx_mitigation_usec_ = COPRO_RX_MITIGATION_USECS;
-+
-+ // Initialise command queue metadata
-+ cmd_que_init(
-+ &priv->cmd_queue_,
-+ (gmac_cmd_que_ent_t*)descriptors_phys_to_virt(priv->copro_params_.cmd_que_head_),
-+ priv->copro_cmd_que_num_entries_);
-+
-+ // Initialise tx offload queue metadata
-+ tx_que_init(
-+ &priv->tx_queue_,
-+ (gmac_tx_que_ent_t*)descriptors_phys_to_virt(priv->copro_params_.tx_que_head_),
-+ priv->copro_tx_que_num_entries_);
-+
-+ // Allocate DMA coherent space for the parameter block shared with the CoPro
-+ priv->shared_copro_params_ = dma_alloc_coherent(0, sizeof(copro_params_t), &priv->shared_copro_params_pa_, GFP_KERNEL);
-+ if (!priv->shared_copro_params_) {
-+ DBG(1, KERN_ERR "open() %s: Failed to allocate DMA coherent space for parameters\n");
-+ status = -ENOMEM;
-+ goto open_err_out;
-+ }
-+
-+ // Update the CoPro's parameters with the current MTU
-+ priv->copro_params_.mtu_ = dev->mtu;
-+
-+ // Fill the shared CoPro parameter block from the ARM's local copy
-+ memcpy(priv->shared_copro_params_, &priv->copro_params_, sizeof(copro_params_t));
-+
-+ // Load CoPro program and start it running
-+ init_copro(leon_srec, priv->shared_copro_params_pa_);
-+
-+ // Enable selected semaphore register bits to cause ARM interrupts
-+ *((volatile unsigned long*)SYS_CTRL_SEMA_MASKA_CTRL) = SEM_INTA_MASK;
-+ *((volatile unsigned long*)SYS_CTRL_SEMA_MASKB_CTRL) = SEM_INTB_MASK;
-+
-+#ifdef TEST_COPRO
-+ // Send test commands to the CoPro
-+ test_copro(priv);
-+#endif // TEST_COPRO
-+#endif // CONFIG_LEON_COPRO
-+
-+ // Do startup operations that are in common with gmac_down()/_up() processing
-+ priv->mii_init_media = 1;
-+ priv->phy_force_negotiation = 1;
-+ status = gmac_up(dev);
-+ if (status) {
-+ goto open_err_out;
-+ }
-+
-+ return 0;
-+
-+open_err_out:
-+ stop(dev);
-+
-+ return status;
-+}
-+
-+#if defined(CONFIG_LEON_COPRO) && defined(CONFIG_LEON_OFFLOAD_TX)
-+static int hard_start_xmit(
-+ struct sk_buff *skb,
-+ struct net_device *dev)
-+{
-+ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+ volatile gmac_tx_que_ent_t *job;
-+ unsigned long irq_flags;
-+
-+ if (skb_shinfo(skb)->frag_list) {
-+ panic("Frag list - can't handle this!\n");
-+ }
-+
-+ // Protection against concurrent operations in ISR and hard_start_xmit()
-+ if (!spin_trylock_irqsave(&priv->tx_spinlock_, irq_flags)) {
-+ return NETDEV_TX_LOCKED;
-+ }
-+
-+ // NETIF_F_LLTX apparently introduces a potential for hard_start_xmit() to
-+ // be called when the queue has been stopped (although I think only in SMP)
-+ // so do a check here to make sure we should proceed
-+ if (netif_queue_stopped(dev)) {
-+ spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
-+ return NETDEV_TX_BUSY;
-+ }
-+
-+ job = tx_que_get_idle_job(dev);
-+ if (!job) {
-+ // Tx offload queue is full, so add skb to pending skb list
-+ list_add_tail((struct list_head*)&skb->cb, &priv->copro_tx_skb_list_);
-+
-+ // Keep track of how many entries are in the pending SKB list
-+ ++priv->copro_tx_skb_list_count_;
-+
-+ // Have we queued the max allowed number of SKBs?
-+ if (priv->copro_tx_skb_list_count_ >= COPRO_MAX_QUEUED_TX_SKBS) {
-+ // Stop further calls to hard_start_xmit() until some descriptors
-+ // are freed up by already queued TX packets being completed
-+ netif_stop_queue(dev);
-+ }
-+ } else {
-+ if (priv->copro_tx_skb_list_count_) {
-+ // Have queued pending SKBs, so add new SKB to tail of pending list
-+ list_add_tail((struct list_head*)&skb->cb, &priv->copro_tx_skb_list_);
-+
-+ // Keep track of how many entries are in the pending SKB list
-+ ++priv->copro_tx_skb_list_count_;
-+
-+ // Process pending SKBs, oldest first
-+ copro_process_pending_tx_skbs(dev, job);
-+ } else {
-+ // Fill the Tx offload job with the network packet's details
-+ copro_fill_tx_job(job, skb);
-+
-+ // Enqueue the new Tx offload job with the CoPro
-+ tx_que_new_job(dev, job);
-+ }
-+
-+ // Record start of transmission, so timeouts will work once they're
-+ // implemented
-+ dev->trans_start = jiffies;
-+
-+ // Interrupt the CoPro to cause it to examine the Tx offload queue
-+ wmb();
-+ writel(1UL << COPRO_SEM_INT_TX, SYS_CTRL_SEMA_SET_CTRL);
-+
-+ // If the network stack's Tx queue was stopped and we now have resources
-+ // to process more Tx offload jobs
-+ if (netif_queue_stopped(dev) &&
-+ !tx_que_is_full(&priv->tx_queue_) &&
-+ !priv->copro_tx_skb_list_count_) {
-+ // Restart the network stack's TX queue
-+ netif_wake_queue(dev);
-+ }
-+ }
-+
-+ spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
-+
-+ return NETDEV_TX_OK;
-+}
-+#else
-+static inline void unmap_fragments(
-+ tx_frag_info_t *frags,
-+ int count)
-+{
-+ while (count--) {
-+ dma_unmap_single(0, frags->phys_adr, frags->length, DMA_TO_DEVICE);
-+ ++frags;
-+ }
-+}
-+
-+static int hard_start_xmit(
-+ struct sk_buff *skb,
-+ struct net_device *dev)
-+{
-+ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+ unsigned long irq_flags;
-+ struct skb_shared_info *shinfo = skb_shinfo(skb);
-+ int fragment_count = shinfo->nr_frags + 1;
-+ tx_frag_info_t fragments[fragment_count];
-+ int frag_index;
-+
-+ // Get consistent DMA mappings for the SDRAM to be DMAed from by the GMAC,
-+ // causing a flush from the CPU's cache to the memory.
-+
-+ // Do the DMA mappings before acquiring the tx lock, even though it complicates
-+ // the later code, as this can be a long operation involving cache flushing
-+
-+ // Map the main buffer
-+ fragments[0].length = skb_headlen(skb);
-+ fragments[0].phys_adr = dma_map_single(0, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
-+ BUG_ON(dma_mapping_error(fragments[0].phys_adr));
-+
-+ // Map any SG fragments
-+ for (frag_index = 0; frag_index < shinfo->nr_frags; ++frag_index) {
-+ skb_frag_t *frag = &shinfo->frags[frag_index];
-+
-+ fragments[frag_index + 1].length = frag->size;
-+ fragments[frag_index + 1].phys_adr = dma_map_page(0, frag->page, frag->page_offset, frag->size, DMA_TO_DEVICE);
-+ BUG_ON(dma_mapping_error(fragments[frag_index + 1].phys_adr));
-+ }
-+
-+ // Protection against concurrent operations in ISR and hard_start_xmit()
-+ if (unlikely(!spin_trylock_irqsave(&priv->tx_spinlock_, irq_flags))) {
-+ unmap_fragments(fragments, fragment_count);
-+ return NETDEV_TX_LOCKED;
-+ }
-+
-+ // NETIF_F_LLTX apparently introduces a potential for hard_start_xmit() to
-+ // be called when the queue has been stopped (although I think only in SMP)
-+ // so do a check here to make sure we should proceed
-+ if (unlikely(netif_queue_stopped(dev))) {
-+ unmap_fragments(fragments, fragment_count);
-+ spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
-+ return NETDEV_TX_BUSY;
-+ }
-+
-+ // Construct the GMAC DMA descriptor
-+ if (unlikely(set_tx_descriptor(priv,
-+ skb,
-+ fragments,
-+ fragment_count,
-+ skb->ip_summed == CHECKSUM_PARTIAL) < 0)) {
-+ // Shouldn't see a full ring without the queue having already been
-+ // stopped, and the queue should already have been stopped if we have
-+ // already queued a single pending packet
-+ if (priv->tx_pending_skb) {
-+ printk(KERN_WARNING "hard_start_xmit() Ring full and pending packet already queued\n");
-+ unmap_fragments(fragments, fragment_count);
-+ spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
-+ return NETDEV_TX_BUSY;
-+ }
-+
-+ // Should keep a record of the skb that we haven't been able to queue
-+ // for transmission and queue it as soon as a descriptor becomes free
-+ priv->tx_pending_skb = skb;
-+ priv->tx_pending_fragment_count = fragment_count;
-+
-+ // Copy the fragment info to the allocated storage
-+ memcpy(priv->tx_pending_fragments, fragments, sizeof(tx_frag_info_t) * fragment_count);
-+
-+ // Stop further calls to hard_start_xmit() until some descriptors are
-+ // freed up by already queued TX packets being completed
-+ netif_stop_queue(dev);
-+ } else {
-+ // Record start of transmission, so timeouts will work once they're
-+ // implemented
-+ dev->trans_start = jiffies;
-+
-+ // Poke the transmitter to look for available TX descriptors, as we have
-+ // just added one, in case it had previously found there were no more
-+ // pending transmission
-+ dma_reg_write(priv, DMA_TX_POLL_REG, 0);
-+ }
-+
-+ spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
-+
-+ return NETDEV_TX_OK;
-+}
-+#endif // CONFIG_LEON_COPRO && CONFIG_LEON_OFFLOAD_TX
-+
-+static struct net_device_stats *get_stats(struct net_device *dev)
-+{
-+ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+ return &priv->stats;
-+}
-+
-+#ifdef CONFIG_NET_POLL_CONTROLLER
-+/**
-+ * Polling 'interrupt' - used by things like netconsole to send skbs without
-+ * having to re-enable interrupts. It's not called while the interrupt routine
-+ * is executing.
-+ */
-+static void netpoll(struct net_device *netdev)
-+{
-+ disable_irq(netdev->irq);
-+ int_handler(netdev->irq, netdev, NULL);
-+ enable_irq(netdev->irq);
-+}
-+#endif // CONFIG_NET_POLL_CONTROLLER
-+
-+static int probe(
-+ struct net_device *netdev,
-+ u32 vaddr,
-+ u32 irq,
-+ int copro_a_irq,
-+ int copro_b_irq)
-+{
-+ int err = 0;
-+ u32 version;
-+ int i;
-+ unsigned synopsis_version;
-+ unsigned vendor_version;
-+ gmac_priv_t* priv = netdev_priv(netdev);
-+ u32 reg_contents;
-+
-+ // Ensure the MAC block is properly reset
-+ writel(1UL << SYS_CTRL_RSTEN_MAC_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+ writel(1UL << SYS_CTRL_RSTEN_MAC_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+
-+ // Enable the clock to the MAC block
-+ writel(1UL << SYS_CTRL_CKEN_MAC_BIT, SYS_CTRL_CKEN_SET_CTRL);
-+
-+ // Ensure reset and clock operations are complete
-+ wmb();
-+
-+ // Ensure all of the device private data are zero, so we can clean up in
-+ // the event of a later failure to initialise all fields
-+ priv = (gmac_priv_t*)netdev_priv(netdev);
-+ memset(priv, 0, sizeof(gmac_priv_t));
-+
-+ // No debug messages allowed
-+ priv->msg_level = 0UL;
-+
-+ // Initialise the ISR/hard_start_xmit() lock
-+ spin_lock_init(&priv->tx_spinlock_);
-+
-+ // Initialise the PHY access lock
-+ spin_lock_init(&priv->phy_lock);
-+
-+ // Set hardware device base addresses
-+ priv->macBase = vaddr + MAC_BASE_OFFSET;
-+ priv->dmaBase = vaddr + DMA_BASE_OFFSET;
-+
-+ // Initialise IRQ ownership to not owned
-+ priv->have_irq = 0;
-+
-+ // Lock protecting access to CoPro command queue functions or direct access
-+ // to the GMAC interrupt enable register if CoPro is not in use
-+ spin_lock_init(&priv->cmd_que_lock_);
-+
-+#ifdef CONFIG_LEON_COPRO
-+ sema_init(&copro_stop_semaphore, 0);
-+ sema_init(&copro_start_semaphore, 0);
-+ sema_init(&copro_int_clr_semaphore, 0);
-+ sema_init(&copro_update_semaphore, 0);
-+ sema_init(&copro_rx_enable_semaphore, 0);
-+ priv->copro_a_irq_alloced_ = 0;
-+ priv->copro_b_irq_alloced_ = 0;
-+ sema_init(&priv->copro_stop_complete_semaphore_, 0);
-+ INIT_LIST_HEAD(&priv->copro_tx_skb_list_);
-+ priv->copro_tx_skb_list_count_ = 0;
-+#endif // CONFIG_LEON_COPRO
-+
-+ init_timer(&priv->watchdog_timer);
-+ priv->watchdog_timer.function = &watchdog_timer_action;
-+ priv->watchdog_timer.data = (unsigned long)priv;
-+
-+ // Set pointer to device in private data
-+ priv->netdev = netdev;
-+
-+ /** Do something here to detect the present or otherwise of the MAC
-+ * Read the version register as a first test */
-+ version = mac_reg_read(priv, MAC_VERSION_REG);
-+ synopsis_version = version & 0xff;
-+ vendor_version = (version >> 8) & 0xff;
-+
-+ /** Assume device is at the adr and irq specified until have probing working */
-+ netdev->base_addr = vaddr;
-+ netdev->irq = irq;
-+#ifdef CONFIG_LEON_COPRO
-+ priv->copro_a_irq_ = copro_a_irq;
-+ priv->copro_b_irq_ = copro_b_irq;
-+#endif // CONFIG_LEON_COPRO
-+
-+#ifdef CONFIG_LEON_COPRO
-+ // Allocate the CoPro A IRQ
-+ err = request_irq(priv->copro_a_irq_, &copro_sema_intr, 0, "SEMA", netdev);
-+ if (err) {
-+ DBG(1, KERN_ERR "probe() %s: Failed to allocate CoPro irq A (%d)\n", netdev->name, priv->copro_a_irq_);
-+ goto probe_err_out;
-+ }
-+ // Release the CoPro A IRQ again, as open()/stop() should manage IRQ ownership
-+ free_irq(priv->copro_a_irq_, netdev);
-+
-+ // Allocate the CoPro B IRQ
-+ err = request_irq(priv->copro_b_irq_, &copro_semb_intr, 0, "SEMB", netdev);
-+ if (err) {
-+ DBG(1, KERN_ERR "probe() %s: Failed to allocate CoPro irq B (%d)\n", netdev->name, priv->copro_b_irq_);
-+ goto probe_err_out;
-+ }
-+ // Release the CoPro B IRQ again, as open()/stop() should manage IRQ ownership
-+ free_irq(priv->copro_b_irq_, netdev);
-+#else // CONFIG_LEON_COPRO
-+ // Allocate the IRQ
-+ err = request_irq(netdev->irq, &int_handler, 0, netdev->name, netdev);
-+ if (err) {
-+ DBG(1, KERN_ERR "probe() %s: Failed to allocate irq %d\n", netdev->name, netdev->irq);
-+ goto probe_err_out;
-+ }
-+
-+ // Release the IRQ again, as open()/stop() should manage IRQ ownership
-+ free_irq(netdev->irq, netdev);
-+#endif // CONFIG_LEON_COPRO
-+
-+ // Initialise the ethernet device with std. contents
-+ ether_setup(netdev);
-+
-+ // Tell the kernel of our MAC address
-+ for (i = 0; i < netdev->addr_len; i++) {
-+ netdev->dev_addr[i] = (unsigned char)mac_adr[i];
-+ }
-+
-+ // Setup operations pointers
-+ netdev->open = &open;
-+ netdev->hard_start_xmit = &hard_start_xmit;
-+ netdev->stop = &stop;
-+ netdev->get_stats = &get_stats;
-+ netdev->change_mtu = &change_mtu;
-+#ifdef CONFIG_NET_POLL_CONTROLLER
-+ netdev->poll_controller = &netpoll;
-+#endif // CONFIG_NET_POLL_CONTROLLER
-+ netdev->set_mac_address = &set_mac_address;
-+ netdev->set_multicast_list = &set_multicast_list;
-+
-+ // Initialise NAPI support
-+ netif_napi_add(netdev, &priv->napi_struct, &poll, NAPI_POLL_WEIGHT);
-+
-+ set_ethtool_ops(netdev);
-+
-+ if (debug) {
-+ netdev->flags |= IFF_DEBUG;
-+ }
-+
-+#if defined(CONFIG_LEON_COPRO) && defined(CONFIG_LEON_OFFLOAD_TSO)
-+ // Do TX H/W checksum and SG list processing
-+ netdev->features |= NETIF_F_HW_CSUM;
-+ netdev->features |= NETIF_F_SG;
-+
-+ // Do hardware TCP/IP Segmentation Offload
-+ netdev->features |= NETIF_F_TSO;
-+#elif !defined(CONFIG_LEON_COPRO) && !defined(CONFIG_OXNAS_VERSION_0X800)
-+ // Do TX H/W checksum and SG list processing
-+ netdev->features |= NETIF_F_HW_CSUM;
-+ netdev->features |= NETIF_F_SG;
-+#endif // USE_TX_CSUM
-+
-+ // We take care of our own TX locking
-+ netdev->features |= NETIF_F_LLTX;
-+
-+ // Initialise PHY support
-+ priv->mii.phy_id_mask = 0x1f;
-+ priv->mii.reg_num_mask = 0x1f;
-+ priv->mii.force_media = 0;
-+ priv->mii.full_duplex = 1;
-+ priv->mii.using_100 = 0;
-+ priv->mii.using_1000 = 1;
-+ priv->mii.using_pause = 1;
-+ priv->mii.dev = netdev;
-+ priv->mii.mdio_read = phy_read;
-+ priv->mii.mdio_write = phy_write;
-+
-+ priv->gmii_csr_clk_range = 5; // Slowest for now
-+
-+ // Use simple mux for 25/125 Mhz clock switching and
-+ // enable GMII_GTXCLK to follow GMII_REFCLK - required for gigabit PHY
-+ reg_contents = readl(SYS_CTRL_GMAC_CTRL);
-+ reg_contents |= ((1UL << SYS_CTRL_GMAC_SIMPLE_MAX) |
-+ (1UL << SYS_CTRL_GMAC_CKEN_GTX));
-+ writel(reg_contents, SYS_CTRL_GMAC_CTRL);
-+
-+ // Remember whether auto-negotiation is allowed
-+#ifdef ALLOW_AUTONEG
-+ priv->ethtool_cmd.autoneg = 1;
-+ priv->ethtool_pauseparam.autoneg = 1;
-+#else // ALLOW_AUTONEG
-+ priv->ethtool_cmd.autoneg = 0;
-+ priv->ethtool_pauseparam.autoneg = 0;
-+#endif // ALLOW_AUTONEG
-+
-+ // Set up PHY mode for when auto-negotiation is not allowed
-+ priv->ethtool_cmd.speed = SPEED_1000;
-+ priv->ethtool_cmd.duplex = DUPLEX_FULL;
-+ priv->ethtool_cmd.port = PORT_MII;
-+ priv->ethtool_cmd.transceiver = XCVR_INTERNAL;
-+
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+ // We can support both reception and generation of pause frames
-+ priv->ethtool_pauseparam.rx_pause = 1;
-+ priv->ethtool_pauseparam.tx_pause = 1;
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+
-+ // Initialise the set of features we would like to advertise as being
-+ // available for negotiation
-+ priv->ethtool_cmd.advertising = (ADVERTISED_10baseT_Half |
-+ ADVERTISED_10baseT_Full |
-+ ADVERTISED_100baseT_Half |
-+ ADVERTISED_100baseT_Full |
-+#if !defined(CONFIG_OXNAS_VERSION_0X800) || defined(ALLOW_OX800_1000M)
-+ ADVERTISED_1000baseT_Half |
-+ ADVERTISED_1000baseT_Full |
-+ ADVERTISED_Pause |
-+ ADVERTISED_Asym_Pause |
-+#endif
-+ ADVERTISED_Autoneg |
-+ ADVERTISED_MII);
-+
-+ // Attempt to locate the PHY
-+ phy_detect(netdev);
-+ priv->ethtool_cmd.phy_address = priv->mii.phy_id;
-+
-+ // Did we find a PHY?
-+ if (priv->phy_type == PHY_TYPE_NONE) {
-+ printk(KERN_WARNING "%s: No PHY found\n", netdev->name);
-+ err = ENXIO;
-+ goto probe_err_out;
-+ }
-+
-+ // Setup the PHY
-+ initialise_phy(priv);
-+
-+ // Find out what modes the PHY supports
-+ priv->ethtool_cmd.supported = get_phy_capabilies(priv);
-+#if defined(CONFIG_OXNAS_VERSION_0X800) && !defined(ALLOW_OX800_1000M)
-+ // OX800 has broken 1000M support in the MAC
-+ priv->ethtool_cmd.supported &= ~(SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half);
-+#endif
-+
-+ // Register the device with the network intrastructure
-+ err = register_netdev(netdev);
-+ if (err) {
-+ DBG(1, KERN_ERR "probe() %s: Failed to register device\n", netdev->name);
-+ goto probe_err_out;
-+ }
-+
-+ // Record details about the hardware we found
-+ printk(KERN_NOTICE "%s: GMAC ver = %u, vendor ver = %u at 0x%lx, IRQ %d\n", netdev->name, synopsis_version, vendor_version, netdev->base_addr, netdev->irq);
-+#ifndef ARMULATING
-+ printk(KERN_NOTICE "%s: Found PHY at address %u, type 0x%08x -> %s\n", priv->netdev->name, priv->phy_addr, priv->phy_type, (priv->ethtool_cmd.supported & SUPPORTED_1000baseT_Full) ? "10/100/1000" : "10/100");
-+#endif // !ARMULATING
-+ printk(KERN_NOTICE "%s: Ethernet addr: ", priv->netdev->name);
-+ for (i = 0; i < 5; i++) {
-+ printk("%02x:", netdev->dev_addr[i]);
-+ }
-+ printk("%02x\n", netdev->dev_addr[5]);
-+
-+#ifdef CONFIG_LEON_COPRO
-+ // Define sizes of queues for communicating with the CoPro
-+ priv->copro_cmd_que_num_entries_ = COPRO_CMD_QUEUE_NUM_ENTRIES;
-+ priv->copro_tx_que_num_entries_ = COPRO_TX_QUEUE_NUM_ENTRIES;
-+#endif // CONFIG_LEON_COPRO
-+
-+ // Initialise sysfs for link state reporting
-+ err = gmac_link_state_init_sysfs(priv);
-+ if (err) {
-+ DBG(1, KERN_ERR "probe() %s: Failed to initialise sysfs support\n", netdev->name);
-+ goto probe_err_out;
-+ }
-+
-+ // Initialise the work queue entry to be used to issue hotplug events to userspace
-+ INIT_WORK(&priv->link_state_change_work, work_handler);
-+
-+ return 0;
-+
-+probe_err_out:
-+#ifdef CONFIG_LEON_COPRO
-+ shutdown_copro();
-+
-+ if (priv->shared_copro_params_) {
-+ // Free the DMA coherent parameter space
-+ dma_free_coherent(0, sizeof(copro_params_t), priv->shared_copro_params_, priv->shared_copro_params_pa_);
-+ priv->shared_copro_params_ = 0;
-+ }
-+#endif // CONFIG_LEON_COPRO
-+
-+ // Disable the clock to the MAC block
-+ writel(1UL << SYS_CTRL_CKEN_MAC_BIT, SYS_CTRL_CKEN_CLR_CTRL);
-+
-+ return err;
-+}
-+
-+static int gmac_found_count = 0;
-+static struct net_device* gmac_netdev[MAX_GMAC_UNITS];
-+
-+/**
-+ * External entry point to the driver, called from Space.c to detect a card
-+ */
-+struct net_device* __init synopsys_gmac_probe(int unit)
-+{
-+ int err = 0;
-+ struct net_device *netdev = alloc_etherdev(sizeof(gmac_priv_t));
-+
-+ printk(KERN_NOTICE "Probing for Synopsis GMAC, unit %d\n", unit);
-+
-+ // Will allocate private data later, as may want descriptors etc in special memory
-+ if (!netdev) {
-+ printk(KERN_WARNING "synopsys_gmac_probe() failed to alloc device\n");
-+ err = -ENODEV;
-+ } else {
-+ if (unit >= 0) {
-+ sprintf(netdev->name, "eth%d", unit);
-+
-+ netdev_boot_setup_check(netdev);
-+
-+ if (gmac_found_count >= MAX_GMAC_UNITS) {
-+ err = -ENODEV;
-+ } else {
-+ err = probe(netdev, MAC_BASE, MAC_INTERRUPT, SEM_A_INTERRUPT, SEM_B_INTERRUPT);
-+ if (err) {
-+ printk(KERN_WARNING "synopsys_gmac_probe() Probing failed for %s\n", netdev->name);
-+ } else {
-+ ++gmac_found_count;
-+ }
-+ }
-+ }
-+
-+ if (err) {
-+ netdev->reg_state = NETREG_UNREGISTERED;
-+ free_netdev(netdev);
-+ } else {
-+ gmac_netdev[unit] = netdev;
-+ }
-+ }
-+
-+ return ERR_PTR(err);
-+}
-+
-+static int __init gmac_module_init(void)
-+{
-+ return (int)synopsys_gmac_probe(0);
-+}
-+module_init(gmac_module_init);
-+
-+static void __exit gmac_module_cleanup(void)
-+{
-+ int i;
-+ for (i=0; i < gmac_found_count; i++) {
-+ stop(gmac_netdev[i]);
-+ gmac_netdev[i]->reg_state = NETREG_UNREGISTERED;
-+ free_netdev(gmac_netdev[i]);
-+ }
-+}
-+module_exit(gmac_module_cleanup);
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac.h
---- linux-2.6.24/arch/arm/mach-oxnas/gmac.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac.h 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,194 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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
-+ */
-+#if !defined(__GMAC_H__)
-+#define __GMAC_H__
-+
-+#include <asm/semaphore.h>
-+#include <asm/types.h>
-+#include <linux/mii.h>
-+#include <linux/netdevice.h>
-+#include <linux/spinlock.h>
-+#include <linux/workqueue.h>
-+#include <linux/list.h>
-+#include <linux/ethtool.h>
-+#include <linux/kobject.h>
-+#include <asm/arch/desc_alloc.h>
-+#include <asm/arch/dma.h>
-+#ifdef CONFIG_LEON_COPRO
-+#include <asm/arch/leon.h>
-+#include "gmac_offload.h"
-+#endif // CONFIG_LEON_COPRO
-+
-+#ifdef GMAC_DEBUG
-+#define DBG(n, args...)\
-+ do {\
-+ if ((n) <= priv->msg_level)\
-+ printk(args);\
-+ } while (0)
-+#else
-+#define DBG(n, args...) do { } while(0)
-+#endif
-+
-+#define MS_TO_JIFFIES(x) (((x) < (1000/(HZ))) ? 1 : (x) * (HZ) / 1000)
-+
-+#define USE_RX_CSUM
-+//#define ARMULATING
-+
-+typedef struct gmac_desc_list_info {
-+ volatile gmac_dma_desc_t *base_ptr;
-+ gmac_dma_desc_t *shadow_ptr;
-+ int num_descriptors;
-+ int empty_count;
-+ int full_count;
-+ int r_index;
-+ int w_index;
-+} gmac_desc_list_info_t;
-+
-+#ifdef CONFIG_LEON_COPRO
-+typedef struct copro_params {
-+ u32 cmd_que_head_;
-+ u32 cmd_que_tail_;
-+ u32 fwd_intrs_mailbox_;
-+ u32 tx_que_head_;
-+ u32 tx_que_tail_;
-+ u32 free_start_;
-+ u32 mtu_;
-+ u32 rx_mitigation_;
-+ u32 rx_mitigation_frames_;
-+ u32 rx_mitigation_usec_;
-+} __attribute ((aligned(4),packed)) copro_params_t;
-+#endif // CONFIG_LEON_COPRO
-+
-+typedef struct tx_frag_info {
-+ dma_addr_t phys_adr;
-+ u16 length;
-+} tx_frag_info_t;
-+
-+// Private data structure for the GMAC driver
-+typedef struct gmac_priv {
-+ /** Base address of GMAC MAC registers */
-+ u32 macBase;
-+ /** Base address of GMAC DMA registers */
-+ u32 dmaBase;
-+
-+ struct net_device* netdev;
-+
-+ struct net_device_stats stats;
-+
-+ u32 msg_level;
-+
-+ /** Whether we own an IRQ */
-+ int have_irq;
-+
-+ /** Pointer to outstanding tx packet that has not yet been queued due to
-+ * lack of descriptors */
-+ struct sk_buff *tx_pending_skb;
-+ tx_frag_info_t tx_pending_fragments[18];
-+ int tx_pending_fragment_count;
-+
-+ /** DMA consistent physical address of outstanding tx packet */
-+ dma_addr_t tx_pending_dma_addr;
-+ unsigned long tx_pending_length;
-+
-+ /** To synchronise ISR and thread TX activities' access to private data */
-+ spinlock_t tx_spinlock_;
-+
-+ /** To synchronise access to the PHY */
-+ spinlock_t phy_lock;
-+
-+ /** The timer for NAPI polling when out of memory when trying to fill RX
-+ * descriptor ring */
-+
-+ /** PHY related info */
-+ struct mii_if_info mii;
-+ struct ethtool_cmd ethtool_cmd;
-+ struct ethtool_pauseparam ethtool_pauseparam;
-+ u32 phy_addr;
-+ u32 phy_type;
-+ int gmii_csr_clk_range;
-+
-+ /** Periodic timer to check link status etc */
-+ struct timer_list watchdog_timer;
-+ volatile int watchdog_timer_shutdown;
-+
-+ /** The number of descriptors in the gmac_dma_desc_t array holding both the TX and
-+ * RX descriptors. The TX descriptors reside at the start of the array */
-+ unsigned total_num_descriptors;
-+ /** The CPU accessible virtual address of the start of the descriptor array */
-+ gmac_dma_desc_t* desc_vaddr;
-+ /** The hardware accessible physical address of the start of the descriptor array */
-+ dma_addr_t desc_dma_addr;
-+
-+ /** Descriptor list management */
-+ gmac_desc_list_info_t tx_gmac_desc_list_info;
-+ gmac_desc_list_info_t rx_gmac_desc_list_info;
-+
-+ /** Record of disabling RX overflow interrupts */
-+ unsigned rx_overflow_ints_disabled;
-+
-+ /** The result of the last H/W DMA generated checksum operation */
-+ u16 tx_csum_result_;
-+
-+ /** Whether we deal in jumbo frames */
-+ int jumbo_;
-+
-+ volatile int mii_init_media;
-+ volatile int phy_force_negotiation;
-+
-+#ifdef CONFIG_LEON_COPRO
-+ /** DMA coherent memory for CoPro's parameter storage */
-+ copro_params_t *shared_copro_params_;
-+ dma_addr_t shared_copro_params_pa_;
-+
-+ /** ARM's local CoPro parameter storage */
-+ copro_params_t copro_params_;
-+
-+ /** Queue for commands/acks to/from CoPro */
-+ int copro_a_irq_;
-+ int copro_a_irq_alloced_;
-+ int copro_b_irq_;
-+ int copro_b_irq_alloced_;
-+ cmd_que_t cmd_queue_;
-+ tx_que_t tx_queue_;
-+ int copro_cmd_que_num_entries_;
-+ int copro_tx_que_num_entries_;
-+ struct semaphore copro_stop_complete_semaphore_;
-+ struct list_head copro_tx_skb_list_;
-+ int copro_tx_skb_list_count_;
-+#endif // CONFIG_LEON_COPRO
-+
-+ spinlock_t cmd_que_lock_;
-+ u32 rx_buffer_size_;
-+ int rx_buffers_per_page;
-+
-+ gmac_dma_desc_t *tx_desc_shadow_;
-+ gmac_dma_desc_t *rx_desc_shadow_;
-+
-+ struct napi_struct napi_struct;
-+
-+ /** sysfs dir tree root for recovery button driver */
-+ struct kset link_state_kset;
-+ struct kobject link_state_kobject;
-+ struct work_struct link_state_change_work;
-+ int link_state;
-+} gmac_priv_t;
-+
-+#endif // #if !defined(__GMAC_H__)
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_desc.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_desc.c
---- linux-2.6.24/arch/arm/mach-oxnas/gmac_desc.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_desc.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,452 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac_desc.c
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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 <linux/delay.h>
-+
-+//#define GMAC_DEBUG
-+#undef GMAC_DEBUG
-+
-+#include "gmac.h"
-+#include "gmac_desc.h"
-+
-+void init_rx_desc_list(
-+ gmac_desc_list_info_t *desc_list,
-+ volatile gmac_dma_desc_t *base_ptr,
-+ gmac_dma_desc_t *shadow_ptr,
-+ int num_descriptors,
-+ u16 rx_buffer_length)
-+{
-+ int i;
-+
-+ desc_list->base_ptr = base_ptr;
-+ desc_list->shadow_ptr = shadow_ptr;
-+ desc_list->num_descriptors = num_descriptors;
-+ desc_list->empty_count = num_descriptors;
-+ desc_list->full_count = 0;
-+ desc_list->r_index = 0;
-+ desc_list->w_index = 0;
-+
-+ for (i=0; i < num_descriptors; ++i) {
-+ gmac_dma_desc_t *shadow = shadow_ptr + i;
-+ volatile gmac_dma_desc_t *desc = base_ptr + i;
-+
-+ // Initialise the shadow descriptor
-+ shadow->status = 0;
-+ shadow->length = (rx_buffer_length << RDES1_RBS1_BIT);
-+ if (i == (num_descriptors - 1)) {
-+ shadow->length |= (1UL << RDES1_RER_BIT);
-+ }
-+ shadow->buffer1 = 0;
-+ shadow->buffer2 = 0;
-+
-+ // Copy the shadow descriptor into the real descriptor
-+ desc->status = shadow->status;
-+ desc->length = shadow->length;
-+ desc->buffer1 = shadow->buffer1;
-+ desc->buffer2 = shadow->buffer2;
-+ }
-+}
-+
-+void init_tx_desc_list(
-+ gmac_desc_list_info_t *desc_list,
-+ volatile gmac_dma_desc_t *base_ptr,
-+ gmac_dma_desc_t *shadow_ptr,
-+ int num_descriptors)
-+{
-+ int i;
-+
-+ desc_list->base_ptr = base_ptr;
-+ desc_list->shadow_ptr = shadow_ptr;
-+ desc_list->num_descriptors = num_descriptors;
-+ desc_list->empty_count = num_descriptors;
-+ desc_list->full_count = 0;
-+ desc_list->r_index = 0;
-+ desc_list->w_index = 0;
-+
-+ for (i=0; i < num_descriptors; ++i) {
-+ gmac_dma_desc_t *shadow = shadow_ptr + i;
-+ volatile gmac_dma_desc_t *desc = base_ptr + i;
-+
-+ // Initialise the shadow descriptor
-+ shadow->status = 0;
-+ shadow->length = (1UL << TDES1_IC_BIT);
-+ if (i == (num_descriptors - 1)) {
-+ shadow->length |= (1UL << TDES1_TER_BIT);
-+ }
-+ shadow->buffer1 = 0;
-+ shadow->buffer2 = 0;
-+
-+ // Copy the shadow descriptor into the real descriptor
-+ desc->status = shadow->status;
-+ desc->length = shadow->length;
-+ desc->buffer1 = shadow->buffer1;
-+ desc->buffer2 = shadow->buffer2;
-+ }
-+}
-+
-+void rx_take_ownership(gmac_desc_list_info_t* desc_list)
-+{
-+ int i;
-+ for (i=0; i < desc_list->num_descriptors; ++i) {
-+ (desc_list->base_ptr + i)->status &= ~(1UL << RDES0_OWN_BIT);
-+ }
-+
-+ // Ensure all write to the descriptor shared with MAC have completed
-+ wmb();
-+}
-+
-+void tx_take_ownership(gmac_desc_list_info_t* desc_list)
-+{
-+ int i;
-+ for (i=0; i < desc_list->num_descriptors; ++i) {
-+ (desc_list->base_ptr + i)->status &= ~(1UL << TDES0_OWN_BIT);
-+ }
-+
-+ // Ensure all write to the descriptor shared with MAC have completed
-+ wmb();
-+}
-+
-+int set_rx_descriptor(
-+ gmac_priv_t *priv,
-+ rx_frag_info_t *frag_info)
-+{
-+ int index = -1;
-+
-+ // Is there a Rx descriptor available for writing by the CPU?
-+ if (available_for_write(&priv->rx_gmac_desc_list_info)) {
-+ // Setup the descriptor required to describe the RX packet
-+ volatile gmac_dma_desc_t *descriptor;
-+ gmac_dma_desc_t *shadow;
-+
-+ // Get the index of the next RX descriptor available for writing by the CPU
-+ index = priv->rx_gmac_desc_list_info.w_index;
-+
-+ // Get a pointer to the next RX descriptor available for writing by the CPU
-+ descriptor = priv->rx_gmac_desc_list_info.base_ptr + index;
-+ shadow = priv->rx_gmac_desc_list_info.shadow_ptr + index;
-+
-+ // Set first buffer pointer to buffer from skb
-+ descriptor->buffer1 = shadow->buffer1 = frag_info->phys_adr;
-+
-+ // Remember the skb associated with the buffer
-+ shadow->buffer2 = (u32)frag_info->page;
-+
-+ // Ensure all prior writes to the descriptor shared with MAC have
-+ // completed before setting the descriptor ownership flag to transfer
-+ // ownership to the GMAC
-+ wmb();
-+
-+ // Set RX descriptor status to transfer ownership to the GMAC
-+ descriptor->status = (1UL << RDES0_OWN_BIT);
-+
-+ // Update the index of the next descriptor available for writing by the CPU
-+ priv->rx_gmac_desc_list_info.w_index = (shadow->length & (1UL << RDES1_RER_BIT)) ? 0 : index + 1;
-+
-+ // Account for the descriptor used to hold the new packet
-+ --priv->rx_gmac_desc_list_info.empty_count;
-+ ++priv->rx_gmac_desc_list_info.full_count;
-+ }
-+
-+ return index;
-+}
-+
-+int get_rx_descriptor(
-+ gmac_priv_t *priv,
-+ int *last,
-+ u32 *status,
-+ rx_frag_info_t *frag_info)
-+{
-+ int index;
-+ volatile gmac_dma_desc_t *descriptor;
-+ gmac_dma_desc_t *shadow;
-+ u32 desc_status;
-+
-+ if (!priv->rx_gmac_desc_list_info.full_count) {
-+ return -2;
-+ }
-+
-+ // Get the index of the descriptor released the longest time ago by the GMAC DMA
-+ index = priv->rx_gmac_desc_list_info.r_index;
-+ descriptor = priv->rx_gmac_desc_list_info.base_ptr + index;
-+ shadow = priv->rx_gmac_desc_list_info.shadow_ptr + index;
-+
-+ if (status && *status) {
-+ desc_status = *status;
-+ } else {
-+ desc_status = descriptor->status;
-+ }
-+
-+ if (desc_status & (1UL << RDES0_OWN_BIT)) {
-+ return -1;
-+ }
-+
-+ // Update the index of the next descriptor with which the GMAC DMA may have finished
-+ priv->rx_gmac_desc_list_info.r_index = (shadow->length & (1UL << RDES1_RER_BIT)) ? 0 : index + 1;
-+
-+ // Account for the descriptor which is now no longer waiting to be processed by the CPU
-+ ++priv->rx_gmac_desc_list_info.empty_count;
-+ --priv->rx_gmac_desc_list_info.full_count;
-+
-+ // Get packet details from the descriptor
-+ frag_info->page = (struct page*)(shadow->buffer2);
-+ frag_info->phys_adr = shadow->buffer1;
-+ frag_info->length = get_rx_length(desc_status);
-+
-+ // Is this descriptor the last contributing to a packet
-+ *last = desc_status & (1UL << RDES0_LS_BIT);
-+
-+ // Accumulate the status
-+ if (status && !*status) {
-+ *status = desc_status;
-+ }
-+
-+ return index;
-+}
-+
-+static inline int num_descriptors_needed(u16 length)
-+{
-+ static const int GMAC_MAX_DESC_ORDER = 11;
-+ static const u16 GMAC_MAX_DESC_MASK = ((1 << (GMAC_MAX_DESC_ORDER)) - 1);
-+
-+ int count = length >> GMAC_MAX_DESC_ORDER;
-+ if (length & GMAC_MAX_DESC_MASK) {
-+ ++count;
-+ }
-+ if ((count * max_descriptor_length()) < length) {
-+ ++count;
-+ }
-+
-+ return count;
-+}
-+
-+int set_tx_descriptor(
-+ gmac_priv_t *priv,
-+ struct sk_buff *skb,
-+ tx_frag_info_t *frag_info,
-+ int frag_count,
-+ int use_hw_csum)
-+{
-+ int first_descriptor_index = -1;
-+ int num_descriptors = frag_count;
-+ int frag_index = 0;
-+ int check_oversized_frags = priv->netdev->mtu >= (max_descriptor_length() - ETH_HLEN);
-+
-+ if (unlikely(check_oversized_frags)) {
-+ // Calculate the number of extra descriptors required due to fragments
-+ // being longer than the maximum buffer size that can be described by a
-+ // single descriptor
-+ num_descriptors = 0;
-+ do {
-+ // How many descriptors are required to describe the fragment?
-+ num_descriptors += num_descriptors_needed(frag_info[frag_index].length);
-+ } while (++frag_index < frag_count);
-+ }
-+
-+ // Are sufficicent descriptors available for writing by the CPU?
-+ if (available_for_write(&priv->tx_gmac_desc_list_info) < num_descriptors) {
-+ return -1;
-+ }
-+
-+ {
-+ volatile gmac_dma_desc_t *previous_descriptor = 0;
-+ gmac_dma_desc_t *previous_shadow = 0;
-+ volatile gmac_dma_desc_t *descriptors[num_descriptors];
-+ int desc_index = 0;
-+
-+ frag_index = 0;
-+ do {
-+ int last_frag = (frag_index == (frag_count - 1));
-+ u16 part_length = frag_info[frag_index].length;
-+ dma_addr_t phys_adr = frag_info[frag_index].phys_adr;
-+ int part = 0;
-+ int parts = 1;
-+
-+ if (unlikely(check_oversized_frags)) {
-+ // How many descriptors are required to describe the fragment?
-+ parts = num_descriptors_needed(part_length);
-+ }
-+
-+ // Setup a descriptor for each part of the fragment that can be
-+ // described by a single descriptor
-+ do {
-+ int last_part = (part == (parts - 1));
-+ int index = priv->tx_gmac_desc_list_info.w_index;
-+ volatile gmac_dma_desc_t *descriptor = priv->tx_gmac_desc_list_info.base_ptr + index;
-+ gmac_dma_desc_t *shadow = priv->tx_gmac_desc_list_info.shadow_ptr + index;
-+ u32 length = shadow->length;
-+ u32 buffer2 = 0;
-+
-+ // Remember descriptor pointer for final passing of ownership to GMAC
-+ descriptors[desc_index++] = descriptor;
-+
-+ // May have a second chained descriptor, but never a second buffer,
-+ // so clear the flag indicating whether there is a chained descriptor
-+ length &= ~(1UL << TDES1_TCH_BIT);
-+
-+ // Clear the first/last descriptor flags
-+ length &= ~((1UL << TDES1_LS_BIT) | (1UL << TDES1_FS_BIT));
-+
-+ // Set the Tx checksum mode
-+ length &= ~(((1UL << TDES1_CIC_NUM_BITS) - 1) << TDES1_CIC_BIT);
-+ if (use_hw_csum) {
-+ // Don't want full mode as network stack will have already
-+ // computed the TCP/UCP pseudo header and placed in into the
-+ // TCP/UCP checksum field
-+ length |= (TDES1_CIC_PAYLOAD << TDES1_CIC_BIT);
-+ }
-+ // Set fragment buffer length
-+ length &= ~(((1UL << TDES1_TBS1_NUM_BITS) - 1) << TDES1_TBS1_BIT);
-+ length |= ((part_length > max_descriptor_length() ? max_descriptor_length() : part_length) << TDES1_TBS1_BIT);
-+
-+ // Set fragment buffer address
-+ descriptor->buffer1 = shadow->buffer1 = phys_adr;
-+
-+ if (previous_shadow) {
-+ // Make the previous descriptor chain to the current one
-+ previous_shadow->length |= (1UL << TDES1_TCH_BIT);
-+ previous_descriptor->length = previous_shadow->length;
-+
-+ previous_shadow->buffer2 |= descriptors_virt_to_phys((u32)descriptor);
-+ previous_descriptor->buffer2 = previous_shadow->buffer2;
-+ }
-+
-+ // Is this the first desciptor for the packet?
-+ if (!frag_index && !part) {
-+ // Need to return index of first descriptor used for packet
-+ first_descriptor_index = index;
-+
-+ // Set flag indicating is first descriptor for packet
-+ length |= (1UL << TDES1_FS_BIT);
-+ }
-+
-+ // Is this the last descriptor for the packet?
-+ if (last_frag && last_part) {
-+ // Store the skb pointer with the last descriptor for packet, in
-+ // which the second buffer address will be unused as we do not use
-+ // second buffers and only intermedate buffers may use the chained
-+ // descriptor address
-+ buffer2 = (u32)skb;
-+
-+ // Set flag indicating is last descriptor for packet
-+ length |= (1UL << TDES1_LS_BIT);
-+ } else {
-+ // For descriptor chaining need to remember previous descriptor
-+ previous_descriptor = descriptor;
-+ previous_shadow = shadow;
-+
-+ // Is this descriptor not the last describing a single fragment
-+ // buffer?
-+ if (!last_part) {
-+ // This descriptor does not own the fragment buffer, so use
-+ // the (h/w ignored) lsb of buffer2 to encode this info.
-+ buffer2 = 1;
-+
-+ // Update the fragment buffer part details
-+ part_length -= max_descriptor_length();
-+ phys_adr += max_descriptor_length();
-+ }
-+ }
-+
-+ // Write the assembled length descriptor entry to the descriptor
-+ descriptor->length = shadow->length = length;
-+
-+ // Write the assembled buffer2 descriptor entry to the descriptor
-+ shadow->buffer2 = buffer2;
-+
-+ // Update the index of the next descriptor available for writing by the CPU
-+ priv->tx_gmac_desc_list_info.w_index = (length & (1UL << TDES1_TER_BIT)) ? 0 : index + 1;
-+ } while (++part < parts);
-+ } while (++frag_index < frag_count);
-+
-+ // Ensure all prior writes to the descriptors shared with MAC have
-+ // completed before setting the descriptor ownership flags to transfer
-+ // ownership to the GMAC
-+ wmb();
-+
-+ // Transfer descriptors to GMAC's ownership in reverse order, so when
-+ // GMAC begins processing the first descriptor all others are already
-+ // owned by the GMAC
-+ for (desc_index = (num_descriptors - 1); desc_index >= 0; --desc_index) {
-+ descriptors[desc_index]->status = (1UL << TDES0_OWN_BIT);
-+ }
-+ }
-+
-+ // Account for the number of descriptors used to hold the new packet
-+ priv->tx_gmac_desc_list_info.empty_count -= (num_descriptors);
-+ priv->tx_gmac_desc_list_info.full_count += (num_descriptors);
-+
-+ return first_descriptor_index;
-+}
-+
-+int get_tx_descriptor(
-+ gmac_priv_t *priv,
-+ struct sk_buff **skb,
-+ u32 *status,
-+ tx_frag_info_t *frag_info,
-+ int *buffer_owned)
-+{
-+ int index = -1;
-+ u32 local_status;
-+
-+ // Find the first available Tx descriptor
-+ if (tx_available_for_read(&priv->tx_gmac_desc_list_info, &local_status)) {
-+ gmac_dma_desc_t *shadow;
-+ u32 length;
-+ u32 buffer2;
-+
-+ // Get the descriptor released the longest time ago by the GMAC DMA
-+ index = priv->tx_gmac_desc_list_info.r_index;
-+ shadow = priv->tx_gmac_desc_list_info.shadow_ptr + index;
-+
-+ // Get the length of the buffer
-+ length = shadow->length;
-+ frag_info->length = ((length >> TDES1_TBS1_BIT) & ((1UL << TDES1_TBS1_NUM_BITS) - 1));
-+
-+ // Get a pointer to the buffer
-+ frag_info->phys_adr = shadow->buffer1;
-+
-+ // Get buffer ownership or skb info
-+ buffer2 = shadow->buffer2;
-+
-+ // Check that chained buffer not is use before setting skb from buffer2
-+ if (!(length & (1UL << TDES1_TCH_BIT))) {
-+ *skb = (struct sk_buff*)buffer2;
-+ *buffer_owned = 1;
-+ } else {
-+ // The lsb (h/w ignored) is used to encode buffer ownership
-+ *buffer_owned = !(buffer2 & 1);
-+ *skb = 0;
-+ }
-+
-+ // Accumulate status
-+ if (status) {
-+ *status |= local_status;
-+ }
-+
-+ // Update the index of the next descriptor with which the GMAC DMA may have finished
-+ priv->tx_gmac_desc_list_info.r_index = (length & (1UL << TDES1_TER_BIT)) ? 0 : index + 1;
-+
-+ // Account for the descriptor which is now no longer waiting to be processed by the CPU
-+ ++priv->tx_gmac_desc_list_info.empty_count;
-+ --priv->tx_gmac_desc_list_info.full_count;
-+ }
-+
-+ return index;
-+}
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_desc.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_desc.h
---- linux-2.6.24/arch/arm/mach-oxnas/gmac_desc.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_desc.h 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,315 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac_desc.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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
-+ */
-+#if !defined(__GMAC_DESC_H__)
-+#define __GMAC_DESC_H__
-+
-+#include <asm/types.h>
-+#include "gmac.h"
-+
-+typedef enum rdes0 {
-+ RDES0_OWN_BIT = 31,
-+ RDES0_AFM_BIT = 30,
-+ RDES0_FL_BIT = 16,
-+ RDES0_ES_BIT = 15,
-+ RDES0_DE_BIT = 14,
-+ RDES0_SAF_BIT = 13,
-+ RDES0_LE_BIT = 12,
-+ RDES0_OE_BIT = 11,
-+ RDES0_IPC_BIT = 10,
-+ RDES0_FS_BIT = 9,
-+ RDES0_LS_BIT = 8,
-+ RDES0_VLAN_BIT = 7,
-+ RDES0_LC_BIT = 6,
-+ RDES0_FT_BIT = 5,
-+ RDES0_RWT_BIT = 4,
-+ RDES0_RE_BIT = 3,
-+ RDES0_DRE_BIT = 2,
-+ RDES0_CE_BIT = 1,
-+ RDES0_PCE_BIT = 0
-+} rdes0_t;
-+
-+#define RX_DESC_STATUS_FL_NUM_BITS 14
-+
-+typedef enum rdes1 {
-+ RDES1_DIC_BIT = 31,
-+ RDES1_RER_BIT = 25,
-+ RDES1_RCH_BIT = 24,
-+ RDES1_RBS2_BIT = 11,
-+ RDES1_RBS1_BIT = 0,
-+} rdes1_t;
-+
-+#define RX_DESC_LENGTH_RBS2_NUM_BITS 11
-+#define RX_DESC_LENGTH_RBS1_NUM_BITS 11
-+
-+typedef enum tdes0 {
-+ TDES0_OWN_BIT = 31,
-+ TDES0_IHE_BIT = 16,
-+ TDES0_ES_BIT = 15,
-+ TDES0_JT_BIT = 14,
-+ TDES0_FF_BIT = 13,
-+ TDES0_PCE_BIT = 12,
-+ TDES0_LOC_BIT = 11,
-+ TDES0_NC_BIT = 10,
-+ TDES0_LC_BIT = 9,
-+ TDES0_EC_BIT = 8,
-+ TDES0_VF_BIT = 7,
-+ TDES0_CC_BIT = 3,
-+ TDES0_ED_BIT = 2,
-+ TDES0_UF_BIT = 1,
-+ TDES0_DB_BIT = 0
-+} tdes0_t;
-+
-+#define TDES0_CC_NUM_BITS 4
-+
-+typedef enum tdes1 {
-+ TDES1_IC_BIT = 31,
-+ TDES1_LS_BIT = 30,
-+ TDES1_FS_BIT = 29,
-+ TDES1_CIC_BIT = 27,
-+ TDES1_DC_BIT = 26,
-+ TDES1_TER_BIT = 25,
-+ TDES1_TCH_BIT = 24,
-+ TDES1_DP_BIT = 23,
-+ TDES1_TBS2_BIT = 11,
-+ TDES1_TBS1_BIT = 0
-+} tdes1_t;
-+
-+#define TDES1_CIC_NUM_BITS 2
-+#define TDES1_TBS2_NUM_BITS 11
-+#define TDES1_TBS1_NUM_BITS 11
-+
-+#define TDES1_CIC_NONE 0
-+#define TDES1_CIC_HDR 1
-+#define TDES1_CIC_PAYLOAD 2
-+#define TDES1_CIC_FULL 3
-+
-+extern void init_rx_desc_list(
-+ gmac_desc_list_info_t *desc_list,
-+ volatile gmac_dma_desc_t *base_ptr,
-+ gmac_dma_desc_t *shadow_ptr,
-+ int num_descriptors,
-+ u16 rx_buffer_length);
-+
-+extern void init_tx_desc_list(
-+ gmac_desc_list_info_t *desc_list,
-+ volatile gmac_dma_desc_t *base_ptr,
-+ gmac_dma_desc_t *shadow_ptr,
-+ int num_descriptors);
-+
-+/** Force ownership of all descriptors in the specified list to being owned by
-+ * the CPU
-+ */
-+extern void rx_take_ownership(gmac_desc_list_info_t* desc_list);
-+
-+/** Force ownership of all descriptors in the specified list to being owned by
-+ * the CPU
-+ */
-+extern void tx_take_ownership(gmac_desc_list_info_t* desc_list);
-+
-+/** Return the number of descriptors available for the CPU to fill with new
-+ * packet info */
-+static inline int available_for_write(gmac_desc_list_info_t* desc_list)
-+{
-+ return desc_list->empty_count;
-+}
-+
-+/** Return non-zero if there is a descriptor available with a packet with which
-+ * the GMAC DMA has finished */
-+static inline int tx_available_for_read(
-+ volatile gmac_desc_list_info_t *desc_list,
-+ u32 *status)
-+{
-+ if (!desc_list->full_count) {
-+ return 0;
-+ }
-+
-+ *status = (desc_list->base_ptr + desc_list->r_index)->status;
-+
-+ if (*status & (1UL << TDES0_OWN_BIT)) {
-+ return 0;
-+ }
-+
-+ return 1;
-+}
-+
-+/**
-+ * Return non-zero if there is a descriptor available with a packet with which
-+ * the GMAC DMA has finished.
-+ */
-+static inline int rx_available_for_read(
-+ volatile gmac_desc_list_info_t *desc_list,
-+ u32 *status)
-+{
-+ u32 local_status;
-+
-+ if (!desc_list->full_count) {
-+ return 0;
-+ }
-+
-+ local_status = (desc_list->base_ptr + desc_list->r_index)->status;
-+
-+ if (local_status & (1UL << RDES0_OWN_BIT)) {
-+ return 0;
-+ }
-+
-+ if (status) {
-+ *status = local_status;
-+ }
-+
-+ return 1;
-+}
-+
-+typedef struct rx_frag_info {
-+ struct page *page;
-+ dma_addr_t phys_adr;
-+ u16 length;
-+} rx_frag_info_t;
-+
-+/**
-+ * Fill a RX descriptor and pass ownership to DMA engine
-+ */
-+extern int set_rx_descriptor(
-+ gmac_priv_t *priv,
-+ rx_frag_info_t *frag_info);
-+
-+/**
-+ * Extract data from the next available descriptor with which the GMAC DMA
-+ * controller has finished.
-+ * The caller indicates via the 'first_last' argument whether the first
-+ * descriptor contributing to a packet is expected. The 'first_last' argument
-+ * will be returned set to indicate whether the descriptor was the last
-+ * contributing to a packet.
-+ * If the 'status' argument is non-null it will have the status from the
-+ * descriptor or'ed into it, thus enabling the compound status for all
-+ * descriptors contributing to a packet to be built up
-+ */
-+extern int get_rx_descriptor(
-+ gmac_priv_t *priv,
-+ int *last,
-+ u32 *status,
-+ rx_frag_info_t *frag_info);
-+
-+/**
-+ * Fill in descriptors describing all fragments in a single Tx packet and pass
-+ * ownership to the GMAC. The 'frag_info' argument points to an array describing
-+ * each buffer that is to contribute to the transmitted packet. The 'frag_count'
-+ * argument gives the number of elements in that array
-+ */
-+extern int set_tx_descriptor(
-+ gmac_priv_t *priv,
-+ struct sk_buff *skb,
-+ tx_frag_info_t *frag_info,
-+ int frag_count,
-+ int use_hw_csum);
-+
-+/**
-+ * Extract information about the TX packet transmitted the longest time ago.
-+ * If the 'status' argument is non-null it will have the status from the
-+ * descriptor or'ed into it.
-+ */
-+extern int get_tx_descriptor(
-+ gmac_priv_t *priv,
-+ struct sk_buff **skb,
-+ u32 *status,
-+ tx_frag_info_t *frag_info,
-+ int *buffer_owned);
-+
-+/**
-+ * @param A u32 containing the status from a received frame's DMA descriptor
-+ * @return An int which is non-zero if a valid received frame has no error
-+ * condititions flagged
-+ */
-+static inline int is_rx_valid(u32 status)
-+{
-+ return !(status & (1UL << RDES0_ES_BIT)) &&
-+ !(status & (1UL << RDES0_IPC_BIT));
-+}
-+
-+static inline int is_rx_dribbling(u32 status)
-+{
-+ return status & (1UL << RDES0_DRE_BIT);
-+}
-+
-+static inline u32 get_rx_length(u32 status)
-+{
-+ return (status >> RDES0_FL_BIT) & ((1UL << RX_DESC_STATUS_FL_NUM_BITS) - 1);
-+}
-+
-+static inline int is_rx_collision_error(u32 status)
-+{
-+ return status & ((1UL << RDES0_OE_BIT) | (1UL << RDES0_LC_BIT));
-+}
-+
-+static inline int is_rx_crc_error(u32 status)
-+{
-+ return status & (1UL << RDES0_CE_BIT);
-+}
-+
-+static inline int is_rx_frame_error(u32 status)
-+{
-+ return status & (1UL << RDES0_DE_BIT);
-+}
-+
-+static inline int is_rx_length_error(u32 status)
-+{
-+ return status & (1UL << RDES0_LE_BIT);
-+}
-+
-+static inline int is_rx_csum_error(u32 status)
-+{
-+ return (status & (1UL << RDES0_IPC_BIT))
-+#ifndef CONFIG_OXNAS_VERSION_0X800
-+ || (status & (1UL << RDES0_PCE_BIT))
-+#endif // !CONFIG_OXNAS_VERSION_0X800
-+ ;
-+}
-+
-+static inline int is_rx_long_frame(u32 status)
-+{
-+ return status & (1UL << RDES0_VLAN_BIT);
-+}
-+
-+static inline int is_tx_valid(u32 status)
-+{
-+ return !(status & (1UL << TDES0_ES_BIT));
-+}
-+
-+static inline int is_tx_collision_error(u32 status)
-+{
-+ return (status & (((1UL << TDES0_CC_NUM_BITS) - 1) << TDES0_CC_BIT)) >> TDES0_CC_BIT;
-+}
-+
-+static inline int is_tx_aborted(u32 status)
-+{
-+ return status & ((1UL << TDES0_LC_BIT) | (1UL << TDES0_EC_BIT));
-+}
-+
-+static inline int is_tx_carrier_error(u32 status)
-+{
-+ return status & ((1UL << TDES0_LOC_BIT) | (1UL << TDES0_NC_BIT));
-+}
-+
-+static inline u16 max_descriptor_length(void) {
-+ static const int GMAC_MAX_DESC_LEN = 2047;
-+
-+ return GMAC_MAX_DESC_LEN;
-+}
-+#endif // #if !defined(__GMAC_DESC_H__)
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_ethtool.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_ethtool.c
---- linux-2.6.24/arch/arm/mach-oxnas/gmac_ethtool.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_ethtool.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,275 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac_ethtool.c
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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 <asm/types.h>
-+#include <linux/errno.h>
-+#include <linux/ethtool.h>
-+#include <linux/netdevice.h>
-+#include <asm/io.h>
-+#include <asm/arch/leon.h>
-+
-+//#define GMAC_DEBUG
-+#undef GMAC_DEBUG
-+
-+#include "gmac.h"
-+#include "gmac_desc.h"
-+
-+static int get_settings(struct net_device* dev, struct ethtool_cmd* cmd)
-+{
-+ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+ unsigned long irq_flags;
-+ int status;
-+
-+ spin_lock_irqsave(&priv->phy_lock, irq_flags);
-+ status = mii_ethtool_gset(&priv->mii, cmd);
-+ spin_unlock_irqrestore(&priv->phy_lock, irq_flags);
-+
-+ return status;
-+}
-+
-+static int set_settings(struct net_device* dev, struct ethtool_cmd* cmd)
-+{
-+ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+ unsigned long irq_flags;
-+ int status;
-+
-+ spin_lock_irqsave(&priv->phy_lock, irq_flags);
-+ status = mii_ethtool_sset(&priv->mii, cmd);
-+ spin_unlock_irqrestore(&priv->phy_lock, irq_flags);
-+
-+ return status;
-+}
-+
-+static void get_drvinfo(struct net_device* dev, struct ethtool_drvinfo* drvinfo)
-+{
-+ strncpy(drvinfo->driver, "GMAC", 32);
-+ strncpy(drvinfo->version, "1.0", 32);
-+ strncpy(drvinfo->fw_version, "1.0", 32); // Version of CoPro s/w
-+ strncpy(drvinfo->bus_info, "AMBA", 32);
-+}
-+
-+static int nway_reset(struct net_device* dev)
-+{
-+ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+ unsigned long irq_flags;
-+ int status;
-+
-+ spin_lock_irqsave(&priv->phy_lock, irq_flags);
-+ status = mii_nway_restart(&priv->mii);
-+ spin_unlock_irqrestore(&priv->phy_lock, irq_flags);
-+
-+ return status;
-+}
-+
-+static u32 get_msglevel(struct net_device* dev)
-+{
-+ return ((gmac_priv_t*)netdev_priv(dev))->msg_level;
-+}
-+
-+static void set_msglevel(struct net_device* dev, u32 data)
-+{
-+ ((gmac_priv_t*)netdev_priv(dev))->msg_level = data;
-+}
-+
-+static u32 get_rx_csum(struct net_device* dev)
-+{
-+#ifdef USE_RX_CSUM
-+ return 1;
-+#else
-+ return 0;
-+#endif
-+}
-+
-+static int set_rx_csum(struct net_device* dev, u32 data)
-+{
-+ return 0;
-+}
-+
-+static int get_regs_len(struct net_device* dev)
-+{
-+ return 0;
-+}
-+
-+static void get_regs(struct net_device* dev, struct ethtool_regs* regs, void *p)
-+{
-+ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+ unsigned long irq_state;
-+ u32 status;
-+
-+ printk("RX ring info:\n");
-+ printk(" num_descriptors = %d\n", priv->rx_gmac_desc_list_info.num_descriptors);
-+ printk(" empty_count = %d\n", priv->rx_gmac_desc_list_info.empty_count);
-+ printk(" full_count = %d\n", priv->rx_gmac_desc_list_info.full_count);
-+ printk(" r_index = %d\n", priv->rx_gmac_desc_list_info.r_index);
-+ printk(" w_index = %d\n", priv->rx_gmac_desc_list_info.w_index);
-+ printk(" available_for_write = %d\n", available_for_write(&priv->rx_gmac_desc_list_info));
-+ printk(" available_for_read %s\n", rx_available_for_read(&priv->rx_gmac_desc_list_info, 0) ? "yes" :"no");
-+
-+ spin_lock_irqsave(&priv->tx_spinlock_, irq_state);
-+ printk("TX ring info:\n");
-+ printk(" num_descriptors = %d\n", priv->tx_gmac_desc_list_info.num_descriptors);
-+ printk(" empty_count = %d\n", priv->tx_gmac_desc_list_info.empty_count);
-+ printk(" full_count = %d\n", priv->tx_gmac_desc_list_info.full_count);
-+ printk(" r_index = %d\n", priv->tx_gmac_desc_list_info.r_index);
-+ printk(" w_index = %d\n", priv->tx_gmac_desc_list_info.w_index);
-+ printk(" available_for_write = %d\n", available_for_write(&priv->tx_gmac_desc_list_info));
-+ printk(" available_for_read %s\n", tx_available_for_read(&priv->tx_gmac_desc_list_info, &status) ? "yes" : "no");
-+ spin_unlock_irqrestore(&priv->tx_spinlock_, irq_state);
-+}
-+
-+static void get_wol(struct net_device* dev, struct ethtool_wolinfo* wol_info)
-+{
-+}
-+
-+static int set_wol(struct net_device* dev, struct ethtool_wolinfo* wol_info)
-+{
-+ return -EINVAL;
-+}
-+
-+static int get_coalesce(struct net_device* dev, struct ethtool_coalesce *ethtool_coalesce)
-+{
-+#ifdef CONFIG_LEON_COPRO
-+ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+
-+ if (priv->copro_params_.rx_mitigation_) {
-+ ethtool_coalesce->rx_max_coalesced_frames = priv->copro_params_.rx_mitigation_frames_;
-+ ethtool_coalesce->rx_coalesce_usecs = priv->copro_params_.rx_mitigation_usec_;
-+printk("get_coalesce() %u packets, %u usec\n", ethtool_coalesce->rx_max_coalesced_frames, ethtool_coalesce->rx_coalesce_usecs);
-+ }
-+#endif // CONFIG_LEON_COPRO
-+ return 0;
-+}
-+
-+static int set_coalesce(struct net_device* dev, struct ethtool_coalesce *ethtool_coalesce)
-+{
-+#ifdef CONFIG_LEON_COPRO
-+ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+
-+ if (priv->copro_params_.rx_mitigation_) {
-+printk("set_coalesce() %u packets, %u usec\n", ethtool_coalesce->rx_max_coalesced_frames, ethtool_coalesce->rx_coalesce_usecs);
-+ priv->copro_params_.rx_mitigation_frames_ = ethtool_coalesce->rx_max_coalesced_frames;
-+ priv->copro_params_.rx_mitigation_usec_ = ethtool_coalesce->rx_coalesce_usecs;
-+
-+ // Only attempt to write to uncached/unbuffered shared parameter storage
-+ // if CoPro is started and thus storage has been allocated
-+ if (priv->shared_copro_params_) {
-+ // Fill the CoPro parameter block
-+ memcpy(priv->shared_copro_params_, &priv->copro_params_, sizeof(copro_params_t));
-+ }
-+
-+ // Make sure the CoPro parameter block updates have made it to memory (which
-+ // is uncached/unbuffered, so just compiler issues to overcome)
-+ wmb();
-+
-+ spin_lock(&priv->cmd_que_lock_);
-+ cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_UPDATE_PARAMS, 0, 0);
-+ spin_unlock(&priv->cmd_que_lock_);
-+
-+ // Interrupt the CoPro so it sees the new command
-+ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
-+ }
-+#endif // CONFIG_LEON_COPRO
-+
-+ return 0;
-+}
-+
-+static void get_ringparam(struct net_device* dev, struct ethtool_ringparam *ethtool_ringparam)
-+{
-+}
-+
-+static int set_ringparam(struct net_device* dev, struct ethtool_ringparam *ethtool_ringparam)
-+{
-+ return -EINVAL;
-+}
-+
-+static void get_pauseparam(struct net_device* dev, struct ethtool_pauseparam* ethtool_pauseparam)
-+{
-+}
-+
-+static int set_pauseparam(struct net_device* dev, struct ethtool_pauseparam* ethtool_pauseparam)
-+{
-+ return -EINVAL;
-+}
-+
-+static int self_test_count(struct net_device* dev)
-+{
-+ return -EINVAL;
-+}
-+
-+static void self_test(struct net_device* dev, struct ethtool_test* ethtool_test, u64 *data)
-+{
-+}
-+
-+static void get_strings(struct net_device* dev, u32 stringset, u8 *data)
-+{
-+}
-+
-+static int phys_id(struct net_device* dev, u32 data)
-+{
-+ return -EINVAL;
-+}
-+
-+static int get_stats_count(struct net_device* dev)
-+{
-+ return -EINVAL;
-+}
-+
-+static void get_ethtool_stats(struct net_device* dev, struct ethtool_stats* ethtool_stats, u64 *data)
-+{
-+}
-+
-+static struct ethtool_ops ethtool_ops = {
-+ .get_settings = get_settings,
-+ .set_settings = set_settings,
-+ .get_drvinfo = get_drvinfo,
-+ .get_regs_len = get_regs_len,
-+ .get_regs = get_regs,
-+ .get_wol = get_wol,
-+ .set_wol = set_wol,
-+ .get_msglevel = get_msglevel,
-+ .set_msglevel = set_msglevel,
-+ .nway_reset = nway_reset,
-+ .get_link = ethtool_op_get_link,
-+ .get_coalesce = get_coalesce,
-+ .set_coalesce = set_coalesce,
-+ .get_ringparam = get_ringparam,
-+ .set_ringparam = set_ringparam,
-+ .get_pauseparam = get_pauseparam,
-+ .set_pauseparam = set_pauseparam,
-+ .get_rx_csum = get_rx_csum,
-+ .set_rx_csum = set_rx_csum,
-+ .get_tx_csum = ethtool_op_get_tx_csum,
-+ .set_tx_csum = ethtool_op_set_tx_csum,
-+ .get_sg = ethtool_op_get_sg,
-+ .set_sg = ethtool_op_set_sg,
-+ .get_tso = ethtool_op_get_tso,
-+ .set_tso = ethtool_op_set_tso,
-+ .self_test_count = self_test_count,
-+ .self_test = self_test,
-+ .get_strings = get_strings,
-+ .phys_id = phys_id,
-+ .get_stats_count = get_stats_count,
-+ .get_ethtool_stats = get_ethtool_stats
-+};
-+
-+void set_ethtool_ops(struct net_device *netdev)
-+{
-+ SET_ETHTOOL_OPS(netdev, ðtool_ops);
-+}
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_ethtool.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_ethtool.h
---- linux-2.6.24/arch/arm/mach-oxnas/gmac_ethtool.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_ethtool.h 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,26 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac_ethtool.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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
-+ */
-+#if !defined(__GMAC_ETHTOOL_H__)
-+#define __GMAC_ETHTOOL_H__
-+
-+extern void set_ethtool_ops(struct net_device *netdev);
-+
-+#endif // #if !defined(__GMAC_ETHTOOL_H__)
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_offload.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_offload.c
---- linux-2.6.24/arch/arm/mach-oxnas/gmac_offload.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_offload.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,223 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac-offload.c
-+ *
-+ * Copyright (C) 2006 Oxford Semiconductor Ltd
-+ *
-+ * 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
-+ */
-+#ifdef CONFIG_LEON_COPRO
-+
-+#include <linux/slab.h>
-+#include "gmac.h"
-+
-+void cmd_que_init(
-+ cmd_que_t *queue,
-+ gmac_cmd_que_ent_t *start,
-+ int num_entries)
-+{
-+ // Initialise queue management metadata
-+ INIT_LIST_HEAD(&queue->ack_list_);
-+ queue->head_ = start;
-+ queue->tail_ = start + num_entries;
-+ queue->w_ptr_ = queue->head_;
-+
-+ // Zeroise all entries in the queue
-+ memset(start, 0, num_entries * sizeof(gmac_cmd_que_ent_t));
-+}
-+
-+int cmd_que_dequeue_ack(cmd_que_t *queue)
-+{
-+ struct list_head *list_entry;
-+ cmd_que_ack_t *ack;
-+
-+ if (list_empty(&queue->ack_list_)) {
-+ return -1;
-+ }
-+
-+ // Remove the first entry on the acknowledgement list
-+ list_entry = queue->ack_list_.next;
-+ BUG_ON(!list_entry);
-+
-+ // Get pointer to ack entry from it's list_head member
-+ ack = list_entry(list_entry, cmd_que_ack_t, list_);
-+ BUG_ON(!ack);
-+ BUG_ON(!ack->entry_);
-+ BUG_ON(!ack->callback_);
-+
-+ // Has the CoPro acknowledged the command yet?
-+ if (!(ack->entry_->opcode_ & (1UL << GMAC_CMD_QUE_SKP_BIT))) {
-+ // No, so no further acknowledgements can be pending as CoPro executes
-+ // commands/acks in order
-+ return -1;
-+ }
-+
-+ // Going to process the acknowledgement, so remove it from the pending list
-+ list_del(list_entry);
-+
-+//printk("ak=0x%08x:0x%08x\n", ack->entry_->opcode_, ack->entry_->operand_);
-+ // Invoke the acknowledgement handler routine
-+ ack->callback_(ack->entry_);
-+
-+ // Reset ACK flag in command queue entry
-+ ack->entry_->opcode_ &= ~(1UL << GMAC_CMD_QUE_ACK_BIT);
-+
-+ kfree(ack);
-+ return 0;
-+}
-+
-+#define OPCODE_FLAGS_MASK ((1UL << (GMAC_CMD_QUE_OWN_BIT)) |\
-+ (1UL << (GMAC_CMD_QUE_ACK_BIT)) |\
-+ (1UL << (GMAC_CMD_QUE_SKP_BIT)))
-+
-+int cmd_que_queue_cmd(
-+ cmd_que_t *queue,
-+ u32 opcode,
-+ u32 operand,
-+ cmd_que_ack_callback callback)
-+{
-+ int result = -1;
-+
-+ do {
-+ volatile gmac_cmd_que_ent_t* entry = queue->w_ptr_;
-+ u32 old_opcode = entry->opcode_;
-+
-+ if (old_opcode & (1UL << GMAC_CMD_QUE_OWN_BIT)) {
-+ // Queue is full as we've run into an entry still owned by the CoPro
-+ break;
-+ }
-+
-+ if (!(old_opcode & (1UL << GMAC_CMD_QUE_ACK_BIT))) {
-+ // We've found an entry we own that isn't waiting for the contained
-+ // ack to be processed, so we can use it for the new command
-+ opcode &= ~(OPCODE_FLAGS_MASK);
-+ opcode |= (1UL << GMAC_CMD_QUE_OWN_BIT);
-+
-+ if (callback) {
-+ // Register ack. handler before releasing entry to CoPro
-+ cmd_que_ack_t *ack = kmalloc(sizeof(cmd_que_ack_t), GFP_ATOMIC);
-+ BUG_ON(!ack);
-+
-+ ack->entry_ = queue->w_ptr_;
-+ ack->callback_ = callback;
-+ INIT_LIST_HEAD(&ack->list_);
-+ list_add_tail(&ack->list_, &queue->ack_list_);
-+
-+ // Mark the entry as requiring an ack.
-+ opcode |= (1UL << GMAC_CMD_QUE_ACK_BIT);
-+ }
-+
-+ // Copy the command into the queue entry and pass ownership to the
-+ // CoPro, being sure to set the OWN flag last
-+//printk("op=0x%08x:0x%08x\n", opcode, operand);
-+ queue->w_ptr_->operand_ = operand;
-+ wmb();
-+ queue->w_ptr_->opcode_ = opcode;
-+ // Ensure the OWN flag gets to memory before any following interrupt
-+ // to the CoPro is issued
-+ wmb();
-+
-+ result = 0;
-+ }
-+
-+ // Make the write pointer point to the next potentially available entry
-+ if (++queue->w_ptr_ == queue->tail_) {
-+ queue->w_ptr_ = queue->head_;
-+ }
-+ } while (result);
-+
-+ return result;
-+}
-+
-+void tx_que_init(
-+ tx_que_t *queue,
-+ gmac_tx_que_ent_t *start,
-+ int num_entries)
-+{
-+ // Initialise queue management metadata
-+ queue->head_ = start;
-+ queue->tail_ = start + num_entries;
-+ queue->w_ptr_ = queue->head_;
-+ queue->r_ptr_ = queue->head_;
-+ queue->full_ = 0;
-+
-+ // Zeroise all entries in the queue
-+ memset(start, 0, num_entries * sizeof(gmac_tx_que_ent_t));
-+}
-+
-+static inline void tx_que_inc_w_ptr(tx_que_t *queue)
-+{
-+ if (++queue->w_ptr_ == queue->tail_) {
-+ queue->w_ptr_ = queue->head_;
-+ }
-+ queue->full_ = (queue->w_ptr_ == queue->r_ptr_);
-+}
-+
-+volatile gmac_tx_que_ent_t* tx_que_get_finished_job(struct net_device *dev)
-+{
-+ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+ tx_que_t *queue = &priv->tx_queue_;
-+ volatile gmac_tx_que_ent_t *entry = 0;
-+
-+ if (tx_que_not_empty(queue)) {
-+ entry = queue->r_ptr_;
-+ if (entry->flags_ & (1UL << TX_JOB_FLAGS_OWN_BIT)) {
-+ entry = (volatile gmac_tx_que_ent_t*)0;
-+ } else {
-+ tx_que_inc_r_ptr(queue);
-+ }
-+ }
-+
-+ return entry;
-+}
-+
-+/**
-+ * A call to tx_que_get_idle_job() must be followed by a call to tx_que_new_job()
-+ * before any subsequent call to tx_que_get_idle_job()
-+ */
-+volatile gmac_tx_que_ent_t* tx_que_get_idle_job(struct net_device *dev)
-+{
-+ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+ tx_que_t *queue = &priv->tx_queue_;
-+ volatile gmac_tx_que_ent_t *entry = 0;
-+
-+ // Must not reuse completed Tx packets returned by CoPro until the queue
-+ // reader has had a chance to process them
-+ if (!tx_que_is_full(queue)) {
-+ entry = queue->w_ptr_;
-+ }
-+
-+ return entry;
-+}
-+
-+/**
-+ * A call to tx_que_get_idle_job() must be followed by a call to tx_que_new_job()
-+ * before any subsequent call to tx_que_get_idle_job()
-+ */
-+void tx_que_new_job(
-+ struct net_device *dev,
-+ volatile gmac_tx_que_ent_t *entry)
-+{
-+ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+
-+ // Make sure any modifications to Tx job structures make it to memory before
-+ // setting the OWN flag to pass ownership to the CoPro
-+ wmb();
-+
-+ entry->flags_ |= (1UL << TX_JOB_FLAGS_OWN_BIT);
-+
-+ tx_que_inc_w_ptr(&priv->tx_queue_);
-+}
-+#endif // #ifdef CONFIG_LEON_COPRO
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_offload.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_offload.h
---- linux-2.6.24/arch/arm/mach-oxnas/gmac_offload.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_offload.h 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,163 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac-offload.h
-+ *
-+ * Copyright (C) 2006 Oxford Semiconductor Ltd
-+ *
-+ * 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
-+ */
-+#ifdef CONFIG_LEON_COPRO
-+
-+#if !defined(__GMAC_OFFLOAD_H__)
-+#define __GMAC_OFFLOAD_H__
-+
-+#include <linux/kernel.h>
-+#include <linux/list.h>
-+
-+#define GMAC_CMD_QUE_OWN_BIT 31 // 0-Owned by ARM, 1-Owned by CoPro
-+#define GMAC_CMD_QUE_ACK_BIT 30
-+#define GMAC_CMD_QUE_SKP_BIT 29
-+
-+typedef struct gmac_cmd_que_ent {
-+ u32 opcode_;
-+ u32 operand_;
-+} __attribute ((aligned(4),packed)) gmac_cmd_que_ent_t;
-+
-+#define GMAC_CMD_STOP 0
-+#define GMAC_CMD_START 1
-+#define GMAC_CMD_INT_EN_SET 2
-+#define GMAC_CMD_INT_EN_CLR 3
-+#define GMAC_CMD_HEARTBEAT 4
-+#define GMAC_CMD_UPDATE_PARAMS 5
-+#define GMAC_CMD_CHANGE_GIG_MODE 6
-+#define GMAC_CMD_CHANGE_RX_ENABLE 7
-+#define GMAC_CMD_CLEAR_RX_INTS 8
-+#define GMAC_CMD_CHANGE_PAUSE_MODE 9
-+
-+typedef void (*cmd_que_ack_callback)(volatile gmac_cmd_que_ent_t* entry);
-+
-+typedef struct cmd_que_ack {
-+ struct list_head list_;
-+ volatile gmac_cmd_que_ent_t *entry_;
-+ cmd_que_ack_callback callback_;
-+} cmd_que_ack_t;
-+
-+typedef struct cmd_que {
-+ gmac_cmd_que_ent_t *head_;
-+ gmac_cmd_que_ent_t *tail_;
-+ volatile gmac_cmd_que_ent_t *w_ptr_;
-+ struct list_head ack_list_;
-+} cmd_que_t;
-+
-+extern void cmd_que_init(
-+ cmd_que_t *queue,
-+ gmac_cmd_que_ent_t *start,
-+ int num_entries);
-+
-+extern int cmd_que_dequeue_ack(cmd_que_t *queue);
-+
-+extern int cmd_que_queue_cmd(
-+ cmd_que_t *queue,
-+ u32 opcode,
-+ u32 operand,
-+ cmd_que_ack_callback callback); // non-zero if ack. required
-+
-+#define COPRO_SEM_INT_CMD 0
-+#define COPRO_SEM_INT_TX 1
-+
-+typedef struct gmac_fwd_intrs {
-+ u32 status_;
-+} __attribute ((aligned(4),packed)) gmac_fwd_intrs_t;
-+
-+#define TX_JOB_FLAGS_OWN_BIT 0
-+#define TX_JOB_FLAGS_COPRO_RESERVED_1_BIT 1
-+#define TX_JOB_FLAGS_ACCELERATE_BIT 2
-+
-+#define TX_JOB_STATS_BYTES_BIT 0
-+#define TX_JOB_STATS_BYTES_NUM_BITS 16
-+#define TX_JOB_STATS_BYTES_MASK (((1UL << TX_JOB_STATS_BYTES_NUM_BITS) - 1) << TX_JOB_STATS_BYTES_BIT)
-+#define TX_JOB_STATS_PACKETS_BIT 16
-+#define TX_JOB_STATS_PACKETS_NUM_BITS 6
-+#define TX_JOB_STATS_PACKETS_MASK (((1UL << TX_JOB_STATS_PACKETS_NUM_BITS) - 1) << TX_JOB_STATS_PACKETS_BIT)
-+#define TX_JOB_STATS_ABORT_BIT 22
-+#define TX_JOB_STATS_ABORT_NUM_BITS 3
-+#define TX_JOB_STATS_ABORT_MASK (((1UL << TX_JOB_STATS_ABORT_NUM_BITS) - 1) << TX_JOB_STATS_ABORT_BIT)
-+#define TX_JOB_STATS_CARRIER_BIT 25
-+#define TX_JOB_STATS_CARRIER_NUM_BITS 3
-+#define TX_JOB_STATS_CARRIER_MASK (((1UL << TX_JOB_STATS_CARRIER_NUM_BITS) - 1) << TX_JOB_STATS_CARRIER_BIT)
-+#define TX_JOB_STATS_COLLISION_BIT 28
-+#define TX_JOB_STATS_COLLISION_NUM_BITS 4
-+#define TX_JOB_STATS_COLLISION_MASK (((1UL << TX_JOB_STATS_COLLISION_NUM_BITS) - 1) << TX_JOB_STATS_COLLISION_BIT)
-+
-+/* Make even number else gmac_tx_que_ent_t struct below alignment will be wrong */
-+#define COPRO_NUM_TX_FRAGS_DIRECT 18
-+
-+typedef struct gmac_tx_que_ent {
-+ u32 skb_;
-+ u32 len_;
-+ u32 data_len_;
-+ u32 ethhdr_;
-+ u32 iphdr_;
-+ u16 iphdr_csum_;
-+ u16 tso_segs_;
-+ u16 tso_size_;
-+ u16 flags_;
-+ u32 frag_ptr_[COPRO_NUM_TX_FRAGS_DIRECT];
-+ u16 frag_len_[COPRO_NUM_TX_FRAGS_DIRECT];
-+ u32 statistics_;
-+} __attribute ((aligned(4),packed)) gmac_tx_que_ent_t;
-+
-+typedef struct tx_que {
-+ gmac_tx_que_ent_t *head_;
-+ gmac_tx_que_ent_t *tail_;
-+ volatile gmac_tx_que_ent_t *w_ptr_;
-+ volatile gmac_tx_que_ent_t *r_ptr_;
-+ int full_;
-+} tx_que_t;
-+
-+extern void tx_que_init(
-+ tx_que_t *queue,
-+ gmac_tx_que_ent_t *start,
-+ int num_entries);
-+
-+static inline int tx_que_not_empty(tx_que_t *queue)
-+{
-+ return (queue->r_ptr_ != queue->w_ptr_) || queue->full_;
-+}
-+
-+static inline int tx_que_is_full(tx_que_t *queue)
-+{
-+ return queue->full_;
-+}
-+
-+static inline void tx_que_inc_r_ptr(tx_que_t *queue)
-+{
-+ if (++queue->r_ptr_ == queue->tail_) {
-+ queue->r_ptr_ = queue->head_;
-+ }
-+ if (queue->full_) {
-+ queue->full_ = 0;
-+ }
-+}
-+
-+extern volatile gmac_tx_que_ent_t* tx_que_get_finished_job(struct net_device *dev);
-+
-+extern volatile gmac_tx_que_ent_t* tx_que_get_idle_job(struct net_device *dev);
-+
-+extern void tx_que_new_job(
-+ struct net_device *dev,
-+ volatile gmac_tx_que_ent_t *entry);
-+
-+#endif // #if !defined(__GMAC_OFFLOAD_H__)
-+#endif // CONFIG_LEON_COPRO
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_phy.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_phy.c
---- linux-2.6.24/arch/arm/mach-oxnas/gmac_phy.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_phy.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,318 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac_phy.c
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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 <linux/delay.h>
-+
-+//#define GMAC_DEBUG
-+#undef GMAC_DEBUG
-+
-+#include "gmac.h"
-+#include "gmac_phy.h"
-+#include "gmac_reg.h"
-+
-+static const int PHY_TRANSFER_TIMEOUT_MS = 100;
-+
-+/*
-+ * Reads a register from the MII Management serial interface
-+ */
-+int phy_read(struct net_device *dev, int phyaddr, int phyreg)
-+{
-+ int data = 0;
-+#ifndef ARMULATING
-+ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+ unsigned long end;
-+
-+ u32 addr = (phyaddr << MAC_GMII_ADR_PA_BIT) |
-+ (phyreg << MAC_GMII_ADR_GR_BIT) |
-+ (priv->gmii_csr_clk_range << MAC_GMII_ADR_CR_BIT) |
-+ (1UL << MAC_GMII_ADR_GB_BIT);
-+
-+ mac_reg_write(priv, MAC_GMII_ADR_REG, addr);
-+
-+ end = jiffies + MS_TO_JIFFIES(PHY_TRANSFER_TIMEOUT_MS);
-+ while (time_before(jiffies, end)) {
-+ if (!(mac_reg_read(priv, MAC_GMII_ADR_REG) & (1UL << MAC_GMII_ADR_GB_BIT))) {
-+ // Successfully read from PHY
-+ data = mac_reg_read(priv, MAC_GMII_DATA_REG) & 0xFFFF;
-+ break;
-+ }
-+ }
-+
-+ DBG(1, KERN_INFO "phy_read() %s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", dev->name, phyaddr, phyreg, data);
-+#endif // ARMULATING
-+
-+ return data;
-+}
-+
-+/*
-+ * Writes a register to the MII Management serial interface
-+ */
-+void phy_write(struct net_device *dev, int phyaddr, int phyreg, int phydata)
-+{
-+#ifndef ARMULATING
-+ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+ unsigned long end;
-+
-+ u32 addr = (phyaddr << MAC_GMII_ADR_PA_BIT) |
-+ (phyreg << MAC_GMII_ADR_GR_BIT) |
-+ (priv->gmii_csr_clk_range << MAC_GMII_ADR_CR_BIT) |
-+ (1UL << MAC_GMII_ADR_GW_BIT) |
-+ (1UL << MAC_GMII_ADR_GB_BIT);
-+
-+ mac_reg_write(priv, MAC_GMII_DATA_REG, phydata);
-+ mac_reg_write(priv, MAC_GMII_ADR_REG, addr);
-+
-+ end = jiffies + MS_TO_JIFFIES(PHY_TRANSFER_TIMEOUT_MS);
-+ while (time_before(jiffies, end)) {
-+ if (!(mac_reg_read(priv, MAC_GMII_ADR_REG) & (1UL << MAC_GMII_ADR_GB_BIT))) {
-+ break;
-+ }
-+ }
-+
-+ DBG(1, KERN_INFO "phy_write() %s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", dev->name, phyaddr, phyreg, phydata);
-+#endif // ARMULATING
-+}
-+
-+/*
-+ * Finds and reports the PHY address
-+ */
-+void phy_detect(struct net_device *dev)
-+{
-+ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+#ifdef ARMULATING
-+ priv->mii.phy_id = 0;
-+ priv->phy_type = 0x22 << 16 | 0x1619;
-+ priv->phy_addr = 0;
-+#else // ARMULATING
-+ int phyaddr;
-+
-+ DBG(2, KERN_INFO "phy_detect() %s: Entered\n", priv->netdev->name);
-+
-+ // Scan all 32 PHY addresses if necessary
-+ priv->phy_type = 0;
-+ for (phyaddr = 1; phyaddr < 33; ++phyaddr) {
-+ unsigned int id1, id2;
-+
-+ // Read the PHY identifiers
-+ id1 = phy_read(priv->netdev, phyaddr & 31, MII_PHYSID1);
-+ id2 = phy_read(priv->netdev, phyaddr & 31, MII_PHYSID2);
-+
-+ DBG(2, KERN_INFO "phy_detect() %s: PHY adr = %u -> phy_id1=0x%x, phy_id2=0x%x\n", priv->netdev->name, phyaddr, id1, id2);
-+
-+ // Make sure it is a valid identifier
-+ if (id1 != 0x0000 && id1 != 0xffff && id1 != 0x8000 &&
-+ id2 != 0x0000 && id2 != 0xffff && id2 != 0x8000) {
-+ DBG(2, KERN_NOTICE "phy_detect() %s: Found PHY at address = %u\n", priv->netdev->name, phyaddr);
-+ priv->mii.phy_id = phyaddr & 31;
-+ priv->phy_type = id1 << 16 | id2;
-+ priv->phy_addr = phyaddr;
-+ break;
-+ }
-+ }
-+#endif // ARMULATING
-+}
-+
-+void start_phy_reset(gmac_priv_t* priv)
-+{
-+ // Ask the PHY to reset
-+ phy_write(priv->netdev, priv->phy_addr, MII_BMCR, BMCR_RESET);
-+}
-+
-+int is_phy_reset_complete(gmac_priv_t* priv)
-+{
-+#ifdef ARMULATING
-+ return 1;
-+#else // ARMULATING
-+ int complete = 0;
-+ int bmcr;
-+
-+ // Read back the status until it indicates reset, or we timeout
-+ bmcr = phy_read(priv->netdev, priv->phy_addr, MII_BMCR);
-+ if (!(bmcr & BMCR_RESET)) {
-+ complete = 1;
-+ }
-+
-+ return complete;
-+#endif // ARMULATING
-+}
-+
-+int phy_reset(struct net_device *dev)
-+{
-+#ifdef ARMULATING
-+ return 0;
-+#else // ARMULATING
-+ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+ int complete = 0;
-+ unsigned long end;
-+
-+ // Start the reset operation
-+ start_phy_reset(priv);
-+
-+ // Total time to wait for reset to complete
-+ end = jiffies + MS_TO_JIFFIES(PHY_TRANSFER_TIMEOUT_MS);
-+
-+ // Should apparently wait at least 50mS before reading back from PHY; this
-+ // could just be a nasty feature of the SMC91x MAC/PHY and not apply to us
-+ msleep(50);
-+
-+ // Read back the status until it indicates reset, or we timeout
-+ while (!(complete = is_phy_reset_complete(priv)) && time_before(jiffies, end)) {
-+ msleep(1);
-+ }
-+
-+ return !complete;
-+#endif // ARMULATING
-+}
-+
-+void phy_powerdown(struct net_device *dev)
-+{
-+ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
-+
-+ unsigned int bmcr = phy_read(dev, priv->phy_addr, MII_BMCR);
-+ phy_write(dev, priv->phy_addr, MII_BMCR, bmcr | BMCR_PDOWN);
-+}
-+
-+void set_phy_negotiate_mode(struct net_device *dev)
-+{
-+ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
-+ struct mii_if_info *mii = &priv->mii;
-+ struct ethtool_cmd *ecmd = &priv->ethtool_cmd;
-+ u32 bmcr;
-+
-+ bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
-+
-+ if (ecmd->autoneg == AUTONEG_ENABLE) {
-+ u32 advert, tmp;
-+ u32 advert2 = 0, tmp2 = 0;
-+
-+//printk("set_phy_negotiate_mode() Auto negotiating link mode\n");
-+ // Advertise only what has been requested
-+ advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE);
-+ tmp = advert & ~(ADVERTISE_ALL | ADVERTISE_100BASE4 |
-+ ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
-+
-+ if (ecmd->supported & (SUPPORTED_1000baseT_Full | ADVERTISE_1000HALF)) {
-+ advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
-+ tmp2 = advert2 & ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
-+ }
-+
-+ if (ecmd->advertising & ADVERTISED_10baseT_Half) {
-+ tmp |= ADVERTISE_10HALF;
-+ }
-+ if (ecmd->advertising & ADVERTISED_10baseT_Full) {
-+ tmp |= ADVERTISE_10FULL;
-+ }
-+ if (ecmd->advertising & ADVERTISED_100baseT_Half) {
-+ tmp |= ADVERTISE_100HALF;
-+ }
-+ if (ecmd->advertising & ADVERTISED_100baseT_Full) {
-+ tmp |= ADVERTISE_100FULL;
-+ }
-+ if ((ecmd->supported & SUPPORTED_1000baseT_Half) &&
-+ (ecmd->advertising & ADVERTISED_1000baseT_Half)) {
-+ tmp2 |= ADVERTISE_1000HALF;
-+ }
-+ if ((ecmd->supported & SUPPORTED_1000baseT_Full) &&
-+ (ecmd->advertising & ADVERTISED_1000baseT_Full)) {
-+ tmp2 |= ADVERTISE_1000FULL;
-+ }
-+
-+ if (ecmd->advertising & ADVERTISED_Pause) {
-+ tmp |= ADVERTISE_PAUSE_CAP;
-+ }
-+ if (ecmd->advertising & ADVERTISED_Asym_Pause) {
-+ tmp |= ADVERTISE_PAUSE_ASYM;
-+ }
-+
-+ if (advert != tmp) {
-+//printk("set_phy_negotiate_mode() Setting MII_ADVERTISE to 0x%08x\n", tmp);
-+ mii->mdio_write(dev, mii->phy_id, MII_ADVERTISE, tmp);
-+ mii->advertising = tmp;
-+ }
-+ if (advert2 != tmp2) {
-+//printk("set_phy_negotiate_mode() Setting MII_CTRL1000 to 0x%08x\n", tmp2);
-+ mii->mdio_write(dev, mii->phy_id, MII_CTRL1000, tmp2);
-+ }
-+
-+ // Auto-negotiate the link state
-+ bmcr |= (BMCR_ANRESTART | BMCR_ANENABLE);
-+ mii->mdio_write(dev, mii->phy_id, MII_BMCR, bmcr);
-+ } else {
-+ u32 tmp;
-+//printk("set_phy_negotiate_mode() Unilaterally setting link mode\n");
-+
-+ // Turn off auto negotiation, set speed and duplicitly unilaterally
-+ tmp = bmcr & ~(BMCR_ANENABLE | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_FULLDPLX);
-+ if (ecmd->speed == SPEED_1000) {
-+ tmp |= BMCR_SPEED1000;
-+ } else if (ecmd->speed == SPEED_100) {
-+ tmp |= BMCR_SPEED100;
-+ }
-+
-+ if (ecmd->duplex == DUPLEX_FULL) {
-+ tmp |= BMCR_FULLDPLX;
-+ mii->full_duplex = 1;
-+ } else {
-+ mii->full_duplex = 0;
-+ }
-+
-+ if (bmcr != tmp) {
-+ mii->mdio_write(dev, mii->phy_id, MII_BMCR, tmp);
-+ }
-+ }
-+}
-+
-+u32 get_phy_capabilies(gmac_priv_t* priv)
-+{
-+ struct mii_if_info *mii = &priv->mii;
-+
-+ // Ask the PHY for it's capabilities
-+ u32 reg = mii->mdio_read(priv->netdev, mii->phy_id, MII_BMSR);
-+
-+ // Assume PHY has MII interface
-+ u32 features = SUPPORTED_MII;
-+
-+ if (reg & BMSR_ANEGCAPABLE) {
-+ features |= SUPPORTED_Autoneg;
-+ }
-+ if (reg & BMSR_100FULL) {
-+ features |= SUPPORTED_100baseT_Full;
-+ }
-+ if (reg & BMSR_100HALF) {
-+ features |= SUPPORTED_100baseT_Half;
-+ }
-+ if (reg & BMSR_10FULL) {
-+ features |= SUPPORTED_10baseT_Full;
-+ }
-+ if (reg & BMSR_10HALF) {
-+ features |= SUPPORTED_10baseT_Half;
-+ }
-+
-+ // Does the PHY have the extended status register?
-+ if (reg & BMSR_ESTATEN) {
-+ reg = mii->mdio_read(priv->netdev, mii->phy_id, MII_ESTATUS);
-+
-+ if (reg & ESTATUS_1000_TFULL)
-+ features |= SUPPORTED_1000baseT_Full;
-+ if (reg & ESTATUS_1000_THALF)
-+ features |= SUPPORTED_1000baseT_Half;
-+ }
-+
-+ return features;
-+}
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_phy.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_phy.h
---- linux-2.6.24/arch/arm/mach-oxnas/gmac_phy.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_phy.h 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,78 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac_phy.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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
-+ */
-+#if !defined(__GMAC_PHY_H__)
-+#define __GMAC_PHY_H__
-+
-+#include <asm/types.h>
-+#include <linux/netdevice.h>
-+#include <linux/mii.h>
-+#include "gmac.h"
-+
-+#define PHY_TYPE_NONE 0
-+#define PHY_TYPE_MICREL_KS8721BL 0x00221619
-+#define PHY_TYPE_VITESSE_VSC8201XVZ 0x000fc413
-+#define PHY_TYPE_REALTEK_RTL8211BGR 0x001cc912
-+#define PHY_TYPE_LSI_ET1011C 0x0282f013
-+#define PHY_TYPE_LSI_ET1011C2 0x0282f014
-+#define PHY_TYPE_ICPLUS_IP1001 0x02430d90
-+
-+#define VSC8201_MII_ACSR 0x1c // Vitesse VCS8201 gigabit PHY Auxillary Control and Status register
-+#define VSC8201_MII_ACSR_MDPPS_BIT 2 // Mode/Duplex Pin Priority Select
-+
-+#define ET1011C_MII_CONFIG 0x16
-+#define ET1011C_MII_CONFIG_IFMODESEL 0
-+#define ET1011C_MII_CONFIG_IFMODESEL_NUM_BITS 3
-+#define ET1011C_MII_CONFIG_SYSCLKEN 4
-+#define ET1011C_MII_CONFIG_TXCLKEN 5
-+#define ET1011C_MII_CONFIG_TBI_RATESEL 8
-+#define ET1011C_MII_CONFIG_CRS_TX_EN 15
-+
-+#define ET1011C_MII_CONFIG_IFMODESEL_GMII_MII 0
-+#define ET1011C_MII_CONFIG_IFMODESEL_TBI 1
-+#define ET1011C_MII_CONFIG_IFMODESEL_GMII_MII_GTX 2
-+
-+#define ET1011C_MII_LED2 0x1c
-+#define ET1011C_MII_LED2_LED_TXRX 12
-+#define ET1011C_MII_LED2_LED_NUM_BITS 4
-+
-+#define ET1011C_MII_LED2_LED_TXRX_ON 0xe
-+#define ET1011C_MII_LED2_LED_TXRX_ACTIVITY 0x7
-+
-+extern int phy_read(struct net_device *dev, int phyaddr, int phyreg);
-+
-+extern void phy_write(struct net_device *dev, int phyaddr, int phyreg, int phydata);
-+
-+extern void phy_detect(struct net_device *dev);
-+
-+extern int phy_reset(struct net_device *dev);
-+
-+extern void phy_powerdown(struct net_device *dev);
-+
-+extern void start_phy_reset(gmac_priv_t* priv);
-+
-+extern int is_phy_reset_complete(gmac_priv_t* priv);
-+
-+extern void set_phy_negotiate_mode(struct net_device *dev);
-+
-+extern u32 get_phy_capabilies(gmac_priv_t* priv);
-+
-+extern u32 get_phy_capabilies(gmac_priv_t* priv);
-+#endif // #if !defined(__GMAC_PHY_H__)
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_reg.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_reg.h
---- linux-2.6.24/arch/arm/mach-oxnas/gmac_reg.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_reg.h 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,508 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/gmac_reg.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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
-+ */
-+#if !defined(__GMAC_REG_H__)
-+#define __GMAC_REG_H__
-+
-+#include <asm/io.h>
-+#include "gmac.h"
-+
-+/**
-+ * MAC register access functions
-+ */
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the MAC register to access
-+ */
-+static inline u32 mac_reg_read(gmac_priv_t* priv, int reg_num)
-+{
-+//printk("$WReading MAC register %u at byte adr 0x%08x\n", reg_num, priv->macBase + (reg_num << 2));
-+ return readl(priv->macBase + (reg_num << 2));
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the MAC register to access
-+ */
-+static inline void mac_reg_write(gmac_priv_t* priv, int reg_num, u32 value)
-+{
-+//printk("$WWriting MAC register %u at byte adr 0x%08x with 0x%08x\n", reg_num, priv->macBase + (reg_num << 2), value);
-+ writel(value, priv->macBase + (reg_num << 2));
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the MAC register to access
-+ * @param bits_to_clear A u32 specifying which bits of the specified register to
-+ * clear. A set bit in this parameter will cause the matching bit in the
-+ * register to be cleared
-+ */
-+static inline void mac_reg_clear_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_clear)
-+{
-+ mac_reg_write(priv, reg_num, mac_reg_read(priv, reg_num) & ~bits_to_clear);
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the MAC register to access
-+ * @param bits_to_set A u32 specifying which bits of the specified register to
-+ * set. A set bit in this parameter will cause the matching bit in the register
-+ * to be set
-+ */
-+static inline void mac_reg_set_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_set)
-+{
-+ mac_reg_write(priv, reg_num, mac_reg_read(priv, reg_num) | bits_to_set);
-+}
-+
-+/**
-+ * DMA register access functions
-+ */
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the DMA register to access
-+ */
-+static inline u32 dma_reg_read(gmac_priv_t* priv, int reg_num)
-+{
-+//printk("$WReading DMA register %u at byte adr 0x%08x\n", reg_num, priv->dmaBase + (reg_num << 2));
-+ return readl(priv->dmaBase + (reg_num << 2));
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the DMA register to access
-+ */
-+static inline void dma_reg_write(gmac_priv_t* priv, int reg_num, u32 value)
-+{
-+//printk("$WWriting DMA register %u at byte adr 0x%08x with 0x%08x\n", reg_num, priv->dmaBase + (reg_num << 2), value);
-+ writel(value, priv->dmaBase + (reg_num << 2));
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the DMA register to access
-+ * @param bits_to_clear A u32 specifying which bits of the specified register to
-+ * clear. A set bit in this parameter will cause the matching bit in the
-+ * register to be cleared
-+ * @return An u32 containing the new value written to the register
-+ */
-+static inline u32 dma_reg_clear_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_clear)
-+{
-+ u32 new_value = dma_reg_read(priv, reg_num) & ~bits_to_clear;
-+ dma_reg_write(priv, reg_num, new_value);
-+ return new_value;
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the DMA register to access
-+ * @param bits_to_set A u32 specifying which bits of the specified register to
-+ * set. A set bit in this parameter will cause the matching bit in the register
-+ * to be set
-+ * @return An u32 containing the new value written to the register
-+ */
-+static inline u32 dma_reg_set_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_set)
-+{
-+ u32 new_value = dma_reg_read(priv, reg_num) | bits_to_set;
-+ dma_reg_write(priv, reg_num, new_value);
-+ return new_value;
-+}
-+
-+#define NUM_PERFECT_MATCH_REGISTERS 15
-+
-+/**
-+ * MAC register indices
-+ */
-+typedef enum gmac_mac_regs {
-+ MAC_CONFIG_REG = 0,
-+ MAC_FRAME_FILTER_REG = 1,
-+ MAC_HASH_HIGH_REG = 2,
-+ MAC_HASH_LOW_REG = 3,
-+ MAC_GMII_ADR_REG = 4,
-+ MAC_GMII_DATA_REG = 5,
-+ MAC_FLOW_CNTL_REG = 6,
-+ MAC_VLAN_TAG_REG = 7,
-+ MAC_VERSION_REG = 8,
-+ MAC_ADR0_HIGH_REG = 16,
-+ MAC_ADR0_LOW_REG = 17,
-+ MAC_ADR1_HIGH_REG = 18,
-+ MAC_ADR1_LOW_REG = 19,
-+ MAC_ADR2_HIGH_REG = 20,
-+ MAC_ADR2_LOW_REG = 21,
-+ MAC_ADR3_HIGH_REG = 22,
-+ MAC_ADR3_LOW_REG = 23,
-+ MAC_ADR4_HIGH_REG = 24,
-+ MAC_ADR4_LOW_REG = 25,
-+ MAC_ADR5_HIGH_REG = 26,
-+ MAC_ADR5_LOW_REG = 27,
-+ MAC_ADR6_HIGH_REG = 28,
-+ MAC_ADR6_LOW_REG = 29,
-+ MAC_ADR7_HIGH_REG = 30,
-+ MAC_ADR7_LOW_REG = 31,
-+ MAC_ADR8_HIGH_REG = 32,
-+ MAC_ADR8_LOW_REG = 33,
-+ MAC_ADR9_HIGH_REG = 34,
-+ MAC_ADR9_LOW_REG = 35,
-+ MAC_ADR10_HIGH_REG = 36,
-+ MAC_ADR10_LOW_REG = 37,
-+ MAC_ADR11_HIGH_REG = 38,
-+ MAC_ADR11_LOW_REG = 39,
-+ MAC_ADR12_HIGH_REG = 40,
-+ MAC_ADR12_LOW_REG = 41,
-+ MAC_ADR13_HIGH_REG = 42,
-+ MAC_ADR13_LOW_REG = 43,
-+ MAC_ADR14_HIGH_REG = 44,
-+ MAC_ADR14_LOW_REG = 45,
-+ MAC_ADR15_HIGH_REG = 46,
-+ MAC_ADR15_LOW_REG = 47
-+} gmac_mac_regs_t;
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the perfect matching low register
-+ * @param value A u32 specifying the value to write to the register
-+ */
-+static inline void mac_adrlo_reg_write(gmac_priv_t* priv, int reg_num, u32 value)
-+{
-+ mac_reg_write(priv, MAC_ADR1_LOW_REG + (2*reg_num), value);
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the perfect matching high register
-+ * @param value A u32 specifying the value to write to the register
-+ */
-+static inline void mac_adrhi_reg_write(gmac_priv_t* priv, int reg_num, u32 value)
-+{
-+ mac_reg_write(priv, MAC_ADR1_HIGH_REG + (2*reg_num), value);
-+}
-+
-+/**
-+ * MAC register field definitions
-+ */
-+typedef enum gmac_config_reg {
-+ MAC_CONFIG_WD_BIT = 23,
-+ MAC_CONFIG_JD_BIT = 22,
-+ MAC_CONFIG_BE_BIT = 21,
-+ MAC_CONFIG_JE_BIT = 20,
-+ MAC_CONFIG_IFG_BIT = 17,
-+ MAC_CONFIG_PS_BIT = 15,
-+ MAC_CONFIG_DO_BIT = 13,
-+ MAC_CONFIG_LM_BIT = 12,
-+ MAC_CONFIG_DM_BIT = 11,
-+ MAC_CONFIG_IPC_BIT = 10,
-+ MAC_CONFIG_DR_BIT = 9,
-+ MAC_CONFIG_ACS_BIT = 7,
-+ MAC_CONFIG_BL_BIT = 5,
-+ MAC_CONFIG_DC_BIT = 4,
-+ MAC_CONFIG_TE_BIT = 3,
-+ MAC_CONFIG_RE_BIT = 2
-+} gmac_config_reg_t;
-+
-+#define MAC_CONFIG_IFG_NUM_BITS 3
-+#define MAC_CONFIG_BL_NUM_BITS 2
-+
-+typedef enum gmac_frame_filter_reg {
-+ MAC_FRAME_FILTER_RA_BIT = 31,
-+ MAC_FRAME_FILTER_SAF_BIT = 9,
-+ MAC_FRAME_FILTER_SAIF_BIT = 8,
-+ MAC_FRAME_FILTER_PCF_BIT = 6,
-+ MAC_FRAME_FILTER_DBF_BIT = 5,
-+ MAC_FRAME_FILTER_PM_BIT = 4,
-+ MAC_FRAME_FILTER_DAIF_BIT = 3,
-+ MAC_FRAME_FILTER_HMC_BIT = 2,
-+ MAC_FRAME_FILTER_HUC_BIT = 1,
-+ MAC_FRAME_FILTER_PR_BIT = 0
-+} gmac_frame_filter_reg_t;
-+
-+#define MAC_FRAME_FILTER_PCF_NUM_BITS 2
-+
-+typedef enum gmac_hash_table_high_reg {
-+ MAC_HASH_HIGH_HTH_BIT = 0
-+} gmac_hash_table_high_reg_t;
-+
-+typedef enum gmac_hash_table_low_reg {
-+ MAC_HASH_LOW_HTL_BIT = 0
-+} gmac_hash_table_low_reg_t;
-+
-+typedef enum gmac_gmii_address_reg {
-+ MAC_GMII_ADR_PA_BIT = 11,
-+ MAC_GMII_ADR_GR_BIT = 6,
-+ MAC_GMII_ADR_CR_BIT = 2,
-+ MAC_GMII_ADR_GW_BIT = 1,
-+ MAC_GMII_ADR_GB_BIT = 0
-+} gmac_gmii_address_reg_t;
-+
-+#define MAC_GMII_ADR_PA_NUM_BITS 5
-+#define MAC_GMII_ADR_GR_NUM_BITS 5
-+#define MAC_GMII_ADR_CR_NUM_BITS 3
-+
-+typedef enum gmac_gmii_data_reg {
-+ MAC_GMII_DATA_GD_BIT = 0
-+} gmac_gmii_data_reg_t;
-+
-+#define MAC_GMII_DATA_GD_NUM_BITS 16
-+
-+typedef enum gmac_flow_control_reg {
-+ MAC_FLOW_CNTL_PT_BIT = 16,
-+ MAC_FLOW_CNTL_PLT_BIT = 4,
-+ MAC_FLOW_CNTL_UP_BIT = 3,
-+ MAC_FLOW_CNTL_RFE_BIT = 2,
-+ MAC_FLOW_CNTL_TFE_BIT = 1,
-+ MAC_FLOW_CNTL_FCB_BPA_BIT = 0
-+} gmac_flow_control_reg_t;
-+
-+#define MAC_FLOW_CNTL_PT_NUM_BITS 16
-+#define MAC_FLOW_CNTL_PLT_NUM_BITS 2
-+
-+typedef enum gmac_vlan_tag_reg {
-+ MAC_VLAN_TAG_LV_BIT = 0
-+} gmac_vlan_tag_reg_t;
-+
-+#define MAC_VLAN_TAG_LV_NUM_BITS 16
-+
-+typedef enum gmac_version_reg {
-+ MAC_VERSION_UD_BIT = 8,
-+ MAC_VERSION_SD_BIT = 0
-+} gmac_version_reg_t;
-+
-+#define MAC_VERSION_UD_NUM_BITS 8
-+#define MAC_VERSION_SD_NUM_BITS 8
-+
-+typedef enum gmac_mac_adr_0_high_reg {
-+ MAC_ADR0_HIGH_MO_BIT = 31,
-+ MAC_ADR0_HIGH_A_BIT = 0
-+} gmac_mac_adr_0_high_reg_t;
-+
-+#define MAC_ADR0_HIGH_A_NUM_BITS 16
-+
-+typedef enum gmac_mac_adr_0_low_reg {
-+ MAC_ADR0_LOW_A_BIT = 0
-+} gmac_mac_adr_0_low_reg_t;
-+
-+typedef enum gmac_mac_adr_1_high_reg {
-+ MAC_ADR1_HIGH_AE_BIT = 31,
-+ MAC_ADR1_HIGH_SA_BIT = 30,
-+ MAC_ADR1_HIGH_MBC_BIT = 24,
-+ MAC_ADR1_HIGH_A_BIT = 0
-+} gmac_mac_adr_1_high_reg_t;
-+
-+#define MAC_ADR1_HIGH_MBC_NUM_BITS 6
-+#define MAC_ADR1_HIGH_A_NUM_BITS 16
-+
-+typedef enum gmac_mac_adr_1_low_reg {
-+ MAC_ADR1_LOW_A_BIT = 0
-+} gmac_mac_adr_1_low_reg_t;
-+
-+
-+/**
-+ * MMC register indices - registers accessed via the MAC accessor functions
-+ */
-+typedef enum gmac_mmc_regs {
-+ MMC_CONTROL_REG = 64,
-+ MMC_RX_INT_REG = 65,
-+ MMC_TX_INT_REG = 66,
-+ MMC_RX_MASK_REG = 67,
-+ MMC_TX_MASK_REG = 68
-+} gmac_mmc_regs_t;
-+
-+
-+/**
-+ * DMA register indices
-+ */
-+typedef enum gmac_dma_regs {
-+ DMA_BUS_MODE_REG = 0,
-+ DMA_TX_POLL_REG = 1,
-+ DMA_RX_POLL_REG = 2,
-+ DMA_RX_DESC_ADR_REG = 3,
-+ DMA_TX_DESC_ADR_REG = 4,
-+ DMA_STATUS_REG = 5,
-+ DMA_OP_MODE_REG = 6,
-+ DMA_INT_ENABLE_REG = 7,
-+ DMA_MISSED_OVERFLOW_REG = 8,
-+ DMA_CUR_TX_DESC_REG = 18,
-+ DMA_CUR_RX_DESC_REG = 19,
-+ DMA_CUR_TX_ADR_REG = 20,
-+ DMA_CUR_RX_ADR_REG = 21
-+} gmac_dma_regs_t;
-+
-+
-+/**
-+ * DMA register field definitions
-+ */
-+
-+typedef enum gmac_dma_bus_mode_reg {
-+ DMA_BUS_MODE_FB_BIT = 16,
-+ DMA_BUS_MODE_PR_BIT = 14,
-+ DMA_BUS_MODE_PBL_BIT = 8,
-+ DMA_BUS_MODE_DSL_BIT = 2,
-+ DMA_BUS_MODE_DA_BIT = 1,
-+ DMA_BUS_MODE_SWR_BIT = 0
-+} gmac_dma_bus_mode_reg_t;
-+
-+#define DMA_BUS_MODE_PR_NUM_BITS 2
-+#define DMA_BUS_MODE_PBL_NUM_BITS 6
-+#define DMA_BUS_MODE_DSL_NUM_BITS 5
-+
-+typedef enum gmac_dma_tx_poll_demand_reg {
-+ DMA_TX_POLL_TPD_BIT = 0
-+} gmac_dma_tx_poll_demand_reg_t;
-+
-+typedef enum gmac_dma_rx_poll_demand_reg {
-+ DMA_RX_POLL_RPD_BIT = 0
-+} gmac_dma_rx_poll_demand_reg_t;
-+
-+typedef enum gmac_dma_rx_desc_list_adr_reg {
-+ DMA_RX_DESC_ADR_SRL_BIT = 0
-+} gmac_dma_rx_desc_list_adr_reg_t;
-+
-+typedef enum gmac_dma_tx_desc_list_adr_reg {
-+ DMA_TX_DESC_ADR_STL_BIT = 0
-+} gmac_dma_tx_desc_list_adr_reg_t;
-+
-+typedef enum gmac_dma_status_reg {
-+ DMA_STATUS_GPI_BIT = 28,
-+ DMA_STATUS_GMI_BIT = 27,
-+ DMA_STATUS_GLI_BIT = 26,
-+ DMA_STATUS_EB_BIT = 23,
-+ DMA_STATUS_TS_BIT = 20,
-+ DMA_STATUS_RS_BIT = 17,
-+ DMA_STATUS_NIS_BIT = 16,
-+ DMA_STATUS_AIS_BIT = 15,
-+ DMA_STATUS_ERI_BIT = 14,
-+ DMA_STATUS_FBE_BIT = 13,
-+ DMA_STATUS_ETI_BIT = 10,
-+ DMA_STATUS_RWT_BIT = 9,
-+ DMA_STATUS_RPS_BIT = 8,
-+ DMA_STATUS_RU_BIT = 7,
-+ DMA_STATUS_RI_BIT = 6,
-+ DMA_STATUS_UNF_BIT = 5,
-+ DMA_STATUS_OVF_BIT = 4,
-+ DMA_STATUS_TJT_BIT = 3,
-+ DMA_STATUS_TU_BIT = 2,
-+ DMA_STATUS_TPS_BIT = 1,
-+ DMA_STATUS_TI_BIT = 0
-+} gmac_dma_status_reg_t;
-+
-+#define DMA_STATUS_EB_NUM_BITS 3
-+#define DMA_STATUS_TS_NUM_BITS 3
-+#define DMA_STATUS_RS_NUM_BITS 3
-+
-+typedef enum gmac_dma_status_ts_val {
-+ DMA_STATUS_TS_CLOSING = 7,
-+ DMA_STATUS_TS_SUSPENDED = 6,
-+ DMA_STATUS_TS_RESERVED = 5,
-+ DMA_STATUS_TS_FLUSHING = 4,
-+ DMA_STATUS_TS_READING = 3,
-+ DMA_STATUS_TS_WAITING = 2,
-+ DMA_STATUS_TS_FETCHING = 1,
-+ DMA_STATUS_TS_STOPPED = 0
-+} gmac_dma_status_ts_val_t;
-+
-+typedef enum gmac_dma_op_mode_reg {
-+ DMA_OP_MODE_DT_BIT = 26,
-+ DMA_OP_MODE_RSF_BIT = 25,
-+ DMA_OP_MODE_DFF_BIT = 24,
-+ DMA_OP_MODE_RFA2_BIT = 23,
-+ DMA_OP_MODE_RFD2_BIT = 22,
-+ DMA_OP_MODE_SF_BIT = 21,
-+ DMA_OP_MODE_FTF_BIT = 20,
-+ DMA_OP_MODE_TTC_BIT = 14,
-+ DMA_OP_MODE_ST_BIT = 13,
-+ DMA_OP_MODE_RFD_BIT = 11,
-+ DMA_OP_MODE_RFA_BIT = 9,
-+ DMA_OP_MODE_EFC_BIT = 8,
-+ DMA_OP_MODE_FEF_BIT = 7,
-+ DMA_OP_MODE_FUF_BIT = 6,
-+ DMA_OP_MODE_RTC_BIT = 3,
-+ DMA_OP_MODE_OSF_BIT = 2,
-+ DMA_OP_MODE_SR_BIT = 1
-+} gmac_dma_op_mode_reg_t;
-+
-+#define DMA_OP_MODE_TTC_NUM_BITS 3
-+
-+typedef enum gmac_dma_op_mode_ttc_val {
-+ DMA_OP_MODE_TTC_16 = 7,
-+ DMA_OP_MODE_TTC_24 = 6,
-+ DMA_OP_MODE_TTC_32 = 5,
-+ DMA_OP_MODE_TTC_40 = 4,
-+ DMA_OP_MODE_TTC_256 = 3,
-+ DMA_OP_MODE_TTC_192 = 2,
-+ DMA_OP_MODE_TTC_128 = 1,
-+ DMA_OP_MODE_TTC_64 = 0
-+} gmac_dma_op_mode_ttc_val_t;
-+
-+#define DMA_OP_MODE_RFD_NUM_BITS 2
-+#define DMA_OP_MODE_RFA_NUM_BITS 2
-+#define DMA_OP_MODE_RTC_NUM_BITS 2
-+
-+typedef enum gmac_dma_op_mode_rtc_val {
-+ DMA_OP_MODE_RTC_128 = 3,
-+ DMA_OP_MODE_RTC_96 = 2,
-+ DMA_OP_MODE_RTC_32 = 1,
-+ DMA_OP_MODE_RTC_64 = 0
-+} gmac_dma_op_mode_rtc_val_t;
-+
-+typedef enum gmac_dma_intr_enable_reg {
-+ DMA_INT_ENABLE_NI_BIT = 16,
-+ DMA_INT_ENABLE_AI_BIT = 15,
-+ DMA_INT_ENABLE_ERE_BIT = 14,
-+ DMA_INT_ENABLE_FBE_BIT = 13,
-+ DMA_INT_ENABLE_ETE_BIT = 10,
-+ DMA_INT_ENABLE_RW_BIT = 9,
-+ DMA_INT_ENABLE_RS_BIT = 8,
-+ DMA_INT_ENABLE_RU_BIT = 7,
-+ DMA_INT_ENABLE_RI_BIT = 6,
-+ DMA_INT_ENABLE_UN_BIT = 5,
-+ DMA_INT_ENABLE_OV_BIT = 4,
-+ DMA_INT_ENABLE_TJ_BIT = 3,
-+ DMA_INT_ENABLE_TU_BIT = 2,
-+ DMA_INT_ENABLE_TS_BIT = 1,
-+ DMA_INT_ENABLE_TI_BIT = 0
-+} gmac_dma_intr_enable_reg_t;
-+
-+typedef enum gmac_dma_missed_overflow_reg {
-+ DMA_MISSED_OVERFLOW_OFOC_BIT = 28, // Overflow bit for FIFO Overflow Counter
-+ DMA_MISSED_OVERFLOW_AMFC_BIT = 17, // Application Missed Frames Count
-+ DMA_MISSED_OVERFLOW_OAMFO_BIT = 16, // Overflow bit for Application Missed Frames Count
-+ DMA_MISSED_OVERFLOW_CMFC_BIT = 0 // Controller Missed Frames Count
-+} gmac_dma_missed_overflow_reg_t;
-+
-+#define DMA_MISSED_OVERFLOW_OAMFO_NUM_BITS 11
-+#define DMA_MISSED_OVERFLOW_CMFC_NUM_BITS 16
-+
-+typedef enum gmac_dma_current_tx_desc_reg {
-+ DMA_CUR_TX_DESC_A_BIT = 0
-+} gmac_dma_current_tx_desc_reg_t;
-+
-+typedef enum gmac_dma_current_rx_desc_reg {
-+ DMA_CUR_RX_DESC_A_BIT = 0
-+} gmac_dma_current_rx_desc_reg_t;
-+
-+typedef enum gmac_dma_current_tx_adr_reg {
-+ DMA_CUR_TX_ADR_A_BIT = 0
-+} gmac_dma_current_tx_adr_reg_t;
-+
-+typedef enum gmac_dma_current_rx_adr_reg {
-+ DMA_CUR_RX_ADR_A_BIT = 0
-+} gmac_dma_current_rx_adr_reg_t;
-+
-+#endif // #if !defined(__GMAC_REG_H__)
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gpioTest.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/gpioTest.c
---- linux-2.6.24/arch/arm/mach-oxnas/gpioTest.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gpioTest.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,657 @@
-+#include <asm/io.h>
-+#include <asm/bitops.h>
-+#include <asm/uaccess.h> // copy_to_user and copy_from_user
-+#include <linux/init.h> // modules
-+#include <linux/module.h> // module
-+#include <linux/types.h> // dev_t type
-+#include <linux/fs.h> // chrdev allocation
-+#include <linux/slab.h> // kmalloc and kfree
-+#include <linux/cdev.h> // struct cdev
-+#include <linux/errno.h> // error codes
-+#include <linux/interrupt.h>
-+#include <linux/delay.h>
-+#include <asm/arch/hardware.h>
-+
-+MODULE_LICENSE("GPL v2");
-+
-+MODULE_AUTHOR("C Ford");
-+MODULE_DESCRIPTION("gpioTest first version");
-+
-+struct gpioTest_dev {
-+ struct semaphore sem; // Mutual exclusion semaphore
-+ struct cdev cdev; // Char device structure
-+ int found;
-+};
-+
-+struct gpioTest_dev * gpioTest_device; // Contains the gpioTest devices
-+
-+dev_t dev; // Contains major and first minor number
-+static wait_queue_head_t ir_block;
-+
-+////////////////////////////
-+// LINKED LIST OPERATIONS //
-+////////////////////////////
-+
-+
-+///////////////
-+// CALLBACKS //
-+///////////////
-+
-+#define GPIO_TEST_SCL (1UL << CONFIG_OXNAS_I2C_SCL)
-+#define GPIO_TEST_SDA (1UL << CONFIG_OXNAS_I2C_SDA)
-+
-+void DumpGPIO( void )
-+{
-+ printk( KERN_INFO "================= GPIO Dump\n"
-+ " GPIO_A_DATA 0x%08x\n"
-+ " GPIO_A_OUTPUT_ENABLE 0x%08x\n"
-+ " GPIO_A_INTERRUPT_ENABLE 0x%08x\n"
-+ " GPIO_A_INTERRUPT_EVENT 0x%08x\n"
-+ " GPIO_A_OUTPUT_VALUE 0x%08x\n"
-+ " GPIO_A_OUTPUT_SET 0x%08x\n"
-+ " GPIO_A_OUTPUT_CLEAR 0x%08x\n"
-+ " GPIO_A_OUTPUT_ENABLE_SET 0x%08x\n"
-+ " GPIO_A_OUTPUT_ENABLE_CLEAR 0x%08x\n"
-+ " GPIO_A_INPUT_DEBOUNCE_ENABLE 0x%08x\n"
-+ " GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE 0x%08x\n"
-+ " GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE 0x%08x\n"
-+ " GPIO_A_RISING_EDGE_DETECT 0x%08x\n"
-+ " GPIO_A_FALLING_EDGE_DETECT 0x%08x\n"
-+ " GPIO_A_LEVEL_INTERRUPT_ENABLE 0x%08x\n"
-+ " GPIO_A_INTERRUPT_STATUS_REGISTER 0x%08x\n",
-+ readl( GPIO_A_DATA ),
-+ readl( GPIO_A_OUTPUT_ENABLE ),
-+ readl( GPIO_A_INTERRUPT_ENABLE ),
-+ readl( GPIO_A_INTERRUPT_EVENT ),
-+ readl( GPIO_A_OUTPUT_VALUE ),
-+ readl( GPIO_A_OUTPUT_SET ),
-+ readl( GPIO_A_OUTPUT_CLEAR ),
-+ readl( GPIO_A_OUTPUT_ENABLE_SET ),
-+ readl( GPIO_A_OUTPUT_ENABLE_CLEAR ),
-+ readl( GPIO_A_INPUT_DEBOUNCE_ENABLE ),
-+ readl( GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ),
-+ readl( GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ),
-+ readl( GPIO_A_RISING_EDGE_DETECT ),
-+ readl( GPIO_A_FALLING_EDGE_DETECT ),
-+ readl( GPIO_A_LEVEL_INTERRUPT_ENABLE ),
-+ readl( GPIO_A_INTERRUPT_STATUS_REGISTER ) );
-+
-+}
-+
-+irqreturn_t irqHandler( int irq, void* dev_id)
-+{
-+ // is this interrupt fors us??
-+ struct gpioTest_dev* pGPIO = (struct gpioTest_dev*) dev_id;
-+ unsigned int temp = readl( (volatile unsigned long *) GPIO_A_INTERRUPT_STATUS_REGISTER );
-+
-+ if ( !(temp & (GPIO_TEST_SCL | GPIO_TEST_SDA) ) )
-+ {
-+ printk("Not for us...\n");
-+ return IRQ_NONE;
-+ }
-+
-+ // apparantly it is, for simplicity, we will stop the intterupting pin,
-+ // and clear its source, then signal the bottmo half to continue
-+ if ( test_bit( CONFIG_OXNAS_I2C_SCL, (volatile unsigned long *) &temp ) )
-+ {
-+ printk("Int Found CONFIG_OXNAS_I2C_SCL\n");
-+ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) &= ~(1UL << CONFIG_OXNAS_I2C_SCL);
-+ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) &= ~(1UL << CONFIG_OXNAS_I2C_SCL);
-+ *( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE ) &= ~(1UL << CONFIG_OXNAS_I2C_SCL);
-+ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_DETECT ) &= ~(1UL << CONFIG_OXNAS_I2C_SCL);
-+ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_DETECT ) &= ~(1UL << CONFIG_OXNAS_I2C_SCL);
-+ pGPIO->found |= GPIO_TEST_SCL;
-+ }
-+
-+ if ( test_bit( CONFIG_OXNAS_I2C_SDA, (volatile unsigned long *) &temp ) )
-+ {
-+ printk("Int Found CONFIG_OXNAS_I2C_SDA\n");
-+ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) &= ~(1UL << CONFIG_OXNAS_I2C_SDA);
-+ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) &= ~(1UL << CONFIG_OXNAS_I2C_SDA);
-+ *( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE ) &= ~(1UL << CONFIG_OXNAS_I2C_SDA);
-+ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_DETECT ) &= ~(1UL << CONFIG_OXNAS_I2C_SDA);
-+ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_DETECT ) &= ~(1UL << CONFIG_OXNAS_I2C_SDA);
-+ pGPIO->found |= GPIO_TEST_SDA;
-+ }
-+
-+ if ( pGPIO->found )
-+ {
-+ printk("Int cleared\n");
-+ wake_up_interruptible(&ir_block);
-+ }
-+
-+ return IRQ_HANDLED;
-+}
-+
-+int gpioTest_go(void)
-+{
-+ unsigned long flags;
-+ unsigned int temp;
-+ unsigned int i;
-+
-+ //assert( CONFIG_OXNAS_I2C_SDA < CONFIG_OXNAS_I2C_SCL );
-+
-+ printk( KERN_ERR "****************************************************************\n");
-+ printk( KERN_ERR "************************************************** gpioTest_go:\n");
-+ printk( KERN_ERR "Please connect I2c SDA to I2C SCLK, and optionally attach scope:\n\n");
-+
-+ printk( KERN_ERR "Test 1: setup all inputs (and check for pull up res)\n");
-+
-+ // Setting lines to GPIO
-+ *( (volatile unsigned long *) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) &= ~(1UL << (CONFIG_OXNAS_I2C_SDA & 0x0000001F) );
-+ *( (volatile unsigned long *) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) &= ~(1UL << (CONFIG_OXNAS_I2C_SCL & 0x0000001F) );
-+
-+ *( (volatile unsigned long *) SYS_CTRL_GPIO_SECSEL_CTRL_0 ) &= ~(1UL << (CONFIG_OXNAS_I2C_SDA & 0x0000001F) );
-+ *( (volatile unsigned long *) SYS_CTRL_GPIO_SECSEL_CTRL_0 ) &= ~(1UL << (CONFIG_OXNAS_I2C_SCL & 0x0000001F) );
-+
-+// Setting lines to Input
-+/*
-+temp = readl( GPIO_A_OUTPUT_ENABLE );
-+temp |= (GPIO_TEST_SCL | GPIO_TEST_SDA | GPIO_TEST_SCS);
-+writel( temp, GPIO_A_OUTPUT_ENABLE );
-+for (i=0; i<65000; ++i)
-+{
-+ temp = (i & 0x00000007) << CONFIG_OXNAS_I2C_SCL;
-+ flags = readl( GPIO_A_OUTPUT_VALUE );
-+ flags &= ~(GPIO_TEST_SCL | GPIO_TEST_SDA | GPIO_TEST_SCS);
-+ flags |= temp;
-+ writel( flags, GPIO_A_OUTPUT_VALUE );
-+ printk( "reads 0x%08x ",readl( GPIO_A_DATA ) );
-+ udelay(100);
-+ printk( " 0x%08x\n",readl( GPIO_A_DATA ) );
-+
-+}
-+*/
-+DumpGPIO();
-+ // Setting lines to Input
-+ temp = readl( GPIO_A_OUTPUT_ENABLE );
-+ temp &= ~(GPIO_TEST_SCL | GPIO_TEST_SDA);
-+ writel( temp, GPIO_A_OUTPUT_ENABLE );
-+ udelay(1);
-+ if ( *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE) & (1UL << CONFIG_OXNAS_I2C_SDA) ||
-+ *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE) & (1UL << CONFIG_OXNAS_I2C_SCL))
-+ {
-+ printk( KERN_ERR "Test 1: Failed to clear GPIO Output Enable register)\n");
-+ return -1;
-+ }
-+
-+ udelay(1);
-+ // read the input value: it should be one due to the pull up
-+ if ( !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
-+ !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) ))
-+ {
-+ printk( KERN_ERR "Test 1: Failed to read 1 on the input(check for pull up res.))\n");
-+ return -1;
-+ }
-+
-+ printk( KERN_ERR "===== Passed Test 1 ======= Created GPIO inputs, and read correct values\n");
-+
-+ // Test 2: set output using direct setting, first set the output latches to zero on all lines
-+ printk( KERN_ERR "Test 2: output testing and OE testing\n");
-+ *( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR ) |= (1UL << (CONFIG_OXNAS_I2C_SDA & 0x0000001F) );
-+ *( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR ) |= (1UL << (CONFIG_OXNAS_I2C_SCL & 0x0000001F) );
-+ for (i=CONFIG_OXNAS_I2C_SCL; i<=CONFIG_OXNAS_I2C_SDA; ++i)
-+ {
-+ // from all input, set output using direct write. Assume all input at start.
-+ temp = readl( GPIO_A_OUTPUT_ENABLE );
-+ temp |= ((0x00000001) << i);
-+ writel( temp, GPIO_A_OUTPUT_ENABLE );
-+
-+ udelay(1);
-+ if ( ( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
-+ ( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) ))
-+ {
-+ printk( KERN_ERR "Test 2: Failed to read 0 on the %d input (output enabled with direct write.))\n", i);
-+ return -1;
-+ }
-+
-+ // Setting lines to Input
-+ temp = readl( GPIO_A_OUTPUT_ENABLE );
-+ temp &= ~(GPIO_TEST_SCL | GPIO_TEST_SDA);
-+ writel( temp, GPIO_A_OUTPUT_ENABLE );
-+
-+ udelay(1);
-+ if ( ( *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
-+ ( *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE) & (1UL << CONFIG_OXNAS_I2C_SCL) ) ||
-+ !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
-+ !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) ) )
-+ {
-+ printk( KERN_ERR "Test 2: Failed to reset to clean state 1)\n");
-+ return -1;
-+ }
-+
-+ // from all inputs, set an output enable usign output enable set
-+ *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_SET ) |= (1UL << i);
-+
-+ udelay(1);
-+ if ( ( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
-+ ( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) ) )
-+ {
-+ printk( KERN_ERR "Test 2: Failed to read 0 on the input %d (output enabled with direct write.))\n", i);
-+ return -1;
-+ }
-+
-+ // now exercise the setting and clearing of the output value
-+ *( (volatile unsigned long *) GPIO_A_OUTPUT_SET ) |= (1UL << i);
-+
-+ udelay(1);
-+ if ( !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
-+ !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) ) )
-+ {
-+ printk( KERN_ERR "Test 2: Failed to read 1 on the input after settin %d ahs high)\n", i);
-+ return -1;
-+ }
-+
-+ // now exercise the setting and clearing of the output value
-+ *( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR ) |= (1UL << i);
-+
-+ udelay(1);
-+ if ( ( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
-+ ( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) ) )
-+ {
-+ printk( KERN_ERR "Test 2: Failed to read 1 on the input after settin %d ahs high)\n", i);
-+ return -1;
-+ }
-+
-+ // from i as output, set all inputs , set an output enable usign output enable set
-+ *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_CLEAR ) |= (1UL << i);
-+
-+ udelay(1);
-+ if ( temp != readl( GPIO_A_OUTPUT_ENABLE ) ||
-+ ( *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
-+ ( *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE) & (1UL << CONFIG_OXNAS_I2C_SCL) ) ||
-+ !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
-+ !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) ) )
-+ {
-+ printk( KERN_ERR "Test 2: Failed to reset to clean state 2)\n");
-+ return -1;
-+ }
-+ }
-+
-+ printk( KERN_ERR "===== Passed Test 2 ======= Used all Set and clear methods for both OE and OV\n");
-+
-+ // Test 3, now exercise the interrupt.
-+ printk( KERN_ERR "Test 3: Interrupt testing\n");
-+ init_waitqueue_head(&ir_block);
-+
-+ request_irq(
-+ (int) GPIO_1_INTERRUPT, // unsigned int irq,
-+ &irqHandler, // irqreturn_t (*handler)(int, void *, struct pt_regs *),
-+ IRQF_SHARED, // unsigned long irq_flags,
-+ "GPIO Test Module", // const char * devname,
-+ (void*) gpioTest_device ); // void * dev_id)
-+
-+
-+ // set int condiiton....
-+ for (i=CONFIG_OXNAS_I2C_SCL; i<=CONFIG_OXNAS_I2C_SDA; ++i)
-+ {
-+ int tmo;
-+ int drv = i+1 > CONFIG_OXNAS_I2C_SDA ? CONFIG_OXNAS_I2C_SCL : i+1; // BHC - This is rubbish, there's no contract saying SDA has to be on a higher numbered GPIO than SCL
-+
-+
-+ // ================================================= level detect
-+ // set an interrupt on i being high-level
-+ printk( KERN_INFO "Test %d level int High against OP %d\n", i, drv);
-+ local_irq_save(flags);
-+ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) |= (1UL << i);
-+ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) &= ~(1UL << i);
-+ *( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE ) |= (1UL << i);
-+ *( (volatile unsigned long *) GPIO_A_INTERRUPT_EVENT ) |= (1UL << i);
-+ gpioTest_device->found = 0;
-+ local_irq_restore(flags);
-+
-+ tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
-+printk("tmo1 == 0x%08x / 0x%08x\n", tmo, 1*HZ );
-+ if ( !(gpioTest_device->found & ((0x00000001 << i))) )
-+ {
-+
-+ printk( KERN_ERR "$R FAILED Test 3 timed out 1 sec with no interrupt "
-+ "While waiting for level high int....\n");
-+ return -1;
-+ }
-+
-+ // Next try setting the lines low, and ensure that the devices times out
-+ local_irq_save(flags);
-+ *( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR ) |= (1UL << drv);
-+ *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_SET ) |= (1UL << drv);
-+ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) |= (1UL << i);
-+ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) &= ~(1UL << i);
-+ *( (volatile unsigned long *) GPIO_A_INTERRUPT_EVENT ) |= (1UL << i);
-+ *( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE ) |= (1UL << i);
-+ gpioTest_device->found = 0;
-+
-+ local_irq_restore(flags);
-+ tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
-+printk("tmo2 == 0x%08x\n", tmo );
-+ if ( gpioTest_device->found )
-+ {
-+
-+ printk( KERN_ERR "$R FAILED Test 3 did not timed out "
-+ "While waiting for level high int with 0 input....\n");
-+ return -1;
-+ }
-+
-+ // set the int acive low level now.
-+ printk( KERN_INFO "Test %d level int Low against OP %d\n", i, drv);
-+ local_irq_save(flags);
-+ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) &= ~(1UL << i);
-+ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) |= (1UL << i);
-+ *( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE ) |= (1UL << i);
-+ *( (volatile unsigned long *) GPIO_A_INTERRUPT_EVENT ) |= (1UL << i);
-+ gpioTest_device->found = 0;
-+
-+ local_irq_restore(flags);
-+ tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
-+printk("tmo3 == 0x%08x / 0x%08x\n", tmo, 1*HZ );
-+ if ( !(gpioTest_device->found & ((0x00000001 << i))) )
-+ {
-+
-+ printk( KERN_ERR "$R FAILED Test 3 timed out 1 sec with no interrupt "
-+ "While waiting for level low int....\n");
-+ return -1;
-+ }
-+
-+ // Next try setting the lines high, and ensure that the devices times out
-+ *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_CLEAR ) |= ~(1UL << drv);
-+ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) &= ~(1UL << i);
-+ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) |= (1UL << i);
-+ *( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE ) |= (1UL << i);
-+ *( (volatile unsigned long *) GPIO_A_INTERRUPT_EVENT ) |= (1UL << i);
-+ gpioTest_device->found = 0;
-+
-+ local_irq_restore(flags);
-+ tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
-+printk("tmo4 == 0x%08x\n", tmo );
-+ if ( gpioTest_device->found )
-+ {
-+
-+ printk( KERN_ERR "$R FAILED Test 3 did not timed out "
-+ "While waiting for level low int with 1 input....\n");
-+ return -1;
-+ }
-+
-+ // Setting lines to Input --------------------------------------
-+ temp = readl( GPIO_A_OUTPUT_ENABLE );
-+ temp &= ~(GPIO_TEST_SCL | GPIO_TEST_SDA);
-+ writel( temp, GPIO_A_OUTPUT_ENABLE );
-+ // ================================================= Edge detect
-+
-+ // set an interrupt on i being high-level
-+ local_irq_save(flags);
-+ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) |= (1UL << i);
-+ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) &= ~(1UL << i);
-+ *( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE ) &= ~(1UL << i);
-+ *( (volatile unsigned long *) GPIO_A_INTERRUPT_EVENT ) |= (1UL << i);
-+ gpioTest_device->found = 0;
-+
-+ printk( KERN_INFO "Test %d rising edge int High against falling edge on OP %d\n", i, drv);
-+ local_irq_restore(flags);
-+
-+ *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_SET ) |= (1UL << drv);
-+ *( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR ) |= (1UL << drv);
-+ tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
-+ if ( gpioTest_device->found || tmo )
-+ {
-+
-+ printk( KERN_ERR "$R FAILED Test 3 found int on %d falling edge, when set to rising...\n", i);
-+ return -1;
-+ }
-+
-+ // now do th rising edge...
-+ *( (volatile unsigned long *) GPIO_A_OUTPUT_SET ) |= (1UL << drv);
-+
-+ tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
-+ if ( !(gpioTest_device->found & (0x00000001 << i)) || (tmo == 0) )
-+ {
-+
-+ printk( KERN_ERR "$R FAILED Test 3 did not find int on %d rising edge, when set to rising...\n", i);
-+ return -1;
-+ }
-+
-+ // set the int acive low level now.
-+ local_irq_save(flags);
-+
-+ *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_SET ) |= (1UL << drv);
-+ *( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR ) |= (1UL << drv);
-+
-+ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) &= ~(1UL << i);
-+ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) |= (1UL << i);
-+ *( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE ) &= ~(1UL << i);
-+ *( (volatile unsigned long *) GPIO_A_INTERRUPT_EVENT ) |= (1UL << i);
-+ gpioTest_device->found = 0;
-+
-+ printk( KERN_INFO "Test %d falling edge int against rising edge on OP %d\n", i, drv);
-+ local_irq_restore(flags);
-+
-+ *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_SET ) |= (1UL << drv);
-+ *( (volatile unsigned long *) GPIO_A_OUTPUT_SET ) |= (1UL << drv);
-+ tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
-+ if ( gpioTest_device->found || tmo )
-+ {
-+
-+ printk( KERN_ERR "$R FAILED Test 3 found int on %d falling edge, when set to rising...\n", i);
-+ return -1;
-+ }
-+
-+ // now do th rising edge...
-+ *( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR) |= (1UL << drv);
-+
-+ tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
-+ if ( !(gpioTest_device->found & (0x00000001 << i)) || (tmo == 0) )
-+ {
-+
-+ printk( KERN_ERR "$R FAILED Test 3 did not find int on %d rising edge, when set to rising...\n", i);
-+ return -1;
-+ }
-+
-+
-+
-+ // Setting lines to Input --------------------------------------
-+ temp = readl( GPIO_A_OUTPUT_ENABLE );
-+ temp &= ~(GPIO_TEST_SCL | GPIO_TEST_SDA);
-+ writel( temp, GPIO_A_OUTPUT_ENABLE );
-+ }
-+
-+
-+ printk("$G All gpiuo tests passed.\n");
-+
-+ return 0;
-+}
-+
-+
-+/*
-+Read callback:
-+-> filp, contains the device in its private data
-+-> buf, the buffer in userspace
-+-> count, amount of that to be read
-+-> f_pos, the starting point of the data
-+-> return:number of bytes read
-+*/
-+ssize_t gpioTest_read(struct file *filp, char __user *buf, size_t count,loff_t *f_pos){
-+// dev was stored in filp during the open call.
-+// struct gpioTest_dev *dev = filp->private_data;
-+
-+ printk( KERN_ERR "gpioTest_read:\n");
-+
-+// Copy this quantum (from the offset, to the end of this quantum)
-+// to userspace
-+// if(copy_to_user(buf, dptr->data[s_pos] + q_pos, count)){
-+// retval = -EFAULT;
-+// goto out;
-+// }
-+
-+// Update the file offset
-+// *f_pos += count;
-+// retval = count;
-+// out:
-+// up(&dev->sem);
-+ return 0;
-+}
-+
-+/*
-+Write callback
-+-> filp, contains the device in its private data
-+-> buf, the buffer in userspace
-+-> count, amount of that to be written
-+-> f_pos, the starting point of the data
-+-> return:number of bytes written
-+*/
-+ssize_t gpioTest_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos){
-+
-+// struct gpioTest_dev *dev = filp->private_data;
-+
-+ printk( KERN_ERR "gpioTest_write:\n");
-+
-+
-+ // Copy the data to be written from userspace
-+ // if(copy_from_user(dptr->data[s_pos]+q_pos, buf, count)){
-+ // retval = -EFAULT;
-+ // }
-+ //
-+ // *f_pos+=count;
-+ // retval = count;
-+
-+ // Update the size
-+ // if(dev->size < *f_pos){
-+ // dev->size = *f_pos;
-+ // }
-+
-+// out:
-+ // up(&dev->sem);
-+ return 0;
-+}
-+
-+
-+
-+/*
-+Release callback
-+*/
-+int gpioTest_release(struct inode *inode, struct file *filp)
-+{
-+ printk( KERN_ERR "gpioTest_release:\n");
-+ return 0;
-+}
-+
-+/*
-+Open callback
-+*/
-+int gpioTest_open(struct inode *inode, struct file *filp){
-+// struct gpioTest_dev *dev;
-+
-+ printk( KERN_ERR "gpioTest_open:\n");
-+ // This macro takes a pointer to a field of type 'container_field', within
-+ // a strcture of type 'container_type' and returns a pointer to the containing
-+ // structure.
-+ // dev = container_of(inode->i_cdev, struct gpioTest_dev, cdev);
-+ // Store the pointer for future access
-+ // filp->private_data = dev;
-+
-+ return 0;
-+}
-+
-+
-+
-+
-+//////////////////
-+// MODULE STUFF //
-+//////////////////
-+
-+// File operations for this charater device
-+struct file_operations gpioTest_fops = {
-+ .owner = THIS_MODULE,
-+ //.llseek = gpioTest_llseek,
-+ .read = gpioTest_read,
-+ .write = gpioTest_write,
-+ // .ioctl = gpioTest_ioctl,
-+ .open = gpioTest_open,
-+ .release = gpioTest_release,
-+};
-+
-+
-+/*
-+ Module loading
-+*/
-+static int gpioTest_init(void){
-+
-+ // alloc_chrdev_region return 0 on success
-+ int res = alloc_chrdev_region(
-+ &dev,
-+ 0,
-+ 1,
-+ "GPIOTest");
-+
-+ printk( KERN_ERR "gpioTest_init:\n");
-+
-+ if(res){
-+ printk(KERN_WARNING "gpioTest: could not allocate device\n");
-+ return res;
-+ }else{
-+ printk(KERN_WARNING "gpioTest: registered with major number:%i\n", MAJOR(dev));
-+ }
-+
-+
-+ // Allocate memory for gpioTest_COUNT gpioTest_devices
-+ gpioTest_device = kmalloc(sizeof(struct gpioTest_dev), GFP_KERNEL);
-+ if(gpioTest_device == NULL){
-+ res = -ENOMEM;
-+ goto fail;
-+ }
-+
-+ // Fill the gpioTest_devices region with zeros
-+ memset(gpioTest_device, 0, sizeof(struct gpioTest_dev));
-+
-+ // Initialise the devices
-+
-+ // Register the cdev, gpioTest_fops contains all the defined callbacks
-+ cdev_init(&gpioTest_device->cdev,&gpioTest_fops);
-+ gpioTest_device->cdev.owner = THIS_MODULE;
-+ gpioTest_device->cdev.ops = &gpioTest_fops;
-+ res = cdev_add(&gpioTest_device->cdev,MKDEV(MAJOR(dev), MINOR(dev)) ,1);
-+ if(res){
-+ printk(KERN_NOTICE "Error %d adding gpioTest\n", res);
-+ }else{
-+ printk(KERN_NOTICE "gpioTest added\n");
-+ }
-+
-+ // perform a test
-+ res = readl( GPIO_A_INPUT_DEBOUNCE_ENABLE );
-+ res &= ~(GPIO_TEST_SCL | GPIO_TEST_SDA);
-+ writel( res, GPIO_A_INPUT_DEBOUNCE_ENABLE );
-+ if ( gpioTest_go() )
-+ {
-+ DumpGPIO();
-+ }
-+
-+ // perform a test again with debounce.
-+ res = readl( GPIO_A_INPUT_DEBOUNCE_ENABLE );
-+ res |= (GPIO_TEST_SCL | GPIO_TEST_SDA);
-+ writel( res, GPIO_A_INPUT_DEBOUNCE_ENABLE );
-+ if ( gpioTest_go() )
-+ {
-+ DumpGPIO();
-+ }
-+
-+
-+
-+ return 0;
-+
-+fail:
-+ // do cleanup;
-+ return res;
-+}
-+
-+
-+/*
-+ Module unloading
-+*/
-+static void gpioTest_exit(void){
-+ // Free the devices
-+ printk( KERN_ERR "gpioTest_exit:\n");
-+ cdev_del(&gpioTest_device->cdev);
-+ kfree(gpioTest_device);
-+ gpioTest_device = NULL;
-+ unregister_chrdev_region(dev,1);
-+}
-+
-+module_init(gpioTest_init);
-+module_exit(gpioTest_exit);
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/i2s.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/i2s.c
---- linux-2.6.24/arch/arm/mach-oxnas/i2s.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/i2s.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,352 @@
-+/*
-+ * procfs3.c - create a "file" in /proc, use the file_operation way
-+ * to manage the file.
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h> /* We're doing kernel work */
-+#include <linux/module.h> /* Specifically, a module */
-+#include <linux/proc_fs.h> /* Necessary because we use proc fs */
-+#include <asm/uaccess.h> /* for copy_*_user */
-+#include "asm/arch-oxnas/i2s.h"
-+#include "asm/io.h"
-+
-+#define DRV_NAME "i2s"
-+#define DRV_VERSION "0.1"
-+#define PROC_ENTRY_FILENAME "i2s"
-+#define PROCFS_MAX_SIZE 2048
-+
-+
-+
-+MODULE_AUTHOR("Chris Ford");
-+MODULE_DESCRIPTION("I2S Test module");
-+MODULE_LICENSE("GPL");
-+MODULE_VERSION(DRV_VERSION);
-+
-+/**
-+ * The buffer (2k) for this module
-+ *
-+ */
-+static char procfs_buffer[PROCFS_MAX_SIZE];
-+
-+/**
-+ * The size of the data hold in the buffer
-+ *
-+ */
-+static unsigned long procfs_buffer_size = 0;
-+
-+/**
-+ * The structure keeping information about the /proc file
-+ *
-+ */
-+static struct proc_dir_entry *Our_Proc_File;
-+
-+
-+void RefreshI2SRegisters(void)
-+{
-+ int iLen = sprintf( procfs_buffer,
-+ "DumpI2SRegisters----------------------------------\n"
-+ " \n"
-+ " TX_CONTROL = 0x%08x\n"
-+ " TX_SETUP = 0x%08x\n"
-+ " TX_SETUP1 = 0x%08x\n"
-+ " TX_STATUS = 0x%08x\n"
-+ " RX_CONTROL = 0x%08x\n"
-+ " RX_SETUP = 0x%08x\n"
-+ " RX_SETUP1 = 0x%08x\n"
-+ " RX_STATUS = 0x%08x\n"
-+ " TX_DEBUG = 0x%08x\n"
-+ " TX_DEBUG2 = 0x%08x\n"
-+ " TX_DEBUG3 = 0x%08x\n"
-+ " RX_DEBUG_ = 0x%08x\n"
-+ " RX_DEBUG2 = 0x%08x\n"
-+ " RX_DEBUG3 = 0x%08x\n"
-+ " TX_BUFFER_LEVEL = 0x%08x\n"
-+ " TX_BUFFER_INTERRUPT_LEVEL = 0x%08x\n"
-+ " RX_BUFFER_LEVEL = 0x%08x\n"
-+ " RX_BUFFER_INTERRUPT_LEVEL = 0x%08x\n"
-+ " RX_SPDIF_DEBUG = 0x%08x\n"
-+ " RX_SPDIF_DEBUG2 = 0x%08x\n",
-+ (u32) __raw_readl( TX_CONTROL ),
-+ (u32) __raw_readl( TX_SETUP ),
-+ (u32) __raw_readl( TX_SETUP1 ),
-+ (u32) __raw_readl( TX_STATUS ),
-+ (u32) __raw_readl( RX_CONTROL ),
-+ (u32) __raw_readl( RX_SETUP ),
-+ (u32) __raw_readl( RX_SETUP1 ),
-+ (u32) __raw_readl( RX_STATUS ),
-+ (u32) __raw_readl( TX_DEBUG ),
-+ (u32) __raw_readl( TX_DEBUG2 ),
-+ (u32) __raw_readl( TX_DEBUG3 ),
-+ (u32) __raw_readl( RX_DEBUG_ ),
-+ (u32) __raw_readl( RX_DEBUG2 ),
-+ (u32) __raw_readl( RX_DEBUG3 ),
-+ (u32) __raw_readl( TX_BUFFER_LEVEL ),
-+ (u32) __raw_readl( TX_BUFFER_INTERRUPT_LEVEL ),
-+ (u32) __raw_readl( RX_BUFFER_LEVEL ),
-+ (u32) __raw_readl( RX_BUFFER_INTERRUPT_LEVEL ),
-+ (u32) __raw_readl( RX_SPDIF_DEBUG ),
-+ (u32) __raw_readl( RX_SPDIF_DEBUG2 ) );
-+
-+ procfs_buffer_size = iLen + sprintf( procfs_buffer + iLen,
-+ " INTERRUPT_CONTROL_STATUS = 0x%08x\n"
-+ " INTERRUPT_MASK = 0x%08x\n"
-+ " VERSION = 0x%08x\n"
-+ " TX_DATA_IN_FORMAT = 0x%08x\n"
-+ " TX_CHANNELS_ENABLE = 0x%08x\n"
-+ " TX_WRITES_TO = 0x%08x\n"
-+ " RX_DATA_OUT_FORMAT = 0x%08x\n"
-+ " RX_CHANNELS_ENABLE = 0x%08x\n"
-+ " RX_READS_FROM = 0x%08x\n"
-+ " TX_CPU_DATA_WRITES_ALT = 0x%08x\n"
-+ " RX_CPU_DATA_READS_ALT = 0x%08x\n"
-+ " TX_CPU_DATA_WRITES = 0x%08x\n"
-+ " RX_CPU_DATA_READS = 0x%08x\n"
-+ "\n"
-+ "--------------------------------------------------\n",
-+ (u32) __raw_readl( INTERRUPT_CONTROL_STATUS ),
-+ (u32) __raw_readl( INTERRUPT_MASK ),
-+ (u32) __raw_readl( VERSION ),
-+ (u32) __raw_readl( TX_DATA_IN_FORMAT ),
-+ (u32) __raw_readl( TX_CHANNELS_ENABLE ),
-+ (u32) __raw_readl( TX_WRITES_TO ),
-+ (u32) __raw_readl( RX_DATA_OUT_FORMAT ),
-+ (u32) __raw_readl( RX_CHANNELS_ENABLE ),
-+ (u32) __raw_readl( RX_READS_FROM ),
-+ (u32) __raw_readl( TX_CPU_DATA_WRITES_ALT ),
-+ (u32) __raw_readl( RX_CPU_DATA_READS_ALT ),
-+ (u32) __raw_readl( TX_CPU_DATA_WRITES ),
-+ (u32) __raw_readl( RX_CPU_DATA_READS ) );
-+}
-+
-+
-+void DumpI2SRegisters(void)
-+{
-+ RefreshI2SRegisters();
-+ printk( KERN_INFO "%s", procfs_buffer );
-+ return;
-+}
-+
-+
-+/**
-+ * This funtion is called when the /proc file is read
-+ *
-+ */
-+static ssize_t procfs_read(
-+ struct file *filp, /* see include/linux/fs.h */
-+ char *buffer, /* buffer to fill with data */
-+ size_t length, /* length of the buffer */
-+ loff_t * offset)
-+{
-+ static int finished = 0;
-+
-+ /*
-+ * We return 0 to indicate end of file, that we have
-+ * no more information. Otherwise, processes will
-+ * continue to read from us in an endless loop.
-+ */
-+ if ( finished ) {
-+ printk(KERN_INFO "procfs_read: END\n");
-+ finished = 0;
-+ return 0;
-+ }
-+
-+ finished = 1;
-+
-+ /*
-+ * We use put_to_user to copy the string from the kernel's
-+ * memory segment to the memory segment of the process
-+ * that called us. get_from_user, BTW, is
-+ * used for the reverse.
-+ */
-+ if ( copy_to_user(buffer, procfs_buffer, procfs_buffer_size) ) {
-+ return -EFAULT;
-+ }
-+
-+ printk(KERN_INFO "procfs_read: read %lu bytes\n", procfs_buffer_size);
-+
-+ return procfs_buffer_size; /* Return the number of bytes "read" */
-+}
-+
-+/*
-+ * This function is called when /proc is written
-+ */
-+static ssize_t
-+procfs_write(struct file *file, const char *buffer, size_t len, loff_t * off)
-+{
-+ if ( len > PROCFS_MAX_SIZE ) {
-+ procfs_buffer_size = PROCFS_MAX_SIZE;
-+ }
-+ else {
-+ procfs_buffer_size = len;
-+ }
-+
-+ if ( copy_from_user(procfs_buffer, buffer, procfs_buffer_size) ) {
-+ return -EFAULT;
-+ }
-+
-+ printk(KERN_INFO "procfs_write: write %s\n",buffer);
-+ printk(KERN_INFO "procfs_write: write %lu bytes\n", procfs_buffer_size);
-+
-+ return procfs_buffer_size;
-+}
-+
-+/*
-+ * This function decides whether to allow an operation
-+ * (return zero) or not allow it (return a non-zero
-+ * which indicates why it is not allowed).
-+ *
-+ * The operation can be one of the following values:
-+ * 0 - Execute (run the "file" - meaningless in our case)
-+ * 2 - Write (input to the kernel module)
-+ * 4 - Read (output from the kernel module)
-+ *
-+ * This is the real function that checks file
-+ * permissions. The permissions returned by ls -l are
-+ * for referece only, and can be overridden here.
-+ */
-+
-+static int module_permission(struct inode *inode, int op, struct nameidata *foo)
-+{
-+ /*
-+ * We allow everybody to read from our module, but
-+ * only root (uid 0) may write to it
-+ */
-+ if (op == 4 || (op == 2 && current->euid == 0)) {
-+ printk( KERN_INFO "Insufficient permissions\n");
-+ return 0;
-+ }
-+
-+ /*
-+ * If it's anything else, access is denied
-+ */
-+ return -EACCES;
-+}
-+
-+/*
-+ * The file is opened - we don't really care about
-+ * that, but it does mean we need to increment the
-+ * module's reference count.
-+ */
-+int procfs_open(struct inode *inode, struct file *file)
-+{
-+ u32 temp = 0;
-+
-+ /* Open an entry on the proc filesystem */
-+ printk(KERN_INFO "I2S::procfs_open\n");
-+ try_module_get(THIS_MODULE);
-+
-+ // printk(KERN_INFO "I2S::pre-reg set..\n");
-+ // RefreshI2SRegisters();
-+
-+ /* Setup the I2S TX Core... */
-+ temp = 1 << TX_CONTROL_ENABLE |
-+ 1 << TX_CONTROL_FLUSH |
-+ 0 << TX_CONTROL_MUTE |
-+ 0 << TX_CONTROL_TRICK |
-+ 0 << TX_CONTROL_SPEED |
-+ 1 << TX_CONTROL_ABORT_DMA |
-+ 0 << TX_CONTROL_AHB_ENABLE |
-+ 1 << TX_CONTROL_QUAD_BURSTS;
-+ __raw_writel( temp, TX_CONTROL );
-+
-+ temp = TRUE_I2S << TX_SETUP_FORMAT |
-+ I2S_SLAVE << TX_SETUP_MODE |
-+ 0 << TX_SETUP_FLOW_INVERT |
-+ 0 << TX_SETUP_POS_EDGE |
-+ 0 << TX_SETUP_CLOCK_STOP |
-+ 0 << TX_SETUP_SPLIT_QUAD |
-+ 0 << TX_SETUP_SPDIF_EN;
-+ __raw_writel( temp, TX_SETUP );
-+
-+ temp = TWOS_COMPLIMENT << TX_SETUP1_INPUT |
-+ 0 << TX_SETUP1_REVERSE |
-+ 0 << TX_SETUP1_INVERT |
-+ 0 << TX_SETUP1_BIG_ENDIAN |
-+ 0 << TX_SETUP1_QUAD_ENDIAN |
-+ 0 << TX_SETUP1_QUAD_SAMPLES |
-+ 0 << TX_SETUP1_FLOW_CONTROL;
-+ __raw_writel( temp, TX_SETUP1 );
-+
-+ /* Setup the I2S RX Core... */
-+
-+ printk(KERN_INFO "\n\nI2S::post-reg set..\n");
-+ RefreshI2SRegisters();
-+ return 0;
-+}
-+
-+/*
-+ * The file is closed - again, interesting only because
-+ * of the reference count.
-+ */
-+int procfs_close(struct inode *inode, struct file *file)
-+{
-+ printk(KERN_INFO "I2S::procfs_close\n");
-+ module_put(THIS_MODULE);
-+ return 0; /* success */
-+}
-+
-+static struct file_operations File_Ops_4_Our_Proc_File = {
-+ .read = procfs_read,
-+ .write = procfs_write,
-+ .open = procfs_open,
-+ .release = procfs_close,
-+};
-+
-+/*
-+ * Inode operations for our proc file. We need it so
-+ * we'll have some place to specify the file operations
-+ * structure we want to use, and the function we use for
-+ * permissions. It's also possible to specify functions
-+ * to be called for anything else which could be done to
-+ * an inode (although we don't bother, we just put
-+ * NULL).
-+ */
-+
-+static struct inode_operations Inode_Ops_4_Our_Proc_File = {
-+ .permission = module_permission, /* check for permissions */
-+};
-+
-+/*
-+ * Module initialization and cleanup
-+ */
-+static int __init oxnas_i2s_init_module(void)
-+{
-+ printk(KERN_INFO "I2S::init_module\n");
-+
-+ /* create the /proc file */
-+ Our_Proc_File = create_proc_entry(PROC_ENTRY_FILENAME, 0644, NULL);
-+
-+ /* check if the /proc file was created successfuly */
-+ if (Our_Proc_File == NULL){
-+ printk(KERN_ALERT "Error: Could not initialize /proc/%s\n",
-+ PROC_ENTRY_FILENAME);
-+ return -ENOMEM;
-+ }
-+
-+ Our_Proc_File->owner = THIS_MODULE;
-+ Our_Proc_File->proc_iops = &Inode_Ops_4_Our_Proc_File;
-+ Our_Proc_File->proc_fops = &File_Ops_4_Our_Proc_File;
-+ Our_Proc_File->mode = S_IFREG | S_IRUGO | S_IWUSR;
-+ Our_Proc_File->uid = 0;
-+ Our_Proc_File->gid = 0;
-+ Our_Proc_File->size = 80;
-+
-+ printk(KERN_INFO "/proc/%s created\n", PROC_ENTRY_FILENAME);
-+
-+ return 0; /* success */
-+}
-+
-+static void __exit oxnas_i2s_cleanup_module(void)
-+{
-+ printk(KERN_INFO "I2S::cleanup_module\n");
-+ remove_proc_entry(PROC_ENTRY_FILENAME, &proc_root);
-+ printk(KERN_INFO "/proc/%s removed\n", PROC_ENTRY_FILENAME);
-+}
-+
-+module_init(oxnas_i2s_init_module);
-+module_exit(oxnas_i2s_cleanup_module);
-+
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/irq.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/irq.c
---- linux-2.6.24/arch/arm/mach-oxnas/irq.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/irq.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,59 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/irq.c
-+ *
-+ * 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 <linux/init.h>
-+#include <linux/list.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/mach/irq.h>
-+
-+static void OXNAS_mask_irq(unsigned int irq)
-+{
-+ *((volatile unsigned long*)(RPS_IRQ_DISABLE)) = (1UL << irq);
-+}
-+
-+static void OXNAS_unmask_irq(unsigned int irq)
-+{
-+ *((volatile unsigned long*)RPS_IRQ_ENABLE) = (1UL << irq);
-+}
-+
-+static struct irq_chip OXNAS_chip = {
-+ .name = "OXNAS",
-+ .ack = OXNAS_mask_irq,
-+ .mask = OXNAS_mask_irq,
-+ .unmask = OXNAS_unmask_irq,
-+};
-+
-+void __init oxnas_init_irq(void)
-+{
-+ unsigned irq;
-+
-+ // Disable all IRQs
-+ *((volatile unsigned long*)(RPS_IRQ_DISABLE)) = ~0UL;
-+
-+ // Disable FIQ
-+ *((volatile unsigned long*)(RPS_FIQ_DISABLE)) = ~0UL;
-+
-+ // Initialise IRQ tracking structures
-+ for (irq=0; irq < NR_IRQS; irq++)
-+ {
-+ set_irq_chip(irq, &OXNAS_chip);
-+ set_irq_handler(irq, handle_level_irq);
-+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-+ }
-+}
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/leds.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/leds.c
---- linux-2.6.24/arch/arm/mach-oxnas/leds.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/leds.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,212 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/leds.c
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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
-+ */
-+#define DEBUG
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/timer.h>
-+#include <linux/interrupt.h>
-+
-+#include <linux/platform_device.h>
-+
-+
-+#include <linux/leds.h>
-+
-+#include <asm/hardware.h>
-+
-+#define DEBUG_PRINT(A) printk(KERN_NOTICE A)
-+
-+#define writel(data,address) (*(volatile u32 *) address = data)
-+#define readl(address) (*(volatile u32 *) address)
-+
-+/* run pwm refresh at approximately 100Hz to avoid flicker */
-+/* resolution is 8bits, sys clock 200MHz divider is therefore 7812 less 1 cycle */
-+#define PWM_PERIOD (7811)
-+
-+#define MAX_PWMS 16
-+
-+static void ramp_power_on_leds(unsigned long data);
-+
-+DEFINE_TIMER (power_ramp_timer, ramp_power_on_leds, 0, 0);
-+
-+enum { POWER_ON,
-+ NUMBER_LEDS};
-+
-+static struct platform_device *oxnas_leds;
-+static u16 offset[NUMBER_LEDS] = {25};
-+
-+static u16 led [NUMBER_LEDS];
-+
-+#define MAX_BRIGHTNESS 255
-+
-+static void set_led(u16 led, u16 value)
-+{
-+ u16 led_index = offset[led] % MAX_PWMS;
-+
-+ writel(value, (PWM_DATA_REGISTER_BASE+4*led_index));
-+
-+}
-+
-+static void ramp_power_on_leds(unsigned long data)
-+{
-+ if (led[POWER_ON] < MAX_BRIGHTNESS) {
-+ set_led(POWER_ON, ++led[POWER_ON]);
-+ mod_timer(&power_ramp_timer, (power_ramp_timer.expires + msecs_to_jiffies(64)) );
-+ }
-+ else del_timer(&power_ramp_timer);
-+}
-+
-+static void oxnasled_power_on_set(struct led_classdev *led_cdev, enum led_brightness value)
-+{
-+ if (value == 0) {
-+ current_bright = 0;
-+ led[POWER_ON]=0;
-+ set_led(POWER_ON, 0);
-+
-+ }
-+ else
-+ {
-+ power_ramp_timer.expires = jiffies + msecs_to_jiffies(64);
-+ add_timer(&power_ramp_timer);
-+ }
-+}
-+
-+static struct led_classdev oxnas_power_on_led = {
-+ .name = "oxnas:power_on",
-+ .brightness_set = oxnasled_power_on_set,
-+};
-+
-+
-+#ifdef CONFIG_PM
-+
-+// TODO implement led suspend operation on NAS
-+static int oxnasled_suspend(struct platform_device *dev, pm_message_t state)
-+{
-+#ifdef CONFIG_LEDS_TRIGGERS
-+ if (oxnas_amber_led.trigger && strcmp(oxnas_amber_led.trigger->name, "sharpsl-charge"))
-+#endif
-+ led_classdev_suspend(&oxnas_amber_led);
-+ led_classdev_suspend(&oxnas_green_led);
-+ return 0;
-+}
-+// TODO implement led resume operation on NAS
-+static int oxnasled_resume(struct platform_device *dev)
-+{
-+ led_classdev_resume(&oxnas_amber_led);
-+ led_classdev_resume(&oxnas_green_led);
-+ return 0;
-+}
-+#endif
-+
-+static int oxnasled_probe(struct platform_device *pdev)
-+{
-+ int ret;
-+ int i;
-+
-+ writel(PWM_PERIOD, PWM_CLOCK_REGISTER);
-+
-+
-+ /* enable PWM drives outputs */
-+ for (i=0; i < NUMBER_LEDS ; ++i)
-+ {
-+ if (offset[i] < 32) {
-+ writel(readl(SYS_CTRL_GPIO_PWMSEL_CTRL_0) | (1 << offset[i]), SYS_CTRL_GPIO_PWMSEL_CTRL_0);
-+ }
-+ else {
-+ writel(readl(SYS_CTRL_GPIO_PWMSEL_CTRL_1) | (1 << (offset[i]% 32)), SYS_CTRL_GPIO_PWMSEL_CTRL_1);
-+ }
-+ }
-+
-+ ret = led_classdev_register(&pdev->dev, &oxnas_power_on_led);
-+
-+ if (ret < 0) goto error_1;
-+
-+ return ret;
-+
-+error_1:
-+ return ret;
-+}
-+
-+static int oxnasled_remove(struct platform_device *pdev)
-+{
-+ int i;
-+
-+ led_classdev_unregister(&oxnas_power_on_led);
-+
-+ /* disable PWM drives outputs */
-+ for (i=0; i < NUMBER_LEDS ; ++i)
-+ {
-+ if (offset[i] < 32) {
-+ writel(readl(SYS_CTRL_GPIO_PWMSEL_CTRL_0) & ~((u32)1 << offset[i]), SYS_CTRL_GPIO_PWMSEL_CTRL_0);
-+ }
-+ else {
-+ writel(readl(SYS_CTRL_GPIO_PWMSEL_CTRL_1) & ~((u32)1 << (offset[i]% 32)), SYS_CTRL_GPIO_PWMSEL_CTRL_1);
-+ }
-+ }
-+
-+ writel(PWM_CLOCK_REGISTER, 0);
-+
-+ return 0;
-+}
-+
-+
-+static struct platform_driver oxnasled_driver = {
-+ .probe = oxnasled_probe,
-+ .remove = oxnasled_remove,
-+#ifdef CONFIG_PM
-+ .suspend = oxnasled_suspend,
-+ .resume = oxnasled_resume,
-+#endif
-+ .driver = {
-+ .name = "oxnas-leds",
-+ .owner = THIS_MODULE,
-+ },
-+};
-+
-+static int __init oxnasled_init(void)
-+{
-+ int ret;
-+
-+ ret = platform_driver_register(&oxnasled_driver);
-+
-+
-+
-+ /* now register the devices on the bus so they can be associated with the driver */
-+ if (!ret)
-+ oxnas_leds=platform_device_register_simple("oxnas-leds", -1, NULL, 0);
-+ return ret;
-+}
-+
-+static void __exit oxnasled_exit(void)
-+{
-+ if (oxnas_leds) {
-+ platform_device_unregister(oxnas_leds);
-+ }
-+
-+ platform_driver_unregister(&oxnasled_driver);
-+}
-+
-+module_init(oxnasled_init);
-+module_exit(oxnasled_exit);
-+
-+MODULE_AUTHOR("John Larkworthy <john.larkworthy@oxsem.com");
-+MODULE_DESCRIPTION("OXNAS front panel LED driver");
-+MODULE_LICENSE("GPL");
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/ledtrig_sata.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/ledtrig_sata.c
---- linux-2.6.24/arch/arm/mach-oxnas/ledtrig_sata.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/ledtrig_sata.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,69 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/leds.c
-+ *
-+ * Copyright (C) 2006 Oxford Semiconductor Ltd
-+ *
-+ * 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 <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/timer.h>
-+#include <linux/leds.h>
-+
-+static void ledtrig_ide_timerfunc(unsigned long data);
-+
-+DEFINE_LED_TRIGGER(ledtrig_ide);
-+static DEFINE_TIMER(ledtrig_ide_timer, ledtrig_ide_timerfunc, 0, 0);
-+static int ide_activity;
-+static int ide_lastactivity;
-+
-+void ledtrig_sata_activity(void)
-+{
-+ ide_activity++;
-+ if (!timer_pending(&ledtrig_ide_timer))
-+ mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
-+}
-+EXPORT_SYMBOL(ledtrig_sata_activity);
-+
-+static void ledtrig_ide_timerfunc(unsigned long data)
-+{
-+ if (ide_lastactivity != ide_activity) {
-+ ide_lastactivity = ide_activity;
-+ led_trigger_event(ledtrig_ide, LED_FULL);
-+ mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
-+ } else {
-+ led_trigger_event(ledtrig_ide, LED_OFF);
-+ }
-+}
-+
-+static int __init ledtrig_ide_init(void)
-+{
-+ led_trigger_register_simple("sata-disk", &ledtrig_ide);
-+ return 0;
-+}
-+
-+static void __exit ledtrig_ide_exit(void)
-+{
-+ led_trigger_unregister_simple(ledtrig_ide);
-+}
-+
-+module_init(ledtrig_ide_init);
-+module_exit(ledtrig_ide_exit);
-+
-+MODULE_AUTHOR("John Larkworthy <john.larkworthy@oxnas.com>");
-+MODULE_DESCRIPTION("LED SATA Disk Activity Trigger");
-+MODULE_LICENSE("GPL");
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/leon.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/leon.c
---- linux-2.6.24/arch/arm/mach-oxnas/leon.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/leon.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,244 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/leon.c
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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
-+ */
-+#ifdef CONFIG_SUPPORT_LEON
-+
-+#include <asm/io.h>
-+#include <asm/types.h>
-+#include <asm/arch/hardware.h>
-+#include <linux/ctype.h>
-+#include <linux/delay.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/errno.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <asm/arch/leon.h>
-+
-+static u8 asciihex_to_decimal(u8 ascii)
-+{
-+ return isdigit(ascii) ? (ascii - '0') : (isalpha(ascii) ? ((toupper(ascii) - 'A') + 10) : 0);
-+}
-+
-+static u8 srec_read_u8(const s8** srec)
-+{
-+ u8 first_ascii = **srec;
-+ u8 second_ascii = *++*srec;
-+ ++*srec;
-+ return ((asciihex_to_decimal(first_ascii) << 4) | asciihex_to_decimal(second_ascii));
-+}
-+
-+static u32 srec_read_u32(const s8** srec)
-+{
-+ u32 word = ((u32)srec_read_u8(srec) << 24);
-+ word |= ((u32)srec_read_u8(srec) << 16);
-+ word |= ((u16)srec_read_u8(srec) << 8);
-+ word |= srec_read_u8(srec);
-+ return word;
-+}
-+
-+static void skip_to_next_record(const s8** srec)
-+{
-+ while (*++*srec != '\n');
-+ ++*srec;
-+}
-+
-+/**
-+ * @param srec An const s8** pointing to the position in the input s-record
-+ * array at which to begin parsing
-+ * @param buf An u8* into which any extracted record in to be placed
-+ * @param adr An u8** into which either the extracted record's load address is
-+ * to be written, or the execution start address
-+ * @param len An u8* into which the length in bytes of the extracted record is
-+ * to be written
-+ * @return An int which is zero if another record is available, else if non-zero
-+ * indicated that the execution start address is available in the
-+ * adr argument
-+ */
-+static void read_record(u8 len, const s8** srec, u8* buf)
-+{
-+ int quads = len/sizeof(u32);
-+ int spare = len - (quads*sizeof(u32));
-+
-+ int i=0;
-+ while (i < quads) {
-+ ((u32*)buf)[i++] = srec_read_u32(srec);
-+ }
-+ i = len-spare;
-+ while (i < len) {
-+ buf[i++] = srec_read_u8(srec);
-+ }
-+}
-+
-+static int get_next_record(const s8** srec, u8* buf, u8** adr, u8* len)
-+{
-+ int again;
-+ int last = 1;
-+
-+ *adr = 0;
-+ do {
-+ again = 0;
-+ if (**srec == 'S') {
-+ switch (*++*srec) {
-+ case '0':
-+ skip_to_next_record(srec);
-+ again = 1;
-+ break;
-+ case '3':
-+ ++*srec;
-+ *len = srec_read_u8(srec) - sizeof(u32) - 1;
-+ *adr = (u8*)srec_read_u32(srec);
-+ read_record(*len, srec, buf);
-+ skip_to_next_record(srec);
-+ last = 0;
-+ break;
-+ case '7':
-+ ++*srec;
-+ *len = srec_read_u8(srec) - 1;
-+ if (*len >= sizeof(u32)) {
-+ *adr = (u8*)srec_read_u32(srec);
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ } while (again);
-+
-+ return last;
-+}
-+
-+static const u32 ENDIAN_LITTLE_READ_BIT = 30;
-+static const u32 ENDIAN_BIG_WRITE_BIT = 31;
-+
-+static u8* convert_adr_to_virt(u8* adr)
-+{
-+ static const u32 ARM_HIGH_ORDER_ADR_BIT = 30;
-+
-+ u32 virt = (u32)adr;
-+
-+ // Zero the Leon endian control bits
-+ virt &= ~((1UL << ENDIAN_BIG_WRITE_BIT) | (1UL << ENDIAN_LITTLE_READ_BIT));
-+
-+ // Convert to an ARM physical address
-+ virt |= (1UL << ARM_HIGH_ORDER_ADR_BIT);
-+
-+ // Is address sane?
-+ if (virt < LEON_IMAGE_BASE_PA) {
-+ panic("CoPro SRAM load address 0x%08x below mapped region beginning at 0x%08lx\n", (u32)adr, LEON_IMAGE_BASE_PA);
-+ } else {
-+ virt -= LEON_IMAGE_BASE_PA;
-+ virt += LEON_IMAGE_BASE;
-+ }
-+
-+ return (u8*)virt;
-+}
-+
-+static void leon_load_image(const s8 *srec)
-+{
-+ u8 *buf;
-+ u8 *adr;
-+ u8 len;
-+ u32 code_base;
-+
-+ // Copy each record to the specified address
-+ // Convert the LEON physical address to an ARM virtual address before
-+ // attempting to get the ARM to access it
-+ // NB must endian-swap any trailing non-quad multiple bytes, as LEON will
-+ // expect its instruction data in big endian format, whereas the ARM is
-+ // little endian
-+ buf = kmalloc(512, GFP_KERNEL);
-+ while (!get_next_record(&srec, buf, &adr, &len)) {
-+ int i=0;
-+ int quads = len/sizeof(u32);
-+ int spare = len - (quads*sizeof(u32));
-+ int padded_len = len+(sizeof(u32)-spare);
-+ u32* quad_ptr;
-+
-+ adr = convert_adr_to_virt(adr);
-+
-+ quad_ptr = (u32*)adr;
-+ while (i < quads) {
-+ *quad_ptr++ = ((u32*)buf)[i++];
-+ }
-+ adr = (u8*)quad_ptr;
-+ for (i=len; i < padded_len; i++) {
-+ buf[i] = 0;
-+ }
-+ i = padded_len-1;
-+ while (i >= (len-spare)) {
-+ *adr++ = buf[i--];
-+ }
-+ }
-+ kfree(buf);
-+
-+ // Start LEON execution at the address specified by the S-records, with
-+ // correct endianess. Use the address unchanged, as the LEON required
-+ // physical addresses and may make use of alternative upper nibble values
-+ code_base = (((u32)adr & ~((1UL << ENDIAN_BIG_WRITE_BIT) | (1UL << ENDIAN_LITTLE_READ_BIT))) | (1UL << ENDIAN_BIG_WRITE_BIT));
-+
-+ // Set the LEON's start address
-+ printk(KERN_NOTICE "CoPro: Programming start address as 0x%08x (basic adr = 0x%08x)\n", code_base, (u32)adr);
-+ writel(code_base, SYS_CTRL_COPRO_CTRL);
-+
-+ // Ensure start address has been loaded before release the LEON from reset
-+ wmb();
-+}
-+
-+void init_copro(const s8 *srec, unsigned long arg)
-+{
-+ // Ensure the LEON is in reset
-+ writel(1UL << SYS_CTRL_RSTEN_COPRO_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+
-+ // Enable the clock to the LEON
-+ writel(1UL << SYS_CTRL_CKEN_COPRO_BIT, SYS_CTRL_CKEN_SET_CTRL);
-+
-+ // Ensure reset and clock operations are complete
-+ wmb();
-+
-+ // Place LEON context argument in top quad of SRAM
-+ *((u32*)(LEON_IMAGE_BASE+LEON_IMAGE_SIZE-sizeof(u32))) = arg;
-+
-+ // Load LEON's program and data and execution start address
-+ leon_load_image(srec);
-+
-+ // Release the LEON from reset so it begins execution of the loaded code
-+ writel(1UL << SYS_CTRL_RSTEN_COPRO_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+
-+ // Give the LEON a chance to stabilise before giving it any commands
-+ mdelay(100);
-+ return;
-+}
-+EXPORT_SYMBOL_GPL(init_copro);
-+
-+void shutdown_copro(void)
-+{
-+ // Ensure the LEON is in reset
-+ writel(1UL << SYS_CTRL_RSTEN_COPRO_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+
-+ // Disable the clock to the LEON
-+ writel(1UL << SYS_CTRL_CKEN_COPRO_BIT, SYS_CTRL_CKEN_CLR_CTRL);
-+
-+ // Ensure reset and clock operations are complete
-+ wmb();
-+}
-+EXPORT_SYMBOL_GPL(shutdown_copro);
-+
-+#endif // CONFIG_SUPPORT_LEON
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/oxnas-ahb-monitor.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/oxnas-ahb-monitor.c
---- linux-2.6.24/arch/arm/mach-oxnas/oxnas-ahb-monitor.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/oxnas-ahb-monitor.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,374 @@
-+/*
-+ * arch/arm/mach-oxnas/oxnas-ahb-monitor.c
-+ *
-+ * Copyright (C) 2006 Oxford Semiconductor Ltd
-+ *
-+ * 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 <linux/types.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/miscdevice.h>
-+#include <linux/smp_lock.h>
-+#include <linux/kernel.h>
-+#include <linux/delay.h>
-+#include <linux/sched.h>
-+#include <linux/i2c.h>
-+#include <linux/proc_fs.h>
-+#include <linux/capability.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/spinlock.h>
-+#include <linux/smp_lock.h>
-+#include <linux/wait.h>
-+#include <linux/suspend.h>
-+#include <linux/kthread.h>
-+#include <linux/moduleparam.h>
-+
-+#include <asm/io.h>
-+#include <asm/system.h>
-+#include <asm/sections.h>
-+#include <asm/uaccess.h>
-+#include <asm/bitops.h>
-+
-+#include <asm/hardware.h>
-+
-+
-+/* usb test masks and offsets */
-+#define TEST_MASK 0xF
-+#define TEST_OFFSET 16
-+
-+#define MODULE_VERS "0.1"
-+#define MODULE_NAME "oxnas-test"
-+MODULE_AUTHOR( "John Larkworthy" );
-+MODULE_DESCRIPTION( "Driver to access the test hardware in oxnas units" );
-+MODULE_LICENSE( "GPL" );
-+
-+
-+static struct proc_dir_entry *proc_dir_usb_test_read, *oxnas_test_dir;
-+
-+
-+static struct {
-+ void * address;
-+ char * name;
-+ long unsigned low_add;
-+ long unsigned high_add;
-+ unsigned burst;
-+ unsigned burst_mask;
-+ unsigned hprot;
-+ unsigned hprot_mask;
-+ unsigned mode;
-+} monitor[] =
-+{
-+ { (void *) 0x00000, "ARM_Data", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
-+ { (void *) 0x10000, "Arm_Inst", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
-+ { (void *) 0x20000, "DMA_A", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
-+ { (void *) 0x30000, "DMA_B", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
-+ { (void *) 0x40000, "CoPro", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
-+ { (void *) 0x50000, "USBHS", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
-+ { (void *) 0x60000, "GMAC", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
-+ { (void *) 0x70000, "PCI", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 }
-+};
-+#define NO_MONITORS (sizeof(monitor)/sizeof(monitor[0]))
-+
-+/* create proc filing system entries to accept configuration data */
-+static int usb_test_write_entries(const char *name, write_proc_t *w, read_proc_t *r, int data)
-+{
-+ struct proc_dir_entry * entry = create_proc_entry(name, 0222, oxnas_test_dir);
-+ if (entry) {
-+ entry->write_proc = w;
-+ entry->read_proc =r;
-+ entry->data = (void *)data;
-+ entry->owner = THIS_MODULE;
-+ return 0;
-+ }
-+ else
-+ {
-+ return -ENOMEM;
-+ }
-+}
-+
-+static int
-+oxnas_test_read(char *buf, char **start, off_t offset,
-+ int count, int *eof, void *unused)
-+{
-+
-+ int i;
-+ int len = 0;
-+ long unsigned *rd_monitor;
-+
-+
-+ for (i=0; i < NO_MONITORS; i++)
-+ {
-+ rd_monitor = (long unsigned *) (AHB_MON_BASE + monitor[i].address);
-+ len += sprintf(buf+len, "%s CL:%ld EV:%ld hld:%ld slw:%lx tm:%ld\n",
-+ monitor[i].name,
-+ *rd_monitor,
-+ *(rd_monitor+1),
-+ *(rd_monitor+2),
-+ *(rd_monitor+3),
-+ (*(rd_monitor+4) & 0xFFFF));
-+ }
-+ *eof=1;
-+ return len;
-+}
-+/*
-+ * function to clear and start all the timers mainly together.
-+ */
-+#define MAX_CMD 5
-+static int
-+oxnas_test_control(struct file *file, const char *buf, unsigned long count, void * data)
-+{
-+ int len;
-+ int i;
-+ long unsigned *rd_monitor;
-+ unsigned cmd = 0;
-+
-+ char local[MAX_CMD];
-+ int result;
-+
-+ if (count > MAX_CMD-1)
-+ len= MAX_CMD-1;
-+ else
-+ len=count;
-+
-+ if (copy_from_user(&local, buf, len))
-+ return -EFAULT;
-+
-+ result=sscanf(local, "%d", &cmd);
-+
-+ switch (cmd)
-+ {
-+ case 0:
-+ printk(KERN_INFO "oxnas-test: stop command\n");
-+ break;
-+ case 1:
-+ printk(KERN_INFO "oxnas-test: run command\n");
-+ break;
-+ case 2:
-+ printk(KERN_INFO "oxnas-test: reset command\n");
-+ break;
-+ default:
-+ printk(KERN_INFO "oxnas-test: ignored command\n");
-+ return len;
-+ break;
-+ }
-+
-+ for (i=0; i < NO_MONITORS; i++)
-+ {
-+ rd_monitor = (long unsigned *) (AHB_MON_BASE + monitor[i].address);
-+ *rd_monitor = (long unsigned) cmd;
-+ }
-+ return len;
-+}
-+
-+
-+/*
-+ * The write function accepts a line as below:
-+ * start_addr, end_addr, mode, burst, burst_mask, hprot, hprot_mask
-+ * expected string length is 10 + 10 + 3 + 3 + 4 + 3 + 4 < 40char.
-+ * This is decoded by the scanf function into the separate items. - missing items are defaulted.
-+ */
-+
-+#define MAX_STRING 40
-+static int
-+oxnas_test_config_write(struct file *file, const char *buf, unsigned long count, void * data)
-+{
-+
-+ int len;
-+ int i = (int) data;
-+ char local[MAX_STRING];
-+ int result;
-+ unsigned long * mon_ptr;
-+
-+ if (count > MAX_STRING-1)
-+ len= MAX_STRING-1;
-+ else
-+ len=count;
-+
-+ if (copy_from_user(&local, buf, len))
-+ return -EFAULT;
-+
-+ /* extract value from buffer and store */
-+
-+ result = sscanf(local, "%li,%li,%i,%i,%i,%i,%i",
-+ &monitor[i].low_add,
-+ &monitor[i].high_add,
-+ &monitor[i].mode,
-+ &monitor[i].burst,
-+ &monitor[i].burst_mask,
-+ &monitor[i].hprot,
-+ &monitor[i].hprot_mask
-+ );
-+ if (result != 7)
-+ return -EINVAL;
-+
-+ /* load values on hardware */
-+
-+ mon_ptr=(unsigned long *) (AHB_MON_BASE + monitor[i].address);
-+
-+ *(mon_ptr + 1) = monitor[i].mode & 0x3;
-+ *(mon_ptr + 2) = monitor[i].low_add;
-+ *(mon_ptr + 3) = monitor[i].high_add;
-+ *(mon_ptr + 4) = ((monitor[i].burst & 0x7) << 4 | (monitor[i].burst_mask & 0x7));
-+ *(mon_ptr + 5) = ((monitor[i].hprot & 0xf) << 4 | (monitor[i].hprot_mask &0xf));
-+
-+ return len;
-+}
-+
-+static int
-+oxnas_test_config_read(char *buf, char **start, off_t offset,
-+ int count, int *eof, void *data)
-+{
-+
-+ int len = 0;
-+ int i = (int) data;
-+
-+ len += sprintf(buf+len, "name low high mode burst/mask hprot/mask\n");
-+
-+ len += sprintf(buf+len, "%s 0x%08lx 0x%08lx %d 0x%x/0x%x 0x%x/0x%x\n",
-+ monitor[i].name,
-+ monitor[i].low_add,
-+ monitor[i].high_add,
-+ monitor[i].mode,
-+ monitor[i].burst,
-+ monitor[i].burst_mask,
-+ monitor[i].hprot,
-+ monitor[i].hprot_mask);
-+
-+
-+ *eof=1;
-+ return len;
-+}
-+
-+static int __init oxnas_test_init(void)
-+{
-+ int rv=0;
-+ int i;
-+
-+ oxnas_test_dir = proc_mkdir(MODULE_NAME, NULL);
-+ if (oxnas_test_dir == NULL) {
-+ printk(KERN_ERR "oxnas-test: unable to register /proc/usb-test\n");
-+ rv= -ENOMEM;
-+ goto out;
-+ }
-+
-+ oxnas_test_dir->owner= THIS_MODULE;
-+
-+ proc_dir_usb_test_read = create_proc_entry("read", 0444, oxnas_test_dir);
-+ if (proc_dir_usb_test_read) {
-+ proc_dir_usb_test_read->read_proc = oxnas_test_read;
-+ } else {
-+ printk(KERN_ERR "oxnas-test: unable to register /proc/usb-test/read\n");
-+ rv = -ENOMEM;
-+ goto no_read;
-+ }
-+
-+ /* create port write file entries */
-+ for (i=0;i<NO_MONITORS;i++)
-+ {
-+ rv = usb_test_write_entries(monitor[i].name, &oxnas_test_config_write, &oxnas_test_config_read, i);
-+ if (rv < 0)
-+ {
-+ while (i != 0)
-+ {
-+ i--;
-+ /* remove any allocated entries */
-+ remove_proc_entry (monitor[i].name, oxnas_test_dir);
-+ }
-+ goto no_write;
-+ }
-+ }
-+
-+ {
-+ struct proc_dir_entry * entry = create_proc_entry("control", 0666, oxnas_test_dir);
-+ if (entry) {
-+ entry->write_proc = oxnas_test_control;
-+ entry->owner = THIS_MODULE;
-+ return 0;
-+ }
-+ else
-+ {
-+ goto no_control;
-+ }
-+ }
-+
-+
-+ printk(KERN_INFO "%s %s initialised\n", MODULE_NAME, MODULE_VERS);
-+
-+ return 0;
-+
-+ no_control:
-+ for (i = NO_MONITORS; i != 0; )
-+ {
-+ i--;
-+ /* remove any allocated entries */
-+ remove_proc_entry (monitor[i].name, oxnas_test_dir);
-+ }
-+
-+ no_write:
-+ remove_proc_entry("read", oxnas_test_dir);
-+ no_read:
-+ remove_proc_entry(MODULE_NAME, NULL);
-+ out:
-+ return rv;
-+}
-+
-+
-+static void __exit oxnas_test_exit(void)
-+{
-+ int i;
-+
-+ remove_proc_entry("control", oxnas_test_dir);
-+
-+ for (i = 0; i < NO_MONITORS; i++)
-+ {
-+ remove_proc_entry(monitor[i].name, oxnas_test_dir);
-+ }
-+
-+ remove_proc_entry("read", oxnas_test_dir);
-+ remove_proc_entry(MODULE_NAME, NULL);
-+
-+ printk(KERN_INFO "%s %s removed\n", MODULE_NAME, MODULE_VERS);
-+
-+}
-+
-+
-+module_init(oxnas_test_init);
-+module_exit(oxnas_test_exit);
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/oxnas-wd810-leds.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/oxnas-wd810-leds.c
---- linux-2.6.24/arch/arm/mach-oxnas/oxnas-wd810-leds.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/oxnas-wd810-leds.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,1021 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/oxnas-wd810-leds.c
-+ *
-+ * Copyright (c) 2008 Oxford Semiconductor Ltd.
-+ *
-+ * 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 <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/timer.h>
-+#include <linux/interrupt.h>
-+#include <linux/platform_device.h>
-+#include <linux/leds.h>
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+
-+
-+/* Timer Values and Pulse Width Modulation */
-+#define PWM_RESOLUTION 255
-+#define TIMER_LED_MODE TIMER_MODE_PERIODIC
-+
-+#define LED100 (PWM_RESOLUTION) /* 100% duty cycle */
-+#define LED50 (PWM_RESOLUTION / 2) /* 50% duty cycle */
-+#define LED25 (PWM_RESOLUTION / 4) /* 25% duty cycle */
-+
-+#define STEP_RESOLUTION (16) /* change intensity in 16 steps */
-+
-+
-+/* Setup Timer2 prescaler, operation mode, and start it */
-+#define PERIODIC_INTERRUPT \
-+ ( \
-+ (TIMER_PRESCALE_256 << TIMER_PRESCALE_BIT) | \
-+ (TIMER_LED_MODE << TIMER_MODE_BIT) | \
-+ (TIMER_ENABLE_ENABLE << TIMER_ENABLE_BIT) \
-+ )
-+
-+/*
-+ * Target frame rate is 60Hz. Slower frame rates flicker badly.
-+ * Since each frame has 16 divisions to perform the pulse width
-+ * modulation that means we need the timer set to 960Hz (i.e. 60 * 16)
-+ *
-+ * With a system clock of 25Mhz and a load register value of (1627) prescaled 256
-+ * to achieve 2Hz:
-+ * 25Mhz / 256 / 24414 =~4Hz //1627 = ~60
-+ *
-+ * PWM clock = 183MHz/256/814=~877kHz
-+ */
-+#define FAST_TIMER_INT 24414 //48828//(1627) /* Timer2 count down */
-+#define SYS_CLOCK CONFIG_NOMINAL_RPSCLK_FREQ /* System clock frequency */
-+#define PRESCALE_VALUE (256) /* Value set in prescaler */
-+#define PWM_PRESCALE 814 /* Value loaded on PWM clock register */
-+#define MAX_PWM 255
-+#define SLOW_TPS ((SYS_CLOCK/PRESCALE_VALUE) / FAST_TIMER_INT) //=~4Hz, 250ms
-+
-+
-+ /**** if GPIO31~GPIO16 is used, sift left 16 bits ****//* GPIO bits dedicated to LEDs *///Need to modify if different GPIO used
-+#define LED_MASK_CG5 (1 << GPIO_34) /* Capacity Gauge TOP LED */
-+#define LED_MASK_CG4 (1 << GPIO_7) /* Capacity Gauge 4th LED */
-+#define LED_MASK_CG3 (1 << GPIO_6) /* Capacity Gauge 3rd LED */
-+#define LED_MASK_CG2 (1 << GPIO_5) /* Capacity Gauge 2nd LED */
-+#define LED_MASK_CG1 ((1 << GPIO_26)>>16) //sift left 16 bits for PWM10 /* Capacity Gauge 1st LED */
-+#define LED_MASK_CG0 ((1 << GPIO_25)>>16) //sift left 16 bits for PWM9 /* Capacity Gauge BOTTOM LED */
-+
-+/* Mask for all the LEDs in the Fuel Gauge.*/
-+/* Mask for all the LEDs on GPIO_A */
-+
-+#define LED_MASK_GPIO_A \
-+ ( \
-+ (LED_MASK_CG0<<16) | \
-+ (LED_MASK_CG1<<16) | \
-+ LED_MASK_CG2 | \
-+ LED_MASK_CG3 | \
-+ LED_MASK_CG4 \
-+ )
-+
-+/* Mask for all the LEDs on GPIO_B */
-+#define LED_MASK_GPIO_B \
-+ ( \
-+ LED_MASK_CG5 \
-+ )
-+
-+#define LED_MASK_GAUGE \
-+ ( \
-+ LED_MASK_CG0 | \
-+ LED_MASK_CG1 | \
-+ LED_MASK_CG2 | \
-+ LED_MASK_CG3 | \
-+ LED_MASK_CG4 | \
-+ LED_MASK_CG5 \
-+ )
-+
-+#define LED_MASK_GAUGE_ODD \
-+ ( \
-+ LED_MASK_CG0 | \
-+ LED_MASK_CG2 | \
-+ LED_MASK_CG4 \
-+ )
-+
-+#define LED_MASK_GAUGE_EVEN \
-+ ( \
-+ LED_MASK_CG1 | \
-+ LED_MASK_CG3 | \
-+ LED_MASK_CG5 \
-+ )
-+
-+#define LED_MASK_GAUGE_CENTER \
-+ ( \
-+ LED_MASK_CG2 | \
-+ LED_MASK_CG3 \
-+ )
-+
-+#define LED_MASK_GAUGE_MID \
-+ ( \
-+ LED_MASK_CG1 | \
-+ LED_MASK_CG4 \
-+ )
-+
-+#define LED_MASK_GAUGE_OUTER \
-+ ( \
-+ LED_MASK_CG0 | \
-+ LED_MASK_CG5 \
-+ )
-+
-+#define CLEAR(addr, mask) writel(readl(addr) & ~mask, addr)
-+
-+
-+/* Variables to hold the number of LED classes created */
-+static int leds_created;
-+
-+/* Variables to save/restore timer register values */
-+static u32 timer_load;
-+static u32 timer_control;
-+
-+/* LED polarity */
-+static int negative_led_logic = 0;
-+module_param(negative_led_logic, bool, 0);
-+
-+/*
-+ * States for the main LED behavior state machine.
-+ */
-+enum {
-+ STATE_NOP,
-+ STANDBY,
-+ SHOW_CAPACITY,
-+ ACTIVITY,
-+ POWER_OFF,
-+ RESET,
-+ ATTENTION,
-+ FAILURE,
-+ BOOT_OK,
-+ BOOT_stage1,
-+ BOOT_stage2,
-+ BOOT_stage3,
-+ BOOT_stage4,
-+ BOOT_stage5,
-+ BOOT_stage6,
-+};
-+
-+/*Various LED state timing*/
-+#define BOOTOK_RAMP_DIV 11
-+#define STANBY_RAMP_DIV 9
-+#define STANBY_ALT_STEP (SLOW_TPS*4) //16//8//250 //~4sec
-+#define POWEROFF_RAMP_DIV 6
-+#define POWEROFF_ALT_STEP ((SLOW_TPS/2)*7) //14//7//200 //~3.5sec
-+#define ATTENTION_ALT_STEP (SLOW_TPS/2) // 2 //~2Hz, 0.5sec
-+#define FAILURE_RAMP_DIV 6
-+#define FAILURE_ALT_STEP (SLOW_TPS/2) // 2 //~2Hz, 0.5sec
-+#define ACTIVITY_RAMP_DIV 1 // 2
-+#define ACTIVITY_ALT_STEP (SLOW_TPS/4) // 2 //~2Hz, 0.5sec
-+#define RESET_ALT_STEP (SLOW_TPS/2) // 2 //~2Hz, 0.5sec
-+
-+
-+/* Variables for main LED behavior state machine */
-+static int state;
-+static u8 start;
-+static u8 act;
-+static u8 mark;
-+static u16 act_led[6] = {
-+ LED_MASK_CG0,
-+ LED_MASK_CG1,
-+ LED_MASK_CG2,
-+ LED_MASK_CG3,
-+ LED_MASK_CG4,
-+ LED_MASK_CG5,
-+};
-+static u32 alt = 0;
-+static int count;
-+static u16 capacity_gauge_bits; /* see LED frame buffer design assumption */
-+static u8 leds_switch;
-+static u8 activity_block = 1;
-+
-+
-+/*
-+ * Declare tasklet for the LED behavior state machine.
-+ */
-+void oxnas_wd810_leds_behavior(unsigned long);
-+DECLARE_TASKLET(oxnas_wd810_leds_behavior_tasklet,
-+ oxnas_wd810_leds_behavior, 0);
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_interrupt */
-+/* */
-+/* PURPOSE: */
-+/* Interrupt handler for the oxnas-wd810-leds pulse width modulation */
-+/***************************************************************************/
-+static irqreturn_t oxnas_wd810_leds_interrupt(int irq, void *dev_id)
-+{
-+ writel(0, TIMER2_CLEAR);
-+
-+ tasklet_schedule(&oxnas_wd810_leds_behavior_tasklet);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: get_vbar_bits */
-+/* */
-+/* PURPOSE: */
-+/* Convert the bit map of V-bar LEDs into the GPIO bit map */
-+/***************************************************************************/
-+static u16 get_vbar_bits(u16 value)
-+{
-+ u16 pattern = 0;
-+
-+ // Convert the bit map to the GPIO bit pattern
-+ if (value & (1 << 0))
-+ pattern |= LED_MASK_CG0;
-+ if (value & (1 << 1))
-+ pattern |= LED_MASK_CG1;
-+ if (value & (1 << 2))
-+ pattern |= LED_MASK_CG2;
-+ if (value & (1 << 3))
-+ pattern |= LED_MASK_CG3;
-+ if (value & (1 << 4))
-+ pattern |= LED_MASK_CG4;
-+ if (value & (1 << 5))
-+ pattern |= LED_MASK_CG5;
-+
-+ return pattern;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: get_percentage_pattern */
-+/* */
-+/* PURPOSE: */
-+/* Convert a percentage to a V-bar bit map. Note, we never display */
-+/* less than 1 LED for a percentage so that something is alway visible. */
-+/***************************************************************************/
-+static u16 get_percentage_pattern(u16 percentage)
-+{
-+ if (percentage >= 50) {
-+ if (percentage >= 67) {
-+ if (percentage >= 83) {
-+ if (percentage >= 97) {
-+ return 0x3F; // 6 LEDs is >= 97%
-+ } else {
-+ return 0x1F; // 5 LEDs is >= 83%
-+ }
-+ } else {
-+ return 0x0F; // 4 LEDs is >= 67%
-+ }
-+ } else {
-+ return 0x07; // 3 LEDs is >= 50%
-+ }
-+ } else {
-+ if (percentage >= 33) {
-+ return 0x03; // 2 LEDs is >= 33%
-+ } else {
-+ return 0x01; // 1 LED is >= 0%
-+ }
-+ }
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: set_led */
-+/* */
-+/* PURPOSE: */
-+/* Set requested brightness on the requested LED(s) */
-+/***************************************************************************/
-+static void set_led(u16 led_bits, u8 value, u16 ramp, u16 ramp_div)
-+{
-+ u16 bit;
-+ s8 count = 0;
-+ u32 reg;
-+
-+ if (negative_led_logic) {
-+ value = MAX_PWM - value;
-+ if (ramp & 0x100) {
-+ ramp = ((MAX_PWM - (ramp & 0xFF)) | 0x100);
-+ } else
-+ ramp = ((MAX_PWM - (ramp & 0xFF)));
-+ }
-+
-+ reg = ((ramp << 16) | value);
-+//printk(KERN_INFO "set_led: reg=%x\n", reg);
-+ if (ramp & 0x100) {
-+ writel(ramp_div, (PWM_DATA_REGISTER_BASE + 0x404));
-+ }
-+ for (bit = 1; bit > 0; bit <<= 1, ++count) {
-+ if (bit & led_bits) {
-+ writel(reg, ((u32 *) PWM_DATA_REGISTER_BASE + count));
-+ }
-+ }
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: display_vbar */
-+/* */
-+/* PURPOSE: */
-+/* Set bits for the requested V-bar map */
-+/***************************************************************************/
-+static void display_vbar(u16 vbar_bits)
-+{
-+ //printk(KERN_INFO "display_vbar: vbar_bits=%x\n", vbar_bits);
-+
-+ //set_led(~vbar_bits & LED_MASK_GAUGE, 0, 0, 0);
-+ set_led(LED_MASK_GAUGE, 0, 0, 0);
-+ set_led(vbar_bits, LED100, 0, 0);
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_behavior_init */
-+/* */
-+/* PURPOSE: */
-+/* Initialization for LED behavior main state machine */
-+/***************************************************************************/
-+void oxnas_wd810_leds_behavior_init(void)
-+{
-+ /* State machine variables */
-+ state = BOOT_OK;
-+ count = 0;
-+ capacity_gauge_bits = 0;
-+ leds_switch = 0xFF;
-+}
-+
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_behavior */
-+/* */
-+/* PURPOSE: */
-+/* LED behavior main state machine */
-+/***************************************************************************/
-+void oxnas_wd810_leds_behavior(unsigned long unused)
-+{
-+//printk(KERN_INFO "oxnas_wd810_leds_behavior state=%d count=%d\n", state, count);
-+ switch (state) {
-+ case STANDBY:
-+ //All LEDs dim-up and dim-down every 4sec.
-+ if (leds_switch & (1 << 0)) { //LEDS display turn on
-+ if (count-- != 0)
-+ break;
-+ alt++;
-+ if ((alt % 2) == 1) {
-+ set_led(LED_MASK_GAUGE, 0, 0x1FF, STANBY_RAMP_DIV);
-+ } else {
-+ set_led(LED_MASK_GAUGE, 255, 0x100, STANBY_RAMP_DIV);
-+ }
-+ count = STANBY_ALT_STEP;
-+ } else {
-+ printk(KERN_INFO " state STANDBY LED display off \n");
-+ state = STATE_NOP;
-+ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+ }
-+ break;
-+
-+ case SHOW_CAPACITY:
-+ //Each LED represents 1/6 of the total available capacity.
-+ if (leds_switch & (1 << 1)) { //LEDS display turn on
-+ display_vbar(capacity_gauge_bits);
-+ } else {
-+ printk(KERN_INFO " state SHOW_CAPACITY LED display off \n");
-+ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+ }
-+ state = STATE_NOP;
-+ break;
-+
-+
-+ case ACTIVITY:
-+ //LEDs illuminate in a up and down "cylon" motion.
-+ if (leds_switch & (1 << 2)) { //LEDS display turn on
-+ if (count-- != 0)
-+ break;
-+
-+ if (start == 0) {
-+ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+ set_led(act_led[act], 0, 0x1FF, ACTIVITY_RAMP_DIV);
-+ start = 1;
-+ } else {
-+ if ((mark == 0) && (++act < 6)) {
-+ set_led(act_led[act], 0, 0x1FF, ACTIVITY_RAMP_DIV);
-+ set_led(act_led[act - 1], 255, 0x100,
-+ ACTIVITY_RAMP_DIV);
-+ goto NEXT;
-+ }
-+ mark = 1;
-+ if ((mark == 1) && (act-- > 1)) {
-+ set_led(act_led[act], 255, 0x100, ACTIVITY_RAMP_DIV);
-+ set_led(act_led[act - 1], 0, 0x1FF, ACTIVITY_RAMP_DIV);
-+ goto NEXT;
-+ }
-+ mark = 0;
-+ state = SHOW_CAPACITY; //Michael TBD
-+ }
-+ NEXT:
-+ count = ACTIVITY_ALT_STEP;
-+ } else {
-+ printk(KERN_INFO " state ACTIVITY LED display off \n");
-+ state = STATE_NOP;
-+ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+ }
-+ break;
-+
-+ case POWER_OFF:
-+ //LEDs in the array dim-up/dim-down in an odd/even alternating pattern.
-+ if (leds_switch & (1 << 3)) { //LEDS display turn on
-+ if (count-- != 0)
-+ break;
-+ alt++;
-+ if ((alt % 2) == 1) {
-+ set_led(LED_MASK_GAUGE_ODD, 0, 0x1FF, POWEROFF_RAMP_DIV);
-+ set_led(LED_MASK_GAUGE_EVEN, 255, 0x100,
-+ POWEROFF_RAMP_DIV);
-+ } else {
-+ set_led(LED_MASK_GAUGE_ODD, 255, 0x100, POWEROFF_RAMP_DIV);
-+ set_led(LED_MASK_GAUGE_EVEN, 0, 0x1FF, POWEROFF_RAMP_DIV);
-+ }
-+ count = POWEROFF_ALT_STEP;
-+ } else {
-+ printk(KERN_INFO " state POWER_OFF LED display off \n");
-+ state = STATE_NOP;
-+ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+ }
-+
-+ break;
-+
-+ case RESET:
-+ //Alternately blink the upper LED and lower LED at 1/2 sec rate.
-+ if (leds_switch & (1 << 4)) { //LEDS display turn on
-+ if (count-- != 0)
-+ break;
-+ alt++;
-+ if ((alt % 2) == 1) {
-+ set_led(act_led[0], 255, 0x000, 0);
-+ set_led(act_led[5], 0, 0x000, 0);
-+ } else {
-+ set_led(act_led[0], 0, 0x000, 0);
-+ set_led(act_led[5], 255, 0x000, 0);
-+ }
-+ count = RESET_ALT_STEP;
-+ } else {
-+ printk(KERN_INFO " state RESET LED display off \n");
-+ state = STATE_NOP;
-+ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+ }
-+
-+ break;
-+
-+ case ATTENTION:
-+ //All LEDs flash simultaneously at a 1/2 sec. rate
-+ if (count-- != 0)
-+ break;
-+ alt++;
-+ if ((alt % 2) == 1) {
-+ set_led(LED_MASK_GAUGE, 255, 0x000, 0);
-+
-+ } else {
-+ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+ }
-+ count = ATTENTION_ALT_STEP;
-+
-+ break;
-+
-+ case FAILURE:
-+ //LEDs illuminate in a continous "center out" sweep pattern.
-+ if (count-- != 0)
-+ break;
-+
-+ switch ((alt % 4)) {
-+ case 0:
-+ set_led(LED_MASK_GAUGE_CENTER, 0, 0x1FF, FAILURE_RAMP_DIV);
-+ break;
-+ case 1:
-+ set_led(LED_MASK_GAUGE_MID, 0, 0x1FF, FAILURE_RAMP_DIV);
-+ break;
-+ case 2:
-+ set_led(LED_MASK_GAUGE_OUTER, 0, 0x1FF, FAILURE_RAMP_DIV);
-+ break;
-+ case 3:
-+ set_led(LED_MASK_GAUGE, 0, 0, 0);
-+ break;
-+ }
-+ alt++;
-+ count = FAILURE_ALT_STEP;
-+
-+ break;
-+
-+ case BOOT_OK:
-+ //All 6 LEDs ramp up smoothly to full intensity.
-+ if (leds_switch & (1 << 5)) { //LEDS display turn on
-+ set_led(LED_MASK_GAUGE, 0, 0x1FF, BOOTOK_RAMP_DIV);
-+ } else {
-+ printk(KERN_INFO " state BOOT_OK LED display off \n");
-+ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+ }
-+ state = STATE_NOP;
-+ break;
-+
-+ case BOOT_stage1:
-+ //Bottom LED ramp up smoothly to full intensity.
-+ if (leds_switch & (1 << 6)) { //LEDS display turn on
-+ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+ set_led(LED_MASK_CG0, 0, 0x1FF, BOOTOK_RAMP_DIV);
-+ } else {
-+ printk(KERN_INFO " state BOOT_stage1~3 LED display off \n");
-+ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+ }
-+ state = STATE_NOP;
-+ break;
-+
-+ case BOOT_stage2:
-+ // 2nd LED ramp up smoothly to full intensity.
-+ if (leds_switch & (1 << 6)) { //LEDS display turn on
-+ set_led(LED_MASK_CG1, 0, 0x1FF, BOOTOK_RAMP_DIV);
-+ } else {
-+ printk(KERN_INFO " state BOOT_stage1~3 LED display off \n");
-+ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+ }
-+ state = STATE_NOP;
-+ break;
-+
-+ case BOOT_stage3:
-+ // 3rd LED ramp up smoothly to full intensity.
-+ if (leds_switch & (1 << 6)) { //LEDS display turn on
-+ set_led(LED_MASK_CG2, 0, 0x1FF, BOOTOK_RAMP_DIV);
-+ } else {
-+ printk(KERN_INFO " state BOOT_stage1~3 LED display off \n");
-+ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+ }
-+ state = STATE_NOP;
-+ break;
-+
-+ case BOOT_stage4:
-+ // 4th LED ramp up smoothly to full intensity.
-+ if (leds_switch & (1 << 7)) { //LEDS display turn on
-+ set_led(LED_MASK_CG3, 0, 0x1FF, BOOTOK_RAMP_DIV);
-+ } else {
-+ printk(KERN_INFO " state BOOT_stage4~6 LED display off \n");
-+ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+ }
-+ state = STATE_NOP;
-+ break;
-+
-+ case BOOT_stage5:
-+ //5th LED ramp up smoothly to full intensity.
-+ if (leds_switch & (1 << 7)) { //LEDS display turn on
-+ set_led(LED_MASK_CG4, 0, 0x1FF, BOOTOK_RAMP_DIV);
-+ } else {
-+ printk(KERN_INFO " state BOOT_stage4~6 LED display off \n");
-+ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+ }
-+ state = STATE_NOP;
-+ break;
-+
-+ case BOOT_stage6:
-+ //Top LED ramp up smoothly to full intensity.
-+ if (leds_switch & (1 << 7)) { //LEDS display turn on
-+ set_led(LED_MASK_CG5, 0, 0x1FF, BOOTOK_RAMP_DIV);
-+ } else {
-+ printk(KERN_INFO " state BOOT_stage4~6 LED display off \n");
-+ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
-+ }
-+ state = STATE_NOP;
-+ break;
-+
-+ case STATE_NOP:
-+ default:
-+ return;
-+ }
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_set_switch */
-+/* */
-+/* PURPOSE: */
-+/* Set the LED display "on/off" of each state by Web GUI */
-+/***************************************************************************/
-+static void oxnas_wd810_leds_set_switch
-+ (struct led_classdev *led_cdev, enum led_brightness value) {
-+ leds_switch = value;
-+}
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_set_state */
-+/* */
-+/* PURPOSE: */
-+/* Set the "state" LED to the requested behavior */
-+/***************************************************************************/
-+static void oxnas_wd810_leds_set_state
-+ (struct led_classdev *led_cdev, enum led_brightness value) {
-+ count = 0;
-+ alt = 0;
-+ state = value;
-+ start = 0;
-+ act = 0;
-+ mark = 0;
-+ printk(KERN_INFO "oxnas_wd810_leds_state state=%d\n", state);
-+
-+ if (state > 3)
-+ activity_block = 1;
-+ else
-+ activity_block = 0;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_set_activity */
-+/* */
-+/* PURPOSE: */
-+/* Trigger activity display behavior */
-+/***************************************************************************/
-+//TBD Michael
-+static void oxnas_wd810_leds_set_activity
-+ (struct led_classdev *led_cdev, enum led_brightness value) {
-+ if (activity_block == 0) {
-+//printk("<1> oxnas_wd810_leds_set_activity value=%x\n", value);
-+ state = ACTIVITY;
-+ }
-+}
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_set_capacity_gauge */
-+/* */
-+/* PURPOSE: */
-+/* Set the fuel gauge to the requested value (treated as a percentage) */
-+/***************************************************************************/
-+static void oxnas_wd810_leds_set_capacity_gauge
-+ (struct led_classdev *led_cdev, enum led_brightness value) {
-+ capacity_gauge_bits = get_vbar_bits(get_percentage_pattern(value));
-+//printk("<1> oxnas_wd810_leds_set_capacity_gauge capacity_gauge_bits=%x\n", capacity_gauge_bits);
-+ state = SHOW_CAPACITY;
-+ activity_block = 0;
-+}
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: oxnas_wd810_leds_switch */
-+/* */
-+/* PURPOSE: */
-+/* Describe the oxnas-wd810-leds "switch" on/off */
-+/***************************************************************************/
-+static struct led_classdev oxnas_wd810_leds_switch = {
-+ .name = "oxnas-wd810-leds:switch",.brightness_set =
-+ oxnas_wd810_leds_set_switch,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: oxnas_wd810_leds_state */
-+/* */
-+/* PURPOSE: */
-+/* Describe the oxnas-wd810-leds "power" pseudo-LED */
-+/***************************************************************************/
-+static struct led_classdev oxnas_wd810_leds_state = {
-+ .name = "oxnas-wd810-leds:state",
-+ .brightness_set = oxnas_wd810_leds_set_state,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: oxnas_wd810_leds_activity */
-+/* */
-+/* PURPOSE: */
-+/* Describe the oxnas-wd810-leds "activity" pseudo-LED */
-+/***************************************************************************/
-+//TBD Michael
-+static struct led_classdev oxnas_wd810_leds_activity = {
-+ .name = "oxnas-wd810-leds:activity",
-+ .brightness_set = oxnas_wd810_leds_set_activity,
-+ .default_trigger = "sata-disk"
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: oxnas_wd810_leds_capacity_gauge */
-+/* */
-+/* PURPOSE: */
-+/* Describe the oxnas-wd810-leds "capacity-gauge" LEDs (brightness = % full) */
-+/***************************************************************************/
-+static struct led_classdev oxnas_wd810_leds_capacity_gauge = {
-+ .name = "oxnas-wd810-leds:capacity",
-+ .brightness_set = oxnas_wd810_leds_set_capacity_gauge,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: oxnas_wd810_leds_classes[] */
-+/* */
-+/* PURPOSE: */
-+/* Array of LED classes to create/destroy */
-+/***************************************************************************/
-+static struct led_classdev *oxnas_led_classes[] = {
-+ &oxnas_wd810_leds_switch,
-+ &oxnas_wd810_leds_state,
-+ &oxnas_wd810_leds_activity, //TBD
-+ &oxnas_wd810_leds_capacity_gauge,
-+};
-+
-+#ifdef DEBUG
-+static ssize_t
-+show_registers(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ char *out = buf;
-+ u32 clock_data = readl(PWM_CLOCK_REGISTER);
-+ u32 data_ptr = PWM_CLOCK_REGISTER;
-+ u8 no_pwms = (clock_data >> 16);
-+ u8 i;
-+ /* report hardware status here */
-+ out += sprintf(buf, "PWM drive registers\n");
-+ out +=
-+ sprintf(out, "clock register:0x%08x @ 0x%08x\n", clock_data,
-+ data_ptr);
-+
-+ for (i = 0; i < no_pwms; ++i) {
-+ data_ptr = (u32) ((u32 *) PWM_BASE + i);
-+ out +=
-+ sprintf(out, "%d:%d @ 0x%08x\n", i, (u8) readl(data_ptr),
-+ data_ptr);
-+ }
-+
-+ return out - buf;
-+}
-+
-+/* create a register 'file' to enbale reading back the pwm drive register status */
-+static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
-+
-+static void create_debug_files(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ device_create_file(dev, &dev_attr_registers);
-+}
-+
-+static void remove_debug_files(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ device_remove_file(dev, &dev_attr_registers);
-+}
-+#endif
-+
-+
-+#ifdef CONFIG_PM
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_suspend */
-+/* */
-+/* PURPOSE: */
-+/* Suspend all LED class devices created by this driver */
-+/***************************************************************************/
-+static int
-+oxnas_wd810_leds_suspend(struct platform_device *pdev, pm_message_t state)
-+{
-+ int n = leds_created;
-+ while (n > 0) {
-+ if (--n < ARRAY_SIZE(oxnas_led_classes)) {
-+ led_classdev_suspend(oxnas_led_classes[n]);
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_resume */
-+/* */
-+/* PURPOSE: */
-+/* Wake up all LED class devices created by this driver */
-+/***************************************************************************/
-+static int
-+oxnas_wd810_leds_resume(struct platform_device *pdev, pm_message_t state)
-+{
-+ int n = leds_created;
-+ while (n > 0) {
-+ if (--n < ARRAY_SIZE(oxnas_led_classes)) {
-+ led_classdev_resume(oxnas_led_classes[n]);
-+ }
-+ }
-+
-+ return 0;
-+}
-+#endif /* CONFIG_PM */
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_probe */
-+/* */
-+/* PURPOSE: */
-+/* Perform any necessary probing and initial setup for oxnas-wd810-leds device */
-+/***************************************************************************/
-+static int oxnas_wd810_leds_probe(struct platform_device *pdev)
-+{
-+ int rc;
-+ int timer_changed = 0;
-+ int interrupt_allocated = 0;
-+ leds_created = 0;
-+
-+ /* Turn off all the LEDs */
-+ if (negative_led_logic) {
-+ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_SET);
-+ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_SET);
-+ } else {
-+ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_CLEAR);
-+ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_CLEAR);
-+ }
-+ /* put PWM module back into reset and disable clock */
-+ writel((1 << SYS_CTRL_RSTEN_MISC_BIT), SYS_CTRL_RSTEN_SET_CTRL);
-+ // writel(PWM_CLOCK, SYS_CTRL_CKEN_CLR_CTRL);
-+
-+ do {
-+ /* Enable LED output drivers and disable other uses */
-+ CLEAR(SYS_CTRL_GPIO_PRIMSEL_CTRL_0, LED_MASK_GPIO_A);
-+ CLEAR(SYS_CTRL_GPIO_SECSEL_CTRL_0, LED_MASK_GPIO_A);
-+ CLEAR(SYS_CTRL_GPIO_TERTSEL_CTRL_0, LED_MASK_GPIO_A);
-+
-+ CLEAR(SYS_CTRL_GPIO_PRIMSEL_CTRL_1, LED_MASK_GPIO_B);
-+ CLEAR(SYS_CTRL_GPIO_SECSEL_CTRL_1, LED_MASK_GPIO_B);
-+ CLEAR(SYS_CTRL_GPIO_TERTSEL_CTRL_1, LED_MASK_GPIO_B);
-+ /* Turn off all the LEDs */
-+ if (negative_led_logic) {
-+ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_SET);
-+ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_SET);
-+ } else {
-+ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_CLEAR);
-+ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_CLEAR);
-+ }
-+
-+ /* bring PWM module out of reset and enable clock */
-+ writel((1 << SYS_CTRL_RSTEN_MISC_BIT), SYS_CTRL_RSTEN_CLR_CTRL);
-+ //writel(PWM_CLOCK, SYS_CTRL_CKEN_SET_CTRL);
-+
-+ /* enable PWM clock */
-+ writel(PWM_PRESCALE, PWM_CLOCK_REGISTER);
-+
-+ /* Initialize frame buffer to everything off */
-+//printk(KERN_INFO "oxnas_wd810_leds_probe: LED_MASK_GAUGE=%x\n",LED_MASK_GAUGE);
-+ set_led(LED_MASK_GAUGE, 0, 0, 0);
-+ /* Enable output to the LEDs */
-+ writel(LED_MASK_GPIO_A, SYS_CTRL_GPIO_PWMSEL_CTRL_0);
-+ writel(LED_MASK_GPIO_B, SYS_CTRL_GPIO_PWMSEL_CTRL_1);
-+
-+ /* Initialize the LED behavior state machine */
-+ oxnas_wd810_leds_behavior_init();
-+ /* Save Timer2 state for restoring later */
-+ timer_load = readl(TIMER2_LOAD);
-+ timer_control = readl(TIMER2_CONTROL);
-+ writel(0, TIMER2_CONTROL);
-+ timer_changed = 1;
-+ /* Setup Timer2 for LED control */
-+ rc = request_irq(TIMER_2_INTERRUPT, oxnas_wd810_leds_interrupt, 0,
-+ "led_pwm", 0);
-+
-+ // rc = request_irq(TIMER_2_INTERRUPT, wdc_leds_interrupt, 0, "led_pwm", 0);
-+ if (rc < 0) {
-+ printk(KERN_ERR "failed to get IRQ\n");
-+ break;
-+ }
-+
-+ interrupt_allocated = 1;
-+ writel(FAST_TIMER_INT, TIMER2_LOAD);
-+ writel(PERIODIC_INTERRUPT, TIMER2_CONTROL);
-+
-+ /* Register each LED class device */
-+ while (leds_created < ARRAY_SIZE(oxnas_led_classes)) {
-+ rc = led_classdev_register(&pdev->dev,
-+ oxnas_led_classes[leds_created]);
-+ if (rc < 0) {
-+ printk(KERN_ERR "failed to register led class \"%s\"\n",
-+ oxnas_led_classes[leds_created]->name);
-+ break;
-+ }
-+
-+ ++leds_created;
-+ }
-+ }
-+ while (0);
-+ /* If we failed then perform any needed clean up */
-+ if (rc < 0) {
-+ /* Unregister any classes we registered */
-+ while (leds_created > 0) {
-+ if (--leds_created < ARRAY_SIZE(oxnas_led_classes)) {
-+ led_classdev_unregister(oxnas_led_classes[leds_created]);
-+ }
-+ }
-+
-+ /* Free the interrupt if we allocated one */
-+ if (interrupt_allocated) {
-+ free_irq(TIMER_2_INTERRUPT, 0);
-+ }
-+
-+ /* Restore Timer2 if we changed it */
-+ if (timer_changed) {
-+ writel(timer_load, TIMER2_LOAD);
-+ writel(timer_control, TIMER2_CONTROL);
-+ }
-+ }
-+#ifdef DEBUG
-+ create_debug_files(pdev);
-+#endif
-+ return rc;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_remove */
-+/* */
-+/* PURPOSE: */
-+/* Perform steps to remove the oxnas-wd810-leds device */
-+/***************************************************************************/
-+static int oxnas_wd810_leds_remove(struct platform_device *pdev)
-+{
-+ while (leds_created > 0) {
-+ if (--leds_created < ARRAY_SIZE(oxnas_led_classes)) {
-+ led_classdev_unregister(oxnas_led_classes[leds_created]);
-+ }
-+ }
-+
-+ writel(0, TIMER2_CONTROL);
-+ free_irq(TIMER_2_INTERRUPT, 0);
-+ writel(timer_load, TIMER2_LOAD);
-+ writel(timer_control, TIMER2_CONTROL);
-+ /* Turn off all the LEDs */
-+ if (negative_led_logic) {
-+ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_SET);
-+ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_SET);
-+ } else {
-+ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_CLEAR);
-+ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_CLEAR);
-+ }
-+ /* put PWM module back into reset and disable clock */
-+ writel((1 << SYS_CTRL_RSTEN_MISC_BIT), SYS_CTRL_RSTEN_SET_CTRL);
-+ // writel(PWM_CLOCK, SYS_CTRL_CKEN_CLR_CTRL);
-+#ifdef DEBUG
-+ remove_debug_files(pdev);
-+#endif
-+ return 0;
-+}
-+
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: oxnas_wd810_leds_driver */
-+/* */
-+/* PURPOSE: */
-+/* Describe the oxnas-wd810-leds platform device driver */
-+/***************************************************************************/
-+static struct platform_driver oxnas_wd810_leds_driver = {
-+ .probe = oxnas_wd810_leds_probe,
-+ .remove = oxnas_wd810_leds_remove,
-+#ifdef CONFIG_PM
-+ .suspend = oxnas_wd810_leds_suspend,.resume = oxnas_wd810_leds_resume,
-+#endif /* CONFIG_PM */
-+ .driver = {.name = "oxnas-wd810-leds",},
-+};
-+
-+/* Pointer to device returned by platform_device_register_simple */
-+static struct platform_device *oxnas_wd810_leds;
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_init */
-+/* */
-+/* PURPOSE: */
-+/* Perform module initialization */
-+/***************************************************************************/
-+static int __init oxnas_wd810_leds_init(void)
-+{
-+ int ret;
-+ printk(KERN_INFO "oxnas-wd810-leds: SLOW_TPS=%d\n", SLOW_TPS);
-+ ret = platform_driver_register(&oxnas_wd810_leds_driver);
-+ if (!ret) {
-+ oxnas_wd810_leds =
-+ platform_device_register_simple("oxnas-wd810-leds", -1, NULL,
-+ 0);
-+ }
-+
-+ return ret;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: oxnas_wd810_leds_exit */
-+/* */
-+/* PURPOSE: */
-+/* Perform module unloading and cleanup */
-+/***************************************************************************/
-+static void __exit oxnas_wd810_leds_exit(void)
-+{
-+ if (oxnas_wd810_leds) {
-+ platform_device_unregister(oxnas_wd810_leds);
-+ }
-+ platform_driver_unregister(&oxnas_wd810_leds_driver);
-+}
-+
-+
-+module_init(oxnas_wd810_leds_init);
-+module_exit(oxnas_wd810_leds_exit);
-+MODULE_DESCRIPTION("oxnas wd810 1NC/2NC LEDs");
-+MODULE_AUTHOR("Oxford Semiconductor Ltd");
-+MODULE_LICENSE("GPL");
-+/******************************* End of File *********************************/
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/oxnas.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/oxnas.c
---- linux-2.6.24/arch/arm/mach-oxnas/oxnas.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/oxnas.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,1104 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/oxnas.c
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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 <linux/delay.h>
-+#include <linux/platform_device.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/completion.h>
-+#include <linux/serial.h>
-+#include <linux/serial_core.h>
-+#include <linux/serial_8250.h>
-+
-+#include <asm/sizes.h>
-+#include <asm/setup.h>
-+#include <asm/mach-types.h>
-+#include <asm/mach/arch.h>
-+#include <asm/mach/map.h>
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/dma.h>
-+
-+#ifdef CONFIG_DO_MEM_TEST
-+#include <linux/dma-mapping.h>
-+#include <asm/io.h>
-+#include <asm/arch/ahb_mon.h>
-+#endif // CONFIG_DO_MEM_TEST
-+
-+#include <asm/io.h>
-+
-+#ifdef CONFIG_LEON_START_EARLY
-+#include <asm/arch/leon.h>
-+#include <asm/arch/leon-early-prog.h>
-+#endif // CONFIG_LEON_START_EARLY
-+
-+#ifdef CONFIG_OXNAS_PCI_RESET_GPIO
-+#if (CONFIG_OXNAS_PCI_RESET_GPIO < 32)
-+#define PCI_RESET_NUM CONFIG_OXNAS_PCI_RESET_GPIO
-+#define PCI_RESET_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_0
-+#define PCI_RESET_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_0
-+#define PCI_RESET_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_0
-+#define PCI_RESET_SET_OE_REG GPIO_A_OUTPUT_ENABLE_SET
-+#define PCI_RESET_OUTPUT_SET_REG GPIO_A_OUTPUT_SET
-+#define PCI_RESET_OUTPUT_CLR_REG GPIO_A_OUTPUT_CLEAR
-+#else
-+#define PCI_RESET_NUM ((CONFIG_OXNAS_PCI_RESET_GPIO) - 32)
-+#define PCI_RESET_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_1
-+#define PCI_RESET_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_1
-+#define PCI_RESET_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_1
-+#define PCI_RESET_SET_OE_REG GPIO_B_OUTPUT_ENABLE_SET
-+#define PCI_RESET_OUTPUT_SET_REG GPIO_B_OUTPUT_SET
-+#define PCI_RESET_OUTPUT_CLR_REG GPIO_B_OUTPUT_CLEAR
-+#endif
-+
-+#define PCI_RESET_MASK (1UL << (PCI_RESET_NUM))
-+#endif // CONFIG_OXNAS_PCI_RESET_GPIO
-+
-+#define PCI_CLOCK_NUM 10
-+#define PCI_CLOCK_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_0
-+#define PCI_CLOCK_SET_OE_REG GPIO_A_OUTPUT_ENABLE_SET
-+#define PCI_CLOCK_MASK (1UL << (PCI_CLOCK_NUM))
-+
-+#ifdef CONFIG_OXNAS_SATA_POWER_GPIO_1
-+#if (CONFIG_OXNAS_SATA_POWER_GPIO_1 < 32)
-+#define SATA_POWER_1_NUM CONFIG_OXNAS_SATA_POWER_GPIO_1
-+#define SATA_POWER_1_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_0
-+#define SATA_POWER_1_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_0
-+#define SATA_POWER_1_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_0
-+#define SATA_POWER_1_SET_OE_REG GPIO_A_OUTPUT_ENABLE_SET
-+#define SATA_POWER_1_OUTPUT_SET_REG GPIO_A_OUTPUT_SET
-+#define SATA_POWER_1_OUTPUT_CLR_REG GPIO_A_OUTPUT_CLEAR
-+#else
-+#define SATA_POWER_1_NUM ((CONFIG_OXNAS_SATA_POWER_GPIO_1) - 32)
-+#define SATA_POWER_1_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_1
-+#define SATA_POWER_1_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_1
-+#define SATA_POWER_1_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_1
-+#define SATA_POWER_1_SET_OE_REG GPIO_B_OUTPUT_ENABLE_SET
-+#define SATA_POWER_1_OUTPUT_SET_REG GPIO_B_OUTPUT_SET
-+#define SATA_POWER_1_OUTPUT_CLR_REG GPIO_B_OUTPUT_CLEAR
-+#endif
-+
-+#define SATA_POWER_1_MASK (1UL << (SATA_POWER_1_NUM))
-+#endif // CONFIG_OXNAS_SATA_POWER_GPIO_1
-+
-+#ifdef CONFIG_OXNAS_SATA_POWER_GPIO_2
-+#if (CONFIG_OXNAS_SATA_POWER_GPIO_2 < 32)
-+#define SATA_POWER_2_NUM CONFIG_OXNAS_SATA_POWER_GPIO_2
-+#define SATA_POWER_2_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_0
-+#define SATA_POWER_2_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_0
-+#define SATA_POWER_2_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_0
-+#define SATA_POWER_2_SET_OE_REG GPIO_A_OUTPUT_ENABLE_SET
-+#define SATA_POWER_2_OUTPUT_SET_REG GPIO_A_OUTPUT_SET
-+#define SATA_POWER_2_OUTPUT_CLR_REG GPIO_A_OUTPUT_CLEAR
-+#else
-+#define SATA_POWER_2_NUM ((CONFIG_OXNAS_SATA_POWER_GPIO_2) - 32)
-+#define SATA_POWER_2_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_1
-+#define SATA_POWER_2_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_1
-+#define SATA_POWER_2_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_1
-+#define SATA_POWER_2_SET_OE_REG GPIO_B_OUTPUT_ENABLE_SET
-+#define SATA_POWER_2_OUTPUT_SET_REG GPIO_B_OUTPUT_SET
-+#define SATA_POWER_2_OUTPUT_CLR_REG GPIO_B_OUTPUT_CLEAR
-+#endif
-+
-+#define SATA_POWER_2_MASK (1UL << (SATA_POWER_2_NUM))
-+#endif // CONFIG_OXNAS_SATA_POWER_GPIO_2
-+
-+#ifdef CONFIG_OXNAS_USB_HUB_RESET_GPIO
-+#if (CONFIG_OXNAS_USB_HUB_RESET_GPIO < 32)
-+#define USB_HUB_RESET_NUM CONFIG_OXNAS_USB_HUB_RESET_GPIO
-+#define USB_HUB_RESET_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_0
-+#define USB_HUB_RESET_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_0
-+#define USB_HUB_RESET_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_0
-+#define USB_HUB_RESET_SET_OE_REG GPIO_A_OUTPUT_ENABLE_SET
-+#define USB_HUB_RESET_OUTPUT_SET_REG GPIO_A_OUTPUT_SET
-+#define USB_HUB_RESET_OUTPUT_CLR_REG GPIO_A_OUTPUT_CLEAR
-+#else
-+#define USB_HUB_RESET_NUM ((CONFIG_OXNAS_USB_HUB_RESET_GPIO) - 32)
-+#define USB_HUB_RESET_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_1
-+#define USB_HUB_RESET_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_1
-+#define USB_HUB_RESET_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_1
-+#define USB_HUB_RESET_SET_OE_REG GPIO_B_OUTPUT_ENABLE_SET
-+#define USB_HUB_RESET_OUTPUT_SET_REG GPIO_B_OUTPUT_SET
-+#define USB_HUB_RESET_OUTPUT_CLR_REG GPIO_B_OUTPUT_CLEAR
-+#endif
-+
-+#define USB_HUB_RESET_MASK (1UL << (USB_HUB_RESET_NUM))
-+#endif // CONFIG_OXNAS_USB_HUB_RESET_GPIO
-+
-+extern void oxnas_init_irq(void);
-+extern struct sys_timer oxnas_timer;
-+
-+// The spinlock exported to allow atomic use of GPIO register set
-+spinlock_t oxnas_gpio_spinlock;
-+
-+// To hold LED inversion state
-+int oxnas_global_invert_leds = 0;
-+#include <linux/module.h>
-+EXPORT_SYMBOL(oxnas_global_invert_leds);
-+
-+static struct map_desc oxnas_io_desc[] __initdata = {
-+ { CORE_MODULE_BASE, __phys_to_pfn(CORE_MODULE_BASE_PA), SZ_4K, MT_DEVICE },
-+ { APB_BRIDGE_A_BASE, __phys_to_pfn(APB_BRIDGE_A_BASE_PA), SZ_16M, MT_DEVICE },
-+ { STATIC_CONTROL_BASE, __phys_to_pfn(STATIC_CONTROL_BASE_PA), SZ_4K, MT_DEVICE },
-+ { STATIC_CS0_BASE, __phys_to_pfn(STATIC_CS0_BASE_PA), SZ_4K, MT_DEVICE },
-+ { STATIC_CS1_BASE, __phys_to_pfn(STATIC_CS1_BASE_PA), SZ_4K, MT_DEVICE },
-+ { STATIC_CS2_BASE, __phys_to_pfn(STATIC_CS2_BASE_PA), SZ_4K, MT_DEVICE },
-+ { APB_BRIDGE_B_BASE, __phys_to_pfn(APB_BRIDGE_B_BASE_PA), SZ_16M, MT_DEVICE },
-+ { USB_BASE, __phys_to_pfn(USB_BASE_PA), SZ_4M, MT_DEVICE },
-+ { MAC_BASE, __phys_to_pfn(MAC_BASE_PA), SZ_4M, MT_DEVICE },
-+ { ROM_BASE, __phys_to_pfn(ROM_BASE_PA), SZ_16K, MT_DEVICE },
-+ { PCI_CSRS_BASE, __phys_to_pfn(PCI_CSRS_BASE_PA), SZ_4K, MT_DEVICE }
-+#ifdef CONFIG_SUPPORT_LEON
-+#if (CONFIG_LEON_PAGES == 1)
-+ ,{ LEON_IMAGE_BASE, __phys_to_pfn(LEON_IMAGE_BASE_PA), SZ_4K, MT_DEVICE }
-+#elif (CONFIG_LEON_PAGES == 2)
-+ ,{ LEON_IMAGE_BASE, __phys_to_pfn(LEON_IMAGE_BASE_PA), SZ_8K, MT_DEVICE }
-+#elif (CONFIG_LEON_PAGES == 3)
-+ ,{ LEON_IMAGE_BASE, __phys_to_pfn(LEON_IMAGE_BASE_PA), SZ_8K, MT_DEVICE }
-+ ,{ LEON_IMAGE_BASE+0x2000, __phys_to_pfn(LEON_IMAGE_BASE_PA+0x2000), SZ_4K, MT_DEVICE }
-+#elif (CONFIG_LEON_PAGES == 4)
-+ ,{ LEON_IMAGE_BASE, __phys_to_pfn(LEON_IMAGE_BASE_PA), SZ_8K, MT_DEVICE }
-+ ,{ LEON_IMAGE_BASE+0x2000, __phys_to_pfn(LEON_IMAGE_BASE_PA+0x2000), SZ_8K, MT_DEVICE }
-+#else
-+#error "Unsupported number of Leon code pages"
-+#endif // CONFIG_LEON_PAGES
-+#endif // CONFIG_SUPPORT_LEON
-+ /*
-+ * Upto 8 pages for GMAC/DMA descriptors plus ARM/Leon TSO workspace if
-+ * Leon TSO is in use
-+ */
-+ ,{ SRAM_BASE, __phys_to_pfn(SRAM_PA), SZ_16K, MT_DEVICE }
-+ ,{ SRAM_BASE+0x4000, __phys_to_pfn(SRAM_PA+0x4000), SZ_16K, MT_DEVICE }
-+};
-+
-+static struct resource usb_resources[] = {
-+ [0] = {
-+ .start = USB_BASE_PA,
-+ .end = USB_BASE_PA + 0x10000 - 1,
-+ .flags = IORESOURCE_MEM,
-+ },
-+ [1] = {
-+ .start = USB_FS_INTERRUPT,
-+ .end = USB_FS_INTERRUPT,
-+ .flags = IORESOURCE_IRQ,
-+ },
-+};
-+
-+static u64 usb_dmamask = ~(u32)0;
-+
-+static struct platform_device usb_device = {
-+ .name = "oxnas-ehci",
-+ .id = 0,
-+ .dev = {
-+ .dma_mask = &usb_dmamask,
-+ .coherent_dma_mask = 0xffffffff,
-+ },
-+ .num_resources = ARRAY_SIZE(usb_resources),
-+ .resource = usb_resources,
-+};
-+
-+static struct platform_device *platform_devices[] __initdata = {
-+ &usb_device,
-+};
-+
-+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
-+
-+#define INT_UART_BASE_BAUD (NOMINAL_SYSCLK)
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART1
-+static struct uart_port internal_serial_port_1 = {
-+ .membase = (char *)(UART_1_BASE),
-+ .mapbase = UART_1_BASE_PA,
-+ .irq = UART_1_INTERRUPT,
-+ .flags = STD_COM_FLAGS,
-+ .iotype = UPIO_MEM,
-+ .regshift = 0,
-+ .uartclk = INT_UART_BASE_BAUD,
-+ .line = 0,
-+ .type = PORT_16550A,
-+ .fifosize = 16
-+};
-+#endif // CONFIG_ARCH_OXNAS_UART1
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART2
-+static struct uart_port internal_serial_port_2 = {
-+ .membase = (char *)(UART_2_BASE),
-+ .mapbase = UART_2_BASE_PA,
-+ .irq = UART_2_INTERRUPT,
-+ .flags = STD_COM_FLAGS,
-+ .iotype = UPIO_MEM,
-+ .regshift = 0,
-+ .uartclk = INT_UART_BASE_BAUD,
-+ .line = 0,
-+ .type = PORT_16550A,
-+ .fifosize = 16
-+};
-+#endif // CONFIG_ARCH_OXNAS_UART2
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART3
-+static struct uart_port internal_serial_port_3 = {
-+ .membase = (char *)(UART_3_BASE),
-+ .mapbase = UART_3_BASE_PA,
-+ .irq = UART_3_INTERRUPT,
-+ .flags = STD_COM_FLAGS,
-+ .iotype = UPIO_MEM,
-+ .regshift = 0,
-+ .uartclk = INT_UART_BASE_BAUD,
-+ .line = 0,
-+ .type = PORT_16550A,
-+ .fifosize = 16
-+};
-+#endif // CONFIG_ARCH_OXNAS_UART3
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART4
-+static struct uart_port internal_serial_port_4 = {
-+ .membase = (char *)(UART_4_BASE),
-+ .mapbase = UART_4_BASE_PA,
-+ .irq = UART_4_INTERRUPT,
-+ .flags = STD_COM_FLAGS,
-+ .iotype = UPIO_MEM,
-+ .regshift = 0,
-+ .uartclk = INT_UART_BASE_BAUD,
-+ .line = 0,
-+ .type = PORT_16550A,
-+ .fifosize = 16
-+};
-+#endif // CONFIG_ARCH_OXNAS_UART4
-+
-+static void __init oxnas_mapio(void)
-+{
-+ unsigned int uart_line=0;
-+
-+//printk("oxnas_mapio()\n");
-+
-+ // Setup kernel mappings for hardware cores
-+ iotable_init(oxnas_io_desc, ARRAY_SIZE(oxnas_io_desc));
-+
-+#ifdef CONFIG_ARCH_OXNAS_FPGA
-+ // Setup the ARM926-EJ-S integrator module clock and bus clock divider
-+ asm volatile(
-+ "mov r3,%2,LSL #4;" /* Bus clock divider = ((n+1) << 4) */
-+ "sub r3,r3,#16;"
-+ "mov r0,%1;" /* Processor clock frequency */
-+ "sub r0,r0,#8;" /* correction for MHz */
-+ "and r0,r0,#0xFF;" /* ensure byte value */
-+ "mov r2,%0;" /* read CM base value */
-+ "ldr r1,[r2,#8];" /* read CM_OSC */
-+ "bic r1,r1,#0x0FF;" /* clear bottom byte r1 */
-+ "orr r1,r1,r0;" /* write in new clock values */
-+ "ldr r4,[r2,#0x24];" /* read CM_INIT */
-+ "bic r4,r4,#0x070;" /* clear bits [6:4] */
-+ "orr r4,r4,r3;" /* write in new clock values */
-+ "mov r0,#0xA000;"
-+ "orr r0,r0,#0x5F;" /* build 0xA05F in r0 */
-+ "str r0,[r2,#0x14];" /* write to unlock CM_LOCK */
-+ "str r1,[r2,#8];" /* write value back */
-+ "str r4,[r2,#0x24];" /* write HCLK value back */
-+ "str r1,[r2,#0x14];" /* write in any value to relock CM_LOCK */
-+ :
-+ : "r" (CORE_MODULE_BASE), "r" (CONFIG_OXNAS_CORE_CLK), "r" (CONFIG_OXNAS_CORE_BUS_CLK_DIV)
-+ : "r0","r1","r2","r3","r4");
-+#endif // CONFIG_ARCH_OXNAS_FPGA
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ // Configure the DDR controller arbitration scheme
-+ *(volatile u32*)DDR_ARB_REG = ((1UL << DDR_ARB_DATDIR_NCH_BIT) |
-+ (1UL << DDR_ARB_DATDIR_EN_BIT) |
-+ (1UL << DDR_ARB_REQAGE_EN_BIT) |
-+ (1UL << DDR_ARB_LRUBANK_EN_BIT) |
-+ (1UL << DDR_ARB_MIDBUF_BIT));
-+
-+ // Setup the DDR client read buffers
-+ // NB 0X800 ASIC bug means DMA read buffers should never be enabled
-+ *(volatile u32*)DDR_AHB_REG = ((1UL << DDR_AHB_NO_RCACHE_ARMD_BIT) |
-+ /*(1UL << DDR_AHB_NO_RCACHE_ARMI_BIT) |*/
-+ (1UL << DDR_AHB_NO_RCACHE_COPRO_BIT) |
-+ (1UL << DDR_AHB_NO_RCACHE_DMAA_BIT) |
-+ (1UL << DDR_AHB_NO_RCACHE_DMAB_BIT) |
-+ /* (1UL << DDR_AHB_NO_RCACHE_PCI_BIT) |
-+ (1UL << DDR_AHB_NO_RCACHE_GMAC_BIT) |*/
-+ (1UL << DDR_AHB_NO_RCACHE_USB_BIT));
-+
-+ // Ignore HPROT for all clients except ARM data, as ARM Linux interrupt
-+ // latency will mask any slight delay in data written by cores getting to
-+ // memory after the core raises an interrupt
-+ *(volatile u32*)DDR_AHB2_REG = ((1UL << DDR_AHB2_IGNORE_HPROT_ARMI_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_HPROT_COPRO_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_HPROT_DMAA_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_HPROT_DMAB_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_HPROT_PCI_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_HPROT_GMAC_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_HPROT_USB_BIT));
-+#elif CONFIG_OXNAS_VERSION_0X810
-+ // Configure the DDR controller arbitration scheme
-+ *(volatile u32*)DDR_ARB_REG = ((1UL << DDR_ARB_DATDIR_NCH_BIT) |
-+ (1UL << DDR_ARB_DATDIR_EN_BIT) |
-+ (1UL << DDR_ARB_REQAGE_EN_BIT) |
-+ (1UL << DDR_ARB_LRUBANK_EN_BIT) |
-+ (1UL << DDR_ARB_MIDBUF_BIT));
-+
-+ // Configure read buffers - Do not disable any read buffers
-+ *(volatile u32*)DDR_AHB_REG = 0UL;
-+
-+ // Configure wrapping - Ignore wrap
-+ // Configure HPROT - Ignore all HPROT except ARM data
-+ *(volatile u32*)DDR_AHB2_REG = ((1UL << DDR_AHB2_IGNORE_WRAP_ARMD_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_WRAP_ARMI_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_WRAP_COPRO_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_WRAP_DMAA_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_WRAP_DMAB_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_WRAP_PCI_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_WRAP_GMAC_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_WRAP_US_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_HPROT_ARMI_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_HPROT_COPRO_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_HPROT_DMAA_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_HPROT_DMAB_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_HPROT_PCI_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_HPROT_GMAC_BIT) |
-+ (1UL << DDR_AHB2_IGNORE_HPROT_USB_BIT));
-+
-+ // Configure burst ordering - Do not disable burst ordering
-+ // Configure non-cachable - Do not prevent non-cachable accesses from using read buffers
-+ *(volatile u32*)DDR_AHB3_REG = 0UL;
-+
-+ // Configure read buffer timeout - Do not enable read buffer invalidate after timeout
-+ // Configure write behind - Enable write behind coherency
-+ *(volatile u32*)DDR_AHB4_REG = ((1UL << DDR_AHB4_EN_WRBEHIND_ARMD_BIT) |
-+ (1UL << DDR_AHB4_EN_WRBEHIND_ARMI_BIT) |
-+ (1UL << DDR_AHB4_EN_WRBEHIND_COPRO_BIT) |
-+ (1UL << DDR_AHB4_EN_WRBEHIND_DMAA_BIT) |
-+ (1UL << DDR_AHB4_EN_WRBEHIND_DMAB_BIT) |
-+ (1UL << DDR_AHB4_EN_WRBEHIND_PCI_BIT) |
-+ (1UL << DDR_AHB4_EN_WRBEHIND_GMAC_BIT) |
-+ (1UL << DDR_AHB4_EN_WRBEHIND_USB_BIT));
-+
-+#endif // CONFIG_OXNAS_VERSION_0X8xx
-+
-+ // Enable all DDR client interfaces
-+ *(volatile u32*)DDR_BLKEN_REG |= (((1UL << DDR_BLKEN_CLIENTS_NUM_BITS) - 1) << DDR_BLKEN_CLIENTS_BIT);
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART1
-+ // Block reset UART1
-+ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART1_BIT);
-+ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART1_BIT);
-+
-+ // Route UART1 SOUT onto external pin
-+ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x80000000;
-+ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 &= ~0x80000000;
-+ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |= 0x80000000;
-+
-+ // Route UART1 SIN onto external pin
-+ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_1 &= ~0x00000001;
-+ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_1 &= ~0x00000001;
-+ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_1 |= 0x00000001;
-+
-+ // Setup GPIO line direction for UART1 SOUT
-+ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_SET |= 0x80000000;
-+
-+ // Setup GPIO line direction for UART1 SIN
-+ *(volatile u32*)GPIO_B_OUTPUT_ENABLE_CLEAR |= 0x00000001;
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART1_MODEM
-+ // Route UART1 modem control lines onto external pins
-+ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x78000000;
-+ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 &= ~0x78000000;
-+ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |= 0x78000000;
-+
-+ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_1 &= ~0x00000006;
-+ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_1 &= ~0x00000006;
-+ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_1 |= 0x00000006;
-+
-+ // Setup GPIO line directions for UART1 modem control lines
-+ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_SET |= 0x08000000;
-+ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_CLEAR |= 0x70000000;
-+
-+ *(volatile u32*)GPIO_B_OUTPUT_ENABLE_SET |= 0x00000004;
-+ *(volatile u32*)GPIO_B_OUTPUT_ENABLE_CLEAR |= 0x00000002;
-+#endif // CONFIG_ARCH_OXNAS_UART1_MODEM
-+
-+ // Give Linux a contiguous numbering scheme for available UARTs
-+ internal_serial_port_1.line = uart_line++;
-+ early_serial_setup(&internal_serial_port_1);
-+#endif // CONFIG_ARCH_OXNAS_UART1
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART2
-+ // Block reset UART2
-+ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART2_BIT);
-+ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART2_BIT);
-+
-+ // Route UART2 SIN/SOUT onto external pin
-+ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x00500000;
-+ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 &= ~0x00500000;
-+ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |= 0x00500000;
-+
-+ // Setup GPIO line directions for UART2 SIN/SOUT
-+ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_SET |= 0x00100000;
-+ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_CLEAR |= 0x00400000;
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART2_MODEM
-+ // Route UART2 modem control lines onto external pins
-+ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x07800300;
-+ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 &= ~0x07800300;
-+ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |= 0x07800300;
-+
-+ // Setup GPIO line directions for UART2 modem control lines
-+ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_SET |= 0x02000200;
-+ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_CLEAR |= 0x05800100;
-+#endif // CONFIG_ARCH_OXNAS_UART2_MODEM
-+
-+ // Give Linux a contiguous numbering scheme for available UARTs
-+ internal_serial_port_2.line = uart_line++;
-+ early_serial_setup(&internal_serial_port_2);
-+#endif // CONFIG_ARCH_OXNAS_UART2
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART3
-+ // Block reset UART3
-+ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART3_BIT);
-+ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART3_BIT);
-+
-+ // Route UART3 SIN/SOUT onto external pin
-+ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x000000C0;
-+ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 &= ~0x000000C0;
-+ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |= 0x000000C0;
-+
-+ // Setup GPIO line directions for UART3 SIN/SOUT
-+ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_SET |= 0x00000080;
-+ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_CLEAR |= 0x00000040;
-+
-+ // Enable UART3 interrupt
-+ *(volatile u32*)SYS_CTRL_UART_CTRL |= (1UL << SYS_CTRL_UART3_IQ_EN);
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART3_MODEM
-+ // Route UART3 modem control lines onto external pins
-+ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x0000003f;
-+ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 &= ~0x0000003f;
-+ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |= 0x0000003f;
-+
-+ // Setup GPIO line directions for UART3 modem control lines
-+ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_SET |= 0x00000030;
-+ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_CLEAR |= 0x0000000f;
-+#endif // CONFIG_ARCH_OXNAS_UART3_MODEM
-+
-+ // Give Linux a contiguous numbering scheme for available UARTs
-+ internal_serial_port_3.line = uart_line++;
-+ early_serial_setup(&internal_serial_port_3);
-+#endif // CONFIG_ARCH_OXNAS_UART3
-+
-+#ifdef CONFIG_ARCH_OXNAS_UART4
-+ // Block reset UART4
-+ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART4_BIT);
-+ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART4_BIT);
-+
-+ // Enable UART4 interrupt
-+ *(volatile u32*)SYS_CTRL_UART_CTRL |= (1UL << SYS_CTRL_UART4_IQ_EN);
-+
-+ // Enable UART4 to override PCI functions onto GPIOs
-+ *(volatile u32*)SYS_CTRL_UART_CTRL |= (1UL << SYS_CTRL_UART4_NOT_PCI_MODE);
-+
-+ internal_serial_port_4.line = uart_line++;
-+ early_serial_setup(&internal_serial_port_4);
-+#endif // CONFIG_ARCH_OXNAS_UART4
-+
-+#ifdef CONFIG_PCI
-+ // Block reset PCI core
-+ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_PCI_BIT);
-+ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_PCI_BIT);
-+
-+ // Setup the PCI clock divider
-+ {
-+ static const u32 PCIDIV_MASK = (((1UL << SYS_CTRL_CKCTRL_CTRL_PCIDIV_NUM_BITS) - 1) << SYS_CTRL_CKCTRL_CTRL_PCIDIV_BIT);
-+ *(volatile u32*)SYS_CTRL_CKCTRL_CTRL &= ~PCIDIV_MASK;
-+ *(volatile u32*)SYS_CTRL_CKCTRL_CTRL |= (PCI_CLOCK_DIVIDER << SYS_CTRL_CKCTRL_CTRL_PCIDIV_BIT);
-+ }
-+
-+ // Enable clock to PCI core
-+ *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_PCI_BIT);
-+
-+ // Enable auto-arbitration between static and PCI
-+ *(u32*)SYS_CTRL_PCI_CTRL1 &= ~(1UL << SYSCTL_PCI_CTRL1_SYSPCI_STATIC_REQ);
-+
-+ // Enable primary function on PCI clock line to be looped back
-+ writel(readl(PCI_CLOCK_PRISEL_REG) | PCI_CLOCK_MASK, PCI_CLOCK_PRISEL_REG);
-+
-+ // Enable GPIO output on PCI clock line to be looped back
-+ writel(PCI_CLOCK_MASK, PCI_CLOCK_SET_OE_REG);
-+
-+#ifdef CONFIG_OXNAS_PCI_RESET
-+ // Disable primary, secondary and teriary GPIO functions on PCI reset line
-+ writel(readl(PCI_RESET_PRISEL_REG) & ~PCI_RESET_MASK, PCI_RESET_PRISEL_REG);
-+ writel(readl(PCI_RESET_SECSEL_REG) & ~PCI_RESET_MASK, PCI_RESET_SECSEL_REG);
-+ writel(readl(PCI_RESET_TERSEL_REG) & ~PCI_RESET_MASK, PCI_RESET_TERSEL_REG);
-+
-+ // Assert PCI reset from GPIO line
-+ writel(PCI_RESET_MASK, PCI_RESET_OUTPUT_CLR_REG);
-+
-+ // Enable GPIO output on PCI reset line
-+ writel(PCI_RESET_MASK, PCI_RESET_SET_OE_REG);
-+
-+ // Wait awhile for PCI reset to take effect
-+ mdelay(100);
-+
-+ // Deassert PCI reset from GPIO line
-+ writel(PCI_RESET_MASK, PCI_RESET_OUTPUT_SET_REG);
-+#endif // CONFIG_OXNAS_PCI_RESET
-+#endif // CONFIG_PCI
-+
-+#ifdef CONFIG_OXNAS_SATA_POWER_1
-+ // Disable primary, secondary and teriary GPIO functions on SATA 1 power line
-+ writel(readl(SATA_POWER_1_PRISEL_REG) & ~SATA_POWER_1_MASK, SATA_POWER_1_PRISEL_REG);
-+ writel(readl(SATA_POWER_1_SECSEL_REG) & ~SATA_POWER_1_MASK, SATA_POWER_1_SECSEL_REG);
-+ writel(readl(SATA_POWER_1_TERSEL_REG) & ~SATA_POWER_1_MASK, SATA_POWER_1_TERSEL_REG);
-+
-+ // Enable power to SATA 1
-+ writel(SATA_POWER_1_MASK, SATA_POWER_1_OUTPUT_SET_REG);
-+
-+ // Enable GPIO output on SATA 1 power line
-+ writel(SATA_POWER_1_MASK, SATA_POWER_1_SET_OE_REG);
-+#endif // CONFIG_OXNAS_SATA_POWER_1
-+
-+#ifdef CONFIG_OXNAS_SATA_POWER_2
-+ // Disable primary, secondary and teriary GPIO functions on SATA 2 power line
-+ writel(readl(SATA_POWER_2_PRISEL_REG) & ~SATA_POWER_2_MASK, SATA_POWER_2_PRISEL_REG);
-+ writel(readl(SATA_POWER_2_SECSEL_REG) & ~SATA_POWER_2_MASK, SATA_POWER_2_SECSEL_REG);
-+ writel(readl(SATA_POWER_2_TERSEL_REG) & ~SATA_POWER_2_MASK, SATA_POWER_2_TERSEL_REG);
-+
-+ // Enable power to SATA 2
-+ writel(SATA_POWER_2_MASK, SATA_POWER_2_OUTPUT_SET_REG);
-+
-+ // Enable GPIO output on SATA 2 power line
-+ writel(SATA_POWER_2_MASK, SATA_POWER_2_SET_OE_REG);
-+#endif // CONFIG_OXNAS_SATA_POWER_2
-+
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES_GPIO
-+ // Use GPIO 6 (normally PCI Req 6) for copies instrumentation
-+ #define INSTRUMENT_COPIES_GPIO_MASK ((1UL << 6) | (1UL << 7))
-+
-+ // Enable normal GPIO on line
-+ writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) & ~INSTRUMENT_COPIES_GPIO_MASK, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+ writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0) & ~INSTRUMENT_COPIES_GPIO_MASK, SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+ writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0) & ~INSTRUMENT_COPIES_GPIO_MASK, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+
-+ // Set line inactive to begin with
-+ writel(INSTRUMENT_COPIES_GPIO_MASK, GPIO_A_OUTPUT_CLEAR);
-+
-+ // Enable line as an output
-+ writel(INSTRUMENT_COPIES_GPIO_MASK, GPIO_A_OUTPUT_ENABLE_SET);
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES_GPIO
-+
-+#ifdef CONFIG_OXNAS_USB_CKOUT
-+ // Enable secondary function (USB clock out) on GPIO 10
-+ writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) & ~(1UL << 10), SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+ writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0) | (1UL << 10), SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+#endif // CONFIG_OXNAS_USB_CKOUT
-+
-+#ifdef CONFIG_OXNAS_USB_HUB_RESET_CONTROL
-+ // Disable primary, secondary and teriary GPIO functions on USB hub reset control line
-+ writel(readl(USB_HUB_RESET_PRISEL_REG) & ~USB_HUB_RESET_MASK, USB_HUB_RESET_PRISEL_REG);
-+ writel(readl(USB_HUB_RESET_SECSEL_REG) & ~USB_HUB_RESET_MASK, USB_HUB_RESET_SECSEL_REG);
-+ writel(readl(USB_HUB_RESET_TERSEL_REG) & ~USB_HUB_RESET_MASK, USB_HUB_RESET_TERSEL_REG);
-+
-+#ifdef CONFIG_OXNAS_USB_HUB_RESET_TOGGLE
-+ // Assert USB hub reset
-+ writel(USB_HUB_RESET_MASK, CONFIG_OXNAS_USB_HUB_RESET_ACTIVE_HIGH ? USB_HUB_RESET_OUTPUT_SET_REG : USB_HUB_RESET_OUTPUT_CLR_REG);
-+#else
-+ // Deassert USB hub reset
-+ writel(USB_HUB_RESET_MASK, CONFIG_OXNAS_USB_HUB_RESET_ACTIVE_HIGH ? USB_HUB_RESET_OUTPUT_CLR_REG : USB_HUB_RESET_OUTPUT_SET_REG);
-+#endif // CONFIG_OXNAS_USB_HUB_RESET_TOGGLE
-+
-+ // Enable GPIO output on USB hub reset line
-+ writel(USB_HUB_RESET_MASK, USB_HUB_RESET_SET_OE_REG);
-+
-+#ifdef CONFIG_OXNAS_USB_HUB_RESET_TOGGLE
-+ if (CONFIG_OXNAS_USB_HUB_RESET_PERIOD_MS > 0) {
-+ // Wait for USB hub reset toggle assertion time
-+ mdelay(CONFIG_OXNAS_USB_HUB_RESET_PERIOD_MS);
-+ }
-+
-+ // Deassert USB hub reset
-+ writel(USB_HUB_RESET_MASK, CONFIG_OXNAS_USB_HUB_RESET_ACTIVE_HIGH ? USB_HUB_RESET_OUTPUT_CLR_REG : USB_HUB_RESET_OUTPUT_SET_REG);
-+#endif // CONFIG_OXNAS_USB_HUB_RESET_TOGGLE
-+
-+#endif // CONFIG_OXNAS_USB_HUB_RESET_CONTROL
-+}
-+
-+static void __init oxnas_fixup(
-+ struct machine_desc *desc,
-+ struct tag *tags,
-+ char **cmdline,
-+ struct meminfo *mi)
-+{
-+
-+ mi->nr_banks = 0;
-+ mi->bank[mi->nr_banks].start = SDRAM_PA;
-+ mi->bank[mi->nr_banks].size = SDRAM_SIZE;
-+ mi->bank[mi->nr_banks].node = mi->nr_banks;
-+ ++mi->nr_banks;
-+#ifdef CONFIG_DISCONTIGMEM
-+ mi->bank[mi->nr_banks].start = SRAM_PA;
-+ mi->bank[mi->nr_banks].size = SRAM_SIZE;
-+#ifdef LEON_IMAGE_IN_SRAM
-+ mi->bank[mi->nr_banks].size -= LEON_IMAGE_SIZE;
-+#endif
-+ mi->bank[mi->nr_banks].node = mi->nr_banks;
-+ ++mi->nr_banks;
-+#endif
-+
-+//printk(KERN_NOTICE "%d memory %s\n", mi->nr_banks, (mi->nr_banks > 1) ? "regions" : "region");
-+}
-+
-+#ifdef CONFIG_DO_MEM_TEST
-+static void __init oxnas_asm_copy(void* dst, void* src, u32 length)
-+{
-+ // Assume the length is consistent with transfering 8 quads per load/store
-+ asm volatile(
-+ "1:ldmia %0!, {r3, r4, r5, r6, r7, r8, r9, r12};"
-+ "subs %2, %2, #32;"
-+ "stmia %1!, {r3, r4, r5, r6, r7, r8, r9, r12};"
-+ "bne 1b;"
-+ :
-+ : "r" (src), "r" (dst), "r" (length)
-+ : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r12");
-+}
-+
-+static void __init oxnas_mem_test(void)
-+{
-+ static const unsigned BUFFER_SIZE_CHARS = 16*1024;
-+ static const unsigned BUFFER_ELEMENTS = (BUFFER_SIZE_CHARS / sizeof(unsigned long));
-+
-+ dma_addr_t dma_address;
-+ unsigned long* buffer;
-+
-+ buffer = dma_alloc_coherent(0, BUFFER_SIZE_CHARS, &dma_address, GFP_KERNEL | GFP_DMA);
-+ if (!buffer) {
-+ printk(KERN_ERR "$RFailed to allocate ucached/unbuffered memory test buffer\n");
-+ } else {
-+ static const int ITERATIONS = 10;
-+
-+ unsigned long* buf1 = buffer;
-+ unsigned long* buf2 = buffer + (BUFFER_ELEMENTS/2);
-+ int j;
-+ u32* time1 = (u32*)kmalloc(ITERATIONS *sizeof(u32), GFP_KERNEL);
-+ u32* time2 = (u32*)kmalloc(ITERATIONS *sizeof(u32), GFP_KERNEL);
-+
-+ BUG_ON(!time1 || !time2);
-+
-+ printk("Uncached/unbuffered: src = 0x%08x, dst = 0x%08x, length = %u, elements = %u, dma_address = 0x%08x\n", (u32)buf1, (u32)buf2, BUFFER_SIZE_CHARS/2, BUFFER_ELEMENTS/2, dma_address);
-+
-+ printk("\nAll accesses:\n");
-+ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, 0, 0, 0, 0);
-+
-+ for (j=0; j < ITERATIONS; j++) {
-+ unsigned long* src = buf1;
-+ unsigned long* dst = buf2;
-+// int i;
-+
-+ time1[j] = readl(TIMER2_VALUE);
-+// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+// *dst++ = *src++;
-+// }
-+ time2[j] = readl(TIMER2_VALUE);
-+ }
-+ read_ahb_monitors();
-+ for (j=0; j < ITERATIONS; j++) {
-+ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+ }
-+
-+ printk("\nNon-burst accesses:\n");
-+ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_SINGLE, 0, 0);
-+ for (j=0; j < ITERATIONS; j++) {
-+ unsigned long* src = buf1;
-+ unsigned long* dst = buf2;
-+// int i;
-+
-+ time1[j] = readl(TIMER2_VALUE);
-+// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+// *dst++ = *src++;
-+// }
-+ time2[j] = readl(TIMER2_VALUE);
-+ }
-+ read_ahb_monitors();
-+ for (j=0; j < ITERATIONS; j++) {
-+ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+ }
-+
-+ printk("\nINCR accesses:\n");
-+ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_INCR, 0, 0);
-+ for (j=0; j < ITERATIONS; j++) {
-+ unsigned long* src = buf1;
-+ unsigned long* dst = buf2;
-+// int i;
-+
-+ time1[j] = readl(TIMER2_VALUE);
-+// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+// *dst++ = *src++;
-+// }
-+ time2[j] = readl(TIMER2_VALUE);
-+ }
-+ read_ahb_monitors();
-+ for (j=0; j < ITERATIONS; j++) {
-+ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+ }
-+
-+ printk("\nWRAP4 accesses:\n");
-+ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_WRAP4, 0, 0);
-+ for (j=0; j < ITERATIONS; j++) {
-+ unsigned long* src = buf1;
-+ unsigned long* dst = buf2;
-+// int i;
-+
-+ time1[j] = readl(TIMER2_VALUE);
-+// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+// *dst++ = *src++;
-+// }
-+ time2[j] = readl(TIMER2_VALUE);
-+ }
-+ read_ahb_monitors();
-+ for (j=0; j < ITERATIONS; j++) {
-+ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+ }
-+
-+ printk("\nINCR4 accesses:\n");
-+ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_INCR4, 0, 0);
-+ for (j=0; j < ITERATIONS; j++) {
-+ unsigned long* src = buf1;
-+ unsigned long* dst = buf2;
-+// int i;
-+
-+ time1[j] = readl(TIMER2_VALUE);
-+// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+// *dst++ = *src++;
-+// }
-+ time2[j] = readl(TIMER2_VALUE);
-+ }
-+ read_ahb_monitors();
-+ for (j=0; j < ITERATIONS; j++) {
-+ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+ }
-+
-+ printk("\nWRAP8 accesses:\n");
-+ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_WRAP8, 0, 0);
-+ for (j=0; j < ITERATIONS; j++) {
-+ unsigned long* src = buf1;
-+ unsigned long* dst = buf2;
-+// int i;
-+
-+ time1[j] = readl(TIMER2_VALUE);
-+// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+// *dst++ = *src++;
-+// }
-+ time2[j] = readl(TIMER2_VALUE);
-+ }
-+ read_ahb_monitors();
-+ for (j=0; j < ITERATIONS; j++) {
-+ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+ }
-+
-+ printk("\nINCR8 accesses:\n");
-+ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_INCR8, 0, 0);
-+ for (j=0; j < ITERATIONS; j++) {
-+ unsigned long* src = buf1;
-+ unsigned long* dst = buf2;
-+// int i;
-+
-+ time1[j] = readl(TIMER2_VALUE);
-+// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+// *dst++ = *src++;
-+// }
-+ time2[j] = readl(TIMER2_VALUE);
-+ }
-+ read_ahb_monitors();
-+ for (j=0; j < ITERATIONS; j++) {
-+ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+ }
-+
-+ printk("\nWRAP16 accesses:\n");
-+ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_WRAP16, 0, 0);
-+ for (j=0; j < ITERATIONS; j++) {
-+ unsigned long* src = buf1;
-+ unsigned long* dst = buf2;
-+// int i;
-+
-+ time1[j] = readl(TIMER2_VALUE);
-+// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+// *dst++ = *src++;
-+// }
-+ time2[j] = readl(TIMER2_VALUE);
-+ }
-+ read_ahb_monitors();
-+ for (j=0; j < ITERATIONS; j++) {
-+ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+ }
-+
-+ printk("\nINCR16 accesses:\n");
-+ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_INCR16, 0, 0);
-+ for (j=0; j < ITERATIONS; j++) {
-+ unsigned long* src = buf1;
-+ unsigned long* dst = buf2;
-+// int i;
-+
-+ time1[j] = readl(TIMER2_VALUE);
-+// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+// *dst++ = *src++;
-+// }
-+ time2[j] = readl(TIMER2_VALUE);
-+ }
-+ read_ahb_monitors();
-+ for (j=0; j < ITERATIONS; j++) {
-+ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+ }
-+
-+ dma_free_coherent(0, BUFFER_SIZE_CHARS, buffer, dma_address);
-+
-+ kfree(time1);
-+ kfree(time2);
-+ }
-+
-+ buffer = kmalloc(BUFFER_SIZE_CHARS, GFP_KERNEL | GFP_DMA);
-+ if (!buffer) {
-+ printk(KERN_ERR "$RFailed to allocate cached memory test buffer\n");
-+ } else {
-+ static const int ITERATIONS = 100;
-+
-+ unsigned long* buf1 = buffer;
-+ unsigned long* buf2 = buffer + (BUFFER_ELEMENTS/2);
-+ unsigned long* src = buf1;
-+ unsigned long* dst = buf2;
-+ int j;
-+ u32* time1 = (u32*)kmalloc(ITERATIONS *sizeof(u32), GFP_KERNEL);
-+ u32* time2 = (u32*)kmalloc(ITERATIONS *sizeof(u32), GFP_KERNEL);
-+
-+ BUG_ON(!time1 || !time2);
-+
-+ printk("Cached/: src = 0x%08x, dst = 0x%08x, length = %u, elements = %u\n", (u32)buf1, (u32)buf2, BUFFER_SIZE_CHARS/2, BUFFER_ELEMENTS/2);
-+
-+ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, 0, 0, 0, 0);
-+
-+ // Measure the first cached iteration separately
-+ printk("1st iteration:\n");
-+ restart_ahb_monitors();
-+ time1[0] = readl(TIMER2_VALUE);
-+// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+// *dst++ = *src++;
-+// }
-+ time2[0] = readl(TIMER2_VALUE);
-+ read_ahb_monitors();
-+ printk("%u->%lu Bytes/s\n", time1[0]-time2[0], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[0]-time2[0]));
-+
-+ printk("Subsequent iterations:\n");
-+ restart_ahb_monitors();
-+ for (j=1; j < ITERATIONS; j++) {
-+ src = buf1;
-+ dst = buf2;
-+// int i;
-+
-+ time1[j] = readl(TIMER2_VALUE);
-+// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
-+ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
-+// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
-+// *dst++ = *src++;
-+// }
-+ time2[j] = readl(TIMER2_VALUE);
-+ }
-+ read_ahb_monitors();
-+
-+ for (j=1; j < ITERATIONS; j++) {
-+ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
-+ }
-+
-+ kfree(time1);
-+ kfree(time2);
-+
-+ kfree(buffer);
-+ }
-+}
-+#endif // CONFIG_DO_MEM_TEST
-+
-+#ifdef CONFIG_OXNAS_LED_TEST
-+
-+#define LED_D1 (1UL << 6)
-+#define LED_D2 (1UL << 7)
-+#define LED_D3 (1UL << 13)
-+#define LED_D4 (1UL << 14)
-+#define LED_D5 (1UL << 19)
-+#define LED_D6 (1UL << 21)
-+#define LED_D7 (1UL << 25)
-+#define LED_D8 (1UL << 26)
-+#define LED_D9 (1UL << 27)
-+#define FIRST_LEDS_MASK (LED_D1 | LED_D2 | LED_D3 | LED_D4 | LED_D5 | LED_D6 | LED_D7 | LED_D8 | LED_D9)
-+
-+#define LED_D10 (1UL << 1)
-+#define SECOND_LEDS_MASK (LED_D10)
-+
-+#define PWM_MASK (1UL << 8)
-+
-+static void test_leds_and_pwm(void)
-+{
-+ // Disable primary, secondary and teriary GPIO functions for first nine LEDS
-+ writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) & ~FIRST_LEDS_MASK, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+ writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0) & ~FIRST_LEDS_MASK, SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+ writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0) & ~FIRST_LEDS_MASK, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+
-+ // Disable primary, secondary and teriary GPIO functions for last LED
-+ writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_1) & ~SECOND_LEDS_MASK, SYS_CTRL_GPIO_PRIMSEL_CTRL_1);
-+ writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_1) & ~SECOND_LEDS_MASK, SYS_CTRL_GPIO_SECSEL_CTRL_1);
-+ writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_1) & ~SECOND_LEDS_MASK, SYS_CTRL_GPIO_TERTSEL_CTRL_1);
-+
-+ // Turn off first nine LEDs
-+ writel(FIRST_LEDS_MASK, GPIO_A_OUTPUT_SET);
-+
-+ // Turn off tenth LED
-+ writel(SECOND_LEDS_MASK, GPIO_B_OUTPUT_SET);
-+
-+ // Enable first nine LEDs as outputs
-+ writel(FIRST_LEDS_MASK, GPIO_A_OUTPUT_ENABLE_SET);
-+
-+ // Enable tenth LED as output
-+ writel(SECOND_LEDS_MASK, GPIO_B_OUTPUT_ENABLE_SET);
-+
-+ // Turn on first nine LEDs sequentially
-+ mdelay(1000);
-+ writel(LED_D1, GPIO_A_OUTPUT_CLEAR);
-+ mdelay(1000);
-+ writel(LED_D2, GPIO_A_OUTPUT_CLEAR);
-+ mdelay(1000);
-+ writel(LED_D3, GPIO_A_OUTPUT_CLEAR);
-+ mdelay(1000);
-+ writel(LED_D4, GPIO_A_OUTPUT_CLEAR);
-+ mdelay(1000);
-+ writel(LED_D5, GPIO_A_OUTPUT_CLEAR);
-+ mdelay(1000);
-+ writel(LED_D6, GPIO_A_OUTPUT_CLEAR);
-+ mdelay(1000);
-+ writel(LED_D7, GPIO_A_OUTPUT_CLEAR);
-+ mdelay(1000);
-+ writel(LED_D8, GPIO_A_OUTPUT_CLEAR);
-+ mdelay(1000);
-+ writel(LED_D9, GPIO_A_OUTPUT_CLEAR);
-+
-+ // Turn on tenth LED
-+ mdelay(1000);
-+ writel(LED_D10, GPIO_B_OUTPUT_CLEAR);
-+
-+ // Disable primary, secondary and teriary GPIO functions for PWN line
-+ writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) & ~PWM_MASK, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+ writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0) & ~PWM_MASK, SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+ writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0) & ~PWM_MASK, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+
-+ // Turn off PWM line
-+ writel(PWM_MASK, GPIO_A_OUTPUT_SET);
-+
-+ // Enable PWM line as output
-+ writel(PWM_MASK, GPIO_A_OUTPUT_ENABLE_SET);
-+
-+ // Turn on PWM line
-+ mdelay(1000);
-+ writel(PWM_MASK, GPIO_A_OUTPUT_CLEAR);
-+}
-+#endif // CONFIG_OXNAS_LED_TEST
-+
-+static void __init oxnas_init_machine(void)
-+{
-+//printk("oxnas_init_machine()\n");
-+ /* Initialise the spinlock used to make GPIO register set access atomic */
-+ spin_lock_init(&oxnas_gpio_spinlock);
-+
-+ /*
-+ * Initialise the support for our multi-channel memory-to-memory DMAC
-+ * The interrupt subsystem needs to be available before we can initialise
-+ * the DMAC support
-+ */
-+ oxnas_dma_init();
-+
-+#ifdef CONFIG_DO_MEM_TEST
-+ /*
-+ * Do memory performance test
-+ */
-+ oxnas_mem_test();
-+#endif // CONFIG_DO_MEM_TEST
-+
-+#ifdef CONFIG_LEON_START_EARLY
-+ init_copro(leon_early_srec, 0);
-+#endif // CONFIG_LEON_START_EARLY
-+
-+#ifdef CONFIG_OXNAS_LED_TEST
-+ test_leds_and_pwm();
-+#endif // CONFIG_OXNAS_LED_TEST
-+
-+ // Add any platform bus devices
-+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-+}
-+
-+void sata_power_off(void)
-+{
-+#ifdef CONFIG_OXNAS_SATA_POWER_1
-+ // Disable power to SATA 1
-+ printk(KERN_INFO "Turning off disk 1\n");
-+ writel(SATA_POWER_1_MASK, SATA_POWER_1_OUTPUT_CLR_REG);
-+#endif // CONFIG_OXNAS_SATA_POWER_1
-+
-+#ifdef CONFIG_OXNAS_SATA_POWER_2
-+ // Disable power to SATA 2
-+ printk(KERN_INFO "Turning off disk 2\n");
-+ writel(SATA_POWER_2_MASK, SATA_POWER_2_OUTPUT_CLR_REG);
-+#endif // CONFIG_OXNAS_SATA_POWER_2
-+}
-+
-+MACHINE_START(OXNAS, "Oxsemi NAS")
-+ /* Maintainer: Oxford Semiconductor Ltd */
-+#ifdef CONFIG_ARCH_OXNAS_UART1
-+ .phys_io = UART_1_BASE_PA,
-+ .io_pg_offst = (((u32)UART_1_BASE) >> 18) & 0xfffc,
-+#elif defined(CONFIG_ARCH_OXNAS_UART2)
-+ .phys_io = UART_2_BASE_PA,
-+ .io_pg_offst = (((u32)UART_2_BASE) >> 18) & 0xfffc,
-+#elif defined(CONFIG_ARCH_OXNAS_UART3)
-+ .phys_io = UART_3_BASE_PA,
-+ .io_pg_offst = (((u32)UART_3_BASE) >> 18) & 0xfffc,
-+#elif defined(CONFIG_ARCH_OXNAS_UART4)
-+ .phys_io = UART_4_BASE_PA,
-+ .io_pg_offst = (((u32)UART_4_BASE) >> 18) & 0xfffc,
-+#endif
-+ .boot_params = SDRAM_PA + 0x100,
-+ .fixup = oxnas_fixup,
-+ .map_io = oxnas_mapio,
-+ .init_irq = oxnas_init_irq,
-+ .timer = &oxnas_timer,
-+ .init_machine = oxnas_init_machine,
-+MACHINE_END
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/pci.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/pci.c
---- linux-2.6.24/arch/arm/mach-oxnas/pci.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/pci.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,678 @@
-+/*
-+ * arch/arm/mach-oxnas/pci.c
-+ *
-+ * Copyright (C) 2006 Oxford Semiconductor Ltd
-+ *
-+ * 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 <linux/kernel.h>
-+
-+#include <linux/pci.h>
-+#include <linux/ptrace.h>
-+#include <linux/interrupt.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+
-+#include <asm/io.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/system.h>
-+#include <asm/mach/pci.h>
-+#include <asm/mach-types.h>
-+
-+#ifndef CONFIG_PCI
-+
-+inline void outb(unsigned char v, u32 p) { *((volatile u8*)(__io(p))) = (v); }
-+inline void outw(unsigned short v, u32 p) { *((volatile u16*)(__io(p))) = cpu_to_le16(v); }
-+inline void outl(unsigned long v, u32 p) { *((volatile u32*)(__io(p))) = cpu_to_le32(v); }
-+
-+inline unsigned char inb(u32 p) { return (*((volatile u8*)(__io(p)))); }
-+inline unsigned short inw(u32 p) { return le16_to_cpu(*((volatile u16*)(__io(p)))); }
-+inline unsigned long inl(u32 p) { return le32_to_cpu(*((volatile u32*)(__io(p)))); }
-+
-+inline void outsb(u32 p, unsigned char * from, u32 len) { while (len--) { outb((*from++),(p) ); } }
-+inline void outsw(u32 p, unsigned short * from, u32 len) { while (len--) { outw((*from++),(p) ); } }
-+inline void outsl(u32 p, unsigned long * from, u32 len) { while (len--) { outl((*from++),(p) ); } }
-+
-+inline void insb(u32 p, unsigned char * to, u32 len) { while (len--) { *to++ = inb(p); } }
-+inline void insw(u32 p, unsigned short * to, u32 len) { while (len--) { *to++ = inw(p); } }
-+inline void insl(u32 p, unsigned long * to, u32 len) { while (len--) { *to++ = inl(p); } }
-+
-+EXPORT_SYMBOL( inb );
-+EXPORT_SYMBOL( inw );
-+EXPORT_SYMBOL( inl );
-+
-+EXPORT_SYMBOL( outb );
-+EXPORT_SYMBOL( outw );
-+EXPORT_SYMBOL( outl );
-+
-+EXPORT_SYMBOL( insb );
-+EXPORT_SYMBOL( insw );
-+EXPORT_SYMBOL( insl );
-+
-+EXPORT_SYMBOL( outsb );
-+EXPORT_SYMBOL( outsw );
-+EXPORT_SYMBOL( outsl );
-+
-+#else // #ifdef CONFIG_PCI
-+
-+extern spinlock_t oxnas_gpio_spinlock;
-+
-+#define PCI_BUS_NONMEM_START 0x00000000
-+#define PCI_BUS_NONMEM_SIZE 0x00080000
-+
-+
-+#define PCI_BUS_PREMEM_START PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE
-+#define PCI_BUS_PREMEM_SIZE 0x00080000
-+
-+#define SYNOPSYS_PCI_MEMORY_BASE_ADDRESS PCI_BASE_ADDRESS_0
-+#define SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS PCI_BASE_ADDRESS_2
-+#define SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS PCI_BASE_ADDRESS_1 // PLEASE NOTE - THESE ARE INCORRECT IN THE DOCUMENT!!
-+
-+
-+inline void outb(unsigned char v, u32 p) { pciio_write(v,(u32)__io(p), sizeof(char ) ); }
-+inline void outw(unsigned short v, u32 p) { pciio_write(cpu_to_le16(v),(u32)__io(p),sizeof(short) ); }
-+inline void outl(unsigned long v, u32 p) { pciio_write(cpu_to_le32(v),(u32)__io(p),sizeof(long ) ); }
-+
-+inline unsigned char inb(u32 p) { unsigned int __v = (pciio_read((u32)__io(p),sizeof(char ))); return __v; }
-+inline unsigned short inw(u32 p) { unsigned int __v = le16_to_cpu(pciio_read((u32)__io(p),sizeof(short))); return __v; }
-+inline unsigned long inl(u32 p) { unsigned int __v = le32_to_cpu(pciio_read((u32)__io(p),sizeof(long ))); return __v; }
-+
-+inline void outsb(volatile u32 p, unsigned char * from, u32 len) { while (len--) { pciio_write( (*from++),(u32)__io(p),sizeof(char ) ); } }
-+inline void outsw(volatile u32 p, unsigned short * from, u32 len) { while (len--) { pciio_write(cpu_to_le16(*from++),(u32)__io(p),sizeof(short) ); } }
-+inline void outsl(volatile u32 p, unsigned long * from, u32 len) { while (len--) { pciio_write(cpu_to_le32(*from++),(u32)__io(p),sizeof(long ) ); } }
-+
-+inline void insb(volatile u32 p, unsigned char * to, u32 len) { while (len--) { *to++ = (pciio_read((u32)__io(p),sizeof(char ))); } }
-+inline void insw(volatile u32 p, unsigned short * to, u32 len) { while (len--) { *to++ = le16_to_cpu(pciio_read((u32)__io(p),sizeof(short))); } }
-+inline void insl(volatile u32 p, unsigned long * to, u32 len) { while (len--) { *to++ = le32_to_cpu(pciio_read((u32)__io(p),sizeof(long ))); } }
-+
-+EXPORT_SYMBOL( inb );
-+EXPORT_SYMBOL( inw );
-+EXPORT_SYMBOL( inl );
-+
-+EXPORT_SYMBOL( outb );
-+EXPORT_SYMBOL( outw );
-+EXPORT_SYMBOL( outl );
-+
-+EXPORT_SYMBOL( insb );
-+EXPORT_SYMBOL( insw );
-+EXPORT_SYMBOL( insl );
-+
-+EXPORT_SYMBOL( outsb );
-+EXPORT_SYMBOL( outsw );
-+EXPORT_SYMBOL( outsl );
-+
-+EXPORT_SYMBOL( pciio_read );
-+EXPORT_SYMBOL( pciio_write );
-+
-+static spinlock_t oxnas_lock = SPIN_LOCK_UNLOCKED;
-+
-+//static int oxnas_pci_read_core_config( unsigned int config_register )
-+//{
-+// unsigned long val, flags;
-+// //printk(KERN_DEBUG "PCI: oxnas_pci_read_core_config( 0x%x )\n", config_register );
-+// spin_lock_irqsave(&oxnas_lock, flags);
-+// writel(
-+// 0x00 << PCI_CRP_BYTE_ENABLES_START |
-+// PCI_BUS_CMD_CONFIGURATION_READ << PCI_CRP_CMD_START |
-+// config_register << PCI_CRP_ADDRESS_START,
-+// PCI_CRP_CMD_AND_ADDR );
-+// wmb();
-+// val = readl( PCI_CRP_READ_DATA );
-+// spin_unlock_irqrestore(&oxnas_lock, flags);
-+// return val;
-+//}
-+
-+
-+static void oxnas_pci_write_core_config( unsigned int value, unsigned int config_register )
-+{
-+ unsigned long flags;
-+
-+ //printk(KERN_DEBUG "PCI: oxnas_pci_write_core_config( 0x%x, 0x%x )\n", config_register , value);
-+ /* printk(KERN_DEBUG "PCI: writel( 0x%lx, 0x%lx )\n",
-+ 0x00 << PCI_CRP_BYTE_ENABLES_START |
-+ PCI_BUS_CMD_CONFIGURATION_WRITE << PCI_CRP_CMD_START |
-+ config_register << PCI_CRP_ADDRESS_START,
-+ PCI_CRP_CMD_AND_ADDR ); */
-+
-+ spin_lock_irqsave(&oxnas_lock, flags);
-+ writel(
-+ 0x00 << PCI_CRP_BYTE_ENABLES_START |
-+ PCI_BUS_CMD_CONFIGURATION_WRITE << PCI_CRP_CMD_START |
-+ config_register << PCI_CRP_ADDRESS_START,
-+ PCI_CRP_CMD_AND_ADDR );
-+ wmb();
-+
-+ // printk(KERN_DEBUG "PCI: writel( 0x%lx, 0x%lx )\n", value, PCI_CRP_WRITE_DATA );
-+ writel( value, PCI_CRP_WRITE_DATA );
-+ spin_unlock_irqrestore(&oxnas_lock, flags);
-+}
-+
-+
-+
-+inline unsigned int CheckAndClearBusError(void)
-+{
-+ unsigned int value = readl( PCI_ERROR_MSG ) & 0x00000003;
-+ if ( value )
-+ {
-+// printk(KERN_DEBUG "PCI: %s ERROR ON PCI BUS Clearing error\n", value & 0x00000001 ? "FATAL" : "PARITY" );
-+ writel( ( value ), PCI_ERROR_MSG );
-+ }
-+
-+ return value;
-+}
-+
-+
-+void pciio_write(unsigned int data, u32 addr, unsigned int size)
-+{
-+ // setup byte enables
-+ unsigned long flags;
-+ unsigned int be = 0x0000000f >> (4-size);
-+ unsigned int trunc = (addr & 0x00000003);
-+ be <<= trunc;
-+ be = (~be) & 0x00000000f;
-+
-+
-+ data &= (0xffffffff >> ((4-size)*8));
-+ data <<= (trunc*8);
-+
-+ //printk(KERN_DEBUG "$YPCI: pciio_write( 0x%08x = 0x%08x (%x:%x) )\n", addr, data, size, be);
-+
-+ /* Setup the io read address (rounded down to word boundry) */
-+ spin_lock_irqsave(&oxnas_lock, flags);
-+ writel( addr , PCI_CONFIG_IO_CYCLE_ADDR );
-+ wmb();
-+
-+ /* issue the config io read command to the config io cmd reg */
-+ writel( ( be << PCI_CONFIG_IO_BYTE_ENABLES_START) |
-+ ( PCI_BUS_CMD_IO_WRITE << PCI_CONFIG_IO_CMD_START ),
-+ PCI_CONFIG_IO_BYTE_CMD );
-+ wmb();
-+
-+ writel( data, PCI_CONFIG_IO_WRITE_DATA );
-+
-+ if ( CheckAndClearBusError() )
-+ {
-+ printk(KERN_DEBUG "PCI: failed to write io\n");
-+ }
-+ spin_unlock_irqrestore(&oxnas_lock, flags);
-+}
-+
-+
-+unsigned int pciio_read(u32 addr, unsigned int size)
-+{
-+ // setup byte enables
-+ unsigned long flags;
-+ unsigned int be = 0x0000000f >> (4-size);
-+ unsigned int trunc = (addr & 0x00000003);
-+ be <<= trunc;
-+ be = (~be) & 0x00000000f;
-+
-+
-+ //printk(KERN_DEBUG "$YPCI: pciio_read[ 0x%x ] ( 0x%x == ", size, addr );
-+
-+ /* Setup the io read address (rounded down to word boundry) */
-+ spin_lock_irqsave(&oxnas_lock, flags);
-+ writel( addr, PCI_CONFIG_IO_CYCLE_ADDR );
-+ wmb();
-+
-+ /* issue the config io read command to the config io cmd reg */
-+ writel( ( be << PCI_CONFIG_IO_BYTE_ENABLES_START) |
-+ ( PCI_BUS_CMD_IO_READ << PCI_CONFIG_IO_CMD_START ),
-+ PCI_CONFIG_IO_BYTE_CMD );
-+ wmb();
-+
-+ if ( CheckAndClearBusError() )
-+ {
-+ printk(KERN_DEBUG "PCI: failed to read io\n");
-+ }
-+
-+ be = readl( PCI_CONFIG_IO_READ_DATA );
-+ //printk("0x%x )\n", be);
-+
-+ if ( CheckAndClearBusError() )
-+ {
-+ printk(KERN_DEBUG "PCI: failed to read io\n");
-+ }
-+
-+ spin_unlock_irqrestore(&oxnas_lock, flags);
-+
-+ be >>= (trunc*8);
-+ be &= (0xffffffff >> ((4-size)*8));
-+
-+
-+ return be;
-+}
-+
-+
-+static int oxnas_read_config(struct pci_bus *bus, unsigned int devfn, int where,
-+ int size, u32 *value)
-+{
-+ // unsigned long flags;
-+ unsigned long flags;
-+ unsigned int temp;
-+ unsigned long addr = ( 0x00000800 << (PCI_SLOT(devfn)-1) ) |
-+ ( PCI_FUNC(devfn) << 8 ) |
-+ ( where & 0xfc );
-+
-+ /* Setup the config io read address (rounded down to word boundry) */
-+ temp = addr;
-+
-+ // printk(KERN_DEBUG "PCI: %s::%u oxnas_read_config( %u, %d, %d, )\n", bus->name, bus->number, devfn, where, size );
-+ spin_lock_irqsave(&oxnas_lock, flags);
-+ CheckAndClearBusError();
-+
-+ // printk(KERN_DEBUG "PCI: writel( 0x%08lx, 0x%08lx)\n", temp, PCI_CONFIG_IO_CYCLE_ADDR );
-+ writel( temp, PCI_CONFIG_IO_CYCLE_ADDR );
-+ wmb();
-+
-+ /* issue the config io read command to the config io cmd reg */
-+ temp = ( ( 0x00 << PCI_CONFIG_IO_BYTE_ENABLES_START) |
-+ ( PCI_BUS_CMD_CONFIGURATION_READ << PCI_CONFIG_IO_CMD_START ) );
-+ // printk(KERN_DEBUG "PCI: writel( 0x%08lx, 0x%08lx)\n", temp, PCI_CONFIG_IO_BYTE_CMD);
-+ writel( temp, PCI_CONFIG_IO_BYTE_CMD );
-+ wmb();
-+
-+ if ( CheckAndClearBusError() )
-+ {
-+ spin_unlock_irqrestore(&oxnas_lock, flags);
-+// printk(KERN_DEBUG "PCI: failed to read config\n" );
-+ *value = 0xffffffff;
-+ return PCIBIOS_DEVICE_NOT_FOUND;
-+ }
-+
-+ wmb();
-+ *value=readl(PCI_CONFIG_IO_READ_DATA);
-+ spin_unlock_irqrestore(&oxnas_lock, flags);
-+
-+ /* Read the result from the config io read data reg */
-+ switch (size) {
-+ case 1:
-+ // printk(KERN_DEBUG "PCI: readb( 0x%lx )\n", PCI_CONFIG_IO_READ_DATA );
-+ *value>>=(where&3);
-+ *value&=0x000000ff;
-+ break;
-+ case 2:
-+ // printk(KERN_DEBUG "PCI: readw( 0x%lx )\n", PCI_CONFIG_IO_READ_DATA );
-+ *value>>=(where&2);
-+ *value&=0x0000ffff;
-+ break;
-+ case 4:
-+ // printk(KERN_DEBUG "PCI: readl( 0x%lx )\n", PCI_CONFIG_IO_READ_DATA );
-+ break;
-+ }
-+ // printk(KERN_DEBUG "PCI: $Goxnas_read_config_%s( 0x%lx ) == 0x%lx\n",
-+ // size == 1 ? "byte" : size == 2 ? "short" : "word",
-+ // (unsigned long) addr,
-+ // (unsigned long) *value);
-+
-+ return PCIBIOS_SUCCESSFUL;
-+}
-+
-+static int oxnas_write_config(struct pci_bus *bus, unsigned int devfn, int where,
-+ int size, u32 value)
-+{
-+ unsigned long flags;
-+ unsigned long byteEnables = ~(( 0xffffffff >> (32 - size) ) << (where&3));
-+ unsigned long addr = ( 0x00000800 << (PCI_SLOT(devfn)-1) ) |
-+ ( PCI_FUNC(devfn) << 8 ) |
-+ ( where & 0xfc );
-+ value <<= 8*(where & 0x00000003);
-+
-+ // printk(KERN_DEBUG "$GPCI: %s::%u oxnas_write_config_%s( 0x%lx, 0x%lx & 0x%lx)\n",
-+ // bus->name,
-+ // bus->number,
-+ // size == 1 ? "byte" : size == 2 ? "short" : "word",
-+ // (unsigned long) addr,
-+ // (unsigned long) value,
-+ // (unsigned long) byteEnables );
-+
-+ if ( PCI_SLOT(devfn) > 15 )
-+ {
-+ /* only 16 devices supported */
-+ return PCIBIOS_DEVICE_NOT_FOUND;
-+ }
-+
-+
-+ spin_lock_irqsave(&oxnas_lock, flags);
-+ CheckAndClearBusError();
-+
-+ /* Setup the config io read address (rounded down to word boundry) */
-+ // printk(KERN_DEBUG "PCI: writel( 0x%lx, 0x%lx)\n", addr, PCI_CONFIG_IO_CYCLE_ADDR );
-+ writel( addr, PCI_CONFIG_IO_CYCLE_ADDR );
-+ wmb();
-+
-+ /* issue the config io read command to the config io cmd reg */
-+ // printk(KERN_DEBUG "PCI: writel( 0x%lx, 0x%lx )\n",
-+ // ( (byteEnables & 0xf) << PCI_CONFIG_IO_BYTE_ENABLES_START) |
-+ // ( PCI_BUS_CMD_CONFIGURATION_WRITE << PCI_CONFIG_IO_CMD_START ),
-+ // PCI_CONFIG_IO_BYTE_CMD );
-+
-+ writel( ( (byteEnables & 0xf) << PCI_CONFIG_IO_BYTE_ENABLES_START) |
-+ ( PCI_BUS_CMD_CONFIGURATION_WRITE << PCI_CONFIG_IO_CMD_START ),
-+ PCI_CONFIG_IO_BYTE_CMD );
-+ wmb();
-+
-+ /* write the value... */
-+ // printk(KERN_DEBUG "PCI: writel( 0x%lx, 0x%lx )\n", value, PCI_CONFIG_IO_WRITE_DATA );
-+ writel( value, PCI_CONFIG_IO_WRITE_DATA );
-+ wmb();
-+
-+ if ( CheckAndClearBusError() )
-+ {
-+ printk(KERN_DEBUG "PCI: failed to write config\n");
-+ return PCIBIOS_DEVICE_NOT_FOUND;
-+ }
-+
-+ spin_unlock_irqrestore(&oxnas_lock, flags);
-+ return PCIBIOS_SUCCESSFUL;
-+}
-+
-+
-+// #if PCI_BUS_NONMEM_START & 0x000fffff
-+// #error PCI_BUS_NONMEM_START must be megabyte aligned
-+// #endif
-+// #if PCI_BUS_PREMEM_START & 0x000fffff
-+// #error PCI_BUS_PREMEM_START must be megabyte aligned
-+// #endif
-+//
-+
-+static struct resource io_mem = {
-+ .name = "PCI I/O Space",
-+ .start = 0x00001000,
-+ .end = 0xffff0000,
-+ .flags = IORESOURCE_IO,
-+};
-+
-+static struct resource non_mem = {
-+ .name = "PCI non-prefetchable",
-+ .start = PCI_BASE_PA + PCI_BUS_NONMEM_START,
-+ .end = PCI_BASE_PA + PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE - 1,
-+ .flags = IORESOURCE_MEM,
-+};
-+
-+static struct resource pre_mem = {
-+ .name = "PCI prefetchable",
-+ .start = PCI_BASE_PA + PCI_BUS_PREMEM_START,
-+ .end = PCI_BASE_PA + PCI_BUS_PREMEM_START + PCI_BUS_PREMEM_SIZE - 1,
-+ .flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,
-+};
-+
-+
-+/*
-+ * This routine handles multiple bridges.
-+ */
-+static u8 __init oxnas_swizzle(struct pci_dev *dev, u8 *pinp)
-+{
-+// printk(KERN_DEBUG "PCI: oxnas_swizzle\n");
-+ return pci_std_swizzle(dev, pinp);
-+}
-+
-+
-+// static int irq_tab[4] __initdata = {
-+// IRQ_AP_PCIINT0, IRQ_AP_PCIINT1, IRQ_AP_PCIINT2, IRQ_AP_PCIINT3
-+// };
-+
-+
-+/*
-+ * map the specified device/slot/pin to an IRQ. This works out such
-+ * that ..
-+ */
-+static int __init oxnas_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-+{
-+ BUG_ON(pin < 1 || pin > 4);
-+
-+// printk(KERN_DEBUG "PCI: oxnas_map_irq %d,%d,%d = %d\n", dev->bus->number, dev->devfn, slot, PCI_A_INTERRUPT /*pci_irq_table[pin-1]*/ );
-+ return PCI_A_INTERRUPT;
-+}
-+
-+
-+static int __init oxnas_pci_setup_resources(struct resource **resource)
-+{
-+ /*
-+ * bus->resource[0] is the IO resource for this bus
-+ * bus->resource[1] is the mem resource for this bus
-+ * bus->resource[2] is the prefetch mem resource for this bus
-+ */
-+
-+ resource[0] = &io_mem;
-+ resource[1] = &pre_mem;
-+ resource[2] = &non_mem;
-+
-+ // these regions apply to incomming transactions on PCI
-+ oxnas_pci_write_core_config( 0xffffffff , SYNOPSYS_PCI_MEMORY_BASE_ADDRESS );
-+ oxnas_pci_write_core_config( 0xffffffff , SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS );
-+ oxnas_pci_write_core_config( 0xffffffff , SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS );
-+
-+// printk(KERN_DEBUG "PCI: SYNOPSYS_PCI_MEMORY_BASE_ADDRESS $YWindow Size == 0x%08x\n", (u32) oxnas_pci_read_core_config(SYNOPSYS_PCI_MEMORY_BASE_ADDRESS ) );
-+// printk(KERN_DEBUG "PCI: SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS $YWindow Size == 0x%08x\n", (u32) oxnas_pci_read_core_config(SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS ) );
-+// printk(KERN_DEBUG "PCI: SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS $YWindow Size == 0x%08x\n", (u32) oxnas_pci_read_core_config(SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS ) );
-+
-+ oxnas_pci_write_core_config( SDRAM_PA , SYNOPSYS_PCI_MEMORY_BASE_ADDRESS );
-+ oxnas_pci_write_core_config( SDRAM_PA , SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS );
-+ oxnas_pci_write_core_config( SDRAM_PA , SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS );
-+
-+// printk(KERN_DEBUG "PCI: SYNOPSYS_PCI_MEMORY_BASE_ADDRESS == 0x%08x\n", (u32) oxnas_pci_read_core_config(SYNOPSYS_PCI_MEMORY_BASE_ADDRESS ) );
-+// printk(KERN_DEBUG "PCI: SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS == 0x%08x\n", (u32) oxnas_pci_read_core_config(SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS ) );
-+// printk(KERN_DEBUG "PCI: SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS == 0x%08x\n", (u32) oxnas_pci_read_core_config(SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS ) );
-+ return 1;
-+}
-+
-+
-+int __init oxnas_pci_setup(int nr, struct pci_sys_data *sys)
-+{
-+ int ret = 0;
-+
-+// printk(KERN_DEBUG "PCI: oxnas_pci_setup nr == %u\n", nr);
-+ if (nr == 0) {
-+ /* the PCI core has been setup so that the top nybble is forced to 0, so
-+ we need to offset by whatever is in the top nybble or the devices won't
-+ recognise their memory accesses */
-+ sys->mem_offset = PCI_BASE_PA & 0xf0000000 ;
-+
-+ // ioremap is not called on IO ports. this should shift the physical
-+ // address to the statically mapped virtual one after the BARS have been
-+ // setup.
-+ sys->io_offset = 0;
-+
-+ spin_lock_init(&oxnas_lock);
-+ ret = oxnas_pci_setup_resources(sys->resource);
-+ }
-+
-+ return ret;
-+}
-+
-+
-+static struct pci_ops oxnas_pci_ops = {
-+ .read = oxnas_read_config,
-+ .write = oxnas_write_config,
-+};
-+
-+
-+struct pci_bus *oxnas_pci_scan_bus(int nr, struct pci_sys_data *sys)
-+{
-+// printk(KERN_DEBUG "PCI: oxnas_pci_scan_bus\n");
-+ return pci_scan_bus(sys->busnr, &oxnas_pci_ops, sys);
-+}
-+
-+void __init oxnas_pci_preinit(void)
-+{
-+ unsigned int temp;
-+ unsigned long flags;
-+// printk(KERN_DEBUG "PCI: oxnas_pci_preinit\n");
-+
-+ // Configure GPIO lines which map PCI INTA for both minipci and planar as active low
-+ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+ *((volatile unsigned long*)GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE) |= ((1UL << PCI_GPIO_INTA_MINIPCI) | (1UL << PCI_GPIO_INTA_PLANAR));
-+ *((volatile unsigned long*)GPIO_A_LEVEL_INTERRUPT_ENABLE) |= ((1UL << PCI_GPIO_INTA_MINIPCI) | (1UL << PCI_GPIO_INTA_PLANAR));
-+ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+
-+ /*
-+ printk(KERN_DEBUG "\n\nPCI: GPIO ABse 0x%08x\n", GPIO_1_BASE );
-+ for ( temp=0;temp<0x40; temp += 4 )
-+ {
-+ printk(KERN_DEBUG " GPIO ABse + 0x%02x == 0x%08x\n",temp, readl( GPIO_1_BASE+temp ) );
-+ }
-+ */
-+
-+ // put pci into host mode
-+ temp = ( 0 << SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO5 ) |
-+ ( 0 << SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO4 ) |
-+ ( 0 << SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO3 ) |
-+ ( 0 << SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO2 ) |
-+ ( 0 << SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO1 ) |
-+ ( 0 << SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO0 ) |
-+ ( 0 << SYSCTL_PCI_CTRL1_ENPU ) |
-+ ( 0 << SYSCTL_PCI_CTRL1_ENCB ) |
-+ ( 0 << SYSCTL_PCI_CTRL1_SYSPCI_STATIC_REQ ) |
-+ ( 1 << SYSCTL_PCI_CTRL1_SS_HOST_E ) |
-+ ( 0 << SYSCTL_PCI_CTRL1_SYSPCI_PAKING_ENABLE ) |
-+ ( 0 << SYSCTL_PCI_CTRL1_SYSPCI_PAKING_MASTE ) |
-+ ( 0 << SYSCTL_PCI_CTRL1_SS_CADBUS_E ) |
-+ ( 0 << SYSCTL_PCI_CTRL1_SS_MINIPCI_ ) |
-+ ( 0 << SYSCTL_PCI_CTRL1_SS_INT_MASK_0 ) |
-+ ( 0 << SYSCTL_PCI_CTRL1_INT_STATUS_0 ) |
-+ ( 0 << SYSCTL_PCI_CTRL1_APP_EQUIES_NOM_CLK ) |
-+ ( 0 << SYSCTL_PCI_CTRL1_APP_CBUS_INT_N ) |
-+ ( 0 << SYSCTL_PCI_CTRL1_APP_CSTSCHG_N );
-+
-+// printk(KERN_DEBUG "PCI: pci into host mode - writel( 0x%08x, 0x%08x )\n", (u32) temp, (u32) (SYS_CTRL_PCI_CTRL1) );
-+ writel( temp, SYS_CTRL_PCI_CTRL1 );
-+
-+ /* the interrupt lines map directly to the GPIO lines, so disable any
-+ primary, secondary and tertiary functionality */
-+ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+
-+ // Interrupt line the cardbus/mini-PCI slot
-+ *((volatile unsigned long*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0) &= ~(1UL << PCI_GPIO_INTA_MINIPCI);
-+ *((volatile unsigned long*)SYS_CTRL_GPIO_SECSEL_CTRL_0) &= ~(1UL << PCI_GPIO_INTA_MINIPCI);
-+ *((volatile unsigned long*)SYS_CTRL_GPIO_TERTSEL_CTRL_0) &= ~(1UL << PCI_GPIO_INTA_MINIPCI);
-+
-+ // Interrupt line for VIA-SATA PCI device
-+ *((volatile unsigned long*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0) &= ~(1UL << PCI_GPIO_INTA_PLANAR);
-+ *((volatile unsigned long*)SYS_CTRL_GPIO_SECSEL_CTRL_0) &= ~(1UL << PCI_GPIO_INTA_PLANAR);
-+ *((volatile unsigned long*)SYS_CTRL_GPIO_TERTSEL_CTRL_0) &= ~(1UL << PCI_GPIO_INTA_PLANAR);
-+
-+#ifdef CONFIG_ARCH_OXNAS_PCI_CLKOUT_0
-+ *((volatile unsigned long*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_0);
-+ *((volatile unsigned long*)SYS_CTRL_GPIO_SECSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_0);
-+ *((volatile unsigned long*)SYS_CTRL_GPIO_TERTSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_0);
-+#endif // CONFIG_ARCH_OXNAS_PCI_CLKOUT_0
-+
-+#ifdef CONFIG_ARCH_OXNAS_PCI_CLKOUT_1
-+ *((volatile unsigned long*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_1);
-+ *((volatile unsigned long*)SYS_CTRL_GPIO_SECSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_1);
-+ *((volatile unsigned long*)SYS_CTRL_GPIO_TERTSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_1);
-+#endif // CONFIG_ARCH_OXNAS_PCI_CLKOUT_1
-+
-+#ifdef CONFIG_ARCH_OXNAS_PCI_CLKOUT_2
-+ *((volatile unsigned long*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_2);
-+ *((volatile unsigned long*)SYS_CTRL_GPIO_SECSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_2);
-+ *((volatile unsigned long*)SYS_CTRL_GPIO_TERTSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_2);
-+#endif // CONFIG_ARCH_OXNAS_PCI_CLKOUT_2
-+
-+#ifdef CONFIG_ARCH_OXNAS_PCI_CLKOUT_3
-+ *((volatile unsigned long*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_3);
-+ *((volatile unsigned long*)SYS_CTRL_GPIO_SECSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_3);
-+ *((volatile unsigned long*)SYS_CTRL_GPIO_TERTSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_3);
-+#endif // CONFIG_ARCH_OXNAS_PCI_CLKOUT_3
-+
-+// printk(KERN_DEBUG "PCI: set gnt and req functions for pci arbiters\n" );
-+
-+#ifdef CONFIG_ARCH_OXNAS_PCI_REQGNT_0
-+ *((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_REQ_N0);
-+ *((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_GNT_N0);
-+#endif // CONFIG_ARCH_OXNAS_PCI_REQGNT_0
-+
-+#ifdef CONFIG_ARCH_OXNAS_PCI_REQGNT_1
-+ *((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_REQ_N1);
-+ *((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_GNT_N1);
-+#endif // CONFIG_ARCH_OXNAS_PCI_REQGNT_1
-+
-+#ifdef CONFIG_ARCH_OXNAS_PCI_REQGNT_2
-+ *((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_REQ_N2);
-+ *((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_GNT_N2);
-+#endif // CONFIG_ARCH_OXNAS_PCI_REQGNT_2
-+
-+#ifdef CONFIG_ARCH_OXNAS_PCI_REQGNT_3
-+ *((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_REQ_N2);
-+ *((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_GNT_N2);
-+#endif // CONFIG_ARCH_OXNAS_PCI_REQGNT_3
-+
-+ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+
-+ // no eeprom to setup core, so perform eeporm functions --------------------
-+ // setup the data to write to enable pci config
-+// printk(KERN_DEBUG "PCI: enable core features\n" );
-+ oxnas_pci_write_core_config(
-+ PCI_COMMAND_IO |
-+ PCI_COMMAND_MEMORY |
-+ PCI_COMMAND_MASTER |
-+ PCI_COMMAND_SPECIAL |
-+ PCI_COMMAND_INVALIDATE |
-+ PCI_COMMAND_VGA_PALETTE |
-+ PCI_COMMAND_PARITY |
-+ PCI_COMMAND_WAIT |
-+ PCI_COMMAND_SERR |
-+ PCI_COMMAND_FAST_BACK /* |
-+ PCI_COMMAND_INTX_DISABLE, */,
-+ PCI_COMMAND );
-+
-+// printk(KERN_DEBUG "PCI: PCI_COMMAND == 0x%08x\n", (u32) oxnas_pci_read_core_config(PCI_COMMAND) );
-+}
-+
-+void __init oxnas_pci_postinit(void)
-+{
-+// printk(KERN_DEBUG "PCI: oxnas_pci_postinit\n");
-+}
-+
-+static struct hw_pci oxnas_pci __initdata = {
-+ .swizzle = oxnas_swizzle,
-+ .map_irq = oxnas_map_irq,
-+ .setup = oxnas_pci_setup,
-+ .nr_controllers = 1,
-+ .scan = oxnas_pci_scan_bus,
-+ .preinit = oxnas_pci_preinit,
-+ .postinit = oxnas_pci_postinit,
-+};
-+
-+static int __init oxnas_pci_init(void)
-+{
-+ pci_common_init(&oxnas_pci);
-+ return 0;
-+}
-+
-+static void __exit oxnas_pci_exit(void)
-+{
-+ // if ( resource[0] ) {
-+ // int errVal = release_resource(resource[0];
-+ // if ( errVal ) {
-+ // printk(KERN_ERR "PCI: unable to release csrRegister space %d", errVal );
-+ // }
-+ // }
-+
-+ // Put the PCI core into reset, but don't stop the clock as the PCI arbiter
-+ // still requires it in order to be able to grant the static bus access to
-+ // the PCI I/Os
-+ writel(1UL << SYS_CTRL_RSTEN_PCI_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+
-+ return;
-+}
-+
-+subsys_initcall(oxnas_pci_init);
-+module_exit(oxnas_pci_exit);
-+
-+#endif
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/power_button.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/power_button.c
---- linux-2.6.24/arch/arm/mach-oxnas/power_button.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/power_button.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,270 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/power_button.c
-+ *
-+ * Copyright (C) 2006 Oxford Semiconductor Ltd
-+ *
-+ * 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 <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/module.h>
-+#include <linux/timer.h>
-+#include <linux/kobject.h>
-+#include <linux/workqueue.h>
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+
-+MODULE_LICENSE("GPL v2");
-+
-+// Global variable to hold LED inversion state
-+extern int oxnas_global_invert_leds;
-+
-+// Make a module parameter to set whether LED are inverted
-+static int invert_leds = 0;
-+module_param(invert_leds, bool, S_IRUGO|S_IWUSR);
-+
-+#if (CONFIG_OXNAS_POWER_BUTTON_GPIO < 32)
-+#define SWITCH_NUM CONFIG_OXNAS_POWER_BUTTON_GPIO
-+#define IRQ_NUM GPIO_1_INTERRUPT
-+#define INT_STATUS_REG GPIO_A_INTERRUPT_STATUS_REGISTER
-+#define SWITCH_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_0
-+#define SWITCH_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_0
-+#define SWITCH_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_0
-+#define SWITCH_CLR_OE_REG GPIO_A_OUTPUT_ENABLE_CLEAR
-+#define DEBOUNCE_REG GPIO_A_INPUT_DEBOUNCE_ENABLE
-+#define LEVEL_INT_REG GPIO_A_LEVEL_INTERRUPT_ENABLE
-+#define FALLING_INT_REG GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE
-+#define DATA_REG GPIO_A_DATA
-+#else
-+#define SWITCH_NUM ((CONFIG_OXNAS_POWER_BUTTON_GPIO) - 32)
-+#define IRQ_NUM GPIO_2_INTERRUPT
-+#define INT_STATUS_REG GPIO_B_INTERRUPT_STATUS_REGISTER
-+#define SWITCH_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_1
-+#define SWITCH_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_1
-+#define SWITCH_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_1
-+#define SWITCH_CLR_OE_REG GPIO_B_OUTPUT_ENABLE_CLEAR
-+#define DEBOUNCE_REG GPIO_B_INPUT_DEBOUNCE_ENABLE
-+#define LEVEL_INT_REG GPIO_B_LEVEL_INTERRUPT_ENABLE
-+#define FALLING_INT_REG GPIO_B_FALLING_EDGE_ACTIVE_LOW_ENABLE
-+#define DATA_REG GPIO_B_DATA
-+#endif
-+
-+#define SWITCH_MASK (1UL << (SWITCH_NUM))
-+
-+#define TIMER_INTERVAL_JIFFIES ((HZ) >> 3) /* An eigth of a second */
-+#define TIMER_COUNT_LIMIT 24 /* In eigths of a second */
-+
-+extern spinlock_t oxnas_gpio_spinlock;
-+
-+static unsigned long count;
-+static struct timer_list timer;
-+
-+/** Have to use active low level interupt generation, as otherwise might miss
-+ * interrupts that arrive concurrently with a PCI interrupt, as PCI interrupts
-+ * are generated via GPIO pins and std PCI drivers will not know that there
-+ * may be other pending GPIO interrupt sources waiting to be serviced and will
-+ * simply return IRQ_HANDLED if they see themselves as having generated the
-+ * interrupt, thus preventing later chained handlers from being called
-+ */
-+static irqreturn_t int_handler(int irq, void* dev_id)
-+{
-+ int status = IRQ_NONE;
-+ unsigned int int_status = readl((volatile unsigned long *)INT_STATUS_REG);
-+
-+ /* Is the interrupt for us? */
-+ if (int_status & SWITCH_MASK) {
-+ /* Disable the power button GPIO line interrupt */
-+ spin_lock(&oxnas_gpio_spinlock);
-+ writel(readl(FALLING_INT_REG) & ~SWITCH_MASK, FALLING_INT_REG);
-+ spin_unlock(&oxnas_gpio_spinlock);
-+
-+ /* Zeroise button hold down counter */
-+ count = 0;
-+
-+ /* Start hold down timer with a timeout of 1/8 second */
-+ mod_timer(&timer, jiffies + TIMER_INTERVAL_JIFFIES);
-+
-+ /* Only mark interrupt as serviced if no other unmasked GPIO interrupts
-+ are pending */
-+ if (!readl((volatile unsigned long *)INT_STATUS_REG)) {
-+ status = IRQ_HANDLED;
-+ }
-+ }
-+
-+ return status;
-+}
-+
-+/*
-+ * Device driver object
-+ */
-+typedef struct power_button_driver_s {
-+ /** sysfs dir tree root for power button driver */
-+ struct kset kset;
-+ struct kobject power_button;
-+} power_button_driver_t;
-+
-+static power_button_driver_t power_button_driver;
-+
-+static void work_handler(struct work_struct * not_used) {
-+ kobject_uevent(&power_button_driver.power_button, KOBJ_OFFLINE);
-+}
-+
-+DECLARE_WORK(power_button_hotplug_work, work_handler);
-+
-+static void timer_handler(unsigned long data)
-+{
-+ unsigned long flags;
-+
-+ /* Is the power button still pressed? */
-+ if (!(readl(DATA_REG) & SWITCH_MASK)) {
-+ /* Yes, so increment count of how many timer intervals have passed since
-+ power button was pressed */
-+ if (++count == TIMER_COUNT_LIMIT) {
-+ schedule_work(&power_button_hotplug_work);
-+ } else {
-+ /* Restart timer with a timeout of 1/8 second */
-+ mod_timer(&timer, jiffies + TIMER_INTERVAL_JIFFIES);
-+ }
-+ } else {
-+ /* The h/w debounced power button has been released, so reenable the
-+ active low interrupt detection to trap the user's next attempt to
-+ power down */
-+ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+ writel(readl(FALLING_INT_REG) | SWITCH_MASK, FALLING_INT_REG);
-+ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+ }
-+}
-+
-+static struct kobj_type ktype_power_button = {
-+ .release = 0,
-+ .sysfs_ops = 0,
-+ .default_attrs = 0,
-+};
-+
-+static int power_button_hotplug_filter(struct kset* kset, struct kobject* kobj) {
-+ return get_ktype(kobj) == &ktype_power_button;
-+}
-+
-+static const char* power_button_hotplug_name(struct kset* kset, struct kobject* kobj) {
-+ return "oxnas_power_button";
-+}
-+
-+static struct kset_uevent_ops power_button_uevent_ops = {
-+ .filter = power_button_hotplug_filter,
-+ .name = power_button_hotplug_name,
-+ .uevent = NULL,
-+};
-+
-+static int power_button_prep_sysfs(void)
-+{
-+ int err = 0;
-+
-+ /* prep the sysfs interface for use */
-+ kobject_set_name(&power_button_driver.kset.kobj, "power-button");
-+ power_button_driver.kset.ktype = &ktype_power_button;
-+
-+ err = subsystem_register(&power_button_driver.kset);
-+ if (err)
-+ return err;
-+
-+ /* setup hotplugging */
-+ power_button_driver.kset.uevent_ops = &power_button_uevent_ops;
-+
-+ /* setup the heirarchy, the name will be set on detection */
-+ kobject_init(&power_button_driver.power_button);
-+ power_button_driver.power_button.kset = kset_get(&power_button_driver.kset);
-+ power_button_driver.power_button.parent = &power_button_driver.kset.kobj;
-+
-+ return 0;
-+}
-+
-+static int power_button_build_sysfs(void) {
-+ kobject_set_name(&power_button_driver.power_button, "power-button-1");
-+ return kobject_add(&power_button_driver.power_button);
-+}
-+
-+static int __init power_button_init(void)
-+{
-+ int err = 0;
-+ unsigned long flags;
-+
-+ /* Copy the LED inversion module parameter into the global variable */
-+ oxnas_global_invert_leds = invert_leds;
-+
-+ err = power_button_prep_sysfs();
-+ if (err)
-+ return -EINVAL;
-+
-+ err = power_button_build_sysfs();
-+ if (err)
-+ return -EINVAL;
-+
-+ /* Setup the timer that will time how long the user holds down the power
-+ button */
-+ init_timer(&timer);
-+ timer.data = 0;
-+ timer.function = timer_handler;
-+
-+ /* Install a shared interrupt handler on the appropriate GPIO bank's
-+ interrupt line */
-+ if (request_irq(IRQ_NUM, int_handler, IRQF_SHARED, "Power Button", &power_button_driver)) {
-+ printk(KERN_ERR "Power Button: cannot register IRQ %d\n", IRQ_NUM);
-+ del_timer_sync(&timer);
-+ return -EIO;
-+ }
-+
-+ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+ /* Disable primary, secondary and teriary GPIO functions on switch lines */
-+ writel(readl(SWITCH_PRISEL_REG) & ~SWITCH_MASK, SWITCH_PRISEL_REG);
-+ writel(readl(SWITCH_SECSEL_REG) & ~SWITCH_MASK, SWITCH_SECSEL_REG);
-+ writel(readl(SWITCH_TERSEL_REG) & ~SWITCH_MASK, SWITCH_TERSEL_REG);
-+
-+ /* Enable GPIO input on switch line */
-+ writel(SWITCH_MASK, SWITCH_CLR_OE_REG);
-+
-+ /* Set up the power button GPIO line for active low, debounced interrupt */
-+ writel(readl(DEBOUNCE_REG) | SWITCH_MASK, DEBOUNCE_REG);
-+ writel(readl(LEVEL_INT_REG) | SWITCH_MASK, LEVEL_INT_REG);
-+ writel(readl(FALLING_INT_REG) | SWITCH_MASK, FALLING_INT_REG);
-+ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+
-+ printk(KERN_INFO "Power button driver registered\n");
-+ return 0;
-+}
-+
-+static void __exit power_button_exit(void)
-+{
-+ unsigned long flags;
-+
-+ kobject_del(&power_button_driver.power_button);
-+ subsystem_unregister(&power_button_driver.kset);
-+
-+ /* Deactive the timer */
-+ del_timer_sync(&timer);
-+
-+ /* Disable interrupt generation by the power button GPIO line */
-+ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+ writel(readl(FALLING_INT_REG) & ~SWITCH_MASK, FALLING_INT_REG);
-+ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+
-+ /* Remove the handler for the shared interrupt line */
-+ free_irq(IRQ_NUM, &power_button_driver);
-+}
-+
-+/**
-+ * macros to register intiialisation and exit functions with kernal
-+ */
-+module_init(power_button_init);
-+module_exit(power_button_exit);
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/samba_reserve.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/samba_reserve.c
---- linux-2.6.24/arch/arm/mach-oxnas/samba_reserve.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/samba_reserve.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,50 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/samba_receive.c
-+ *
-+ * Copyright (C) 2008 Oxford Semiconductor Ltd
-+ *
-+ * 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 <linux/errno.h>
-+#include <linux/file.h>
-+#include <linux/fs.h>
-+#include <linux/kernel.h>
-+
-+typedef struct xfs_flock64 {
-+ __s16 l_type;
-+ __s16 l_whence;
-+ __s64 l_start;
-+ __s64 l_len; /* len == 0 means until end of file */
-+ __s32 l_sysid;
-+ __u32 l_pid;
-+ __s32 l_pad[4]; /* reserve area */
-+} xfs_flock64_t;
-+
-+#define XFS_IOC_RESVSP64 _IOW ('X', 42, struct xfs_flock64)
-+
-+asmlinkage long sys_samba_reserve(
-+ int fd,
-+ void __user *info)
-+{
-+ struct file *file = fget(fd);
-+ long ret = -EINVAL;
-+
-+ /* Do I need any locking around the unlocked_ioctl() call? */
-+ ret = file->f_op->unlocked_ioctl(file, XFS_IOC_RESVSP64, (unsigned long)info);
-+
-+ fput(file);
-+
-+ return ret;
-+}
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/thermAndFan.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/thermAndFan.c
---- linux-2.6.24/arch/arm/mach-oxnas/thermAndFan.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/thermAndFan.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,738 @@
-+/*
-+ * Device driver for the i2c thermostat found on the iBook G4, Albook G4
-+ *
-+ * Copyright (C) 2003, 2004 Colin Leroy, Rasmus Rohde, Benjamin Herrenschmidt
-+ *
-+ * Documentation from
-+ * http://www.analog.com/UploadedFiles/Data_Sheets/115254175ADT7467_pra.pdf
-+ * http://www.analog.com/UploadedFiles/Data_Sheets/3686221171167ADT7460_b.pdf
-+ *
-+ */
-+
-+
-+#include <linux/types.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/miscdevice.h>
-+#include <linux/smp_lock.h>
-+#include <linux/kernel.h>
-+#include <linux/delay.h>
-+#include <linux/sched.h>
-+#include <linux/i2c.h>
-+#include <linux/proc_fs.h>
-+#include <linux/capability.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/spinlock.h>
-+#include <linux/smp_lock.h>
-+#include <linux/wait.h>
-+#include <linux/suspend.h>
-+#include <linux/kthread.h>
-+#include <linux/moduleparam.h>
-+#include <linux/freezer.h>
-+
-+#include <asm/io.h>
-+#include <asm/system.h>
-+#include <asm/sections.h>
-+#include <asm/uaccess.h>
-+#include <asm/bitops.h>
-+
-+#include "asm/arch-oxnas/taco.h"
-+#include "thermistorCalibration.h"
-+
-+//#define DEBUG 1
-+#undef DEBUG
-+
-+/* Set this define to simulate different temperature values and test the
-+ * working of the fan control module
-+ */
-+//#define SIMULATE_TEMPERATURE 1
-+#undef SIMULATE_TEMPERATURE
-+
-+/******************************************************************************
-+ * *
-+ * delta t = dutyCycle.Period *
-+ * *
-+ * PWM in >----+ V' = Vcc - Vt *
-+ * | -------- *
-+ * _|_ Vcc *
-+ * | | | *
-+ * \| | Rt = delta t *
-+ * | | ------------- *
-+ * |\| -C.ln( V' ) *
-+ * | | *
-+ * | |\ delta t is discovered by the hardware which performs a *
-+ * !_! \ varies the PWM duty cycle until one is found that just *
-+ * | trips the Vt threshold. *
-+ * | *
-+ * |-----------> V in (Schmidt trigger @ Vt) *
-+ * | *
-+ * ___!___ *
-+ * _______ C ( eg 100nF ) *
-+ * | *
-+ * | *
-+ * | *
-+ * ---+--- *
-+ * *
-+ * Steinhart Thermistor approximation: *
-+ * *
-+ * 1/T = A + B.ln(Rt) + C.ln(Rt)^3 *
-+ * *
-+ ******************************************************************************/
-+
-+#define MAX_FAN_RATIO_CHANGE 20
-+#define OXSEMI_FAN_SPEED_RATIO_MIN 0
-+#define OXSEMI_FAN_SPEED_RATIO_MAX 255
-+#define FAN_SPEED_RATIO_SET (PWM_DATA_2)
-+#define MIN_TEMP_COUNT_CHANGE 2
-+
-+/* This is not absolute temperature but counter val - thermistorCalibration*/
-+static int hot_limit = 16;
-+
-+#ifdef OXNAS_TACHO_Ox810
-+static int cold_limit = 104;
-+#else /* OXNAS_TACHO_Ox810 */
-+static int cold_limit = 200;
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+static int min_fan_speed_ratio = 64;
-+
-+#ifdef OXNAS_TACHO_Ox810
-+static int fan_pulse_per_rev = 1;
-+static int output_flag = 0;
-+static int current_temp = 0;
-+static int current_speed = 0;
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+MODULE_AUTHOR( "Chris Ford" );
-+
-+#ifdef OXNAS_TACHO_Ox810
-+MODULE_DESCRIPTION( "Driver for Temperature sense and Fan control of ox810" );
-+#else /* OXNAS_TACHO_Ox810 */
-+MODULE_DESCRIPTION( "Driver for Fan and temp sense of ox800" );
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+MODULE_LICENSE( "GPL" );
-+
-+module_param(hot_limit, int, 0644);
-+MODULE_PARM_DESC(hot_limit, "Thermistor input for maximum fan drive");
-+
-+module_param(cold_limit, int, 0644);
-+MODULE_PARM_DESC(cold_limit,"Thermistor input for minimum fan drive");
-+
-+module_param(min_fan_speed_ratio, int, 0644);
-+MODULE_PARM_DESC(min_fan_speed_ratio,"Specify starting( minimum) fan drive (0-255) (default 64)");
-+
-+#ifdef OXNAS_TACHO_Ox810
-+module_param(fan_pulse_per_rev, int, 0644);
-+MODULE_PARM_DESC(fan_pulse_per_rev,"Specify the number of pulses per revolution of fan - 1(default) or 2");
-+
-+module_param(output_flag, bool, 0644);
-+MODULE_PARM_DESC(output_flag,"Flag to specify whether temperature and speed output to user is required");
-+
-+module_param(current_temp, int, S_IRUGO);
-+MODULE_PARM_DESC(current_temp,"Read only for the current temperature in counts");
-+
-+module_param(current_speed, int, S_IRUGO);
-+MODULE_PARM_DESC(current_speed,"Read only for the current speed in rpm");
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+
-+struct thermostat {
-+ int temps;
-+ int cached_temp;
-+ int curr_speed;
-+ int last_speed;
-+ int set_speed;
-+ int last_var;
-+ struct semaphore sem;
-+// struct cdev cdev;
-+};
-+
-+static struct thermostat* thermostat = NULL;
-+static struct task_struct* thread_therm = NULL;
-+
-+
-+static int write_reg( int reg, u32 data )
-+{
-+ writel( data, reg );
-+ return 0;
-+}
-+
-+static int read_reg( int reg )
-+{
-+ int data = 0;
-+ data = readl( reg );
-+ return data;
-+}
-+
-+/** GetTemperatureCounter is an internal function to the module that reads the
-+ * temperature as a counter value and returns it to the caller. The counter
-+ * value is used in all the internal calculations avoiding the necessity to
-+ * convert to Kelvin for interpretation. For corresponding temperature values
-+ * in Kelvin look at thermistoCalilbration.h
-+ */
-+int GetTemperatureCounter(void)
-+{
-+ u32 res;
-+
-+/* printk(KERN_INFO "T&F?::GetTemperatureCounter ----\n");
-+ */
-+ /* Test to ensure we are ready.
-+ */
-+ if ( !thermostat ) {
-+ printk(KERN_INFO "T&F?::$RERROR - Temperature conv not started\n");
-+ return -1;
-+ }
-+
-+ while ( !( read_reg( TACHO_THERMISTOR_CONTROL ) &
-+ (1 << TACHO_THERMISTOR_CONTROL_THERM_VALID) ) ) {
-+ printk(KERN_INFO "T&F?::$rWarning - Temperature reading not stabalised\n");
-+ msleep(100);
-+ }
-+
-+ res = read_reg( TACHO_THERMISTOR_RC_COUNTER ) & TACHO_THERMISTOR_RC_COUNTER_MASK;
-+
-+#ifdef DEBUG
-+ printk(KERN_INFO "Therm&Fan - Temperature Counter - %d \n",res);
-+#endif
-+
-+ return res;
-+}
-+
-+/** This function converts the unit of the temperature from counts to
-+ * temperature in Kelvin
-+ */
-+int ConverttoKelvin(int tempCount)
-+{
-+ u32 res, arrayIndex;
-+
-+ /* Convert the Counter Value to Temperature in Kelvin */
-+ arrayIndex = tempCount/THERM_INTERPOLATION_STEP;
-+ res = TvsCnt[arrayIndex];
-+ if ((THERM_ENTRIES_IN_CALIB_TABLE - 2) > arrayIndex)
-+ res -= (tempCount % THERM_INTERPOLATION_STEP) * (TvsCnt[arrayIndex] - TvsCnt[arrayIndex + 1]) / THERM_INTERPOLATION_STEP;
-+ else
-+ res -= (tempCount % THERM_INTERPOLATION_STEP) * (TvsCnt[THERM_ENTRIES_IN_CALIB_TABLE - 2] - TvsCnt[THERM_ENTRIES_IN_CALIB_TABLE - 1]) / THERM_INTERPOLATION_STEP;
-+
-+#ifdef DEBUG
-+ printk(KERN_INFO "Get Temperature- Temperature in Kelvin = %d\n", res);
-+#endif
-+ return res;
-+}
-+
-+/**
-+ * GetTemperature reads the temperature from the thermistor and converts it
-+ * to the corresponding Kelvin equivalent
-+ */
-+int GetTemperature(void)
-+{
-+ u32 tempCount;
-+ tempCount = GetTemperatureCounter();
-+ return ConverttoKelvin(tempCount);
-+}
-+
-+/**
-+ * GetFanRPM will read the fan tacho register and convert the value to
-+ * RPM.
-+ * @return an int that represents the fan speed in RPM, or a
-+ * negative value in the case of error.
-+ */
-+int GetFanRPM(void)
-+{
-+ u32 res;
-+ u32 iCounterValue;
-+
-+#ifdef OXNAS_TACHO_Ox810
-+
-+ if(thermostat->last_speed == OXSEMI_FAN_SPEED_RATIO_MIN)
-+ {
-+#ifdef DEBUG
-+ printk(KERN_INFO "ThernAndFan::GetFanRPM - Fan Speed %d \n", OXSEMI_FAN_SPEED_RATIO_MIN);
-+#endif
-+ return OXSEMI_FAN_SPEED_RATIO_MIN;
-+ }
-+
-+ write_reg( TACHO_FAN_ONE_SHOT_CONTROL, (1 << TACHO_FAN_ONE_SHOT_CONTROL_START));
-+
-+ while ( !(read_reg( TACHO_FAN_SPEED_COUNTER ) &
-+ (1 << TACHO_FAN_SPEED_COUNTER_COUNT_VALID) ) ) {
-+/* printk(KERN_INFO "ThernAndFan::$rWarning - Fan Counter reading not stabalised\n");
-+ */ msleep(100);
-+ }
-+
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+ iCounterValue = read_reg( TACHO_FAN_SPEED_COUNTER )
-+ & TACHO_FAN_SPEED_COUNTER_MASK;
-+
-+#ifndef OXNAS_TACHO_Ox810 /* Code thats only for non ox810 versions */
-+ if(iCounterValue == TACHO_FAN_SPEED_COUNTER_MASK)
-+ {
-+ /* speed less than measurable */
-+#ifdef DEBUG
-+ printk(KERN_INFO "ThernAndFan::GetFanRPM - RPM < 117 - returning 0\n");
-+#endif
-+ return 0;
-+ }
-+#endif
-+
-+ ++iCounterValue;
-+
-+#ifdef OXNAS_TACHO_Ox810
-+ /* Fan Speed (rpm) = 60 * 2000 / (counter value +1) * pulses per rev */
-+ res = (60 * 2000 ) / (iCounterValue * fan_pulse_per_rev);
-+#else /* OXNAS_TACHO_Ox810 */
-+ /* Fan Speed (rpm) = 60 * 2000 / (counter value +1) */
-+ res = 60 * 2000 / iCounterValue;
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+#ifdef SIMULATE_TEMPERATURE
-+ printk(KERN_INFO "thermAndFan::GetFanRPM == %d\n", res);
-+#endif /*SIMULATE_TEMPERATURE */
-+
-+ return res;
-+}
-+
-+#ifdef OXNAS_TACHO_Ox810
-+
-+static void read_sensors(struct thermostat *th)
-+{
-+ static int state;
-+#ifdef SIMULATE_TEMPERATURE
-+ static int curTemp = 30;
-+#endif /* SIMULATE_TEMPERATURE */
-+
-+ if ( !th ) {
-+ printk(KERN_INFO "thermAndFan::read_sensors $RTH NOT ESTABLISHED YET\n");
-+ return;
-+ }
-+ switch(state){
-+ case 0:
-+ th->temps = GetTemperatureCounter();
-+
-+ /* Set to speed measurement */
-+ write_reg( TACHO_FAN_SPEED_CONTROL,
-+ (1 << (TACHO_FAN_SPEED_CONTROL_PWM_ENABLE_BASE
-+ + TACHO_FAN_SPEED_CONTROL_PWM_USED))
-+ | (1 << TACHO_FAN_SPEED_CONTROL_FAN_COUNT_MODE));
-+ state = 1;
-+
-+ if(output_flag) /* Set the temperature to user space here */
-+ {
-+ current_temp = th->temps;
-+ }
-+
-+ #ifdef SIMULATE_TEMPERATURE
-+ th->temps = curTemp;
-+ curTemp += 5;
-+ if(curTemp > cold_limit + 20)
-+ curTemp = hot_limit - 20;
-+ printk(KERN_INFO "thermAndFan::read_sensors Temp Set to - %d\n", curTemp);
-+ #endif /* SIMULATE_TEMPERATURE */
-+ break;
-+
-+ case 1:
-+ default:
-+
-+ th->curr_speed = GetFanRPM();
-+
-+ /* Set to Temperature measurement */
-+ write_reg( TACHO_THERMISTOR_CONTROL, ((1 << TACHO_THERMISTOR_CONTROL_THERM_ENABLE)
-+ | (0 << TACHO_THERMISTOR_CONTROL_THERM_VALID)) );
-+ state = 0;
-+
-+ if(output_flag) /* Set the speed to user space here */
-+ {
-+ current_speed = th->curr_speed;
-+ }
-+ break;
-+ }
-+}
-+
-+#else /* OXNAS_TACHO_Ox810 */
-+
-+static void read_sensors(struct thermostat *th)
-+{
-+ static int state;
-+
-+ if ( !th ) {
-+ printk(KERN_INFO "thermAndFan::read_sensors $RTH NOT ESTABLISHED YET\n");
-+ return;
-+ }
-+
-+ switch (state) {
-+ case 0: /* Get the temperature */
-+ th->temps = GetTemperatureCounter();
-+ write_reg( TACHO_CLOCK_DIVIDER, TACHO_CORE_TACHO_DIVIDER_VALUE );
-+ state = 1;
-+ break;
-+
-+ case 1:
-+ /* Get the fan speed */
-+ th->curr_speed = GetFanRPM();
-+ /* free fall to default case needed */
-+/* break;
-+ */
-+ default:
-+ /* Stop the thermister measuring */
-+ write_reg( TACHO_THERMISTOR_CONTROL, 0 );
-+ write_reg( TACHO_CLOCK_DIVIDER, TACHO_CORE_THERM_DIVIDER_VALUE );
-+ /* Start the thermister measuring */
-+ write_reg( TACHO_THERMISTOR_CONTROL, (1 << TACHO_THERMISTOR_CONTROL_THERM_ENABLE) );
-+ state = 0;
-+ break;
-+ }
-+}
-+
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+
-+#ifdef DEBUG
-+/**
-+ * DumpTachoRegisters is a debug function used to inspect hte tacho registers.
-+ */
-+void DumpTachoRegisters(void)
-+{
-+
-+ printk(KERN_INFO \
-+ "\n<Taco Registers> ---------------------------------\n"
-+ " TACHO_FAN_SPEED_COUNTER == 0x%08x\n"
-+ " TACHO_THERMISTOR_RC_COUNTER == 0x%08x\n"
-+ " TACHO_THERMISTOR_CONTROL == 0x%08x\n"
-+ " TACHO_CLOCK_DIVIDER == 0x%08x\n"
-+ " PWM_CORE_CLK_DIVIDER_VALUE == 0x%08x\n"
-+ " FAN_SPEED_RATIO_SET == 0x%08x\n"
-+ "<\\Taco Registers> --------------------------------\n\n",
-+ (u32) (read_reg( TACHO_FAN_SPEED_COUNTER) & TACHO_FAN_SPEED_COUNTER_MASK),
-+ (u32) (read_reg( TACHO_THERMISTOR_RC_COUNTER) & TACHO_THERMISTOR_RC_COUNTER_MASK),
-+ (u32) read_reg( TACHO_THERMISTOR_CONTROL ),
-+ (u32) (read_reg( TACHO_CLOCK_DIVIDER) & TACHO_CLOCK_DIVIDER_MASK),
-+ (u32) read_reg( PWM_CLOCK_DIVIDER ),
-+ (u32) read_reg( FAN_SPEED_RATIO_SET ) );
-+}
-+#else
-+void DumpTachoRegisters(void) {}
-+#endif
-+
-+static void write_fan_speed(struct thermostat *th, int speed)
-+{
-+/* printk(KERN_INFO "thermAndFan::write_fan_speed %u\n", speed);
-+*/
-+ /* The fan speed can vary between the max and the min speed ratio or
-+ * it can be min ratio value of 0
-+ */
-+ if (speed > OXSEMI_FAN_SPEED_RATIO_MAX)
-+ speed = OXSEMI_FAN_SPEED_RATIO_MAX;
-+ else if ((speed < min_fan_speed_ratio) && (speed > OXSEMI_FAN_SPEED_RATIO_MIN))
-+ speed = min_fan_speed_ratio;
-+ else if (speed < OXSEMI_FAN_SPEED_RATIO_MIN)
-+ speed = OXSEMI_FAN_SPEED_RATIO_MIN;
-+
-+ if (th->last_speed == speed)
-+ return;
-+
-+ write_reg( FAN_SPEED_RATIO_SET, speed );
-+
-+#ifdef SIMULATE_TEMPERATURE
-+ printk(KERN_INFO "Speed Ratio Written - %d\n", speed);
-+#endif /* SIMULATE_TEMPERATURE */
-+
-+ th->last_speed = speed;
-+}
-+
-+#ifdef DEBUG
-+static void display_stats(struct thermostat *th)
-+{
-+ if ( 1 || th->temps != th->cached_temp) {
-+ printk(KERN_INFO
-+ "thermAndFan:: Temperature infos:\n"
-+ " * thermostats: %d;\n"
-+ " * pwm: %d;\n"
-+ " * fan speed: %d RPM\n\n",
-+ th->temps,
-+ min_fan_speed_ratio,
-+ GetFanRPM());
-+ th->cached_temp = th->temps;
-+ }
-+}
-+#endif
-+
-+/*
-+ * Use fuzzy logic type approach to creating the new fan speed.
-+ * if count < cold_limit fan should be off.
-+ * if count > hot_limit fan should be full on.
-+ * if count between limits set proportionally to base speed + proportional element.
-+ */
-+static void update_fan_speed(struct thermostat *th)
-+{
-+ int var = th->temps;
-+
-+/* remember that var = 1/T ie smaller var higher temperature and faster fan speed needed */
-+ if (abs(var - th->last_var) >= MIN_TEMP_COUNT_CHANGE) {
-+ int new_speed;
-+
-+ if(var < cold_limit){
-+
-+ if (var < hot_limit)
-+ {
-+ th->last_var = var;
-+ /* too hot for proportional control */
-+ new_speed = OXSEMI_FAN_SPEED_RATIO_MAX;
-+ }
-+ else
-+ {
-+ /* fan speed it the user selected starting value for the fan
-+ * so scale operatation from nominal at cold limit to max at hot limit.
-+ */
-+ new_speed = OXSEMI_FAN_SPEED_RATIO_MAX -
-+ (OXSEMI_FAN_SPEED_RATIO_MAX - min_fan_speed_ratio) * (var - hot_limit)/(cold_limit - hot_limit);
-+
-+ if (th->set_speed == 0 ) th->set_speed = min_fan_speed_ratio;
-+
-+ if ((new_speed - th->set_speed) > MAX_FAN_RATIO_CHANGE)
-+ new_speed = th->set_speed + MAX_FAN_RATIO_CHANGE;
-+ else if ((new_speed - th->set_speed) < -MAX_FAN_RATIO_CHANGE)
-+ new_speed = th->set_speed - MAX_FAN_RATIO_CHANGE;
-+ else
-+ th->last_var = var;
-+ }
-+ }
-+ else {
-+
-+ th->last_var = var;
-+ /* var greater than low limit - too cold for fan. */
-+ new_speed = OXSEMI_FAN_SPEED_RATIO_MIN;
-+ }
-+
-+ write_fan_speed(th, new_speed);
-+ th->set_speed = new_speed;
-+ }
-+}
-+
-+static int monitor_task(void *arg)
-+{
-+ struct thermostat* th = arg;
-+
-+ while(!kthread_should_stop()) {
-+ if (unlikely(freezing(current)))
-+ refrigerator();
-+
-+ msleep_interruptible(2000);
-+
-+#ifdef DEBUG
-+ DumpTachoRegisters();
-+#endif
-+
-+ read_sensors(th);
-+
-+ update_fan_speed(th);
-+
-+#ifdef DEBUG
-+ /* be carefule with the stats displayed. The Fan Counter value depends
-+ * on what value is written in the register during the read sensors
-+ * call. If its in temperature read setting, the fan counter and hence
-+ * the rpm will be WRONG
-+ */
-+ display_stats(th);
-+#endif
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+oxsemi_therm_read(char *buf, char **start, off_t offset,
-+ int len, int *eof, void *unused)
-+{
-+ len = sprintf(buf,
-+ "Thermostat And Fan state ---------\n"
-+ " temps_counter == %d\n"
-+ " speed_ratio_set == %d\n"
-+ " measured-fan_speed == %d\n"
-+ " last_temp_counter == %d\n\n",
-+ thermostat->temps,
-+ thermostat->last_speed,
-+ thermostat->curr_speed,
-+ thermostat->last_var );
-+ //*start = buf;
-+ return len;
-+}
-+
-+static struct proc_dir_entry *proc_oxsemi_therm;
-+
-+
-+static struct file_operations oxsemi_therm_fops = {
-+ .owner = THIS_MODULE,
-+ .open = nonseekable_open,
-+};
-+
-+static struct miscdevice oxsemi_therm_miscdev = {
-+ TEMP_MINOR,
-+ "temp",
-+ &oxsemi_therm_fops
-+};
-+
-+static int __init oxsemi_therm_init(void)
-+{
-+ struct thermostat* th;
-+ int rc, ret;
-+
-+ if (thermostat)
-+ return 0;
-+
-+ read_reg(SYS_CTRL_RSTEN_CTRL);
-+
-+/* release fan/tacho from system reset */
-+ *((volatile unsigned long *) SYS_CTRL_RSTEN_CLR_CTRL) = (1UL << SYS_CTRL_RSTEN_MISC_BIT);
-+
-+/* Pull Down the GPIO 29 from the software */
-+#ifdef OXNAS_TACHO_Ox810
-+ *((volatile unsigned long *) SYSCTRL_GPIO_PULLUP_CTRL_0) |= TEMP_TACHO_PULLUP_CTRL_VALUE;
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+/* printk(KERN_INFO "thermAndFan: mux out therm and fan pins onto GPIO)\n" );
-+ */
-+ *((volatile unsigned long *) SYS_CTRL_GPIO_PRIMSEL_CTRL_0) &= ~(1UL << SECONDARY_FUNCTION_ENABLE_FAN_PWM2);
-+ *((volatile unsigned long *) SYS_CTRL_GPIO_PRIMSEL_CTRL_0) |= (1UL << PRIMARY_FUNCTION_ENABLE_FAN_TACHO);
-+ *((volatile unsigned long *) SYS_CTRL_GPIO_PRIMSEL_CTRL_0) |= (1UL << PRIMARY_FUNCTION_ENABLE_FAN_TEMP);
-+
-+/* disable secondary use */
-+ *((volatile unsigned long *) SYS_CTRL_GPIO_SECSEL_CTRL_0) |= (1UL << SECONDARY_FUNCTION_ENABLE_FAN_PWM2);
-+ *((volatile unsigned long *) SYS_CTRL_GPIO_SECSEL_CTRL_0) &= ~(1UL << PRIMARY_FUNCTION_ENABLE_FAN_TACHO);
-+ *((volatile unsigned long *) SYS_CTRL_GPIO_SECSEL_CTRL_0) &= ~(1UL << PRIMARY_FUNCTION_ENABLE_FAN_TEMP);
-+
-+/* disable tertiary use */
-+ *((volatile unsigned long *) SYS_CTRL_GPIO_TERTSEL_CTRL_0) &= ~(1UL << SECONDARY_FUNCTION_ENABLE_FAN_PWM2);
-+ *((volatile unsigned long *) SYS_CTRL_GPIO_TERTSEL_CTRL_0) &= ~(1UL << PRIMARY_FUNCTION_ENABLE_FAN_TACHO);
-+ *((volatile unsigned long *) SYS_CTRL_GPIO_TERTSEL_CTRL_0) &= ~(1UL << PRIMARY_FUNCTION_ENABLE_FAN_TEMP);
-+
-+ read_reg(SYS_CTRL_RSTEN_CTRL);
-+ read_reg(SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+ read_reg(SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+ read_reg(SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+
-+ th = (struct thermostat *)
-+ kmalloc(sizeof(struct thermostat), GFP_KERNEL);
-+
-+ if (!th)
-+ return -ENOMEM;
-+
-+ memset(th, 0, sizeof(struct thermostat));
-+ init_MUTEX( &th->sem );
-+
-+ rc = read_reg(TACHO_CLOCK_DIVIDER);
-+ if (rc < 0) {
-+ printk(KERN_ERR "thermAndFan: Thermostat failed to read config ");
-+ kfree(th);
-+ return -ENODEV;
-+ }
-+
-+ /* Set the Tacho clock divider up */
-+/* printk(KERN_INFO "thermAndFan: Setting tacho core frequency divider to %d\n", TACHO_CORE_THERM_DIVIDER_VALUE );
-+ */
-+#ifdef OXNAS_TACHO_Ox810
-+ write_reg( TACHO_CLOCK_DIVIDER, TACHO_CORE_TACHO_DIVIDER_VALUE );
-+
-+ /* check tacho divider set correctly */
-+ rc = read_reg(TACHO_CLOCK_DIVIDER);
-+ /* Comparing a 10 bit value to a 32 bit return value */
-+ if ((rc & TACHO_CORE_TACHO_DIVIDER_VALUE) != TACHO_CORE_TACHO_DIVIDER_VALUE) {
-+ printk(KERN_ERR "thermAndFan: Set Tacho Divider Value Failed readback:%d\n", rc);
-+ kfree(th);
-+ return -ENODEV;
-+ }
-+
-+#else /* OXNAS_TACHO_Ox810 */
-+ write_reg( TACHO_CLOCK_DIVIDER, TACHO_CORE_THERM_DIVIDER_VALUE );
-+
-+/* check tacho divider set correctly */
-+ rc = read_reg(TACHO_CLOCK_DIVIDER);
-+ /* Comparing a 10 bit value to a 32 bit return value */
-+ if ((rc & TACHO_CORE_THERM_DIVIDER_VALUE) != TACHO_CORE_THERM_DIVIDER_VALUE) {
-+ printk(KERN_ERR "thermAndFan: Thermostat failed to set config tacho divider readback:%d\n", rc);
-+ kfree(th);
-+ return -ENODEV;
-+ }
-+
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+/* printk(KERN_INFO "thermAndFan: Setting PWM core frequency divider to %d\n", PWM_CORE_CLK_DIVIDER_VALUE );
-+ */
-+ write_reg( PWM_CLOCK_DIVIDER, PWM_CORE_CLK_DIVIDER_VALUE );
-+
-+#ifdef OXNAS_TACHO_Ox810
-+ printk(KERN_INFO "thermAndFan: initializing - ox810\n");
-+#else /* OXNAS_TACHO_Ox810 */
-+ printk(KERN_INFO "thermAndFan: initializing\n");
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+#ifdef DEBUG
-+ DumpTachoRegisters();
-+#endif
-+
-+ thermostat = th;
-+
-+ /* Start the thermister measuring */
-+ write_reg( TACHO_THERMISTOR_CONTROL, (1 << TACHO_THERMISTOR_CONTROL_THERM_ENABLE) );
-+
-+ /* Start Speed measuring */
-+#ifdef OXNAS_TACHO_Ox810
-+ write_reg( TACHO_FAN_SPEED_CONTROL,
-+ (1 << (TACHO_FAN_SPEED_CONTROL_PWM_ENABLE_BASE
-+ + TACHO_FAN_SPEED_CONTROL_PWM_USED))
-+ | (1 << TACHO_FAN_SPEED_CONTROL_FAN_COUNT_MODE));
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+ /* be sure to really write fan speed the first time */
-+ th->last_speed = -2;
-+ th->last_var = -80;
-+
-+ /* Set fan to initial speed */
-+ write_fan_speed(th, min_fan_speed_ratio);
-+
-+ thread_therm = kthread_run(monitor_task, th, "kfand");
-+
-+ if (thread_therm == ERR_PTR(-ENOMEM)) {
-+ printk(KERN_INFO "thermAndFan: Kthread creation failed\n");
-+ thread_therm = NULL;
-+ return -ENOMEM;
-+ }
-+
-+ ret = misc_register(&oxsemi_therm_miscdev);
-+ if (ret < 0)
-+ return ret;
-+
-+ proc_oxsemi_therm = create_proc_entry("therm-fan", 0, NULL);
-+ if (proc_oxsemi_therm) {
-+ proc_oxsemi_therm->read_proc = oxsemi_therm_read;
-+ } else {
-+ printk(KERN_ERR "therm-fan: unable to register /proc/therm\n");
-+ }
-+
-+ return 0;
-+}
-+
-+
-+static void __exit oxsemi_therm_exit(void)
-+{
-+ if ( thread_therm )
-+ {
-+ kthread_stop(thread_therm);
-+ }
-+
-+ remove_proc_entry("therm-fan", NULL);
-+ misc_deregister(&oxsemi_therm_miscdev);
-+
-+ kfree(thermostat);
-+ thermostat = NULL;
-+/* return fan/tacho to system reset */
-+ *((volatile unsigned long *) SYS_CTRL_RSTEN_SET_CTRL) |= (1UL << SYS_CTRL_RSTEN_MISC_BIT);
-+}
-+
-+
-+module_init(oxsemi_therm_init);
-+module_exit(oxsemi_therm_exit);
-+
-+
-+/* End of File */
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/thermistorCalibration.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/thermistorCalibration.h
---- linux-2.6.24/arch/arm/mach-oxnas/thermistorCalibration.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/thermistorCalibration.h 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,149 @@
-+#ifndef __THERMISTOR_LOOKUP_TABLE_10K3A_H
-+#define __THERMISTOR_LOOKUP_TABLE_10K3A_H
-+
-+/* Thermistor is a 10K3A*/
-+/* THERM_COEF_A == 0.001129241*/
-+/* THERM_COEF_B == 0.0002341077. */
-+/* THERM_COEF_C == 0.00000008775468. */
-+
-+/* Capacitor is 100 nF */
-+/* Stepped frequency increment is 128000 Hz */
-+/* Schmitdt trigger threshold assumed: 1 / 3.3 V */
-+
-+
-+/* Inverse C.ln(V') == 216 */
-+#define THERM_INTERPOLATION_STEP 8
-+#define THERM_ENTRIES_IN_CALIB_TABLE 128
-+
-+static const unsigned long TvsCnt[THERM_ENTRIES_IN_CALIB_TABLE] = {
-+ 416, /* == 143.37 deg C: Count == 0, R == 216 Ohms */
-+ 340, /* == 67.07 deg C: Count == 8, R == 1948 Ohms */
-+ 323, /* == 49.59 deg C: Count == 16, R == 3679 Ohms */
-+ 313, /* == 39.76 deg C: Count == 24, R == 5410 Ohms */
-+ 306, /* == 33 deg C: Count == 32, R == 7141 Ohms */
-+ 301, /* == 27.9 deg C: Count == 40, R == 8873 Ohms */
-+ 297, /* == 23.82 deg C: Count == 48, R == 10604 Ohms */
-+ 293, /* == 20.43 deg C: Count == 56, R == 12335 Ohms */
-+ 291, /* == 17.55 deg C: Count == 64, R == 14066 Ohms */
-+ 288, /* == 15.04 deg C: Count == 72, R == 15798 Ohms */
-+ 286, /* == 12.82 deg C: Count == 80, R == 17529 Ohms */
-+ 284, /* == 10.84 deg C: Count == 88, R == 19260 Ohms */
-+ 282, /* == 9.04 deg C: Count == 96, R == 20991 Ohms */
-+ 280, /* == 7.41 deg C: Count == 104, R == 22722 Ohms */
-+ 279, /* == 5.91 deg C: Count == 112, R == 24454 Ohms */
-+ 278, /* == 4.53 deg C: Count == 120, R == 26185 Ohms */
-+ 276, /* == 3.25 deg C: Count == 128, R == 27916 Ohms */
-+ 275, /* == 2.05 deg C: Count == 136, R == 29647 Ohms */
-+ 274, /* == 0.93 deg C: Count == 144, R == 31379 Ohms */
-+ 273, /* == -0.12 deg C: Count == 152, R == 33110 Ohms */
-+ 272, /* == -1.12 deg C: Count == 160, R == 34841 Ohms */
-+ 271, /* == -2.06 deg C: Count == 168, R == 36572 Ohms */
-+ 270, /* == -2.95 deg C: Count == 176, R == 38304 Ohms */
-+ 269, /* == -3.8 deg C: Count == 184, R == 40035 Ohms */
-+ 268, /* == -4.6 deg C: Count == 192, R == 41766 Ohms */
-+ 268, /* == -5.37 deg C: Count == 200, R == 43497 Ohms */
-+ 267, /* == -6.11 deg C: Count == 208, R == 45229 Ohms */
-+ 266, /* == -6.81 deg C: Count == 216, R == 46960 Ohms */
-+ 266, /* == -7.49 deg C: Count == 224, R == 48691 Ohms */
-+ 265, /* == -8.14 deg C: Count == 232, R == 50422 Ohms */
-+ 264, /* == -8.77 deg C: Count == 240, R == 52154 Ohms */
-+ 264, /* == -9.37 deg C: Count == 248, R == 53885 Ohms */
-+ 263, /* == -9.95 deg C: Count == 256, R == 55616 Ohms */
-+ 262, /* == -10.52 deg C: Count == 264, R == 57347 Ohms */
-+ 262, /* == -11.06 deg C: Count == 272, R == 59078 Ohms */
-+ 261, /* == -11.59 deg C: Count == 280, R == 60810 Ohms */
-+ 261, /* == -12.1 deg C: Count == 288, R == 62541 Ohms */
-+ 260, /* == -12.59 deg C: Count == 296, R == 64272 Ohms */
-+ 260, /* == -13.07 deg C: Count == 304, R == 66003 Ohms */
-+ 259, /* == -13.53 deg C: Count == 312, R == 67735 Ohms */
-+ 259, /* == -13.99 deg C: Count == 320, R == 69466 Ohms */
-+ 259, /* == -14.43 deg C: Count == 328, R == 71197 Ohms */
-+ 258, /* == -14.86 deg C: Count == 336, R == 72928 Ohms */
-+ 258, /* == -15.27 deg C: Count == 344, R == 74660 Ohms */
-+ 257, /* == -15.68 deg C: Count == 352, R == 76391 Ohms */
-+ 257, /* == -16.08 deg C: Count == 360, R == 78122 Ohms */
-+ 257, /* == -16.46 deg C: Count == 368, R == 79853 Ohms */
-+ 256, /* == -16.84 deg C: Count == 376, R == 81585 Ohms */
-+ 256, /* == -17.21 deg C: Count == 384, R == 83316 Ohms */
-+ 255, /* == -17.57 deg C: Count == 392, R == 85047 Ohms */
-+ 255, /* == -17.92 deg C: Count == 400, R == 86778 Ohms */
-+ 255, /* == -18.26 deg C: Count == 408, R == 88510 Ohms */
-+ 254, /* == -18.6 deg C: Count == 416, R == 90241 Ohms */
-+ 254, /* == -18.93 deg C: Count == 424, R == 91972 Ohms */
-+ 254, /* == -19.25 deg C: Count == 432, R == 93703 Ohms */
-+ 253, /* == -19.57 deg C: Count == 440, R == 95434 Ohms */
-+ 253, /* == -19.88 deg C: Count == 448, R == 97166 Ohms */
-+ 253, /* == -20.18 deg C: Count == 456, R == 98897 Ohms */
-+ 253, /* == -20.48 deg C: Count == 464, R == 100628 Ohms */
-+ 252, /* == -20.77 deg C: Count == 472, R == 102359 Ohms */
-+ 252, /* == -21.06 deg C: Count == 480, R == 104091 Ohms */
-+ 252, /* == -21.34 deg C: Count == 488, R == 105822 Ohms */
-+ 251, /* == -21.62 deg C: Count == 496, R == 107553 Ohms */
-+ 251, /* == -21.89 deg C: Count == 504, R == 109284 Ohms */
-+ 251, /* == -22.16 deg C: Count == 512, R == 111016 Ohms */
-+ 251, /* == -22.42 deg C: Count == 520, R == 112747 Ohms */
-+ 250, /* == -22.68 deg C: Count == 528, R == 114478 Ohms */
-+ 250, /* == -22.93 deg C: Count == 536, R == 116209 Ohms */
-+ 250, /* == -23.18 deg C: Count == 544, R == 117941 Ohms */
-+ 250, /* == -23.43 deg C: Count == 552, R == 119672 Ohms */
-+ 249, /* == -23.67 deg C: Count == 560, R == 121403 Ohms */
-+ 249, /* == -23.91 deg C: Count == 568, R == 123134 Ohms */
-+ 249, /* == -24.14 deg C: Count == 576, R == 124866 Ohms */
-+ 249, /* == -24.37 deg C: Count == 584, R == 126597 Ohms */
-+ 248, /* == -24.6 deg C: Count == 592, R == 128328 Ohms */
-+ 248, /* == -24.82 deg C: Count == 600, R == 130059 Ohms */
-+ 248, /* == -25.04 deg C: Count == 608, R == 131790 Ohms */
-+ 248, /* == -25.26 deg C: Count == 616, R == 133522 Ohms */
-+ 248, /* == -25.47 deg C: Count == 624, R == 135253 Ohms */
-+ 247, /* == -25.68 deg C: Count == 632, R == 136984 Ohms */
-+ 247, /* == -25.89 deg C: Count == 640, R == 138715 Ohms */
-+ 247, /* == -26.1 deg C: Count == 648, R == 140447 Ohms */
-+ 247, /* == -26.3 deg C: Count == 656, R == 142178 Ohms */
-+ 247, /* == -26.5 deg C: Count == 664, R == 143909 Ohms */
-+ 246, /* == -26.69 deg C: Count == 672, R == 145640 Ohms */
-+ 246, /* == -26.89 deg C: Count == 680, R == 147372 Ohms */
-+ 246, /* == -27.08 deg C: Count == 688, R == 149103 Ohms */
-+ 246, /* == -27.27 deg C: Count == 696, R == 150834 Ohms */
-+ 246, /* == -27.46 deg C: Count == 704, R == 152565 Ohms */
-+ 245, /* == -27.64 deg C: Count == 712, R == 154297 Ohms */
-+ 245, /* == -27.82 deg C: Count == 720, R == 156028 Ohms */
-+ 245, /* == -28 deg C: Count == 728, R == 157759 Ohms */
-+ 245, /* == -28.18 deg C: Count == 736, R == 159490 Ohms */
-+ 245, /* == -28.36 deg C: Count == 744, R == 161222 Ohms */
-+ 244, /* == -28.53 deg C: Count == 752, R == 162953 Ohms */
-+ 244, /* == -28.7 deg C: Count == 760, R == 164684 Ohms */
-+ 244, /* == -28.87 deg C: Count == 768, R == 166415 Ohms */
-+ 244, /* == -29.04 deg C: Count == 776, R == 168146 Ohms */
-+ 244, /* == -29.21 deg C: Count == 784, R == 169878 Ohms */
-+ 244, /* == -29.37 deg C: Count == 792, R == 171609 Ohms */
-+ 243, /* == -29.53 deg C: Count == 800, R == 173340 Ohms */
-+ 243, /* == -29.69 deg C: Count == 808, R == 175071 Ohms */
-+ 243, /* == -29.85 deg C: Count == 816, R == 176803 Ohms */
-+ 243, /* == -30.01 deg C: Count == 824, R == 178534 Ohms */
-+ 243, /* == -30.16 deg C: Count == 832, R == 180265 Ohms */
-+ 243, /* == -30.32 deg C: Count == 840, R == 181996 Ohms */
-+ 243, /* == -30.47 deg C: Count == 848, R == 183728 Ohms */
-+ 242, /* == -30.62 deg C: Count == 856, R == 185459 Ohms */
-+ 242, /* == -30.77 deg C: Count == 864, R == 187190 Ohms */
-+ 242, /* == -30.92 deg C: Count == 872, R == 188921 Ohms */
-+ 242, /* == -31.06 deg C: Count == 880, R == 190653 Ohms */
-+ 242, /* == -31.21 deg C: Count == 888, R == 192384 Ohms */
-+ 242, /* == -31.35 deg C: Count == 896, R == 194115 Ohms */
-+ 242, /* == -31.49 deg C: Count == 904, R == 195846 Ohms */
-+ 241, /* == -31.63 deg C: Count == 912, R == 197578 Ohms */
-+ 241, /* == -31.77 deg C: Count == 920, R == 199309 Ohms */
-+ 241, /* == -31.91 deg C: Count == 928, R == 201040 Ohms */
-+ 241, /* == -32.04 deg C: Count == 936, R == 202771 Ohms */
-+ 241, /* == -32.18 deg C: Count == 944, R == 204502 Ohms */
-+ 241, /* == -32.31 deg C: Count == 952, R == 206234 Ohms */
-+ 241, /* == -32.44 deg C: Count == 960, R == 207965 Ohms */
-+ 240, /* == -32.58 deg C: Count == 968, R == 209696 Ohms */
-+ 240, /* == -32.71 deg C: Count == 976, R == 211427 Ohms */
-+ 240, /* == -32.83 deg C: Count == 984, R == 213159 Ohms */
-+ 240, /* == -32.96 deg C: Count == 992, R == 214890 Ohms */
-+ 240, /* == -33.09 deg C: Count == 1000, R == 216621 Ohms */
-+ 240, /* == -33.21 deg C: Count == 1008, R == 218352 Ohms */
-+ 240, /* == -33.34 deg C: Count == 1016, R == 220084 Ohms */
-+};
-+
-+#endif
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/time.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/time.c
---- linux-2.6.24/arch/arm/mach-oxnas/time.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/time.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,159 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/irq.c
-+ *
-+ * 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 <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/irq.h>
-+
-+#include <asm/io.h>
-+#include <asm/hardware.h>
-+#include <asm/mach/time.h>
-+
-+#ifdef CONFIG_OXNAS_AHB_MON
-+#include <asm/arch/ahb_mon.h>
-+#endif // CONFIG_OXNAS_AHB_MON
-+
-+#ifdef CONFIG_OXNAS_DDR_MON
-+static int client = 0;
-+#endif // CONFIG_OXNAS_DDR_MON
-+
-+static irqreturn_t OXNAS_timer_interrupt(int irq, void *dev_id)
-+{
-+#ifdef CONFIG_OXNAS_DDR_MON
-+ static const int NUM_MON_CLIENTS = 8;
-+#endif // CONFIG_OXNAS_DDR_MON
-+
-+ write_seqlock(&xtime_lock);
-+
-+ // Clear the timer interrupt - any write will do
-+ *((volatile unsigned long*)TIMER1_CLEAR) = 0;
-+
-+ timer_tick();
-+
-+ write_sequnlock(&xtime_lock);
-+
-+#ifdef CONFIG_OXNAS_DDR_MON
-+ if (!(jiffies % CONFIG_OXNAS_MONITOR_SUBSAMPLE)) {
-+ // Read the DDR core bus monitors
-+ u32 diag_reg_contents = readl(DDR_DIAG_REG);
-+ u32 holdoffs = (diag_reg_contents >> DDR_DIAG_HOLDOFFS_BIT) & ((1UL << DDR_DIAG_HOLDOFFS_NUM_BITS) - 1);
-+ u32 writes = (diag_reg_contents >> DDR_DIAG_WRITES_BIT) & ((1UL << DDR_DIAG_WRITES_NUM_BITS) - 1);
-+ u32 reads = (diag_reg_contents >> DDR_DIAG_READS_BIT) & ((1UL << DDR_DIAG_READS_NUM_BITS) - 1);
-+
-+ printk(KERN_INFO "$WC %d: H=%u, W=%u, R=%u\n", client, holdoffs, writes, reads);
-+ // Re-arm the DDR core bus monitors
-+ writel(client << DDR_MON_CLIENT_BIT, DDR_MON_REG);
-+ if (++client >= NUM_MON_CLIENTS) {
-+ client = 0;
-+ }
-+ }
-+#endif // CONFIG_OXNAS_DDR_MON
-+
-+#ifdef CONFIG_OXNAS_AHB_MON
-+ if (!(jiffies % CONFIG_OXNAS_MONITOR_SUBSAMPLE)) {
-+ read_ahb_monitors();
-+ restart_ahb_monitors();
-+ }
-+#endif // CONFIG_OXNAS_AHB_MON
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static struct irqaction oxnas_timer_irq = {
-+ .name = "Jiffy tick",
-+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-+ .handler = OXNAS_timer_interrupt
-+};
-+
-+static void /*__init*/ oxnas_init_time(void)
-+{
-+ // Connect the timer interrupt handler
-+ oxnas_timer_irq.handler = OXNAS_timer_interrupt;
-+ setup_irq(TIMER_1_INTERRUPT, &oxnas_timer_irq);
-+
-+ // Stop both timers before programming them
-+ *((volatile unsigned long*)TIMER1_CONTROL) = 0;
-+ *((volatile unsigned long*)TIMER2_CONTROL) = 0;
-+
-+ // Setup timer 1 load value
-+ *((volatile unsigned long*)TIMER1_LOAD) = TIMER_1_LOAD_VALUE;
-+
-+ // Setup timer 1 prescaler, periodic operation and start it
-+ *((volatile unsigned long*)TIMER1_CONTROL) =
-+ (TIMER_1_PRESCALE_ENUM << TIMER_PRESCALE_BIT) |
-+ (TIMER_1_MODE << TIMER_MODE_BIT) |
-+ (TIMER_ENABLE_ENABLE << TIMER_ENABLE_BIT);
-+
-+ // Setup timer 2 prescaler, free-running operation and start it
-+ // This will not be used to generate interrupt, just as a hi-res source of
-+ // timing information
-+ *((volatile unsigned long*)TIMER2_CONTROL) =
-+ (TIMER_2_PRESCALE_ENUM << TIMER_PRESCALE_BIT) |
-+ (TIMER_2_MODE << TIMER_MODE_BIT) |
-+ (TIMER_ENABLE_ENABLE << TIMER_ENABLE_BIT);
-+
-+#ifdef CONFIG_OXNAS_DDR_MON
-+ // Arm the DDR core bus monitors, start with client zero
-+ writel(client << DDR_MON_CLIENT_BIT, DDR_MON_REG);
-+#endif // CONFIG_OXNAS_DDR_MON
-+
-+#ifdef CONFIG_OXNAS_AHB_MON
-+ // Monitor all accesses
-+ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, 0, 0, 0, 0);
-+#endif // CONFIG_OXNAS_AHB_MON
-+}
-+
-+/*
-+ * Returns number of microseconds since last clock tick interrupt.
-+ * Note that interrupts will be disabled when this is called
-+ * Should take account of any pending timer tick interrupt
-+ */
-+static unsigned long oxnas_gettimeoffset(void)
-+{
-+ // How long since last timer interrupt?
-+ unsigned long ticks_since_last_intr =
-+ (unsigned long)TIMER_1_LOAD_VALUE - *((volatile unsigned long*)TIMER1_VALUE);
-+
-+ // Is there a timer interrupt pending
-+ int timer_int_pending =
-+ *((volatile unsigned long*)RPS_IRQ_RAW_STATUS) & (1UL << TIMER_1_INTERRUPT);
-+
-+ if (timer_int_pending) {
-+ // Sample time since last timer interrupt again. Theoretical race between
-+ // interrupt occuring and ARM reading value before reload has taken
-+ // effect, but in practice it's not going to happen because it takes
-+ // multiple clock cycles for the ARM to read the timer value register
-+ unsigned long ticks2 = (unsigned long)TIMER_1_LOAD_VALUE - *((volatile unsigned long*)TIMER1_VALUE);
-+
-+ // If the timer interrupt which hasn't yet been serviced, and thus has
-+ // not yet contributed to the tick count, occured before our initial
-+ // read of the current timer value then we need to account for a whole
-+ // timer interrupt period
-+ if (ticks_since_last_intr <= ticks2) {
-+ // Add on a whole timer interrupt period, as the tick count will have
-+ // wrapped around since the previously seen timer interrupt (?)
-+ ticks_since_last_intr += TIMER_1_LOAD_VALUE;
-+ }
-+ }
-+
-+ return TICKS_TO_US(ticks_since_last_intr);
-+}
-+
-+struct sys_timer oxnas_timer = {
-+ .init = oxnas_init_time,
-+ .offset = oxnas_gettimeoffset,
-+};
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/usb-test-mode.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/usb-test-mode.c
---- linux-2.6.24/arch/arm/mach-oxnas/usb-test-mode.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/usb-test-mode.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,253 @@
-+/*
-+ * arch/arm/mach-oxnas/usb-test-mode.c
-+ *
-+ * Copyright (C) 2006 Oxford Semiconductor Ltd
-+ *
-+ * 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 <linux/types.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/miscdevice.h>
-+#include <linux/smp_lock.h>
-+#include <linux/kernel.h>
-+#include <linux/delay.h>
-+#include <linux/sched.h>
-+#include <linux/i2c.h>
-+#include <linux/proc_fs.h>
-+#include <linux/capability.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/spinlock.h>
-+#include <linux/smp_lock.h>
-+#include <linux/wait.h>
-+#include <linux/suspend.h>
-+#include <linux/kthread.h>
-+#include <linux/moduleparam.h>
-+#include <linux/interrupt.h>
-+
-+#include <asm/io.h>
-+#include <asm/system.h>
-+#include <asm/sections.h>
-+#include <asm/uaccess.h>
-+#include <asm/bitops.h>
-+
-+#include <asm/hardware.h>
-+
-+
-+/* usb test masks and offsets */
-+#define TEST_MASK 0xF
-+#define TEST_OFFSET 16
-+
-+#define MODULE_VERS "0.1"
-+#define MODULE_NAME "usb_test_mode"
-+MODULE_AUTHOR( "John Larkworthy" );
-+MODULE_DESCRIPTION( "Driver to put usb ports in test modes" );
-+MODULE_LICENSE( "GPL" );
-+
-+
-+static struct proc_dir_entry *proc_dir_usb_test_read, *usb_test_dir;
-+
-+
-+/* create proc filing system entries to accept configuration data */
-+static int usb_test_write_entries(const char *name, write_proc_t *w, int data)
-+{
-+ struct proc_dir_entry * entry = create_proc_entry(name, 0222, usb_test_dir);
-+ if (entry) {
-+ entry->write_proc = w;
-+ entry->data = (void *)data;
-+ entry->owner = THIS_MODULE;
-+ return 0;
-+ }
-+ else
-+ {
-+ return -ENOMEM;
-+ }
-+}
-+
-+
-+
-+#if 0
-+static int
-+oxsemi_usb_test_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-+{
-+ //int i = (int __user *)arg;
-+
-+ printk(KERN_INFO "usb test:: usb_test_ioctl\n");
-+ switch(cmd) {
-+ case SET_TEST_MODE:
-+ break;
-+ // etc...
-+
-+ default:
-+ return -ENOIOCTLCMD;
-+ }
-+
-+ return 0;
-+}
-+#endif
-+
-+static int
-+oxsemi_usb_test_read(char *buf, char **start, off_t offset,
-+ int count, int *eof, void *unused)
-+{
-+
-+ int i;
-+ int len = 0;
-+ long unsigned *usbport;
-+
-+ usbport = (long unsigned *) (USB_BASE+0x184);
-+
-+ for (i=0; i < 3; i++)
-+ {
-+ len += sprintf(buf+len, "usb port %d [%p]:%08lx \n", i, (usbport+4*i) , *(usbport+i));
-+ }
-+ *eof=1;
-+ return len;
-+}
-+
-+static int
-+oxsemi_usb_test_write(struct file *file, const char *buf, unsigned long count, void * data)
-+{
-+ int len;
-+ long int *usbport;
-+ char local[10];
-+ int result;
-+ int test_mode;
-+ unsigned long flags;
-+
-+ if (count > 9)
-+ len= 9;
-+ else
-+ len=count;
-+
-+ if (copy_from_user(&local, buf, len))
-+ return -EFAULT;
-+
-+ /* extract value from buffer and store */
-+ result = sscanf(local, "%1d", &test_mode);
-+ if (result != 1)
-+ return -EINVAL;
-+
-+ usbport = (long int *) (USB_BASE+0X184 + (4* (int) data));
-+ printk(KERN_ERR "usb-test-write : [%08lx] <- %08lx \n",
-+ (long unsigned) usbport,
-+ (long unsigned) ((test_mode & TEST_MASK) << TEST_OFFSET));
-+ /* lock system while this is updated */
-+ local_irq_save(flags);
-+ *usbport = (*usbport & ~(TEST_MASK<<TEST_OFFSET)) | ((test_mode & TEST_MASK) << TEST_OFFSET);
-+ local_irq_restore(flags);
-+ printk(KERN_ERR "usb-test-writen: [%08lx]:%08lx \n", (long unsigned) usbport, (long unsigned) *usbport);
-+ return len;
-+}
-+
-+
-+static int __init oxsemi_usb_test_init(void)
-+{
-+ int rv;
-+ int i;
-+ char name[] = "usb-test/write0"; /* overwritten with new name below */
-+
-+ usb_test_dir = proc_mkdir(MODULE_NAME, NULL);
-+ if (usb_test_dir == NULL) {
-+ printk(KERN_ERR "usb-test: unable to register /proc/usb-test\n");
-+ rv= -ENOMEM;
-+ goto out;
-+ }
-+
-+ usb_test_dir->owner= THIS_MODULE;
-+
-+ proc_dir_usb_test_read = create_proc_entry("read", 0444, usb_test_dir);
-+ if (proc_dir_usb_test_read) {
-+ proc_dir_usb_test_read->read_proc = oxsemi_usb_test_read;
-+ } else {
-+ printk(KERN_ERR "usb-test: unable to register /proc/usb-test/read\n");
-+ rv = -ENOMEM;
-+ goto no_read;
-+ }
-+ /* create port write file entries */
-+ for (i=0;i<3;i++)
-+ {
-+ sprintf(name,"write%d",i+1);
-+ rv = usb_test_write_entries(name, &oxsemi_usb_test_write, i);
-+ if (rv < 0)
-+ {
-+ while (i != 0)
-+ {
-+ i--;
-+ /* remove any allocated entries */
-+ sprintf(name,"usb-test/write%d",i+1);
-+ remove_proc_entry (name, usb_test_dir);
-+ }
-+ goto no_write;
-+ }
-+ }
-+ printk(KERN_INFO "%s %s initialised\n", MODULE_NAME, MODULE_VERS);
-+
-+ return 0;
-+ no_write:
-+ remove_proc_entry("usb-test/read", usb_test_dir);
-+ no_read:
-+ remove_proc_entry(MODULE_NAME, NULL);
-+ out:
-+ return rv;
-+}
-+
-+
-+static void __exit oxsemi_usb_test_exit(void)
-+{
-+ char name[] = "usb-test/write0";
-+ int i;
-+
-+ for (i = 0; i < 3; i++)
-+ {
-+ sprintf(name, "write%1d", (i+1));
-+ remove_proc_entry(name, usb_test_dir);
-+ }
-+
-+ remove_proc_entry("read", usb_test_dir);
-+ remove_proc_entry(MODULE_NAME, NULL);
-+
-+ printk(KERN_INFO "%s %s removed\n", MODULE_NAME, MODULE_VERS);
-+
-+}
-+
-+
-+module_init(oxsemi_usb_test_init);
-+module_exit(oxsemi_usb_test_exit);
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/user_recovery_button.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/user_recovery_button.c
---- linux-2.6.24/arch/arm/mach-oxnas/user_recovery_button.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/user_recovery_button.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,260 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/user_recovery_button.c
-+ *
-+ * Copyright (C) 2008 Oxford Semiconductor Ltd
-+ *
-+ * 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 <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/module.h>
-+#include <linux/timer.h>
-+#include <linux/kobject.h>
-+#include <linux/workqueue.h>
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+
-+MODULE_LICENSE("GPL v2");
-+
-+#if (CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO < 32)
-+#define SWITCH_NUM CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO
-+#define IRQ_NUM GPIO_1_INTERRUPT
-+#define INT_STATUS_REG GPIO_A_INTERRUPT_STATUS_REGISTER
-+#define SWITCH_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_0
-+#define SWITCH_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_0
-+#define SWITCH_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_0
-+#define SWITCH_CLR_OE_REG GPIO_A_OUTPUT_ENABLE_CLEAR
-+#define DEBOUNCE_REG GPIO_A_INPUT_DEBOUNCE_ENABLE
-+#define LEVEL_INT_REG GPIO_A_LEVEL_INTERRUPT_ENABLE
-+#define FALLING_INT_REG GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE
-+#define DATA_REG GPIO_A_DATA
-+#else
-+#define SWITCH_NUM ((CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO) - 32)
-+#define IRQ_NUM GPIO_2_INTERRUPT
-+#define INT_STATUS_REG GPIO_B_INTERRUPT_STATUS_REGISTER
-+#define SWITCH_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_1
-+#define SWITCH_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_1
-+#define SWITCH_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_1
-+#define SWITCH_CLR_OE_REG GPIO_B_OUTPUT_ENABLE_CLEAR
-+#define DEBOUNCE_REG GPIO_B_INPUT_DEBOUNCE_ENABLE
-+#define LEVEL_INT_REG GPIO_B_LEVEL_INTERRUPT_ENABLE
-+#define FALLING_INT_REG GPIO_B_FALLING_EDGE_ACTIVE_LOW_ENABLE
-+#define DATA_REG GPIO_B_DATA
-+#endif
-+
-+#define SWITCH_MASK (1UL << (SWITCH_NUM))
-+
-+#define TIMER_INTERVAL_JIFFIES ((HZ) >> 3) /* An eigth of a second */
-+#define TIMER_COUNT_LIMIT 32 /* In eigths of a second */
-+
-+extern spinlock_t oxnas_gpio_spinlock;
-+
-+static unsigned long count;
-+static struct timer_list timer;
-+
-+/** Have to use active low level interupt generation, as otherwise might miss
-+ * interrupts that arrive concurrently with a PCI interrupt, as PCI interrupts
-+ * are generated via GPIO pins and std PCI drivers will not know that there
-+ * may be other pending GPIO interrupt sources waiting to be serviced and will
-+ * simply return IRQ_HANDLED if they see themselves as having generated the
-+ * interrupt, thus preventing later chained handlers from being called
-+ */
-+static irqreturn_t int_handler(int irq, void* dev_id)
-+{
-+ int status = IRQ_NONE;
-+ unsigned int int_status = readl((volatile unsigned long *)INT_STATUS_REG);
-+
-+ /* Is the interrupt for us? */
-+ if (int_status & SWITCH_MASK) {
-+ /* Disable the user recovery button GPIO line interrupt */
-+ spin_lock(&oxnas_gpio_spinlock);
-+ writel(readl(FALLING_INT_REG) & ~SWITCH_MASK, FALLING_INT_REG);
-+ spin_unlock(&oxnas_gpio_spinlock);
-+
-+ /* Zeroise button hold down counter */
-+ count = 0;
-+
-+ /* Start hold down timer with a timeout of 1/8 second */
-+ mod_timer(&timer, jiffies + TIMER_INTERVAL_JIFFIES);
-+
-+ /* Only mark interrupt as serviced if no other unmasked GPIO interrupts
-+ are pending */
-+ if (!readl((volatile unsigned long *)INT_STATUS_REG)) {
-+ status = IRQ_HANDLED;
-+ }
-+ }
-+
-+ return status;
-+}
-+
-+/*
-+ * Device driver object
-+ */
-+typedef struct recovery_button_driver_s {
-+ /** sysfs dir tree root for recovery button driver */
-+ struct kset kset;
-+ struct kobject recovery_button;
-+} recovery_button_driver_t;
-+
-+static recovery_button_driver_t recovery_button_driver;
-+
-+static void work_handler(struct work_struct * not_used) {
-+ kobject_uevent(&recovery_button_driver.recovery_button, KOBJ_OFFLINE);
-+}
-+
-+DECLARE_WORK(recovery_button_hotplug_work, work_handler);
-+
-+static void timer_handler(unsigned long data)
-+{
-+ unsigned long flags;
-+
-+ /* Is the user recovery button still pressed? */
-+ if (!(readl(DATA_REG) & SWITCH_MASK)) {
-+ /* Yes, so increment count of how many timer intervals have passed since
-+ user recovery button was pressed */
-+ if (++count == TIMER_COUNT_LIMIT) {
-+ schedule_work(&recovery_button_hotplug_work);
-+ } else {
-+ /* Restart timer with a timeout of 1/8 second */
-+ mod_timer(&timer, jiffies + TIMER_INTERVAL_JIFFIES);
-+ }
-+ } else {
-+ /* The h/w debounced user recovery button has been released, so reenable the
-+ active low interrupt detection to trap the user's next attempt to
-+ recover */
-+ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+ writel(readl(FALLING_INT_REG) | SWITCH_MASK, FALLING_INT_REG);
-+ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+ }
-+}
-+
-+static struct kobj_type ktype_recovery_button = {
-+ .release = 0,
-+ .sysfs_ops = 0,
-+ .default_attrs = 0,
-+};
-+
-+static int recovery_button_hotplug_filter(struct kset* kset, struct kobject* kobj) {
-+ return get_ktype(kobj) == &ktype_recovery_button;
-+}
-+
-+static const char* recovery_button_hotplug_name(struct kset* kset, struct kobject* kobj) {
-+ return "oxnas_user_recovery";
-+}
-+
-+static struct kset_uevent_ops recovery_button_uevent_ops = {
-+ .filter = recovery_button_hotplug_filter,
-+ .name = recovery_button_hotplug_name,
-+ .uevent = NULL,
-+};
-+
-+static int recovery_button_prep_sysfs(void)
-+{
-+ int err = 0;
-+
-+ /* prep the sysfs interface for use */
-+ kobject_set_name(&recovery_button_driver.kset.kobj, "recovery-button");
-+ recovery_button_driver.kset.ktype = &ktype_recovery_button;
-+
-+ err = subsystem_register(&recovery_button_driver.kset);
-+ if (err)
-+ return err;
-+
-+ /* setup hotplugging */
-+ recovery_button_driver.kset.uevent_ops = &recovery_button_uevent_ops;
-+
-+ /* setup the heirarchy, the name will be set on detection */
-+ kobject_init(&recovery_button_driver.recovery_button);
-+ recovery_button_driver.recovery_button.kset = kset_get(&recovery_button_driver.kset);
-+ recovery_button_driver.recovery_button.parent = &recovery_button_driver.kset.kobj;
-+
-+ return 0;
-+}
-+
-+static int recovery_button_build_sysfs(void) {
-+ kobject_set_name(&recovery_button_driver.recovery_button, "recovery-button-1");
-+ return kobject_add(&recovery_button_driver.recovery_button);
-+}
-+
-+static int __init recovery_button_init(void)
-+{
-+ int err = 0;
-+ unsigned long flags;
-+
-+ err = recovery_button_prep_sysfs();
-+ if (err)
-+ return -EINVAL;
-+
-+ err = recovery_button_build_sysfs();
-+ if (err)
-+ return -EINVAL;
-+
-+ /* Setup the timer that will time how long the user holds down the recovery
-+ button */
-+ init_timer(&timer);
-+ timer.data = 0;
-+ timer.function = timer_handler;
-+
-+ /* Install a shared interrupt handler on the appropriate GPIO bank's
-+ interrupt line */
-+ if (request_irq(IRQ_NUM, int_handler, IRQF_SHARED, "User Recovery Button", &recovery_button_driver)) {
-+ printk(KERN_ERR "User Recovery Button: cannot register IRQ %d\n", IRQ_NUM);
-+ del_timer_sync(&timer);
-+ return -EIO;
-+ }
-+
-+ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+ /* Disable primary, secondary and teriary GPIO functions on switch lines */
-+ writel(readl(SWITCH_PRISEL_REG) & ~SWITCH_MASK, SWITCH_PRISEL_REG);
-+ writel(readl(SWITCH_SECSEL_REG) & ~SWITCH_MASK, SWITCH_SECSEL_REG);
-+ writel(readl(SWITCH_TERSEL_REG) & ~SWITCH_MASK, SWITCH_TERSEL_REG);
-+
-+ /* Enable GPIO input on switch line */
-+ writel(SWITCH_MASK, SWITCH_CLR_OE_REG);
-+
-+ /* Set up the user recovery button GPIO line for active low, debounced interrupt */
-+ writel(readl(DEBOUNCE_REG) | SWITCH_MASK, DEBOUNCE_REG);
-+ writel(readl(LEVEL_INT_REG) | SWITCH_MASK, LEVEL_INT_REG);
-+ writel(readl(FALLING_INT_REG) | SWITCH_MASK, FALLING_INT_REG);
-+ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+
-+ printk(KERN_INFO "Recovery button driver registered\n");
-+ return 0;
-+}
-+
-+static void __exit recovery_button_exit(void)
-+{
-+ unsigned long flags;
-+
-+ kobject_del(&recovery_button_driver.recovery_button);
-+ subsystem_unregister(&recovery_button_driver.kset);
-+
-+ /* Deactive the timer */
-+ del_timer_sync(&timer);
-+
-+ /* Disable interrupt generation by the recovery button GPIO line */
-+ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+ writel(readl(FALLING_INT_REG) & ~SWITCH_MASK, FALLING_INT_REG);
-+ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+
-+ /* Remove the handler for the shared interrupt line */
-+ free_irq(IRQ_NUM, &recovery_button_driver);
-+}
-+
-+/**
-+ * macros to register intiialisation and exit functions with kernal
-+ */
-+module_init(recovery_button_init);
-+module_exit(recovery_button_exit);
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/wdc-fan.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/wdc-fan.c
---- linux-2.6.24/arch/arm/mach-oxnas/wdc-fan.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/wdc-fan.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,336 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/wdc-fan.c
-+ *
-+ * Copyright (C) 2006-2007 Western Digital
-+ *
-+ * 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 <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/err.h>
-+#include <linux/ctype.h>
-+#include <linux/platform_device.h>
-+#include <asm/hardware.h>
-+
-+/* Human recognizable driver name. */
-+#define DRIVER_NAME "WDC_Fan"
-+
-+/* GPIOs for the fan on the Galaxy 2NC platform. All are on GPIO_A */
-+#define FAN_MASK_LOW (1 << GPIO_29)
-+#define FAN_MASK_HIGH (1 << GPIO_8)
-+
-+#define FAN_MASK ( FAN_MASK_LOW | FAN_MASK_HIGH )
-+
-+
-+/* I/O register access (FIXME: why not use the standard linux macros?) */
-+#define ox_writel(data, addr) (*(volatile unsigned long*)addr = (data))
-+#define ox_readl(addr) (*(volatile unsigned long*)addr)
-+#define writel(data, addr) (*(volatile u32*)addr = (data))
-+#define readl(addr) (*(volatile u32*)addr)
-+#define CLEAR(addr, mask) writel(readl(addr) & ~mask, addr)
-+
-+enum fan_speeds
-+{
-+ FAN_OFF = 0,
-+ FAN_SPEED_MAX = 100
-+};
-+
-+typedef struct s_fan_device_state
-+{
-+ unsigned char speed; /* Range FAN_OFF .. FAN_SPEED_MAX */
-+} fan_device_state;
-+
-+
-+/*
-+ * Driver-global variables.
-+ */
-+
-+/* Number of successful probes. */
-+/* TODO: protect this variable??!? */
-+static int fans_found;
-+
-+/* This spinlock protects the GPIO setup code from
-+ interrupts but is not SMP-correct. */
-+static spinlock_t oxnas_gpio_spinlock;
-+
-+/* Device instance state.
-+ Only one fan is supported, so this can be a global variable. */
-+static fan_device_state fan_state;
-+
-+
-+/*
-+ * Device attribute getter/setters
-+ */
-+static ssize_t fan_speed_show (struct device*, struct device_attribute*,
-+ char *buf);
-+
-+static ssize_t fan_speed_store(struct device*, struct device_attribute*,
-+ const char *buf, size_t count);
-+
-+/* Declare device attributes using the functions above.
-+ Contrary to the macro's name, DEVICE_ATTR declares a dev_attr_... */
-+static DEVICE_ATTR(speed, 0644, fan_speed_show, fan_speed_store);
-+
-+
-+static void set_fan_speed(unsigned char speed);
-+
-+static int fan_probe (struct platform_device *pdev);
-+static int fan_remove(struct platform_device *pdev);
-+
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: fan_probe */
-+/* */
-+/* PURPOSE: */
-+/* Look for fans and do initialize. */
-+/***************************************************************************/
-+int fan_probe(struct platform_device *pdev)
-+{
-+ int rc = 0;
-+
-+ do {
-+ unsigned long lock_flags;
-+
-+ printk(KERN_DEBUG "Fan probe\n");
-+
-+ memset(&fan_state, sizeof(fan_state), 0);
-+
-+ /* Setup the fan-control GPIO lines properly. */
-+ spin_lock_irqsave(&oxnas_gpio_spinlock, lock_flags);
-+
-+ do {
-+ /* Enable desired GPIO drivers by disabling other functions. */
-+ CLEAR(SYS_CTRL_GPIO_PRIMSEL_CTRL_0, FAN_MASK);
-+ CLEAR(SYS_CTRL_GPIO_SECSEL_CTRL_0, FAN_MASK);
-+ CLEAR(SYS_CTRL_GPIO_TERTSEL_CTRL_0, FAN_MASK);
-+
-+ /* Turn off the fan... then enable its outputs. */
-+ writel(FAN_MASK, GPIO_A_OUTPUT_CLEAR);
-+ writel(FAN_MASK, GPIO_A_OUTPUT_ENABLE_SET);
-+
-+ } while (0);
-+
-+ spin_unlock_irqrestore(&oxnas_gpio_spinlock, lock_flags);
-+
-+
-+ /* Create an entry in sysfs so user apps can control the fan. */
-+ rc = device_create_file(&pdev->dev, &dev_attr_speed);
-+ if (rc < 0) break;
-+
-+ fans_found++;
-+
-+ set_fan_speed(FAN_OFF);
-+
-+ } while(0);
-+
-+
-+ /* Cleanup if any errors occured. */
-+ if(rc < 0)
-+ {
-+ fan_remove(pdev);
-+ }
-+
-+ return rc;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: fan_remove */
-+/* */
-+/* PURPOSE: */
-+/* Deactive the fan device(s) */
-+/***************************************************************************/
-+int fan_remove(struct platform_device *pdev)
-+{
-+ printk(KERN_DEBUG "Fan remove\n");
-+
-+ /* Undo everything that might have been done by fan_probe() */
-+
-+ device_remove_file(&pdev->dev, &dev_attr_speed);
-+
-+ writel(FAN_MASK, GPIO_A_OUTPUT_ENABLE_CLEAR);
-+
-+ return 0;
-+}
-+
-+
-+/***************************************************************************/
-+/* */
-+/* sysfs attribute I/O - user-space control points */
-+/* */
-+/***************************************************************************/
-+
-+/* fan_speed_show()
-+ *
-+ * Called when the speed setting attribute is read;
-+ * returns the current fan speed.
-+ */
-+ssize_t fan_speed_show(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ /* TODO: Check sizeof buf? Nobody else does*/
-+
-+ return sprintf(buf, "%u\n", fan_state.speed);
-+}
-+
-+/* fan_speed_store()
-+ *
-+ * Called when the speed setting attribute is written;
-+ * sets a new fan speed.
-+ */
-+ssize_t fan_speed_store(struct device *dev, struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ char *end;
-+ long newSpeed;
-+
-+ newSpeed = simple_strtol(buf, &end, 10);
-+ while (*end)
-+ {
-+ if (!isspace(*end++)) return -EINVAL;
-+ }
-+
-+ if (newSpeed < 0) newSpeed = 0;
-+ if (newSpeed > FAN_SPEED_MAX) newSpeed = FAN_SPEED_MAX;
-+
-+ set_fan_speed( (unsigned char)newSpeed );
-+
-+ return count; /* Entire string was consumed and validated. */
-+}
-+
-+/* set_fan_speed()
-+ *
-+ * Sets the fan's speed by twiddling its power control (GPO) lines.
-+ */
-+void set_fan_speed(unsigned char newSpeed)
-+{
-+int oldSpeed = fan_state.speed;
-+
-+ /* Round the requested fan speed to the nearest supported
-+ value and set the fan's power lines appropriately. */
-+
-+ /* The 2NC platform has three fan settings: off, low, hi-speed. */
-+
-+ if (newSpeed < 10)
-+ {
-+ fan_state.speed = FAN_OFF; /* Turn off the fan. */
-+ writel(FAN_MASK_LOW | FAN_MASK_HIGH, GPIO_A_OUTPUT_CLEAR);
-+ }
-+ else if (newSpeed < 75)
-+ {
-+ fan_state.speed = 50; /* Set to low speed. */
-+ writel(FAN_MASK_HIGH, GPIO_A_OUTPUT_CLEAR);
-+ writel(FAN_MASK_LOW, GPIO_A_OUTPUT_SET);
-+ }
-+ else
-+ {
-+ fan_state.speed = FAN_SPEED_MAX; /* Set to max (high) speed. */
-+ writel(FAN_MASK_LOW | FAN_MASK_HIGH, GPIO_A_OUTPUT_SET);
-+ }
-+
-+ if (oldSpeed != fan_state.speed)
-+ {
-+#if 0
-+ printk(KERN_DEBUG "WDC Fan speed set %u\n", fan_state.speed);
-+#endif
-+ }
-+}
-+
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_driver */
-+/* */
-+/* PURPOSE: */
-+/* Describe the wdc-leds platform device driver */
-+/***************************************************************************/
-+static struct platform_driver fan_driver =
-+{
-+ .probe = fan_probe,
-+ .remove = fan_remove,
-+ .driver =
-+ {
-+ .name = "wdc-fan",
-+ },
-+};
-+
-+static struct platform_device *fan_device;
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_init */
-+/* */
-+/* PURPOSE: */
-+/* Perform module initialization */
-+/***************************************************************************/
-+static int __init wdc_fan_init(void)
-+{
-+ int rc = 0;
-+
-+ fans_found = 0;
-+ spin_lock_init(&oxnas_gpio_spinlock);
-+
-+ rc = platform_driver_register(&fan_driver);
-+ if (rc) goto quit;
-+
-+ fan_device = platform_device_register_simple("wdc-fan", -1, NULL, 0);
-+ if (IS_ERR(fan_device))
-+ {
-+ rc = PTR_ERR(fan_device);
-+ fan_device = NULL;
-+
-+ platform_driver_unregister(&fan_driver);
-+ goto quit;
-+ }
-+
-+
-+quit:
-+ if (rc)
-+ {
-+ printk(KERN_ERR DRIVER_NAME " init failed, rc=%i\n", rc);
-+ }
-+ else
-+ {
-+ printk(KERN_INFO DRIVER_NAME " initialized\n");
-+ }
-+
-+ return rc;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_exit */
-+/* */
-+/* PURPOSE: */
-+/* Perform module unloading and cleanup */
-+/***************************************************************************/
-+static void __exit wdc_fan_exit(void)
-+{
-+ platform_device_unregister(fan_device);
-+ platform_driver_unregister(&fan_driver);
-+
-+ printk(KERN_INFO DRIVER_NAME " goodbye!\n");
-+}
-+
-+
-+module_init(wdc_fan_init);
-+module_exit(wdc_fan_exit);
-+
-+MODULE_AUTHOR("James Lin");
-+MODULE_DESCRIPTION("Western Digital NetCenter/2NC Fan Control");
-+MODULE_LICENSE("GPL");
-+
-+/*EOF*/
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/wdc-leds.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/wdc-leds.c
---- linux-2.6.24/arch/arm/mach-oxnas/wdc-leds.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/wdc-leds.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,1299 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/wdc-leds.c
-+ *
-+ * Copyright (C) 2006 Western Digital
-+ *
-+ * 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 <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/timer.h>
-+#include <linux/interrupt.h>
-+#include <linux/platform_device.h>
-+#include <linux/leds.h>
-+#include <asm/hardware.h>
-+
-+#define DEBUG
-+
-+#ifdef DEBUG
-+ #define DUMP(A,B) printk(KERN_INFO A,B);
-+#else
-+ #define DUMP(A,B)
-+#endif
-+
-+/* Number of LEDs */
-+#define NUM_ACTIVITY_LEDS 4
-+#define NUM_FUEL_GAUGE_LEDS 6
-+
-+/* Timer Values and Pulse Width Modulation */
-+#define PWM_RESOLUTION 255
-+#define TIMER_LED_MODE TIMER_MODE_PERIODIC
-+
-+#define PWM_CLOCK_DATA (
-+
-+#define LED100 (PWM_RESOLUTION) /* 100% duty cycle */
-+#define LED50 (PWM_RESOLUTION / 2) /* 50% duty cycle */
-+#define LED25 (PWM_RESOLUTION / 4) /* 25% duty cycle */
-+
-+#define STEP_RESOLUTION (16) /* change intensity in 16 steps */
-+
-+/* Setup Timer2 prescaler, operation mode, and start it */
-+#define PERIODIC_INTERRUPT \
-+ ( \
-+ (TIMER_PRESCALE_256 << TIMER_PRESCALE_BIT) | \
-+ (TIMER_LED_MODE << TIMER_MODE_BIT) | \
-+ (TIMER_ENABLE_ENABLE << TIMER_ENABLE_BIT) \
-+ )
-+
-+/*
-+ * Target frame rate is 60Hz. Slower frame rates flicker badly.
-+ * Since each frame has 16 divisions to perform the pulse width
-+ * modulation that means we need the timer set to 960Hz (i.e. 60 * 16)
-+ *
-+ * With a system clock of 25Mhz and a load register value of 1627 prescaled 256
-+ * to achieve 60Hz:
-+ * 25Mhz / 256 / 1627 = ~60
-+ */
-+#define FAST_TIMER_INT (1627) /* Timer2 count down */
-+#define SYS_CLOCK (25000000) /* System clock frequency */
-+#define PRESCALE_VALUE (256) /* Value set in prescaler */
-+#define PWM_PRESCALE 814 /* Value loaded on PWM clock register */
-+#define MAX_PWM 255
-+#define SLOW_TPS ((SYS_CLOCK/PRESCALE_VALUE) / FAST_TIMER_INT)
-+
-+/* The GPIO assignent to LED Masks need to make sure that the
-+ * LED_MASK_GPIO_A and LED_MASK_GPIO_B are set appropriately
-+ * based on the GPIOs assigned
-+ */
-+
-+/* GPIO bits dedicated to LEDs */
-+#define LED_MASK_ACT12 (1 << GPIO_6) /* Activity 12 o'clock */
-+#define LED_MASK_ACT3 (1 << GPIO_7) /* Activity 3 o'clock */
-+#define LED_MASK_ACT6 (1 << GPIO_5) /* Activity 6 o'clock */
-+#define LED_MASK_ACT9 (1 << GPIO_34) /* Activity 9 o'clock */
-+#define LED_MASK_FG12 (1 << GPIO_10) /* Fuel Gauge 10 o'clock */
-+#define LED_MASK_FG2 (1 << GPIO_9) /* Fuel Gauge 8 o'clock */
-+#define LED_MASK_FG4 (1 << GPIO_25) /* Fuel Gauge 6 o'clock */
-+#define LED_MASK_FG6 (1 << GPIO_26) /* Fuel Gauge 4 o'clock */
-+#define LED_MASK_FG8 (1 << GPIO_27) /* Fuel Gauge 2 o'clock */
-+#define LED_MASK_FG10 (1 << GPIO_33) /* Fuel Gauge 12 o'clock */
-+
-+/*
-+ * Mask for all the LEDs in the Fuel Gauge. This is in frame buffer format
-+ * (see LED frame buffer design assumption comments below, near the
-+ * frame_buffer declaration).
-+ */
-+#define LED_MASK_FUEL_GAUGE \
-+ ( \
-+ LED_MASK_FG12 | \
-+ LED_MASK_FG2 | \
-+ LED_MASK_FG4 | \
-+ LED_MASK_FG6 | \
-+ LED_MASK_FG8 | \
-+ LED_MASK_FG10 \
-+ )
-+
-+/* Mask for all the Activity LEDs */
-+#define LED_MASK_ACTIVITY \
-+ ( \
-+ LED_MASK_ACT12 | \
-+ LED_MASK_ACT3 | \
-+ LED_MASK_ACT6 | \
-+ LED_MASK_ACT9 \
-+ )
-+
-+/* The GPIO_A and GPIO_B Masks below need to be set based on the
-+ * GPIO numbers that are assigned for the LED MASKS
-+ */
-+
-+/* Mask for all the LEDs on GPIO_A */
-+#define LED_MASK_GPIO_A \
-+ ( \
-+ LED_MASK_ACT12 | \
-+ LED_MASK_ACT3 | \
-+ LED_MASK_ACT6 | \
-+ LED_MASK_FG12 | \
-+ LED_MASK_FG2 | \
-+ LED_MASK_FG4 | \
-+ LED_MASK_FG6 | \
-+ LED_MASK_FG8 \
-+ )
-+
-+/* Mask for all the LEDs on GPIO_B */
-+#define LED_MASK_GPIO_B \
-+ ( \
-+ LED_MASK_ACT9 | \
-+ LED_MASK_FG10 \
-+ )
-+
-+/* I/O register access (FIXME: why not use the standard linux macros?) */
-+#define ox_writel(data, addr) (*(volatile unsigned long*)addr = (data))
-+#define ox_readl(addr) (*(volatile unsigned long*)addr)
-+#define writel(data, addr) (*(volatile u32*)addr = (data))
-+#define readl(addr) (*(volatile u32*)addr)
-+#define CLEAR(addr, mask) writel(readl(addr) & ~mask, addr)
-+
-+
-+/* Variables to hold the number of LED classes created */
-+static int leds_created;
-+
-+/* Variables to save/restore timer register values */
-+static u32 timer_load;
-+static u32 timer_control;
-+
-+/* LED polarity */
-+static int negative_led_logic = 0;
-+module_param(negative_led_logic, bool, 0);
-+
-+/*
-+ * States for the main LED behavior state machine. The order of these states
-+ * is important. In particular, the TRANS states use this ordering so that
-+ * incrementing the state variable walks through the ordering shown below.
-+ * This allows most of the TRANS states to share common code.
-+ */
-+enum {
-+ FULLY_ON__ENTRY, /* FullyOn - Initialize */
-+ FULLY_ON__RE_ENTRY, /* FullyOn - Initialize (skipping POR) */
-+ FULLY_ON__POR_RAMP_UP, /* FullyOn - Ramp up full ring */
-+ FULLY_ON__POR_HOLD, /* FullyOn - Hold a while with full ring */
-+ FULLY_ON__RAMP_UP, /* FullyOn - Ramp up full ring (skipping POR) */
-+ FULLY_ON__ACTIVITY, /* FullyOn - Read/write activity */
-+ FULLY_ON__IDLE_HOLD, /* FullyOn - Hold a while for no R/W activity */
-+ FULLY_ON__RAMP_DOWN, /* FullyOn - Ramp down full ring */
-+ STANDBY__ENTRY, /* Standby - Initialize */
-+ STANDBY__DARK, /* Standby - Full ring off */
-+ STANDBY__RAMP_UP, /* Standby - Ramp up full ring */
-+ STANDBY__RAMP_DOWN, /* Standby - Ramp down full ring */
-+ POWER_OFF__ENTRY, /* PowerOff - Initialize */
-+ POWER_OFF__DARK, /* PowerOff - Full ring off */
-+ DEGRADED__ENTRY, /* Degraded - Initialize */
-+ DEGRADED__BLINK1, /* Degraded - Blink step1 */
-+ DEGRADED__BLINK2, /* Degraded - Blink step2 */
-+ OVERTEMP__ENTRY, /* OverTemp - Initialize */
-+ OVERTEMP__BLINK1, /* OverTemp - Blink step1 */
-+ OVERTEMP__BLINK2, /* OverTemp - Blink step2 */
-+ TRANS__ENTRY, /* Transition - Initialize */
-+ TRANS__1_UP, /* 1st cycle - up 12 & 6 - down 9 & 3 o'clock */
-+ TRANS__1_DN, /* 1st cycle - down 12 & 6 - up 9 & 3 o'clock */
-+ TRANS__2_UP, /* 2nd cycle - up 12 & 6 - down 9 & 3 o'clock */
-+ TRANS__2_DN, /* 2nd cycle - down 12 & 6 - up 9 & 3 o'clock */
-+ TRANS__3_UP, /* 3rd cycle - up 12 & 6 - down 9 & 3 o'clock */
-+ TRANS__3_DN, /* 3rd cycle - down 12 & 6 - up 9 & 3 o'clock */
-+ TRANS__4_UP, /* 4th cycle - up 12 & 6 - down 9 & 3 o'clock */
-+ TRANS__4_DN /* 4th cycle - down 12 & 6 - down 9 & 3 o'clock */
-+};
-+
-+
-+/* Pattern for the activity behavior */
-+const u16 activity_pattern[NUM_ACTIVITY_LEDS] = {
-+ LED100,
-+ LED25,
-+ 0,
-+ 0
-+};
-+
-+
-+/* Various LED state machine constants */
-+#define TRANS_STEP (1)
-+#define SLEEP_HI (0)
-+#define SLEEP_LO (-STEP_RESOLUTION)
-+#define NUM_POWER_STEPS (STEP_RESOLUTION)
-+#define NUM_BREATHE_STEPS (SLEEP_HI - SLEEP_LO)
-+#define NUM_TRANS_STEPS ((SLEEP_HI - SLEEP_LO) / TRANS_STEP)
-+#define BIT_MASK_FUEL_GAUGE ((1 << NUM_FUEL_GAUGE_LEDS) - 1)
-+
-+/*
-+ * Calculate various speeds of the LED state machine based on the system
-+ * clock frequency, the hardware timer prescaler, and the hardware timer
-+ * load register value. This results in a calculation of the ticks per
-+ * second (TPS) of the timer interrupt used to perform the pulse width
-+ * modulation and the slower TPS of the tasklet that performs the main
-+ * state machine of the LED behavior. The remaining speeds are
-+ * calculated from the slow TPS.
-+ */
-+ #define RW_SPEED (SLOW_TPS / 4) /* want ~4Hz */
-+#define BLINK_SPEED (SLOW_TPS / 2) /* want ~2Hz */
-+#define HOLD_BREATH (SLOW_TPS * 4) /* want ~4sec */
-+#define HOLD_ON_ENTER (SLOW_TPS * 10) /* want ~10sec */
-+#define POWER_SPEED (SLOW_TPS / NUM_POWER_STEPS)
-+#define BREATHE_SPEED (SLOW_TPS / NUM_BREATHE_STEPS)
-+#define TRANS_SPEED (SLOW_TPS / NUM_TRANS_STEPS)
-+
-+#if \
-+ (!SLOW_TPS) || \
-+ (!RW_SPEED) || \
-+ (!BLINK_SPEED) || \
-+ (!POWER_SPEED) || \
-+ (!BREATHE_SPEED) || \
-+ (!TRANS_SPEED)
-+# error TPS calculation(s) resulted in zero!
-+#endif
-+
-+
-+/* Variables for main LED behavior state machine */
-+static int state;
-+static int next_state;
-+static int active_count;
-+static int count;
-+static u32 fuel_gauge_bits; /* see LED frame buffer design assumption */
-+static u8 need_to_display_current_fuel_gauge;
-+static u8 inner_ring_rotate;
-+static u8 ignore_activity;
-+static s8 active_tail;
-+static s8 ramp1;
-+static s8 ramp2;
-+static s8 activity_led[NUM_ACTIVITY_LEDS];
-+static u16 rebuild_percentage; /* 0=not rebuilding */
-+
-+
-+/*
-+ * Declare tasklet for the LED behavior state machine. The interrupt will
-+ * only handle the pulse width modulation which can be performed quickly.
-+ * The slower LED behavior state machine does not need to execute at such
-+ * a high frequency so it will be executed by a tasklet that is
-+ * periodically scheduled by the interrupt.
-+ */
-+void wdc_leds_behavior(unsigned long);
-+DECLARE_TASKLET(wdc_leds_behavior_tasklet, wdc_leds_behavior, 0);
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_interrupt */
-+/* */
-+/* PURPOSE: */
-+/* Interrupt handler for the wdc-leds pulse width modulation */
-+/***************************************************************************/
-+static irqreturn_t wdc_leds_interrupt
-+ (int irq, void *dev_id) {
-+ ox_writel(0, TIMER2_CLEAR);
-+
-+
-+ tasklet_schedule(&wdc_leds_behavior_tasklet);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: get_inner_ring_bits */
-+/* */
-+/* PURPOSE: */
-+/* Convert the bit map of inner ring LEDs into the GPIO bit map */
-+/***************************************************************************/
-+static u32 get_inner_ring_bits(u16 value)
-+{
-+ u32 pattern = 0;
-+
-+ // Convert the bit map to the GPIO bit pattern
-+ if (value & (1 << 0))
-+ pattern |= LED_MASK_FG2;
-+ if (value & (1 << 1))
-+ pattern |= LED_MASK_FG4;
-+ if (value & (1 << 2))
-+ pattern |= LED_MASK_FG6;
-+ if (value & (1 << 3))
-+ pattern |= LED_MASK_FG8;
-+ if (value & (1 << 4))
-+ pattern |= LED_MASK_FG10;
-+ if (value & (1 << 5))
-+ pattern |= LED_MASK_FG12;
-+
-+ return pattern;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: get_percentage_pattern */
-+/* */
-+/* PURPOSE: */
-+/* Convert a percentage to a inner ring bit map. Note, we never display */
-+/* less than 1 LED for a percentage so that something is alway visible. */
-+/***************************************************************************/
-+static u16 get_percentage_pattern(u16 percentage)
-+{
-+ if (percentage >= 50) {
-+ if (percentage >= 67) {
-+ if (percentage >= 83) {
-+ if (percentage >= 97) {
-+ return 0x3F; // 6 LEDs is >= 97%
-+ } else {
-+ return 0x1F; // 5 LEDs is >= 83%
-+ }
-+ } else {
-+ return 0x0F; // 4 LEDs is >= 67%
-+ }
-+ } else {
-+ return 0x07; // 3 LEDs is >= 50%
-+ }
-+ } else {
-+ if (percentage >= 33) {
-+ return 0x03; // 2 LEDs is >= 33%
-+ } else {
-+ return 0x01; // 1 LED is >= 0%
-+ }
-+ }
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: set_led */
-+/* */
-+/* PURPOSE: */
-+/* Set frame buffer for the requested brightness on the requested LED(s) */
-+/***************************************************************************/
-+static void set_led(u32 led_bits, s8 value)
-+{
-+ u32 bit;
-+ s8 count = 0;
-+
-+ if (negative_led_logic) {
-+ value = MAX_PWM - value;
-+ }
-+
-+ for (bit = 1; bit > 0; bit <<= 1, ++count) {
-+ if (bit & led_bits) writel(value, ((u32 *)PWM_DATA_REGISTER_BASE + count ));
-+ }
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: display_inner_ring */
-+/* */
-+/* PURPOSE: */
-+/* Set frame buffer for the requested inner ring bit map */
-+/***************************************************************************/
-+static void display_inner_ring(u32 inner_ring_bits)
-+{
-+ set_led(~inner_ring_bits & LED_MASK_FUEL_GAUGE, 0);
-+ set_led(inner_ring_bits, LED100);
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: display_current_fuel_gauge */
-+/* */
-+/* PURPOSE: */
-+/* Display the current Fuel Gauge if it is not already being displayed */
-+/***************************************************************************/
-+static void display_current_fuel_gauge(void)
-+{
-+ if (need_to_display_current_fuel_gauge) {
-+ display_inner_ring(fuel_gauge_bits);
-+ need_to_display_current_fuel_gauge = 0;
-+ }
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: handle_inner_ring */
-+/* */
-+/* PURPOSE: */
-+/* Perform the LED behavior for the inner ring */
-+/***************************************************************************/
-+static void handle_inner_ring(void)
-+{
-+ /* If currently rebuilding then display the rebuild percentage as */
-+ /* a series of LEDs representing the percentage complete rotating */
-+ /* around the inner ring. Note, the percentage is rotated to */
-+ /* distinguish it from normal fuel gauge behavior. */
-+ if (rebuild_percentage) {
-+ /* Convert the rebuild percentage into a bit map of LEDs */
-+ u32 rotated_pattern = get_percentage_pattern(rebuild_percentage);
-+ /* Now rotate that pattern */
-+ rotated_pattern <<= inner_ring_rotate;
-+ rotated_pattern |= (rotated_pattern >> NUM_FUEL_GAUGE_LEDS);
-+ rotated_pattern &= BIT_MASK_FUEL_GAUGE;
-+ /* Now display the rotated pattern on the inner ring */
-+ display_inner_ring(get_inner_ring_bits(rotated_pattern));
-+ if (++inner_ring_rotate >= NUM_FUEL_GAUGE_LEDS) {
-+ inner_ring_rotate = 0;
-+ }
-+
-+ need_to_display_current_fuel_gauge = 1;
-+ }
-+
-+ /* Otherwise not rebuilding so just display normal fuel gauge */
-+ else {
-+ display_current_fuel_gauge();
-+ }
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: get_next_state_from_fully_on */
-+/* */
-+/* PURPOSE: */
-+/* Movement to STANDBY or POWER_OFF requires TRANSITION behavior; */
-+/* Otherwise just jump to next_state */
-+/***************************************************************************/
-+static int get_next_state_from_fully_on(void)
-+{
-+ switch (next_state) {
-+ case STANDBY__ENTRY:
-+ case POWER_OFF__ENTRY:
-+ return TRANS__ENTRY;
-+ default:
-+ return next_state;
-+ }
-+}
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_behavior_init */
-+/* */
-+/* PURPOSE: */
-+/* Initialization for LED behavior main state machine */
-+/***************************************************************************/
-+void wdc_leds_behavior_init(void)
-+{
-+ /* State machine variables */
-+ state = FULLY_ON__ENTRY;
-+ next_state = FULLY_ON__ENTRY;
-+ /* Outer ring variables */
-+ active_count = 0;
-+ count = 0;
-+ ignore_activity = 0;
-+ active_tail = NUM_ACTIVITY_LEDS - 1;
-+ ramp1 = 0;
-+ ramp2 = 0;
-+ activity_led[0] = 0;
-+ activity_led[1] = 0;
-+ activity_led[2] = 0;
-+ activity_led[3] = 0;
-+ /* Inner ring variables */
-+ inner_ring_rotate = 0;
-+ rebuild_percentage = 0;
-+ fuel_gauge_bits = 0;
-+ need_to_display_current_fuel_gauge = 1;
-+}
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_behavior */
-+/* */
-+/* PURPOSE: */
-+/* LED behavior main state machine */
-+/***************************************************************************/
-+void wdc_leds_behavior(unsigned long unused)
-+{
-+ static u8 been_there_done_that = 0;
-+ s8 j, k;
-+ switch (state) {
-+ case FULLY_ON__ENTRY:
-+ case FULLY_ON__RE_ENTRY:
-+ inner_ring_rotate = 0;
-+ need_to_display_current_fuel_gauge = 1;
-+ activity_led[0] = LED100;
-+ activity_led[1] = LED100;
-+ activity_led[2] = LED100;
-+ activity_led[3] = LED100;
-+ ramp1 = -STEP_RESOLUTION;
-+ ramp2 = -STEP_RESOLUTION;
-+ if (state == FULLY_ON__RE_ENTRY) {
-+ /* Don't go through the POR hold period for a re-entry */
-+ count = 0;
-+ state = FULLY_ON__RAMP_UP;
-+ break;
-+ }
-+ count = 0;
-+ state = FULLY_ON__POR_RAMP_UP;
-+ /* Fall through */
-+ case FULLY_ON__POR_RAMP_UP:
-+ if (--count > 0)
-+ break;
-+ count = POWER_SPEED;
-+ ++ramp2;
-+ if (++ramp1 < 0)
-+ break;
-+ count = HOLD_ON_ENTER;
-+ state = FULLY_ON__POR_HOLD;
-+ break;
-+ case FULLY_ON__POR_HOLD:
-+ display_current_fuel_gauge();
-+ if (--count > 0)
-+ break;
-+ active_count = 0;
-+ count = 0;
-+ state = FULLY_ON__RAMP_UP;
-+ break;
-+ case FULLY_ON__RAMP_UP:
-+ if (next_state != FULLY_ON__ENTRY) {
-+ state = get_next_state_from_fully_on();
-+ break;
-+ }
-+
-+ display_current_fuel_gauge();
-+ if (--count > 0)
-+ break;
-+ count = POWER_SPEED;
-+ ++ramp2;
-+ if (++ramp1 >= 0) {
-+ ramp1 = 0;
-+ ramp2 = 0;
-+ }
-+ if (active_count == 0) {
-+ activity_led[0] = LED100;
-+ activity_led[1] = LED100;
-+ activity_led[2] = LED100;
-+ activity_led[3] = LED100;
-+ break;
-+ }
-+
-+ activity_led[0] = 0;
-+ activity_led[1] = 0;
-+ activity_led[2] = 0;
-+ activity_led[3] = 0;
-+ count = 0;
-+ ramp1 = 0;
-+ ramp2 = 0;
-+ state = FULLY_ON__ACTIVITY;
-+ /* Fall through */
-+ case FULLY_ON__ACTIVITY:
-+ if (next_state != FULLY_ON__ENTRY) {
-+ state = get_next_state_from_fully_on();
-+ break;
-+ }
-+
-+ if (--count > 0)
-+ break;
-+ count = RW_SPEED;
-+ handle_inner_ring();
-+ if (active_count) {
-+ j = active_tail =
-+ ((active_tail >
-+ 0) ? (active_tail - 1) : (NUM_ACTIVITY_LEDS - 1)
-+ );
-+ k = NUM_ACTIVITY_LEDS;
-+ while (k--) {
-+ activity_led[j] = activity_pattern[k];
-+ j = ((j > 0) ? (j - 1) : (NUM_ACTIVITY_LEDS - 1));
-+ }
-+ ramp1 = 0;
-+ ramp2 = 0;
-+ }
-+ if (active_count == 0) {
-+ count = RW_SPEED;
-+ state = FULLY_ON__IDLE_HOLD;
-+ }
-+ active_count = 0;
-+ break;
-+ case FULLY_ON__IDLE_HOLD:
-+ if (--count > 0)
-+ break;
-+ count = 0;
-+ state = FULLY_ON__RAMP_DOWN;
-+ break;
-+ case FULLY_ON__RAMP_DOWN:
-+ if (--count > 0)
-+ break;
-+ count = POWER_SPEED;
-+ --ramp2;
-+ if ((--ramp1 <= -STEP_RESOLUTION) || active_count) {
-+ display_current_fuel_gauge();
-+ ramp1 = -STEP_RESOLUTION;
-+ ramp2 = -STEP_RESOLUTION;
-+ state = FULLY_ON__RAMP_UP;
-+ }
-+ break;
-+ case STANDBY__ENTRY:
-+ activity_led[0] = LED100;
-+ activity_led[1] = LED100;
-+ activity_led[2] = LED100;
-+ activity_led[3] = LED100;
-+ ramp1 = -STEP_RESOLUTION;
-+ ramp2 = -STEP_RESOLUTION;
-+ count = HOLD_BREATH;
-+ state = STANDBY__DARK;
-+ display_current_fuel_gauge();
-+ /* Fall through */
-+ case STANDBY__DARK:
-+ if (next_state != STANDBY__ENTRY) {
-+ state = next_state;
-+ break;
-+ }
-+
-+ if (--count > 0)
-+ break;
-+ state = STANDBY__RAMP_UP;
-+ break;
-+ case STANDBY__RAMP_UP:
-+ ramp2++;
-+ ramp1++;
-+ if (ramp1 < SLEEP_HI)
-+ break;
-+ state = STANDBY__RAMP_DOWN;
-+ break;
-+ case STANDBY__RAMP_DOWN:
-+ ramp2--;
-+ if (ramp1-- > -STEP_RESOLUTION)
-+ break;
-+ state = STANDBY__ENTRY;
-+ break;
-+ case POWER_OFF__ENTRY:
-+ display_inner_ring(0x00);
-+ activity_led[0] = 0;
-+ activity_led[1] = 0;
-+ activity_led[2] = 0;
-+ activity_led[3] = 0;
-+ ramp1 = 0;
-+ ramp2 = 0;
-+ state = POWER_OFF__DARK;
-+ /* Fall through */
-+ case POWER_OFF__DARK:
-+ if (next_state != POWER_OFF__ENTRY) {
-+ state = next_state;
-+ break;
-+ }
-+ break;
-+ case DEGRADED__ENTRY:
-+ display_inner_ring(get_inner_ring_bits(BIT_MASK_FUEL_GAUGE));
-+ ramp1 = 0;
-+ ramp2 = 0;
-+ activity_led[0] = 0;
-+ activity_led[1] = 0;
-+ activity_led[2] = 0;
-+ activity_led[3] = 0;
-+ count = BLINK_SPEED;
-+ state = DEGRADED__BLINK1;
-+ /* Fall through */
-+ case DEGRADED__BLINK1:
-+ if (next_state != DEGRADED__ENTRY) {
-+ display_inner_ring(0);
-+ state = TRANS__ENTRY;
-+ break;
-+ }
-+
-+ if (--count > 0)
-+ break;
-+ display_inner_ring(0);
-+ activity_led[0] = LED100;
-+ activity_led[1] = LED100;
-+ activity_led[2] = LED100;
-+ activity_led[3] = LED100;
-+ count = BLINK_SPEED;
-+ state = DEGRADED__BLINK2;
-+ break;
-+ case DEGRADED__BLINK2:
-+ if (--count > 0)
-+ break;
-+ state = DEGRADED__ENTRY;
-+ break;
-+ case OVERTEMP__ENTRY:
-+ display_inner_ring(0);
-+ ramp1 = 0;
-+ ramp2 = 0;
-+ activity_led[0] = 0;
-+ activity_led[1] = 0;
-+ activity_led[2] = 0;
-+ activity_led[3] = 0;
-+ count = BLINK_SPEED;
-+ state = OVERTEMP__BLINK1;
-+ /* Fall through */
-+ case OVERTEMP__BLINK1:
-+ if (next_state != OVERTEMP__ENTRY) {
-+ display_inner_ring(0);
-+ state = TRANS__ENTRY;
-+ break;
-+ }
-+
-+ if (--count > 0)
-+ break;
-+ display_inner_ring(get_inner_ring_bits(BIT_MASK_FUEL_GAUGE));
-+ activity_led[0] = LED100;
-+ activity_led[1] = LED100;
-+ activity_led[2] = LED100;
-+ activity_led[3] = LED100;
-+ count = BLINK_SPEED;
-+ state = OVERTEMP__BLINK2;
-+ break;
-+ case OVERTEMP__BLINK2:
-+ if (--count > 0)
-+ break;
-+ state = OVERTEMP__ENTRY;
-+ break;
-+ case TRANS__ENTRY:
-+ activity_led[0] = LED100;
-+ activity_led[1] = LED100;
-+ activity_led[2] = LED100;
-+ activity_led[3] = LED100;
-+ ramp1 = SLEEP_LO;
-+ ramp2 = SLEEP_HI;
-+ state = TRANS__1_UP;
-+ /* Fall through */
-+ case TRANS__1_UP:
-+ case TRANS__2_UP:
-+ case TRANS__3_UP:
-+ case TRANS__4_UP:
-+ ramp2 -= TRANS_STEP;
-+ ramp1 += TRANS_STEP;
-+ if ((ramp1 - TRANS_STEP) < SLEEP_HI)
-+ break;
-+ state++;
-+ break;
-+ case TRANS__4_DN:
-+ if (ramp1 <= -STEP_RESOLUTION) {
-+ if (next_state == TRANS__ENTRY) {
-+ /*
-+ * If no one told us where to go then just go to FullyOn, but
-+ * don't go through the POR hold period because that makes
-+ * the next transition display for the next button press wait
-+ * too long.
-+ *
-+ * Note, that next_state needs to be set to FULLY_ON__ENTRY
-+ * because it is used for the test whether or not to leave
-+ * the FullyOn state even though we are entering FullyOn
-+ * through the re-entry path.
-+ */
-+ next_state = FULLY_ON__ENTRY;
-+ state = FULLY_ON__RE_ENTRY;
-+ } else {
-+ state = next_state;
-+ }
-+ break;
-+ }
-+ ramp2 -= TRANS_STEP;
-+ /* Fall through */
-+ case TRANS__1_DN:
-+ case TRANS__2_DN:
-+ case TRANS__3_DN:
-+ ramp2 += TRANS_STEP;
-+ ramp1 -= TRANS_STEP;
-+ if ((ramp1 + TRANS_STEP) > -STEP_RESOLUTION)
-+ break;
-+ ramp1 = SLEEP_LO;
-+ ramp2 = SLEEP_HI;
-+ state++;
-+ break;
-+ default:
-+ if (!been_there_done_that) {
-+ printk(KERN_ERR "Invalid LED behavior state\n");
-+ been_there_done_that = 1;
-+ return;
-+ }
-+ }
-+
-+ /* Set the activity brightness according to value and ramp */
-+ set_led(LED_MASK_ACT12, activity_led[0] + ramp1);
-+ set_led(LED_MASK_ACT9, activity_led[1] + ramp2);
-+ set_led(LED_MASK_ACT6, activity_led[2] + ramp1);
-+ set_led(LED_MASK_ACT3, activity_led[3] + ramp2);
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_set_power */
-+/* */
-+/* PURPOSE: */
-+/* Set the "power" LED to the requested behavior */
-+/***************************************************************************/
-+static void wdc_leds_set_power
-+ (struct led_classdev *led_cdev, enum led_brightness value) {
-+ if (value >= 255) {
-+ next_state = FULLY_ON__ENTRY;
-+ } else if (value > 0) {
-+ next_state = STANDBY__ENTRY;
-+ } else {
-+ next_state = POWER_OFF__ENTRY;
-+ }
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_set_activity */
-+/* */
-+/* PURPOSE: */
-+/* Trigger activity display behavior */
-+/***************************************************************************/
-+static void wdc_leds_set_activity
-+ (struct led_classdev *led_cdev, enum led_brightness value) {
-+ if (!ignore_activity && (value > 0)) {
-+ active_count++;
-+ }
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_set_ignore_activity */
-+/* */
-+/* PURPOSE: */
-+/* Set the "ignore activity" setting */
-+/***************************************************************************/
-+static void wdc_leds_set_ignore_activity
-+ (struct led_classdev *led_cdev, enum led_brightness value) {
-+ ignore_activity = value;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_set_transition */
-+/* */
-+/* PURPOSE: */
-+/* Trigger "transition" display behavior */
-+/***************************************************************************/
-+static void wdc_leds_set_transition
-+ (struct led_classdev *led_cdev, enum led_brightness value) {
-+ next_state = ((value > 0) ? TRANS__ENTRY : FULLY_ON__ENTRY);
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_set_fuel_gauge */
-+/* */
-+/* PURPOSE: */
-+/* Set the fuel gauge to the requested value (treated as a percentage) */
-+/***************************************************************************/
-+static void wdc_leds_set_fuel_gauge
-+ (struct led_classdev *led_cdev, enum led_brightness value) {
-+ fuel_gauge_bits = get_inner_ring_bits(get_percentage_pattern(value));
-+ need_to_display_current_fuel_gauge = 1;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_set_fg_bitmap */
-+/* */
-+/* PURPOSE: */
-+/* Set the fuel gauge to the requested value (treated as a bitmap) */
-+/***************************************************************************/
-+static void wdc_leds_set_fg_bitmap
-+ (struct led_classdev *led_cdev, enum led_brightness value) {
-+ fuel_gauge_bits = get_inner_ring_bits((u16) value);
-+ need_to_display_current_fuel_gauge = 1;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_set_rebuilding */
-+/* */
-+/* PURPOSE: */
-+/* Set the rebuilding behavior (value = % complete, 0 = not rebuilding) */
-+/***************************************************************************/
-+static void wdc_leds_set_rebuilding
-+ (struct led_classdev *led_cdev, enum led_brightness value) {
-+ rebuild_percentage = value;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_set_degraded */
-+/* */
-+/* PURPOSE: */
-+/* Set the degraded mode display behavior */
-+/***************************************************************************/
-+static void wdc_leds_set_degraded
-+ (struct led_classdev *led_cdev, enum led_brightness value) {
-+ next_state = ((value > 0) ? DEGRADED__ENTRY : FULLY_ON__ENTRY);
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_set_over_temp */
-+/* */
-+/* PURPOSE: */
-+/* Set the over temperature mode display behavior */
-+/***************************************************************************/
-+static void wdc_leds_set_over_temp
-+ (struct led_classdev *led_cdev, enum led_brightness value) {
-+ next_state = ((value > 0) ? OVERTEMP__ENTRY : FULLY_ON__ENTRY);
-+}
-+
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_power */
-+/* */
-+/* PURPOSE: */
-+/* Describe the wdc-leds "power" pseudo-LED */
-+/***************************************************************************/
-+static struct led_classdev wdc_leds_power = {
-+ .name = "wdc-leds:power",.brightness_set = wdc_leds_set_power,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_activity */
-+/* */
-+/* PURPOSE: */
-+/* Describe the wdc-leds "activity" pseudo-LED */
-+/***************************************************************************/
-+static struct led_classdev wdc_leds_activity = {
-+ .name = "wdc-leds:activity",.brightness_set =
-+ wdc_leds_set_activity,.default_trigger = "sata-disk"
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_ignore_activity */
-+/* */
-+/* PURPOSE: */
-+/* Describe the wdc-leds "ignore-activity" pseudo-LED */
-+/***************************************************************************/
-+static struct led_classdev wdc_leds_ignore_activity = {
-+ .name = "wdc-leds:ignore-act",.brightness_set =
-+ wdc_leds_set_ignore_activity,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_transition */
-+/* */
-+/* PURPOSE: */
-+/* Describe the wdc-leds "transition" pseudo-LED */
-+/***************************************************************************/
-+static struct led_classdev wdc_leds_transition = {
-+ .name = "wdc-leds:transition",.brightness_set =
-+ wdc_leds_set_transition,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_fuel_gauge */
-+/* */
-+/* PURPOSE: */
-+/* Describe the wdc-leds "fuel-gauge" LEDs (brightness = % full) */
-+/***************************************************************************/
-+static struct led_classdev wdc_leds_fuel_gauge = {
-+ .name = "wdc-leds:fuel-gauge",.brightness_set =
-+ wdc_leds_set_fuel_gauge,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_fg_bitmap */
-+/* */
-+/* PURPOSE: */
-+/* Describe the wdc-leds "fuel-gauge" LEDs (brightness = bitmap) */
-+/***************************************************************************/
-+static struct led_classdev wdc_leds_fg_bitmap = {
-+ .name = "wdc-leds:fg-bitmap",.brightness_set = wdc_leds_set_fg_bitmap,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_rebuilding */
-+/* */
-+/* PURPOSE: */
-+/* Describe the wdc-leds RAID1 "rebuilding" mode pseudo-LED */
-+/* (brightness = % complete) */
-+/***************************************************************************/
-+static struct led_classdev wdc_leds_rebuilding = {
-+ .name = "wdc-leds:rebuilding",.brightness_set =
-+ wdc_leds_set_rebuilding,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_degraded */
-+/* */
-+/* PURPOSE: */
-+/* Describe the wdc-leds "degraded" mode pseudo-LED */
-+/***************************************************************************/
-+static struct led_classdev wdc_leds_degraded = {
-+ .name = "wdc-leds:degraded",.brightness_set = wdc_leds_set_degraded,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_over_temp */
-+/* */
-+/* PURPOSE: */
-+/* Describe the wdc-leds "over-temp" pseudo-LED */
-+/***************************************************************************/
-+static struct led_classdev wdc_leds_over_temp = {
-+ .name = "wdc-leds:over-temp",.brightness_set = wdc_leds_set_over_temp,
-+};
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_classes[] */
-+/* */
-+/* PURPOSE: */
-+/* Array of LED classes to create/destroy */
-+/***************************************************************************/
-+static struct led_classdev *wdc_led_classes[] = {
-+ &wdc_leds_power,
-+ &wdc_leds_activity,
-+ &wdc_leds_ignore_activity,
-+ &wdc_leds_transition,
-+ &wdc_leds_fuel_gauge,
-+ &wdc_leds_fg_bitmap,
-+ &wdc_leds_rebuilding,
-+ &wdc_leds_degraded,
-+ &wdc_leds_over_temp
-+};
-+
-+#ifdef DEBUG
-+static ssize_t show_registers (struct device *dev, struct device_attribute *attr, char *buf)
-+{
-+ char * out = buf;
-+ u32 clock_data = readl(PWM_CLOCK_REGISTER);
-+ u32 data_ptr = PWM_CLOCK_REGISTER;
-+ u8 no_pwms = (clock_data >> 16);
-+ u8 i;
-+ /* report hardware status here */
-+ out += sprintf(buf,"PWM drive registers\n");
-+ out += sprintf(out, "clock register:0x%08x @ 0x%08x\n", clock_data, data_ptr);
-+
-+ for (i = 0; i < no_pwms; ++i)
-+ {
-+ data_ptr=(u32)((u32 *)PWM_BASE+i);
-+ out+= sprintf(out,"%d:%d @ 0x%08x\n", i, (u8)readl(data_ptr),data_ptr);
-+ }
-+
-+ return out - buf;
-+}
-+
-+/* create a register 'file' to enbale reading back the pwm drive register status */
-+static DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
-+
-+static int create_debug_files(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ return device_create_file(dev, &dev_attr_registers);
-+}
-+
-+static void remove_debug_files(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ device_remove_file(dev, &dev_attr_registers);
-+}
-+#endif
-+
-+
-+#ifdef CONFIG_PM
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_suspend */
-+/* */
-+/* PURPOSE: */
-+/* Suspend all LED class devices created by this driver */
-+/***************************************************************************/
-+static int wdc_leds_suspend(struct platform_device *pdev,
-+ pm_message_t state)
-+{
-+ int n = leds_created;
-+ while (n > 0) {
-+ if (--n < ARRAY_SIZE(wdc_led_classes)) {
-+ led_classdev_suspend(wdc_led_classes[n]);
-+ }
-+ }
-+
-+return 0}
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_resume */
-+/* */
-+/* PURPOSE: */
-+/* Wake up all LED class devices created by this driver */
-+/***************************************************************************/
-+static int wdc_leds_resume(struct platform_device *pdev,
-+ pm_message_t state)
-+{
-+ int n = leds_created;
-+ while (n > 0) {
-+ if (--n < ARRAY_SIZE(wdc_led_classes)) {
-+ led_classdev_resume(wdc_led_classes[n]);
-+ }
-+ }
-+
-+return 0}
-+#endif /* CONFIG_PM */
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_probe */
-+/* */
-+/* PURPOSE: */
-+/* Perform any necessary probing and initial setup for wdc-leds device */
-+/***************************************************************************/
-+static int wdc_leds_probe(struct platform_device *pdev)
-+{
-+ int rc;
-+ int timer_changed = 0;
-+ int interrupt_allocated = 0;
-+ leds_created = 0;
-+ do {
-+ /* Enable LED output drivers and disable other uses */
-+ CLEAR(SYS_CTRL_GPIO_PRIMSEL_CTRL_0, LED_MASK_GPIO_A);
-+ CLEAR(SYS_CTRL_GPIO_SECSEL_CTRL_0, LED_MASK_GPIO_A);
-+ CLEAR(SYS_CTRL_GPIO_TERTSEL_CTRL_0, LED_MASK_GPIO_A);
-+
-+ CLEAR(SYS_CTRL_GPIO_PRIMSEL_CTRL_1, LED_MASK_GPIO_B);
-+ CLEAR(SYS_CTRL_GPIO_SECSEL_CTRL_1, LED_MASK_GPIO_B);
-+ CLEAR(SYS_CTRL_GPIO_TERTSEL_CTRL_1, LED_MASK_GPIO_B);
-+ /* Turn off all the LEDs */
-+ if (negative_led_logic) {
-+ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_SET);
-+ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_SET);
-+ } else {
-+ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_CLEAR);
-+ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_CLEAR);
-+ }
-+
-+ /* bring PWM module out of reset and enable clock */
-+ writel((1<<SYS_CTRL_RSTEN_MISC_BIT), SYS_CTRL_RSTEN_CLR_CTRL);
-+ //writel(PWM_CLOCK, SYS_CTRL_CKEN_SET_CTRL);
-+
-+ /* enable PWM clock */
-+ writel(PWM_PRESCALE, PWM_CLOCK_REGISTER);
-+
-+ /* Initialize frame buffer to everything off */
-+ set_led(LED_MASK_FUEL_GAUGE | LED_MASK_ACTIVITY, 0);
-+ /* Enable output to the LEDs */
-+ writel(LED_MASK_GPIO_A, SYS_CTRL_GPIO_PWMSEL_CTRL_0);
-+ writel(LED_MASK_GPIO_B, SYS_CTRL_GPIO_PWMSEL_CTRL_1);
-+ /* Initialize the LED behavior state machine */
-+ wdc_leds_behavior_init();
-+ /* Save Timer2 state for restoring later */
-+ timer_load = ox_readl(TIMER2_LOAD);
-+ timer_control = ox_readl(TIMER2_CONTROL);
-+ ox_writel(0, TIMER2_CONTROL);
-+ timer_changed = 1;
-+ /* Setup Timer2 for LED control */
-+ rc = request_irq
-+ (TIMER_2_INTERRUPT,
-+ wdc_leds_interrupt, 0, "led_pwm", 0);
-+ if (rc < 0) {
-+ printk(KERN_ERR "failed to get IRQ\n");
-+ break;
-+ }
-+
-+ interrupt_allocated = 1;
-+ ox_writel(FAST_TIMER_INT, TIMER2_LOAD);
-+ ox_writel(PERIODIC_INTERRUPT, TIMER2_CONTROL);
-+ /* Register each LED class device */
-+ while (leds_created < ARRAY_SIZE(wdc_led_classes)) {
-+ rc = led_classdev_register(&pdev->dev,
-+ wdc_led_classes[leds_created]);
-+ if (rc < 0) {
-+ printk(KERN_ERR "failed to register led class \"%s\"\n",
-+ wdc_led_classes[leds_created]->name);
-+ break;
-+ }
-+
-+ ++leds_created;
-+ }
-+ }
-+ while (0);
-+ /* If we failed then perform any needed clean up */
-+ if (rc < 0) {
-+ /* Unregister any classes we registered */
-+ while (leds_created > 0) {
-+ if (--leds_created < ARRAY_SIZE(wdc_led_classes)) {
-+ led_classdev_unregister(wdc_led_classes[leds_created]);
-+ }
-+ }
-+
-+ /* Free the interrupt if we allocated one */
-+ if (interrupt_allocated) {
-+ free_irq(TIMER_2_INTERRUPT, 0);
-+ }
-+
-+ /* Restore Timer2 if we changed it */
-+ if (timer_changed) {
-+ ox_writel(timer_load, TIMER2_LOAD);
-+ ox_writel(timer_control, TIMER2_CONTROL);
-+ }
-+ }
-+#ifdef DEBUG
-+ create_debug_files(pdev);
-+#endif
-+ return rc;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_remove */
-+/* */
-+/* PURPOSE: */
-+/* Perform steps to remove the wdc-leds device */
-+/***************************************************************************/
-+static int wdc_leds_remove(struct platform_device *pdev)
-+{
-+ while (leds_created > 0) {
-+ if (--leds_created < ARRAY_SIZE(wdc_led_classes)) {
-+ led_classdev_unregister(wdc_led_classes[leds_created]);
-+ }
-+ }
-+
-+ ox_writel(0, TIMER2_CONTROL);
-+ free_irq(TIMER_2_INTERRUPT, 0);
-+ ox_writel(timer_load, TIMER2_LOAD);
-+ ox_writel(timer_control, TIMER2_CONTROL);
-+ /* Turn off all the LEDs */
-+ if (negative_led_logic) {
-+ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_SET);
-+ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_SET);
-+ } else {
-+ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_CLEAR);
-+ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_CLEAR);
-+ }
-+ /* put PWM module back into reset and disable clock */
-+ writel((1<<SYS_CTRL_RSTEN_MISC_BIT), SYS_CTRL_RSTEN_SET_CTRL);
-+ // writel(PWM_CLOCK, SYS_CTRL_CKEN_CLR_CTRL);
-+#ifdef DEBUG
-+ remove_debug_files(pdev);
-+#endif
-+ return 0;
-+}
-+
-+
-+/***************************************************************************/
-+/* DATA STRUCTURE: wdc_leds_driver */
-+/* */
-+/* PURPOSE: */
-+/* Describe the wdc-leds platform device driver */
-+/***************************************************************************/
-+static struct platform_driver wdc_leds_driver = {
-+ .probe = wdc_leds_probe,.remove = wdc_leds_remove,
-+#ifdef CONFIG_PM
-+ .suspend = wdc_leds_suspend,.resume = wdc_leds_resume,
-+#endif /* CONFIG_PM */
-+ .driver = {
-+ .name = "wdc-leds",},
-+};
-+
-+/* Pointer to device returned by platform_device_register_simple */
-+static struct platform_device *wdc_leds;
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_init */
-+/* */
-+/* PURPOSE: */
-+/* Perform module initialization */
-+/***************************************************************************/
-+static int __init wdc_leds_init(void)
-+{
-+ int ret;
-+ printk
-+ (KERN_INFO "wdc-leds: SLOW_TPS=%d\n",
-+ SLOW_TPS);
-+ ret = platform_driver_register(&wdc_leds_driver);
-+ if (!ret) {
-+ wdc_leds =
-+ platform_device_register_simple("wdc-leds", -1, NULL, 0);
-+ }
-+
-+ return ret;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_leds_exit */
-+/* */
-+/* PURPOSE: */
-+/* Perform module unloading and cleanup */
-+/***************************************************************************/
-+static void __exit wdc_leds_exit(void)
-+{
-+ if (wdc_leds) {
-+ platform_device_unregister(wdc_leds);
-+ }
-+ platform_driver_unregister(&wdc_leds_driver);
-+}
-+
-+
-+module_init(wdc_leds_init);
-+module_exit(wdc_leds_exit);
-+MODULE_AUTHOR("Michael Webster");
-+MODULE_DESCRIPTION("WDC 2NC LEDs");
-+MODULE_LICENSE("GPL");
-+/******************************* End of File *********************************/
-diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/wdc-ledtrig-sata.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/wdc-ledtrig-sata.c
---- linux-2.6.24/arch/arm/mach-oxnas/wdc-ledtrig-sata.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/wdc-ledtrig-sata.c 2008-06-11 17:47:55.000000000 +0200
-@@ -0,0 +1,78 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/wdc-ledtrig-sata.c
-+ *
-+ * Copyright (C) 2006 Western Digital
-+ *
-+ * 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 <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/leds.h>
-+
-+
-+DEFINE_LED_TRIGGER(wdc_ledtrig_sata);
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_ledtrig_sata_activity */
-+/* */
-+/* PURPOSE: */
-+/* Entry point to trip the trigger (called from within SATA driver) */
-+/***************************************************************************/
-+void wdc_ledtrig_sata_activity(void)
-+{
-+ led_trigger_event(wdc_ledtrig_sata, LED_FULL);
-+}
-+EXPORT_SYMBOL(wdc_ledtrig_sata_activity);
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_ledtrig_sata_init */
-+/* */
-+/* PURPOSE: */
-+/* Perform module initialization */
-+/***************************************************************************/
-+static int __init wdc_ledtrig_sata_init(void)
-+{
-+ printk("<1>Hello, LED trigger\n");
-+
-+ led_trigger_register_simple("sata-disk", &wdc_ledtrig_sata);
-+ return 0;
-+}
-+
-+
-+/***************************************************************************/
-+/* FUNCTION: wdc_ledtrig_sata_exit */
-+/* */
-+/* PURPOSE: */
-+/* Perform module unloading and cleanup */
-+/***************************************************************************/
-+static void __exit wdc_ledtrig_sata_exit(void)
-+{
-+ led_trigger_unregister_simple(wdc_ledtrig_sata);
-+
-+ printk("<1>Goodbye LED trigger\n");
-+}
-+
-+
-+module_init(wdc_ledtrig_sata_init);
-+module_exit(wdc_ledtrig_sata_exit);
-+
-+MODULE_AUTHOR("Michael Webster");
-+MODULE_DESCRIPTION("WDC 2NC LED trigger");
-+MODULE_LICENSE("GPL");
-+
-+/******************************* End of File *********************************/
-diff -Nurd linux-2.6.24/arch/arm/mach-pxa/clock.c linux-2.6.24-oxe810/arch/arm/mach-pxa/clock.c
---- linux-2.6.24/arch/arm/mach-pxa/clock.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mach-pxa/clock.c 2008-06-11 17:47:55.000000000 +0200
-@@ -23,18 +23,27 @@
- static DEFINE_MUTEX(clocks_mutex);
- static DEFINE_SPINLOCK(clocks_lock);
-
-+static struct clk *clk_lookup(struct device *dev, const char *id)
-+{
-+ struct clk *p;
-+
-+ list_for_each_entry(p, &clocks, node)
-+ if (strcmp(id, p->name) == 0 && p->dev == dev)
-+ return p;
-+
-+ return NULL;
-+}
-+
- struct clk *clk_get(struct device *dev, const char *id)
- {
- struct clk *p, *clk = ERR_PTR(-ENOENT);
-
- mutex_lock(&clocks_mutex);
-- list_for_each_entry(p, &clocks, node) {
-- if (strcmp(id, p->name) == 0 &&
-- (p->dev == NULL || p->dev == dev)) {
-- clk = p;
-- break;
-- }
-- }
-+ p = clk_lookup(dev, id);
-+ if (!p)
-+ p = clk_lookup(NULL, id);
-+ if (p)
-+ clk = p;
- mutex_unlock(&clocks_mutex);
-
- return clk;
-diff -Nurd linux-2.6.24/arch/arm/mm/Kconfig linux-2.6.24-oxe810/arch/arm/mm/Kconfig
---- linux-2.6.24/arch/arm/mm/Kconfig 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mm/Kconfig 2008-06-11 17:47:57.000000000 +0200
-@@ -171,8 +171,8 @@
- # ARM926T
- config CPU_ARM926T
- bool "Support ARM926T processor"
-- depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI
-- default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI
-+ depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI || ARCH_OXNAS
-+ default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI || ARCH_OXNAS
- select CPU_32v5
- select CPU_ABRT_EV5TJ
- select CPU_CACHE_VIVT
-diff -Nurd linux-2.6.24/arch/arm/mm/init.c linux-2.6.24-oxe810/arch/arm/mm/init.c
---- linux-2.6.24/arch/arm/mm/init.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mm/init.c 2008-06-11 17:47:57.000000000 +0200
-@@ -173,9 +173,19 @@
- #ifdef CONFIG_MMU
- struct map_desc map;
-
-+#ifdef CONFIG_OXNAS_MAP_SRAM
-+ /*
-+ * Assume only a single bank and stop the overwrite of the first section
-+ * descriptor
-+ */
-+ map.pfn = __phys_to_pfn(bank->start + 1024*1024);
-+ map.virtual = __phys_to_virt(bank->start) + 1024*1024;
-+ map.length = bank->size - 1024*1024;
-+#else // CONFIG_OXNAS_MAP_SRAM
- map.pfn = __phys_to_pfn(bank->start);
- map.virtual = __phys_to_virt(bank->start);
- map.length = bank->size;
-+#endif // CONFIG_OXNAS_MAP_SRAM
- map.type = MT_MEMORY;
-
- create_mapping(&map);
-diff -Nurd linux-2.6.24/arch/arm/mm/mmu.c linux-2.6.24-oxe810/arch/arm/mm/mmu.c
---- linux-2.6.24/arch/arm/mm/mmu.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mm/mmu.c 2008-06-11 17:47:57.000000000 +0200
-@@ -617,6 +617,15 @@
- reserve_bootmem_node(pgdat, __pa(swapper_pg_dir),
- PTRS_PER_PGD * sizeof(pgd_t));
-
-+#ifdef CONFIG_OXNAS_MAP_SRAM
-+ /*
-+ * Reserve the page table describing the first MB of address space in 4KB
-+ * pages so we can map SRAM over part of it. This didn't work for some reason
-+ * so instead reserve first 0x4000 as some other archs do
-+ */
-+ res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
-+#endif // CONFIG_OXNAS_MAP_SRAM
-+
- /*
- * Hmm... This should go elsewhere, but we really really need to
- * stop things allocating the low memory; ideally we need a better
-diff -Nurd linux-2.6.24/arch/arm/mm/proc-arm926.S linux-2.6.24-oxe810/arch/arm/mm/proc-arm926.S
---- linux-2.6.24/arch/arm/mm/proc-arm926.S 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/arm/mm/proc-arm926.S 2008-06-11 17:47:57.000000000 +0200
-@@ -245,6 +245,7 @@
- *
- * (same as v4wb)
- */
-+.section ".text.arm926_dma_clean_range"
- ENTRY(arm926_dma_inv_range)
- #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- tst r0, #CACHE_DLINESIZE - 1
-@@ -259,6 +260,7 @@
- blo 1b
- mcr p15, 0, r0, c7, c10, 4 @ drain WB
- mov pc, lr
-+.section ".text.other"
-
- /*
- * dma_clean_range(start, end)
-@@ -270,6 +272,7 @@
- *
- * (same as v4wb)
- */
-+.section ".text.arm926_dma_clean_range"
- ENTRY(arm926_dma_clean_range)
- #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- bic r0, r0, #CACHE_DLINESIZE - 1
-@@ -280,6 +283,7 @@
- #endif
- mcr p15, 0, r0, c7, c10, 4 @ drain WB
- mov pc, lr
-+.section ".text.other"
-
- /*
- * dma_flush_range(start, end)
-@@ -289,6 +293,7 @@
- * - start - virtual start address
- * - end - virtual end address
- */
-+.section ".text.arm926_dma_flush_range"
- ENTRY(arm926_dma_flush_range)
- bic r0, r0, #CACHE_DLINESIZE - 1
- 1:
-@@ -302,6 +307,7 @@
- blo 1b
- mcr p15, 0, r0, c7, c10, 4 @ drain WB
- mov pc, lr
-+.section ".text.other"
-
- ENTRY(arm926_cache_fns)
- .long arm926_flush_kern_cache_all
-diff -Nurd linux-2.6.24/arch/mips/kernel/i8259.c linux-2.6.24-oxe810/arch/mips/kernel/i8259.c
---- linux-2.6.24/arch/mips/kernel/i8259.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/mips/kernel/i8259.c 2008-06-11 17:48:37.000000000 +0200
-@@ -338,8 +338,10 @@
-
- init_8259A(0);
-
-- for (i = I8259A_IRQ_BASE; i < I8259A_IRQ_BASE + 16; i++)
-+ for (i = I8259A_IRQ_BASE; i < I8259A_IRQ_BASE + 16; i++) {
- set_irq_chip_and_handler(i, &i8259A_chip, handle_level_irq);
-+ set_irq_probe(i);
-+ }
-
- setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2);
- }
-diff -Nurd linux-2.6.24/arch/mips/kernel/irq.c linux-2.6.24-oxe810/arch/mips/kernel/irq.c
---- linux-2.6.24/arch/mips/kernel/irq.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/mips/kernel/irq.c 2008-06-11 17:48:37.000000000 +0200
-@@ -145,6 +145,11 @@
-
- void __init init_IRQ(void)
- {
-+ int i;
-+
-+ for (i = 0; i < NR_IRQS; i++)
-+ set_irq_noprobe(i);
-+
- arch_init_irq();
-
- #ifdef CONFIG_KGDB
-diff -Nurd linux-2.6.24/arch/powerpc/platforms/chrp/pci.c linux-2.6.24-oxe810/arch/powerpc/platforms/chrp/pci.c
---- linux-2.6.24/arch/powerpc/platforms/chrp/pci.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/powerpc/platforms/chrp/pci.c 2008-06-11 17:47:35.000000000 +0200
-@@ -354,7 +354,7 @@
- * mode as well. The same fixup must be done to the class-code property in
- * the IDE node /pci@80000000/ide@C,1
- */
--static void __devinit chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide)
-+static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide)
- {
- u8 progif;
- struct pci_dev *viaisa;
-@@ -375,4 +375,4 @@
-
- pci_dev_put(viaisa);
- }
--DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata);
-+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata);
-diff -Nurd linux-2.6.24/arch/powerpc/platforms/powermac/feature.c linux-2.6.24-oxe810/arch/powerpc/platforms/powermac/feature.c
---- linux-2.6.24/arch/powerpc/platforms/powermac/feature.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/powerpc/platforms/powermac/feature.c 2008-06-11 17:47:38.000000000 +0200
-@@ -2565,6 +2565,8 @@
-
- /* Locate core99 Uni-N */
- uninorth_node = of_find_node_by_name(NULL, "uni-n");
-+ uninorth_maj = 1;
-+
- /* Locate G5 u3 */
- if (uninorth_node == NULL) {
- uninorth_node = of_find_node_by_name(NULL, "u3");
-@@ -2575,8 +2577,10 @@
- uninorth_node = of_find_node_by_name(NULL, "u4");
- uninorth_maj = 4;
- }
-- if (uninorth_node == NULL)
-+ if (uninorth_node == NULL) {
-+ uninorth_maj = 0;
- return;
-+ }
-
- addrp = of_get_property(uninorth_node, "reg", NULL);
- if (addrp == NULL)
-@@ -3029,3 +3033,8 @@
- pmac_agp_resume(pmac_agp_bridge);
- }
- EXPORT_SYMBOL(pmac_resume_agp_for_card);
-+
-+int pmac_get_uninorth_variant(void)
-+{
-+ return uninorth_maj;
-+}
-diff -Nurd linux-2.6.24/arch/s390/lib/uaccess_pt.c linux-2.6.24-oxe810/arch/s390/lib/uaccess_pt.c
---- linux-2.6.24/arch/s390/lib/uaccess_pt.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/s390/lib/uaccess_pt.c 2008-06-11 17:48:25.000000000 +0200
-@@ -406,6 +406,8 @@
- {
- int ret;
-
-+ if (!current->mm)
-+ return -EFAULT;
- spin_lock(¤t->mm->page_table_lock);
- uaddr = (int __user *) __dat_user_addr((unsigned long) uaddr);
- if (!uaddr) {
-diff -Nurd linux-2.6.24/arch/s390/lib/uaccess_std.c linux-2.6.24-oxe810/arch/s390/lib/uaccess_std.c
---- linux-2.6.24/arch/s390/lib/uaccess_std.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/s390/lib/uaccess_std.c 2008-06-11 17:48:25.000000000 +0200
-@@ -293,10 +293,10 @@
-
- asm volatile(
- " sacf 256\n"
-- " cs %1,%4,0(%5)\n"
-- "0: lr %0,%1\n"
-- "1: sacf 0\n"
-- EX_TABLE(0b,1b)
-+ "0: cs %1,%4,0(%5)\n"
-+ "1: lr %0,%1\n"
-+ "2: sacf 0\n"
-+ EX_TABLE(0b,2b) EX_TABLE(1b,2b)
- : "=d" (ret), "+d" (oldval), "=m" (*uaddr)
- : "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr)
- : "cc", "memory" );
-diff -Nurd linux-2.6.24/arch/sparc/kernel/Makefile linux-2.6.24-oxe810/arch/sparc/kernel/Makefile
---- linux-2.6.24/arch/sparc/kernel/Makefile 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/sparc/kernel/Makefile 2008-06-11 17:48:46.000000000 +0200
-@@ -1,4 +1,4 @@
--# $Id: Makefile,v 1.62 2000/12/15 00:41:17 davem Exp $
-+#
- # Makefile for the linux kernel.
- #
-
-@@ -12,7 +12,8 @@
- sys_sparc.o sunos_asm.o systbls.o \
- time.o windows.o cpu.o devices.o sclow.o \
- tadpole.o tick14.o ptrace.o sys_solaris.o \
-- unaligned.o muldiv.o semaphore.o prom.o of_device.o devres.o
-+ unaligned.o una_asm.o muldiv.o semaphore.o \
-+ prom.o of_device.o devres.o
-
- devres-y = ../../../kernel/irq/devres.o
-
-diff -Nurd linux-2.6.24/arch/sparc/kernel/una_asm.S linux-2.6.24-oxe810/arch/sparc/kernel/una_asm.S
---- linux-2.6.24/arch/sparc/kernel/una_asm.S 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/sparc/kernel/una_asm.S 2008-06-11 17:48:46.000000000 +0200
-@@ -0,0 +1,153 @@
-+/* una_asm.S: Kernel unaligned trap assembler helpers.
-+ *
-+ * Copyright (C) 1996,2005,2008 David S. Miller (davem@davemloft.net)
-+ * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
-+ */
-+
-+#include <linux/errno.h>
-+
-+ .text
-+
-+retl_efault:
-+ retl
-+ mov -EFAULT, %o0
-+
-+ /* int __do_int_store(unsigned long *dst_addr, int size,
-+ * unsigned long *src_val)
-+ *
-+ * %o0 = dest_addr
-+ * %o1 = size
-+ * %o2 = src_val
-+ *
-+ * Return '0' on success, -EFAULT on failure.
-+ */
-+ .globl __do_int_store
-+__do_int_store:
-+ ld [%o2], %g1
-+ cmp %1, 2
-+ be 2f
-+ cmp %1, 4
-+ be 1f
-+ srl %g1, 24, %g2
-+ srl %g1, 16, %g7
-+4: stb %g2, [%o0]
-+ srl %g1, 8, %g2
-+5: stb %g7, [%o0 + 1]
-+ ld [%o2 + 4], %g7
-+6: stb %g2, [%o0 + 2]
-+ srl %g7, 24, %g2
-+7: stb %g1, [%o0 + 3]
-+ srl %g7, 16, %g1
-+8: stb %g2, [%o0 + 4]
-+ srl %g7, 8, %g2
-+9: stb %g1, [%o0 + 5]
-+10: stb %g2, [%o0 + 6]
-+ b 0f
-+11: stb %g7, [%o0 + 7]
-+1: srl %g1, 16, %g7
-+12: stb %g2, [%o0]
-+ srl %g1, 8, %g2
-+13: stb %g7, [%o0 + 1]
-+14: stb %g2, [%o0 + 2]
-+ b 0f
-+15: stb %g1, [%o0 + 3]
-+2: srl %g1, 8, %g2
-+16: stb %g2, [%o0]
-+17: stb %g1, [%o0 + 1]
-+0: retl
-+ mov 0, %o0
-+
-+ .section __ex_table,#alloc
-+ .word 4b, retl_efault
-+ .word 5b, retl_efault
-+ .word 6b, retl_efault
-+ .word 7b, retl_efault
-+ .word 8b, retl_efault
-+ .word 9b, retl_efault
-+ .word 10b, retl_efault
-+ .word 11b, retl_efault
-+ .word 12b, retl_efault
-+ .word 13b, retl_efault
-+ .word 14b, retl_efault
-+ .word 15b, retl_efault
-+ .word 16b, retl_efault
-+ .word 17b, retl_efault
-+ .previous
-+
-+ /* int do_int_load(unsigned long *dest_reg, int size,
-+ * unsigned long *saddr, int is_signed)
-+ *
-+ * %o0 = dest_reg
-+ * %o1 = size
-+ * %o2 = saddr
-+ * %o3 = is_signed
-+ *
-+ * Return '0' on success, -EFAULT on failure.
-+ */
-+ .globl do_int_load
-+do_int_load:
-+ cmp %o1, 8
-+ be 9f
-+ cmp %o1, 4
-+ be 6f
-+4: ldub [%o2], %g1
-+5: ldub [%o2 + 1], %g2
-+ sll %g1, 8, %g1
-+ tst %o3
-+ be 3f
-+ or %g1, %g2, %g1
-+ sll %g1, 16, %g1
-+ sra %g1, 16, %g1
-+3: b 0f
-+ st %g1, [%o0]
-+6: ldub [%o2 + 1], %g2
-+ sll %g1, 24, %g1
-+7: ldub [%o2 + 2], %g7
-+ sll %g2, 16, %g2
-+8: ldub [%o2 + 3], %g3
-+ sll %g7, 8, %g7
-+ or %g3, %g2, %g3
-+ or %g7, %g3, %g7
-+ or %g1, %g7, %g1
-+ b 0f
-+ st %g1, [%o0]
-+9: ldub [%o2], %g1
-+10: ldub [%o2 + 1], %g2
-+ sll %g1, 24, %g1
-+11: ldub [%o2 + 2], %g7
-+ sll %g2, 16, %g2
-+12: ldub [%o2 + 3], %g3
-+ sll %g7, 8, %g7
-+ or %g1, %g2, %g1
-+ or %g7, %g3, %g7
-+ or %g1, %g7, %g7
-+13: ldub [%o2 + 4], %g1
-+ st %g7, [%o0]
-+14: ldub [%o2 + 5], %g2
-+ sll %g1, 24, %g1
-+15: ldub [%o2 + 6], %g7
-+ sll %g2, 16, %g2
-+16: ldub [%o2 + 7], %g3
-+ sll %g7, 8, %g7
-+ or %g1, %g2, %g1
-+ or %g7, %g3, %g7
-+ or %g1, %g7, %g7
-+ st %g7, [%o0 + 4]
-+0: retl
-+ mov 0, %o0
-+
-+ .section __ex_table,#alloc
-+ .word 4b, retl_efault
-+ .word 5b, retl_efault
-+ .word 6b, retl_efault
-+ .word 7b, retl_efault
-+ .word 8b, retl_efault
-+ .word 9b, retl_efault
-+ .word 10b, retl_efault
-+ .word 11b, retl_efault
-+ .word 12b, retl_efault
-+ .word 13b, retl_efault
-+ .word 14b, retl_efault
-+ .word 15b, retl_efault
-+ .word 16b, retl_efault
-+ .previous
-diff -Nurd linux-2.6.24/arch/sparc/kernel/unaligned.c linux-2.6.24-oxe810/arch/sparc/kernel/unaligned.c
---- linux-2.6.24/arch/sparc/kernel/unaligned.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/sparc/kernel/unaligned.c 2008-06-11 17:48:46.000000000 +0200
-@@ -175,157 +175,31 @@
- panic(str);
- }
-
--#define do_integer_load(dest_reg, size, saddr, is_signed, errh) ({ \
--__asm__ __volatile__ ( \
-- "cmp %1, 8\n\t" \
-- "be 9f\n\t" \
-- " cmp %1, 4\n\t" \
-- "be 6f\n" \
--"4:\t" " ldub [%2], %%l1\n" \
--"5:\t" "ldub [%2 + 1], %%l2\n\t" \
-- "sll %%l1, 8, %%l1\n\t" \
-- "tst %3\n\t" \
-- "be 3f\n\t" \
-- " add %%l1, %%l2, %%l1\n\t" \
-- "sll %%l1, 16, %%l1\n\t" \
-- "sra %%l1, 16, %%l1\n" \
--"3:\t" "b 0f\n\t" \
-- " st %%l1, [%0]\n" \
--"6:\t" "ldub [%2 + 1], %%l2\n\t" \
-- "sll %%l1, 24, %%l1\n" \
--"7:\t" "ldub [%2 + 2], %%g7\n\t" \
-- "sll %%l2, 16, %%l2\n" \
--"8:\t" "ldub [%2 + 3], %%g1\n\t" \
-- "sll %%g7, 8, %%g7\n\t" \
-- "or %%l1, %%l2, %%l1\n\t" \
-- "or %%g7, %%g1, %%g7\n\t" \
-- "or %%l1, %%g7, %%l1\n\t" \
-- "b 0f\n\t" \
-- " st %%l1, [%0]\n" \
--"9:\t" "ldub [%2], %%l1\n" \
--"10:\t" "ldub [%2 + 1], %%l2\n\t" \
-- "sll %%l1, 24, %%l1\n" \
--"11:\t" "ldub [%2 + 2], %%g7\n\t" \
-- "sll %%l2, 16, %%l2\n" \
--"12:\t" "ldub [%2 + 3], %%g1\n\t" \
-- "sll %%g7, 8, %%g7\n\t" \
-- "or %%l1, %%l2, %%l1\n\t" \
-- "or %%g7, %%g1, %%g7\n\t" \
-- "or %%l1, %%g7, %%g7\n" \
--"13:\t" "ldub [%2 + 4], %%l1\n\t" \
-- "st %%g7, [%0]\n" \
--"14:\t" "ldub [%2 + 5], %%l2\n\t" \
-- "sll %%l1, 24, %%l1\n" \
--"15:\t" "ldub [%2 + 6], %%g7\n\t" \
-- "sll %%l2, 16, %%l2\n" \
--"16:\t" "ldub [%2 + 7], %%g1\n\t" \
-- "sll %%g7, 8, %%g7\n\t" \
-- "or %%l1, %%l2, %%l1\n\t" \
-- "or %%g7, %%g1, %%g7\n\t" \
-- "or %%l1, %%g7, %%g7\n\t" \
-- "st %%g7, [%0 + 4]\n" \
--"0:\n\n\t" \
-- ".section __ex_table,#alloc\n\t" \
-- ".word 4b, " #errh "\n\t" \
-- ".word 5b, " #errh "\n\t" \
-- ".word 6b, " #errh "\n\t" \
-- ".word 7b, " #errh "\n\t" \
-- ".word 8b, " #errh "\n\t" \
-- ".word 9b, " #errh "\n\t" \
-- ".word 10b, " #errh "\n\t" \
-- ".word 11b, " #errh "\n\t" \
-- ".word 12b, " #errh "\n\t" \
-- ".word 13b, " #errh "\n\t" \
-- ".word 14b, " #errh "\n\t" \
-- ".word 15b, " #errh "\n\t" \
-- ".word 16b, " #errh "\n\n\t" \
-- ".previous\n\t" \
-- : : "r" (dest_reg), "r" (size), "r" (saddr), "r" (is_signed) \
-- : "l1", "l2", "g7", "g1", "cc"); \
--})
--
--#define store_common(dst_addr, size, src_val, errh) ({ \
--__asm__ __volatile__ ( \
-- "ld [%2], %%l1\n" \
-- "cmp %1, 2\n\t" \
-- "be 2f\n\t" \
-- " cmp %1, 4\n\t" \
-- "be 1f\n\t" \
-- " srl %%l1, 24, %%l2\n\t" \
-- "srl %%l1, 16, %%g7\n" \
--"4:\t" "stb %%l2, [%0]\n\t" \
-- "srl %%l1, 8, %%l2\n" \
--"5:\t" "stb %%g7, [%0 + 1]\n\t" \
-- "ld [%2 + 4], %%g7\n" \
--"6:\t" "stb %%l2, [%0 + 2]\n\t" \
-- "srl %%g7, 24, %%l2\n" \
--"7:\t" "stb %%l1, [%0 + 3]\n\t" \
-- "srl %%g7, 16, %%l1\n" \
--"8:\t" "stb %%l2, [%0 + 4]\n\t" \
-- "srl %%g7, 8, %%l2\n" \
--"9:\t" "stb %%l1, [%0 + 5]\n" \
--"10:\t" "stb %%l2, [%0 + 6]\n\t" \
-- "b 0f\n" \
--"11:\t" " stb %%g7, [%0 + 7]\n" \
--"1:\t" "srl %%l1, 16, %%g7\n" \
--"12:\t" "stb %%l2, [%0]\n\t" \
-- "srl %%l1, 8, %%l2\n" \
--"13:\t" "stb %%g7, [%0 + 1]\n" \
--"14:\t" "stb %%l2, [%0 + 2]\n\t" \
-- "b 0f\n" \
--"15:\t" " stb %%l1, [%0 + 3]\n" \
--"2:\t" "srl %%l1, 8, %%l2\n" \
--"16:\t" "stb %%l2, [%0]\n" \
--"17:\t" "stb %%l1, [%0 + 1]\n" \
--"0:\n\n\t" \
-- ".section __ex_table,#alloc\n\t" \
-- ".word 4b, " #errh "\n\t" \
-- ".word 5b, " #errh "\n\t" \
-- ".word 6b, " #errh "\n\t" \
-- ".word 7b, " #errh "\n\t" \
-- ".word 8b, " #errh "\n\t" \
-- ".word 9b, " #errh "\n\t" \
-- ".word 10b, " #errh "\n\t" \
-- ".word 11b, " #errh "\n\t" \
-- ".word 12b, " #errh "\n\t" \
-- ".word 13b, " #errh "\n\t" \
-- ".word 14b, " #errh "\n\t" \
-- ".word 15b, " #errh "\n\t" \
-- ".word 16b, " #errh "\n\t" \
-- ".word 17b, " #errh "\n\n\t" \
-- ".previous\n\t" \
-- : : "r" (dst_addr), "r" (size), "r" (src_val) \
-- : "l1", "l2", "g7", "g1", "cc"); \
--})
-+/* una_asm.S */
-+extern int do_int_load(unsigned long *dest_reg, int size,
-+ unsigned long *saddr, int is_signed);
-+extern int __do_int_store(unsigned long *dst_addr, int size,
-+ unsigned long *src_val);
-
--#define do_integer_store(reg_num, size, dst_addr, regs, errh) ({ \
-- unsigned long *src_val; \
-- static unsigned long zero[2] = { 0, }; \
-- \
-- if (reg_num) src_val = fetch_reg_addr(reg_num, regs); \
-- else { \
-- src_val = &zero[0]; \
-- if (size == 8) \
-- zero[1] = fetch_reg(1, regs); \
-- } \
-- store_common(dst_addr, size, src_val, errh); \
--})
-+static int do_int_store(int reg_num, int size, unsigned long *dst_addr,
-+ struct pt_regs *regs)
-+{
-+ unsigned long zero[2] = { 0, 0 };
-+ unsigned long *src_val;
-+
-+ if (reg_num)
-+ src_val = fetch_reg_addr(reg_num, regs);
-+ else {
-+ src_val = &zero[0];
-+ if (size == 8)
-+ zero[1] = fetch_reg(1, regs);
-+ }
-+ return __do_int_store(dst_addr, size, src_val);
-+}
-
- extern void smp_capture(void);
- extern void smp_release(void);
-
--#define do_atomic(srcdest_reg, mem, errh) ({ \
-- unsigned long flags, tmp; \
-- \
-- smp_capture(); \
-- local_irq_save(flags); \
-- tmp = *srcdest_reg; \
-- do_integer_load(srcdest_reg, 4, mem, 0, errh); \
-- store_common(mem, 4, &tmp, errh); \
-- local_irq_restore(flags); \
-- smp_release(); \
--})
--
- static inline void advance(struct pt_regs *regs)
- {
- regs->pc = regs->npc;
-@@ -342,9 +216,7 @@
- return !floating_point_load_or_store_p(insn);
- }
-
--void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("kernel_mna_trap_fault");
--
--void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
-+static void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
- {
- unsigned long g2 = regs->u_regs [UREG_G2];
- unsigned long fixup = search_extables_range(regs->pc, &g2);
-@@ -379,48 +251,34 @@
- printk("Unsupported unaligned load/store trap for kernel at <%08lx>.\n",
- regs->pc);
- unaligned_panic("Wheee. Kernel does fpu/atomic unaligned load/store.");
--
-- __asm__ __volatile__ ("\n"
--"kernel_unaligned_trap_fault:\n\t"
-- "mov %0, %%o0\n\t"
-- "call kernel_mna_trap_fault\n\t"
-- " mov %1, %%o1\n\t"
-- :
-- : "r" (regs), "r" (insn)
-- : "o0", "o1", "o2", "o3", "o4", "o5", "o7",
-- "g1", "g2", "g3", "g4", "g5", "g7", "cc");
- } else {
- unsigned long addr = compute_effective_address(regs, insn);
-+ int err;
-
- #ifdef DEBUG_MNA
- printk("KMNA: pc=%08lx [dir=%s addr=%08lx size=%d] retpc[%08lx]\n",
- regs->pc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]);
- #endif
-- switch(dir) {
-+ switch (dir) {
- case load:
-- do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
-- size, (unsigned long *) addr,
-- decode_signedness(insn),
-- kernel_unaligned_trap_fault);
-+ err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
-+ regs),
-+ size, (unsigned long *) addr,
-+ decode_signedness(insn));
- break;
-
- case store:
-- do_integer_store(((insn>>25)&0x1f), size,
-- (unsigned long *) addr, regs,
-- kernel_unaligned_trap_fault);
-- break;
--#if 0 /* unsupported */
-- case both:
-- do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs),
-- (unsigned long *) addr,
-- kernel_unaligned_trap_fault);
-+ err = do_int_store(((insn>>25)&0x1f), size,
-+ (unsigned long *) addr, regs);
- break;
--#endif
- default:
- panic("Impossible kernel unaligned trap.");
- /* Not reached... */
- }
-- advance(regs);
-+ if (err)
-+ kernel_mna_trap_fault(regs, insn);
-+ else
-+ advance(regs);
- }
- }
-
-@@ -459,9 +317,7 @@
- return 0;
- }
-
--void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("user_mna_trap_fault");
--
--void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
-+static void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
- {
- siginfo_t info;
-
-@@ -485,7 +341,7 @@
- if(!ok_for_user(regs, insn, dir)) {
- goto kill_user;
- } else {
-- int size = decode_access_size(insn);
-+ int err, size = decode_access_size(insn);
- unsigned long addr;
-
- if(floating_point_load_or_store_p(insn)) {
-@@ -496,48 +352,34 @@
- addr = compute_effective_address(regs, insn);
- switch(dir) {
- case load:
-- do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
-- size, (unsigned long *) addr,
-- decode_signedness(insn),
-- user_unaligned_trap_fault);
-+ err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
-+ regs),
-+ size, (unsigned long *) addr,
-+ decode_signedness(insn));
- break;
-
- case store:
-- do_integer_store(((insn>>25)&0x1f), size,
-- (unsigned long *) addr, regs,
-- user_unaligned_trap_fault);
-+ err = do_int_store(((insn>>25)&0x1f), size,
-+ (unsigned long *) addr, regs);
- break;
-
- case both:
--#if 0 /* unsupported */
-- do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs),
-- (unsigned long *) addr,
-- user_unaligned_trap_fault);
--#else
- /*
- * This was supported in 2.4. However, we question
- * the value of SWAP instruction across word boundaries.
- */
- printk("Unaligned SWAP unsupported.\n");
-- goto kill_user;
--#endif
-+ err = -EFAULT;
- break;
-
- default:
- unaligned_panic("Impossible user unaligned trap.");
--
-- __asm__ __volatile__ ("\n"
--"user_unaligned_trap_fault:\n\t"
-- "mov %0, %%o0\n\t"
-- "call user_mna_trap_fault\n\t"
-- " mov %1, %%o1\n\t"
-- :
-- : "r" (regs), "r" (insn)
-- : "o0", "o1", "o2", "o3", "o4", "o5", "o7",
-- "g1", "g2", "g3", "g4", "g5", "g7", "cc");
- goto out;
- }
-- advance(regs);
-+ if (err)
-+ goto kill_user;
-+ else
-+ advance(regs);
- goto out;
- }
-
-diff -Nurd linux-2.6.24/arch/sparc/lib/rwsem.S linux-2.6.24-oxe810/arch/sparc/lib/rwsem.S
---- linux-2.6.24/arch/sparc/lib/rwsem.S 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/sparc/lib/rwsem.S 2008-06-11 17:48:47.000000000 +0200
-@@ -7,7 +7,7 @@
- #include <asm/ptrace.h>
- #include <asm/psr.h>
-
-- .section .sched.text
-+ .section .sched.text, "ax"
- .align 4
-
- .globl ___down_read
-diff -Nurd linux-2.6.24/arch/sparc64/lib/rwsem.S linux-2.6.24-oxe810/arch/sparc64/lib/rwsem.S
---- linux-2.6.24/arch/sparc64/lib/rwsem.S 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/sparc64/lib/rwsem.S 2008-06-11 17:48:11.000000000 +0200
-@@ -6,7 +6,7 @@
-
- #include <asm/rwsem-const.h>
-
-- .section .sched.text
-+ .section .sched.text, "ax"
-
- .globl __down_read
- __down_read:
-diff -Nurd linux-2.6.24/arch/sparc64/mm/fault.c linux-2.6.24-oxe810/arch/sparc64/mm/fault.c
---- linux-2.6.24/arch/sparc64/mm/fault.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/sparc64/mm/fault.c 2008-06-11 17:48:12.000000000 +0200
-@@ -244,16 +244,8 @@
- if (regs->tstate & TSTATE_PRIV) {
- const struct exception_table_entry *entry;
-
-- if (asi == ASI_P && (insn & 0xc0800000) == 0xc0800000) {
-- if (insn & 0x2000)
-- asi = (regs->tstate >> 24);
-- else
-- asi = (insn >> 5);
-- }
--
-- /* Look in asi.h: All _S asis have LS bit set */
-- if ((asi & 0x1) &&
-- (entry = search_exception_tables(regs->tpc))) {
-+ entry = search_exception_tables(regs->tpc);
-+ if (entry) {
- regs->tpc = entry->fixup;
- regs->tnpc = regs->tpc + 4;
- return;
-@@ -294,7 +286,7 @@
- unsigned long tpc = regs->tpc;
-
- /* Sanity check the PC. */
-- if ((tpc >= KERNBASE && tpc < (unsigned long) _etext) ||
-+ if ((tpc >= KERNBASE && tpc < (unsigned long) __init_end) ||
- (tpc >= MODULES_VADDR && tpc < MODULES_END)) {
- /* Valid, no problems... */
- } else {
-diff -Nurd linux-2.6.24/arch/x86/ia32/ia32_signal.c linux-2.6.24-oxe810/arch/x86/ia32/ia32_signal.c
---- linux-2.6.24/arch/x86/ia32/ia32_signal.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/ia32/ia32_signal.c 2008-06-11 17:48:21.000000000 +0200
-@@ -494,7 +494,7 @@
- regs->ss = __USER32_DS;
-
- set_fs(USER_DS);
-- regs->eflags &= ~TF_MASK;
-+ regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
- if (test_thread_flag(TIF_SINGLESTEP))
- ptrace_notify(SIGTRAP);
-
-@@ -600,7 +600,7 @@
- regs->ss = __USER32_DS;
-
- set_fs(USER_DS);
-- regs->eflags &= ~TF_MASK;
-+ regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
- if (test_thread_flag(TIF_SINGLESTEP))
- ptrace_notify(SIGTRAP);
-
-diff -Nurd linux-2.6.24/arch/x86/kernel/Makefile_32 linux-2.6.24-oxe810/arch/x86/kernel/Makefile_32
---- linux-2.6.24/arch/x86/kernel/Makefile_32 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/Makefile_32 2008-06-11 17:48:20.000000000 +0200
-@@ -19,7 +19,8 @@
- obj-$(CONFIG_X86_CPUID) += cpuid.o
- obj-$(CONFIG_MICROCODE) += microcode.o
- obj-$(CONFIG_PCI) += early-quirks.o
--obj-$(CONFIG_APM) += apm_32.o
-+apm-y := apm_32.o
-+obj-$(CONFIG_APM) += apm.o
- obj-$(CONFIG_X86_SMP) += smp_32.o smpboot_32.o tsc_sync.o
- obj-$(CONFIG_SMP) += smpcommon_32.o
- obj-$(CONFIG_X86_TRAMPOLINE) += trampoline_32.o
-diff -Nurd linux-2.6.24/arch/x86/kernel/apic_32.c linux-2.6.24-oxe810/arch/x86/kernel/apic_32.c
---- linux-2.6.24/arch/x86/kernel/apic_32.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/apic_32.c 2008-06-11 17:48:20.000000000 +0200
-@@ -154,7 +154,7 @@
- /**
- * enable_NMI_through_LVT0 - enable NMI through local vector table 0
- */
--void enable_NMI_through_LVT0 (void * dummy)
-+void __cpuinit enable_NMI_through_LVT0(void)
- {
- unsigned int v = APIC_DM_NMI;
-
-diff -Nurd linux-2.6.24/arch/x86/kernel/apic_64.c linux-2.6.24-oxe810/arch/x86/kernel/apic_64.c
---- linux-2.6.24/arch/x86/kernel/apic_64.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/apic_64.c 2008-06-11 17:48:20.000000000 +0200
-@@ -151,7 +151,7 @@
- return send_status;
- }
-
--void enable_NMI_through_LVT0 (void * dummy)
-+void enable_NMI_through_LVT0(void)
- {
- unsigned int v;
-
-diff -Nurd linux-2.6.24/arch/x86/kernel/io_apic_32.c linux-2.6.24-oxe810/arch/x86/kernel/io_apic_32.c
---- linux-2.6.24/arch/x86/kernel/io_apic_32.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/io_apic_32.c 2008-06-11 17:48:20.000000000 +0200
-@@ -2080,7 +2080,7 @@
- .eoi = ack_apic,
- };
-
--static void setup_nmi (void)
-+static void __init setup_nmi(void)
- {
- /*
- * Dirty trick to enable the NMI watchdog ...
-@@ -2093,7 +2093,7 @@
- */
- apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ...");
-
-- on_each_cpu(enable_NMI_through_LVT0, NULL, 1, 1);
-+ enable_NMI_through_LVT0();
-
- apic_printk(APIC_VERBOSE, " done.\n");
- }
-diff -Nurd linux-2.6.24/arch/x86/kernel/io_apic_64.c linux-2.6.24-oxe810/arch/x86/kernel/io_apic_64.c
---- linux-2.6.24/arch/x86/kernel/io_apic_64.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/io_apic_64.c 2008-06-11 17:48:20.000000000 +0200
-@@ -1565,7 +1565,7 @@
- .end = end_lapic_irq,
- };
-
--static void setup_nmi (void)
-+static void __init setup_nmi(void)
- {
- /*
- * Dirty trick to enable the NMI watchdog ...
-@@ -1578,7 +1578,7 @@
- */
- printk(KERN_INFO "activating NMI Watchdog ...");
-
-- enable_NMI_through_LVT0(NULL);
-+ enable_NMI_through_LVT0();
-
- printk(" done.\n");
- }
-@@ -1654,7 +1654,7 @@
- *
- * FIXME: really need to revamp this for modern platforms only.
- */
--static inline void check_timer(void)
-+static inline void __init check_timer(void)
- {
- struct irq_cfg *cfg = irq_cfg + 0;
- int apic1, pin1, apic2, pin2;
-diff -Nurd linux-2.6.24/arch/x86/kernel/process_64.c linux-2.6.24-oxe810/arch/x86/kernel/process_64.c
---- linux-2.6.24/arch/x86/kernel/process_64.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/process_64.c 2008-06-11 17:48:20.000000000 +0200
-@@ -212,14 +212,13 @@
- current_thread_info()->status |= TS_POLLING;
- /* endless idle loop with no priority at all */
- while (1) {
-+ tick_nohz_stop_sched_tick();
- while (!need_resched()) {
- void (*idle)(void);
-
- if (__get_cpu_var(cpu_idle_state))
- __get_cpu_var(cpu_idle_state) = 0;
-
-- tick_nohz_stop_sched_tick();
--
- rmb();
- idle = pm_idle;
- if (!idle)
-diff -Nurd linux-2.6.24/arch/x86/kernel/signal_32.c linux-2.6.24-oxe810/arch/x86/kernel/signal_32.c
---- linux-2.6.24/arch/x86/kernel/signal_32.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/signal_32.c 2008-06-11 17:48:20.000000000 +0200
-@@ -396,7 +396,7 @@
- * The tracer may want to single-step inside the
- * handler too.
- */
-- regs->eflags &= ~TF_MASK;
-+ regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
- if (test_thread_flag(TIF_SINGLESTEP))
- ptrace_notify(SIGTRAP);
-
-@@ -489,7 +489,7 @@
- * The tracer may want to single-step inside the
- * handler too.
- */
-- regs->eflags &= ~TF_MASK;
-+ regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
- if (test_thread_flag(TIF_SINGLESTEP))
- ptrace_notify(SIGTRAP);
-
-diff -Nurd linux-2.6.24/arch/x86/kernel/signal_64.c linux-2.6.24-oxe810/arch/x86/kernel/signal_64.c
---- linux-2.6.24/arch/x86/kernel/signal_64.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/signal_64.c 2008-06-11 17:48:20.000000000 +0200
-@@ -295,7 +295,7 @@
- see include/asm-x86_64/uaccess.h for details. */
- set_fs(USER_DS);
-
-- regs->eflags &= ~TF_MASK;
-+ regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
- if (test_thread_flag(TIF_SINGLESTEP))
- ptrace_notify(SIGTRAP);
- #ifdef DEBUG_SIG
-diff -Nurd linux-2.6.24/arch/x86/kernel/smpboot_32.c linux-2.6.24-oxe810/arch/x86/kernel/smpboot_32.c
---- linux-2.6.24/arch/x86/kernel/smpboot_32.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/smpboot_32.c 2008-06-11 17:48:20.000000000 +0200
-@@ -405,7 +405,7 @@
- setup_secondary_clock();
- if (nmi_watchdog == NMI_IO_APIC) {
- disable_8259A_irq(0);
-- enable_NMI_through_LVT0(NULL);
-+ enable_NMI_through_LVT0();
- enable_8259A_irq(0);
- }
- /*
-diff -Nurd linux-2.6.24/arch/x86/kernel/smpboot_64.c linux-2.6.24-oxe810/arch/x86/kernel/smpboot_64.c
---- linux-2.6.24/arch/x86/kernel/smpboot_64.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/kernel/smpboot_64.c 2008-06-11 17:48:20.000000000 +0200
-@@ -338,7 +338,7 @@
-
- if (nmi_watchdog == NMI_IO_APIC) {
- disable_8259A_irq(0);
-- enable_NMI_through_LVT0(NULL);
-+ enable_NMI_through_LVT0();
- enable_8259A_irq(0);
- }
-
-diff -Nurd linux-2.6.24/arch/x86/mm/pageattr_64.c linux-2.6.24-oxe810/arch/x86/mm/pageattr_64.c
---- linux-2.6.24/arch/x86/mm/pageattr_64.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/mm/pageattr_64.c 2008-06-11 17:48:22.000000000 +0200
-@@ -207,7 +207,7 @@
- if (__pa(address) < KERNEL_TEXT_SIZE) {
- unsigned long addr2;
- pgprot_t prot2;
-- addr2 = __START_KERNEL_map + __pa(address);
-+ addr2 = __START_KERNEL_map + __pa(address) - phys_base;
- /* Make sure the kernel mappings stay executable */
- prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot)));
- err = __change_page_attr(addr2, pfn, prot2,
-diff -Nurd linux-2.6.24/arch/x86/pci/mmconfig-shared.c linux-2.6.24-oxe810/arch/x86/pci/mmconfig-shared.c
---- linux-2.6.24/arch/x86/pci/mmconfig-shared.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/pci/mmconfig-shared.c 2008-06-11 17:48:22.000000000 +0200
-@@ -22,42 +22,9 @@
- #define MMCONFIG_APER_MIN (2 * 1024*1024)
- #define MMCONFIG_APER_MAX (256 * 1024*1024)
-
--DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
--
- /* Indicate if the mmcfg resources have been placed into the resource table. */
- static int __initdata pci_mmcfg_resources_inserted;
-
--/* K8 systems have some devices (typically in the builtin northbridge)
-- that are only accessible using type1
-- Normally this can be expressed in the MCFG by not listing them
-- and assigning suitable _SEGs, but this isn't implemented in some BIOS.
-- Instead try to discover all devices on bus 0 that are unreachable using MM
-- and fallback for them. */
--static void __init unreachable_devices(void)
--{
-- int i, bus;
-- /* Use the max bus number from ACPI here? */
-- for (bus = 0; bus < PCI_MMCFG_MAX_CHECK_BUS; bus++) {
-- for (i = 0; i < 32; i++) {
-- unsigned int devfn = PCI_DEVFN(i, 0);
-- u32 val1, val2;
--
-- pci_conf1_read(0, bus, devfn, 0, 4, &val1);
-- if (val1 == 0xffffffff)
-- continue;
--
-- if (pci_mmcfg_arch_reachable(0, bus, devfn)) {
-- raw_pci_ops->read(0, bus, devfn, 0, 4, &val2);
-- if (val1 == val2)
-- continue;
-- }
-- set_bit(i + 32 * bus, pci_mmcfg_fallback_slots);
-- printk(KERN_NOTICE "PCI: No mmconfig possible on device"
-- " %02x:%02x\n", bus, i);
-- }
-- }
--}
--
- static const char __init *pci_mmcfg_e7520(void)
- {
- u32 win;
-@@ -270,8 +237,6 @@
- return;
-
- if (pci_mmcfg_arch_init()) {
-- if (type == 1)
-- unreachable_devices();
- if (known_bridge)
- pci_mmcfg_insert_resources(IORESOURCE_BUSY);
- pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
-diff -Nurd linux-2.6.24/arch/x86/pci/mmconfig_32.c linux-2.6.24-oxe810/arch/x86/pci/mmconfig_32.c
---- linux-2.6.24/arch/x86/pci/mmconfig_32.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/pci/mmconfig_32.c 2008-06-11 17:48:22.000000000 +0200
-@@ -30,10 +30,6 @@
- struct acpi_mcfg_allocation *cfg;
- int cfg_num;
-
-- if (seg == 0 && bus < PCI_MMCFG_MAX_CHECK_BUS &&
-- test_bit(PCI_SLOT(devfn) + 32*bus, pci_mmcfg_fallback_slots))
-- return 0;
--
- for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) {
- cfg = &pci_mmcfg_config[cfg_num];
- if (cfg->pci_segment == seg &&
-@@ -68,13 +64,16 @@
- u32 base;
-
- if ((bus > 255) || (devfn > 255) || (reg > 4095)) {
-- *value = -1;
-+err: *value = -1;
- return -EINVAL;
- }
-
-+ if (reg < 256)
-+ return pci_conf1_read(seg,bus,devfn,reg,len,value);
-+
- base = get_base_addr(seg, bus, devfn);
- if (!base)
-- return pci_conf1_read(seg,bus,devfn,reg,len,value);
-+ goto err;
-
- spin_lock_irqsave(&pci_config_lock, flags);
-
-@@ -105,9 +104,12 @@
- if ((bus > 255) || (devfn > 255) || (reg > 4095))
- return -EINVAL;
-
-+ if (reg < 256)
-+ return pci_conf1_write(seg,bus,devfn,reg,len,value);
-+
- base = get_base_addr(seg, bus, devfn);
- if (!base)
-- return pci_conf1_write(seg,bus,devfn,reg,len,value);
-+ return -EINVAL;
-
- spin_lock_irqsave(&pci_config_lock, flags);
-
-@@ -134,12 +136,6 @@
- .write = pci_mmcfg_write,
- };
-
--int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus,
-- unsigned int devfn)
--{
-- return get_base_addr(seg, bus, devfn) != 0;
--}
--
- int __init pci_mmcfg_arch_init(void)
- {
- printk(KERN_INFO "PCI: Using MMCONFIG\n");
-diff -Nurd linux-2.6.24/arch/x86/pci/mmconfig_64.c linux-2.6.24-oxe810/arch/x86/pci/mmconfig_64.c
---- linux-2.6.24/arch/x86/pci/mmconfig_64.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/pci/mmconfig_64.c 2008-06-11 17:48:22.000000000 +0200
-@@ -40,9 +40,7 @@
- static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
- {
- char __iomem *addr;
-- if (seg == 0 && bus < PCI_MMCFG_MAX_CHECK_BUS &&
-- test_bit(32*bus + PCI_SLOT(devfn), pci_mmcfg_fallback_slots))
-- return NULL;
-+
- addr = get_virt(seg, bus);
- if (!addr)
- return NULL;
-@@ -56,13 +54,16 @@
-
- /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
- if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
-- *value = -1;
-+err: *value = -1;
- return -EINVAL;
- }
-
-+ if (reg < 256)
-+ return pci_conf1_read(seg,bus,devfn,reg,len,value);
-+
- addr = pci_dev_base(seg, bus, devfn);
- if (!addr)
-- return pci_conf1_read(seg,bus,devfn,reg,len,value);
-+ goto err;
-
- switch (len) {
- case 1:
-@@ -88,9 +89,12 @@
- if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
- return -EINVAL;
-
-+ if (reg < 256)
-+ return pci_conf1_write(seg,bus,devfn,reg,len,value);
-+
- addr = pci_dev_base(seg, bus, devfn);
- if (!addr)
-- return pci_conf1_write(seg,bus,devfn,reg,len,value);
-+ return -EINVAL;
-
- switch (len) {
- case 1:
-@@ -126,12 +130,6 @@
- return addr;
- }
-
--int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus,
-- unsigned int devfn)
--{
-- return pci_dev_base(seg, bus, devfn) != NULL;
--}
--
- int __init pci_mmcfg_arch_init(void)
- {
- int i;
-diff -Nurd linux-2.6.24/arch/x86/pci/pci.h linux-2.6.24-oxe810/arch/x86/pci/pci.h
---- linux-2.6.24/arch/x86/pci/pci.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/arch/x86/pci/pci.h 2008-06-11 17:48:22.000000000 +0200
-@@ -98,13 +98,6 @@
-
- /* pci-mmconfig.c */
-
--/* Verify the first 16 busses. We assume that systems with more busses
-- get MCFG right. */
--#define PCI_MMCFG_MAX_CHECK_BUS 16
--extern DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
--
--extern int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus,
-- unsigned int devfn);
- extern int __init pci_mmcfg_arch_init(void);
-
- /*
-diff -Nurd linux-2.6.24/block/ll_rw_blk.c linux-2.6.24-oxe810/block/ll_rw_blk.c
---- linux-2.6.24/block/ll_rw_blk.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/block/ll_rw_blk.c 2008-06-11 17:46:40.000000000 +0200
-@@ -1424,6 +1424,13 @@
- else
- max_sectors = q->max_sectors;
-
-+ /*
-+ * If the RAID modes of the bio associated with the request differs
-+ * from the merge candidate bio, it can't be merged
-+ */
-+ if (req->bio->bi_raid != bio->bi_raid)
-+ return 0;
-+
- if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
- req->cmd_flags |= REQ_NOMERGE;
- if (req == q->last_merge)
-@@ -1462,6 +1469,12 @@
- else
- max_sectors = q->max_sectors;
-
-+ /*
-+ * If the RAID modes of the bio associated with the request differs
-+ * from the merge candidate bio, it can't be merged
-+ */
-+ if (req->bio->bi_raid != bio->bi_raid)
-+ return 0;
-
- if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
- req->cmd_flags |= REQ_NOMERGE;
-@@ -1502,6 +1515,17 @@
- */
- if (req->special || next->special)
- return 0;
-+
-+ /*
-+ * If the RAID modes of the bio associated with the two requests differ
-+ * then they cannot be merged.
-+ *
-+ BUG_ON(!req);
-+ BUG_ON(!req->bio);
-+ BUG_ON(!next);
-+ BUG_ON(!next->bio);
-+ if (req->bio->bi_raid != next->bio->bi_raid)
-+ return 0;*/
-
- /*
- * Will it become too large?
-@@ -2965,7 +2989,7 @@
-
- static int __make_request(struct request_queue *q, struct bio *bio)
- {
-- struct request *req;
-+ struct request *req = 0;
- int el_ret, nr_sectors, barrier, err;
- const unsigned short prio = bio_prio(bio);
- const int sync = bio_sync(bio);
-@@ -2992,6 +3016,15 @@
- goto get_rq;
-
- el_ret = elv_merge(q, &req, bio);
-+
-+ /* if the bio raid modes differ, force a no-merge */
-+ if ((!ELEVATOR_NO_MERGE) &&
-+ (req) &&
-+ (req->bio) &&
-+ (bio->bi_raid != req->bio->bi_raid )) {
-+ el_ret = ELEVATOR_NO_MERGE;
-+ }
-+
- switch (el_ret) {
- case ELEVATOR_BACK_MERGE:
- BUG_ON(!rq_mergeable(req));
-diff -Nurd linux-2.6.24/crypto/async_tx/async_xor.c linux-2.6.24-oxe810/crypto/async_tx/async_xor.c
---- linux-2.6.24/crypto/async_tx/async_xor.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/crypto/async_tx/async_xor.c 2008-06-11 17:43:37.000000000 +0200
-@@ -264,7 +264,7 @@
-
- BUG_ON(src_cnt <= 1);
-
-- if (tx) {
-+ if (tx && src_cnt <= device->max_xor) {
- dma_addr_t dma_addr;
- enum dma_data_direction dir;
-
-diff -Nurd linux-2.6.24/crypto/xcbc.c linux-2.6.24-oxe810/crypto/xcbc.c
---- linux-2.6.24/crypto/xcbc.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/crypto/xcbc.c 2008-06-11 17:43:39.000000000 +0200
-@@ -124,6 +124,11 @@
- unsigned int offset = sg[i].offset;
- unsigned int slen = sg[i].length;
-
-+ if (unlikely(slen > nbytes))
-+ slen = nbytes;
-+
-+ nbytes -= slen;
-+
- while (slen > 0) {
- unsigned int len = min(slen, ((unsigned int)(PAGE_SIZE)) - offset);
- char *p = crypto_kmap(pg, 0) + offset;
-@@ -177,7 +182,6 @@
- offset = 0;
- pg++;
- }
-- nbytes-=sg[i].length;
- i++;
- } while (nbytes>0);
-
-diff -Nurd linux-2.6.24/crypto/xts.c linux-2.6.24-oxe810/crypto/xts.c
---- linux-2.6.24/crypto/xts.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/crypto/xts.c 2008-06-11 17:43:39.000000000 +0200
-@@ -77,16 +77,16 @@
- }
-
- struct sinfo {
-- be128 t;
-+ be128 *t;
- struct crypto_tfm *tfm;
- void (*fn)(struct crypto_tfm *, u8 *, const u8 *);
- };
-
- static inline void xts_round(struct sinfo *s, void *dst, const void *src)
- {
-- be128_xor(dst, &s->t, src); /* PP <- T xor P */
-+ be128_xor(dst, s->t, src); /* PP <- T xor P */
- s->fn(s->tfm, dst, dst); /* CC <- E(Key1,PP) */
-- be128_xor(dst, dst, &s->t); /* C <- T xor CC */
-+ be128_xor(dst, dst, s->t); /* C <- T xor CC */
- }
-
- static int crypt(struct blkcipher_desc *d,
-@@ -101,7 +101,6 @@
- .tfm = crypto_cipher_tfm(ctx->child),
- .fn = fn
- };
-- be128 *iv;
- u8 *wsrc;
- u8 *wdst;
-
-@@ -109,20 +108,20 @@
- if (!w->nbytes)
- return err;
-
-+ s.t = (be128 *)w->iv;
- avail = w->nbytes;
-
- wsrc = w->src.virt.addr;
- wdst = w->dst.virt.addr;
-
- /* calculate first value of T */
-- iv = (be128 *)w->iv;
-- tw(crypto_cipher_tfm(ctx->tweak), (void *)&s.t, w->iv);
-+ tw(crypto_cipher_tfm(ctx->tweak), w->iv, w->iv);
-
- goto first;
-
- for (;;) {
- do {
-- gf128mul_x_ble(&s.t, &s.t);
-+ gf128mul_x_ble(s.t, s.t);
-
- first:
- xts_round(&s, wdst, wsrc);
-diff -Nurd linux-2.6.24/drivers/acorn/char/defkeymap-l7200.c linux-2.6.24-oxe810/drivers/acorn/char/defkeymap-l7200.c
---- linux-2.6.24/drivers/acorn/char/defkeymap-l7200.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/acorn/char/defkeymap-l7200.c 2008-06-11 17:49:37.000000000 +0200
-@@ -347,40 +347,40 @@
- };
-
- struct kbdiacruc accent_table[MAX_DIACR] = {
-- {'`', 'A', '\300'}, {'`', 'a', '\340'},
-- {'\'', 'A', '\301'}, {'\'', 'a', '\341'},
-- {'^', 'A', '\302'}, {'^', 'a', '\342'},
-- {'~', 'A', '\303'}, {'~', 'a', '\343'},
-- {'"', 'A', '\304'}, {'"', 'a', '\344'},
-- {'O', 'A', '\305'}, {'o', 'a', '\345'},
-- {'0', 'A', '\305'}, {'0', 'a', '\345'},
-- {'A', 'A', '\305'}, {'a', 'a', '\345'},
-- {'A', 'E', '\306'}, {'a', 'e', '\346'},
-- {',', 'C', '\307'}, {',', 'c', '\347'},
-- {'`', 'E', '\310'}, {'`', 'e', '\350'},
-- {'\'', 'E', '\311'}, {'\'', 'e', '\351'},
-- {'^', 'E', '\312'}, {'^', 'e', '\352'},
-- {'"', 'E', '\313'}, {'"', 'e', '\353'},
-- {'`', 'I', '\314'}, {'`', 'i', '\354'},
-- {'\'', 'I', '\315'}, {'\'', 'i', '\355'},
-- {'^', 'I', '\316'}, {'^', 'i', '\356'},
-- {'"', 'I', '\317'}, {'"', 'i', '\357'},
-- {'-', 'D', '\320'}, {'-', 'd', '\360'},
-- {'~', 'N', '\321'}, {'~', 'n', '\361'},
-- {'`', 'O', '\322'}, {'`', 'o', '\362'},
-- {'\'', 'O', '\323'}, {'\'', 'o', '\363'},
-- {'^', 'O', '\324'}, {'^', 'o', '\364'},
-- {'~', 'O', '\325'}, {'~', 'o', '\365'},
-- {'"', 'O', '\326'}, {'"', 'o', '\366'},
-- {'/', 'O', '\330'}, {'/', 'o', '\370'},
-- {'`', 'U', '\331'}, {'`', 'u', '\371'},
-- {'\'', 'U', '\332'}, {'\'', 'u', '\372'},
-- {'^', 'U', '\333'}, {'^', 'u', '\373'},
-- {'"', 'U', '\334'}, {'"', 'u', '\374'},
-- {'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
-- {'T', 'H', '\336'}, {'t', 'h', '\376'},
-- {'s', 's', '\337'}, {'"', 'y', '\377'},
-- {'s', 'z', '\337'}, {'i', 'j', '\377'},
-+ {'`', 'A', 0300}, {'`', 'a', 0340},
-+ {'\'', 'A', 0301}, {'\'', 'a', 0341},
-+ {'^', 'A', 0302}, {'^', 'a', 0342},
-+ {'~', 'A', 0303}, {'~', 'a', 0343},
-+ {'"', 'A', 0304}, {'"', 'a', 0344},
-+ {'O', 'A', 0305}, {'o', 'a', 0345},
-+ {'0', 'A', 0305}, {'0', 'a', 0345},
-+ {'A', 'A', 0305}, {'a', 'a', 0345},
-+ {'A', 'E', 0306}, {'a', 'e', 0346},
-+ {',', 'C', 0307}, {',', 'c', 0347},
-+ {'`', 'E', 0310}, {'`', 'e', 0350},
-+ {'\'', 'E', 0311}, {'\'', 'e', 0351},
-+ {'^', 'E', 0312}, {'^', 'e', 0352},
-+ {'"', 'E', 0313}, {'"', 'e', 0353},
-+ {'`', 'I', 0314}, {'`', 'i', 0354},
-+ {'\'', 'I', 0315}, {'\'', 'i', 0355},
-+ {'^', 'I', 0316}, {'^', 'i', 0356},
-+ {'"', 'I', 0317}, {'"', 'i', 0357},
-+ {'-', 'D', 0320}, {'-', 'd', 0360},
-+ {'~', 'N', 0321}, {'~', 'n', 0361},
-+ {'`', 'O', 0322}, {'`', 'o', 0362},
-+ {'\'', 'O', 0323}, {'\'', 'o', 0363},
-+ {'^', 'O', 0324}, {'^', 'o', 0364},
-+ {'~', 'O', 0325}, {'~', 'o', 0365},
-+ {'"', 'O', 0326}, {'"', 'o', 0366},
-+ {'/', 'O', 0330}, {'/', 'o', 0370},
-+ {'`', 'U', 0331}, {'`', 'u', 0371},
-+ {'\'', 'U', 0332}, {'\'', 'u', 0372},
-+ {'^', 'U', 0333}, {'^', 'u', 0373},
-+ {'"', 'U', 0334}, {'"', 'u', 0374},
-+ {'\'', 'Y', 0335}, {'\'', 'y', 0375},
-+ {'T', 'H', 0336}, {'t', 'h', 0376},
-+ {'s', 's', 0337}, {'"', 'y', 0377},
-+ {'s', 'z', 0337}, {'i', 'j', 0377},
- };
-
- unsigned int accent_table_size = 68;
-diff -Nurd linux-2.6.24/drivers/acpi/blacklist.c linux-2.6.24-oxe810/drivers/acpi/blacklist.c
---- linux-2.6.24/drivers/acpi/blacklist.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/acpi/blacklist.c 2008-06-11 17:49:40.000000000 +0200
-@@ -208,24 +208,24 @@
- * Disable OSI(Linux) warnings on all "Acer, inc."
- *
- * _OSI(Linux) disables the latest Windows BIOS code:
-+ * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3100"),
- * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5050"),
-+ * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
- * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5580"),
- * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 3010"),
- * _OSI(Linux) effect unknown:
- * DMI_MATCH(DMI_PRODUCT_NAME, "Ferrari 5000"),
- */
-- {
-- .callback = dmi_disable_osi_linux,
-- .ident = "Acer, inc.",
-- .matches = {
-- DMI_MATCH(DMI_SYS_VENDOR, "Acer, inc."),
-- },
-- },
-+ /*
-+ * note that dmi_check_system() uses strstr()
-+ * to match sub-strings rather than !strcmp(),
-+ * so "Acer" below matches "Acer, inc." above.
-+ */
- /*
- * Disable OSI(Linux) warnings on all "Acer"
- *
- * _OSI(Linux) effect unknown:
-- * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
-+ * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"),
- * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
- * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720Z"),
- * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5520"),
-@@ -300,7 +300,7 @@
- DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
- },
- },
-- { /* OSI(Linux) touches USB, breaks suspend to disk */
-+ { /* OSI(Linux) touches USB, unknown side-effect */
- .callback = dmi_disable_osi_linux,
- .ident = "Dell Dimension 5150",
- .matches = {
-@@ -474,6 +474,11 @@
- *
- * _OSI(Linux) confirmed to be a NOP:
- * DMI_MATCH(DMI_PRODUCT_NAME, "P1-J150B"),
-+ * with DMI_MATCH(DMI_BOARD_NAME, "ROCKY"),
-+ *
-+ * unknown:
-+ * DMI_MATCH(DMI_PRODUCT_NAME, "S1-MDGDG"),
-+ * with DMI_MATCH(DMI_BOARD_NAME, "ROCKY"),
- */
- {
- .callback = dmi_disable_osi_linux,
-diff -Nurd linux-2.6.24/drivers/acpi/osl.c linux-2.6.24-oxe810/drivers/acpi/osl.c
---- linux-2.6.24/drivers/acpi/osl.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/acpi/osl.c 2008-06-11 17:49:40.000000000 +0200
-@@ -120,7 +120,7 @@
- */
- #define OSI_LINUX_ENABLE 0
-
--struct osi_linux {
-+static struct osi_linux {
- unsigned int enable:1;
- unsigned int dmi:1;
- unsigned int cmdline:1;
-@@ -1213,24 +1213,24 @@
- *
- * Returns 0 on success
- */
--int acpi_dmi_dump(void)
-+static int acpi_dmi_dump(void)
- {
-
- if (!dmi_available)
- return -1;
-
- printk(KERN_NOTICE PREFIX "DMI System Vendor: %s\n",
-- dmi_get_slot(DMI_SYS_VENDOR));
-+ dmi_get_system_info(DMI_SYS_VENDOR));
- printk(KERN_NOTICE PREFIX "DMI Product Name: %s\n",
-- dmi_get_slot(DMI_PRODUCT_NAME));
-+ dmi_get_system_info(DMI_PRODUCT_NAME));
- printk(KERN_NOTICE PREFIX "DMI Product Version: %s\n",
-- dmi_get_slot(DMI_PRODUCT_VERSION));
-+ dmi_get_system_info(DMI_PRODUCT_VERSION));
- printk(KERN_NOTICE PREFIX "DMI Board Name: %s\n",
-- dmi_get_slot(DMI_BOARD_NAME));
-+ dmi_get_system_info(DMI_BOARD_NAME));
- printk(KERN_NOTICE PREFIX "DMI BIOS Vendor: %s\n",
-- dmi_get_slot(DMI_BIOS_VENDOR));
-+ dmi_get_system_info(DMI_BIOS_VENDOR));
- printk(KERN_NOTICE PREFIX "DMI BIOS Date: %s\n",
-- dmi_get_slot(DMI_BIOS_DATE));
-+ dmi_get_system_info(DMI_BIOS_DATE));
-
- return 0;
- }
-diff -Nurd linux-2.6.24/drivers/ata/Kconfig linux-2.6.24-oxe810/drivers/ata/Kconfig
---- linux-2.6.24/drivers/ata/Kconfig 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/Kconfig 2008-06-11 17:50:32.000000000 +0200
-@@ -182,15 +182,49 @@
- firmware in the BIOS. This driver can sometimes handle
- otherwise unsupported hardware.
-
-+config SATA_OX800
-+ bool "Oxford Semiconductor OX800 SATA support"
-+ depends on ARCH_OXNAS && OXNAS_VERSION_0X800
-+ default n
-+ help
-+ This option enables support for the 924 based sata core
-+
-+config SATA_OX810
-+ bool "Oxford Semiconductor OX810 SATA support"
-+ depends on ARCH_OXNAS && OXNAS_VERSION_0X810
-+ default n
-+ help
-+ This option enables support for the 934 based sata core
-+
- config SATA_FSL
- tristate "Freescale 3.0Gbps SATA support"
- depends on PPC_MPC837x
- help
- This option enables support for Freescale 3.0Gbps SATA controller.
- It can be found on MPC837x and MPC8315.
--
- If unsure, say N.
-
-+config SATA_OXNAS_SINGLE_SATA
-+ bool "Force OXNAS family devices to only use one SATA port"
-+ depends on SATA_OX800 || SATA_OX810
-+ default n
-+ help
-+ Prevents the ox800sata module from registering its second sata port, this
-+ reduces startup time on systems where only one port is physically present
-+ on the board/chip periphery.
-+
-+config SATA_OXNAS_DISK_LIGHT
-+ bool "Whether OXNAS family device should use a SATA disk activity light"
-+ depends on SATA_OX800 || SATA_OX810
-+ default n
-+
-+config SATA_OXNAS_DISK_LIGHT_GPIO_LINE
-+ int "GPIO line of the disk light"
-+ depends on SATA_OXNAS_DISK_LIGHT
-+ default 29
-+ help
-+ Selects the GPIO line of the disk activity light.
-+
- config PATA_ALI
- tristate "ALi PATA support (Experimental)"
- depends on PCI && EXPERIMENTAL
-diff -Nurd linux-2.6.24/drivers/ata/Makefile linux-2.6.24-oxe810/drivers/ata/Makefile
---- linux-2.6.24/drivers/ata/Makefile 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/Makefile 2008-06-11 17:50:32.000000000 +0200
-@@ -18,6 +18,8 @@
- obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
- obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
- obj-$(CONFIG_SATA_FSL) += sata_fsl.o
-+obj-$(CONFIG_SATA_OX800) += ox800sata.o
-+obj-$(CONFIG_SATA_OX810) += ox810sata.o
-
- obj-$(CONFIG_PATA_ALI) += pata_ali.o
- obj-$(CONFIG_PATA_AMD) += pata_amd.o
-diff -Nurd linux-2.6.24/drivers/ata/libata-core.c linux-2.6.24-oxe810/drivers/ata/libata-core.c
---- linux-2.6.24/drivers/ata/libata-core.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/libata-core.c 2008-06-11 17:50:32.000000000 +0200
-@@ -140,6 +140,8 @@
- */
- void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis)
- {
-+
-+ VPRINTK("\n");
- fis[0] = 0x27; /* Register - Host to Device FIS */
- fis[1] = pmp & 0xf; /* Port multiplier number*/
- if (is_cmd)
-@@ -182,6 +184,8 @@
-
- void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf)
- {
-+
-+ VPRINTK("\n");
- tf->command = fis[2]; /* status */
- tf->feature = fis[3]; /* error */
-
-@@ -245,6 +249,8 @@
-
- int index, fua, lba48, write;
-
-+
-+ VPRINTK("\n");
- fua = (tf->flags & ATA_TFLAG_FUA) ? 4 : 0;
- lba48 = (tf->flags & ATA_TFLAG_LBA48) ? 2 : 0;
- write = (tf->flags & ATA_TFLAG_WRITE) ? 1 : 0;
-@@ -288,6 +294,8 @@
- {
- u64 block = 0;
-
-+
-+ VPRINTK("\n");
- if (tf->flags & ATA_TFLAG_LBA) {
- if (tf->flags & ATA_TFLAG_LBA48) {
- block |= (u64)tf->hob_lbah << 40;
-@@ -336,6 +344,8 @@
- u64 block, u32 n_block, unsigned int tf_flags,
- unsigned int tag)
- {
-+
-+ VPRINTK("\n");
- tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
- tf->flags |= tf_flags;
-
-@@ -454,6 +464,8 @@
- unsigned int mwdma_mask,
- unsigned int udma_mask)
- {
-+
-+ VPRINTK("\n");
- return ((pio_mask << ATA_SHIFT_PIO) & ATA_MASK_PIO) |
- ((mwdma_mask << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA) |
- ((udma_mask << ATA_SHIFT_UDMA) & ATA_MASK_UDMA);
-@@ -474,6 +486,7 @@
- unsigned int *mwdma_mask,
- unsigned int *udma_mask)
- {
-+ VPRINTK("\n");
- if (pio_mask)
- *pio_mask = (xfer_mask & ATA_MASK_PIO) >> ATA_SHIFT_PIO;
- if (mwdma_mask)
-@@ -510,6 +523,7 @@
- int highbit = fls(xfer_mask) - 1;
- const struct ata_xfer_ent *ent;
-
-+ VPRINTK("\n");
- for (ent = ata_xfer_tbl; ent->shift >= 0; ent++)
- if (highbit >= ent->shift && highbit < ent->shift + ent->bits)
- return ent->base + highbit - ent->shift;
-@@ -532,6 +546,7 @@
- {
- const struct ata_xfer_ent *ent;
-
-+ VPRINTK("\n");
- for (ent = ata_xfer_tbl; ent->shift >= 0; ent++)
- if (xfer_mode >= ent->base && xfer_mode < ent->base + ent->bits)
- return 1 << (ent->shift + xfer_mode - ent->base);
-@@ -554,6 +569,7 @@
- {
- const struct ata_xfer_ent *ent;
-
-+ VPRINTK("\n");
- for (ent = ata_xfer_tbl; ent->shift >= 0; ent++)
- if (xfer_mode >= ent->base && xfer_mode < ent->base + ent->bits)
- return ent->shift;
-@@ -600,6 +616,7 @@
- };
- int highbit;
-
-+ VPRINTK("\n");
- highbit = fls(xfer_mask) - 1;
- if (highbit >= 0 && highbit < ARRAY_SIZE(xfer_mode_str))
- return xfer_mode_str[highbit];
-@@ -613,6 +630,7 @@
- "3.0 Gbps",
- };
-
-+ VPRINTK("\n");
- if (spd == 0 || (spd - 1) >= ARRAY_SIZE(spd_str))
- return "<unknown>";
- return spd_str[spd - 1];
-@@ -620,6 +638,7 @@
-
- void ata_dev_disable(struct ata_device *dev)
- {
-+ VPRINTK("\n");
- if (ata_dev_enabled(dev)) {
- if (ata_msg_drv(dev->link->ap))
- ata_dev_printk(dev, KERN_WARNING, "disabled\n");
-@@ -638,6 +657,7 @@
- unsigned int err_mask;
- int rc;
-
-+ VPRINTK("\n");
- /*
- * disallow DIPM for drivers which haven't set
- * ATA_FLAG_IPM. This is because when DIPM is enabled,
-@@ -732,6 +752,7 @@
- int rc = 0;
- struct ata_port *ap = dev->link->ap;
-
-+ VPRINTK("\n");
- /* set HIPM first, then DIPM */
- if (ap->ops->enable_pm)
- rc = ap->ops->enable_pm(ap, policy);
-@@ -764,6 +785,7 @@
- {
- struct ata_port *ap = dev->link->ap;
-
-+ VPRINTK("\n");
- ata_dev_set_dipm(dev, MAX_PERFORMANCE);
- if (ap->ops->disable_pm)
- ap->ops->disable_pm(ap);
-@@ -772,6 +794,7 @@
-
- void ata_lpm_schedule(struct ata_port *ap, enum link_pm policy)
- {
-+ VPRINTK("\n");
- ap->pm_policy = policy;
- ap->link.eh_info.action |= ATA_EHI_LPM;
- ap->link.eh_info.flags |= ATA_EHI_NO_AUTOPSY;
-@@ -786,6 +809,7 @@
- struct ata_device *dev;
- int i;
-
-+ VPRINTK("\n");
- for (i = 0; i < host->n_ports; i++) {
- ap = host->ports[i];
- ata_port_for_each_link(link, ap) {
-@@ -799,6 +823,7 @@
- {
- int i;
-
-+ VPRINTK("\n");
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
- ata_lpm_schedule(ap, ap->pm_policy);
-@@ -828,6 +853,11 @@
- static unsigned int ata_devchk(struct ata_port *ap, unsigned int device)
- {
- struct ata_ioports *ioaddr = &ap->ioaddr;
-+ VPRINTK("\n");
-+ if (ap->ops->dev_chk) {
-+ return ap->ops->dev_chk(ap,device);
-+ } else {
-+
- u8 nsect, lbal;
-
- ap->ops->dev_select(ap, device);
-@@ -848,6 +878,7 @@
- return 1; /* we found a device */
-
- return 0; /* nothing found */
-+ }
- }
-
- /**
-@@ -938,6 +969,7 @@
- unsigned int class;
- u8 err;
-
-+ VPRINTK("\n");
- ap->ops->dev_select(ap, dev->devno);
-
- memset(&tf, 0, sizeof(tf));
-@@ -998,6 +1030,7 @@
- {
- unsigned int c;
-
-+ VPRINTK("\n");
- while (len > 0) {
- c = id[ofs] >> 8;
- *s = c;
-@@ -1031,6 +1064,7 @@
- {
- unsigned char *p;
-
-+ VPRINTK("\n");
- WARN_ON(!(len & 1));
-
- ata_id_string(id, s, ofs, len - 1);
-@@ -1043,6 +1077,7 @@
-
- static u64 ata_id_n_sectors(const u16 *id)
- {
-+ VPRINTK("\n");
- if (ata_id_has_lba(id)) {
- if (ata_id_has_lba48(id))
- return ata_id_u64(id, 100);
-@@ -1060,6 +1095,7 @@
- {
- u64 sectors = 0;
-
-+ VPRINTK("\n");
- sectors |= ((u64)(tf->hob_lbah & 0xff)) << 40;
- sectors |= ((u64)(tf->hob_lbam & 0xff)) << 32;
- sectors |= (tf->hob_lbal & 0xff) << 24;
-@@ -1074,6 +1110,7 @@
- {
- u64 sectors = 0;
-
-+ VPRINTK("\n");
- sectors |= (tf->device & 0x0f) << 24;
- sectors |= (tf->lbah & 0xff) << 16;
- sectors |= (tf->lbam & 0xff) << 8;
-@@ -1100,6 +1137,7 @@
- struct ata_taskfile tf;
- int lba48 = ata_id_has_lba48(dev->id);
-
-+ VPRINTK("\n");
- ata_tf_init(dev, &tf);
-
- /* always clear all address registers */
-@@ -1150,6 +1188,7 @@
- struct ata_taskfile tf;
- int lba48 = ata_id_has_lba48(dev->id);
-
-+ VPRINTK("\n");
- new_sectors--;
-
- ata_tf_init(dev, &tf);
-@@ -1208,6 +1247,7 @@
- u64 native_sectors;
- int rc;
-
-+ VPRINTK("\n");
- /* do we need to do it? */
- if (dev->class != ATA_DEV_ATA ||
- !ata_id_has_lba(dev->id) || !ata_id_hpa_enabled(dev->id) ||
-@@ -1305,6 +1345,7 @@
- unsigned int mask;
- u8 mode;
-
-+ VPRINTK("\n");
- /* Pack the DMA modes */
- mask = ((dev->id[63] >> 8) << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA;
- if (dev->id[53] & 0x04)
-@@ -1341,6 +1382,7 @@
- */
- void ata_noop_dev_select(struct ata_port *ap, unsigned int device)
- {
-+ VPRINTK("\n");
- }
-
-
-@@ -1363,6 +1405,7 @@
- {
- u8 tmp;
-
-+ VPRINTK("\n");
- if (device == 0)
- tmp = ATA_DEVICE_OBS;
- else
-@@ -1394,6 +1437,7 @@
- void ata_dev_select(struct ata_port *ap, unsigned int device,
- unsigned int wait, unsigned int can_sleep)
- {
-+ VPRINTK("\n");
- if (ata_msg_probe(ap))
- ata_port_printk(ap, KERN_INFO, "ata_dev_select: ENTER, "
- "device %u, wait %u\n", device, wait);
-@@ -1469,6 +1513,7 @@
- unsigned int pio_mask, mwdma_mask, udma_mask;
-
- /* Usual case. Word 53 indicates word 64 is valid */
-+ VPRINTK("\n");
- if (id[ATA_ID_FIELD_VALID] & (1 << 1)) {
- pio_mask = id[ATA_ID_PIO_MODES] & 0x03;
- pio_mask <<= 3;
-@@ -1571,6 +1616,7 @@
- {
- struct completion *waiting = qc->private_data;
-
-+ VPRINTK("\n");
- complete(waiting);
- }
-
-@@ -1613,6 +1659,7 @@
- unsigned int err_mask;
- int rc;
-
-+ VPRINTK("\n");
- spin_lock_irqsave(ap->lock, flags);
-
- /* no internal command while frozen */
-@@ -1729,7 +1776,11 @@
- *tf = qc->result_tf;
- err_mask = qc->err_mask;
-
-- ata_qc_free(qc);
-+ if (ap->ops->qc_free) {
-+ ap->ops->qc_free(qc);
-+ } else {
-+ ata_qc_free(qc);
-+ }
- link->active_tag = preempted_tag;
- link->sactive = preempted_sactive;
- ap->qc_active = preempted_qc_active;
-@@ -1783,6 +1834,7 @@
- struct scatterlist *psg = NULL, sg;
- unsigned int n_elem = 0;
-
-+ VPRINTK("\n");
- if (dma_dir != DMA_NONE) {
- WARN_ON(!buf);
- sg_init_one(&sg, buf, buflen);
-@@ -1812,6 +1864,7 @@
- {
- struct ata_taskfile tf;
-
-+ VPRINTK("\n");
- ata_tf_init(dev, &tf);
-
- tf.command = cmd;
-@@ -1831,6 +1884,7 @@
-
- unsigned int ata_pio_need_iordy(const struct ata_device *adev)
- {
-+ VPRINTK("\n");
- /* Controller doesn't support IORDY. Probably a pointless check
- as the caller should know this */
- if (adev->link->ap->flags & ATA_FLAG_NO_IORDY)
-@@ -1854,6 +1908,7 @@
-
- static u32 ata_pio_mask_no_iordy(const struct ata_device *adev)
- {
-+ VPRINTK("\n");
- /* If we have no drive specific rule, then PIO 2 is non IORDY */
- if (adev->id[ATA_ID_FIELD_VALID] & 2) { /* EIDE */
- u16 pio = adev->id[ATA_ID_EIDE_PIO];
-@@ -1900,12 +1955,15 @@
- int may_fallback = 1, tried_spinup = 0;
- int rc;
-
-+ VPRINTK("\n");
- if (ata_msg_ctl(ap))
- ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__);
-
- ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */
- retry:
- ata_tf_init(dev, &tf);
-+
-+ tf.device |= ATA_LBA ;
-
- switch (class) {
- case ATA_DEV_ATA:
-@@ -2043,6 +2101,7 @@
- static inline u8 ata_dev_knobble(struct ata_device *dev)
- {
- struct ata_port *ap = dev->link->ap;
-+ VPRINTK("\n");
- return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id)));
- }
-
-@@ -2052,6 +2111,7 @@
- struct ata_port *ap = dev->link->ap;
- int hdepth = 0, ddepth = ata_id_queue_depth(dev->id);
-
-+ VPRINTK("\n");
- if (!ata_id_has_ncq(dev->id)) {
- desc[0] = '\0';
- return;
-@@ -2096,6 +2156,7 @@
- char modelbuf[ATA_ID_PROD_LEN+1];
- int rc;
-
-+ VPRINTK("\n");
- if (!ata_dev_enabled(dev) && ata_msg_info(ap)) {
- ata_dev_printk(dev, KERN_INFO, "%s: ENTER/EXIT -- nodev\n",
- __FUNCTION__);
-@@ -2334,7 +2395,7 @@
- }
-
- if (ap->ops->dev_config)
-- ap->ops->dev_config(dev);
-+ ap->ops->dev_config(ap, dev);
-
- if (ata_msg_probe(ap))
- ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n",
-@@ -2358,6 +2419,7 @@
-
- int ata_cable_40wire(struct ata_port *ap)
- {
-+ VPRINTK("\n");
- return ATA_CBL_PATA40;
- }
-
-@@ -2371,6 +2433,7 @@
-
- int ata_cable_80wire(struct ata_port *ap)
- {
-+ VPRINTK("\n");
- return ATA_CBL_PATA80;
- }
-
-@@ -2383,6 +2446,7 @@
-
- int ata_cable_unknown(struct ata_port *ap)
- {
-+ VPRINTK("\n");
- return ATA_CBL_PATA_UNK;
- }
-
-@@ -2395,6 +2459,7 @@
-
- int ata_cable_sata(struct ata_port *ap)
- {
-+ VPRINTK("\n");
- return ATA_CBL_SATA;
- }
-
-@@ -2420,6 +2485,7 @@
- int rc;
- struct ata_device *dev;
-
-+ VPRINTK("\n");
- ata_port_probe(ap);
-
- ata_link_for_each_dev(dev, &ap->link)
-@@ -2560,6 +2626,7 @@
-
- void ata_port_probe(struct ata_port *ap)
- {
-+ VPRINTK("\n");
- ap->flags &= ~ATA_FLAG_DISABLED;
- }
-
-@@ -2576,6 +2643,7 @@
- {
- u32 sstatus, scontrol, tmp;
-
-+ VPRINTK("\n");
- if (sata_scr_read(link, SCR_STATUS, &sstatus))
- return;
- sata_scr_read(link, SCR_CONTROL, &scontrol);
-@@ -2604,6 +2672,7 @@
- {
- struct ata_link *link = adev->link;
- struct ata_device *pair = &link->device[1 - adev->devno];
-+ VPRINTK("\n");
- if (!ata_dev_enabled(pair))
- return NULL;
- return pair;
-@@ -2624,6 +2693,7 @@
-
- void ata_port_disable(struct ata_port *ap)
- {
-+ VPRINTK("\n");
- ap->link.device[0].class = ATA_DEV_NONE;
- ap->link.device[1].class = ATA_DEV_NONE;
- ap->flags |= ATA_FLAG_DISABLED;
-@@ -2648,6 +2718,7 @@
- u32 sstatus, spd, mask;
- int rc, highbit;
-
-+ VPRINTK("\n");
- if (!sata_scr_valid(link))
- return -EOPNOTSUPP;
-
-@@ -2693,6 +2764,7 @@
- struct ata_link *host_link = &link->ap->link;
- u32 limit, target, spd;
-
-+ VPRINTK("\n");
- limit = link->sata_spd_limit;
-
- /* Don't configure downstream link faster than upstream link.
-@@ -2732,6 +2804,7 @@
- {
- u32 scontrol;
-
-+ VPRINTK("\n");
- if (sata_scr_read(link, SCR_CONTROL, &scontrol))
- return 1;
-
-@@ -2756,6 +2829,7 @@
- u32 scontrol;
- int rc;
-
-+ VPRINTK("\n");
- if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
- return rc;
-
-@@ -2822,6 +2896,7 @@
-
- static void ata_timing_quantize(const struct ata_timing *t, struct ata_timing *q, int T, int UT)
- {
-+ VPRINTK("\n");
- q->setup = EZ(t->setup * 1000, T);
- q->act8b = EZ(t->act8b * 1000, T);
- q->rec8b = EZ(t->rec8b * 1000, T);
-@@ -2835,6 +2910,7 @@
- void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b,
- struct ata_timing *m, unsigned int what)
- {
-+ VPRINTK("\n");
- if (what & ATA_TIMING_SETUP ) m->setup = max(a->setup, b->setup);
- if (what & ATA_TIMING_ACT8B ) m->act8b = max(a->act8b, b->act8b);
- if (what & ATA_TIMING_REC8B ) m->rec8b = max(a->rec8b, b->rec8b);
-@@ -2849,6 +2925,7 @@
- {
- const struct ata_timing *t;
-
-+ VPRINTK("\n");
- for (t = ata_timing; t->mode != speed; t++)
- if (t->mode == 0xFF)
- return NULL;
-@@ -2861,6 +2938,7 @@
- const struct ata_timing *s;
- struct ata_timing p;
-
-+ VPRINTK("\n");
- /*
- * Find the mode.
- */
-@@ -2948,6 +3026,7 @@
- unsigned int pio_mask, mwdma_mask, udma_mask;
- int quiet, highbit;
-
-+ VPRINTK("\n");
- quiet = !!(sel & ATA_DNXFER_QUIET);
- sel &= ~ATA_DNXFER_QUIET;
-
-@@ -3021,6 +3100,7 @@
- unsigned int err_mask;
- int rc;
-
-+ VPRINTK("\n");
- dev->flags &= ~ATA_DFLAG_PIO;
- if (dev->xfer_shift == ATA_SHIFT_PIO)
- dev->flags |= ATA_DFLAG_PIO;
-@@ -3087,6 +3167,7 @@
- struct ata_device *dev;
- int rc = 0, used_dma = 0, found = 0;
-
-+ VPRINTK("\n");
- /* step 1: calculate xfer_mask */
- ata_link_for_each_dev(dev, link) {
- unsigned int pio_mask, dma_mask;
-@@ -3191,6 +3272,7 @@
- {
- struct ata_port *ap = link->ap;
-
-+ VPRINTK("\n");
- /* has private set_mode? */
- if (ap->ops->set_mode)
- return ap->ops->set_mode(link, r_failed_dev);
-@@ -3213,6 +3295,7 @@
- static inline void ata_tf_to_host(struct ata_port *ap,
- const struct ata_taskfile *tf)
- {
-+ VPRINTK("\n");
- ap->ops->tf_load(ap, tf);
- ap->ops->exec_command(ap, tf);
- }
-@@ -3238,6 +3321,7 @@
- unsigned long timer_start, timeout;
- u8 status;
-
-+ VPRINTK("\n");
- status = ata_busy_wait(ap, ATA_BUSY, 300);
- timer_start = jiffies;
- timeout = timer_start + tmout_pat;
-@@ -3291,6 +3375,7 @@
- {
- unsigned long until = jiffies + ATA_TMOUT_FF_WAIT;
-
-+ VPRINTK("\n");
- if (time_before(until, deadline))
- deadline = until;
-
-@@ -3346,6 +3431,7 @@
- unsigned long start = jiffies;
- int warned = 0;
-
-+ VPRINTK("\n");
- while (1) {
- u8 status = ata_chk_status(ap);
- unsigned long now = jiffies;
-@@ -3377,6 +3463,7 @@
- unsigned int dev1 = devmask & (1 << 1);
- int rc, ret = 0;
-
-+ VPRINTK("\n");
- /* if device 0 was found in ata_devchk, wait for its
- * BSY bit to clear
- */
-@@ -3432,19 +3519,36 @@
- static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
- unsigned long deadline)
- {
-- struct ata_ioports *ioaddr = &ap->ioaddr;
-+ /* create a task file to control ctl register */
-+ struct ata_taskfile tf ;
-
- DPRINTK("ata%u: bus reset via SRST\n", ap->print_id);
-
-+ memset(&tf, 0, sizeof(tf));
-+#if 0
- /* software reset. causes dev0 to be selected */
-- iowrite8(ap->ctl, ioaddr->ctl_addr);
-+ tf.ctl = ap->ctl;
-+ ap->ops->tf_load(ap,&tf);
- udelay(20); /* FIXME: flush */
-- iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
-+
-+ tf.ctl = ap->ctl | ATA_SRST;
-+ ap->ops->tf_load(ap,&tf);
- udelay(20); /* FIXME: flush */
-- iowrite8(ap->ctl, ioaddr->ctl_addr);
-+
-+ tf.ctl = ap->ctl;
-+ ap->ops->tf_load(ap,&tf);
-
-- /* wait a while before checking status */
-- ata_wait_after_reset(ap, deadline);
-+ /* spec mandates ">= 2ms" before checking status.
-+ * We wait 150ms, because that was the magic delay used for
-+ * ATAPI devices in Hale Landis's ATADRVR, for the period of time
-+ * between when the ATA command register is written, and then
-+ * status is checked. Because waiting for "a while" before
-+ * checking status is fine, post SRST, we perform this magic
-+ * delay here as well.
-+ *
-+ * Old drivers/ide uses the 2mS rule and then waits for ready
-+ */
-+ msleep(150);
-
- /* Before we perform post reset processing we want to see if
- * the bus shows 0xFF because the odd clown forgets the D7
-@@ -3452,7 +3556,7 @@
- */
- if (ata_chk_status(ap) == 0xFF)
- return -ENODEV;
--
-+#endif
- return ata_bus_post_reset(ap, devmask, deadline);
- }
-
-@@ -3479,7 +3583,6 @@
- void ata_bus_reset(struct ata_port *ap)
- {
- struct ata_device *device = ap->link.device;
-- struct ata_ioports *ioaddr = &ap->ioaddr;
- unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
- u8 err;
- unsigned int dev0, dev1 = 0, devmask = 0;
-@@ -3530,8 +3633,11 @@
- goto err_out;
-
- if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) {
-+ /** @todo fix by using tf/tf_load as in ata_bus_softreset */
-+ #if 0
- /* set up device control for ATA_FLAG_SATA_RESET */
- iowrite8(ap->ctl, ioaddr->ctl_addr);
-+ #endif
- }
-
- DPRINTK("EXIT\n");
-@@ -3575,6 +3681,7 @@
- u32 last, cur;
- int rc;
-
-+ VPRINTK("\n");
- t = jiffies + msecs_to_jiffies(params[2]);
- if (time_before(t, deadline))
- deadline = t;
-@@ -3633,6 +3740,7 @@
- u32 scontrol;
- int rc;
-
-+ VPRINTK("\n");
- if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
- return rc;
-
-@@ -3673,6 +3781,7 @@
- const unsigned long *timing = sata_ehc_deb_timing(ehc);
- int rc;
-
-+ VPRINTK("\n");
- /* handle link resume */
- if ((ehc->i.flags & ATA_EHI_RESUME_LINK) &&
- (link->flags & ATA_LFLAG_HRST_TO_RESUME))
-@@ -3939,9 +4048,12 @@
- return;
- }
-
-+ /** @todo fix by using tf/tf_load as in ata_bus_softreset */
-+ #if 0
- /* set up device control */
- if (ap->ioaddr.ctl_addr)
- iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
-+ #endif
-
- DPRINTK("EXIT\n");
- }
-@@ -3969,6 +4081,7 @@
- unsigned char model[2][ATA_ID_PROD_LEN + 1];
- unsigned char serial[2][ATA_ID_SERNO_LEN + 1];
-
-+ VPRINTK("\n");
- if (dev->class != new_class) {
- ata_dev_printk(dev, KERN_INFO, "class mismatch %d != %d\n",
- dev->class, new_class);
-@@ -4015,6 +4128,7 @@
- u16 *id = (void *)dev->link->ap->sector_buf;
- int rc;
-
-+ VPRINTK("\n");
- /* read ID data */
- rc = ata_dev_read_id(dev, &class, readid_flags, id);
- if (rc)
-@@ -4049,6 +4163,7 @@
- u64 n_sectors = dev->n_sectors;
- int rc;
-
-+ VPRINTK("\n");
- if (!ata_dev_enabled(dev))
- return -ENODEV;
-
-@@ -4186,6 +4301,7 @@
- const char *p;
- int len;
-
-+ VPRINTK("\n");
- /*
- * check for trailing wildcard: *\0
- */
-@@ -4210,6 +4326,7 @@
- unsigned char model_rev[ATA_ID_FW_REV_LEN + 1];
- const struct ata_blacklist_entry *ad = ata_device_blacklist;
-
-+ VPRINTK("\n");
- ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
- ata_id_c_string(dev->id, model_rev, ATA_ID_FW_REV, sizeof(model_rev));
-
-@@ -4227,6 +4344,7 @@
-
- static int ata_dma_blacklisted(const struct ata_device *dev)
- {
-+ VPRINTK("\n");
- /* We don't support polling DMA.
- * DMA blacklist those ATAPI devices with CDB-intr (and use PIO)
- * if the LLDD handles only interrupts in the HSM_ST_LAST state.
-@@ -4247,6 +4365,7 @@
-
- static int ata_is_40wire(struct ata_device *dev)
- {
-+ VPRINTK("\n");
- if (dev->horkage & ATA_HORKAGE_IVB)
- return ata_drive_40wire_relaxed(dev->id);
- return ata_drive_40wire(dev->id);
-@@ -4271,6 +4390,7 @@
- struct ata_host *host = ap->host;
- unsigned long xfer_mask;
-
-+ VPRINTK("\n");
- /* controller modes available */
- xfer_mask = ata_pack_xfermask(ap->pio_mask,
- ap->mwdma_mask, ap->udma_mask);
-@@ -4525,6 +4645,7 @@
- struct scatterlist *sg;
- unsigned int idx;
-
-+ VPRINTK("\n");
- WARN_ON(qc->__sg == NULL);
- WARN_ON(qc->n_elem == 0 && qc->pad_len == 0);
-
-@@ -4579,6 +4700,7 @@
- struct scatterlist *sg;
- unsigned int idx;
-
-+ VPRINTK("\n");
- WARN_ON(qc->__sg == NULL);
- WARN_ON(qc->n_elem == 0 && qc->pad_len == 0);
-
-@@ -4640,6 +4762,7 @@
- {
- struct ata_port *ap = qc->ap;
-
-+ VPRINTK("\n");
- /* Don't allow DMA if it isn't multiple of 16 bytes. Quite a
- * few ATAPI devices choke on such DMA requests.
- */
-@@ -4669,6 +4792,7 @@
- */
- static int atapi_qc_may_overflow(struct ata_queued_cmd *qc)
- {
-+ VPRINTK("\n");
- if (qc->tf.protocol != ATA_PROT_ATAPI &&
- qc->tf.protocol != ATA_PROT_ATAPI_DMA)
- return 0;
-@@ -4708,6 +4832,7 @@
- {
- struct ata_link *link = qc->dev->link;
-
-+ VPRINTK("\n");
- if (qc->tf.protocol == ATA_PROT_NCQ) {
- if (!ata_tag_valid(link->active_tag))
- return 0;
-@@ -4730,6 +4855,7 @@
- */
- void ata_qc_prep(struct ata_queued_cmd *qc)
- {
-+ VPRINTK("\n");
- if (!(qc->flags & ATA_QCFLAG_DMAMAP))
- return;
-
-@@ -4747,6 +4873,7 @@
- */
- void ata_dumb_qc_prep(struct ata_queued_cmd *qc)
- {
-+ VPRINTK("\n");
- if (!(qc->flags & ATA_QCFLAG_DMAMAP))
- return;
-
-@@ -4770,6 +4897,7 @@
-
- void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
- {
-+ VPRINTK("\n");
- qc->flags |= ATA_QCFLAG_SINGLE;
-
- qc->__sg = &qc->sgent;
-@@ -4799,6 +4927,7 @@
- void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
- unsigned int n_elem)
- {
-+ VPRINTK("\n");
- qc->flags |= ATA_QCFLAG_SG;
- qc->__sg = sg;
- qc->n_elem = n_elem;
-@@ -4827,6 +4956,7 @@
- dma_addr_t dma_address;
- int trim_sg = 0;
-
-+ VPRINTK("\n");
- /* we must lengthen transfers to end on a 32-bit boundary */
- qc->pad_len = sg->length & 3;
- if (qc->pad_len) {
-@@ -5001,6 +5131,7 @@
- struct ata_port *ap = adev->link->ap;
- unsigned int words = buflen >> 1;
-
-+ VPRINTK("\n");
- /* Transfer multiple of 2 bytes */
- if (write_data)
- iowrite16_rep(ap->ioaddr.data_addr, buf, words);
-@@ -5039,6 +5170,7 @@
- unsigned int buflen, int write_data)
- {
- unsigned long flags;
-+ VPRINTK("\n");
- local_irq_save(flags);
- ata_data_xfer(adev, buf, buflen, write_data);
- local_irq_restore(flags);
-@@ -5063,6 +5195,7 @@
- unsigned int offset;
- unsigned char *buf;
-
-+ VPRINTK("\n");
- if (qc->curbytes == qc->nbytes - qc->sect_size)
- ap->hsm_task_state = HSM_ST_LAST;
-
-@@ -5114,6 +5247,7 @@
-
- static void ata_pio_sectors(struct ata_queued_cmd *qc)
- {
-+ VPRINTK("\n");
- if (is_multi_taskfile(&qc->tf)) {
- /* READ/WRITE MULTIPLE */
- unsigned int nsect;
-@@ -5187,6 +5321,7 @@
- unsigned char *buf;
- unsigned int offset, count;
-
-+ VPRINTK("\n");
- next_sg:
- sg = qc->cursg;
- if (unlikely(!sg)) {
-@@ -5287,6 +5422,7 @@
- unsigned int ireason, bc_lo, bc_hi, bytes;
- int i_write, do_write = (qc->tf.flags & ATA_TFLAG_WRITE) ? 1 : 0;
-
-+ VPRINTK("\n");
- /* Abuse qc->result_tf for temp storage of intermediate TF
- * here to save some kernel stack usage.
- * For normal completion, qc->result_tf is not relevant. For
-@@ -5333,6 +5469,7 @@
-
- static inline int ata_hsm_ok_in_wq(struct ata_port *ap, struct ata_queued_cmd *qc)
- {
-+ VPRINTK("\n");
- if (qc->tf.flags & ATA_TFLAG_POLLING)
- return 1;
-
-@@ -5365,6 +5502,7 @@
- struct ata_port *ap = qc->ap;
- unsigned long flags;
-
-+ VPRINTK("\n");
- if (ap->ops->error_handler) {
- if (in_wq) {
- spin_lock_irqsave(ap->lock, flags);
-@@ -5415,6 +5553,7 @@
- unsigned long flags = 0;
- int poll_next;
-
-+ VPRINTK("\n");
- WARN_ON((qc->flags & ATA_QCFLAG_ACTIVE) == 0);
-
- /* Make sure ata_qc_issue_prot() does not throw things
-@@ -5649,6 +5788,7 @@
- u8 status;
- int poll_next;
-
-+ VPRINTK("\n");
- fsm_start:
- WARN_ON(ap->hsm_task_state == HSM_ST_IDLE);
-
-@@ -5664,6 +5804,9 @@
- msleep(2);
- status = ata_busy_wait(ap, ATA_BUSY, 10);
- if (status & ATA_BUSY) {
-+ if (ap->ops->pio_task)
-+ ata_port_queue_task(ap, ap->ops->pio_task, qc, ATA_SHORT_PAUSE);
-+ else
- ata_port_queue_task(ap, ata_pio_task, qc, ATA_SHORT_PAUSE);
- return;
- }
-@@ -5693,6 +5836,7 @@
- struct ata_queued_cmd *qc = NULL;
- unsigned int i;
-
-+ VPRINTK("\n");
- /* no command while frozen */
- if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
- return NULL;
-@@ -5723,7 +5867,14 @@
- struct ata_port *ap = dev->link->ap;
- struct ata_queued_cmd *qc;
-
-- qc = ata_qc_new(ap);
-+ VPRINTK("\n");
-+ /* if a specialised version is not available, call the default */
-+ if (ap->ops->qc_new) {
-+ qc = ap->ops->qc_new(ap);
-+ } else {
-+ qc = ata_qc_new(ap);
-+ }
-+
- if (qc) {
- qc->scsicmd = NULL;
- qc->ap = ap;
-@@ -5750,6 +5901,7 @@
- struct ata_port *ap = qc->ap;
- unsigned int tag;
-
-+ VPRINTK("\n");
- WARN_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
-
- qc->flags = 0;
-@@ -5765,6 +5917,7 @@
- struct ata_port *ap = qc->ap;
- struct ata_link *link = qc->dev->link;
-
-+ VPRINTK("\n");
- WARN_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
- WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE));
-
-@@ -5801,6 +5954,7 @@
- {
- struct ata_port *ap = qc->ap;
-
-+ VPRINTK("\n");
- qc->result_tf.flags = qc->tf.flags;
- ap->ops->tf_read(ap, &qc->result_tf);
- }
-@@ -5820,6 +5974,7 @@
- {
- struct ata_port *ap = qc->ap;
-
-+ VPRINTK("\n");
- /* XXX: New EH and old EH use different mechanisms to
- * synchronize EH with regular execution path.
- *
-@@ -5913,6 +6068,7 @@
- u32 done_mask;
- int i;
-
-+ VPRINTK("\n");
- done_mask = ap->qc_active ^ qc_active;
-
- if (unlikely(done_mask & qc_active)) {
-@@ -5942,6 +6098,7 @@
- {
- struct ata_port *ap = qc->ap;
-
-+ VPRINTK("\n");
- switch (qc->tf.protocol) {
- case ATA_PROT_NCQ:
- case ATA_PROT_DMA:
-@@ -5979,6 +6136,7 @@
- struct ata_port *ap = qc->ap;
- struct ata_link *link = qc->dev->link;
-
-+ VPRINTK("\n");
- /* Make sure only one non-NCQ command is outstanding. The
- * check is skipped for old EH because it reuses active qc to
- * request ATAPI sense.
-@@ -6057,6 +6215,7 @@
- {
- struct ata_port *ap = qc->ap;
-
-+ VPRINTK("\n");
- /* Use polling pio if the LLD doesn't handle
- * interrupt driven pio and atapi CDB interrupt.
- */
-@@ -6084,18 +6243,24 @@
- /* start the command */
- switch (qc->tf.protocol) {
- case ATA_PROT_NODATA:
-+ VPRINTK("ATA_PROT_NODATA\n");
- if (qc->tf.flags & ATA_TFLAG_POLLING)
- ata_qc_set_polling(qc);
-
- ata_tf_to_host(ap, &qc->tf);
- ap->hsm_task_state = HSM_ST_LAST;
-
-- if (qc->tf.flags & ATA_TFLAG_POLLING)
-+ if (qc->tf.flags & ATA_TFLAG_POLLING) {
-+ if (ap->ops->pio_task)
-+ ata_port_queue_task(ap, ap->ops->pio_task, qc, 0);
-+ else
- ata_port_queue_task(ap, ata_pio_task, qc, 0);
-+ }
-
- break;
-
- case ATA_PROT_DMA:
-+ VPRINTK("ATA_PROT_DMA\n");
- WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
-
- ap->ops->tf_load(ap, &qc->tf); /* load tf registers */
-@@ -6105,6 +6270,7 @@
- break;
-
- case ATA_PROT_PIO:
-+ VPRINTK("ATA_PROT_PIO\n");
- if (qc->tf.flags & ATA_TFLAG_POLLING)
- ata_qc_set_polling(qc);
-
-@@ -6113,6 +6279,9 @@
- if (qc->tf.flags & ATA_TFLAG_WRITE) {
- /* PIO data out protocol */
- ap->hsm_task_state = HSM_ST_FIRST;
-+ if (ap->ops->pio_task)
-+ ata_port_queue_task(ap, ap->ops->pio_task, qc, 0);
-+ else
- ata_port_queue_task(ap, ata_pio_task, qc, 0);
-
- /* always send first data block using
-@@ -6122,8 +6291,12 @@
- /* PIO data in protocol */
- ap->hsm_task_state = HSM_ST;
-
-- if (qc->tf.flags & ATA_TFLAG_POLLING)
-+ if (qc->tf.flags & ATA_TFLAG_POLLING) {
-+ if (ap->ops->pio_task)
-+ ata_port_queue_task(ap, ap->ops->pio_task, qc, 0);
-+ else
- ata_port_queue_task(ap, ata_pio_task, qc, 0);
-+ }
-
- /* if polling, ata_pio_task() handles the rest.
- * otherwise, interrupt handler takes over from here.
-@@ -6134,6 +6307,7 @@
-
- case ATA_PROT_ATAPI:
- case ATA_PROT_ATAPI_NODATA:
-+ VPRINTK("ATA_PROT_ATAPI / ATA_PROT_ATAPI_NODATA\n");
- if (qc->tf.flags & ATA_TFLAG_POLLING)
- ata_qc_set_polling(qc);
-
-@@ -6143,11 +6317,16 @@
-
- /* send cdb by polling if no cdb interrupt */
- if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) ||
-- (qc->tf.flags & ATA_TFLAG_POLLING))
-+ (qc->tf.flags & ATA_TFLAG_POLLING)) {
-+ if (ap->ops->pio_task)
-+ ata_port_queue_task(ap, ap->ops->pio_task, qc, 0);
-+ else
- ata_port_queue_task(ap, ata_pio_task, qc, 0);
-+ }
- break;
-
- case ATA_PROT_ATAPI_DMA:
-+ VPRINTK("ATA_PROT_ATAPI_DMA\n");
- WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
-
- ap->ops->tf_load(ap, &qc->tf); /* load tf registers */
-@@ -6155,8 +6334,12 @@
- ap->hsm_task_state = HSM_ST_FIRST;
-
- /* send cdb by polling if no cdb interrupt */
-- if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
-+ if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) {
-+ if (ap->ops->pio_task)
-+ ata_port_queue_task(ap, ap->ops->pio_task, qc, 0);
-+ else
- ata_port_queue_task(ap, ata_pio_task, qc, 0);
-+ }
- break;
-
- default:
-@@ -6291,6 +6474,7 @@
- unsigned int handled = 0;
- unsigned long flags;
-
-+ VPRINTK("\n");
- /* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */
- spin_lock_irqsave(&host->lock, flags);
-
-@@ -6330,6 +6514,7 @@
- {
- struct ata_port *ap = link->ap;
-
-+ VPRINTK("\n");
- return (ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read;
- }
-
-@@ -6351,6 +6536,7 @@
- */
- int sata_scr_read(struct ata_link *link, int reg, u32 *val)
- {
-+ VPRINTK("\n");
- if (ata_is_host_link(link)) {
- struct ata_port *ap = link->ap;
-
-@@ -6380,6 +6566,7 @@
- */
- int sata_scr_write(struct ata_link *link, int reg, u32 val)
- {
-+ VPRINTK("\n");
- if (ata_is_host_link(link)) {
- struct ata_port *ap = link->ap;
-
-@@ -6408,6 +6595,7 @@
- */
- int sata_scr_write_flush(struct ata_link *link, int reg, u32 val)
- {
-+ VPRINTK("\n");
- if (ata_is_host_link(link)) {
- struct ata_port *ap = link->ap;
- int rc;
-@@ -6442,6 +6630,7 @@
- {
- u32 sstatus;
-
-+ VPRINTK("\n");
- if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 &&
- (sstatus & 0xf) == 0x3)
- return 1;
-@@ -6466,6 +6655,7 @@
- {
- u32 sstatus;
-
-+ VPRINTK("\n");
- if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 &&
- (sstatus & 0xf) != 0x3)
- return 1;
-@@ -6477,6 +6667,7 @@
- unsigned int err_mask;
- u8 cmd;
-
-+ VPRINTK("\n");
- if (!ata_try_flush_cache(dev))
- return 0;
-
-@@ -6506,6 +6697,7 @@
- unsigned long flags;
- int i, rc;
-
-+ VPRINTK("\n");
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
- struct ata_link *link;
-@@ -6568,6 +6760,7 @@
- {
- int rc;
-
-+ VPRINTK("\n");
- /*
- * disable link pm on all ports before requesting
- * any pm activity
-@@ -6593,6 +6786,7 @@
- */
- void ata_host_resume(struct ata_host *host)
- {
-+ VPRINTK("\n");
- ata_host_request_pm(host, PMSG_ON, ATA_EH_SOFTRESET,
- ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0);
- host->dev->power.power_state = PMSG_ON;
-@@ -6619,6 +6813,7 @@
- struct device *dev = ap->dev;
- int rc;
-
-+ VPRINTK("\n");
- ap->prd = dmam_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma,
- GFP_KERNEL);
- if (!ap->prd)
-@@ -6648,6 +6843,7 @@
- struct ata_port *ap = link->ap;
- unsigned long flags;
-
-+ VPRINTK("\n");
- /* SATA spd limit is bound to the first device */
- link->sata_spd_limit = link->hw_sata_spd_limit;
- link->sata_spd = 0;
-@@ -6683,6 +6879,7 @@
- {
- int i;
-
-+ VPRINTK("\n");
- /* clear everything except for devices */
- memset(link, 0, offsetof(struct ata_link, device[0]));
-
-@@ -6719,6 +6916,7 @@
- u32 scontrol, spd;
- int rc;
-
-+ VPRINTK("\n");
- rc = sata_scr_read(link, SCR_CONTROL, &scontrol);
- if (rc)
- return rc;
-@@ -6797,6 +6995,7 @@
- struct ata_host *host = dev_get_drvdata(gendev);
- int i;
-
-+ VPRINTK("\n");
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
-
-@@ -6903,6 +7102,7 @@
- struct ata_host *host;
- int i, j;
-
-+ VPRINTK("\n");
- host = ata_host_alloc(dev, n_ports);
- if (!host)
- return NULL;
-@@ -6934,6 +7134,7 @@
- struct ata_host *host = dev_get_drvdata(gendev);
- int i;
-
-+ VPRINTK("\n");
- WARN_ON(!(host->flags & ATA_HOST_STARTED));
-
- for (i = 0; i < host->n_ports; i++) {
-@@ -6969,6 +7170,8 @@
- void *start_dr = NULL;
- int i, rc;
-
-+ VPRINTK("\n");
-+
- if (host->flags & ATA_HOST_STARTED)
- return 0;
-
-@@ -7007,6 +7210,7 @@
- ata_eh_freeze_port(ap);
- }
-
-+
- if (start_dr)
- devres_add(host->dev, start_dr);
- host->flags |= ATA_HOST_STARTED;
-@@ -7038,6 +7242,7 @@
- void ata_host_init(struct ata_host *host, struct device *dev,
- unsigned long flags, const struct ata_port_operations *ops)
- {
-+ VPRINTK("\n");
- spin_lock_init(&host->lock);
- host->dev = dev;
- host->flags = flags;
-@@ -7064,6 +7269,7 @@
- {
- int i, rc;
-
-+ VPRINTK("\n");
- /* host must have been started */
- if (!(host->flags & ATA_HOST_STARTED)) {
- dev_printk(KERN_ERR, host->dev,
-@@ -7203,6 +7409,7 @@
- {
- int i, rc;
-
-+ VPRINTK("\n");
- rc = ata_host_start(host);
- if (rc)
- return rc;
-@@ -7246,6 +7453,7 @@
- struct ata_link *link;
- struct ata_device *dev;
-
-+ VPRINTK("\n");
- if (!ap->ops->error_handler)
- goto skip_eh;
-
-@@ -7293,6 +7501,7 @@
- {
- int i;
-
-+ VPRINTK("\n");
- for (i = 0; i < host->n_ports; i++)
- ata_port_detach(host->ports[i]);
-
-@@ -7314,6 +7523,7 @@
-
- void ata_std_ports(struct ata_ioports *ioaddr)
- {
-+ VPRINTK("\n");
- ioaddr->data_addr = ioaddr->cmd_addr + ATA_REG_DATA;
- ioaddr->error_addr = ioaddr->cmd_addr + ATA_REG_ERR;
- ioaddr->feature_addr = ioaddr->cmd_addr + ATA_REG_FEATURE;
-@@ -7345,6 +7555,7 @@
- struct device *dev = &pdev->dev;
- struct ata_host *host = dev_get_drvdata(dev);
-
-+ VPRINTK("\n");
- ata_host_detach(host);
- }
-
-@@ -7353,6 +7564,7 @@
- {
- unsigned long tmp = 0;
-
-+ VPRINTK("\n");
- switch (bits->width) {
- case 1: {
- u8 tmp8 = 0;
-@@ -7385,6 +7597,7 @@
- #ifdef CONFIG_PM
- void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg)
- {
-+ VPRINTK("\n");
- pci_save_state(pdev);
- pci_disable_device(pdev);
-
-@@ -7396,6 +7609,7 @@
- {
- int rc;
-
-+ VPRINTK("\n");
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
-
-@@ -7415,6 +7629,7 @@
- struct ata_host *host = dev_get_drvdata(&pdev->dev);
- int rc = 0;
-
-+ VPRINTK("\n");
- rc = ata_host_suspend(host, mesg);
- if (rc)
- return rc;
-@@ -7429,6 +7644,7 @@
- struct ata_host *host = dev_get_drvdata(&pdev->dev);
- int rc;
-
-+ VPRINTK("\n");
- rc = ata_pci_device_do_resume(pdev);
- if (rc == 0)
- ata_host_resume(host);
-@@ -7442,6 +7658,7 @@
- static int __init ata_init(void)
- {
- ata_probe_timeout *= HZ;
-+ VPRINTK("\n");
- ata_wq = create_workqueue("ata");
- if (!ata_wq)
- return -ENOMEM;
-@@ -7458,6 +7675,7 @@
-
- static void __exit ata_exit(void)
- {
-+ VPRINTK("\n");
- destroy_workqueue(ata_wq);
- destroy_workqueue(ata_aux_wq);
- }
-@@ -7473,6 +7691,7 @@
- int rc;
- unsigned long flags;
-
-+ VPRINTK("\n");
- spin_lock_irqsave(&ata_ratelimit_lock, flags);
-
- if (time_after(jiffies, ratelimit_time)) {
-@@ -7516,6 +7735,7 @@
- unsigned long timeout;
- u32 tmp;
-
-+ VPRINTK("\n");
- tmp = ioread32(reg);
-
- /* Calculate timeout _after_ the first read to make sure
-@@ -7541,11 +7761,13 @@
-
- static u8 ata_dummy_check_status(struct ata_port *ap)
- {
-+ VPRINTK("\n");
- return ATA_DRDY;
- }
-
- static unsigned int ata_dummy_qc_issue(struct ata_queued_cmd *qc)
- {
-+ VPRINTK("\n");
- return AC_ERR_SYSTEM;
- }
-
-diff -Nurd linux-2.6.24/drivers/ata/libata-eh.c linux-2.6.24-oxe810/drivers/ata/libata-eh.c
---- linux-2.6.24/drivers/ata/libata-eh.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/libata-eh.c 2008-06-11 17:50:32.000000000 +0200
-@@ -89,6 +89,8 @@
- static void __ata_ehi_pushv_desc(struct ata_eh_info *ehi, const char *fmt,
- va_list args)
- {
-+ VPRINTK("\n");
-+
- ehi->desc_len += vscnprintf(ehi->desc + ehi->desc_len,
- ATA_EH_DESC_LEN - ehi->desc_len,
- fmt, args);
-@@ -108,6 +110,8 @@
- {
- va_list args;
-
-+ VPRINTK("\n");
-+
- va_start(args, fmt);
- __ata_ehi_pushv_desc(ehi, fmt, args);
- va_end(args);
-@@ -128,6 +132,8 @@
- {
- va_list args;
-
-+ VPRINTK("\n");
-+
- if (ehi->desc_len)
- __ata_ehi_push_desc(ehi, ", ");
-
-@@ -147,6 +153,8 @@
- */
- void ata_ehi_clear_desc(struct ata_eh_info *ehi)
- {
-+ VPRINTK("\n");
-+
- ehi->desc[0] = '\0';
- ehi->desc_len = 0;
- }
-@@ -168,6 +176,8 @@
- {
- va_list args;
-
-+ VPRINTK("\n");
-+
- WARN_ON(!(ap->pflags & ATA_PFLAG_INITIALIZING));
-
- if (ap->link.eh_info.desc_len)
-@@ -202,6 +212,8 @@
- char *type = "";
- unsigned long long start, len;
-
-+ VPRINTK("\n");
-+
- if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM)
- type = "m";
- else if (pci_resource_flags(pdev, bar) & IORESOURCE_IO)
-@@ -223,6 +235,8 @@
- {
- struct ata_ering_entry *ent;
-
-+ VPRINTK("\n");
-+
- WARN_ON(!err_mask);
-
- ering->cursor++;
-@@ -236,6 +250,8 @@
-
- static void ata_ering_clear(struct ata_ering *ering)
- {
-+ VPRINTK("\n");
-+
- memset(ering, 0, sizeof(*ering));
- }
-
-@@ -246,6 +262,8 @@
- int idx, rc = 0;
- struct ata_ering_entry *ent;
-
-+ VPRINTK("\n");
-+
- idx = ering->cursor;
- do {
- ent = &ering->ring[idx];
-@@ -264,6 +282,8 @@
- {
- struct ata_eh_context *ehc = &dev->link->eh_context;
-
-+ VPRINTK("\n");
-+
- return ehc->i.action | ehc->i.dev_action[dev->devno];
- }
-
-@@ -272,6 +292,8 @@
- {
- struct ata_device *tdev;
-
-+ VPRINTK("\n");
-+
- if (!dev) {
- ehi->action &= ~action;
- ata_link_for_each_dev(tdev, link)
-@@ -537,8 +559,11 @@
- void ata_port_wait_eh(struct ata_port *ap)
- {
- unsigned long flags;
-+
- DEFINE_WAIT(wait);
-
-+ VPRINTK("\n");
-+
- retry:
- spin_lock_irqsave(ap->lock, flags);
-
-@@ -564,6 +589,8 @@
- unsigned int tag;
- int nr = 0;
-
-+ VPRINTK("\n");
-+
- /* count only non-internal commands */
- for (tag = 0; tag < ATA_MAX_QUEUE - 1; tag++)
- if (ata_qc_from_tag(ap, tag))
-@@ -578,6 +605,8 @@
- unsigned long flags;
- int cnt;
-
-+ VPRINTK("\n");
-+
- spin_lock_irqsave(ap->lock, flags);
-
- cnt = ata_eh_nr_in_flight(ap);
-@@ -627,6 +656,8 @@
- {
- int cnt;
-
-+ VPRINTK("\n");
-+
- /* already scheduled? */
- if (ap->pflags & ATA_PFLAG_EH_PENDING)
- return;
-@@ -661,6 +692,8 @@
- {
- struct ata_port *ap = qc->ap;
-
-+ VPRINTK("\n");
-+
- WARN_ON(!ap->ops->error_handler);
-
- qc->flags |= ATA_QCFLAG_FAILED;
-@@ -686,6 +719,8 @@
- */
- void ata_port_schedule_eh(struct ata_port *ap)
- {
-+ VPRINTK("\n");
-+
- WARN_ON(!ap->ops->error_handler);
-
- if (ap->pflags & ATA_PFLAG_INITIALIZING)
-@@ -701,6 +736,8 @@
- {
- int tag, nr_aborted = 0;
-
-+ VPRINTK("\n");
-+
- WARN_ON(!ap->ops->error_handler);
-
- /* we're gonna abort all commands, no need for fast drain */
-@@ -736,6 +773,8 @@
- */
- int ata_link_abort(struct ata_link *link)
- {
-+ VPRINTK("\n");
-+
- return ata_do_link_abort(link->ap, link);
- }
-
-@@ -753,6 +792,8 @@
- */
- int ata_port_abort(struct ata_port *ap)
- {
-+ VPRINTK("\n");
-+
- return ata_do_link_abort(ap, NULL);
- }
-
-@@ -776,6 +817,8 @@
- */
- static void __ata_port_freeze(struct ata_port *ap)
- {
-+ VPRINTK("\n");
-+
- WARN_ON(!ap->ops->error_handler);
-
- if (ap->ops->freeze)
-@@ -802,6 +845,8 @@
- {
- int nr_aborted;
-
-+ VPRINTK("\n");
-+
- WARN_ON(!ap->ops->error_handler);
-
- nr_aborted = ata_port_abort(ap);
-@@ -828,6 +873,8 @@
- u32 sntf;
- int rc;
-
-+ VPRINTK("\n");
-+
- if (!(ap->flags & ATA_FLAG_AN))
- return 0;
-
-@@ -896,6 +943,8 @@
- {
- unsigned long flags;
-
-+ VPRINTK("\n");
-+
- if (!ap->ops->error_handler)
- return;
-
-@@ -917,6 +966,8 @@
- {
- unsigned long flags;
-
-+ VPRINTK("\n");
-+
- if (!ap->ops->error_handler)
- return;
-
-@@ -943,6 +994,8 @@
- struct scsi_cmnd *scmd = qc->scsicmd;
- unsigned long flags;
-
-+ VPRINTK("\n");
-+
- spin_lock_irqsave(ap->lock, flags);
- qc->scsidone = ata_eh_scsidone;
- __ata_qc_complete(qc);
-@@ -962,6 +1015,8 @@
- void ata_eh_qc_complete(struct ata_queued_cmd *qc)
- {
- struct scsi_cmnd *scmd = qc->scsicmd;
-+ VPRINTK("\n");
-+
- scmd->retries = scmd->allowed;
- __ata_eh_qc_complete(qc);
- }
-@@ -980,6 +1035,8 @@
- void ata_eh_qc_retry(struct ata_queued_cmd *qc)
- {
- struct scsi_cmnd *scmd = qc->scsicmd;
-+ VPRINTK("\n");
-+
- if (!qc->err_mask && scmd->retries)
- scmd->retries--;
- __ata_eh_qc_complete(qc);
-@@ -1000,6 +1057,8 @@
- struct ata_port *ap = link->ap;
- unsigned long flags;
-
-+ VPRINTK("\n");
-+
- ata_dev_disable(dev);
-
- spin_lock_irqsave(ap->lock, flags);
-@@ -1039,6 +1098,8 @@
- struct ata_eh_context *ehc = &link->eh_context;
- unsigned long flags;
-
-+ VPRINTK("\n");
-+
- spin_lock_irqsave(ap->lock, flags);
-
- /* Reset is represented by combination of actions and EHI
-@@ -1079,6 +1140,8 @@
- {
- struct ata_eh_context *ehc = &link->eh_context;
-
-+ VPRINTK("\n");
-+
- /* if reset is complete, clear all reset actions & reset modifier */
- if (action & ATA_EH_RESET_MASK) {
- action |= ATA_EH_RESET_MASK;
-@@ -1104,6 +1167,8 @@
- */
- static const char *ata_err_string(unsigned int err_mask)
- {
-+ VPRINTK("\n");
-+
- if (err_mask & AC_ERR_HOST_BUS)
- return "host bus error";
- if (err_mask & AC_ERR_ATA_BUS)
-@@ -1184,6 +1249,8 @@
- u8 csum;
- int i;
-
-+ VPRINTK("\n");
-+
- err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, buf, 1);
- if (err_mask)
- return -EIO;
-@@ -1289,6 +1356,8 @@
- unsigned int err_mask = 0, action = 0;
- u32 hotplug_mask;
-
-+ VPRINTK("\n");
-+
- if (serror & SERR_PERSISTENT) {
- err_mask |= AC_ERR_ATA_BUS;
- action |= ATA_EH_HARDRESET;
-@@ -1347,6 +1416,8 @@
- struct ata_taskfile tf;
- int tag, rc;
-
-+ VPRINTK("\n");
-+
- /* if frozen, we can't do much */
- if (ap->pflags & ATA_PFLAG_FROZEN)
- return;
-@@ -1408,6 +1479,8 @@
- unsigned int tmp, action = 0;
- u8 stat = tf->command, err = tf->feature;
-
-+ VPRINTK("\n");
-+
- if ((stat & (ATA_BUSY | ATA_DRQ | ATA_DRDY)) != ATA_DRDY) {
- qc->err_mask |= AC_ERR_HSM;
- return ATA_EH_SOFTRESET;
-@@ -1453,6 +1526,8 @@
-
- static int ata_eh_categorize_error(int is_io, unsigned int err_mask)
- {
-+ VPRINTK("\n");
-+
- if (err_mask & AC_ERR_ATA_BUS)
- return 1;
-
-@@ -1480,6 +1555,8 @@
- struct speed_down_verdict_arg *arg = void_arg;
- int cat = ata_eh_categorize_error(ent->is_io, ent->err_mask);
-
-+ VPRINTK("\n");
-+
- if (ent->timestamp < arg->since)
- return -1;
-
-@@ -1525,6 +1602,8 @@
- struct speed_down_verdict_arg arg;
- unsigned int verdict = 0;
-
-+ VPRINTK("\n");
-+
- /* scan past 10 mins of error history */
- memset(&arg, 0, sizeof(arg));
- arg.since = j64 - min(j64, j10mins);
-@@ -1569,6 +1648,8 @@
- unsigned int verdict;
- unsigned int action = 0;
-
-+ VPRINTK("\n");
-+
- /* don't bother if Cat-0 error */
- if (ata_eh_categorize_error(is_io, err_mask) == 0)
- return 0;
-@@ -1763,6 +1844,8 @@
- {
- struct ata_link *link;
-
-+ VPRINTK("\n");
-+
- ata_port_for_each_link(link, ap)
- ata_eh_link_autopsy(link);
-
-@@ -1790,6 +1873,8 @@
- char tries_buf[6];
- int tag, nr_failed = 0;
-
-+ VPRINTK("\n");
-+
- if (ehc->i.flags & ATA_EHI_QUIET)
- return;
-
-@@ -1954,6 +2039,8 @@
- {
- struct ata_link *link;
-
-+ VPRINTK("\n");
-+
- __ata_port_for_each_link(link, ap)
- ata_eh_link_report(link);
- }
-@@ -1964,6 +2051,8 @@
- struct ata_device *dev;
- int rc;
-
-+ VPRINTK("\n");
-+
- ata_link_for_each_dev(dev, link)
- classes[dev->devno] = ATA_DEV_UNKNOWN;
-
-@@ -1993,6 +2082,8 @@
- int rc, int classify,
- const unsigned int *classes)
- {
-+ VPRINTK("\n");
-+
- if (link->flags & ATA_LFLAG_NO_SRST)
- return 0;
- if (rc == -EAGAIN)
-@@ -2026,6 +2117,8 @@
- u32 sstatus;
- int rc;
-
-+ VPRINTK("\n");
-+
- /* about to reset */
- spin_lock_irqsave(ap->lock, flags);
- ap->pflags |= ATA_PFLAG_RESETTING;
-@@ -2334,6 +2427,8 @@
- struct ata_device *dev;
- int cnt = 0;
-
-+ VPRINTK("\n");
-+
- ata_link_for_each_dev(dev, link)
- if (ata_dev_enabled(dev))
- cnt++;
-@@ -2345,6 +2440,8 @@
- struct ata_device *dev;
- int cnt = 0;
-
-+ VPRINTK("\n");
-+
- ata_link_for_each_dev(dev, link)
- if (dev->class == ATA_DEV_UNKNOWN)
- cnt++;
-@@ -2356,6 +2453,8 @@
- struct ata_eh_context *ehc = &link->eh_context;
- struct ata_device *dev;
-
-+ VPRINTK("\n");
-+
- /* skip disabled links */
- if (link->flags & ATA_LFLAG_DISABLED)
- return 1;
-@@ -2379,6 +2478,8 @@
- {
- struct ata_eh_context *ehc = &dev->link->eh_context;
-
-+ VPRINTK("\n");
-+
- ehc->tries[dev->devno]--;
-
- switch (err) {
-@@ -2638,6 +2739,8 @@
- {
- int tag;
-
-+ VPRINTK("\n");
-+
- /* retry or finish qcs */
- for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
- struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag);
-@@ -2697,6 +2800,8 @@
- struct ata_device *dev;
- int rc;
-
-+ VPRINTK("\n");
-+
- ata_eh_autopsy(ap);
- ata_eh_report(ap);
-
-@@ -2725,6 +2830,8 @@
- unsigned long flags;
- int rc = 0;
-
-+ VPRINTK("\n");
-+
- /* are we suspending? */
- spin_lock_irqsave(ap->lock, flags);
- if (!(ap->pflags & ATA_PFLAG_PM_PENDING) ||
-@@ -2781,6 +2888,8 @@
- unsigned long flags;
- int rc = 0;
-
-+ VPRINTK("\n");
-+
- /* are we resuming? */
- spin_lock_irqsave(ap->lock, flags);
- if (!(ap->pflags & ATA_PFLAG_PM_PENDING) ||
-diff -Nurd linux-2.6.24/drivers/ata/libata-scsi.c linux-2.6.24-oxe810/drivers/ata/libata-scsi.c
---- linux-2.6.24/drivers/ata/libata-scsi.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/libata-scsi.c 2008-06-11 17:50:32.000000000 +0200
-@@ -1477,7 +1477,10 @@
-
- qc->scsidone(cmd);
-
-- ata_qc_free(qc);
-+ if (ap->ops->qc_free)
-+ ap->ops->qc_free(qc);
-+ else
-+ ata_qc_free(qc);
- }
-
- /**
-@@ -1552,13 +1555,19 @@
- return 0;
-
- early_finish:
-- ata_qc_free(qc);
-+ if (qc->ap->ops->qc_free)
-+ qc->ap->ops->qc_free(qc);
-+ else
-+ ata_qc_free(qc);
- qc->scsidone(cmd);
- DPRINTK("EXIT - early finish (good or error)\n");
- return 0;
-
- err_did:
-- ata_qc_free(qc);
-+ if (qc->ap->ops->qc_free)
-+ qc->ap->ops->qc_free(qc);
-+ else
-+ ata_qc_free(qc);
- cmd->result = (DID_ERROR << 16);
- qc->scsidone(cmd);
- err_mem:
-@@ -1566,7 +1575,10 @@
- return 0;
-
- defer:
-- ata_qc_free(qc);
-+ if (qc->ap->ops->qc_free)
-+ qc->ap->ops->qc_free(qc);
-+ else
-+ ata_qc_free(qc);
- DPRINTK("EXIT - defer\n");
- if (rc == ATA_DEFER_LINK)
- return SCSI_MLQUEUE_DEVICE_BUSY;
-@@ -2314,7 +2326,10 @@
- }
-
- qc->scsidone(qc->scsicmd);
-- ata_qc_free(qc);
-+ if (qc->ap->ops->qc_free)
-+ qc->ap->ops->qc_free(qc);
-+ else
-+ ata_qc_free(qc);
- }
-
- /* is it pointless to prefer PIO for "safety reasons"? */
-@@ -2403,7 +2418,10 @@
-
- qc->scsicmd->result = SAM_STAT_CHECK_CONDITION;
- qc->scsidone(cmd);
-- ata_qc_free(qc);
-+ if (qc->ap->ops->qc_free)
-+ qc->ap->ops->qc_free(qc);
-+ else
-+ ata_qc_free(qc);
- return;
- }
-
-@@ -2448,7 +2466,10 @@
- }
-
- qc->scsidone(cmd);
-- ata_qc_free(qc);
-+ if (qc->ap->ops->qc_free)
-+ qc->ap->ops->qc_free(qc);
-+ else
-+ ata_qc_free(qc);
- }
- /**
- * atapi_xlat - Initialize PACKET taskfile
-@@ -2694,6 +2715,12 @@
- if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0)
- goto invalid_fld;
-
-+ /** @NOTE: OX800/OX810 driver needs polling for PIO and no data commands */
-+ if ((tf->protocol == ATA_PROT_PIO) ||
-+ (tf->protocol == ATA_PROT_NODATA)) {
-+ tf->flags |= ATA_TFLAG_POLLING;
-+ }
-+
- /*
- * 12 and 16 byte CDBs use different offsets to
- * provide the various register values.
-diff -Nurd linux-2.6.24/drivers/ata/ox800sata.c linux-2.6.24-oxe810/drivers/ata/ox800sata.c
---- linux-2.6.24/drivers/ata/ox800sata.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/ox800sata.c 2008-06-11 17:50:32.000000000 +0200
-@@ -0,0 +1,2184 @@
-+/**************************************************************************
-+ *
-+ * Copyright (c) 2004 Oxford Semiconductor Ltd.
-+ *
-+ * 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, 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.
-+ *
-+ * Module Name:
-+ * ox800sata.c
-+ *
-+ * Abstract:
-+ * A driver to interface the 924 based sata core present in the ox800
-+ * with libata and scsi
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/device.h>
-+#include <linux/string.h>
-+#include <linux/sysdev.h>
-+#include <linux/module.h>
-+#include <linux/leds.h>
-+
-+#include <scsi/scsi_host.h>
-+#include <scsi/scsi_cmnd.h>
-+#include <scsi/scsi_device.h>
-+#include <asm/io.h>
-+
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/dma.h>
-+#include <asm/arch/memory.h>
-+#include <asm/arch/sata.h>
-+#include <linux/platform_device.h>
-+
-+/***************************************************************************
-+* DEBUG CONTROL
-+***************************************************************************/
-+//#define SATA_DEBUG
-+//#define SATA_DUMP_REGS
-+//#define SATA_TF_DUMP
-+//#define CRAZY_DUMP_DEBUG
-+
-+#if 0
-+ #ifdef writel
-+ #undef writel
-+ #endif
-+ #define writel(v,a) {printk("[%p]<=%08x\n",a,v);*((volatile u32*)(a)) = v;}
-+#endif
-+
-+#if 0
-+ #ifdef readl
-+ #undef readl
-+ #endif
-+ static inline u32 myreadl(u32 a) {u32 v =(*((volatile u32*)(a)));printk("[%p]=>%08x\n",a,v);return v;}
-+ #define readl(a) (myreadl(a))
-+#endif
-+
-+
-+#include <linux/libata.h>
-+/***************************************************************************
-+* CONSTANTS
-+***************************************************************************/
-+
-+#define DRIVER_AUTHOR "Oxford Semiconductor Ltd."
-+#define DRIVER_DESC "924 SATA core controler"
-+#define DRIVER_NAME "oxnassata"
-+
-+#define SATA_ABORT_WAIT_MS 5000
-+#define SATA_SRST_WAIT_MS 5000
-+
-+/**************************************************************************
-+* PROTOTYPES
-+**************************************************************************/
-+static int ox800sata_init_one(struct platform_device *);
-+static int ox800sata_remove_one(struct platform_device *);
-+
-+static void ox800sata_port_disable(struct ata_port *);
-+static void ox800sata_dev_config(struct ata_device *);
-+static void ox800sata_set_piomode(struct ata_port *, struct ata_device *);
-+static void ox800sata_set_dmamode(struct ata_port *, struct ata_device *);
-+static void ox800sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf);
-+static void ox800sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
-+static void ox800sata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
-+static u8 ox800sata_check_status(struct ata_port *ap);
-+static u8 ox800sata_check_altstatus(struct ata_port *ap);
-+static void ox800sata_dev_select(struct ata_port *ap, unsigned int device);
-+static void ox800sata_phy_reset(struct ata_port *ap);
-+static void ox800sata_bmdma_setup(struct ata_queued_cmd *qc);
-+static void ox800sata_bmdma_start(struct ata_queued_cmd *qc);
-+static u8 ox800sata_bmdma_status(struct ata_port *ap);
-+static struct ata_queued_cmd* ox800sata_qc_new(struct ata_port *ap);
-+static void ox800sata_qc_free(struct ata_queued_cmd *qc);
-+static unsigned int ox800sata_qc_issue(struct ata_queued_cmd *qc);
-+static void ox800sata_eng_timeout(struct ata_port *ap);
-+static irqreturn_t ox800sata_irq_handler(int, void *);
-+static void ox800sata_eng_timeout(struct ata_port *ap);
-+static void ox800sata_irq_clear(struct ata_port *);
-+static int ox800sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
-+static int ox800sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
-+static int ox800sata_port_start(struct ata_port *ap);
-+static void ox800sata_port_stop(struct ata_port *ap);
-+static void ox800sata_host_stop(struct ata_host *host_set);
-+static unsigned int ox800sata_devchk(struct ata_port *ap,unsigned int device);
-+static u32* ox800sata_get_io_base(struct ata_port* ap);
-+static u32* ox800sata_get_bbp_base(void);
-+static u8 ox800sata_irq_ack(struct ata_port *ap, unsigned int chk_drq);
-+static u8 ox800sata_irq_on(struct ata_port *ap);
-+static void ox800sata_bmdma_stop(struct ata_queued_cmd *qc);
-+static void CrazyDumpDebug(struct ata_port *ap);
-+static void ox800sata_spot_the_end(struct work_struct *work);
-+static void ox800sata_timeout_cleanup( struct ata_port *ap );
-+static void ox800sata_reset_core( void );
-+static void ox800sata_pio_start(struct work_struct *work);
-+static void ox800sata_pio_task(struct work_struct *work);
-+static void ox800sata_post_reset_init(struct ata_port* ap);
-+static u32 __ox800sata_scr_read(u32* core_addr, unsigned int sc_reg);
-+static void __ox800sata_scr_write(u32* core_addr, unsigned int sc_reg, u32 val);
-+
-+/**************************************************************************
-+* STRUCTURES
-+**************************************************************************/
-+typedef struct
-+{
-+ struct platform_driver driver;
-+ struct ata_port* ap[2];
-+ struct workqueue_struct* spot_the_end_q;
-+} ox800sata_driver_t;
-+
-+/**
-+ * Struct to hold private (specific to this driver) data for each queued
-+ * command, all queued commands will point to a per-port private data
-+ * structure. This is a completely unresearched decision that will surely
-+ * cause some untracable bug in the future.
-+ */
-+typedef struct
-+{
-+ oxnas_dma_channel_t* DmaChannel;
-+ oxnas_dma_sg_entry_t* sg_entries;
-+ struct spot_the_end_work_s {
-+ struct work_struct worker;
-+ struct ata_port* ap;
-+ } spot_the_end_work;
-+ int port_disabled;
-+ u32 ErrorsWithNoCommamnd;
-+ u32 int_status;
-+ u32 in_cleanup;
-+} ox800sata_private_data;
-+
-+ox800sata_driver_t ox800sata_driver =
-+{
-+ .driver =
-+ {
-+ .driver.name = DRIVER_NAME,
-+ .driver.bus = &platform_bus_type,
-+ .probe = ox800sata_init_one,
-+ .remove = ox800sata_remove_one,
-+ },
-+ .ap = {0,0},
-+};
-+
-+/** If we were writing this in C++ then we would be deriving a subclass of
-+ata_port, these would be the overridden functions*/
-+static struct ata_port_operations ox800sata_port_ops =
-+{
-+ .port_disable = ox800sata_port_disable,
-+ .dev_config = ox800sata_dev_config,
-+ .set_piomode = ox800sata_set_piomode,
-+ .set_dmamode = ox800sata_set_dmamode,
-+ .tf_load = ox800sata_tf_load,
-+ .tf_read = ox800sata_tf_read,
-+ .exec_command = ox800sata_exec_command,
-+ .check_status = ox800sata_check_status,
-+ .check_altstatus = ox800sata_check_altstatus,
-+ .dev_select = ox800sata_dev_select,
-+ .phy_reset = ox800sata_phy_reset,
-+ .bmdma_setup = ox800sata_bmdma_setup,
-+ .bmdma_start = ox800sata_bmdma_start,
-+ .bmdma_stop = ox800sata_bmdma_stop,
-+ .bmdma_status = ox800sata_bmdma_status,
-+ .qc_new = ox800sata_qc_new,
-+ .qc_free = ox800sata_qc_free,
-+ .qc_prep = ata_qc_prep,
-+ .qc_issue = ox800sata_qc_issue,
-+ .eng_timeout = ox800sata_eng_timeout,
-+ .irq_handler = ox800sata_irq_handler,
-+ .irq_clear = ox800sata_irq_clear,
-+ .scr_read = ox800sata_scr_read,
-+ .scr_write = ox800sata_scr_write,
-+ .port_start = ox800sata_port_start,
-+ .port_stop = ox800sata_port_stop,
-+ .host_stop = ox800sata_host_stop,
-+ .dev_chk = ox800sata_devchk,
-+ .irq_on = ox800sata_irq_on,
-+ .irq_ack = ox800sata_irq_ack,
-+ .pio_task = ox800sata_pio_start,
-+};
-+
-+/** the scsi_host_template structure describes the basic capabilities of libata
-+and our 921 core to the SCSI framework, it contains the addresses of functions
-+in the libata library that handle top level comands from the SCSI library */
-+static struct scsi_host_template ox800sata_sht =
-+{
-+ .module = THIS_MODULE,
-+ .name = DRIVER_NAME,
-+ .ioctl = ata_scsi_ioctl,
-+ .queuecommand = ata_scsi_queuecmd,
-+/* .eh_strategy_handler= ata_scsi_error,*/
-+ .can_queue = ATA_DEF_QUEUE,
-+ .this_id = ATA_SHT_THIS_ID,
-+/* .sg_tablesize = LIBATA_MAX_PRD,*/
-+ .sg_tablesize = CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES,
-+ .max_sectors = 256, // Use the full 28-bit SATA value
-+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
-+ .emulated = ATA_SHT_EMULATED,
-+ .use_clustering = ATA_SHT_USE_CLUSTERING,
-+ .proc_name = DRIVER_NAME,
-+ .dma_boundary = ~0UL, // NAS has no DMA boundary restrictions
-+ .slave_configure = ata_scsi_slave_config,
-+ .bios_param = ata_std_bios_param,
-+ .unchecked_isa_dma = 0,
-+
-+};
-+
-+/** after PIO read operations, DRQ can remain set even when all the data has
-+been read, when set, PretendDRQIsClear will mask out the DRQ bit in
-+ox800sata_check_status operation */
-+static char PretendDRQIsClear;
-+
-+/**
-+ * used as a store for atomic test and set operations used to coordinate so
-+ * that only one port is processing comnmands at any time */
-+static unsigned long ox800sata_command_active;
-+
-+/**
-+ * A record of which drives have accumulated raid faults. A set bit indicates
-+ * a fault has occured on that drive */
-+static u32 ox800sata_accumulated_RAID_faults = 0;
-+
-+/**************************************************************************/
-+MODULE_LICENSE("GPL");
-+MODULE_VERSION(1.0);
-+MODULE_AUTHOR(DRIVER_AUTHOR);
-+MODULE_DESCRIPTION(DRIVER_DESC);
-+
-+/**************************************************************************
-+* FUCTIONS
-+* prefix all with "ox800sata_"
-+**************************************************************************/
-+
-+/**
-+ * Gets the base address of the ata core from the ata_port structure
-+ * @param ap pointer to the appropriate ata_port structure
-+ * @return the base address of the SATA core
-+ */
-+static u32* ox800sata_get_io_base(struct ata_port* ap)
-+{
-+ // return (u32* )SATA0_REGS_BASE;
-+
-+ return (u32* )ap->host->iomap;
-+}
-+
-+/**
-+ * Gets the base address of the core that contains the BBP registers
-+ * @return the base address of the SATA core that contains the BBP registers
-+ */
-+static u32* ox800sata_get_bbp_base(void)
-+{
-+ return (u32* )SATA0_REGS_BASE;;
-+}
-+
-+/**
-+ * Gets the base address of the sata link registers core from the
-+ * ata_port structure
-+ * @param ap pointer to the appropriate ata_port structure
-+ * @return the base address of the SATA core
-+ */
-+static u32* ox800sata_get_link_base(struct ata_port* ap)
-+{
-+ u8* link_base = (u8* )ap->host->iomap +
-+ ((u8* )SATA0_LINK_REGS_BASE - (u8* )SATA0_REGS_BASE);
-+
-+ return (u32* )link_base;
-+}
-+
-+/**
-+ * Turns on the cores clock and resets it
-+ */
-+static void ox800sata_reset_core( void ){
-+ // Enable the clock to the SATA block
-+ writel(1UL << SYS_CTRL_CKEN_SATA_BIT, SYS_CTRL_CKEN_SET_CTRL);
-+ wmb();
-+
-+ // reset both MAC and PHY
-+ writel(1UL << SYS_CTRL_RSTEN_SATA_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+ writel(1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+ wmb();
-+ udelay(50);
-+
-+ // un-reset both MAC and PHY
-+ writel(1UL << SYS_CTRL_RSTEN_SATA_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+ writel(1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+ wmb();
-+ udelay(50);
-+}
-+
-+/**
-+ * port capabilities for the ox800 sata ports.
-+ */
-+static const struct ata_port_info ox800sata_port_info = {
-+ .flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET | ATA_FLAG_NO_LEGACY,
-+ .pio_mask = 0x1f, /* pio modes 0..4*/
-+ .mwdma_mask = 0x07, /* mwdma0-2 */
-+ .udma_mask = 0x7f, /* udma0-5 */
-+ .port_ops = &ox800sata_port_ops,
-+};
-+
-+/**
-+ * The driver probe function.
-+ * Registered with the amba bus driver as a parameter of ox800sata_driver.bus
-+ * it will register the ata device with kernel first performing any
-+ * initialisation required (if the correct device is present).
-+ * @param pdev Pointer to the 921 device structure
-+ * @param port where on the bus the port was found, ignored and probably wrong
-+ * @return 0 if no errors
-+ */
-+static int ox800sata_init_one(struct platform_device* pdev)
-+{
-+
-+ u32 version;
-+#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
-+ unsigned long reg;
-+#endif // CONFIG_SATA_OXNAS_DISK_LIGHT
-+ struct ata_host *host;
-+ const struct ata_port_info* port_info[] = { &ox800sata_port_info, NULL };
-+
-+ void __iomem* iomem;
-+ struct resource* memres = platform_get_resource(pdev, IORESOURCE_MEM, 0 );
-+ int irq = platform_get_irq(pdev, 0);
-+
-+ DPRINTK("\n");
-+
-+ /* check resourses for sanity */
-+ if ((memres == NULL) || (irq < 0)) {
-+ return 0;
-+ }
-+ iomem = (void __iomem* ) memres->start;
-+
-+ /* check we support this version of the core */
-+ version = readl(((u32* )iomem) + OX800SATA_VERSION) & 0xff;
-+ switch (version)
-+ {
-+ case OX800SATA_CORE_VERSION:
-+ printk(KERN_INFO"ox800sata: OX800 sata core.\n");
-+ break;
-+ default:
-+ printk(KERN_ERR"ox800sata: unknown sata core (version register = 0x%08x)\n",version);
-+ return 0;
-+ break;
-+ }
-+
-+ /* reset the core */
-+ ox800sata_reset_core();
-+
-+ /* initialise a work queue to spot the end of transfers */
-+ ox800sata_driver.spot_the_end_q = create_singlethread_workqueue("sata-endQ");
-+ if (!ox800sata_driver.spot_the_end_q) {
-+ printk(KERN_ERR DRIVER_NAME " Couldn't create a work queue.\n");
-+ return -1;
-+ }
-+
-+#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
-+ /* setup path */
-+ reg = ~(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE) & readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+ writel(reg, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+ reg = ~(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE) & readl(SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+ writel(reg, SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+ reg = ~(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE) & readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+ writel(reg, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+
-+ /* enable output */
-+ writel(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_ENABLE);
-+
-+ /* disk light off */
-+ writel(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_CLEAR);
-+#endif /* CONFIG_SATA_OXNAS_DISK_LIGHT */
-+
-+ /* setup the probe_ent structure which is basically info about the ports
-+ capabilities */
-+
-+ /* allocate memory and check */
-+ host = ata_host_alloc_pinfo(&(pdev->dev), port_info, OX800SATA_MAX_PORTS );
-+ if (!host) {
-+ printk(KERN_ERR DRIVER_NAME " Couldn't create an ata host.\n");
-+ destroy_workqueue(ox800sata_driver.spot_the_end_q);
-+ }
-+
-+ /* set to base of ata core */
-+ host->iomap = iomem;
-+
-+ /* call ata_device_add and begin probing for drives*/
-+ ata_host_activate(host,
-+ irq,
-+ ox800sata_irq_handler,
-+ 0,
-+ &ox800sata_sht );
-+
-+ return 0;
-+}
-+
-+/**
-+ * Called when the amba bus tells this device to remove itself.
-+ * @param pdev pointer to the device that needs to be shutdown
-+ */
-+static int ox800sata_remove_one(struct platform_device* pdev)
-+{
-+ struct ata_host *host_set = dev_get_drvdata( &(pdev->dev) );
-+ struct ata_port *ap;
-+ unsigned int i;
-+
-+
-+ for (i = 0; i < host_set->n_ports; i++)
-+ {
-+ ap = host_set->ports[i];
-+ scsi_remove_host( ap->scsi_host );
-+ }
-+
-+ /** @TODO etc. */
-+
-+ // Disable the clock to the SATA block
-+ writel(1UL << SYS_CTRL_CKEN_SATA_BIT, SYS_CTRL_CKEN_CLR_CTRL);
-+
-+ return 0;
-+}
-+
-+/**
-+ * module initialisation
-+ * @return success
-+ */
-+static int __init ox800sata_init( void )
-+{
-+ int ret;
-+
-+ printk(KERN_INFO"ox800sata init \n");
-+
-+ ret = platform_driver_register( &ox800sata_driver.driver );
-+
-+ return ret;
-+}
-+
-+/**
-+ * module cleanup
-+ */
-+static void __exit ox800sata_exit( void )
-+{
-+ platform_driver_unregister( &ox800sata_driver.driver );
-+}
-+
-+/**
-+ * macros to register intiialisation and exit functions with kernal
-+ */
-+module_init(ox800sata_init);
-+module_exit(ox800sata_exit);
-+
-+/**
-+ * Called from ata_bus_probe() and ata_bus_reset() error paths, as well as
-+ * when unregistering from the SCSI module (rmmod, hot unplug).
-+ * @param port The port to disable
-+ */
-+static void ox800sata_port_disable(struct ata_port* port)
-+{
-+ DPRINTK("\n");
-+}
-+
-+/**
-+ * Called after IDENTIFY [PACKET] DEVICE is issued to each device found.
-+ * Typically used to apply device-specific fixups prior to issue of
-+ * SET FEATURES - XFER MODE, and prior to operation.
-+ * @param port The port to configure
-+ * @param pdev The hardware associated with controlling the port
-+ */
-+static void ox800sata_dev_config(struct ata_device* pdev)
-+{
-+ u32 reg;
-+ u32 *ioaddr = ox800sata_get_io_base(pdev->ap);
-+
-+ DPRINTK("\n");
-+
-+ /* if needed, set the bits to put the interface into 48-bit node */
-+ if (pdev->flags & ATA_DFLAG_LBA48) {
-+ reg = readl( ioaddr + OX800SATA_DRIVE_CONTROL );
-+
-+ /* mask out the pair of bits associaed with each port */
-+ reg &= ~( 3 << (pdev->ap->port_no * 2) );
-+
-+ /* set the mode pair associated with each port */
-+ reg |= 2 << (pdev->ap->port_no * 2);
-+ writel(reg ,ioaddr + OX800SATA_DRIVE_CONTROL);
-+ }
-+}
-+
-+/**
-+ * Hooks called prior to the issue of SET FEATURES - XFER MODE command.
-+ * dev->pio_mode is guaranteed to be valid when ->set_piomode() is called
-+ *
-+ * If we're doing PIO, we need to disable the burst buffer port to stop it
-+ * trying to do a DMA transfer of the data.
-+ *
-+ * @param port The port to configure
-+ * @param pdev The hardware associated with controlling the port
-+ */
-+static void ox800sata_set_piomode(struct ata_port* port, struct ata_device* pdev)
-+{
-+ u32 Register;
-+ u32 *ioaddr = ox800sata_get_bbp_base();
-+
-+ DPRINTK("\n");
-+
-+ /* disable burst buffer DMA */
-+ Register = readl( ioaddr + OX800SATA_BURST_CONTROL );
-+ Register |= OX800SATA_BBC_DREQ_DIS ;
-+ writel(Register ,ioaddr + OX800SATA_BURST_CONTROL);
-+ PretendDRQIsClear = 0;
-+}
-+
-+/**
-+ * Hooks called prior to the issue of SET FEATURES - XFER MODE command.
-+ * dev->dma_mode is guaranteed to be valid when ->set_dmamode() is called.
-+ *
-+ * When doing a DMA transfer, we need to enable the burst buffer port as this
-+ * may have been disabled by a previous command.
-+ *
-+ * @param port The port to configure
-+ * @param pdev The hardware associated with controlling the port
-+ */
-+static void ox800sata_set_dmamode(struct ata_port* port, struct ata_device* pdev)
-+{
-+ u32 Register;
-+ u32 *ioaddr = ox800sata_get_bbp_base();
-+
-+ DPRINTK("\n");
-+
-+ /* enable burst buffer DMA */
-+ Register = readl( ioaddr + OX800SATA_BURST_CONTROL );
-+ Register &= ~OX800SATA_BBC_DREQ_DIS;
-+ writel(Register ,ioaddr + OX800SATA_BURST_CONTROL);
-+}
-+
-+/**
-+ * Output the taskfile for diagnostic reasons, it will always appear in the
-+ * debug output as if it's a task file being written.
-+ * @param tf The taskfile to output
-+ */
-+static void tfdump(const struct ata_taskfile* tf)
-+{
-+ if (tf->flags & ATA_TFLAG_LBA48) {
-+#ifdef SATA_TF_DUMP
-+ printk("Cmd %x Ft %x%x, LBA-48 %02x%02x%02x%02x%02x%02x, nsect %02x%02x, ctl %02x, dev %x\n",
-+#else // SATA_TF_DUMP
-+ DPRINTK("Cmd %x Ft %x%x, LBA-48 %02x%02x%02x%02x%02x%02x, nsect %02x%02x, ctl %02x, dev %x\n",
-+#endif // SATA_TF_DUMP
-+ tf->command,
-+
-+ tf->hob_feature,
-+ tf->feature,
-+
-+ tf->hob_lbah,
-+ tf->hob_lbam,
-+ tf->hob_lbal,
-+ tf->lbah,
-+ tf->lbam,
-+ tf->lbal,
-+
-+ tf->hob_nsect,
-+ tf->nsect,
-+ tf->ctl,
-+ tf->device );
-+ }else{
-+#ifdef SATA_TF_DUMP
-+ printk("Cmd %x Ft %x, LBA-28 %01x%02x%02x%02x, nsect %02x, ctl %02x, dev %x\n",
-+#else // SATA_TF_DUMP
-+ DPRINTK("Cmd %x Ft %x, LBA-28 %01x%02x%02x%02x, nsect %02x, ctl %02x, dev %x\n",
-+#endif // SATA_TF_DUMP
-+ tf->command,
-+
-+ tf->feature,
-+
-+ tf->device & 0x0f,
-+ tf->lbah,
-+ tf->lbam,
-+ tf->lbal,
-+
-+ tf->nsect,
-+ tf->ctl,
-+ tf->device );
-+ }
-+}
-+
-+/**
-+ * called to write a taskfile into the ORB registers
-+ * @param ap hardware with the registers in
-+ * @param tf taskfile to write to the registers
-+ */
-+static void ox800sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
-+{
-+ u32 count = 0;
-+ u32 Orb1 = 0;
-+ u32 Orb2 = 0;
-+ u32 Orb3 = 0;
-+ u32 Orb4 = 0;
-+ u32 Command_Reg;
-+ u32 *ioaddr = ox800sata_get_io_base(ap);
-+ unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
-+
-+ do {
-+ Command_Reg = readl(ioaddr + OX800SATA_SATA_COMMAND );
-+ if (!(Command_Reg & CMD_CORE_BUSY))
-+ break;
-+ count++;
-+ if ( in_atomic() ) {
-+ mdelay(1);
-+ } else {
-+ msleep(1);
-+ }
-+ } while (count < 10);
-+
-+ /* if the control register has changed, write it */
-+ if (tf->ctl != ap->last_ctl)
-+ {
-+ //DPRINTK("ap->last_ctl = %02x",ap->last_ctl);
-+ Orb4 |= (tf->ctl) << 24;
-+
-+ /* write value to register */
-+ writel(Orb4, ioaddr + OX800SATA_ORB4 );
-+
-+ ap->last_ctl = tf->ctl;
-+ }
-+
-+ /* check if the ctl register has interrupts disabled or enabled and
-+ modify the interrupt enable registers on the ata core as required */
-+ if (tf->ctl & ATA_NIEN)
-+ {
-+ /* interrupts disabled */
-+ ox800sata_irq_clear(ap);
-+ }
-+ else
-+ {
-+ /* interrupts enabled */
-+ ox800sata_irq_on(ap);
-+ }
-+
-+ /* write 48 or 28 bit tf parameters */
-+ if (is_addr)
-+ {
-+ /* set LBA bit as it's an address */
-+ Orb1 |= (tf->device & ATA_LBA) << 24;
-+
-+ if (tf->flags & ATA_TFLAG_LBA48)
-+ {
-+ //DPRINTK(KERN_INFO" 48 bit tf load \n");
-+ Orb1 |= ATA_LBA << 24;
-+
-+ Orb2 |= (tf->hob_nsect) << 8 ;
-+
-+ Orb3 |= (tf->hob_lbal) << 24;
-+
-+ Orb4 |= (tf->hob_lbam) << 0 ;
-+ Orb4 |= (tf->hob_lbah) << 8 ;
-+ Orb4 |= (tf->hob_feature)<< 16;
-+ } else {
-+ Orb1 |= (tf->device & 0xf)<< 24;
-+ }
-+
-+ /* write 28-bit lba */
-+ //DPRINTK(KERN_INFO" 28 bit tf load\n");
-+ Orb1 |= (tf->lbal) << 0 ;
-+ Orb1 |= (tf->lbam) << 8 ;
-+ Orb1 |= (tf->lbah) << 16;
-+
-+ Orb2 |= (tf->nsect) << 0 ;
-+ Orb2 |= (tf->feature) << 16;
-+ Orb2 |= (tf->command) << 24;
-+
-+ Orb3 |= (tf->lbal) << 0 ;
-+ Orb3 |= (tf->lbam) << 8 ;
-+ Orb3 |= (tf->lbah) << 16;
-+
-+ Orb4 |= (tf->ctl) << 24;
-+
-+ /* write values to registers */
-+ writel(Orb1, ioaddr + OX800SATA_ORB1 );
-+ writel(Orb2, ioaddr + OX800SATA_ORB2 );
-+ writel(Orb3, ioaddr + OX800SATA_ORB3 );
-+ writel(Orb4, ioaddr + OX800SATA_ORB4 );
-+ }
-+
-+ if (tf->flags & ATA_TFLAG_DEVICE)
-+ {
-+ Orb1 |= (tf->device) << 24;
-+
-+ /* write value to register */
-+ writel(Orb1, ioaddr + OX800SATA_ORB1 );
-+ }
-+
-+ tfdump(tf);
-+
-+}
-+
-+/**
-+ * Called to read the hardware registers / DMA buffers, to
-+ * obtain the current set of taskfile register values.
-+ * @param ap hardware with the registers in
-+ * @param tf taskfile to read the registers into
-+ */
-+static void ox800sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
-+{
-+ u32 *ioaddr = ox800sata_get_io_base(ap);
-+
-+ /* read the orb registers */
-+ u32 Orb1 = readl( ioaddr + OX800SATA_ORB1 );
-+ u32 Orb2 = readl( ioaddr + OX800SATA_ORB2 );
-+ u32 Orb3 = readl( ioaddr + OX800SATA_ORB3 );
-+ u32 Orb4 = readl( ioaddr + OX800SATA_ORB4 );
-+
-+ DPRINTK("\n");
-+
-+ /* read common 28/48 bit tf parameters */
-+ tf->device = (Orb1 >> 24);
-+ tf->nsect = (Orb2 >> 0);
-+ tf->feature = (Orb2 >> 16);
-+ tf->command = ox800sata_check_status(ap);
-+
-+ /* read 48 or 28 bit tf parameters */
-+ if (tf->flags & ATA_TFLAG_LBA48)
-+ {
-+ //DPRINTK(KERN_INFO" 48 bit tf read \n");
-+ tf->hob_nsect = (Orb2 >> 8 ) ;
-+
-+ tf->lbal = (Orb3 >> 0 ) ;
-+ tf->lbam = (Orb3 >> 8 ) ;
-+ tf->lbah = (Orb3 >> 16) ;
-+ tf->hob_lbal = (Orb3 >> 24) ;
-+
-+ tf->hob_lbam = (Orb4 >> 0 ) ;
-+ tf->hob_lbah = (Orb4 >> 8 ) ;
-+ /* feature ext and control are write only */
-+
-+ }
-+ else
-+ {
-+ /* read 28-bit lba */
-+ //DPRINTK(KERN_INFO" 28 bit tf read\n");
-+ tf->lbal = (Orb1 >> 0 ) ;
-+ tf->lbam = (Orb1 >> 8 ) ;
-+ tf->lbah = (Orb1 >> 16) ;
-+ }
-+
-+ /* fixup NAS SATA core's non-std status reporting */
-+ if (PretendDRQIsClear)
-+ {
-+ tf->command &= ~ATA_DRQ;
-+ }
-+
-+ tfdump(tf);
-+}
-+
-+/**
-+ * Causes an ATA command, previously loaded with ->tf_load(), to be
-+ * initiated in hardware. The command is written into the registers again just
-+ * to be sure. All the other registers that are in Orb2 are also written at the
-+ * same time. The command is initiated in hardware by a poke to the COMMAND
-+ * register.
-+ * @param ap hardware with the registers in
-+ * @param tf taskfile to write to the registers
-+ */
-+static void ox800sata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
-+{
-+ u32 count =0;
-+ u32 *ioaddr = ox800sata_get_io_base(ap);
-+ u32 Orb2 ;
-+ u32 Command_Reg;
-+ ox800sata_private_data* private_data ;
-+
-+ //DPRINTK(KERN_INFO"ox800sata_exec_command cmd %02x\n", tf->command);
-+ do {
-+ Command_Reg = readl(ioaddr + OX800SATA_SATA_COMMAND );
-+ if (!(Command_Reg & CMD_CORE_BUSY))
-+ break;
-+ count++;
-+ if ( in_atomic() ) {
-+ mdelay(1);
-+ } else {
-+ msleep(1);
-+ }
-+ } while (count < 10);
-+
-+ /* write all the things in Orb 2 */
-+ Orb2 = (tf->nsect) << 0 ;
-+ if (tf->flags & ATA_TFLAG_LBA48)
-+ {
-+ Orb2 |= (tf->hob_nsect) << 8 ;
-+ }
-+ Orb2 |= (tf->feature) << 16;
-+ Orb2 |= (tf->command) << 24;
-+ writel( Orb2 , ioaddr + OX800SATA_ORB2 );
-+ wmb();
-+
-+ do {
-+ Command_Reg = readl(ioaddr + OX800SATA_SATA_COMMAND );
-+ if (!(Command_Reg & CMD_CORE_BUSY))
-+ break;
-+ count++;
-+ if ( in_atomic() ) {
-+ mdelay(1);
-+ } else {
-+ msleep(1);
-+ }
-+ } while (count < 10);
-+
-+ /* if the drive has become disconnected, executing a command will be a
-+ problem */
-+ private_data = (ox800sata_private_data*)ap->private_data;
-+
-+ /* Command that the orb registers get written to drive */
-+ Command_Reg &= ~SATA_OPCODE_MASK;
-+ Command_Reg |= CMD_WRITE_TO_ORB_REGS;
-+ writel( Command_Reg , ioaddr + OX800SATA_SATA_COMMAND );
-+ wmb();
-+}
-+
-+
-+/**
-+ * Reads the Status ATA shadow register from hardware. Due to a fault with PIO
-+ * transfers, it it sometimes necessary to mask out the DRQ bit
-+ * @param ap hardware with the registers in
-+ * @return The status register
-+ */
-+static u8 ox800sata_check_status(struct ata_port *ap)
-+{
-+ u32 Reg;
-+ u8 result;
-+ u8 state;
-+ u32 *ioaddr = ox800sata_get_io_base(ap);
-+
-+// VPRINTK(KERN_INFO"ox800sata_check_status ");
-+
-+ /* read byte 3 of Orb2 register */
-+ result = readl(ioaddr + OX800SATA_ORB2 ) >> 24;
-+
-+ /* set DRQ when core is in PIO transfer states */
-+ state = readl(ioaddr + OX800SATA_SATA_CONTROL) & OX800SATA_SATA_CONTROL_TRANS_MASK;
-+ if ((state == OX800SATA_TRANS_PIOITRANS) || (state == OX800SATA_TRANS_PIOOTRANS)) {
-+ result |= ATA_DRQ;
-+ }
-+
-+ if (PretendDRQIsClear)
-+ {
-+// VPRINTK("(ignoring DRQ) ");
-+ result &= ~ATA_DRQ;
-+ }
-+
-+ /* use error informatian from raw interupt status */
-+ if (readl(ioaddr + OX800SATA_INT_STATUS) & OX800SATA_RAW_ERROR) {
-+ result |= ATA_ERR;
-+ } else {
-+ result &= ~ATA_ERR;
-+ }
-+
-+ /* check for the drive going missing indicated by SCR status bits 0-3 = 0 */
-+ ox800sata_scr_read(ap, SCR_STATUS, &Reg);
-+ if (!(Reg & 0x1)) {
-+ result |= ATA_DF;
-+ result |= ATA_ERR;
-+ }
-+ //VPRINTK("%02x\n",result);
-+
-+ return result;
-+}
-+
-+/**
-+ * Reads the alt status ATA shadow register from hardware.
-+ * @param ap hardware with the registers in
-+ * @return The alt status register
-+ */
-+static u8 ox800sata_check_altstatus(struct ata_port *ap)
-+{
-+ u8 result;
-+ u32 *ioaddr = ox800sata_get_io_base(ap);
-+
-+ //DPRINTK(KERN_INFO"ox800sata_check_altstatus base=%p\n",ioaddr);
-+
-+ /* read byte 3 of Orb4 register */
-+ result = ( readl(ioaddr + OX800SATA_ORB4 ) >> 24 ) ;
-+
-+ //DPRINTK(KERN_INFO"alternate status register %02x\n",result);
-+
-+ return result;
-+}
-+
-+/**
-+ * Use the method defined in the ATA specification to make either device 0,
-+ * or device 1, active on the ATA channel. If we ever get port multipliers
-+ * to work, this will be where they would switch.
-+ *
-+ * @param ap hardware with the registers in
-+ * @param number of the device to talk to (0..)
-+ */
-+static void ox800sata_dev_select(struct ata_port *ap, unsigned int device)
-+{
-+ /* currently only one i/f, but this may not always be the case */
-+ const unsigned char interface_no = 0;
-+
-+ u32 *ioaddr = ox800sata_get_io_base(ap);
-+ DPRINTK(" i/f=%d dev=%d\n", interface_no, device);
-+
-+ writel(
-+ (interface_no << 4) | device ,
-+ ioaddr + OX800SATA_DEVICE_SELECT );
-+}
-+
-+/**
-+ * The very first step in the probe phase. Actions vary depending on the bus
-+ * type, typically. After waking up the device and probing for device presence
-+ * (PATA and SATA), typically a soft reset (SRST) will be performed. Drivers
-+ * typically use the helper functions ata_bus_reset() or sata_phy_reset() for
-+ * this hook.
-+ *
-+ * This should reset the SATA core and Phisical layer then jump back into the
-+ * libata libraries for lots of other resetting
-+ *
-+ * @param ap hardware with the registers in
-+ */
-+static void ox800sata_phy_reset(struct ata_port *ap)
-+{
-+ u32 *ioaddr = ox800sata_get_io_base(ap);
-+
-+ //DPRINTK(KERN_INFO"ox800sata_phy_reset base = %p\n", ioaddr);
-+
-+ /* turn ata core on */
-+ writel( (1 << SYS_CTRL_CKEN_SATA_BIT), SYS_CTRL_CKEN_SET_CTRL);
-+
-+ /* stop all the interrupts in the ata core */
-+ writel( ~0, ioaddr + OX800SATA_INT_DISABLE);
-+ writel( ~0, ioaddr + OX800SATA_INT_CLEAR);
-+
-+ /* get libata to perform a soft reset */
-+ sata_phy_reset(ap);
-+
-+}
-+
-+/**
-+ * When setting up an IDE BMDMA transaction, these hooks arm (->bmdma_setup)
-+ * and fire (->bmdma_start) the hardware's DMA engine.
-+ *
-+ * @param qc the queued command to issue
-+ */
-+static void ox800sata_bmdma_setup(struct ata_queued_cmd *qc)
-+{
-+ ox800sata_private_data* PrivateData ;
-+ oxnas_dma_direction_t direction;
-+
-+#ifdef SATA_DEBUG
-+ printk(KERN_INFO"ox800sata_bmdma_setup: %s, %d element%s\n", (qc->dma_dir == DMA_FROM_DEVICE) ? "Read" : "Write", qc->n_elem, qc->n_elem ? "s" : "");
-+#else // SATA_DEBUG
-+ DPRINTK(" %s, %d element%s\n", (qc->dma_dir == DMA_FROM_DEVICE) ? "Read" : "Write", qc->n_elem, qc->n_elem ? "s" : "");
-+#endif // SATA_DEBUG
-+
-+ qc->private_data = qc->ap->private_data;
-+ PrivateData = (ox800sata_private_data* )qc->private_data;
-+
-+ // We check for DMA completion from ISR which cannot wait for all DMA channel
-+ // housekeeping to complete, so need to wait here is case we try to reuse
-+ // channel before that housekeeping has completed
-+ while (oxnas_dma_is_active(PrivateData->DmaChannel)) {
-+ printk("DMA Setup Channel still active\n");
-+ }
-+
-+ /* Do not use DMA callback */
-+ oxnas_dma_set_callback(PrivateData->DmaChannel, OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
-+
-+ /* decide on DMA direction */
-+ direction = (qc->dma_dir == DMA_FROM_DEVICE) ? OXNAS_DMA_FROM_DEVICE :
-+ OXNAS_DMA_TO_DEVICE;
-+
-+/* Expect transfers to be multiples of 4KB */
-+//struct scatterlist* sle = qc->sg;
-+//while (sg_dma_len(sle)) {
-+// BUG_ON(sg_dma_len(sle) % 4096);
-+// ++sle;
-+//}
-+
-+ /* now set-up the DMA transfer */
-+ if (qc->n_elem > 1)
-+ {
-+#ifdef SATA_DEBUG
-+ u32 total=0;
-+ int i=0;
-+ struct scatterlist* sg = qc->__sg;
-+ printk("Lengths: ");
-+ do {
-+ u32 len = sg_dma_len(sg++);
-+ printk("%u ", len);
-+ total += len;
-+ } while (++i < qc->n_elem);
-+ printk("\nTotal len = %u\n", total);
-+#endif // SATA_DEBUG
-+ /* try and setup scatter gather controller */
-+/* if (oxnas_dma_device_set_sg(PrivateData->DmaChannel,
-+ direction,
-+ qc->__sg,
-+ qc->n_elem,
-+ &oxnas_sata_dma_settings,
-+ OXNAS_DMA_MODE_INC )) {
-+ printk(KERN_ERR"Failed to setup DMA with disk.\n");
-+ return;
-+ }*/
-+ if (oxnas_dma_device_set_prd(
-+ PrivateData->DmaChannel,
-+ direction,
-+ qc->ap->prd,
-+ &oxnas_sata_dma_settings,
-+ OXNAS_DMA_MODE_INC,
-+ PrivateData->sg_entries)) {
-+ printk(KERN_ERR"Failed to setup DMA with disk.\n");
-+ return;
-+ }
-+ }
-+ else
-+ {
-+#ifdef SATA_DEBUG
-+ printk("Total len = %u\n", sg_dma_len(qc->__sg));
-+#endif // SATA_DEBUG
-+ /* setup a single dma */
-+ oxnas_dma_device_set( PrivateData->DmaChannel,
-+ direction,
-+ (unsigned char* )sg_dma_address(qc->__sg),
-+ sg_dma_len(qc->__sg),
-+ &oxnas_sata_dma_settings,
-+ OXNAS_DMA_MODE_INC,
-+ 1); /* paused */
-+ }
-+}
-+
-+/**
-+ * When setting up an IDE BMDMA transaction, these hooks arm (->ignedmdma_setup)
-+ * and fire (->bmdma_start) the hardware's DMA engine.
-+ *
-+ * @param qc the queued command to issue
-+ */
-+static void ox800sata_bmdma_start(struct ata_queued_cmd *qc)
-+{
-+ ox800sata_private_data* PrivateData ;
-+ DPRINTK("\n");
-+ PrivateData = (ox800sata_private_data* )(qc->private_data);
-+
-+ {
-+ /* turn on the fifo */
-+ u32 Register;
-+ u32 *ioaddr = ox800sata_get_bbp_base();
-+ Register = readl( ioaddr + OX800SATA_BURST_CONTROL );
-+ Register &= ~OX800SATA_BBC_FIFO_DIS;
-+ writel(Register ,ioaddr + OX800SATA_BURST_CONTROL);
-+ }
-+
-+ /* if the drive has become disconnected, executing a command will be a
-+ problem */
-+ {
-+ /* start DMA transfer */
-+ oxnas_dma_start( PrivateData->DmaChannel );
-+ qc->ap->ops->exec_command(qc->ap, &(qc->tf));
-+ }
-+}
-+
-+
-+/**
-+ * ata_qc_new - Request an available ATA command, for queueing
-+ * @ap: Port associated with device @dev
-+ * @dev: Device from whom we request an available command structure
-+ *
-+ * LOCKING:
-+ */
-+
-+static struct ata_queued_cmd* ox800sata_qc_new(struct ata_port *ap)
-+{
-+ struct ata_queued_cmd *qc = NULL;
-+
-+ /* first see if we're not doing a command */
-+ if (!test_and_set_bit(0, &ox800sata_command_active)) {
-+ /* now set the standard bits for compatibility */
-+ set_bit(0, &ap->qc_allocated);
-+ qc = ata_qc_from_tag(ap, 0);
-+
-+#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
-+ /* disk light on */
-+ writel(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_SET);
-+#endif // CONFIG_SATA_OXNAS_DISK_LIGHT
-+#ifdef CONFIG_WDC_LEDS_TRIGGER_SATA_DISK
-+ wdc_ledtrig_sata_activity();
-+#endif // CONFIG_WDC_LEDS_TRIGGER_SATA_DISK
-+ } else
-+ DPRINTK("Command active flag still set\n");
-+
-+ if (qc)
-+ qc->tag = 0;
-+
-+ return qc;
-+}
-+
-+
-+/**
-+ *
-+ */
-+static void ox800sata_qc_free(struct ata_queued_cmd *qc)
-+{
-+ struct ata_port *ap = qc->ap;
-+ unsigned int tag, do_clear = 0;
-+
-+ DPRINTK("\n");
-+
-+ qc->flags = 0;
-+ tag = qc->tag;
-+ if (likely(ata_tag_valid(tag))) {
-+ if (tag == ap->active_tag)
-+ ap->active_tag = ATA_TAG_POISON;
-+ qc->tag = ATA_TAG_POISON;
-+ do_clear = 1;
-+ }
-+
-+ if (likely(do_clear)) {
-+ clear_bit(tag, &ap->qc_allocated);
-+ clear_bit(0, &ox800sata_command_active);
-+
-+#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
-+ /* disk light off */
-+ writel(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_CLEAR);
-+#endif /* CONFIG_SATA_OXNAS_DISK_LIGHT */
-+ }
-+}
-+
-+/**
-+ * qc_issue is used to make a command active, once the hardware and S/G tables
-+ * have been prepared. IDE BMDMA drivers use the helper function
-+ * ata_qc_issue_prot() for taskfile protocol-based dispatch. More advanced drivers
-+ * roll their own ->qc_issue implementation, using this as the "issue new ATA
-+ * command to hardware" hook.
-+ * @param qc the queued command to issue
-+ */
-+static unsigned int ox800sata_qc_issue(struct ata_queued_cmd *qc)
-+{
-+ u32 Register;
-+ int this_port_fail;
-+ ox800sata_private_data* private_data = (ox800sata_private_data*)qc->ap->private_data ;
-+ u32 *ioaddr = ox800sata_get_bbp_base();
-+ u32 reg;
-+ u32 raid_reg = 0; /* default to no raid */
-+
-+ DPRINTK("\n");
-+
-+ /* get raid settings from the bio if they exist */
-+ if (qc->scsicmd && qc->scsicmd->request && qc->scsicmd->request->bio) {
-+ struct bio* bio;
-+ bio = qc->scsicmd->request->bio;
-+ raid_reg = bio->bi_raid ;
-+ if (raid_reg) DPRINTK(" raid reg 0x%08x\n",raid_reg);
-+ }
-+
-+ /* check cable is still connected */
-+ ox800sata_scr_read(qc->ap, SCR_STATUS, ®);
-+ private_data->port_disabled |= (!(reg & 1));
-+
-+ this_port_fail = private_data->port_disabled;
-+
-+ if (raid_reg) {
-+ int port0fail, port1fail;
-+ port0fail = (! (__ox800sata_scr_read((u32* )SATA0_LINK_REGS_BASE, 0x20 + (4 * SCR_STATUS) ) & 1 ) );
-+ port1fail = (! (__ox800sata_scr_read((u32* )SATA1_LINK_REGS_BASE, 0x20 + (4 * SCR_STATUS) ) & 1 ) );
-+ this_port_fail |= port1fail;
-+
-+ ox800sata_accumulated_RAID_faults |= port0fail ? 1 : 0 ;
-+ ox800sata_accumulated_RAID_faults |= port1fail ? 2 : 0 ;
-+ }
-+
-+ if (!this_port_fail ) {
-+ writel(raid_reg ,ioaddr + OX800SATA_RAID_CONTROL);
-+
-+ DPRINTK(" enabling burst buffer DMA\n");
-+ Register = readl( ioaddr + OX800SATA_BURST_CONTROL );
-+ Register &= ~OX800SATA_BBC_DREQ_DIS;
-+ writel(Register ,ioaddr + OX800SATA_BURST_CONTROL);
-+
-+ /* call the default, this should be changed to take advantage of orb
-+ registers, etc... */
-+ return ata_qc_issue_prot(qc);
-+ } else {
-+ /* record the error */
-+ qc->err_mask |= AC_ERR_ATA_BUS;
-+
-+ /* offline the SCSI device */
-+ printk(KERN_ERR"ata%u offline\n", qc->ap->print_id);
-+ scsi_device_set_state(qc->scsicmd->device, SDEV_OFFLINE);
-+ return 0;
-+ }
-+}
-+
-+/**
-+ * This is a high level error handling function, called from the error
-+ * handling thread, when a command times out.
-+ *
-+ * @todo possibly remove this function and revert to only calling the default
-+ *
-+ * @param ap hardware with the registers in
-+ */
-+static void ox800sata_eng_timeout(struct ata_port *ap)
-+{
-+ struct ata_queued_cmd *qc;
-+ ox800sata_private_data* pd = (ox800sata_private_data*)ap->private_data;
-+ DPRINTK("\n");
-+
-+ /* set the in cleanup flag */
-+ pd->in_cleanup = 1;
-+
-+ /* if we're a PIO command existing cleanup won't be called */
-+ qc = ata_qc_from_tag(ap, ap->active_tag);
-+ if (qc->tf.protocol == ATA_PROT_PIO) {
-+ /* reset the core */
-+ ox800sata_timeout_cleanup(ap);
-+ }
-+
-+ /* call strandard lib ata function */
-+ ata_eng_timeout( ap );
-+
-+ /* clear the in cleanup flag */
-+ pd->in_cleanup = 0;
-+}
-+
-+/**
-+ * irq_handler is the interrupt handling routine registered with the system,
-+ * by libata.
-+ */
-+static irqreturn_t ox800sata_irq_handler(int irq,
-+ void* dev_instance)
-+{
-+ struct ata_port *ap = ((struct ata_host *)dev_instance)->ports[0];
-+ ox800sata_private_data *pd;
-+ u32 *ioaddr;
-+ u32 int_status;
-+
-+ DPRINTK("irq = %d\n", irq);
-+
-+ if (!ap || !ap->private_data)
-+ BUG();
-+
-+ pd = (ox800sata_private_data*)ap->private_data;
-+ ioaddr = ox800sata_get_io_base(ap);
-+
-+ int_status = readl(ioaddr + OX800SATA_INT_STATUS);
-+ while (int_status & OX800SATA_INT_MASKABLE) {
-+ /* store interrupt status for the bottom end */
-+ pd->int_status |= int_status;
-+
-+ /* Clear and mask pending interrupts */
-+ writel(int_status, ioaddr + OX800SATA_INT_CLEAR);
-+ writel(int_status, ioaddr + OX800SATA_INT_DISABLE);
-+
-+ int_status = readl(ioaddr + OX800SATA_INT_STATUS);
-+ }
-+
-+ // Wait a short while for the DMA to finish and if it doesn't start a thread
-+ // to poll for the finish
-+ pd->spot_the_end_work.ap = ap;
-+ if (!oxnas_dma_raw_isactive(pd->DmaChannel)) {
-+ ox800sata_spot_the_end(&(pd->spot_the_end_work.worker));
-+ } else {
-+ udelay(100);
-+ if (!oxnas_dma_raw_isactive(pd->DmaChannel)) {
-+ ox800sata_spot_the_end(&(pd->spot_the_end_work.worker));
-+ } else {
-+ /* Start a worker thread looking for the DMA channel to become idle */
-+ queue_work(ox800sata_driver.spot_the_end_q, &pd->spot_the_end_work.worker);
-+ }
-+ }
-+
-+ return IRQ_HANDLED;
-+}
-+
-+/**
-+ * Work for a work queue, this will check for errors then wait for the DMA to
-+ * complete. On the DMA completing it will call ata_qc_complete
-+ */
-+static void ox800sata_spot_the_end(struct work_struct *work)
-+{
-+ struct spot_the_end_work_s* stew =
-+ container_of(work, struct spot_the_end_work_s, worker);
-+ struct ata_port* ap = stew->ap;
-+ ox800sata_private_data* PrivateData = (ox800sata_private_data* )ap->private_data;
-+ struct ata_queued_cmd* qc = ata_qc_from_tag(ap, ap->active_tag);
-+ unsigned long flags = 0;
-+
-+ /* If there's no command ending associated with this IRQ, ignore it. */
-+ if ((qc == NULL) ||
-+ !(PrivateData->int_status & OX800SATA_INT_END_OF_CMD)) {
-+ DPRINTK(" qc=null\n");
-+ return;
-+ }
-+
-+ /* Look to see if the core is indicating an error condition after a RAID
-+ * command */
-+ if (qc->scsicmd &&
-+ qc->scsicmd->request &&
-+ qc->scsicmd->request->bio &&
-+ qc->scsicmd->request->bio->bi_raid ) {
-+ unsigned long Port0Irq = readl(((u32)(SATA0_REGS_BASE)) + OX800SATA_INT_STATUS);
-+ unsigned long Port1Irq = readl(((u32)(SATA1_REGS_BASE)) + OX800SATA_INT_STATUS);
-+
-+ if (test_bit(OX800SATA_INT_ERROR, &Port0Irq)) {
-+ printk("disk 0 error in raid\n");
-+ ox800sata_accumulated_RAID_faults |= 1;
-+ }
-+ if (test_bit(OX800SATA_INT_ERROR, &Port1Irq)) {
-+ printk("disk 1 error in raid\n");
-+ ox800sata_accumulated_RAID_faults |= 2;
-+ }
-+ }
-+
-+ if (!in_irq()) {
-+ /* wait for the DMA to finish */
-+ while (oxnas_dma_is_active(PrivateData->DmaChannel)) {
-+ schedule();
-+ }
-+ }
-+
-+ /* The command may have aborted, this is indicated by the interrupt bit
-+ * being masked */
-+ if (PrivateData->in_cleanup) {
-+ return;
-+ }
-+
-+ if (!(qc->flags & ATA_QCFLAG_ACTIVE)) {
-+ printk(KERN_WARNING "**** QC already completed! ****\n");
-+ return;
-+ }
-+
-+ /* get the error status */
-+ qc->err_mask = ac_err_mask(ata_chk_status(ap));
-+
-+ /* tell libata we're done */
-+ DPRINTK(" returning err_mask=0x%x\n", qc->err_mask);
-+ local_irq_save(flags);
-+ PrivateData->int_status = 0;
-+ local_irq_restore(flags);
-+ ata_qc_complete(qc);
-+}
-+
-+/**
-+ * ox800sata_irq_clear is called during probe just before the interrupt handler is
-+ * registered, to be sure hardware is quiet. It clears and masks interrupt bits
-+ * in the SATA core.
-+ *
-+ * @param ap hardware with the registers in
-+ */
-+static void ox800sata_irq_clear(struct ata_port* ap)
-+{
-+ u32 *ioaddr = ox800sata_get_io_base(ap);
-+ //DPRINTK(KERN_INFO"ox800sata_irq_clear\n");
-+
-+ writel( ~0, ioaddr + OX800SATA_INT_DISABLE );
-+ writel( ~0, ioaddr + OX800SATA_INT_CLEAR );
-+}
-+
-+static u32 __ox800sata_scr_read(u32* core_addr, unsigned int sc_reg)
-+{
-+ u32 result;
-+ u32 patience;
-+
-+ /* we've got 8 other registers in before the start of the standard ones */
-+ writel(sc_reg, core_addr + OX800SATA_LINK_RD_ADDR );
-+
-+ for (patience = 0x100000;patience > 0;--patience)
-+ {
-+ if (readl(core_addr + OX800SATA_LINK_CONTROL) & 0x00000001)
-+ break;
-+ }
-+
-+ result = readl(core_addr + OX800SATA_LINK_DATA);
-+
-+ //DPRINTK(KERN_INFO"ox800sata_scr_read: [0x%02x]->0x%08x\n", sc_reg, result);
-+ return result;
-+}
-+
-+/**
-+ * Read standard SATA phy registers. Currently only used if
-+ * ->phy_reset hook called the sata_phy_reset() helper function.
-+ *
-+ * These registers are in another clock domain to the processor, access is via
-+ * some bridging registers
-+ *
-+ * @param ap hardware with the registers in
-+ * @param sc_reg the SATA PHY register
-+ * @return the value in the register
-+ */
-+static int ox800sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
-+{
-+ u32* ioaddr = ox800sata_get_link_base(ap);
-+ *val = __ox800sata_scr_read(ioaddr, 0x20 + (sc_reg*4) );
-+ return 0;
-+}
-+
-+static void __ox800sata_scr_write(u32* core_addr, unsigned int sc_reg, u32 val)
-+{
-+ u32 patience;
-+
-+ //DPRINTK(KERN_INFO"ox800sata_scr_write: [0x%02x]<-0x%08x\n", sc_reg, val);
-+ writel(val, core_addr + OX800SATA_LINK_DATA );
-+ writel(sc_reg , core_addr + OX800SATA_LINK_WR_ADDR );
-+
-+ for (patience = 0x100000;patience > 0;--patience)
-+ {
-+ if (readl(core_addr + OX800SATA_LINK_CONTROL) & 0x00000001)
-+ break;
-+ }
-+}
-+/**
-+ * Write standard SATA phy registers. Currently only used if
-+ * phy_reset hook called the sata_phy_reset() helper function.
-+ *
-+ * These registers are in another clock domain to the processor, access is via
-+ * some bridging registers
-+ *
-+ * @param ap hardware with the registers in
-+ * @param sc_reg the SATA PHY register
-+ * @param val the value to write into the register
-+ */
-+static int ox800sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
-+{
-+ u32 *ioaddr = ox800sata_get_link_base(ap);
-+ __ox800sata_scr_write(ioaddr, 0x20 + (sc_reg * 4), val);
-+ return 0;
-+}
-+
-+/**
-+ * port_start() is called just after the data structures for each port are
-+ * initialized. Typically this is used to alloc per-port DMA buffers, tables
-+ * rings, enable DMA engines and similar tasks.
-+ *
-+ * @return 0 = success
-+ * @param ap hardware with the registers in
-+ */
-+static int ox800sata_port_start(struct ata_port *ap)
-+{
-+ ox800sata_private_data* pd;
-+ struct device* pdev = ap->host->dev;
-+
-+ ap->prd = dma_alloc_coherent(pdev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_DMA);
-+ if (!ap->prd) {
-+ return -ENOMEM;
-+ }
-+
-+ /* allocate port private data memory and attach to port */
-+ if (!ap->private_data) {
-+ ap->private_data = kmalloc(sizeof(ox800sata_private_data), GFP_KERNEL);
-+ }
-+
-+ if (!ap->private_data) {
-+ return -ENOMEM;
-+ }
-+
-+ pd = (ox800sata_private_data* )ap->private_data;
-+ pd->DmaChannel = 0;
-+ pd->sg_entries = 0;
-+
-+ DPRINTK("ap = %p, pd = %p\n",ap,ap->private_data);
-+
-+ // Allocate DMA SG entries
-+ if (oxnas_dma_alloc_sg_entries(&pd->sg_entries, CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES)) {
-+ printk(KERN_WARNING "ox800sata_port_start() Failed to obtain DMA SG entries\n");
-+ return -ENOMEM;
-+ }
-+
-+ // Hold on to a DMA channel for the life of the SATA driver
-+ pd->DmaChannel = oxnas_dma_request(1);
-+ if (!pd->DmaChannel) {
-+ printk(KERN_WARNING "ox800sata_port_start() Failed to obtain DMA channel\n");
-+ return -ENOMEM;
-+ }
-+
-+ /* declare a work item to spot when a command finishes */
-+ INIT_WORK(&(pd->spot_the_end_work.worker), &ox800sata_spot_the_end);
-+
-+ /* initialise to zero */
-+ pd->ErrorsWithNoCommamnd = 0;
-+ pd->port_disabled = 0;
-+ pd->int_status = 0;
-+ pd->in_cleanup = 0;
-+
-+ /* store the ata_port painter in the driver structure (BAD, should really
-+ be in the device) */
-+ if (ox800sata_get_io_base(ap) == (u32*)SATA0_REGS_BASE) {
-+ ox800sata_driver.ap[0] = ap;
-+ } else if (ox800sata_get_io_base(ap) == (u32*)SATA1_REGS_BASE) {
-+ ox800sata_driver.ap[1] = ap;
-+ }
-+
-+ // turn ata core on
-+ writel((1 << SYS_CTRL_CKEN_SATA_BIT), SYS_CTRL_CKEN_SET_CTRL);
-+
-+ /* post reset init needs to be called for both ports as there's one reset
-+ for both ports*/
-+ if (ox800sata_driver.ap[0]) {
-+ ox800sata_post_reset_init(ox800sata_driver.ap[0]);
-+ }
-+ if (ox800sata_driver.ap[1]) {
-+ ox800sata_post_reset_init(ox800sata_driver.ap[1]);
-+ }
-+
-+ return 0;
-+}
-+
-+static void ox800sata_post_reset_init(struct ata_port* ap)
-+{
-+ u32 patience;
-+ u32* link_addr = ox800sata_get_link_base(ap);
-+ u32* ioaddr = ox800sata_get_io_base(ap);
-+ uint dev;
-+
-+ /* turn on phy error detection by removing the masks */
-+ writel(0x30003, link_addr + OX800SATA_LINK_DATA );
-+ wmb();
-+ writel(0x0C, link_addr + OX800SATA_LINK_WR_ADDR );
-+ wmb();
-+ for (patience = 0x100000;patience > 0;--patience)
-+ {
-+ if (readl(link_addr + OX800SATA_LINK_CONTROL) & 0x00000001)
-+ break;
-+ }
-+
-+ /* Set FIS modes to flush rather than softtrans */
-+ writel(0xff, ioaddr + OX800SATA_REG_ACCESS);
-+
-+ /* go through all the devices and configure them */
-+ for (dev = 0; dev < ATA_MAX_DEVICES; ++dev) {
-+ if ( ap->device[dev].class == ATA_DEV_ATA )
-+ ox800sata_dev_config( &(ap->device[dev]) );
-+ }
-+}
-+
-+/**
-+ * port_stop() is called after ->host_stop(). It's sole function is to
-+ * release DMA/memory resources, now that they are no longer actively being
-+ * used.
-+ */
-+static void ox800sata_port_stop(struct ata_port *ap)
-+{
-+ ox800sata_private_data* pd = (ox800sata_private_data* )ap->private_data;
-+
-+ DPRINTK("\n");
-+
-+ if (pd->DmaChannel) {
-+ oxnas_dma_free(pd->DmaChannel);
-+ pd->DmaChannel = 0;
-+ }
-+
-+ if (pd->sg_entries) {
-+ oxnas_dma_free_sg_entries(pd->sg_entries);
-+ pd->sg_entries = 0;
-+ }
-+
-+ kfree(pd);
-+}
-+
-+/**
-+ * host_stop() is called when the rmmod or hot unplug process begins. The
-+ * hook must stop all hardware interrupts, DMA engines, etc.
-+ *
-+ * @param ap hardware with the registers in
-+ */
-+static void ox800sata_host_stop(struct ata_host *host_set)
-+{
-+ DPRINTK("\n");
-+}
-+
-+/**
-+ * PATA device presence detection
-+ * @param ap ATA channel to examine
-+ * @param device Device to examine (starting at zero)
-+ * @return true if something found
-+ *
-+ * This technique was originally described in
-+ * Hale Landis's ATADRVR (www.ata-atapi.com), and
-+ * later found its way into the ATA/ATAPI spec.
-+ *
-+ * Write a pattern to the ATA shadow registers,
-+ * and if a device is present, it will respond by
-+ * correctly storing and echoing back the
-+ * ATA shadow register contents.
-+ *
-+ * LOCKING:
-+ * caller.
-+ */
-+static unsigned int ox800sata_devchk(struct ata_port *ap,unsigned int device)
-+{
-+ DPRINTK("\n");
-+
-+ return 0; /* nothing found */
-+}
-+
-+static void ox800sata_pio_start(struct work_struct *work)
-+{
-+ u32 burst_reg;
-+ struct ata_port *ap = container_of(work, struct ata_port, port_task.work);
-+ ox800sata_private_data* pd = (ox800sata_private_data*)ap->private_data;
-+ struct ata_queued_cmd* qc = ap->port_task_data;
-+ u32* ioaddr = ox800sata_get_io_base(ap);
-+ unsigned long flags = 0;
-+
-+ // We check for DMA completion from ISR which cannot wait for all DMA channel
-+ // housekeeping to complete, so need to wait here is case we try to reuse
-+ // channel before that housekeeping has completed
-+ while (oxnas_dma_is_active(pd->DmaChannel)) {
-+ printk(KERN_WARNING "PIO start Channel still active\n");
-+ }
-+
-+ if (qc->tf.protocol != ATA_PROT_NODATA) {
-+ oxnas_dma_direction_t direction = (qc->dma_dir == DMA_FROM_DEVICE) ?
-+ OXNAS_DMA_FROM_DEVICE :
-+ OXNAS_DMA_TO_DEVICE;
-+
-+ /* Do not use DMA callback */
-+ oxnas_dma_set_callback(pd->DmaChannel, OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
-+
-+ /* map memory for dma */
-+ dma_map_sg(NULL, qc->__sg, qc->n_elem, qc->dma_dir);
-+
-+ /* setup a scatter gather dma */
-+ oxnas_dma_device_set_sg(pd->DmaChannel,
-+ direction,
-+ qc->__sg,
-+ qc->n_elem,
-+ &oxnas_sata_dma_settings,
-+ OXNAS_DMA_MODE_INC);
-+
-+ oxnas_dma_start(pd->DmaChannel);
-+
-+ /* turn on the fifo */
-+ burst_reg = readl( ioaddr + OX800SATA_BURST_CONTROL );
-+ burst_reg &= ~OX800SATA_BBC_DREQ_DIS;
-+ writel(burst_reg, ioaddr + OX800SATA_BURST_CONTROL);
-+
-+ if (oxnas_dma_is_active(pd->DmaChannel)) {
-+ /* if the DMA is still busy, schedule a task to poll again in 1 ms */
-+ ata_port_queue_task(ap, ox800sata_pio_task, qc, ATA_SHORT_PAUSE);
-+ return;
-+ }
-+
-+ /* cleanup DMA */
-+ dma_unmap_sg(NULL, qc->__sg, qc->n_elem, qc->dma_dir);
-+ } else {
-+ /* if the core is still busy, reschedule */
-+ if (readl(ioaddr + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY) {
-+ ata_port_queue_task(ap, ox800sata_pio_task, qc, ATA_SHORT_PAUSE);
-+ return;
-+ }
-+ }
-+
-+ /* notify of completion */
-+ PretendDRQIsClear = 1;
-+ qc->err_mask = ac_err_mask(ata_chk_status(ap));
-+ spin_lock_irqsave(ap->lock, flags);
-+ ap->ops->irq_on(ap);
-+ ata_qc_complete(qc);
-+ spin_unlock_irqrestore(ap->lock, flags);
-+}
-+
-+/**
-+ * This is the top level of the PIO task. It is responsible for organising the
-+ * transfer of data, collecting and reacting to status changes and notification
-+ * of command completion.
-+ *
-+ */
-+static void ox800sata_pio_task(struct work_struct *work)
-+{
-+ struct ata_port *ap = container_of(work, struct ata_port, port_task.work);
-+ struct ata_queued_cmd *qc = ap->port_task_data;
-+ unsigned long flags = 0;
-+
-+ if (qc->tf.protocol != ATA_PROT_NODATA) {
-+ ox800sata_private_data* pd = (ox800sata_private_data* )ap->private_data;
-+
-+ if (oxnas_dma_is_active(pd->DmaChannel)) {
-+ /* if the DMA is still busy, re-schedule the task */
-+ /* try again in 1 ms */
-+ ata_port_queue_task(ap, ox800sata_pio_task, qc, ATA_SHORT_PAUSE);
-+ return;
-+ }
-+
-+ /* cleanup DMA */
-+ dma_unmap_sg(NULL, qc->__sg, qc->n_elem, qc->dma_dir);
-+ } else {
-+ u32* ioaddr = ox800sata_get_io_base(ap);
-+
-+ /* if the core is still busy, reschedule */
-+ if (readl(ioaddr + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY) {
-+ ata_port_queue_task(ap, ox800sata_pio_task, qc, ATA_SHORT_PAUSE);
-+ return;
-+ }
-+ }
-+
-+ /* notify of completion */
-+ PretendDRQIsClear = 1;
-+ qc->err_mask = ac_err_mask(ata_chk_status(ap));
-+ spin_lock_irqsave(ap->lock, flags);
-+ ap->ops->irq_on(ap);
-+ ata_qc_complete(qc);
-+ spin_unlock_irqrestore(ap->lock, flags);
-+}
-+
-+static void ox800sata_bmdma_stop(struct ata_queued_cmd *qc)
-+{
-+ struct ata_port *ap = qc->ap;
-+ ox800sata_private_data* private_data = (ox800sata_private_data*)ap->private_data;
-+
-+ /* Check if DMA is in progress, if so abort */
-+ if (oxnas_dma_is_active(private_data->DmaChannel)) {
-+ /*
-+ * Attempt to abort any current transfer:
-+ * Abort DMA transfer at the DMA controller,
-+ */
-+ printk(KERN_ERR "ox800sata_bmdma_stop - aborting DMA\n");
-+
-+ oxnas_dma_abort(private_data->DmaChannel);
-+
-+ /* perform core cleanups and resets */
-+ ox800sata_timeout_cleanup(ap);
-+ }
-+}
-+
-+/**
-+ *
-+ */
-+static void ox800sata_timeout_cleanup( struct ata_port *ap ) {
-+ u32* io_base = ox800sata_get_io_base(ap);
-+ u32* bbp_base = ox800sata_get_bbp_base();
-+ int idle;
-+ u32 reg;
-+ int loops;
-+
-+ /* Test SATA core idle state */
-+ CrazyDumpDebug(ap);
-+ idle = !(readl(io_base + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY);
-+
-+
-+ printk(KERN_ERR "ox800sata_timeout_cleanup() ata%u idle = %d\n", ap->print_id, idle);
-+
-+ if (!idle) {
-+ /*
-+ * Assert SATA core and burst buffer port Force_EOT
-+ */
-+ printk(KERN_INFO "ox800sata_timeout_cleanup - aborting SATA... (may take upto 5 seconds)\n");
-+
-+ reg = readl(io_base + OX800SATA_DEVICE_CONTROL);
-+ reg |= OX800SATA_DEVICE_CONTROL_ABORT;
-+ writel(reg, io_base + OX800SATA_DEVICE_CONTROL);
-+
-+ reg = readl(bbp_base + OX800SATA_BURST_CONTROL);
-+ reg |= OX800SATA_BBC_FORCE_EOT;
-+ writel(reg, bbp_base + OX800SATA_BURST_CONTROL);
-+
-+ /* Wait for SATA core to go idle */
-+ idle = 0;
-+ loops = SATA_ABORT_WAIT_MS;
-+ while(1) {
-+ /* Test SATA core idle state */
-+ idle = !(readl(io_base + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY);
-+ if (idle || (loops-- <= 0)) {
-+ break;
-+ }
-+ /* Wait a millisecond before testing again */
-+ udelay(1000);
-+ }
-+
-+ /* Deassert SATA core abort - BBP Force_EOT is self-clearing` */
-+ reg = readl(io_base + OX800SATA_DEVICE_CONTROL);
-+ reg &= ~OX800SATA_DEVICE_CONTROL_ABORT;
-+ writel(reg, io_base + OX800SATA_DEVICE_CONTROL);
-+
-+ DPRINTK("idle = %d, %d loops remaining\n", idle, loops);
-+
-+ if (!idle) {
-+ /*
-+ * SATA core did not go idle, so attempt a core reset:
-+ * Assert both SATA core internal reset and ORB4 srst
-+ * Deassert both SATA core internal reset and ORB4 srst
-+ */
-+#if 0
-+ printk(KERN_INFO "ox800sata_timeout_cleanup - internal SATA reset... (may take upto 5 seconds)\n");
-+
-+ reg = readl(io_base + OX800SATA_SATA_CONTROL);
-+ reg |= OX800SATA_SCTL_RESET;
-+ writel(reg, io_base + OX800SATA_SATA_CONTROL);
-+
-+ reg = readl(io_base + OX800SATA_ORB4);
-+ reg |= OX800SATA_ORB4_SRST;
-+ writel(reg, io_base + OX800SATA_ORB4);
-+
-+ /* Wait for SATA core to go idle */
-+ idle = 0;
-+ loops = SATA_SRST_WAIT_MS;
-+ while(1) {
-+ /* Test SATA core idle state */
-+ idle = !(readl(io_base + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY);
-+ if (idle || (loops-- <= 0)) {
-+ break;
-+ }
-+ /* Wait a millisecond before testing again */
-+ udelay(1000);
-+ }
-+
-+ reg = readl(io_base + OX800SATA_ORB4);
-+ reg &= ~OX800SATA_ORB4_SRST;
-+ writel(reg, io_base + OX800SATA_ORB4);
-+
-+ reg = readl(io_base + OX800SATA_SATA_CONTROL);
-+ reg &= ~OX800SATA_SCTL_RESET;
-+ writel(reg, io_base + OX800SATA_SATA_CONTROL);
-+ udelay(1000);
-+
-+ DPRINTK("idle = %d, %d loops remaining\n", idle, loops);
-+#endif
-+ idle = !(readl(io_base + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY);
-+ if (!idle) {
-+ /*
-+ * SATA core did not go idle, so cause a SATA core reset from the RPS
-+ * NB It may be required to reset both SATA cores if have a dual system
-+ */
-+ printk(KERN_INFO "ox800sata_timeout_cleanup - RPS SATA core reset\n");
-+
-+ writel(1UL << SYS_CTRL_RSTEN_SATA_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+ udelay(1000);
-+ writel(1UL << SYS_CTRL_RSTEN_SATA_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+
-+ /* Read SATA core idle state */
-+ idle = !(readl(io_base + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY);
-+
-+ printk(KERN_INFO"idle = %d\n", idle);
-+
-+ /* Perform any SATA core re-initialisation after reset */
-+ /* post reset init needs to be called for both ports as there's one reset
-+ for both ports*/
-+ if (ox800sata_driver.ap[0])
-+ ox800sata_post_reset_init(ox800sata_driver.ap[0]);
-+ if (ox800sata_driver.ap[1])
-+ ox800sata_post_reset_init(ox800sata_driver.ap[1]);
-+ }
-+ }
-+ }
-+}
-+
-+/**
-+ * bmdma_status return a made up version of a BMDMA status register
-+ *
-+ * @param ap Hardware with the registers in
-+ * @return the value ATA_DMA_INTR if the interrupt came from the DMA finishing
-+ */
-+static u8 ox800sata_bmdma_status(struct ata_port *ap)
-+{
-+ ox800sata_private_data* PrivateData ;
-+ PrivateData = (ox800sata_private_data* )ap->private_data;
-+
-+ {
-+ u32 interrupt_status;
-+ u32 *ioaddr = ox800sata_get_io_base(ap);
-+ interrupt_status = readl(ioaddr + OX800SATA_INT_STATUS );
-+ DPRINTK(" irq bits are %08x \n",interrupt_status);
-+ }
-+/* if( oxnas_dma_is_active( PrivateData->DmaChannel ) )
-+ {
-+ CrazyDumpDebug(ap);
-+ return 0;
-+ }
-+ else*/
-+ {
-+ return ATA_DMA_INTR;
-+ }
-+}
-+
-+/**
-+ * turn on the interrupts from the ata drive
-+ * wait for idle, clear any pending interrupts.
-+ *
-+ * @param ap Hardware with the registers in
-+ */
-+static u8 ox800sata_irq_on(struct ata_port *ap)
-+{
-+ u32* ioaddr = ox800sata_get_io_base(ap);
-+ u8 tmp;
-+
-+ //DPRINTK(KERN_INFO"ox800sata_irq_on\n");
-+
-+ /* enable End of command interrupt */
-+ writel(OX800SATA_INT_END_OF_CMD, ioaddr + OX800SATA_INT_CLEAR);
-+ writel(OX800SATA_INT_END_OF_CMD, ioaddr + OX800SATA_INT_ENABLE);
-+ tmp = ata_wait_idle(ap);
-+
-+ return tmp;
-+}
-+
-+/**
-+ * Acknowledges any pending interrupts, by clearing them, but not disabling
-+ * them.
-+ *
-+ * @param ap Hardware with the registers in
-+ */
-+static u8 ox800sata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
-+{
-+ u32* ioaddr = ox800sata_get_io_base(ap);
-+ unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
-+ u8 status;
-+
-+ //DPRINTK(KERN_INFO"921ish_irq_ack\n");
-+ status = ata_busy_wait(ap, bits, 1000);
-+ if (status & bits)
-+ {
-+ DPRINTK("abnormal status 0x%X\n", status);
-+ }
-+
-+ /* clear the end of command interrupt bit */
-+ writel(OX800SATA_INT_END_OF_CMD, ioaddr + OX800SATA_INT_CLEAR);
-+
-+ return status;
-+}
-+
-+/**
-+ * Outputs all the registers in the SATA core for diagnosis of faults.
-+ *
-+ * @param ap Hardware with the registers in
-+ */
-+static void CrazyDumpDebug(struct ata_port *ap)
-+{
-+#ifdef CRAZY_DUMP_DEBUG
-+ u32 offset;
-+ u32 result;
-+ u32 patience;
-+ u32* ioaddr;
-+
-+ /* IRQ flags for calling port */
-+ {
-+ ox800sata_private_data* PrivateData = (ox800sata_private_data* )ap->private_data;
-+ printk("IRQ %08x\n",PrivateData->int_status);
-+ }
-+
-+ /* port 0 */
-+ ioaddr = (u32* )SATA0_REGS_BASE;
-+ printk("Port 0 High level registers\n");
-+ for(offset = 0; offset < 32;offset++)
-+ {
-+ printk("[%02x] %08x\n", offset * 4, readl(ioaddr + offset));
-+ }
-+
-+ printk("Port 0 link layer registers\n");
-+ ioaddr = (u32* )SATA0_LINK_REGS_BASE;
-+ for(offset = 0; offset < 15;++offset)
-+ {
-+ writel( (offset*4), ioaddr + OX800SATA_LINK_RD_ADDR );
-+ wmb();
-+
-+ for (patience = 0x100000;patience > 0;--patience)
-+ {
-+ if (readl(ioaddr + OX800SATA_LINK_CONTROL) & 0x00000001)
-+ break;
-+ }
-+
-+ result = readl(ioaddr + OX800SATA_LINK_DATA);
-+ printk("[%02x] %08x\n", offset*4, result);
-+ }
-+
-+ /* port 1 */
-+ ioaddr = (u32* )SATA1_REGS_BASE;
-+ printk("Port 1 High level registers\n");
-+ for(offset = 0; offset < 32;offset++)
-+ {
-+ printk("[%02x] %08x\n", offset * 4, readl(ioaddr + offset));
-+ }
-+
-+ printk("Port 1 link layer registers\n");
-+ ioaddr = (u32* )SATA1_LINK_REGS_BASE;
-+ for(offset = 0; offset < 15;++offset)
-+ {
-+ writel( (offset*4), ioaddr + OX800SATA_LINK_RD_ADDR );
-+ wmb();
-+
-+ for (patience = 0x100000;patience > 0;--patience)
-+ {
-+ if (readl(ioaddr + OX800SATA_LINK_CONTROL) & 0x00000001)
-+ break;
-+ }
-+
-+ result = readl(ioaddr + OX800SATA_LINK_DATA);
-+ printk("[%02x] %08x\n", offset*4, result);
-+ }
-+
-+ oxnas_dma_dump_registers();
-+#endif
-+}
-+
-+/**************************************************************************
-+* DEVICE CODE
-+**************************************************************************/
-+
-+/**
-+ * Describes the identity of the SATA core and the resources it requires
-+ */
-+static struct resource ox800sata_port0_resources[] = {
-+ {
-+ .name = "sata_port_0_registers",
-+ .start = SATA0_REGS_BASE,
-+ .end = (SATA0_LINK_REGS_BASE + 64),
-+ .flags = IORESOURCE_MEM,
-+ },
-+ {
-+ .name = "sata_irq",
-+ .start = SATA_1_INTERRUPT,
-+ .flags = IORESOURCE_IRQ,
-+ }
-+};
-+
-+static struct resource ox800sata_port1_resources[] = {
-+ {
-+ .name = "sata_port_1_registers",
-+ .start = SATA1_REGS_BASE,
-+ .end = (SATA1_LINK_REGS_BASE + 64),
-+ .flags = IORESOURCE_MEM,
-+ },
-+ {
-+ .name = "sata_irq",
-+ .start = SATA_2_INTERRUPT,
-+ .flags = IORESOURCE_IRQ,
-+ },
-+};
-+
-+static struct platform_device ox800sata_dev0 =
-+{
-+ .name = DRIVER_NAME,
-+ .id = 0,
-+ .num_resources = 2,
-+ .resource = ox800sata_port0_resources,
-+ .dev.coherent_dma_mask = 0xffffffff,
-+};
-+
-+static struct platform_device ox800sata_dev1 =
-+{
-+ .name = DRIVER_NAME,
-+ .id = 1,
-+ .num_resources = 2,
-+ .resource = ox800sata_port1_resources,
-+ .dev.coherent_dma_mask = 0xffffffff,
-+};
-+
-+/**
-+ * module initialisation
-+ * @return success is 0
-+ */
-+static int __init ox800sata_device_init( void )
-+{
-+ int ret;
-+
-+ DPRINTK("\n");
-+
-+ {
-+ // register the ata device for the driver to find
-+ ret = platform_device_register( &ox800sata_dev0 );
-+ DPRINTK(" %i\n", ret);
-+ }
-+
-+#ifndef SATA_OXNAS_SINGLE_SATA
-+ {
-+ // register the ata device for the driver to find
-+ ret = platform_device_register( &ox800sata_dev1 );
-+ DPRINTK(" %i\n", ret);
-+ }
-+#endif /* SATA_OXNAS_SINGLE_SATA */
-+
-+ return ret;
-+}
-+
-+/**
-+ * module cleanup
-+ */
-+static void __exit ox800sata_device_exit( void )
-+{
-+ platform_device_unregister( &ox800sata_dev0 );
-+ platform_device_unregister( &ox800sata_dev1 );
-+}
-+
-+/**
-+ * Returns accumulated RAID faults and then clears the accumulation
-+ * @return accumulated RAID faults indicated by set bits
-+ */
-+int oxnassata_RAID_faults( void ) {
-+ int temp = ox800sata_accumulated_RAID_faults;
-+ ox800sata_accumulated_RAID_faults = 0;
-+ return temp;
-+}
-+
-+/**
-+ * Returns ox800 port number the request queue is serviced by.
-+ *
-+ * @param queue The queue under investigation.
-+ * @return The ox800 sata port number servicing the queue or -1 if not found.
-+ */
-+int oxnassata_get_port_no(struct request_queue* q)
-+{
-+ struct ata_port* ap = 0;
-+ struct scsi_device* sdev = 0;
-+
-+ /* check port 0 */
-+ ap = ox800sata_driver.ap[0];
-+ if (ap)
-+ shost_for_each_device(sdev, ap->scsi_host) {
-+ if (sdev->request_queue == q) {
-+ DPRINTK("Queue %p on port 0\n", q);
-+ return 0;
-+ }
-+ }
-+
-+ /* check port 1 */
-+ ap = ox800sata_driver.ap[1];
-+ if (ap)
-+ shost_for_each_device(sdev, ap->scsi_host) {
-+ if (sdev->request_queue == q) {
-+ DPRINTK("Queue %p on port 1\n", q);
-+ return 1;
-+ }
-+ }
-+
-+ /* not found */
-+ return -1;
-+}
-+
-+/**
-+ * @return true if all the drives attached to the internal SATA ports use the
-+ * same LBA size.
-+ */
-+int oxnassata_LBA_schemes_compatible( void )
-+{
-+ unsigned long flags0 ;
-+ unsigned long flags1 ;
-+ struct ata_port* ap ;
-+
-+ /* check port 0 */
-+ ap = ox800sata_driver.ap[0];
-+ if (ap)
-+ flags0 = ap->device[0].flags & ATA_DFLAG_LBA48 ;
-+ else
-+ return 0;
-+
-+ /* check port 1 */
-+ ap = ox800sata_driver.ap[1];
-+ if (ap)
-+ flags1 = ap->device[0].flags & ATA_DFLAG_LBA48 ;
-+ else
-+ return 0;
-+
-+ /* compare */
-+ return (flags0 == flags1);
-+}
-+
-+/**
-+ * macros to register intiialisation and exit functions with kernal
-+ */
-+module_init(ox800sata_device_init);
-+module_exit(ox800sata_device_exit);
-+
-+EXPORT_SYMBOL( oxnassata_RAID_faults );
-+EXPORT_SYMBOL( oxnassata_get_port_no );
-+EXPORT_SYMBOL( oxnassata_LBA_schemes_compatible );
-diff -Nurd linux-2.6.24/drivers/ata/ox810sata.c linux-2.6.24-oxe810/drivers/ata/ox810sata.c
---- linux-2.6.24/drivers/ata/ox810sata.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/ox810sata.c 2008-06-11 17:50:32.000000000 +0200
-@@ -0,0 +1,2423 @@
-+/**************************************************************************
-+ *
-+ * Copyright (c) 2007 Oxford Semiconductor Ltd.
-+ *
-+ * 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, 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.
-+ *
-+ * Module Name:
-+ * ox810sata.c
-+ *
-+ * Abstract:
-+ * A driver to interface the 934 based sata core present in the ox810
-+ * with libata and scsi
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/device.h>
-+#include <linux/string.h>
-+#include <linux/sysdev.h>
-+#include <linux/module.h>
-+#include <linux/leds.h>
-+
-+#include <scsi/scsi_host.h>
-+#include <scsi/scsi_cmnd.h>
-+#include <scsi/scsi_device.h>
-+#include <asm/io.h>
-+
-+#include <linux/platform_device.h>
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/dma.h>
-+#include <asm/arch/memory.h>
-+#include <asm/arch/ox810sata.h>
-+
-+#include <linux/proc_fs.h>
-+
-+/***************************************************************************
-+* DEBUG CONTROL
-+***************************************************************************/
-+//#define SATA_DEBUG
-+//#define SATA_DUMP_REGS
-+//#define SATA_TF_DUMP
-+//#define DEBUG_EOT_FAILURE
-+#define ERROR_INJECTION
-+
-+#define CRAZY_DUMP_DEBUG
-+#if 0
-+typedef struct {
-+ u32 a;
-+ u32 d;
-+ u32 w;
-+} regaccess;
-+static u32 regindex = 0;
-+static regaccess regarray[1024];
-+#endif
-+
-+#if 0
-+ #ifdef writel
-+ #undef writel
-+ #endif
-+ #define writel(v,a) {printk("[%p]<=%08x\n",a,v);*((volatile u32*)(a)) = v;}
-+ //#define writel(vv,aa) {regarray[regindex].a=(aa); regarray[regindex].d=(vv); regarray[regindex].w=1; ++regindex; regindex &= 1023;*((volatile u32*)(aa)) = (vv);}
-+#endif
-+
-+#if 0
-+ #ifdef readl
-+ #undef readl
-+ #endif
-+ static inline u32 myreadl(u32 a) {u32 v =(*((volatile u32*)(a)));printk("[%p]=>%08x\n",a,v);return v;}
-+ //static inline u32 myreadl(u32 a) {u32 v =(*((volatile u32*)(a)));regarray[regindex].a=a; regarray[regindex].d=v; regarray[regindex].w=0; ++regindex; regindex &= 1023;return v;}
-+ #define readl(a) (myreadl(a))
-+#endif
-+
-+
-+#include <linux/libata.h>
-+/***************************************************************************
-+* CONSTANTS
-+***************************************************************************/
-+
-+#define DRIVER_AUTHOR "Oxford Semiconductor Ltd."
-+#define DRIVER_DESC "934 SATA core controler"
-+#define DRIVER_NAME "oxnassata"
-+
-+#define SATA_ABORT_WAIT_MS 5000
-+#define SATA_SRST_WAIT_MS 5000
-+
-+/**************************************************************************
-+* PROTOTYPES
-+**************************************************************************/
-+static int ox810sata_init_one(struct platform_device *);
-+static int ox810sata_remove_one(struct platform_device *);
-+
-+static void ox810sata_dev_config(struct ata_port *, struct ata_device *);
-+static void ox810sata_set_piomode(struct ata_port *, struct ata_device *);
-+static void ox810sata_set_dmamode(struct ata_port *, struct ata_device *);
-+static void ox810sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf);
-+static void ox810sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
-+static void ox810sata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
-+static u8 ox810sata_check_status(struct ata_port *ap);
-+static inline u8 ox810sata_check_altstatus(struct ata_port *ap);
-+static void ox810sata_dev_select(struct ata_port *ap, unsigned int device);
-+static void ox810sata_phy_reset(struct ata_port *ap);
-+static void ox810sata_bmdma_setup(struct ata_queued_cmd *qc);
-+static void ox810sata_bmdma_start(struct ata_queued_cmd *qc);
-+static u8 ox810sata_bmdma_status(struct ata_port *ap);
-+static struct ata_queued_cmd* ox810sata_qc_new(struct ata_port *ap);
-+static void ox810sata_qc_free(struct ata_queued_cmd *qc);
-+static unsigned int ox810sata_qc_issue(struct ata_queued_cmd *qc);
-+static void ox810sata_eng_timeout(struct ata_port *ap);
-+static irqreturn_t ox810sata_irq_handler(int, void *);
-+static void ox810sata_eng_timeout(struct ata_port *ap);
-+static void ox810sata_irq_clear(struct ata_port *);
-+static int ox810sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
-+static int ox810sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
-+static int ox810sata_port_start(struct ata_port *ap);
-+static void ox810sata_port_stop(struct ata_port *ap);
-+static void ox810sata_host_stop(struct ata_host *host_set);
-+static unsigned int ox810sata_devchk(struct ata_port *ap,unsigned int device);
-+static u32* ox810sata_get_io_base(struct ata_port* ap);
-+static u8 ox810sata_irq_on(struct ata_port *ap);
-+static void ox810sata_bmdma_stop(struct ata_queued_cmd *qc);
-+static void CrazyDumpDebug( void );
-+static void ox810sata_spot_the_end(struct work_struct *work);
-+static void ox810sata_timeout_cleanup(struct ata_port *ap);
-+static void ox810sata_error_handler(struct ata_port *ap);
-+static void ox810sata_reset_core(void);
-+static int ox810sata_prereset(struct ata_link *link, unsigned long deadline);
-+static int ox810sata_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline);
-+static void ox810sata_postreset(struct ata_link *link, unsigned int *classes);
-+static void ox810sata_pio_start(struct work_struct *work);
-+static void ox810sata_pio_task(struct work_struct *work);
-+static void ox810sata_post_reset_init(struct ata_port* ap);
-+static u32 inline __ox810sata_scr_read(u32* core_addr, unsigned int sc_reg);
-+static void __ox810sata_scr_write(u32* core_addr, unsigned int sc_reg, u32 val);
-+#ifdef ERROR_INJECTION
-+static int ox810sata_error_inject_show(char *page, char **start, off_t off, int count, int *eof, void *data);
-+static int ox810sata_error_inject_store(struct file *file,const char __user *buffer,unsigned long count,void *data);
-+#endif
-+
-+/**************************************************************************
-+* STRUCTURES
-+**************************************************************************/
-+typedef struct
-+{
-+ struct kobject kobj;
-+ struct platform_driver driver;
-+ struct ata_port* ap[2];
-+ u32 error_inject;
-+ struct workqueue_struct* spot_the_end_q;
-+ u32 hw_raid_active;
-+ struct ata_port* active_port;
-+} ox810sata_driver_t;
-+
-+/**
-+ * Struct to hold per-port private (specific to this driver) data (still
-+ * un-researched).
-+ */
-+typedef struct
-+{
-+ oxnas_dma_channel_t* DmaChannel;
-+ oxnas_dma_sg_entry_t* sg_entries;
-+ struct spot_the_end_work_s {
-+ struct work_struct worker;
-+ struct ata_port* ap;
-+ } spot_the_end_work;
-+ u32 ErrorsWithNoCommamnd;
-+ u32 int_status;
-+ u32 in_cleanup;
-+} ox810sata_private_data;
-+
-+ox810sata_driver_t ox810sata_driver =
-+{
-+ .driver =
-+ {
-+ .driver.name = DRIVER_NAME,
-+ .driver.bus = &platform_bus_type,
-+ .probe = ox810sata_init_one,
-+ .remove = ox810sata_remove_one,
-+ },
-+ .ap = {0,0},
-+ .error_inject = 0,
-+ .hw_raid_active = 0,
-+ .active_port = 0,
-+};
-+
-+/** If we were writing this in C++ then we would be deriving a subclass of
-+ata_port, these would be the overridden functions*/
-+static struct ata_port_operations ox810sata_port_ops =
-+{
-+ .dev_config = ox810sata_dev_config,
-+ .set_piomode = ox810sata_set_piomode,
-+ .set_dmamode = ox810sata_set_dmamode,
-+ .tf_load = ox810sata_tf_load,
-+ .tf_read = ox810sata_tf_read,
-+ .exec_command = ox810sata_exec_command,
-+ .check_status = ox810sata_check_status,
-+ .check_altstatus = ox810sata_check_altstatus,
-+ .dev_select = ox810sata_dev_select,
-+ .phy_reset = ox810sata_phy_reset,
-+ .bmdma_setup = ox810sata_bmdma_setup,
-+ .bmdma_start = ox810sata_bmdma_start,
-+ .bmdma_stop = ox810sata_bmdma_stop,
-+ .bmdma_status = ox810sata_bmdma_status,
-+ .qc_new = ox810sata_qc_new,
-+ .qc_free = ox810sata_qc_free,
-+ .qc_prep = ata_qc_prep,
-+ .qc_issue = ox810sata_qc_issue,
-+ .eng_timeout = ox810sata_eng_timeout,
-+ .irq_handler = ox810sata_irq_handler,
-+ .irq_clear = ox810sata_irq_clear,
-+ .scr_read = ox810sata_scr_read,
-+ .scr_write = ox810sata_scr_write,
-+ .port_start = ox810sata_port_start,
-+ .port_stop = ox810sata_port_stop,
-+ .host_stop = ox810sata_host_stop,
-+ .dev_chk = ox810sata_devchk,
-+ .irq_on = ox810sata_irq_on,
-+ .pio_task = ox810sata_pio_start,
-+ .error_handler = ox810sata_error_handler,
-+ .post_internal_cmd = ox810sata_bmdma_stop,
-+};
-+
-+/** the scsi_host_template structure describes the basic capabilities of libata
-+and our 921 core to the SCSI framework, it contains the addresses of functions
-+in the libata library that handle top level comands from the SCSI library */
-+static struct scsi_host_template ox810sata_sht =
-+{
-+ .module = THIS_MODULE,
-+ .name = DRIVER_NAME,
-+ .ioctl = ata_scsi_ioctl,
-+ .queuecommand = ata_scsi_queuecmd,
-+/* .eh_strategy_handler= ata_scsi_error,*/
-+ .can_queue = ATA_DEF_QUEUE,
-+ .this_id = ATA_SHT_THIS_ID,
-+/* .sg_tablesize = LIBATA_MAX_PRD,*/
-+ .sg_tablesize = CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES,
-+ .max_sectors = 256, // Use the full 28-bit SATA value
-+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
-+ .emulated = ATA_SHT_EMULATED,
-+ .use_clustering = ATA_SHT_USE_CLUSTERING,
-+ .proc_name = DRIVER_NAME,
-+ .dma_boundary = ~0UL, // NAS has no DMA boundary restrictions
-+ .slave_configure = ata_scsi_slave_config,
-+ .bios_param = ata_std_bios_param,
-+ .unchecked_isa_dma = 0,
-+
-+};
-+
-+/** after PIO read operations, DRQ can remain set even when all the data has
-+been read, when set, PretendDRQIsClear will mask out the DRQ bit in
-+ox810sata_check_status operation */
-+static char PretendDRQIsClear;
-+
-+/**
-+ * used as a store for atomic test and set operations used to coordinate so
-+ * that only one port is processing comnmands at any time */
-+static unsigned long ox810sata_command_active = 0;
-+
-+/**
-+ * A record of which drives have accumulated raid faults. A set bit indicates
-+ * a fault has occured on that drive */
-+static u32 ox810sata_accumulated_RAID_faults = 0;
-+
-+/**************************************************************************/
-+MODULE_LICENSE("GPL");
-+MODULE_VERSION(1.0);
-+MODULE_AUTHOR(DRIVER_AUTHOR);
-+MODULE_DESCRIPTION(DRIVER_DESC);
-+
-+/**************************************************************************
-+* FUCTIONS
-+* prefix all with "ox810sata_"
-+**************************************************************************/
-+
-+/**
-+ * Gets the base of the ox810 port associated with the ata-port as known
-+ * by lib-ata, The value returned changes to the single RAID port when
-+ * hardware RAID commands are active.
-+ *
-+ * @param ap pointer to the appropriate ata_port structure
-+ * @return the base address of the SATA core
-+ */
-+static inline u32* ox810sata_get_tfio_base(struct ata_port* ap)
-+{
-+ if ((ox810sata_driver.hw_raid_active) &&
-+ (ox810sata_driver.active_port == ap)) {
-+ return (u32* )SATARAID_REGS_BASE;
-+ } else {
-+ return (u32* )ap->host->iomap;
-+ }
-+}
-+
-+/**
-+ * Gets the base address of the ata core from the ata_port structure. The value
-+ * returned will remain the same when hardware raid is active.
-+ *
-+ * @param ap pointer to the appropriate ata_port structure
-+ * @return the base address of the SATA core
-+ */
-+static inline u32* ox810sata_get_io_base(struct ata_port* ap)
-+{
-+ return (u32* )ap->host->iomap;
-+}
-+
-+/**
-+ * Turns on the cores clock and resets it
-+ */
-+static void ox810sata_reset_core( void ){
-+ // Enable the clock to the SATA block
-+ writel(1UL << SYS_CTRL_CKEN_SATA_BIT, SYS_CTRL_CKEN_SET_CTRL);
-+ wmb();
-+
-+ // reset Controller, Link and PHY
-+ writel( (1UL << SYS_CTRL_RSTEN_SATA_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_SATA_LINK_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT), SYS_CTRL_RSTEN_SET_CTRL);
-+ wmb();
-+ udelay(50);
-+
-+ // un-reset the PHY, then Link and Controller
-+ writel(1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+ udelay(50);
-+ writel( (1UL << SYS_CTRL_RSTEN_SATA_LINK_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_SATA_BIT), SYS_CTRL_RSTEN_CLR_CTRL);
-+ udelay(50);
-+}
-+
-+/**
-+ * port capabilities for the ox810 sata ports.
-+ */
-+static const struct ata_port_info ox810sata_port_info = {
-+ .flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET | ATA_FLAG_NO_LEGACY,
-+ .pio_mask = 0x1f, /* pio modes 0..4*/
-+ .mwdma_mask = 0x07, /* mwdma0-2 */
-+ .udma_mask = 0x7f, /* udma0-5 */
-+ .port_ops = &ox810sata_port_ops,
-+};
-+
-+/**
-+ * The driver probe function.
-+ * Registered with the amba bus driver as a parameter of ox810sata_driver.bus
-+ * it will register the ata device with kernel first performing any
-+ * initialisation required (if the correct device is present).
-+ * @param pdev Pointer to the 921 device structure
-+ * @return 0 if no errors
-+ */
-+static int ox810sata_init_one(struct platform_device* pdev)
-+{
-+ u32 version;
-+#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
-+ unsigned long reg;
-+#endif // CONFIG_SATA_OXNAS_DISK_LIGHT
-+ struct ata_host *host;
-+ void __iomem* iomem;
-+ const struct ata_port_info* port_info[] = { &ox810sata_port_info, NULL };
-+ struct resource* memres = platform_get_resource(pdev, IORESOURCE_MEM, 0 );
-+ int irq = platform_get_irq(pdev, 0);
-+
-+ /* check resourses for sanity */
-+ if ((memres == NULL) || (irq < 0)) {
-+ return 0;
-+ }
-+ iomem = (void __iomem* ) memres->start;
-+
-+ /* check we support this version of the core */
-+ version = readl(((u32* )iomem) + OX810SATA_VERSION);
-+ switch (version) {
-+ case OX810SATA_CORE_VERSION:
-+ printk(KERN_INFO"ox810sata: OX810 sata core.\n");
-+ break;
-+ default:
-+ printk(KERN_ERR"ox810sata: unknown sata core (version register = 0x%08x)\n",version);
-+ return 0;
-+ break;
-+ }
-+
-+ /* initialise a work queue to spot the end of transfers */
-+ ox810sata_driver.spot_the_end_q = create_singlethread_workqueue("sata-endQ");
-+ if (!ox810sata_driver.spot_the_end_q) {
-+ printk(KERN_ERR DRIVER_NAME " Couldn't create a work queue.\n");
-+ return -1;
-+ }
-+
-+#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
-+ /* setup path */
-+ reg = ~(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE) & readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+ writel(reg, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+ reg = ~(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE) & readl(SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+ writel(reg, SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+ reg = ~(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE) & readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+ writel(reg, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+
-+ /* enable output */
-+ writel(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_ENABLE);
-+
-+ /* disk light off */
-+ writel(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_CLEAR);
-+#endif /* CONFIG_SATA_OXNAS_DISK_LIGHT */
-+
-+ /* setup the probe_ent structure which is basically info about the ports
-+ capabilities */
-+
-+ /* allocate memory and check */
-+ host = ata_host_alloc_pinfo(&(pdev->dev), port_info, OX810SATA_MAX_PORTS);
-+ if (!host) {
-+ printk(KERN_ERR DRIVER_NAME " Couldn't create an ata host.\n");
-+ destroy_workqueue(ox810sata_driver.spot_the_end_q);
-+ }
-+
-+ /* set to base of ata core */
-+ host->iomap = iomem;
-+
-+ /* call ata_device_add and begin probing for drives*/
-+ ata_host_activate(host, irq, ox810sata_irq_handler, IRQF_SHARED, &ox810sata_sht);
-+
-+ return 0;
-+}
-+
-+/**
-+ * Called when the amba bus tells this device to remove itself.
-+ * @param pdev pointer to the device that needs to be shutdown
-+ */
-+static int ox810sata_remove_one(struct platform_device* pdev)
-+{
-+ struct ata_host *host_set = dev_get_drvdata( &(pdev->dev) );
-+ struct ata_port *ap;
-+ unsigned int i;
-+
-+ for (i = 0; i < host_set->n_ports; i++)
-+ {
-+ ap = host_set->ports[i];
-+ scsi_remove_host( ap->scsi_host );
-+ }
-+
-+ /** @TODO etc. */
-+
-+ // Disable the clock to the SATA block
-+ writel(1UL << SYS_CTRL_CKEN_SATA_BIT, SYS_CTRL_CKEN_CLR_CTRL);
-+
-+ return 0;
-+}
-+
-+/**
-+ * module initialisation
-+ * @return success
-+ */
-+static int __init ox810sata_init( void )
-+{
-+ int ret;
-+
-+ ret = platform_driver_register( &ox810sata_driver.driver );
-+ DPRINTK(" %i\n", ret);
-+
-+#ifdef ERROR_INJECTION
-+{
-+ struct proc_dir_entry *res=create_proc_entry("ox810sata_errorinject",0,NULL);
-+ if (res) {
-+ res->read_proc=ox810sata_error_inject_show;
-+ res->write_proc=ox810sata_error_inject_store;
-+ res->data=NULL;
-+ }
-+ //create_proc_read_entry("ox810sata_errorinject", 0, NULL, ox810sata_error_inject_show, NULL);
-+}
-+#endif
-+ return ret;
-+}
-+
-+/**
-+ * module cleanup
-+ */
-+static void __exit ox810sata_exit( void )
-+{
-+ platform_driver_unregister( &ox810sata_driver.driver );
-+}
-+
-+/**
-+ * macros to register intiialisation and exit functions with kernal
-+ */
-+module_init(ox810sata_init);
-+module_exit(ox810sata_exit);
-+
-+/**
-+ * Called after IDENTIFY [PACKET] DEVICE is issued to each device found.
-+ * Typically used to apply device-specific fixups prior to issue of
-+ * SET FEATURES - XFER MODE, and prior to operation.
-+ * @param port The port to configure
-+ * @param pdev The hardware associated with controlling the port
-+ */
-+static void ox810sata_dev_config(struct ata_port *ap, struct ata_device* pdev)
-+{
-+ u32 reg;
-+ u32 *ioaddr = ox810sata_get_io_base(ap);
-+
-+ /* Set the bits to put the interface into 28 or 48-bit node */
-+ reg = readl(ioaddr + OX810SATA_DRIVE_CONTROL);
-+
-+ /* mask out the pair of bits associaed with each port */
-+ reg &= ~(3 << (ap->port_no * 2));
-+
-+ /* set the mode pair associated with each port */
-+ reg |= ((pdev->flags & ATA_DFLAG_LBA48) ? OX810SATA_DR_CON_48 :
-+ OX810SATA_DR_CON_28) << (ap->port_no * 2);
-+ writel(reg, ioaddr + OX810SATA_DRIVE_CONTROL);
-+
-+ /* if this is an ATA-6 disk, put the port into ATA-5 auto translate mode */
-+ if (pdev->flags & ATA_DFLAG_LBA48) {
-+ reg = readl(ioaddr + OX810SATA_PORT_CONTROL);
-+ reg |= 2;
-+ writel(reg, ioaddr + OX810SATA_PORT_CONTROL);
-+ }
-+}
-+
-+/**
-+ * nothing to do
-+ *
-+ * @param port The port to configure
-+ * @param pdev The hardware associated with controlling the port
-+ */
-+static void ox810sata_set_piomode(struct ata_port* port, struct ata_device* pdev)
-+{
-+}
-+
-+/**
-+ * nothing to do
-+ *
-+ * @param port The port to configure
-+ * @param pdev The hardware associated with controlling the port
-+ */
-+static void ox810sata_set_dmamode(struct ata_port* port, struct ata_device* pdev)
-+{
-+}
-+
-+/**
-+ * Output the taskfile for diagnostic reasons, it will always appear in the
-+ * debug output as if it's a task file being written.
-+ * @param tf The taskfile to output
-+ */
-+static void tfdump(const struct ata_taskfile* tf)
-+{
-+ if (tf->flags & ATA_TFLAG_LBA48) {
-+#ifdef SATA_TF_DUMP
-+ printk("Cmd %x Ft %x%x, LBA-48 %02x%02x%02x%02x%02x%02x, nsect %02x%02x, ctl %02x, dev %x\n",
-+#else // SATA_TF_DUMP
-+ DPRINTK("Cmd %x Ft %x%x, LBA-48 %02x%02x%02x%02x%02x%02x, nsect %02x%02x, ctl %02x, dev %x\n",
-+#endif // SATA_TF_DUMP
-+ tf->command,
-+
-+ tf->hob_feature,
-+ tf->feature,
-+
-+ tf->hob_lbah,
-+ tf->hob_lbam,
-+ tf->hob_lbal,
-+ tf->lbah,
-+ tf->lbam,
-+ tf->lbal,
-+
-+ tf->hob_nsect,
-+ tf->nsect,
-+ tf->ctl,
-+ tf->device );
-+ } else {
-+#ifdef SATA_TF_DUMP
-+ printk("Cmd %x Ft %x, LBA-28 %01x%02x%02x%02x, nsect %02x, ctl %02x, dev %x\n",
-+#else // SATA_TF_DUMP
-+ DPRINTK("Cmd %x Ft %x, LBA-28 %01x%02x%02x%02x, nsect %02x, ctl %02x, dev %x\n",
-+#endif // SATA_TF_DUMP
-+ tf->command,
-+
-+ tf->feature,
-+
-+ tf->device & 0x0f,
-+ tf->lbah,
-+ tf->lbam,
-+ tf->lbal,
-+
-+ tf->nsect,
-+ tf->ctl,
-+ tf->device );
-+ }
-+}
-+
-+/**
-+ * called to write a taskfile into the ORB registers
-+ * @param ap hardware with the registers in
-+ * @param tf taskfile to write to the registers
-+ */
-+static void ox810sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
-+{
-+ u32 count = 0;
-+ u32 Orb1 = 0;
-+ u32 Orb2 = 0;
-+ u32 Orb3 = 0;
-+ u32 Orb4 = 0;
-+ u32 Command_Reg;
-+ u32 *ioaddr = ox810sata_get_tfio_base(ap);
-+ unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
-+
-+ /* wait a maximum of 10ms for the core to be idle */
-+ do {
-+ Command_Reg = readl(ioaddr + OX810SATA_SATA_COMMAND);
-+ if (!(Command_Reg & CMD_CORE_BUSY)) {
-+ break;
-+ }
-+ count++;
-+ udelay(50);
-+ } while (count < 200);
-+
-+ /* if the control register has changed, write it */
-+ if (tf->ctl != ap->last_ctl)
-+ {
-+ //DPRINTK("ap->last_ctl = %02x",ap->last_ctl);
-+ Orb4 |= (tf->ctl) << 24;
-+
-+ /* write value to register */
-+ writel(Orb4, ioaddr + OX810SATA_ORB4);
-+
-+ ap->last_ctl = tf->ctl;
-+
-+ /** @todo find a more elegant way to do this */
-+ /* if the new control value is a soft reset, command the core to send a
-+ control FIS */
-+ if (tf->ctl & ATA_SRST) {
-+ writel(CMD_WRITE_TO_ORB_REGS_NO_COMMAND, ioaddr + OX810SATA_SATA_COMMAND);
-+ }
-+ }
-+
-+ /* check if the ctl register has interrupts disabled or enabled and
-+ modify the interrupt enable registers on the ata core as required */
-+ if (tf->ctl & ATA_NIEN) {
-+ /* interrupts disabled */
-+ ox810sata_irq_clear(ap);
-+ } else {
-+ /* interrupts enabled */
-+ ox810sata_irq_on(ap);
-+ }
-+
-+ /* write 48 or 28 bit tf parameters */
-+ if (is_addr) {
-+ /* set LBA bit as it's an address */
-+ Orb1 |= (tf->device & ATA_LBA) << 24;
-+
-+ if (tf->flags & ATA_TFLAG_LBA48) {
-+ //DPRINTK(KERN_INFO" 48 bit tf load \n");
-+ Orb1 |= ATA_LBA << 24;
-+
-+ Orb2 |= (tf->hob_nsect) << 8 ;
-+
-+ Orb3 |= (tf->hob_lbal) << 24;
-+
-+ Orb4 |= (tf->hob_lbam) << 0 ;
-+ Orb4 |= (tf->hob_lbah) << 8 ;
-+ Orb4 |= (tf->hob_feature)<< 16;
-+ } else {
-+ Orb3 |= (tf->device & 0xf)<< 24;
-+ }
-+
-+ /* write 28-bit lba */
-+ //DPRINTK(KERN_INFO" 28 bit tf load\n");
-+ Orb2 |= (tf->nsect) << 0 ;
-+ Orb2 |= (tf->feature) << 16;
-+ Orb2 |= (tf->command) << 24;
-+
-+ Orb3 |= (tf->lbal) << 0 ;
-+ Orb3 |= (tf->lbam) << 8 ;
-+ Orb3 |= (tf->lbah) << 16;
-+
-+ Orb4 |= (tf->ctl) << 24;
-+
-+ /* write values to registers */
-+ writel(Orb1, ioaddr + OX810SATA_ORB1 );
-+ writel(Orb2, ioaddr + OX810SATA_ORB2 );
-+ writel(Orb3, ioaddr + OX810SATA_ORB3 );
-+ writel(Orb4, ioaddr + OX810SATA_ORB4 );
-+ }
-+
-+ if (tf->flags & ATA_TFLAG_DEVICE) {
-+ Orb1 |= (tf->device) << 24;
-+
-+ /* write value to register */
-+ writel(Orb1, ioaddr + OX810SATA_ORB1);
-+ }
-+
-+ tfdump(tf);
-+}
-+
-+/**
-+ * Called to read the hardware registers / DMA buffers, to
-+ * obtain the current set of taskfile register values.
-+ * @param ap hardware with the registers in
-+ * @param tf taskfile to read the registers into
-+ */
-+static void ox810sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
-+{
-+ u32 *ioaddr = ox810sata_get_tfio_base(ap);
-+
-+ /* read the orb registers */
-+ u32 Orb1 = readl(ioaddr + OX810SATA_ORB1);
-+ u32 Orb2 = readl(ioaddr + OX810SATA_ORB2);
-+ u32 Orb3 = readl(ioaddr + OX810SATA_ORB3);
-+ u32 Orb4 = readl(ioaddr + OX810SATA_ORB4);
-+
-+ /* read common 28/48 bit tf parameters */
-+ tf->device = (Orb1 >> 24);
-+ tf->nsect = (Orb2 >> 0);
-+ tf->feature = (Orb2 >> 16);
-+ tf->command = ox810sata_check_status(ap);
-+
-+ /* read 48 or 28 bit tf parameters */
-+ if (tf->flags & ATA_TFLAG_LBA48) {
-+ //DPRINTK(KERN_INFO" 48 bit tf read \n");
-+ tf->hob_nsect = (Orb2 >> 8) ;
-+
-+ tf->lbal = (Orb3 >> 0) ;
-+ tf->lbam = (Orb3 >> 8) ;
-+ tf->lbah = (Orb3 >> 16) ;
-+ tf->hob_lbal = (Orb3 >> 24) ;
-+
-+ tf->hob_lbam = (Orb4 >> 0) ;
-+ tf->hob_lbah = (Orb4 >> 8) ;
-+ /* feature ext and control are write only */
-+ } else {
-+ /* read 28-bit lba */
-+ //DPRINTK(KERN_INFO" 28 bit tf read\n");
-+ tf->lbal = (Orb3 >> 0) ;
-+ tf->lbam = (Orb3 >> 8) ;
-+ tf->lbah = (Orb3 >> 16) ;
-+ }
-+
-+ tfdump(tf);
-+}
-+
-+/**
-+ * Causes an ATA command, previously loaded with ->tf_load(), to be
-+ * initiated in hardware. The command is written into the registers again just
-+ * to be sure. All the other registers that are in Orb2 are also written at the
-+ * same time. The command is initiated in hardware by a poke to the COMMAND
-+ * register.
-+ * @param ap hardware with the registers in
-+ * @param tf taskfile to write to the registers
-+ */
-+static void ox810sata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
-+{
-+ u32 count =0;
-+ u32 *ioaddr = ox810sata_get_tfio_base(ap);
-+ u32 Orb2;
-+ u32 Command_Reg;
-+
-+#ifdef ERROR_INJECTION
-+ static u32 prand = 10;
-+ if (ox810sata_driver.error_inject) {
-+ u32 *portaddr = ox810sata_get_io_base(ap);
-+ prand = prand ? prand - 1 : 100;
-+ if ( prand < ox810sata_driver.error_inject) {
-+ DPRINTK("ox810sata_exec_command: error injection on\n");
-+ __ox810sata_scr_write( portaddr, 0x14 , 0xd );
-+ } else {
-+ __ox810sata_scr_write( portaddr, 0x14 , 0x1 );
-+ DPRINTK("ox810sata_exec_command: error injection off\n");
-+ }
-+ }
-+#endif
-+
-+ VPRINTK("\n");
-+ /* Wait a maximum af 10ms for the core to go idle */
-+ do {
-+ Command_Reg = readl(ioaddr + OX810SATA_SATA_COMMAND);
-+ if (!(Command_Reg & CMD_CORE_BUSY)) {
-+ break;
-+ }
-+ count++;
-+ udelay(50);
-+ } while (count < 200);
-+
-+ /* write all the things in Orb 2 */
-+ Orb2 = (tf->nsect) << 0 ;
-+ if (tf->flags & ATA_TFLAG_LBA48) {
-+ Orb2 |= (tf->hob_nsect) << 8;
-+ }
-+ Orb2 |= (tf->feature) << 16;
-+ Orb2 |= (tf->command) << 24;
-+ writel(Orb2 , ioaddr + OX810SATA_ORB2);
-+ wmb();
-+
-+ do {
-+ Command_Reg = readl(ioaddr + OX810SATA_SATA_COMMAND);
-+ if (!(Command_Reg & CMD_CORE_BUSY)) {
-+ break;
-+ }
-+ count++;
-+ udelay(50);
-+ } while (count < 200);
-+
-+ /* Command that the orb registers get written to drive */
-+ Command_Reg &= ~SATA_OPCODE_MASK;
-+ Command_Reg |= CMD_WRITE_TO_ORB_REGS;
-+ writel(Command_Reg , ioaddr + OX810SATA_SATA_COMMAND);
-+ wmb();
-+}
-+
-+
-+/**
-+ * Reads the Status ATA shadow register from hardware. Due to a fault with PIO
-+ * transfers, it it sometimes necessary to mask out the DRQ bit
-+ * @param ap hardware with the registers in
-+ * @return The status register
-+ */
-+static u8 ox810sata_check_status(struct ata_port *ap)
-+{
-+ u32 Reg;
-+ u8 status;
-+ u32 *ioaddr = ox810sata_get_tfio_base(ap);
-+
-+// VPRINTK(KERN_INFO"ox810sata_check_status ");
-+
-+ /* read byte 3 of Orb2 register */
-+ status = readl(ioaddr + OX810SATA_ORB2) >> 24;
-+
-+ /* check for the drive going missing indicated by SCR status bits 0-3 = 0 */
-+ if ( ox810sata_driver.hw_raid_active ) {
-+ u32 Temp;
-+ ox810sata_scr_read(ox810sata_driver.ap[0], SCR_STATUS, &Temp );
-+ ox810sata_scr_read(ox810sata_driver.ap[1], SCR_STATUS, &Reg);
-+ Reg |= Temp;
-+ } else {
-+ ox810sata_scr_read(ap, SCR_STATUS, &Reg );
-+ }
-+ if (!(Reg & 0x1)) {
-+ status |= ATA_DF;
-+ status |= ATA_ERR;
-+ }
-+ //VPRINTK("%02x\n",result);
-+
-+ return status;
-+}
-+
-+/**
-+ * Reads the alt status ATA shadow register from hardware.
-+ * @param ap hardware with the registers in
-+ * @return The alt status register
-+ */
-+static u8 ox810sata_check_altstatus(struct ata_port *ap)
-+{
-+ return readl(ox810sata_get_tfio_base(ap) + OX810SATA_ORB4) >> 24;
-+}
-+
-+/**
-+ * Use the method defined in the ATA specification to make either device 0,
-+ * or device 1, active on the ATA channel. If we ever get port multipliers
-+ * to work, this will be where they would switch.
-+ *
-+ * @param ap hardware with the registers in
-+ * @param number of the device to talk to (0..)
-+ */
-+static void ox810sata_dev_select(struct ata_port *ap, unsigned int device)
-+{
-+}
-+
-+/**
-+ * The very first step in the probe phase. Actions vary depending on the bus
-+ * type, typically. After waking up the device and probing for device presence
-+ * (PATA and SATA), typically a soft reset (SRST) will be performed. Drivers
-+ * typically use the helper functions ata_bus_reset() or sata_phy_reset() for
-+ * this hook.
-+ *
-+ * This should reset the SATA core and Phisical layer then jump back into the
-+ * libata libraries for lots of other resetting
-+ *
-+ * @param ap hardware with the registers in
-+ */
-+static void ox810sata_phy_reset(struct ata_port *ap)
-+{
-+ u32 *ioaddr = ox810sata_get_io_base(ap);
-+
-+ DPRINTK(KERN_INFO "base = %p\n", ioaddr);
-+
-+ /* turn ata core on */
-+ writel((1 << SYS_CTRL_CKEN_SATA_BIT), SYS_CTRL_CKEN_SET_CTRL);
-+
-+ /* stop all the interrupts in the ata core */
-+ writel(~0, ioaddr + OX810SATA_INT_DISABLE);
-+ writel(~0, ioaddr + OX810SATA_INT_CLEAR);
-+
-+ /* get libata to perform a soft reset */
-+ ata_port_probe(ap);
-+ ata_bus_reset(ap);
-+}
-+
-+/**
-+ * When setting up an IDE BMDMA transaction, these hooks arm (->bmdma_setup)
-+ * and fire (->bmdma_start) the hardware's DMA engine.
-+ *
-+ * @param qc the queued command to issue
-+ */
-+static void ox810sata_bmdma_setup(struct ata_queued_cmd *qc)
-+{
-+ ox810sata_private_data* PrivateData ;
-+ oxnas_dma_direction_t direction;
-+
-+#ifdef SATA_DEBUG
-+ printk(KERN_INFO"ox810sata_bmdma_setup: %s, %d element%s\n", (qc->dma_dir == DMA_FROM_DEVICE) ? "Read" : "Write", qc->n_elem, qc->n_elem ? "s" : "");
-+#else // SATA_DEBUG
-+ DPRINTK(" %s, %d element%s\n", (qc->dma_dir == DMA_FROM_DEVICE) ? "Read" : "Write", qc->n_elem, qc->n_elem ? "s" : "");
-+#endif // SATA_DEBUG
-+
-+ qc->private_data = qc->ap->private_data;
-+ PrivateData = (ox810sata_private_data* )qc->private_data;
-+
-+ // We check for DMA completion from ISR which cannot wait for all DMA channel
-+ // housekeeping to complete, so need to wait here is case we try to reuse
-+ // channel before that housekeeping has completed
-+ while (oxnas_dma_is_active(PrivateData->DmaChannel)) {
-+ printk("DMA Setup Channel still active\n");
-+ }
-+
-+ /* Do not use DMA callback */
-+ oxnas_dma_set_callback(PrivateData->DmaChannel, OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
-+
-+ /* decide on DMA direction */
-+ direction = (qc->dma_dir == DMA_FROM_DEVICE) ? OXNAS_DMA_FROM_DEVICE :
-+ OXNAS_DMA_TO_DEVICE;
-+
-+ /* now set-up the DMA transfer */
-+ if (qc->n_elem > 1)
-+ {
-+#ifdef SATA_DEBUG
-+ u32 total=0;
-+ int i=0;
-+ struct scatterlist* sg = qc->__sg;
-+ printk("Lengths: ");
-+ do {
-+ u32 len = sg_dma_len(sg++);
-+ printk("%u ", len);
-+ total += len;
-+ } while (++i < qc->n_elem);
-+ printk("\nTotal len = %u\n", total);
-+#endif // SATA_DEBUG
-+ /* try and setup scatter gather controller */
-+ if (oxnas_dma_device_set_prd(
-+ PrivateData->DmaChannel,
-+ direction,
-+ qc->ap->prd,
-+ &oxnas_sata_dma_settings,
-+ OXNAS_DMA_MODE_INC,
-+ PrivateData->sg_entries)) {
-+ printk(KERN_ERR"Failed to setup DMA with disk.\n");
-+ return;
-+ }
-+ }
-+ else
-+ {
-+#ifdef SATA_DEBUG
-+ printk("Total len = %u\n", sg_dma_len(qc->__sg));
-+#endif // SATA_DEBUG
-+ /* setup a single dma */
-+ oxnas_dma_device_set( PrivateData->DmaChannel,
-+ direction,
-+ (unsigned char* )sg_dma_address(qc->__sg),
-+ sg_dma_len(qc->__sg),
-+ &oxnas_sata_dma_settings,
-+ OXNAS_DMA_MODE_INC,
-+ 1); /* paused */
-+ }
-+}
-+
-+/**
-+ * When setting up an IDE BMDMA transaction, these hooks arm (->ignedmdma_setup)
-+ * and fire (->bmdma_start) the hardware's DMA engine.
-+ *
-+ * @param qc the queued command to issue
-+ */
-+static void ox810sata_bmdma_start(struct ata_queued_cmd *qc)
-+{
-+ ox810sata_private_data* PrivateData ;
-+ DPRINTK("\n");
-+ PrivateData = (ox810sata_private_data*)(qc->private_data);
-+
-+ /* start DMA transfer */
-+ oxnas_dma_start(PrivateData->DmaChannel);
-+ qc->ap->ops->exec_command(qc->ap, &(qc->tf));
-+}
-+
-+
-+/**
-+ * ata_qc_new - Request an available ATA command, for queueing
-+ * @ap: Port associated with device @dev
-+ * @dev: Device from whom we request an available command structure
-+ *
-+ * LOCKING:
-+ */
-+
-+static struct ata_queued_cmd* ox810sata_qc_new(struct ata_port *ap)
-+{
-+ struct ata_queued_cmd *qc = NULL;
-+
-+ VPRINTK("\n");
-+ /* no command while frozen */
-+ if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
-+ return NULL;
-+
-+ /* check to see that there are no internal commands active on either port*/
-+ if ((ox810sata_driver.ap[0]) && (ox810sata_driver.ap[0]->qc_allocated))
-+ return qc;
-+ if ((ox810sata_driver.ap[1]) && (ox810sata_driver.ap[1]->qc_allocated))
-+ return qc;
-+
-+ /* check if we're not doing a command */
-+ if (test_and_set_bit(0, &ox810sata_command_active))
-+ return qc;
-+
-+ /* now set the standard bits for compatibility */
-+ set_bit(0, &ap->qc_allocated);
-+ qc = __ata_qc_from_tag(ap, 0);
-+
-+#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
-+ /* disk light on */
-+ writel(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_SET);
-+#endif // CONFIG_SATA_OXNAS_DISK_LIGHT
-+#ifdef CONFIG_WDC_LEDS_TRIGGER_SATA_DISK
-+ wdc_ledtrig_sata_activity();
-+#endif // CONFIG_WDC_LEDS_TRIGGER_SATA_DISK
-+
-+ if (qc) {
-+ qc->tag = 0;
-+ }
-+
-+ return qc;
-+}
-+
-+
-+/**
-+ *
-+ */
-+static void ox810sata_qc_free(struct ata_queued_cmd *qc)
-+{
-+ unsigned int tag;
-+ struct ata_port *ap = qc->ap;
-+
-+ DPRINTK("\n");
-+
-+ qc->flags = 0;
-+ tag = qc->tag;
-+ if (likely(ata_tag_valid(tag))) {
-+ qc->tag = ATA_TAG_POISON;
-+ VPRINTK("clearing active bits\n");
-+ clear_bit(tag, &ap->qc_allocated);
-+ clear_bit(0, &ox810sata_command_active);
-+
-+#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
-+ /* disk light off */
-+ writel(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_CLEAR);
-+#endif /* CONFIG_SATA_OXNAS_DISK_LIGHT */
-+ }
-+}
-+
-+/**
-+ * qc_issue is used to make a command active, once the hardware and S/G tables
-+ * have been prepared. IDE BMDMA drivers use the helper function
-+ * ata_qc_issue_prot() for taskfile protocol-based dispatch. More advanced drivers
-+ * roll their own ->qc_issue implementation, using this as the "issue new ATA
-+ * command to hardware" hook.
-+ * @param qc the queued command to issue
-+ */
-+static unsigned int ox810sata_qc_issue(struct ata_queued_cmd *qc)
-+{
-+ int this_port_fail;
-+ struct bio* bio;
-+ u32 reg;
-+ ox810sata_private_data* private_data = (ox810sata_private_data*)qc->ap->private_data ;
-+ u32 raid_reg = 0; /* default to no raid */
-+ int port0fail = 0;
-+ int port1fail = 0;
-+ unsigned long flags = 0;
-+
-+ DPRINTK("\n");
-+
-+ /* get raid settings from the bio if they exist */
-+ if (qc->scsicmd && qc->scsicmd->request && qc->scsicmd->request->bio) {
-+ bio = qc->scsicmd->request->bio;
-+ raid_reg = bio->bi_raid ;
-+ //if (raid_reg) {printk("Hardware RAID :");tfdump(&qc->tf);}
-+
-+ }
-+ ox810sata_driver.hw_raid_active = raid_reg;
-+ ox810sata_driver.active_port = qc->ap;
-+
-+ /* check cable is still connected */
-+ ox810sata_scr_read(qc->ap, SCR_STATUS, ®);
-+ this_port_fail = (!(reg & 1));
-+
-+ /* check for failed ports prior to issuing raid-ed commands */
-+ if (raid_reg) {
-+ port0fail = (! (__ox810sata_scr_read((u32* )SATA0_REGS_BASE, 0x20 + (4 * SCR_STATUS) ) & 1 ) );
-+ port1fail = (! (__ox810sata_scr_read((u32* )SATA1_REGS_BASE, 0x20 + (4 * SCR_STATUS) ) & 1 ) );
-+ this_port_fail |= port1fail;
-+
-+ ox810sata_accumulated_RAID_faults |= port0fail ? 1 : 0 ;
-+ ox810sata_accumulated_RAID_faults |= port1fail ? 2 : 0 ;
-+ }
-+
-+ if (!this_port_fail) {
-+ /* clear phy/link errors */
-+ if (ox810sata_driver.ap[0])
-+ ox810sata_scr_write(ox810sata_driver.ap[0], SCR_ERROR, ~0);
-+ if (ox810sata_driver.ap[1])
-+ ox810sata_scr_write(ox810sata_driver.ap[1], SCR_ERROR, ~0);
-+
-+ /* clear errors on both hosts */
-+ reg = readl((u32* )SATA0_REGS_BASE + OX810SATA_SATA_CONTROL);
-+ reg |= OX810SATA_SCTL_CLR_ERR ;
-+ writel(reg, (u32* )SATA0_REGS_BASE + OX810SATA_SATA_CONTROL);
-+ reg = readl((u32* )SATA1_REGS_BASE + OX810SATA_SATA_CONTROL);
-+ reg |= OX810SATA_SCTL_CLR_ERR ;
-+ writel(reg, (u32* )SATA1_REGS_BASE + OX810SATA_SATA_CONTROL);
-+ reg = readl((u32* )SATARAID_REGS_BASE + OX810SATA_SATA_CONTROL);
-+ reg |= OX810SATA_SCTL_CLR_ERR ;
-+ writel(reg, (u32* )SATARAID_REGS_BASE + OX810SATA_SATA_CONTROL);
-+
-+ /* clear all interrupt bits */
-+ writel(~0, (u32* )SATA0_REGS_BASE + OX810SATA_INT_CLEAR);
-+ writel(~0, (u32* )SATA1_REGS_BASE + OX810SATA_INT_CLEAR);
-+ writel(~0, (u32* )SATARAID_REGS_BASE + OX810SATA_INT_CLEAR);
-+ writel(~0, OX810SATA_CORE_IEC );
-+
-+ /* hardware RAID */
-+ if ( raid_reg ) {
-+ /* set interrupt mode for raid controller interrupts only */
-+ writel(OX810SATA_RAID_INTS_WANTED, OX810SATA_CORE_IES );
-+
-+ /* at the moment we only do raid-1 */
-+ writel(OXNASSATA_RAID1, OX810SATA_RAID_CONTROL);
-+ writel(OXNASSATA_RAID_TWODISKS, OX810SATA_RAID_SET);
-+ } else {
-+ /* set normal interrupt scheme */
-+ writel(OX810SATA_NORMAL_INTS_WANTED, OX810SATA_CORE_IES);
-+
-+ /* Set the RAID controller hardware to idle */
-+ writel(OXNASSATA_NOTRAID, OX810SATA_RAID_CONTROL);
-+ }
-+
-+ /* call the default, this should be changed to take advantage of orb
-+ registers, etc... */
-+ return ata_qc_issue_prot(qc);
-+ } else {
-+ /* record the error */
-+ qc->err_mask |= AC_ERR_ATA_BUS;
-+
-+ /* maybee call ata qc complete? */
-+ local_irq_save(flags);
-+ ox810sata_irq_clear(qc->ap);
-+ private_data->int_status = 0;
-+ local_irq_restore(flags);
-+ ata_qc_complete(qc);
-+
-+ return 0;
-+ }
-+}
-+
-+/**
-+ * This is a high level error handling function, called from the error
-+ * handling thread, when a command times out.
-+ *
-+ * @param ap hardware with the registers in
-+ */
-+static void ox810sata_eng_timeout(struct ata_port *ap)
-+{
-+ struct ata_queued_cmd *qc;
-+ ox810sata_private_data* pd = (ox810sata_private_data*)ap->private_data;
-+ DPRINTK("\n");
-+
-+ /* set the in cleanup flag */
-+ pd->in_cleanup = 1;
-+
-+ /* if we're a PIO command existing cleanup won't be called */
-+ qc = ata_qc_from_tag(ap, ap->link.active_tag);
-+ if (qc->tf.protocol == ATA_PROT_PIO) {
-+ /* reset the core */
-+ ox810sata_timeout_cleanup(ap);
-+ }
-+
-+ /* clear the in cleanup flag */
-+ pd->in_cleanup = 0;
-+}
-+
-+/**
-+ * irq_handler is the interrupt handling routine registered with the system,
-+ * by libata.
-+ */
-+static irqreturn_t ox810sata_irq_handler(
-+ int irq,
-+ void *dev_instance)
-+{
-+ struct ata_port *ap = ((struct ata_host *)dev_instance)->ports[0];
-+ ox810sata_private_data *pd;
-+ u32 *ioaddr;
-+ u32 int_status;
-+ u32 count ;
-+
-+ DPRINTK("irq = %d\n", irq);
-+
-+ if (!ap || !ap->private_data)
-+ BUG();
-+
-+ /* check the ISR for the port to see if it created the interrupt */
-+ ioaddr = ox810sata_get_tfio_base(ap);
-+ int_status = readl(ioaddr + OX810SATA_INT_STATUS);
-+ if ( !(int_status & OX810SATA_INT_WANT ) ) {
-+ VPRINTK("not me!\n");
-+ return IRQ_NONE;
-+ }
-+
-+ pd = (ox810sata_private_data*)ap->private_data;
-+ while (int_status & OX810SATA_INT_MASKABLE) {
-+ /* store interrupt status for the bottom end */
-+ pd->int_status |= int_status;
-+
-+ /* Clear and mask pending interrupts */
-+ writel(int_status, ioaddr + OX810SATA_INT_CLEAR);
-+ writel(int_status, ioaddr + OX810SATA_INT_DISABLE);
-+
-+ int_status = readl(ioaddr + OX810SATA_INT_STATUS);
-+ }
-+
-+ // Wait a short while for the DMA to finish and if it doesn't start a thread
-+ // to poll for the finish
-+ pd->spot_the_end_work.ap = ap;
-+ for (count = 0; count < 10; ++count) {
-+ if (!oxnas_dma_raw_isactive(pd->DmaChannel)) {
-+ ox810sata_spot_the_end(&(pd->spot_the_end_work.worker));
-+ break;
-+ }
-+ udelay(100);
-+ }
-+
-+ if (count == 10) {
-+ /* Start a worker thread looking for the DMA channel to become idle */
-+ VPRINTK("queueing work \n");
-+ queue_work(ox810sata_driver.spot_the_end_q, &pd->spot_the_end_work.worker);
-+ }
-+ VPRINTK("done\n");
-+ return IRQ_HANDLED;
-+}
-+
-+/**
-+ * Work for a work queue, this will check for errors then wait for the DMA to
-+ * complete. On the DMA completing it will call ata_qc_complete
-+ */
-+static void ox810sata_spot_the_end(struct work_struct *work)
-+{
-+ struct spot_the_end_work_s* stew =
-+ container_of(work, struct spot_the_end_work_s, worker);
-+ struct ata_port* ap = stew->ap;
-+ ox810sata_private_data* PrivateData = (ox810sata_private_data* )ap->private_data;
-+ struct ata_queued_cmd* qc = ata_qc_from_tag(ap, ap->link.active_tag);
-+ unsigned long flags = 0;
-+
-+ VPRINTK("\n");
-+
-+ /* If there's no command ending associated with this IRQ, ignore it. */
-+ if (qc == NULL) {
-+ DPRINTK(" qc=null\n");
-+ return;
-+ }
-+
-+ /* The command may have aborted, this is indicated by the interrupt bit
-+ * being masked */
-+ if (PrivateData->in_cleanup) {
-+ DPRINTK("cleanup\n");
-+ return;
-+ }
-+
-+ /* get the status before any error cleanup */
-+ qc->err_mask = ac_err_mask(ata_chk_status(ap));
-+
-+ /* Look to see if the core is indicating an error condition after a RAID
-+ * command */
-+ if (qc->scsicmd &&
-+ qc->scsicmd->request &&
-+ qc->scsicmd->request->bio &&
-+ qc->scsicmd->request->bio->bi_raid ) {
-+ unsigned long Port0Irq = readl(((u32)(SATA0_REGS_BASE)) + OX810SATA_INT_STATUS);
-+ unsigned long Port1Irq = readl(((u32)(SATA1_REGS_BASE)) + OX810SATA_INT_STATUS);
-+
-+ if (OX810SATA_RAW_ERROR & Port0Irq) {
-+ printk(KERN_DEBUG"disk 0 error in hw-raid\n");
-+ ox810sata_accumulated_RAID_faults |= 1;
-+ }
-+ if (OX810SATA_RAW_ERROR & Port1Irq) {
-+ printk(KERN_DEBUG"disk 1 error in hw-raid\n");
-+ ox810sata_accumulated_RAID_faults |= 2;
-+ }
-+ }
-+
-+ /* if there was an error and the command hasn't finished, then we need to
-+ * abort the command */
-+ if ((PrivateData->int_status & 0xfffe) &&
-+ !(PrivateData->int_status & 0x1) &&
-+ (qc->tf.protocol == ATA_PROT_DMA))
-+ {
-+ DPRINTK(" int status 0x%08x, ata%u \n",PrivateData->int_status,ap->id);
-+ local_irq_save(flags);
-+ ox810sata_irq_clear(ap);
-+ PrivateData->int_status = 0;
-+ local_irq_restore(flags);
-+ ata_qc_complete(qc);
-+ return;
-+ }
-+
-+ if (!in_irq()) {
-+ /* wait for the DMA to finish */
-+ while (oxnas_dma_is_active(PrivateData->DmaChannel)) {
-+ schedule();
-+ }
-+ }
-+
-+ if (!(qc->flags & ATA_QCFLAG_ACTIVE)) {
-+ printk(KERN_WARNING "OX810 SATA: Command already completed!\n");
-+ return;
-+ }
-+
-+ /** @debug check for any padding */
-+ if(0)
-+ {
-+ unsigned int reg;
-+ reg = readl(OX810SATA_EXCESS);
-+ if (reg) {
-+ printk("command finished with a hint of padding\n");
-+ CrazyDumpDebug();
-+ }
-+ }
-+
-+ /* tell libata we're done */
-+ DPRINTK(" returning err_mask=0x%x\n", qc->err_mask);
-+ local_irq_save(flags);
-+ ox810sata_irq_clear(ap);
-+ PrivateData->int_status = 0;
-+ local_irq_restore(flags);
-+ ata_qc_complete(qc);
-+}
-+
-+/**
-+ * ox810sata_irq_clear is called during probe just before the interrupt handler is
-+ * registered, to be sure hardware is quiet. It clears and masks interrupt bits
-+ * in the SATA core.
-+ *
-+ * @param ap hardware with the registers in
-+ */
-+static void ox810sata_irq_clear(struct ata_port* ap)
-+{
-+ u32 *ioaddr = ox810sata_get_tfio_base(ap);
-+ //DPRINTK(KERN_INFO"ox810sata_irq_clear\n");
-+
-+ writel(~0, ioaddr + OX810SATA_INT_DISABLE);
-+ writel(~0, ioaddr + OX810SATA_INT_CLEAR);
-+}
-+
-+static inline u32 __ox810sata_scr_read(u32* core_addr, unsigned int sc_reg)
-+{
-+ u32 result;
-+ u32 patience;
-+
-+ /* we've got 8 other registers in before the start of the standard ones */
-+ writel(sc_reg, core_addr + OX810SATA_LINK_RD_ADDR );
-+
-+ for (patience = 0x100000; patience > 0; --patience) {
-+ if (readl(core_addr + OX810SATA_LINK_CONTROL) & 0x00000001) {
-+ break;
-+ }
-+ }
-+
-+ result = readl(core_addr + OX810SATA_LINK_DATA);
-+
-+ //DPRINTK(KERN_INFO"ox810sata_scr_read: [0x%02x]->0x%08x\n", sc_reg, result);
-+ return result;
-+}
-+
-+/**
-+ * Read standard SATA phy registers. Currently only used if
-+ * ->phy_reset hook called the sata_phy_reset() helper function.
-+ *
-+ * These registers are in another clock domain to the processor, access is via
-+ * some bridging registers
-+ *
-+ * @param ap hardware with the registers in
-+ * @param sc_reg the SATA PHY register
-+ * @return the value in the register
-+ */
-+static int ox810sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
-+{
-+ u32* ioaddr = ox810sata_get_io_base(ap);
-+ *val = __ox810sata_scr_read(ioaddr, 0x20 + (sc_reg*4));
-+ return 0;
-+}
-+
-+static void __ox810sata_scr_write(u32* core_addr, unsigned int sc_reg, u32 val)
-+{
-+ u32 patience;
-+
-+ //DPRINTK(KERN_INFO"ox810sata_scr_write: [0x%02x]<-0x%08x\n", sc_reg, val);
-+ writel(val, core_addr + OX810SATA_LINK_DATA );
-+ wmb();
-+ writel(sc_reg , core_addr + OX810SATA_LINK_WR_ADDR );
-+ wmb();
-+
-+ for (patience = 0x100000; patience > 0;--patience) {
-+ if (readl(core_addr + OX810SATA_LINK_CONTROL) & 0x00000001) {
-+ break;
-+ }
-+ }
-+}
-+/**
-+ * Write standard SATA phy registers. Currently only used if
-+ * phy_reset hook called the sata_phy_reset() helper function.
-+ *
-+ * These registers are in another clock domain to the processor, access is via
-+ * some bridging registers
-+ *
-+ * @param ap hardware with the registers in
-+ * @param sc_reg the SATA PHY register
-+ * @param val the value to write into the register
-+ */
-+static int ox810sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
-+{
-+ u32 *ioaddr = ox810sata_get_io_base(ap);
-+ __ox810sata_scr_write(ioaddr, 0x20 + (sc_reg * 4), val);
-+ return 0;
-+}
-+
-+/**
-+ * port_start() is called just after the data structures for each port are
-+ * initialized. Typically this is used to alloc per-port DMA buffers, tables
-+ * rings, enable DMA engines and similar tasks.
-+ *
-+ * @return 0 = success
-+ * @param ap hardware with the registers in
-+ */
-+static int ox810sata_port_start(struct ata_port *ap)
-+{
-+ ox810sata_private_data* pd;
-+ struct device* pdev = ap->host->dev;
-+
-+ ap->prd = dma_alloc_coherent(pdev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_DMA);
-+ if (!ap->prd) {
-+ return -ENOMEM;
-+ }
-+
-+ /* allocate port private data memory and attach to port */
-+ if (!ap->private_data) {
-+ ap->private_data = kmalloc(sizeof(ox810sata_private_data), GFP_KERNEL);
-+ }
-+
-+ if (!ap->private_data) {
-+ return -ENOMEM;
-+ }
-+
-+ pd = (ox810sata_private_data* )ap->private_data;
-+ pd->DmaChannel = 0;
-+ pd->sg_entries = 0;
-+
-+ DPRINTK("ap = %p, pd = %p\n",ap,ap->private_data);
-+
-+ // Allocate DMA SG entries
-+ if (oxnas_dma_alloc_sg_entries(&pd->sg_entries, CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES, 0)) {
-+ printk(KERN_WARNING "ox810sata_port_start() Failed to obtain DMA SG entries\n");
-+ return -ENOMEM;
-+ }
-+
-+ // Hold on to a DMA channel for the life of the SATA driver
-+ pd->DmaChannel = oxnas_dma_request(1);
-+
-+ if (!pd->DmaChannel) {
-+ printk(KERN_WARNING "ox810sata_port_start() Failed to obtain DMA channel\n");
-+ return -ENOMEM;
-+ }
-+
-+ /* declare a work item to spot when a command finishes */
-+ INIT_WORK(&(pd->spot_the_end_work.worker), &ox810sata_spot_the_end);
-+
-+ /* initialise to zero */
-+ pd->ErrorsWithNoCommamnd = 0;
-+ pd->int_status = 0;
-+ pd->in_cleanup = 0;
-+
-+ /* store the ata_port pointer in the driver structure */
-+ if (ox810sata_get_io_base(ap) == (u32*)SATA0_REGS_BASE) {
-+ ox810sata_driver.ap[0] = ap;
-+ } else if (ox810sata_get_io_base(ap) == (u32*)SATA1_REGS_BASE) {
-+ ox810sata_driver.ap[1] = ap;
-+ }
-+
-+ // turn ata core on
-+ writel((1 << SYS_CTRL_CKEN_SATA_BIT), SYS_CTRL_CKEN_SET_CTRL);
-+
-+ /* post reset init needs to be called for both ports as there's one reset
-+ for both ports*/
-+ if (ox810sata_driver.ap[0]) {
-+ ox810sata_post_reset_init(ox810sata_driver.ap[0]);
-+ }
-+ if (ox810sata_driver.ap[1]) {
-+ ox810sata_post_reset_init(ox810sata_driver.ap[1]);
-+ }
-+
-+ return 0;
-+}
-+
-+static void ox810sata_post_reset_init(struct ata_port* ap)
-+{
-+ u32 patience;
-+ u32* ioaddr = ox810sata_get_io_base(ap);
-+ uint dev;
-+
-+ /* turn on phy error detection by removing the masks */
-+ writel(0x30003, ioaddr + OX810SATA_LINK_DATA );
-+ wmb();
-+ writel(0x0C, ioaddr + OX810SATA_LINK_WR_ADDR );
-+ wmb();
-+ for (patience = 0x100000; patience > 0;--patience) {
-+ if (readl(ioaddr + OX810SATA_LINK_CONTROL) & 0x00000001) {
-+ break;
-+ }
-+ }
-+
-+ /* enable interrupts for ports */
-+ VPRINTK("Enable interrupts\n");
-+ writel(~0, OX810SATA_CORE_IEC);
-+ writel(OX810SATA_NORMAL_INTS_WANTED, OX810SATA_CORE_IES);
-+
-+ /* go through all the devices and configure them */
-+ for (dev = 0; dev < ATA_MAX_DEVICES; ++dev) {
-+ if (ap->link.device[dev].class == ATA_DEV_ATA) {
-+ ox810sata_phy_reset(ap);
-+ ox810sata_dev_config(ap, &(ap->link.device[dev]));
-+ }
-+ }
-+
-+ /* disable padding */
-+/* {
-+ unsigned int reg = readl(OX810SATA_DEVICE_CONTROL);
-+ reg &= ~OX810SATA_DEVICE_CONTROL_PAD ;
-+ writel(reg, OX810SATA_DEVICE_CONTROL);
-+ }*/
-+ {
-+ unsigned int reg = readl(OX810SATA_DEVICE_CONTROL);
-+ reg |= OX810SATA_DEVICE_CONTROL_PADPAT ;
-+ writel(reg, OX810SATA_DEVICE_CONTROL);
-+ }
-+}
-+
-+/**
-+ * port_stop() is called after ->host_stop(). It's sole function is to
-+ * release DMA/memory resources, now that they are no longer actively being
-+ * used.
-+ */
-+static void ox810sata_port_stop(struct ata_port *ap)
-+{
-+ ox810sata_private_data* pd = (ox810sata_private_data* )ap->private_data;
-+
-+ DPRINTK("\n");
-+
-+ if (pd->DmaChannel) {
-+ oxnas_dma_free(pd->DmaChannel);
-+ pd->DmaChannel = 0;
-+ }
-+
-+ if (pd->sg_entries) {
-+ oxnas_dma_free_sg_entries(pd->sg_entries);
-+ pd->sg_entries = 0;
-+ }
-+
-+ kfree(pd);
-+}
-+
-+/**
-+ * host_stop() is called when the rmmod or hot unplug process begins. The
-+ * hook must stop all hardware interrupts, DMA engines, etc.
-+ *
-+ * @param ap hardware with the registers in
-+ */
-+static void ox810sata_host_stop(struct ata_host *host_set)
-+{
-+ DPRINTK("\n");
-+}
-+
-+/**
-+ * PATA device presence detection
-+ * @param ap ATA channel to examine
-+ * @param device Device to examine (starting at zero)
-+ * @return true if something found
-+ *
-+ * This technique was originally described in
-+ * Hale Landis's ATADRVR (www.ata-atapi.com), and
-+ * later found its way into the ATA/ATAPI spec.
-+ *
-+ * Write a pattern to the ATA shadow registers,
-+ * and if a device is present, it will respond by
-+ * correctly storing and echoing back the
-+ * ATA shadow register contents.
-+ *
-+ * LOCKING:
-+ * caller.
-+ */
-+static unsigned int ox810sata_devchk(struct ata_port *ap,unsigned int device)
-+{
-+ DPRINTK("\n");
-+
-+ return 0; /* nothing found */
-+}
-+
-+static void ox810sata_pio_start(struct work_struct *work)
-+{
-+ struct ata_port *ap = container_of(work, struct ata_port, port_task.work);
-+ ox810sata_private_data* pd = (ox810sata_private_data*)ap->private_data;
-+ struct ata_queued_cmd* qc = ap->port_task_data;
-+ u32* ioaddr = ox810sata_get_io_base(ap);
-+ unsigned long flags = 0;
-+
-+ VPRINTK("\n");
-+ // We check for DMA completion from ISR which cannot wait for all DMA channel
-+ // housekeeping to complete, so need to wait here is case we try to reuse
-+ // channel before that housekeeping has completed
-+ if (oxnas_dma_is_active(pd->DmaChannel)) {
-+ printk(KERN_WARNING "PIO start Channel still active\n");
-+ /* if the DMA is still busy, schedule a task to poll again in 1 ms */
-+ ata_port_queue_task(ap, ox810sata_pio_start, qc, ATA_SHORT_PAUSE);
-+ return;
-+ }
-+
-+ if (qc->tf.protocol != ATA_PROT_NODATA) {
-+ oxnas_dma_direction_t direction = (qc->dma_dir == DMA_FROM_DEVICE) ?
-+ OXNAS_DMA_FROM_DEVICE :
-+ OXNAS_DMA_TO_DEVICE;
-+
-+ /* Do not use DMA callback */
-+ oxnas_dma_set_callback(pd->DmaChannel, OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
-+
-+ /* map memory for dma */
-+ dma_map_sg(NULL, qc->__sg, qc->n_elem, qc->dma_dir);
-+
-+ /* setup a scatter gather dma */
-+ oxnas_dma_device_set_sg(pd->DmaChannel,
-+ direction,
-+ qc->__sg,
-+ qc->n_elem,
-+ &oxnas_sata_dma_settings,
-+ OXNAS_DMA_MODE_INC,
-+ 0);
-+
-+ oxnas_dma_start(pd->DmaChannel);
-+
-+ if (oxnas_dma_is_active(pd->DmaChannel)) {
-+ /* if the DMA is still busy, schedule a task to poll again in 1 ms */
-+ ata_port_queue_task(ap, ox810sata_pio_task, qc, ATA_SHORT_PAUSE);
-+ return;
-+ }
-+
-+ /* cleanup DMA */
-+ dma_unmap_sg(NULL, qc->__sg, qc->n_elem, qc->dma_dir);
-+ } else {
-+ /* if the core is still busy, reschedule */
-+ if (readl(ioaddr + OX810SATA_SATA_COMMAND) & CMD_CORE_BUSY) {
-+ ata_port_queue_task(ap, ox810sata_pio_task, qc, ATA_SHORT_PAUSE);
-+ return;
-+ }
-+ }
-+
-+ /* notify of completion */
-+ PretendDRQIsClear = 1;
-+ qc->err_mask = ac_err_mask(ata_chk_status(ap));
-+ spin_lock_irqsave(ap->lock, flags);
-+ ap->ops->irq_on(ap);
-+ ata_qc_complete(qc);
-+ spin_unlock_irqrestore(ap->lock, flags);
-+}
-+
-+/**
-+ * This is the top level of the PIO task. It is responsible for organising the
-+ * transfer of data, collecting and reacting to status changes and notification
-+ * of command completion.
-+ *
-+ */
-+static void ox810sata_pio_task(struct work_struct *work)
-+{
-+ struct ata_port *ap = container_of(work, struct ata_port, port_task.work);
-+ struct ata_queued_cmd *qc = ap->port_task_data;
-+ u32* ioaddr = ox810sata_get_io_base(ap);
-+ unsigned long flags = 0;
-+ VPRINTK("\n");
-+
-+ if (qc->tf.protocol != ATA_PROT_NODATA) {
-+ ox810sata_private_data* pd = (ox810sata_private_data* )ap->private_data;
-+
-+ /* if the DMA is still busy and there is no error, re-schedule the task */
-+ /* try again in 1 ms */
-+ if ((oxnas_dma_is_active(pd->DmaChannel)) &&
-+ !(readl(ioaddr + OX810SATA_INT_STATUS) & OX810SATA_RAW_ERROR) ) {
-+ ata_port_queue_task(ap, ox810sata_pio_task, qc, ATA_SHORT_PAUSE);
-+ return;
-+ }
-+
-+ /* cleanup DMA */
-+ dma_unmap_sg(NULL, qc->__sg, qc->n_elem, qc->dma_dir);
-+ } else {
-+ /* if the core is still busy, reschedule */
-+ if ((readl(ioaddr + OX810SATA_SATA_COMMAND) & CMD_CORE_BUSY) &&
-+ !(readl(ioaddr + OX810SATA_INT_STATUS) & OX810SATA_RAW_ERROR) ) {
-+ ata_port_queue_task(ap, ox810sata_pio_task, qc, ATA_SHORT_PAUSE);
-+ return;
-+ }
-+ }
-+
-+ /* notify of completion */
-+ PretendDRQIsClear = 1;
-+ qc->err_mask = ac_err_mask(ata_chk_status(ap));
-+ spin_lock_irqsave(ap->lock, flags);
-+ ap->ops->irq_on(ap);
-+ ata_qc_complete(qc);
-+ spin_unlock_irqrestore(ap->lock, flags);
-+}
-+
-+static void ox810sata_bmdma_stop(struct ata_queued_cmd *qc)
-+{
-+ struct ata_port *ap = qc->ap;
-+ ox810sata_private_data* private_data = (ox810sata_private_data*)ap->private_data;
-+
-+ /* Check if DMA is in progress, if so abort */
-+ if (oxnas_dma_is_active(private_data->DmaChannel)) {
-+ /*
-+ * Attempt to abort any current transfer:
-+ * Abort DMA transfer at the DMA controller,
-+ */
-+ printk(KERN_ERR "ox810sata_bmdma_stop - aborting DMA\n");
-+
-+ oxnas_dma_abort(private_data->DmaChannel, 1);
-+ }
-+
-+ /* perform core cleanups and resets as required */
-+ ox810sata_timeout_cleanup(ap);
-+}
-+
-+/**
-+ * @param ap ata port, not used
-+ */
-+static void ox810sata_timeout_cleanup(struct ata_port *ap) {
-+ u32 reg;
-+ u32 patience;
-+
-+// CrazyDumpDebug();
-+
-+ /* Clear error bits in both ports */
-+ reg = readl((u32*)SATA0_REGS_BASE + OX810SATA_SATA_CONTROL);
-+ reg |= OX810SATA_SCTL_CLR_ERR ;
-+ writel(reg, (u32*)SATA0_REGS_BASE + OX810SATA_SATA_CONTROL);
-+ reg = readl((u32*)SATA1_REGS_BASE + OX810SATA_SATA_CONTROL);
-+ reg |= OX810SATA_SCTL_CLR_ERR ;
-+ writel(reg, (u32*)SATA1_REGS_BASE + OX810SATA_SATA_CONTROL);
-+ reg = readl((u32* )SATARAID_REGS_BASE + OX810SATA_SATA_CONTROL);
-+ reg |= OX810SATA_SCTL_CLR_ERR ;
-+ writel(reg, (u32* )SATARAID_REGS_BASE + OX810SATA_SATA_CONTROL);
-+
-+ /* Test SATA core idle state */
-+ if ( !(~readl(OX810SATA_IDLE_STATUS) & OX810SATA_IDLE_CORES) ) {
-+ return;
-+ }
-+
-+// CrazyDumpDebug();
-+
-+ /* abort DMA */
-+ printk(KERN_INFO"ox810sata aborting DMA.\n");
-+ reg = readl(OX810SATA_DEVICE_CONTROL);
-+ writel(reg | OX810SATA_DEVICE_CONTROL_ABORT, OX810SATA_DEVICE_CONTROL);
-+
-+ /* wait until patience runs out for the core to go idle */
-+ patience = 50;
-+ do {
-+ /* if the core is idle, clear the abort bit and return */
-+ if ( !(~readl(OX810SATA_IDLE_STATUS) & OX810SATA_IDLE_CORES) ) {
-+ writel(reg & ~OX810SATA_DEVICE_CONTROL_ABORT, OX810SATA_DEVICE_CONTROL);
-+ return;
-+ }
-+ mdelay(1);
-+ } while (--patience);
-+ writel(reg & ~OX810SATA_DEVICE_CONTROL_ABORT, OX810SATA_DEVICE_CONTROL);
-+
-+// CrazyDumpDebug();
-+
-+ /* command a sync escape on both ports */
-+ printk(KERN_INFO"ox810sata sending sync escapes\n");
-+
-+ /* port 0 */
-+ reg = readl((u32*)SATA0_REGS_BASE + OX810SATA_SATA_COMMAND);
-+ reg &= ~SATA_OPCODE_MASK;
-+ reg |= CMD_SYNC_ESCAPE;
-+ writel(reg, (u32*)SATA0_REGS_BASE + OX810SATA_SATA_COMMAND);
-+
-+ /* wait until patience runs out for the core to go idle */
-+ patience = 50;
-+ do {
-+ /* if the core is idle, clear the abort bit and return */
-+ if ( !(~readl(OX810SATA_IDLE_STATUS) & OX810SATA_IDLE_CORES) ) {
-+ return;
-+ }
-+ mdelay(1);
-+ } while (--patience);
-+
-+ /* port 1 */
-+ reg = readl((u32*)SATA1_REGS_BASE + OX810SATA_SATA_COMMAND);
-+ reg &= ~SATA_OPCODE_MASK;
-+ reg |= CMD_SYNC_ESCAPE;
-+ writel(reg, (u32*)SATA1_REGS_BASE + OX810SATA_SATA_COMMAND);
-+
-+ /* wait until patience runs out for the core to go idle */
-+ patience = 50;
-+ do {
-+ /* if the core is idle, clear the abort bit and return */
-+ if ( !(~readl(OX810SATA_IDLE_STATUS) & OX810SATA_IDLE_CORES) ) {
-+ return;
-+ }
-+ mdelay(1);
-+ } while (--patience);
-+
-+// CrazyDumpDebug();
-+
-+ /* SATA core did not go idle, so cause a SATA core reset from the RPS */
-+ CrazyDumpDebug();
-+ printk(KERN_INFO "ox810sata core reset\n");
-+ ox810sata_reset_core();
-+
-+ /* Read SATA core idle state */
-+ if (~readl(OX810SATA_IDLE_STATUS) & OX810SATA_IDLE_CORES) {
-+ printk(KERN_INFO"ox810sata core still busy\n");
-+ CrazyDumpDebug();
-+ }
-+
-+ /* Perform any SATA core re-initialisation after reset */
-+ /* post reset init needs to be called for both ports as there's one reset
-+ for both ports*/
-+ if (ox810sata_driver.ap[0]) {
-+ ox810sata_post_reset_init(ox810sata_driver.ap[0]);
-+ }
-+ if (ox810sata_driver.ap[1]) {
-+ ox810sata_post_reset_init(ox810sata_driver.ap[1]);
-+ }
-+}
-+
-+
-+static void ox810sata_error_handler(struct ata_port *ap)
-+{
-+ return ata_bmdma_drive_eh(ap, ox810sata_prereset, ata_std_softreset,
-+ ox810sata_hardreset, ox810sata_postreset);
-+}
-+
-+
-+
-+/**
-+ * bmdma_status return a made up version of a BMDMA status register
-+ *
-+ * @param ap Hardware with the registers in
-+ * @return the value ATA_DMA_INTR if the interrupt came from the DMA finishing
-+ */
-+static u8 ox810sata_bmdma_status(struct ata_port *ap)
-+{
-+ return ATA_DMA_INTR;
-+}
-+
-+/**
-+ * turn on the interrupts from the ata drive
-+ * wait for idle, clear any pending interrupts.
-+ *
-+ * @param ap Hardware with the registers in
-+ */
-+static u8 ox810sata_irq_on(struct ata_port *ap)
-+{
-+ u32* ioaddr = ox810sata_get_tfio_base(ap);
-+ u8 tmp;
-+
-+ //DPRINTK(KERN_INFO"ox810sata_irq_on\n");
-+
-+ /* enable End of command interrupt */
-+ writel(~0, ioaddr + OX810SATA_INT_CLEAR);
-+ writel(OX810SATA_INT_WANT, ioaddr + OX810SATA_INT_ENABLE);
-+ tmp = ata_wait_idle(ap);
-+
-+ return tmp;
-+}
-+
-+/**
-+ * ox810_prereset - prepare for reset
-+ * @param link ATA link to be reset
-+ * @param deadline deadline jiffies for the operation
-+ *
-+ * link is about to be reset. Initialize it. Failure from
-+ * prereset makes libata abort whole reset sequence and give up
-+ * that port, so prereset should be best-effort. It does its
-+ * best to prepare for reset sequence but if things go wrong, it
-+ * should just whine, not fail.
-+ *
-+ * LOCKING:
-+ * Kernel thread context (may sleep)
-+ *
-+ * RETURNS:
-+ * 0 on success, -errno otherwise.
-+ */
-+static int ox810sata_prereset(struct ata_link *link, unsigned long deadline) {
-+ struct ata_port *ap = link->ap;
-+ struct ata_eh_context *ehc = &link->eh_context;
-+ const unsigned long *timing = sata_ehc_deb_timing(ehc);
-+ ox810sata_private_data* private_data;
-+ int rc;
-+
-+ VPRINTK("\n");
-+ /* handle link resume */
-+ if ((ehc->i.flags & ATA_EHI_RESUME_LINK) && (link->flags & ATA_LFLAG_HRST_TO_RESUME))
-+ ehc->i.action |= ATA_EH_HARDRESET;
-+
-+ /* Some PMPs don't work with only SRST, force hardreset if PMP
-+ * is supported.
-+ */
-+ if (ap->flags & ATA_FLAG_PMP)
-+ ehc->i.action |= ATA_EH_HARDRESET;
-+
-+ /* if we're about to do hardreset, nothing more to do */
-+ if (ehc->i.action & ATA_EH_HARDRESET)
-+ return 0;
-+
-+ /* we want both ports to be idle as soft-reset requires being able to send
-+ commands. If a command is running, abort it. */
-+ private_data = (ox810sata_private_data*)ap->private_data;
-+
-+ /* Check if DMA is in progress, if so abort */
-+ if (oxnas_dma_is_active(private_data->DmaChannel)) {
-+ /*
-+ * Attempt to abort any current transfer:
-+ * Abort DMA transfer at the DMA controller,
-+ */
-+ printk(KERN_ERR "aborting DMA\n");
-+ oxnas_dma_abort(private_data->DmaChannel, 1);
-+ }
-+
-+ /* perform core cleanups and resets */
-+ ox810sata_timeout_cleanup(NULL);
-+
-+ /* if SATA, resume link */
-+ if (ap->flags & ATA_FLAG_SATA) {
-+ rc = sata_link_resume(link, timing, deadline);
-+ /* whine about phy resume failure but proceed */
-+ if (rc && rc != -EOPNOTSUPP)
-+ ata_link_printk(link, KERN_WARNING, "failed to resume "
-+ "link for reset (errno=%d)\n", rc);
-+ }
-+
-+ /* Wait for !BSY if the controller can wait for the first D2H
-+ * Reg FIS and we don't know that no device is attached.
-+ */
-+ if (!(link->flags & ATA_LFLAG_SKIP_D2H_BSY) && !ata_link_offline(link)) {
-+ rc = ata_wait_ready(ap, deadline);
-+ if (rc && rc != -ENODEV) {
-+ ata_link_printk(link, KERN_WARNING, "device not ready "
-+ "(errno=%d), forcing hardreset\n", rc);
-+ ehc->i.action |= ATA_EH_HARDRESET;
-+ }
-+ }
-+
-+ return 0;
-+}
-+/**
-+ * sata_std_hardreset - reset host port via SATA phy reset
-+ * @link: link to reset
-+ * @class: resulting class of attached device
-+ * @deadline: deadline jiffies for the operation
-+ *
-+ * SATA phy-reset host port using DET bits of SControl register,
-+ * wait for !BSY and classify the attached device.
-+ *
-+ * LOCKING:
-+ * Kernel thread context (may sleep)
-+ *
-+ * RETURNS:
-+ * 0 on success, -errno otherwise.
-+ */
-+static int ox810sata_hardreset(struct ata_link *link, unsigned int *class,
-+ unsigned long deadline)
-+{
-+ struct ata_port *ap = link->ap;
-+ const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
-+ int rc;
-+
-+ DPRINTK("ENTER\n");
-+
-+ /* do hardreset */
-+ rc = sata_link_hardreset(link, timing, deadline);
-+ if (rc) {
-+ ata_link_printk(link, KERN_ERR,
-+ "COMRESET failed (errno=%d)\n", rc);
-+ return rc;
-+ }
-+
-+ /* TODO: phy layer with polling, timeouts, etc. */
-+ if (ata_link_offline(link)) {
-+ *class = ATA_DEV_NONE;
-+ DPRINTK("EXIT, link offline\n");
-+ return 0;
-+ }
-+
-+ /* wait a while before checking status */
-+ ata_wait_after_reset(ap, deadline);
-+
-+ /* If PMP is supported, we have to do follow-up SRST. Note
-+ * that some PMPs don't send D2H Reg FIS after hardreset at
-+ * all if the first port is empty. Wait for it just for a
-+ * second and request follow-up SRST.
-+ */
-+ if (ap->flags & ATA_FLAG_PMP) {
-+ ata_wait_ready(ap, jiffies + HZ);
-+ return -EAGAIN;
-+ }
-+
-+ rc = ata_wait_ready(ap, deadline);
-+ /* link occupied, -ENODEV too is an error */
-+ if (rc) {
-+ ata_link_printk(link, KERN_ERR,
-+ "COMRESET failed (errno=%d)\n", rc);
-+ return rc;
-+ }
-+
-+ *class = ata_dev_try_classify(link->device, 1, NULL);
-+
-+ DPRINTK("EXIT, class=%u\n", *class);
-+ return 0;
-+}
-+
-+/**
-+ * ata_std_postreset - standard postreset callback
-+ * @link: the target ata_link
-+ * @classes: classes of attached devices
-+ *
-+ * This function is invoked after a successful reset. Note that
-+ * the device might have been reset more than once using
-+ * different reset methods before postreset is invoked.
-+ *
-+ * LOCKING:
-+ * Kernel thread context (may sleep)
-+ */
-+static void ox810sata_postreset(struct ata_link *link, unsigned int *classes)
-+{
-+ struct ata_port *ap = link->ap;
-+ u32 serror;
-+ unsigned int dev;
-+
-+ DPRINTK("ENTER\n");
-+
-+ /* print link status */
-+ sata_print_link_status(link);
-+
-+ /* clear SError */
-+ if (sata_scr_read(link, SCR_ERROR, &serror) == 0)
-+ sata_scr_write(link, SCR_ERROR, serror);
-+ link->eh_info.serror = 0;
-+
-+ /* turn on phy error detection by removing the masks */
-+ __ox810sata_scr_write((u32* )SATA0_REGS_BASE , 0x0c, 0x30003 );
-+ __ox810sata_scr_write((u32* )SATA1_REGS_BASE , 0x0c, 0x30003 );
-+
-+ /* bail out if no device is present */
-+ if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
-+ DPRINTK("EXIT, no device\n");
-+ return;
-+ }
-+
-+ /* go through all the devices and configure them */
-+ for (dev = 0; dev < ATA_MAX_DEVICES; ++dev) {
-+ if (ap->link.device[dev].class == ATA_DEV_ATA) {
-+ ox810sata_dev_config(ap, &(ap->link.device[dev]));
-+ }
-+ }
-+
-+ /* disable padding */
-+ {
-+ unsigned int reg = readl(OX810SATA_DEVICE_CONTROL);
-+ reg &= ~OX810SATA_DEVICE_CONTROL_PAD ;
-+ writel(reg, OX810SATA_DEVICE_CONTROL);
-+ }
-+
-+ /** @todo fix by using tf/tf_load as in ata_bus_softreset */
-+ #if 0
-+ /* set up device control */
-+ if (ap->ioaddr.ctl_addr)
-+ iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
-+ #endif
-+
-+ DPRINTK("EXIT\n");
-+}
-+
-+/**
-+ * Outputs all the registers in the SATA core for diagnosis of faults.
-+ *
-+ * @param ap Hardware with the registers in
-+ */
-+static void CrazyDumpDebug()
-+{
-+#ifdef CRAZY_DUMP_DEBUG
-+ u32 offset;
-+ u32 result;
-+ u32 patience;
-+ volatile u32* ioaddr;
-+
-+#if 0
-+ {
-+ u32 i ;
-+ for(i = 0;i < 1024;++i) {
-+ printk("[%08x]%s%08x\n",
-+ regarray[regindex].a,
-+ regarray[regindex].w ? "<=" : "=>",
-+ regarray[regindex].d
-+ );
-+ ++regindex;
-+ regindex &= 1023;
-+ }
-+ }
-+#endif
-+
-+ /* port 0 */
-+ ioaddr = (u32* )SATA0_REGS_BASE;
-+ printk("Port 0 High level registers\n");
-+ for(offset = 0; offset < 48;offset++)
-+ {
-+ printk("[%02x] %08x\n", offset * 4, *(ioaddr + offset));
-+ }
-+
-+ printk("Port 0 link layer registers\n");
-+ for(offset = 0; offset < 16;++offset)
-+ {
-+ *(ioaddr + OX810SATA_LINK_RD_ADDR ) = (offset*4);
-+ wmb();
-+
-+ for (patience = 0x100000;patience > 0;--patience)
-+ {
-+ if (*(ioaddr + OX810SATA_LINK_CONTROL) & 0x00000001)
-+ break;
-+ }
-+
-+ result = *(ioaddr + OX810SATA_LINK_DATA);
-+ printk("[%02x] %08x\n", offset*4, result);
-+ }
-+
-+ /* port 1 */
-+ ioaddr = (u32* )SATA1_REGS_BASE;
-+ printk("Port 1 High level registers\n");
-+ for(offset = 0; offset < 48;offset++)
-+ {
-+ printk("[%02x] %08x\n", offset * 4, *(ioaddr + offset));
-+ }
-+
-+ printk("Port 1 link layer registers\n");
-+ for(offset = 0; offset < 16;++offset)
-+ {
-+ *(ioaddr + OX810SATA_LINK_RD_ADDR ) = (offset*4);
-+ wmb();
-+
-+ for (patience = 0x100000;patience > 0;--patience)
-+ {
-+ if (*(ioaddr + OX810SATA_LINK_CONTROL) & 0x00000001)
-+ break;
-+ }
-+
-+ result = *(ioaddr + OX810SATA_LINK_DATA);
-+ printk("[%02x] %08x\n", offset*4, result);
-+ }
-+
-+ /* port 14 */
-+ ioaddr = (u32* )SATARAID_REGS_BASE;
-+ printk("RAID registers\n");
-+ for(offset = 0; offset < 48;offset++)
-+ {
-+ printk("[%02x] %08x\n", offset * 4, *(ioaddr + offset));
-+ }
-+
-+ /* port 15 */
-+ ioaddr = (u32* )SATACORE_REGS_BASE;
-+ printk("CORE registers\n");
-+ for(offset = 0; offset < 48;offset++)
-+ {
-+ printk("[%02x] %08x\n", offset * 4, *(ioaddr + offset));
-+ }
-+
-+ oxnas_dma_dump_registers();
-+
-+#endif
-+}
-+
-+/**************************************************************************
-+* DEVICE CODE
-+**************************************************************************/
-+
-+/**
-+ * Describes the identity of the SATA core and the resources it requires
-+ */
-+static struct resource ox810sata_port0_resources[] = {
-+ {
-+ .name = "sata_port_0_registers",
-+ .start = SATA0_REGS_BASE,
-+ .end = SATA0_REGS_BASE + 0xff,
-+ .flags = IORESOURCE_MEM,
-+ },
-+ {
-+ .name = "sata_irq",
-+ .start = SATA_1_INTERRUPT,
-+ .flags = IORESOURCE_IRQ,
-+ }
-+};
-+
-+static struct resource ox810sata_port1_resources[] = {
-+ {
-+ .name = "sata_port_1_registers",
-+ .start = SATA1_REGS_BASE,
-+ .end = SATA1_REGS_BASE + 0xff,
-+ .flags = IORESOURCE_MEM,
-+ },
-+ {
-+ .name = "sata_irq",
-+ .start = SATA_1_INTERRUPT,
-+ .flags = IORESOURCE_IRQ,
-+ },
-+};
-+
-+static struct platform_device ox810sata_dev0 =
-+{
-+ .name = DRIVER_NAME,
-+ .id = 0,
-+ .num_resources = 2,
-+ .resource = ox810sata_port0_resources,
-+ .dev.coherent_dma_mask = 0xffffffff,
-+};
-+
-+static struct platform_device ox810sata_dev1 =
-+{
-+ .name = DRIVER_NAME,
-+ .id = 1,
-+ .num_resources = 2,
-+ .resource = ox810sata_port1_resources,
-+ .dev.coherent_dma_mask = 0xffffffff,
-+};
-+
-+/**
-+ * module initialisation
-+ * @return success is 0
-+ */
-+static int __init ox810sata_device_init( void )
-+{
-+ int ret;
-+
-+ /* reset the core */
-+ ox810sata_reset_core();
-+
-+ {
-+ // register the ata device for the driver to find
-+ ret = platform_device_register( &ox810sata_dev0 );
-+ DPRINTK(" %i\n", ret);
-+ }
-+
-+#ifndef CONFIG_OX810SATA_SINGLE_SATA
-+ {
-+ // register the ata device for the driver to find
-+ ret = platform_device_register( &ox810sata_dev1 );
-+ DPRINTK(" %i\n", ret);
-+ }
-+#endif /* CONFIG_OX810_SINGLE_SATA */
-+
-+ return ret;
-+}
-+
-+/**
-+ * module cleanup
-+ */
-+static void __exit ox810sata_device_exit(void)
-+{
-+ platform_device_unregister( &ox810sata_dev0 );
-+ platform_device_unregister( &ox810sata_dev1 );
-+}
-+
-+/**
-+ * Returns accumulated RAID faults and then clears the accumulation
-+ * @return accumulated RAID faults indicated by set bits
-+ */
-+int oxnassata_RAID_faults( void ) {
-+ int temp = ox810sata_accumulated_RAID_faults;
-+ ox810sata_accumulated_RAID_faults = 0;
-+ return temp;
-+}
-+
-+/**
-+ * Returns ox810 port number the request queue is serviced by.
-+ *
-+ * @param queue The queue under investigation.
-+ * @return The ox810 sata port number servicing the queue or -1 if not found.
-+ */
-+int oxnassata_get_port_no(struct request_queue* q)
-+{
-+ struct ata_port* ap = 0;
-+ struct scsi_device* sdev = 0;
-+
-+ /* check port 0 */
-+ ap = ox810sata_driver.ap[0];
-+ if (ap)
-+ shost_for_each_device(sdev, ap->scsi_host) {
-+ if (sdev->request_queue == q) {
-+ DPRINTK("Queue %p on port 0\n", q);
-+ return 0;
-+ }
-+ }
-+
-+ /* check port 1 */
-+ ap = ox810sata_driver.ap[1];
-+ if (ap)
-+ shost_for_each_device(sdev, ap->scsi_host) {
-+ if (sdev->request_queue == q) {
-+ DPRINTK("Queue %p on port 1\n", q);
-+ return 1;
-+ }
-+ }
-+
-+ /* not found */
-+ return -1;
-+}
-+
-+/**
-+ * @return true if all the drives attached to the internal SATA ports use the
-+ * same LBA size.
-+ */
-+int oxnassata_LBA_schemes_compatible( void )
-+{
-+ unsigned long flags0 ;
-+ unsigned long flags1 ;
-+ struct ata_port* ap ;
-+
-+ /* check port 0 */
-+ ap = ox810sata_driver.ap[0];
-+ if (ap)
-+ flags0 = ap->link.device[0].flags & ATA_DFLAG_LBA48 ;
-+ else
-+ return 0;
-+
-+ /* check port 1 */
-+ ap = ox810sata_driver.ap[1];
-+ if (ap)
-+ flags1 = ap->link.device[0].flags & ATA_DFLAG_LBA48 ;
-+ else
-+ return 0;
-+
-+ /* compare */
-+ return (flags0 == flags1);
-+}
-+
-+EXPORT_SYMBOL( oxnassata_RAID_faults );
-+EXPORT_SYMBOL( oxnassata_get_port_no );
-+EXPORT_SYMBOL( oxnassata_LBA_schemes_compatible );
-+
-+
-+#ifdef ERROR_INJECTION
-+
-+/**
-+ * @param kobj Not Used
-+ * @param attr Used to determine which file is being accessed
-+ * @param buffer Space to put the file contents
-+ * @return The number of bytes transferred or an error
-+ */
-+static int ox810sata_error_inject_show(
-+ char *page, char **start, off_t off, int count, int *eof, void *data)
-+{
-+ if (page)
-+ {
-+ if ( ox810sata_driver.error_inject ) {
-+ page[0] = ox810sata_driver.error_inject + '0';
-+ page[1] = '\n';
-+ page[2] = 0;
-+ return 3;
-+ } else {
-+ strcpy(page, "off\n" );
-+ return 5;
-+ }
-+ }
-+
-+ /* if we get here, there's been an error */
-+ return -EIO;
-+}
-+
-+
-+static int ox810sata_error_inject_store(struct file *file,
-+ const char __user *buffer,
-+ unsigned long count,
-+ void *data) {
-+ if (count)
-+ {
-+ if ((buffer[0] >= '0') &&
-+ (buffer[0] <= '9')) {
-+ ox810sata_driver.error_inject = buffer[0] - '0';
-+ }
-+ return count;
-+ }
-+
-+ /* if we get here, there's been an error */
-+ return -EIO;
-+}
-+
-+#endif /* ERROR_INJECTION */
-+
-+
-+
-+/**
-+ * macros to register intiialisation and exit functions with kernal
-+ */
-+module_init(ox810sata_device_init);
-+module_exit(ox810sata_device_exit);
-diff -Nurd linux-2.6.24/drivers/ata/pata_hpt366.c linux-2.6.24-oxe810/drivers/ata/pata_hpt366.c
---- linux-2.6.24/drivers/ata/pata_hpt366.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/pata_hpt366.c 2008-06-11 17:50:32.000000000 +0200
-@@ -27,7 +27,7 @@
- #include <linux/libata.h>
-
- #define DRV_NAME "pata_hpt366"
--#define DRV_VERSION "0.6.1"
-+#define DRV_VERSION "0.6.2"
-
- struct hpt_clock {
- u8 xfer_speed;
-@@ -180,9 +180,9 @@
- if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
- mask &= ~ATA_MASK_UDMA;
- if (hpt_dma_blacklisted(adev, "UDMA3", bad_ata66_3))
-- mask &= ~(0x07 << ATA_SHIFT_UDMA);
-+ mask &= ~(0xF8 << ATA_SHIFT_UDMA);
- if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4))
-- mask &= ~(0x0F << ATA_SHIFT_UDMA);
-+ mask &= ~(0xF0 << ATA_SHIFT_UDMA);
- }
- return ata_pci_default_filter(adev, mask);
- }
-diff -Nurd linux-2.6.24/drivers/ata/pata_hpt37x.c linux-2.6.24-oxe810/drivers/ata/pata_hpt37x.c
---- linux-2.6.24/drivers/ata/pata_hpt37x.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/pata_hpt37x.c 2008-06-11 17:50:32.000000000 +0200
-@@ -24,7 +24,7 @@
- #include <linux/libata.h>
-
- #define DRV_NAME "pata_hpt37x"
--#define DRV_VERSION "0.6.9"
-+#define DRV_VERSION "0.6.11"
-
- struct hpt_clock {
- u8 xfer_speed;
-@@ -281,7 +281,7 @@
- if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
- mask &= ~ATA_MASK_UDMA;
- if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
-- mask &= ~(0x1F << ATA_SHIFT_UDMA);
-+ mask &= ~(0xE0 << ATA_SHIFT_UDMA);
- }
- return ata_pci_default_filter(adev, mask);
- }
-@@ -297,7 +297,7 @@
- {
- if (adev->class == ATA_DEV_ATA) {
- if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
-- mask &= ~ (0x1F << ATA_SHIFT_UDMA);
-+ mask &= ~(0xE0 << ATA_SHIFT_UDMA);
- }
- return ata_pci_default_filter(adev, mask);
- }
-diff -Nurd linux-2.6.24/drivers/ata/pata_serverworks.c linux-2.6.24-oxe810/drivers/ata/pata_serverworks.c
---- linux-2.6.24/drivers/ata/pata_serverworks.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/ata/pata_serverworks.c 2008-06-11 17:50:32.000000000 +0200
-@@ -226,7 +226,7 @@
-
- for (i = 0; (p = csb_bad_ata100[i]) != NULL; i++) {
- if (!strcmp(p, model_num))
-- mask &= ~(0x1F << ATA_SHIFT_UDMA);
-+ mask &= ~(0xE0 << ATA_SHIFT_UDMA);
- }
- return ata_pci_default_filter(adev, mask);
- }
-diff -Nurd linux-2.6.24/drivers/base/firmware_class.c linux-2.6.24-oxe810/drivers/base/firmware_class.c
---- linux-2.6.24/drivers/base/firmware_class.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/base/firmware_class.c 2008-06-11 17:50:32.000000000 +0200
-@@ -292,7 +292,8 @@
-
- static inline void fw_setup_device_id(struct device *f_dev, struct device *dev)
- {
-- snprintf(f_dev->bus_id, BUS_ID_SIZE, "firmware-%s", dev->bus_id);
-+ /* XXX warning we should watch out for name collisions */
-+ strlcpy(f_dev->bus_id, dev->bus_id, BUS_ID_SIZE);
- }
-
- static int fw_register_device(struct device **dev_p, const char *fw_name,
-diff -Nurd linux-2.6.24/drivers/base/platform.c linux-2.6.24-oxe810/drivers/base/platform.c
---- linux-2.6.24/drivers/base/platform.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/base/platform.c 2008-06-11 17:50:32.000000000 +0200
-@@ -647,7 +647,7 @@
- high_totalram += high_totalram - 1;
- mask = (((u64)high_totalram) << 32) + 0xffffffff;
- }
-- return mask & *dev->dma_mask;
-+ return mask;
- }
- EXPORT_SYMBOL_GPL(dma_get_required_mask);
- #endif
-diff -Nurd linux-2.6.24/drivers/block/ub.c linux-2.6.24-oxe810/drivers/block/ub.c
---- linux-2.6.24/drivers/block/ub.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/block/ub.c 2008-06-11 17:49:32.000000000 +0200
-@@ -657,7 +657,6 @@
- if ((cmd = ub_get_cmd(lun)) == NULL)
- return -1;
- memset(cmd, 0, sizeof(struct ub_scsi_cmd));
-- sg_init_table(cmd->sgv, UB_MAX_REQ_SG);
-
- blkdev_dequeue_request(rq);
-
-@@ -668,6 +667,7 @@
- /*
- * get scatterlist from block layer
- */
-+ sg_init_table(&urq->sgv[0], UB_MAX_REQ_SG);
- n_elem = blk_rq_map_sg(lun->disk->queue, rq, &urq->sgv[0]);
- if (n_elem < 0) {
- /* Impossible, because blk_rq_map_sg should not hit ENOMEM. */
-diff -Nurd linux-2.6.24/drivers/char/defkeymap.c_shipped linux-2.6.24-oxe810/drivers/char/defkeymap.c_shipped
---- linux-2.6.24/drivers/char/defkeymap.c_shipped 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/char/defkeymap.c_shipped 2008-06-11 17:49:52.000000000 +0200
-@@ -223,40 +223,40 @@
- };
-
- struct kbdiacruc accent_table[MAX_DIACR] = {
-- {'`', 'A', '\300'}, {'`', 'a', '\340'},
-- {'\'', 'A', '\301'}, {'\'', 'a', '\341'},
-- {'^', 'A', '\302'}, {'^', 'a', '\342'},
-- {'~', 'A', '\303'}, {'~', 'a', '\343'},
-- {'"', 'A', '\304'}, {'"', 'a', '\344'},
-- {'O', 'A', '\305'}, {'o', 'a', '\345'},
-- {'0', 'A', '\305'}, {'0', 'a', '\345'},
-- {'A', 'A', '\305'}, {'a', 'a', '\345'},
-- {'A', 'E', '\306'}, {'a', 'e', '\346'},
-- {',', 'C', '\307'}, {',', 'c', '\347'},
-- {'`', 'E', '\310'}, {'`', 'e', '\350'},
-- {'\'', 'E', '\311'}, {'\'', 'e', '\351'},
-- {'^', 'E', '\312'}, {'^', 'e', '\352'},
-- {'"', 'E', '\313'}, {'"', 'e', '\353'},
-- {'`', 'I', '\314'}, {'`', 'i', '\354'},
-- {'\'', 'I', '\315'}, {'\'', 'i', '\355'},
-- {'^', 'I', '\316'}, {'^', 'i', '\356'},
-- {'"', 'I', '\317'}, {'"', 'i', '\357'},
-- {'-', 'D', '\320'}, {'-', 'd', '\360'},
-- {'~', 'N', '\321'}, {'~', 'n', '\361'},
-- {'`', 'O', '\322'}, {'`', 'o', '\362'},
-- {'\'', 'O', '\323'}, {'\'', 'o', '\363'},
-- {'^', 'O', '\324'}, {'^', 'o', '\364'},
-- {'~', 'O', '\325'}, {'~', 'o', '\365'},
-- {'"', 'O', '\326'}, {'"', 'o', '\366'},
-- {'/', 'O', '\330'}, {'/', 'o', '\370'},
-- {'`', 'U', '\331'}, {'`', 'u', '\371'},
-- {'\'', 'U', '\332'}, {'\'', 'u', '\372'},
-- {'^', 'U', '\333'}, {'^', 'u', '\373'},
-- {'"', 'U', '\334'}, {'"', 'u', '\374'},
-- {'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
-- {'T', 'H', '\336'}, {'t', 'h', '\376'},
-- {'s', 's', '\337'}, {'"', 'y', '\377'},
-- {'s', 'z', '\337'}, {'i', 'j', '\377'},
-+ {'`', 'A', 0300}, {'`', 'a', 0340},
-+ {'\'', 'A', 0301}, {'\'', 'a', 0341},
-+ {'^', 'A', 0302}, {'^', 'a', 0342},
-+ {'~', 'A', 0303}, {'~', 'a', 0343},
-+ {'"', 'A', 0304}, {'"', 'a', 0344},
-+ {'O', 'A', 0305}, {'o', 'a', 0345},
-+ {'0', 'A', 0305}, {'0', 'a', 0345},
-+ {'A', 'A', 0305}, {'a', 'a', 0345},
-+ {'A', 'E', 0306}, {'a', 'e', 0346},
-+ {',', 'C', 0307}, {',', 'c', 0347},
-+ {'`', 'E', 0310}, {'`', 'e', 0350},
-+ {'\'', 'E', 0311}, {'\'', 'e', 0351},
-+ {'^', 'E', 0312}, {'^', 'e', 0352},
-+ {'"', 'E', 0313}, {'"', 'e', 0353},
-+ {'`', 'I', 0314}, {'`', 'i', 0354},
-+ {'\'', 'I', 0315}, {'\'', 'i', 0355},
-+ {'^', 'I', 0316}, {'^', 'i', 0356},
-+ {'"', 'I', 0317}, {'"', 'i', 0357},
-+ {'-', 'D', 0320}, {'-', 'd', 0360},
-+ {'~', 'N', 0321}, {'~', 'n', 0361},
-+ {'`', 'O', 0322}, {'`', 'o', 0362},
-+ {'\'', 'O', 0323}, {'\'', 'o', 0363},
-+ {'^', 'O', 0324}, {'^', 'o', 0364},
-+ {'~', 'O', 0325}, {'~', 'o', 0365},
-+ {'"', 'O', 0326}, {'"', 'o', 0366},
-+ {'/', 'O', 0330}, {'/', 'o', 0370},
-+ {'`', 'U', 0331}, {'`', 'u', 0371},
-+ {'\'', 'U', 0332}, {'\'', 'u', 0372},
-+ {'^', 'U', 0333}, {'^', 'u', 0373},
-+ {'"', 'U', 0334}, {'"', 'u', 0374},
-+ {'\'', 'Y', 0335}, {'\'', 'y', 0375},
-+ {'T', 'H', 0336}, {'t', 'h', 0376},
-+ {'s', 's', 0337}, {'"', 'y', 0377},
-+ {'s', 'z', 0337}, {'i', 'j', 0377},
- };
-
- unsigned int accent_table_size = 68;
-diff -Nurd linux-2.6.24/drivers/char/drm/drm_stub.c linux-2.6.24-oxe810/drivers/char/drm/drm_stub.c
---- linux-2.6.24/drivers/char/drm/drm_stub.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/char/drm/drm_stub.c 2008-06-11 17:49:50.000000000 +0200
-@@ -218,6 +218,7 @@
- if (ret)
- goto err_g1;
-
-+ pci_set_master(pdev);
- if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
- printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
- goto err_g2;
-diff -Nurd linux-2.6.24/drivers/char/drm/drm_vm.c linux-2.6.24-oxe810/drivers/char/drm/drm_vm.c
---- linux-2.6.24/drivers/char/drm/drm_vm.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/char/drm/drm_vm.c 2008-06-11 17:49:50.000000000 +0200
-@@ -506,6 +506,7 @@
- vma->vm_ops = &drm_vm_dma_ops;
-
- vma->vm_flags |= VM_RESERVED; /* Don't swap */
-+ vma->vm_flags |= VM_DONTEXPAND;
-
- vma->vm_file = filp; /* Needed for drm_vm_open() */
- drm_vm_open_locked(vma);
-@@ -655,6 +656,7 @@
- return -EINVAL; /* This should never happen. */
- }
- vma->vm_flags |= VM_RESERVED; /* Don't swap */
-+ vma->vm_flags |= VM_DONTEXPAND;
-
- vma->vm_file = filp; /* Needed for drm_vm_open() */
- drm_vm_open_locked(vma);
-diff -Nurd linux-2.6.24/drivers/char/mspec.c linux-2.6.24-oxe810/drivers/char/mspec.c
---- linux-2.6.24/drivers/char/mspec.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/char/mspec.c 2008-06-11 17:49:52.000000000 +0200
-@@ -283,7 +283,7 @@
- vdata->refcnt = ATOMIC_INIT(1);
- vma->vm_private_data = vdata;
-
-- vma->vm_flags |= (VM_IO | VM_RESERVED | VM_PFNMAP);
-+ vma->vm_flags |= (VM_IO | VM_RESERVED | VM_PFNMAP | VM_DONTEXPAND);
- if (vdata->type == MSPEC_FETCHOP || vdata->type == MSPEC_UNCACHED)
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- vma->vm_ops = &mspec_vm_ops;
-diff -Nurd linux-2.6.24/drivers/char/vt.c linux-2.6.24-oxe810/drivers/char/vt.c
---- linux-2.6.24/drivers/char/vt.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/char/vt.c 2008-06-11 17:49:52.000000000 +0200
-@@ -702,6 +702,7 @@
- if (is_switch) {
- set_leds();
- compute_shiftstate();
-+ notify_update(vc);
- }
- }
-
-diff -Nurd linux-2.6.24/drivers/dma/Kconfig linux-2.6.24-oxe810/drivers/dma/Kconfig
---- linux-2.6.24/drivers/dma/Kconfig 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/dma/Kconfig 2008-06-11 17:49:45.000000000 +0200
-@@ -4,7 +4,7 @@
-
- menuconfig DMADEVICES
- bool "DMA Engine support"
-- depends on (PCI && X86) || ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX
-+ depends on (PCI && X86) || ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX || ARCH_OXNAS
- help
- DMA engines can do asynchronous data transfers without
- involving the host CPU. Currently, this framework can be
-@@ -36,6 +36,14 @@
- help
- Enable support for the Intel(R) IOP Series RAID engines.
-
-+config OXNAS_ADMA
-+ tristate "Oxford Semiconductor ADAM support"
-+ depends on ARCH_OXNAS
-+ select ASYNC_CORE
-+ select DMA_ENGINE
-+ help
-+ Enable support for the Oxford Semiconductor async. DMA engine
-+
- config DMA_ENGINE
- bool
-
-diff -Nurd linux-2.6.24/drivers/dma/Makefile linux-2.6.24-oxe810/drivers/dma/Makefile
---- linux-2.6.24/drivers/dma/Makefile 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/dma/Makefile 2008-06-11 17:49:45.000000000 +0200
-@@ -3,3 +3,4 @@
- obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o
- ioatdma-objs := ioat.o ioat_dma.o ioat_dca.o
- obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
-+obj-$(CONFIG_OXNAS_ADMA) += oxnas_adma.o
-diff -Nurd linux-2.6.24/drivers/dma/ioat_dma.c linux-2.6.24-oxe810/drivers/dma/ioat_dma.c
---- linux-2.6.24/drivers/dma/ioat_dma.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/dma/ioat_dma.c 2008-06-11 17:49:45.000000000 +0200
-@@ -726,6 +726,7 @@
-
- if (new) {
- new->len = len;
-+ new->async_tx.ack = 0;
- return &new->async_tx;
- } else
- return NULL;
-@@ -749,6 +750,7 @@
-
- if (new) {
- new->len = len;
-+ new->async_tx.ack = 0;
- return &new->async_tx;
- } else
- return NULL;
-diff -Nurd linux-2.6.24/drivers/dma/oxnas_adma.c linux-2.6.24-oxe810/drivers/dma/oxnas_adma.c
---- linux-2.6.24/drivers/dma/oxnas_adma.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/dma/oxnas_adma.c 2008-06-11 17:49:45.000000000 +0200
-@@ -0,0 +1,272 @@
-+/*
-+ * drivers/dma/oxnas_adma.c
-+ *
-+ * Copyright (C) 2008 Oxford Semiconductor Ltd
-+ *
-+ * 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 <linux/dmaengine.h>
-+#include <linux/platform_device.h>
-+#include <asm/dma.h>
-+
-+/* MODULE API */
-+MODULE_VERSION("1.0");
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Oxford Semiconductor Ltd.");
-+
-+typedef struct oxnas_adma_device {
-+ struct dma_device common;
-+ struct platform_device *platform_device;
-+} oxnas_adma_device_t;
-+
-+typedef struct oxnas_adma_channel {
-+ struct dma_chan common;
-+ oxnas_dma_channel_t *oxnas_channel;
-+ /* Need a queue for pending descriptors */
-+ /* May need a queue for completed descriptors that haven't been acked yet */
-+} oxnas_adma_channel_t;
-+
-+typedef struct oxnas_adma_desc {
-+ struct dma_async_tx_descriptor async_desc;
-+ size_t len;
-+ dma_addr_t src_adr;
-+ dma_addr_t dst_adr;
-+} oxnas_adma_desc_t;
-+
-+static int __devexit oxnas_adma_remove(struct platform_device *dev)
-+{
-+ oxnas_adma_device_t *oxnas_adma_device = platform_get_drvdata(dev);
-+ struct dma_device *dma_device = &oxnas_adma_device->common;
-+ struct dma_chan *channel, *_channel;
-+
-+ dma_async_device_unregister(dma_device);
-+
-+ list_for_each_entry_safe(channel, _channel, &dma_device->channels, device_node) {
-+ list_del(&channel->device_node);
-+ kfree(channel);
-+ }
-+ kfree(oxnas_adma_device);
-+
-+ return 0;
-+}
-+
-+static void oxnas_adma_set_src(dma_addr_t addr, struct dma_async_tx_descriptor *tx, int index)
-+{
-+ oxnas_adma_desc_t *desc = container_of(tx, oxnas_adma_desc_t, async_desc);
-+ desc->src_adr = addr;
-+}
-+
-+static void oxnas_adm_set_dest(dma_addr_t addr, struct dma_async_tx_descriptor *tx, int index)
-+{
-+ oxnas_adma_desc_t *desc = container_of(tx, oxnas_adma_desc_t, async_desc);
-+ desc->dst_adr = addr;
-+}
-+
-+static void oxnas_dma_callback(
-+ oxnas_dma_channel_t *channel,
-+ oxnas_callback_arg_t arg,
-+ oxnas_dma_callback_status_t status,
-+ u16 checksum,
-+ int interrupt_count)
-+{
-+ oxnas_adma_desc_t *desc = (oxnas_adma_desc_t*)arg;
-+
-+ /* Use cookies to record that this descriptor's transfer has completed */
-+
-+ /* Store the completion status with the descriptor */
-+
-+ /* If there is a queued descriptor, start its transfer now - if that's
-+ possible from a DMA callback - with the callback arg updated */
-+}
-+
-+static dma_cookie_t oxnas_adma_submit_tx(struct dma_async_tx_descriptor *tx)
-+{
-+ oxnas_adma_desc_t *desc = container_of(tx, oxnas_adma_desc_t, async_desc);
-+ oxnas_adma_channel_t *channel = container_of(tx->chan, oxnas_adma_channel_t, common);
-+ dma_cookie_t cookie;
-+
-+ if (oxnas_dma_set(channel->oxnas_channel,
-+ (unsigned char*)desc->src_adr,
-+ desc->len,
-+ (unsigned char*)desc->dst_adr,
-+ OXNAS_DMA_MODE_INC,
-+ OXNAS_DMA_MODE_INC,
-+ 0, 0)) {
-+ return -1;
-+ }
-+
-+ /* Allocate a cookie for this descriptor */
-+ cookie = -1;
-+
-+ /* Be careful to syn. properly with DMA callback here */
-+ if (oxnas_dma_is_active(channel->oxnas_channel)) {
-+ /* Queue the new descriptor to be started when current transfer completes */
-+ } else {
-+ /* Start the new transfer */
-+ oxnas_dma_set_callback(channel->oxnas_channel, oxnas_dma_callback, desc)
-+ oxnas_dma_start(channel->oxnas_channel);
-+ }
-+
-+ return cookie;
-+}
-+
-+/** Allocate a DMA channel and prepare it for memory to memory transfers. Could
-+ * preallocate descriptors here
-+ */
-+static int oxnas_adma_alloc_chan_resources(struct dma_chan *chan)
-+{
-+ oxnas_adma_channel_t *channel = container_of(chan, oxnas_adma_channel_t, common);
-+
-+ channel->oxnas_channel = oxnas_dma_request(0);
-+ if (!channel->oxnas_channel) {
-+ return 0;
-+ }
-+
-+ /* Pretend we've allocated one descriptor */
-+ return 1;
-+}
-+
-+static void oxnas_adma_free_chan_resources(struct dma_chan *chan)
-+{
-+ oxnas_adma_channel_t *channel = container_of(chan, oxnas_adma_channel_t, common);
-+ oxnas_dma_free(channel->oxnas_channel);
-+
-+ /* May need to free leftover descriptors here as well */
-+}
-+
-+/** Poll for the DMA channel's active status. There can be multiple transfers
-+ * queued with the DMA channel identified by cookies, so should be checking
-+ * lists containing all pending transfers and all completed transfers that have
-+ * not yet been polled for completion
-+ */
-+static enum dma_status oxnas_adma_is_tx_complete(
-+ struct dma_chan *chan,
-+ dma_cookie_t cookie,
-+ dma_cookie_t *last,
-+ dma_cookie_t *used)
-+{
-+ oxnas_adma_channel_t *channel = container_of(chan, oxnas_adma_channel_t, common);
-+
-+ /* Use cookies to report completion status */
-+
-+ return oxnas_dma_is_active(channel->oxnas_channel) ? DMA_IN_PROGRESS : DMA_SUCCESS;
-+}
-+
-+/** To push outstanding transfers to h/w. This should use the list of pending
-+ * transfers identified by cookies to select the next transfer and pass this to
-+ * the hardware
-+ */
-+static void oxnas_adma_issue_pending(struct dma_chan *chan)
-+{
-+ /* If there isn't a transfer in progress and one is queued start it now,
-+ being careful to sync. with DMA callback function */
-+}
-+
-+static void oxnas_adma_dependency_added(struct dma_chan *chan)
-+{
-+ /* What is supposed to happen here? */
-+}
-+
-+/** Allocate descriptors capable of mapping the requested length of memory */
-+static struct dma_async_tx_descriptor *oxnas_adma_prep_dma_memcpy(struct dma_chan *chan, size_t len, int int_en)
-+{
-+ oxnas_adma_desc_t *desc = kzalloc(sizeof(oxnas_adma_desc_t), GFP_KERNEL);
-+ if (unlikely(!desc)) {
-+ return NULL;
-+ }
-+
-+ desc->async_desc.tx_set_src = oxnas_adma_set_src;
-+ desc->async_desc.tx_set_dest = oxnas_adm_set_dest;
-+ desc->async_desc.tx_submit = oxnas_adma_submit_tx;
-+ desc->len = len;
-+
-+ return &desc->async_desc;
-+}
-+
-+static int enumerate_dma_channels(struct dma_device *dma_device)
-+{
-+ int i;
-+
-+ dma_device->chancnt = 3;
-+
-+ for (i = 0; i < dma_device->chancnt; i++) {
-+ oxnas_adma_channel_t *channel = kzalloc(sizeof(oxnas_adma_channel_t), GFP_KERNEL);
-+ if (!channel) {
-+ dma_device->chancnt = i;
-+ break;
-+ }
-+
-+ channel->common.device = dma_device;
-+ list_add_tail(&channel->common.device_node, &dma_device->channels);
-+ }
-+
-+ return dma_device->chancnt;
-+}
-+
-+static int __devinit oxnas_adma_probe(struct platform_device *platform_device)
-+{
-+ oxnas_adma_device_t *oxnas_adma_device;
-+ struct dma_device *dma_device;
-+
-+ oxnas_adma_device = kzalloc(sizeof(oxnas_adma_device_t), GFP_KERNEL);
-+ if (!oxnas_adma_device) {
-+ return -ENOMEM;
-+ }
-+
-+ oxnas_adma_device->platform_device = platform_device;
-+ dma_device = &oxnas_adma_device->common;
-+
-+ platform_set_drvdata(platform_device, oxnas_adma_device);
-+
-+ INIT_LIST_HEAD(&dma_device->channels);
-+ enumerate_dma_channels(dma_device);
-+
-+ dma_cap_set(DMA_MEMCPY, dma_device->cap_mask);
-+ dma_device->device_alloc_chan_resources = oxnas_adma_alloc_chan_resources;
-+ dma_device->device_free_chan_resources = oxnas_adma_free_chan_resources;
-+ dma_device->device_is_tx_complete = oxnas_adma_is_tx_complete;
-+ dma_device->device_issue_pending = oxnas_adma_issue_pending;
-+ dma_device->device_dependency_added = oxnas_adma_dependency_added;
-+ dma_device->dev = &platform_device->dev;
-+ dma_device->device_prep_dma_memcpy = oxnas_adma_prep_dma_memcpy;
-+
-+ dma_async_device_register(dma_device);
-+
-+ return 0;
-+}
-+
-+static struct platform_driver oxnas_adma_driver = {
-+ .probe = oxnas_adma_probe,
-+ .remove = oxnas_adma_remove,
-+ .driver = {
-+ .owner = THIS_MODULE,
-+ .name = "oxnas-adma",
-+ },
-+};
-+
-+static int __init oxnas_adma_init_module(void)
-+{
-+ return platform_driver_register(&oxnas_adma_driver);
-+}
-+
-+module_init(oxnas_adma_init_module);
-+
-+static void __exit oxnas_adma_exit_module(void)
-+{
-+ platform_driver_unregister(&oxnas_adma_driver);
-+ return;
-+}
-+
-+module_exit(oxnas_adma_exit_module);
-diff -Nurd linux-2.6.24/drivers/firmware/dmi_scan.c linux-2.6.24-oxe810/drivers/firmware/dmi_scan.c
---- linux-2.6.24/drivers/firmware/dmi_scan.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/firmware/dmi_scan.c 2008-06-11 17:49:40.000000000 +0200
-@@ -469,12 +469,3 @@
-
- return year;
- }
--
--/**
-- * dmi_get_slot - return dmi_ident[slot]
-- * @slot: index into dmi_ident[]
-- */
--char *dmi_get_slot(int slot)
--{
-- return(dmi_ident[slot]);
--}
-diff -Nurd linux-2.6.24/drivers/i2c/algos/Kconfig linux-2.6.24-oxe810/drivers/i2c/algos/Kconfig
---- linux-2.6.24/drivers/i2c/algos/Kconfig 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/i2c/algos/Kconfig 2008-06-11 17:50:33.000000000 +0200
-@@ -34,6 +34,10 @@
- This support is also available as a module. If so, the module
- will be called i2c-algo-pca.
-
-+config I2C_ALGOOXSEMI
-+ tristate "OXNAS I2C interface"
-+ depends on I2C
-+
- config I2C_ALGO_SGI
- tristate "I2C SGI interfaces"
- depends on SGI_IP22 || SGI_IP32 || X86_VISWS
-diff -Nurd linux-2.6.24/drivers/i2c/algos/Makefile linux-2.6.24-oxe810/drivers/i2c/algos/Makefile
---- linux-2.6.24/drivers/i2c/algos/Makefile 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/i2c/algos/Makefile 2008-06-11 17:50:34.000000000 +0200
-@@ -5,6 +5,7 @@
- obj-$(CONFIG_I2C_ALGOBIT) += i2c-algo-bit.o
- obj-$(CONFIG_I2C_ALGOPCF) += i2c-algo-pcf.o
- obj-$(CONFIG_I2C_ALGOPCA) += i2c-algo-pca.o
-+obj-$(CONFIG_I2C_ALGOOXSEMI) += i2c-algo-oxnas.o
- obj-$(CONFIG_I2C_ALGO_SGI) += i2c-algo-sgi.o
-
- ifeq ($(CONFIG_I2C_DEBUG_ALGO),y)
-diff -Nurd linux-2.6.24/drivers/i2c/algos/i2c-algo-oxnas.c linux-2.6.24-oxe810/drivers/i2c/algos/i2c-algo-oxnas.c
---- linux-2.6.24/drivers/i2c/algos/i2c-algo-oxnas.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/i2c/algos/i2c-algo-oxnas.c 2008-06-11 17:50:33.000000000 +0200
-@@ -0,0 +1,858 @@
-+/*
-+ * i2c-algo-oxnas.c i2x driver algorithms for MPCoxnas
-+ * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
-+ *
-+ 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.
-+ *
-+ */
-+
-+// XXX todo
-+// timeout sleep?
-+
-+
-+/* $Id: i2c-algo-oxnas.c,v 1.15 2004/11/20 08:02:24 khali Exp $ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/sched.h>
-+#include "linux/i2c.h"
-+#include "linux/i2c-algo-oxnas.h"
-+#include <asm/bitops.h>
-+
-+
-+
-+#define OXNAS_MAX_READ 513
-+/* #define I2C_CHIP_ERRATA */ /* Try uncomment this if you have an older CPU(earlier than rev D4) */ //NOTE
-+static wait_queue_head_t iic_wait;
-+
-+int oxnas_debug = 1;
-+int oxnas_scan = 1;
-+
-+static inline void oxnas_iic_algo_dump_reg( void )
-+{
-+ i2c_registers_oxnas_t* i2c = (i2c_registers_oxnas_t*) I2C_BASE; // SERIAL_MASTER_CONTROL_BASE;
-+
-+ printk( KERN_INFO "\n\n ==================================================================" );
-+ printk( KERN_INFO " i2c->SerialControlRegister; == 0x%08x @ %p\n", i2c->SerialControlRegister , &(i2c->SerialControlRegister ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x00; */
-+ printk( KERN_INFO " i2c->SerialAddressRegister; == 0x%08x @ %p\n", i2c->SerialAddressRegister , &(i2c->SerialAddressRegister ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x04; */
-+ printk( KERN_INFO " i2c->SerialSWControlOutRegister; == 0x%08x @ %p\n", i2c->SerialSWControlOutRegister , &(i2c->SerialSWControlOutRegister ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x08; */
-+ printk( KERN_INFO " i2c->SerialSWControlInRegister; == 0x%08x @ %p\n", i2c->SerialSWControlInRegister , &(i2c->SerialSWControlInRegister ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x0C; */
-+ printk( KERN_INFO " i2c->SerialInterruptStatusRegister; == 0x%08x @ %p\n", i2c->SerialInterruptStatusRegister , &(i2c->SerialInterruptStatusRegister ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x10; */
-+ printk( KERN_INFO " i2c->SerialInterruptEnableRegister; == 0x%08x @ %p\n", i2c->SerialInterruptEnableRegister , &(i2c->SerialInterruptEnableRegister ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x14; */
-+ printk( KERN_INFO "\n" ); /* PAD REGISTER PACKING ***/
-+ printk( KERN_INFO " i2c->SerialReadData1Register; == 0x%08x @ %p\n", i2c->SerialReadData1Register , &(i2c->SerialReadData1Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x20; */
-+ printk( KERN_INFO " i2c->SerialReadData2Register; == 0x%08x @ %p\n", i2c->SerialReadData2Register , &(i2c->SerialReadData2Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x24; */
-+ printk( KERN_INFO " i2c->SerialReadData3Register; == 0x%08x @ %p\n", i2c->SerialReadData3Register , &(i2c->SerialReadData3Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x28; */
-+ printk( KERN_INFO " i2c->SerialReadData4Register; == 0x%08x @ %p\n", i2c->SerialReadData4Register , &(i2c->SerialReadData4Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x2C; */
-+ printk( KERN_INFO "\n" ); /* PAD REGISTER PACKING ***/
-+ printk( KERN_INFO " i2c->SerialWriteData1Register; == 0x%08x @ %p\n", i2c->SerialWriteData1Register , &(i2c->SerialWriteData1Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x40; */
-+ printk( KERN_INFO " i2c->SerialWriteData2Register; == 0x%08x @ %p\n", i2c->SerialWriteData2Register , &(i2c->SerialWriteData2Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x44; */
-+ printk( KERN_INFO " i2c->SerialWriteData3Register; == 0x%08x @ %p\n", i2c->SerialWriteData3Register , &(i2c->SerialWriteData3Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x48; */
-+ printk( KERN_INFO " i2c->SerialWriteData4Register; == 0x%08x @ %p\n", i2c->SerialWriteData4Register , &(i2c->SerialWriteData4Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x4C; */
-+ printk( KERN_INFO "\n" ); /* PAD REGISTER PACKING ***/
-+ printk( KERN_INFO " i2c->GenericSerialControlRegister; == 0x%08x @ %p\n", i2c->GenericSerialControlRegister , &(i2c->GenericSerialControlRegister ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x80; */
-+ printk( KERN_INFO "\n" ); /* PAD REGISTER PACKING ***/
-+ printk( KERN_INFO " i2c->GenericSerialInterruptStatusRegister; == 0x%08x @ %p\n", i2c->GenericSerialInterruptStatusRegister , &(i2c->GenericSerialInterruptStatusRegister ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x90; */
-+ printk( KERN_INFO " i2c->GenericSerialInterruptEnableRegister; == 0x%08x @ %p\n", i2c->GenericSerialInterruptEnableRegister , &(i2c->GenericSerialInterruptEnableRegister ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x94; */
-+ printk( KERN_INFO "\n" ); /* PAD REGISTER PACKING ***/
-+ printk( KERN_INFO " i2c->GenericSerialReadData1Register; == 0x%08x @ %p\n", i2c->GenericSerialReadData1Register , &(i2c->GenericSerialReadData1Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0xA0; */
-+ printk( KERN_INFO " i2c->GenericSerialReadData2Register; == 0x%08x @ %p\n", i2c->GenericSerialReadData2Register , &(i2c->GenericSerialReadData2Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0xA4; */
-+ printk( KERN_INFO " i2c->GenericSerialReadData3Register; == 0x%08x @ %p\n", i2c->GenericSerialReadData3Register , &(i2c->GenericSerialReadData3Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0xA8; */
-+ printk( KERN_INFO " i2c->GenericSerialReadData4Register; == 0x%08x @ %p\n", i2c->GenericSerialReadData4Register , &(i2c->GenericSerialReadData4Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0xAC; */
-+ printk( KERN_INFO "\n" ); /* PAD REGISTER PACKING ***/
-+ printk( KERN_INFO " i2c->GenericSerialWriteData1Register; == 0x%08x @ %p\n", i2c->GenericSerialWriteData1Register , &(i2c->GenericSerialWriteData1Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0xC0; */
-+ printk( KERN_INFO " i2c->GenericSerialWriteData2Register; == 0x%08x @ %p\n", i2c->GenericSerialWriteData2Register , &(i2c->GenericSerialWriteData2Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0xC4; */
-+ printk( KERN_INFO " i2c->GenericSerialWriteData3Register; == 0x%08x @ %p\n", i2c->GenericSerialWriteData3Register , &(i2c->GenericSerialWriteData3Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0xC8; */
-+ printk( KERN_INFO " i2c->GenericSerialWriteData4Register; == 0x%08x @ %p\n", i2c->GenericSerialWriteData4Register , &(i2c->GenericSerialWriteData4Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0xCC; */
-+ printk( KERN_INFO "\n\n ==================================================================" );
-+
-+
-+}
-+
-+static inline int oxnas_iic_algo_bus_reset( volatile struct i2c_algo_oxnas_data* oxnas )
-+{
-+ /* perform a bus reset to clean up */
-+
-+ unsigned long flags, tmo;
-+ volatile i2c_registers_oxnas_t *pI2C = (i2c_registers_oxnas_t *) oxnas;
-+
-+ local_irq_save(flags);
-+ oxnas->iTransferInProgress_ = 1;
-+
-+ pI2C->SerialControlRegister =
-+ (I2C_SCR_RESET << I2C_SCR_TRANSACTION_TYPE_BIT ) |
-+ (I2C_SCR_RESET << I2C_SCR_TRANSACTION_PROGRESS_BIT );
-+
-+ /* Wait for IIC transfer */
-+ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
-+
-+ // Flag that the transfer has finished
-+ oxnas->iTransferInProgress_ = 0;
-+
-+ local_irq_restore(flags);
-+
-+ return (tmo < 1*HZ);
-+}
-+
-+
-+static void
-+oxnas_iic_algo_interrupt(void *dev_id, struct pt_regs *regs)
-+{
-+ volatile i2c_registers_oxnas_t *i2cReg = (i2c_registers_oxnas_t *)dev_id;
-+ if (oxnas_debug)
-+ printk("oxnas_iic_algo_interrupt(dev_id=%p)\n", dev_id);
-+
-+ /* Clear interrupt.
-+ */
-+ i2cReg->SerialInterruptStatusRegister &= ~(1UL << I2C_ISR_INTERRUPT_STATUS_BIT);
-+
-+ /* Get 'me going again.
-+ */
-+ wake_up_interruptible(&iic_wait);
-+}
-+
-+static void
-+oxnas_iic_algo_init(struct i2c_algo_oxnas_data *oxnas)
-+{
-+ u32 temp;
-+ volatile i2c_registers_oxnas_t* i2c = oxnas->i2c;
-+
-+ if (oxnas_debug) printk(KERN_INFO "oxnas_iic_algo_init()\n");
-+
-+ /* Initialize
-+ * Set up the IIC parameters
-+ */
-+ temp = i2c->SerialControlRegister & I2C_SCR_READ_MASK;
-+ temp >>= I2C_SCR_AUTO_INCREMENT_BUFFER_SIZE_BIT;
-+ temp &= ~(0xffffffff << ( I2C_SCR_AUTO_INCREMENT_BUFFER_SIZE_NUM_BITS ));
-+ oxnas->iMaxAutoIncTransfer_ = temp;
-+
-+ // Initialise the Serial controller(s)
-+ {
-+ // syslib::Lock lock(mutex);
-+
-+ // TODO: Ensure the Serial block is properly reset
-+ // BlockResetRegister& blockResetRegister = BlockResetRegister::Acquire();
-+ // blockResetRegister.ResetSerial();
-+ // blockResetRegister.CommitWrites();
-+ // blockResetRegister.Release();
-+
-+ // TODO: Enable the clock to the Serial block
-+ // ClockStartRegister& clockStartRegister = ClockStartRegister::Acquire();
-+ // clockStartRegister.RefreshReadData();
-+ // clockStartRegister.StartSerialClock();
-+ // clockStartRegister.CommitWrites();
-+ // clockStartRegister.Release();
-+
-+ // TODO: Set the Serial clock rate
-+ // SerialClockSelectRegister& serialClockSelectRegister = SerialClockSelectRegister::GetInstance();
-+ // serialClockSelectRegister.SetClockRate(SerialClockSelectRegister::PLL_DIV_32768);
-+ // serialClockSelectRegister.CommitWrites();
-+
-+ // Disable the Serial Interrupt
-+ if (oxnas_debug) printk(KERN_INFO " - Disabling pre existing i2c interrupt\n");
-+ i2c->SerialInterruptEnableRegister &= ~(1UL << I2C_IER_SERIAL_ENABLE_BIT);
-+
-+ // Disable the Generic serial Interrupt
-+ if (oxnas_debug) printk(KERN_INFO " - Disabling pre existing gen serial interrupt\n");
-+ i2c->SerialInterruptEnableRegister &= ~(1UL << I2C_IER_GEN_ENABLE_BIT);
-+
-+ // Clear any pending Serial interrupts
-+ if ( i2c->SerialInterruptStatusRegister | (1UL << I2C_ISR_INTERRUPT_STATUS_BIT) )
-+ {
-+ // Yes, so clear the interrupt
-+ if (oxnas_debug) printk(KERN_INFO " - Clearing pre existing i2c interrupt\n");
-+ *( &(i2c->SerialInterruptStatusRegister) ) |= (1UL << I2C_ISR_INTERRUPT_STATUS_BIT);
-+ }
-+
-+ // Clear any pending Generic serial interrupts
-+ if ( i2c->SerialInterruptStatusRegister | (1UL << I2C_ISR_GEN_INTERRUPT_STATUS_BIT) )
-+ {
-+ // Yes, so clear the interrupt
-+ if (oxnas_debug) printk(KERN_INFO " - Clearing pre existing generic serial interrupt\n");
-+ *( &(i2c->SerialInterruptStatusRegister) ) |= (1UL << I2C_ISR_GEN_INTERRUPT_STATUS_BIT);
-+ }
-+
-+
-+ // Initialise the generic serial hardware, which shares reset,
-+ // clock and interrupt hardware with the Serial controller(s)
-+ // TODO: GenericSerialHelper::Init();
-+
-+ }
-+
-+ init_waitqueue_head(&iic_wait);
-+
-+ /* Install interrupt handler.
-+ */
-+ if (oxnas_debug) {
-+ printk ("%s[%d] Install ISR for IRQ %d\n",
-+ __func__,__LINE__, I2C_INTERRUPT );
-+ }
-+
-+ (*oxnas->setisr)( (int) I2C_INTERRUPT, &oxnas_iic_algo_interrupt, (void *)i2c);
-+if (oxnas_debug)oxnas_iic_algo_dump_reg();
-+}
-+
-+
-+static int
-+oxnas_iic_algo_shutdown(struct i2c_algo_oxnas_data *oxnas)
-+{
-+ volatile i2c_registers_oxnas_t *i2c = oxnas->i2c;
-+
-+ if (oxnas_debug) printk("oxnas_iic_algo_shutdown()\n");
-+
-+ /* Shut down IIC.
-+ */
-+ // TODO: syslib::Lock lock(mutex);
-+
-+ // TODO: Reset Serial block to ensure there are no actve transfers
-+ // BlockResetRegister& blockResetRegister = BlockResetRegister::Acquire();
-+ // blockResetRegister.ResetSerial();
-+ // blockResetRegister.CommitWrites();
-+ // blockResetRegister.Release();
-+
-+ // Disable the Serial Interrupt
-+ if (oxnas_debug) printk(KERN_INFO " - Disabling pre existing i2c interrupt\n");
-+ i2c->SerialInterruptEnableRegister &= ~(1UL << I2C_IER_SERIAL_ENABLE_BIT);
-+
-+ // Disable the Generic serial Interrupt
-+ if (oxnas_debug) printk(KERN_INFO " - Disabling pre existing gen serial interrupt\n");
-+ i2c->SerialInterruptEnableRegister &= ~(1UL << I2C_IER_GEN_ENABLE_BIT);
-+
-+
-+ // Shutdown the generic serial hardware, which shares reset, clock and
-+ // interrupt hardware with the Serial controller(s)
-+ // TODO: GenericSerialHelper::Shutdown();
-+
-+ // TODO: Disable the clock to the Serial block
-+ // ClockStopRegister& clockStopRegister = ClockStopRegister::Acquire();
-+ // clockStopRegister.RefreshReadData();
-+ // clockStopRegister.StopSerialClock();
-+ // clockStopRegister.CommitWrites();
-+ // clockStopRegister.Release();
-+
-+ (*oxnas->clearisr)( (int) I2C_INTERRUPT, (void *)i2c);
-+if (oxnas_debug)oxnas_iic_algo_dump_reg();
-+
-+ return(0);
-+}
-+
-+
-+#define BD_SC_NAK ((ushort)0x0004) /* NAK - did not respond */
-+#define BD_SC_OV ((ushort)0x0002) /* OV - receive overrun */
-+#define OXNAS_CR_CLOSE_RXBD ((ushort)0x0007)
-+
-+static void force_close(struct i2c_algo_oxnas_data *oxnas)
-+{
-+ volatile i2c_registers_oxnas_t *i2c = oxnas->i2c;
-+
-+ if (oxnas_debug) printk("force_close()\n");
-+
-+ *( &(i2c->SerialControlRegister) ) |= (1UL << I2C_SCR_ABORT_BIT);
-+
-+ /* perform a bus reset to clean up */
-+ oxnas_iic_algo_bus_reset(oxnas);
-+
-+if (oxnas_debug)oxnas_iic_algo_dump_reg();
-+}
-+
-+
-+/* Read from IIC...
-+ * abyte = address byte, with r/w flag already set
-+ */
-+static int
-+oxnas_iic_algo_read(struct i2c_algo_oxnas_data *oxnas, u_char abyte, char *readBuffer, int readBufferLength)
-+{
-+ volatile i2c_registers_oxnas_t *i2c = oxnas->i2c;
-+ const unsigned char* pData;
-+ unsigned long flags, tmo, temp, bytesTransfered;
-+
-+
-+ if (oxnas_debug) printk("oxnas_iic_algo_read(abyte=0x%x)\n", abyte);
-+
-+ if (readBufferLength >= oxnas->iMaxAutoIncTransfer_ ) {
-+ if (oxnas_debug) printk("oxnas_iic_algo_read $RFailed to reaad %d auto. max is %d\n", readBufferLength, oxnas->iMaxAutoIncTransfer_ );
-+ return -EINVAL;
-+ }
-+
-+
-+ if( 1 /*TODO: Split into multipacks. */ )
-+ {
-+
-+ local_irq_save(flags);
-+
-+ /* QUESTION: Does this get locked by the parent? it should be!! */
-+ oxnas->iTransferInProgress_ = 1;
-+ oxnas->iError_ = 0;
-+
-+ // Set up the 7-bit slave address
-+ i2c->SerialAddressRegister = I2C_SAR_WRITE_MASK & ((abyte >> 1) << I2C_SAR_SEVEN_BIT_ADDRESS_BIT);
-+
-+ // Setup the control register
-+ temp = ( I2C_SCR_READ << I2C_SCR_READ_WRITE_BIT ) |
-+ ( I2C_SCR_NORMAL << I2C_SCR_TRANSACTION_TYPE_BIT ) |
-+ ( I2C_SCR_SEVEN_BIT << I2C_SCR_ADDRESS_MODE_BIT ) |
-+ ( 0 << I2C_SCR_SCCB_MODE_ENABLE_BIT ) |
-+ ( 1 << I2C_SCR_SCCB_MODE_RESPECT_ACK_BIT ) |
-+ ( 1 << I2C_SCR_AUTO_INCREMENT_ENABLE_BIT ) |
-+ ( 1 << I2C_SCR_ENABLE_SLAVE_HOLD_OFF_BIT ) |
-+ ( 0 << I2C_SCR_HIGH_SPEED_DRIVE_BIT ) |
-+ ( readBufferLength << I2C_SCR_BYTES_TO_TRANSFER_BIT );
-+
-+ temp &= I2C_SCR_WRITE_MASK;
-+ i2c->SerialControlRegister = temp;
-+
-+ /* Enable some interupts */
-+ *( &(i2c->SerialInterruptEnableRegister) ) |= (1UL << I2C_IER_SERIAL_ENABLE_BIT);
-+
-+ /* Begin transmission */
-+ *( &(i2c->SerialControlRegister) ) |= (1UL << I2C_SCR_TRANSACTION_PROGRESS_BIT);
-+
-+ /* Wait for IIC transfer */
-+ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
-+
-+ /* Woken. Copy data out of special registers. */
-+
-+ temp = i2c->SerialControlRegister;
-+
-+ // How many bytes were read from the slave?
-+ bytesTransfered = (temp >> I2C_SCR_BYTES_TO_TRANSFER_BIT) &
-+ ~(0xffffffff << I2C_SCR_BYTES_TO_TRANSFER_NUM_BITS);
-+
-+ // Did the transfer fail
-+ if ( temp | (1UL << I2C_SCR_TRANSACTION_STATUS_BIT) )
-+ {
-+ // Yes, so remember the error
-+ oxnas->iError_ = 1;
-+ readBufferLength = 0;
-+ }
-+ else if (readBuffer)
-+ {
-+ if (bytesTransfered > readBufferLength)
-+ {
-+ // More bytes were read than we have buffer space to
-+ // store them
-+ oxnas->iError_ = 1;
-+ }
-+ else
-+ {
-+ // Copy the received data into the buffer that was provided by the
-+ // original caller to the Read() or ReadImmediate() method
-+ if (bytesTransfered > 0)
-+ {
-+ int i=0;
-+ temp = i2c->SerialReadData1Register;
-+ pData = (const unsigned char*) (&temp);
-+ readBuffer[i++] = *pData++;
-+ if (bytesTransfered > 1)
-+ {
-+ readBuffer[i++] = *pData++;
-+ if (bytesTransfered > 2)
-+ {
-+ readBuffer[i++] = *pData++;
-+ if (bytesTransfered > 3)
-+ {
-+ readBuffer[i++] = *pData++;
-+ }
-+ }
-+ }
-+
-+ if (bytesTransfered > 4)
-+ {
-+ temp = i2c->SerialReadData2Register;
-+ pData = (const unsigned char*) (&temp);
-+ readBuffer[i++] = *pData++;
-+ if (bytesTransfered > 5)
-+ {
-+ readBuffer[i++] = *pData++;
-+ if (bytesTransfered > 6)
-+ {
-+ readBuffer[i++] = *pData++;
-+ if (bytesTransfered > 7)
-+ {
-+ readBuffer[i++] = *pData++;
-+ }
-+ }
-+ }
-+ }
-+
-+ if (bytesTransfered > 8)
-+ {
-+ temp = i2c->SerialReadData3Register;
-+ pData = (const unsigned char*) (&temp);
-+ if (bytesTransfered > 9)
-+ {
-+ readBuffer[i++] = *pData++;
-+ if (bytesTransfered > 10)
-+ {
-+ readBuffer[i++] = *pData++;
-+ if (bytesTransfered > 11)
-+ {
-+ readBuffer[i++] = *pData++;
-+ }
-+ }
-+ }
-+ }
-+
-+ if (bytesTransfered > 12)
-+ {
-+ temp = i2c->SerialReadData4Register;
-+ pData = (const unsigned char*) (&temp);
-+ if (bytesTransfered > 13)
-+ {
-+ readBuffer[i++] = *pData++;
-+ if (bytesTransfered > 14)
-+ {
-+ readBuffer[i++] = *pData++;
-+ if (bytesTransfered > 15)
-+ {
-+ readBuffer[i++] = *pData++;
-+ }
-+ }
-+ }
-+ }
-+ }
-+ }
-+ }
-+
-+
-+ // Flag that the transfer has finished
-+ oxnas->iTransferInProgress_ = 0;
-+
-+ local_irq_restore(flags);
-+ }
-+
-+ /* IDEA: busy wait for small transfers, its faster time_after(jiffies, tmo) */
-+
-+ if (signal_pending(current) || !tmo){
-+ force_close(oxnas);
-+ if(oxnas_debug)
-+ printk("IIC read: timeout!\n");
-+ return -EIO;
-+ }
-+
-+ if ( i2c->SerialControlRegister | (1UL << I2C_SCR_TRANSACTION_STATUS_BIT) ) {
-+ if (oxnas_debug)
-+ printk("IIC read; no ack\n");
-+ return -EREMOTEIO;
-+ }
-+
-+ if (bytesTransfered > readBufferLength) {
-+ if (oxnas_debug)
-+ printk("IIC read; Overrun\n");
-+ return -EREMOTEIO;;
-+ }
-+
-+ if (oxnas_debug) printk("read %u bytes\n", readBufferLength);
-+
-+ if (bytesTransfered < readBufferLength) {
-+ if (oxnas_debug)
-+ printk("IIC read; short, wanted %lu got %ld\n",
-+ bytesTransfered, readBufferLength);
-+ return 0;
-+ }
-+
-+ return bytesTransfered;
-+}
-+
-+
-+static void LoadWriteRegisters(
-+ volatile i2c_registers_oxnas_t *i2c,
-+ char *data,
-+ int length )
-+{
-+ // Copy the data to be transmited into the write registers
-+ u32 temp;
-+ if (length > 0)
-+ {
-+ int i=0;
-+ unsigned char* pData = (unsigned char*) &temp;
-+ *pData++ = (data[i++]);
-+ if (length > 1)
-+ {
-+ *pData++ = (data[i++]);
-+ if (length > 2)
-+ {
-+ *pData++ = (data[i++]);
-+ if (length > 3)
-+ {
-+ *pData++ = (data[i++]);
-+ }
-+ }
-+ }
-+ i2c->SerialWriteData1Register = temp;
-+
-+ if (length > 4)
-+ {
-+ pData = (unsigned char*) (&temp);
-+ *pData++ = (data[i++]);
-+ if (length > 5)
-+ {
-+ *pData++ = (data[i++]);
-+ if (length > 6)
-+ {
-+ *pData++ = (data[i++]);
-+ if (length > 7)
-+ {
-+ *pData++ = (data[i++]);
-+ }
-+ }
-+ }
-+ i2c->SerialWriteData2Register = temp;
-+ }
-+
-+ if (length > 8)
-+ {
-+ pData = (unsigned char*) (&temp);
-+ *pData++ = (data[i++]);
-+ if (length > 9)
-+ {
-+ *pData++ = (data[i++]);
-+ if (length > 10)
-+ {
-+ *pData++ = (data[i++]);
-+ if (length > 11)
-+ {
-+ *pData++ = (data[i++]);
-+ }
-+ }
-+ }
-+ i2c->SerialWriteData3Register = temp;
-+ }
-+
-+ if (length > 12)
-+ {
-+ pData = (unsigned char*) (&temp);
-+ *pData++ = (data[i++]);
-+ if (length > 13)
-+ {
-+ *pData++ = (data[i++]);
-+ if (length > 14)
-+ {
-+ *pData++ = (data[i++]);
-+ if (length > 15)
-+ {
-+ *pData++ = (data[i++]);
-+ }
-+ }
-+ }
-+ i2c->SerialWriteData4Register = temp;
-+ }
-+ }
-+}
-+
-+
-+/* Write to IIC...
-+ * addr = address byte, with r/w flag already set
-+ */
-+static int
-+oxnas_iic_algo_write(struct i2c_algo_oxnas_data *oxnas, u_char abyte, char *buf,int count)
-+{
-+ volatile i2c_registers_oxnas_t *i2c = oxnas->i2c;
-+ unsigned long flags, tmo, bytesTransfered, temp;
-+
-+ if (oxnas_debug) printk("oxnas_iic_algo_write(abyte=0x%x)\n", abyte);
-+
-+ if (count >= oxnas->iMaxAutoIncTransfer_ ) {
-+ if (oxnas_debug) printk("oxnas_iic_algo_read $RFailed to reaad %d auto. max is %d\n", count, oxnas->iMaxAutoIncTransfer_ );
-+ return -EINVAL;
-+ }
-+
-+ if( 1 /* TODO: Split longer messages */ )
-+ {
-+ LoadWriteRegisters( i2c, buf, count );
-+
-+ local_irq_save(flags);
-+
-+ /* QUESTION: Does this get locked by the parent? it should be!! */
-+ oxnas->iTransferInProgress_ = 1;
-+ oxnas->iError_ = 0;
-+
-+ // Set up the 7-bit slave address
-+ i2c->SerialAddressRegister = I2C_SAR_WRITE_MASK & ((abyte >> 1) << I2C_SAR_SEVEN_BIT_ADDRESS_BIT);
-+
-+ // Setup the control register
-+ temp = ( I2C_SCR_WRITE << I2C_SCR_READ_WRITE_BIT ) |
-+ ( I2C_SCR_NORMAL << I2C_SCR_TRANSACTION_TYPE_BIT ) |
-+ ( I2C_SCR_SEVEN_BIT << I2C_SCR_ADDRESS_MODE_BIT ) |
-+ ( 0 << I2C_SCR_SCCB_MODE_ENABLE_BIT ) |
-+ ( 1 << I2C_SCR_SCCB_MODE_RESPECT_ACK_BIT ) |
-+ ( 1 << I2C_SCR_AUTO_INCREMENT_ENABLE_BIT ) |
-+ ( 1 << I2C_SCR_ENABLE_SLAVE_HOLD_OFF_BIT ) |
-+ ( 0 << I2C_SCR_HIGH_SPEED_DRIVE_BIT ) |
-+ ( count << I2C_SCR_BYTES_TO_TRANSFER_BIT );
-+
-+ temp &= I2C_SCR_WRITE_MASK;
-+ i2c->SerialControlRegister = temp;
-+
-+ /* Enable some interupts */
-+ *( &(i2c->SerialInterruptEnableRegister) ) |= (1UL << I2C_IER_SERIAL_ENABLE_BIT);
-+
-+ /* Begin transmission */
-+ *( &i2c->SerialControlRegister ) |= (1UL << I2C_SCR_TRANSACTION_PROGRESS_BIT);
-+
-+ /* Begin transmission */
-+
-+ /* Wait for IIC transfer */
-+ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
-+ local_irq_restore(flags);
-+ }
-+
-+ /* IDEA: busy wait for small transfers, its faster time_after(jiffies, tmo) */
-+
-+
-+ if (signal_pending(current) || !tmo){
-+ force_close(oxnas);
-+ if(oxnas_debug)
-+ printk("IIC read: timeout!\n");
-+ return -EIO;
-+ }
-+
-+ if ( i2c->SerialControlRegister | (1UL << I2C_SCR_TRANSACTION_STATUS_BIT)) {
-+ if (oxnas_debug)
-+ printk("IIC read; no ack\n");
-+ return -EREMOTEIO;
-+ }
-+
-+ // How many bytes were read from the slave?
-+ bytesTransfered = (temp >> I2C_SCR_BYTES_TO_TRANSFER_BIT) &
-+ ~(0xffffffff << I2C_SCR_BYTES_TO_TRANSFER_NUM_BITS);
-+
-+ if (bytesTransfered > count) {
-+ if (oxnas_debug)
-+ printk("IIC read; Overrun\n");
-+ return -EREMOTEIO;;
-+ }
-+
-+ if (oxnas_debug) printk("read %lu bytes\n", bytesTransfered);
-+
-+ if (bytesTransfered < count) {
-+ if (oxnas_debug)
-+ printk("IIC read; short, wanted %u got %lu\n",
-+ count, bytesTransfered);
-+ return 0;
-+ }
-+
-+ return bytesTransfered;
-+}
-+
-+/* See if an IIC address exists..
-+ * addr = 7 bit address, unshifted
-+ */
-+static int
-+oxnas_iic_algo_tryaddress(struct i2c_algo_oxnas_data *oxnas, int addr)
-+{
-+ volatile i2c_registers_oxnas_t *i2c = oxnas->i2c;
-+ unsigned long flags, length, tmo, temp, bytesTransfered;
-+
-+ if (oxnas_debug) printk("oxnas_iic_algo_tryaddress(oxnas=%p/%p,addr=%d)\n", oxnas, i2c, addr);
-+
-+ /* do a simple read */
-+ length = 2;
-+
-+ {
-+ local_irq_save(flags);
-+
-+ /* QUESTION: Does this get locked by the parent? it should be!! */
-+ oxnas->iTransferInProgress_ = 1;
-+ oxnas->iError_ = 0;
-+
-+ // Set up the 7-bit slave address
-+ i2c->SerialAddressRegister = I2C_SAR_WRITE_MASK & ((addr) << I2C_SAR_SEVEN_BIT_ADDRESS_BIT);
-+
-+ // Setup the control register
-+ temp = ( I2C_SCR_WRITE << I2C_SCR_READ_WRITE_BIT ) |
-+ ( I2C_SCR_NORMAL << I2C_SCR_TRANSACTION_TYPE_BIT ) |
-+ ( I2C_SCR_SEVEN_BIT << I2C_SCR_ADDRESS_MODE_BIT ) |
-+ ( 0 << I2C_SCR_SCCB_MODE_ENABLE_BIT ) |
-+ ( 1 << I2C_SCR_SCCB_MODE_RESPECT_ACK_BIT ) |
-+ ( 1 << I2C_SCR_AUTO_INCREMENT_ENABLE_BIT ) |
-+ ( 1 << I2C_SCR_ENABLE_SLAVE_HOLD_OFF_BIT ) |
-+ ( 0 << I2C_SCR_HIGH_SPEED_DRIVE_BIT ) |
-+ ( length << I2C_SCR_BYTES_TO_TRANSFER_BIT );
-+
-+ temp &= I2C_SCR_WRITE_MASK;
-+ i2c->SerialControlRegister = temp;
-+
-+ /* Enable some interupts */
-+ *( &(i2c->SerialInterruptEnableRegister) ) |= (1UL << I2C_IER_SERIAL_ENABLE_BIT);
-+
-+ /* Begin transmission */
-+ *( &i2c->SerialControlRegister ) |= (1UL << I2C_SCR_TRANSACTION_PROGRESS_BIT);
-+
-+ /* Begin transmission */
-+
-+ /* Wait for IIC transfer */
-+ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
-+ local_irq_restore(flags);
-+ }
-+
-+ /* IDEA: busy wait for small transfers, its faster time_after(jiffies, tmo) */
-+
-+
-+ if (signal_pending(current) || !tmo){
-+ force_close(oxnas);
-+ if(oxnas_debug)
-+ printk("$rIIC test_addr: timeout!\n");
-+ return -EIO;
-+ }
-+
-+ if ( i2c->SerialControlRegister | (1UL << I2C_SCR_TRANSACTION_STATUS_BIT)) {
-+ if (oxnas_debug)
-+ printk("$rIIC test_addr; no ack\n");
-+ return -EREMOTEIO;
-+ }
-+
-+ // How many bytes were read from the slave?
-+ bytesTransfered = (temp >> I2C_SCR_BYTES_TO_TRANSFER_BIT) &
-+ ~(0xffffffff << I2C_SCR_BYTES_TO_TRANSFER_NUM_BITS);
-+
-+ if (bytesTransfered > 2) {
-+ if (oxnas_debug)
-+ printk("$rIIC test_addr; Overrun\n");
-+ return -EREMOTEIO;;
-+ }
-+
-+ if (oxnas_debug) printk("$rtest_addr %lu bytes\n", bytesTransfered);
-+
-+ if (bytesTransfered < 2) {
-+ if (oxnas_debug)
-+ printk("$rIIC test_addr; short, wanted %d got %lu\n",
-+ 2, bytesTransfered);
-+ return 0;
-+ }
-+ printk("$GIIC found @ test_addr (oxnas=%p,addr=%d)\n", oxnas, addr);
-+ return 1;
-+}
-+
-+static int oxnas_xfer(
-+ struct i2c_adapter *adap,
-+ struct i2c_msg msgs[],
-+ int num)
-+{
-+ struct i2c_algo_oxnas_data *oxnas = adap->algo_data;
-+ struct i2c_msg *pmsg;
-+ int i, ret;
-+ u_char addr;
-+
-+ if (oxnas_debug > 1) printk("oxnas_xfer()\n");
-+ for (i = 0; i < num; i++) {
-+ pmsg = &msgs[i];
-+
-+ if (oxnas_debug)
-+ printk("i2c-algo-oxnas.o: "
-+ "#%d addr=0x%x flags=0x%x len=%d\n buf=%lx\n",
-+ i, pmsg->addr, pmsg->flags, pmsg->len, (unsigned long)pmsg->buf);
-+
-+ addr = pmsg->addr << 1;
-+ if (pmsg->flags & I2C_M_RD )
-+ addr |= 1;
-+ if (pmsg->flags & I2C_M_REV_DIR_ADDR )
-+ addr ^= 1;
-+
-+ if (!(pmsg->flags & I2C_M_NOSTART)) {
-+ }
-+ if (pmsg->flags & I2C_M_RD ) {
-+ /* read bytes into buffer*/
-+ ret = oxnas_iic_algo_read(oxnas, addr, pmsg->buf, pmsg->len);
-+ if (oxnas_debug)
-+ printk("i2c-algo-oxnas.o: read %d bytes\n", ret);
-+ if (ret < pmsg->len ) {
-+ return (ret<0)? ret : -EREMOTEIO;
-+ }
-+ } else {
-+ /* write bytes from buffer */
-+ ret = oxnas_iic_algo_write(oxnas, addr, pmsg->buf, pmsg->len);
-+ if (oxnas_debug)
-+ printk("i2c-algo-oxnas.o: wrote %d\n", ret);
-+ if (ret < pmsg->len ) {
-+ return (ret<0) ? ret : -EREMOTEIO;
-+ }
-+ }
-+ }
-+ return (num);
-+}
-+
-+static u32 oxnas_func(struct i2c_adapter *adap)
-+{
-+ if (oxnas_debug > 1) printk("oxnas_func(I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING)\n");
-+
-+ return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
-+ I2C_FUNC_PROTOCOL_MANGLING;
-+}
-+
-+/* -----exported algorithm data: ------------------------------------- */
-+
-+static struct i2c_algorithm oxnas_algo = {
-+ .name = "Oxnas algorithm",
-+ .id = I2C_ALGO_OCP,
-+ .master_xfer = oxnas_xfer,
-+ .functionality = oxnas_func,
-+};
-+
-+/*
-+ * registering functions to load algorithms at runtime
-+ */
-+int i2c_oxnas_algo_add_bus(struct i2c_adapter *adap)
-+{
-+ int i;
-+ struct i2c_algo_oxnas_data *oxnas = adap->algo_data;
-+
-+ if (oxnas_debug) printk("i2c_oxnas_algo_add_bus: hw routines for %s registered.\n", adap->name);
-+
-+ /* register new adapter to i2c module... */
-+
-+ adap->id |= oxnas_algo.id;
-+ adap->algo = &oxnas_algo;
-+
-+ oxnas_iic_algo_init(oxnas);
-+ i2c_add_adapter(adap);
-+
-+ /* scan bus */
-+ if ( oxnas_scan ) {
-+ if (oxnas_debug) printk(KERN_INFO " i2c_oxnas_algo_add_bus: scanning bus %s...\n", adap->name);
-+ for (i = 0; i < 128; i++) {
-+ if (oxnas_debug) printk(KERN_INFO " scanning addr %d...\n", i);
-+ if (oxnas_iic_algo_tryaddress(oxnas, i)) {
-+ printk("(%02x)",i<<1);
-+ }
-+ }
-+ printk("\n");
-+ }
-+
-+ return 0;
-+}
-+
-+
-+int i2c_oxnas_algo_del_bus(struct i2c_adapter *adap)
-+{
-+ struct i2c_algo_oxnas_data *oxnas = adap->algo_data;
-+
-+ oxnas_iic_algo_shutdown(oxnas);
-+
-+ return i2c_del_adapter(adap);
-+}
-+
-+EXPORT_SYMBOL(i2c_oxnas_algo_add_bus);
-+EXPORT_SYMBOL(i2c_oxnas_algo_del_bus);
-+
-+MODULE_AUTHOR("Chris FOrd <....>");
-+MODULE_DESCRIPTION("I2C-Bus oxnas algorithm");
-+MODULE_LICENSE("GPL");
-+
-diff -Nurd linux-2.6.24/drivers/i2c/busses/Kconfig linux-2.6.24-oxe810/drivers/i2c/busses/Kconfig
---- linux-2.6.24/drivers/i2c/busses/Kconfig 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/i2c/busses/Kconfig 2008-06-11 17:50:33.000000000 +0200
-@@ -321,6 +321,15 @@
- This driver can also be built as a module. If so, the module
- will be called i2c-nforce2.
-
-+config I2C_OXNAS_BITBASH
-+ tristate "OXNAS bitbashed I2C interface"
-+ depends on I2C_ALGOBIT
-+ help
-+ Say Y here if you want to use I2C GPIO bit-bash interface
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called i2c-oxnas-bitbash.
-+
- config I2C_OCORES
- tristate "OpenCores I2C Controller"
- depends on EXPERIMENTAL
-diff -Nurd linux-2.6.24/drivers/i2c/busses/Makefile linux-2.6.24-oxe810/drivers/i2c/busses/Makefile
---- linux-2.6.24/drivers/i2c/busses/Makefile 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/i2c/busses/Makefile 2008-06-11 17:50:33.000000000 +0200
-@@ -28,6 +28,7 @@
- obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o
- obj-$(CONFIG_I2C_OMAP) += i2c-omap.o
- obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o
-+obj-$(CONFIG_I2C_OXNAS_BITBASH) += i2c-oxnas-bitbash.o
- obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o
- obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o
- obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o
-diff -Nurd linux-2.6.24/drivers/i2c/busses/i2c-oxnas-bitbash.c linux-2.6.24-oxe810/drivers/i2c/busses/i2c-oxnas-bitbash.c
---- linux-2.6.24/drivers/i2c/busses/i2c-oxnas-bitbash.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/i2c/busses/i2c-oxnas-bitbash.c 2008-06-11 17:50:33.000000000 +0200
-@@ -0,0 +1,158 @@
-+/*
-+ * drivers/i2c/busses/i2c_oxnas_bitbash.c
-+ *
-+ * Copyright (C) 2006-2008 Oxford Semiconductor Ltd
-+ *
-+ * 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 <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/i2c.h>
-+#include <linux/i2c-algo-bit.h>
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+
-+#define I2C_OXNAS_BITBASH_I2C_SDA_OUT (1UL << (CONFIG_OXNAS_I2C_SDA))
-+#define I2C_OXNAS_BITBASH_I2C_SCL_OUT (1UL << (CONFIG_OXNAS_I2C_SCL))
-+#define I2C_OXNAS_BB_PULSEWIDTH (40)
-+#define OPEN_COLLECTOR_CLOCK 1
-+
-+extern spinlock_t oxnas_gpio_spinlock;
-+
-+static void i2c_oxnas_bitbash_setsda(void *data,int state)
-+{
-+ if (state) {
-+ // tristae as input to set line on bus
-+ writel(I2C_OXNAS_BITBASH_I2C_SDA_OUT, GPIO_A_OUTPUT_ENABLE_CLEAR);
-+ } else {
-+ // tristate as output (with latch to zero) to assert zero on the bus
-+ writel(I2C_OXNAS_BITBASH_I2C_SDA_OUT, GPIO_A_OUTPUT_CLEAR);
-+ writel(I2C_OXNAS_BITBASH_I2C_SDA_OUT, GPIO_A_OUTPUT_ENABLE_SET);
-+ }
-+}
-+
-+static void i2c_oxnas_bitbash_setscl(void *data,int state)
-+{
-+#if OPEN_COLLECTOR_CLOCK
-+ if (state) {
-+ // tristae as input to set line on bus
-+ writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_ENABLE_CLEAR);
-+ } else {
-+ // tristate as output (with latch to zero) to assert zero on the bus
-+ writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_CLEAR);
-+ writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_ENABLE_SET);
-+ }
-+#else // driven clock
-+ if (state) {
-+ // tristae as input to set line on bus
-+ writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_SET);
-+ writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_ENABLE_CLEAR);
-+ } else {
-+ // tristate as output (with latch to zero) to assert zero on the bus
-+ writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_CLEAR);
-+ writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_ENABLE_SET);
-+ }
-+
-+#endif
-+}
-+
-+static int i2c_oxnas_bitbash_getsda(void *data)
-+{
-+ return ((readl(GPIO_A_DATA ) & I2C_OXNAS_BITBASH_I2C_SDA_OUT) != 0);
-+}
-+
-+static int i2c_oxnas_bitbash_getscl(void *data)
-+{
-+ return ((readl(GPIO_A_DATA ) & I2C_OXNAS_BITBASH_I2C_SCL_OUT) != 0);
-+}
-+
-+static struct i2c_algo_bit_data bit_i2c_oxnas_bitbash_data = {
-+ .setsda = i2c_oxnas_bitbash_setsda,
-+ .setscl = i2c_oxnas_bitbash_setscl,
-+ .getsda = i2c_oxnas_bitbash_getsda,
-+ .getscl = i2c_oxnas_bitbash_getscl,
-+ .udelay = I2C_OXNAS_BB_PULSEWIDTH,
-+ .timeout = HZ
-+};
-+
-+static struct i2c_adapter oxnas_i2c_bitbash_adapter = {
-+ .owner = THIS_MODULE,
-+ .name = "i2c_oxnas_bitbash adapter driver",
-+ .id = I2C_HW_B_OXNAS,
-+ .algo_data = &bit_i2c_oxnas_bitbash_data,
-+};
-+
-+static int __init i2c_oxnas_bitbash_init(void)
-+{
-+ unsigned long flags;
-+ unsigned long mask = I2C_OXNAS_BITBASH_I2C_SDA_OUT | I2C_OXNAS_BITBASH_I2C_SCL_OUT;
-+ int ret = 0;
-+
-+ /* Dedicate the GPIO over to i2c.
-+ * NOTE: This may be confusing, but we are not using the i2c core here we
-+ * are using bit-bashed GPIO, so we must disable the primary, secondary and
-+ * tertiary functions of the relevant GPIO pins
-+ */
-+ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+ writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) & ~mask, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+ writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0) & ~mask, SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+ writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0) & ~mask, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+
-+ i2c_oxnas_bitbash_setsda(NULL, 1);
-+ i2c_oxnas_bitbash_setscl(NULL, 1);
-+ ret = i2c_bit_add_bus(&oxnas_i2c_bitbash_adapter);
-+ if (!ret) {
-+#if defined(CONFIG_OXNAS_RTC) || defined(CONFIG_OXNAS_RTC_MODULE)
-+ /* Register the ST MT4100 RTC */
-+ struct i2c_board_info rtc_info = {
-+ .driver_name = "rtc-ds1307",
-+ .type = "m41t00",
-+ .flags = 0,
-+ .addr = 0x68,
-+ .platform_data = NULL,
-+ .irq = 0
-+ };
-+
-+ struct i2c_client *client = i2c_new_device(&oxnas_i2c_bitbash_adapter, &rtc_info);
-+ if (!client) {
-+ printk(KERN_WARNING "OXNAS bit-bash I2C driver failed to register RTC device\n");
-+ ret = -EIO;
-+ }
-+#endif // CONFIG_OXNAS_RTC || CONFIG_OXNAS_RTC_MODULE
-+ }
-+
-+ printk(KERN_INFO "OXNAS bit-bash I2C driver initialisation %s\n", ret ? "failed": "OK");
-+ return ret;
-+}
-+
-+static void __exit i2c_oxnas_bitbash_exit(void)
-+{
-+ i2c_oxnas_bitbash_setsda(NULL, 1);
-+ i2c_oxnas_bitbash_setscl(NULL, 1);
-+ i2c_del_adapter(&oxnas_i2c_bitbash_adapter);
-+}
-+
-+MODULE_AUTHOR("Brian Clarke");
-+MODULE_DESCRIPTION("OXNAS bit-bash I2C bus driver");
-+MODULE_LICENSE("GPL");
-+MODULE_VERSION("v2.0");
-+
-+module_init (i2c_oxnas_bitbash_init);
-+module_exit (i2c_oxnas_bitbash_exit);
-+
-diff -Nurd linux-2.6.24/drivers/leds/Kconfig linux-2.6.24-oxe810/drivers/leds/Kconfig
---- linux-2.6.24/drivers/leds/Kconfig 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/leds/Kconfig 2008-06-11 17:50:12.000000000 +0200
-@@ -62,6 +62,20 @@
- This option enables support for LEDs connected to GPIO lines
- on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440.
-
-+config WDC_LEDS_OXNAS800
-+ tristate "LED Support for WDC OXNAS800 GPIO LEDs"
-+ depends on LEDS_CLASS && ARCH_OXNAS
-+ help
-+ This option enables support for LEDs connected to GPIO lines on
-+ Oxford Semiconductor NAS800 in the Western Digital My Book NAS.
-+
-+config OXNAS_WD810_LEDS
-+ tristate "LED Support for 810 based WD NAS"
-+ depends on LEDS_CLASS && ARCH_OXNAS
-+ help
-+ This option enables support for LEDs connected to GPIO lines on the
-+ Oxford Semiconductor OX810 in the Western Digital NAS
-+
- config LEDS_AMS_DELTA
- tristate "LED Support for the Amstrad Delta (E3)"
- depends on LEDS_CLASS && MACH_AMS_DELTA
-@@ -137,6 +151,13 @@
- This allows LEDs to be controlled by IDE disk activity.
- If unsure, say Y.
-
-+config WDC_LEDS_TRIGGER_SATA_DISK
-+ bool "WDC LED SATA Disk Trigger"
-+ depends on LEDS_TRIGGERS
-+ help
-+ This allows WDC LEDs to be controlled by SATA disk activity.
-+ If unsure, say Y.
-+
- config LEDS_TRIGGER_HEARTBEAT
- tristate "LED Heartbeat Trigger"
- depends on LEDS_TRIGGERS
-diff -Nurd linux-2.6.24/drivers/macintosh/smu.c linux-2.6.24-oxe810/drivers/macintosh/smu.c
---- linux-2.6.24/drivers/macintosh/smu.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/macintosh/smu.c 2008-06-11 17:49:30.000000000 +0200
-@@ -85,6 +85,7 @@
- u32 cmd_buf_abs; /* command buffer absolute */
- struct list_head cmd_list;
- struct smu_cmd *cmd_cur; /* pending command */
-+ int broken_nap;
- struct list_head cmd_i2c_list;
- struct smu_i2c_cmd *cmd_i2c_cur; /* pending i2c command */
- struct timer_list i2c_timer;
-@@ -135,6 +136,19 @@
- fend = faddr + smu->cmd_buf->length + 2;
- flush_inval_dcache_range(faddr, fend);
-
-+
-+ /* We also disable NAP mode for the duration of the command
-+ * on U3 based machines.
-+ * This is slightly racy as it can be written back to 1 by a sysctl
-+ * but that never happens in practice. There seem to be an issue with
-+ * U3 based machines such as the iMac G5 where napping for the
-+ * whole duration of the command prevents the SMU from fetching it
-+ * from memory. This might be related to the strange i2c based
-+ * mechanism the SMU uses to access memory.
-+ */
-+ if (smu->broken_nap)
-+ powersave_nap = 0;
-+
- /* This isn't exactly a DMA mapping here, I suspect
- * the SMU is actually communicating with us via i2c to the
- * northbridge or the CPU to access RAM.
-@@ -211,6 +225,10 @@
- misc = cmd->misc;
- mb();
- cmd->status = rc;
-+
-+ /* Re-enable NAP mode */
-+ if (smu->broken_nap)
-+ powersave_nap = 1;
- bail:
- /* Start next command if any */
- smu_start_cmd();
-@@ -461,7 +479,7 @@
- if (np == NULL)
- return -ENODEV;
-
-- printk(KERN_INFO "SMU driver %s %s\n", VERSION, AUTHOR);
-+ printk(KERN_INFO "SMU: Driver %s %s\n", VERSION, AUTHOR);
-
- if (smu_cmdbuf_abs == 0) {
- printk(KERN_ERR "SMU: Command buffer not allocated !\n");
-@@ -533,6 +551,11 @@
- goto fail;
- }
-
-+ /* U3 has an issue with NAP mode when issuing SMU commands */
-+ smu->broken_nap = pmac_get_uninorth_variant() < 4;
-+ if (smu->broken_nap)
-+ printk(KERN_INFO "SMU: using NAP mode workaround\n");
-+
- sys_ctrler = SYS_CTRLER_SMU;
- return 0;
-
-diff -Nurd linux-2.6.24/drivers/md/Kconfig linux-2.6.24-oxe810/drivers/md/Kconfig
---- linux-2.6.24/drivers/md/Kconfig 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/md/Kconfig 2008-06-11 17:50:20.000000000 +0200
-@@ -229,6 +229,22 @@
-
- If unsure, say N.
-
-+config DM_OX_CRYPT
-+ tristate "OX800 Hardware Cryptograpy target support"
-+ depends on BLK_DEV_DM && EXPERIMENTAL && CRYPTO_OXAESLRW
-+ ---help---
-+ Based on dm-crypt by Fruhwirth & Saout it has been modified
-+ to work with the LRW-AES core in the OX800 NAS chip from
-+ Oxford Semiconductor Ltd.
-+
-+ This device-mapper target allows you to create a device that
-+ transparently encrypts the data on it.
-+
-+ To compile this code as a module, choose M here: the module will
-+ be called dm-ox-crypt.
-+
-+ If unsure, say N.
-+
- config DM_SNAPSHOT
- tristate "Snapshot target (EXPERIMENTAL)"
- depends on BLK_DEV_DM && EXPERIMENTAL
-diff -Nurd linux-2.6.24/drivers/md/Makefile linux-2.6.24-oxe810/drivers/md/Makefile
---- linux-2.6.24/drivers/md/Makefile 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/md/Makefile 2008-06-11 17:50:20.000000000 +0200
-@@ -33,6 +33,7 @@
- obj-$(CONFIG_BLK_DEV_MD) += md-mod.o
- obj-$(CONFIG_BLK_DEV_DM) += dm-mod.o
- obj-$(CONFIG_DM_CRYPT) += dm-crypt.o
-+obj-$(CONFIG_DM_OX_CRYPT) += dm-ox-crypt.o
- obj-$(CONFIG_DM_DELAY) += dm-delay.o
- obj-$(CONFIG_DM_MULTIPATH) += dm-multipath.o dm-round-robin.o
- obj-$(CONFIG_DM_MULTIPATH_EMC) += dm-emc.o
-diff -Nurd linux-2.6.24/drivers/md/dm-ox-crypt.c linux-2.6.24-oxe810/drivers/md/dm-ox-crypt.c
---- linux-2.6.24/drivers/md/dm-ox-crypt.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/md/dm-ox-crypt.c 2008-06-11 17:50:20.000000000 +0200
-@@ -0,0 +1,791 @@
-+/* linux/drivers/md/dm-ox-crypt.c
-+ *
-+ * OX800 DPE core compatable device encryption
-+ */
-+
-+/*
-+ * Copyright (C) 2003 Christophe Saout <christophe@saout.de>
-+ * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
-+ *
-+ * This file is released under the GPL.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/bio.h>
-+#include <linux/blkdev.h>
-+#include <linux/mempool.h>
-+#include <linux/slab.h>
-+#include <linux/crypto.h>
-+#include <linux/workqueue.h>
-+#include <asm/atomic.h>
-+#include <asm/scatterlist.h>
-+#include <asm/page.h>
-+#include <asm/arch/cipher.h>
-+
-+#include "dm.h"
-+
-+#define DM_MSG_PREFIX "ox-crypt: "
-+
-+/*
-+ * per bio private data
-+ */
-+struct oxcrypt_io {
-+ struct dm_target *target;
-+ struct bio *bio;
-+ struct bio *first_clone;
-+ struct work_struct work;
-+ atomic_t pending;
-+ int error;
-+};
-+
-+/*
-+ * context holding the current state of a multi-part conversion
-+ */
-+struct convert_context {
-+ struct bio *bio_in;
-+ struct bio *bio_out;
-+ unsigned int offset_in;
-+ unsigned int offset_out;
-+ unsigned int idx_in;
-+ unsigned int idx_out;
-+ sector_t sector;
-+ int write;
-+};
-+
-+struct oxcrypt_config;
-+
-+struct oxcrypt_iv_operations {
-+ int (*ctr)(struct oxcrypt_config *cc, struct dm_target *ti,
-+ const char *opts);
-+ void (*dtr)(struct oxcrypt_config *cc);
-+ const char *(*status)(struct oxcrypt_config *cc);
-+ int (*generator)(struct oxcrypt_config *cc, u8 *iv, sector_t sector);
-+};
-+
-+/*
-+ * Crypt: maps a linear range of a block device
-+ * and encrypts / decrypts at the same time.
-+ */
-+
-+struct oxcrypt_config {
-+ struct dm_dev *dev;
-+ sector_t start;
-+
-+ /*
-+ * pool for per bio private data and
-+ * for encryption buffer pages
-+ */
-+ mempool_t *io_pool;
-+ mempool_t *page_pool;
-+
-+ /*
-+ * crypto related data
-+ */
-+ struct oxcrypt_iv_operations *iv_gen_ops;
-+ void *iv_gen_private;
-+ sector_t iv_offset;
-+ unsigned int iv_size;
-+
-+ struct crypto_tfm *tfm;
-+ u8 key[OX800DPE_KEYSIZE]; /* size of key is fixed by hardware */
-+ u8 iv_key[OX800DPE_KEYSIZE];
-+};
-+
-+#define MIN_IOS 256
-+#define MIN_POOL_PAGES 32
-+#define MIN_BIO_PAGES 8
-+
-+static struct kmem_cache *_oxcrypt_io_pool;
-+
-+/*
-+ * Mempool alloc and free functions for the page
-+ */
-+static void *mempool_alloc_page(gfp_t gfp_mask, void *data)
-+{
-+ return alloc_page(gfp_mask);
-+}
-+
-+static void mempool_free_page(void *page, void *data)
-+{
-+ __free_page(page);
-+}
-+
-+
-+/*
-+ * Different IV generation algorithms:
-+ *
-+ * oxsemi:
-+ * Uses the 32 sector number and a reproducable hash of target device
-+ * properties to generate bits 35-32
-+ *
-+ */
-+
-+static int oxcrypt_iv_oxsemi_gen(struct oxcrypt_config *cc, u8 *iv, sector_t sector)
-+{
-+ *((u32* )iv) = cpu_to_le32(sector & 0xffffffff);
-+ *( ((u32* )iv) + 1) = 0; /** @todo bits 35 - 32 */
-+
-+ return 0;
-+}
-+
-+static struct oxcrypt_iv_operations oxcrypt_iv_oxsemi_ops = {
-+ .generator = oxcrypt_iv_oxsemi_gen
-+};
-+
-+
-+/*static inline*/ int
-+oxcrypt_convert_scatterlist(struct oxcrypt_config *cc, struct scatterlist *out,
-+ struct scatterlist *in, unsigned int length,
-+ int write, sector_t sector)
-+{
-+ u8 iv[OX800DPE_KEYSIZE];
-+ int r = 0;
-+
-+ if (cc->iv_gen_ops) { /* probably no need to check this */
-+ u8* pri = cc->key;
-+ u8* twe = cc->iv_key;
-+
-+ r = cc->iv_gen_ops->generator(cc, iv, sector);
-+ if (r < 0)
-+ return r;
-+
-+ if (write)
-+ r = ox800_aeslrw_encrypt(in, out, 1, iv, pri, twe);
-+ else
-+ r = ox800_aeslrw_decrypt(in, out, 1, iv, pri, twe);
-+ } else {
-+ BUG();
-+ }
-+
-+ //printk("back\n");
-+ if (r < 0) {
-+ printk(KERN_ERR"oxcrypt_convert_scatterlist: core driver returned error %d\n",r);
-+ }
-+
-+ return r;
-+}
-+
-+static void
-+oxcrypt_convert_init(struct oxcrypt_config *cc, struct convert_context *ctx,
-+ struct bio *bio_out, struct bio *bio_in,
-+ sector_t sector, int write)
-+{
-+ ctx->bio_in = bio_in;
-+ ctx->bio_out = bio_out;
-+ ctx->offset_in = 0;
-+ ctx->offset_out = 0;
-+ ctx->idx_in = bio_in ? bio_in->bi_idx : 0;
-+ ctx->idx_out = bio_out ? bio_out->bi_idx : 0;
-+ ctx->sector = sector + cc->iv_offset;
-+ ctx->write = write;
-+}
-+
-+/**
-+ * Encrypt / decrypt data from one bio to another one (can be the same one)
-+ *
-+ * @todo This only goes atr one sector at a time, could it be made to this in
-+ * a scatter gather list of multiple sectors?
-+ */
-+static int oxcrypt_convert(struct oxcrypt_config *cc,
-+ struct convert_context *ctx)
-+{
-+ int r = 0;
-+ struct bio_vec *bv_in ;
-+ struct bio_vec *bv_out ;
-+ struct scatterlist sg_in;
-+ struct scatterlist sg_out;
-+
-+ //printk("oxcrypt_convert config %p context %p \n", cc, ctx);
-+
-+ while(ctx->idx_in < ctx->bio_in->bi_vcnt &&
-+ ctx->idx_out < ctx->bio_out->bi_vcnt) {
-+
-+ bv_in = bio_iovec_idx(ctx->bio_in, ctx->idx_in);
-+ bv_out = bio_iovec_idx(ctx->bio_out, ctx->idx_out);
-+
-+ sg_in.page = bv_in->bv_page;
-+ sg_in.offset = bv_in->bv_offset + ctx->offset_in;
-+ sg_in.length = 1 << SECTOR_SHIFT;
-+
-+ sg_out.page = bv_out->bv_page;
-+ sg_out.offset = bv_out->bv_offset + ctx->offset_out;
-+ sg_out.length = 1 << SECTOR_SHIFT;
-+
-+ ctx->offset_in += sg_in.length;
-+ if (ctx->offset_in >= bv_in->bv_len) {
-+ ctx->offset_in = 0;
-+ ctx->idx_in++;
-+ }
-+
-+ ctx->offset_out += sg_out.length;
-+ if (ctx->offset_out >= bv_out->bv_len) {
-+ ctx->offset_out = 0;
-+ ctx->idx_out++;
-+ }
-+
-+ r = oxcrypt_convert_scatterlist(cc, &sg_out, &sg_in, sg_in.length,
-+ ctx->write, ctx->sector);
-+ if (r < 0)
-+ break;
-+
-+ ctx->sector++;
-+ }
-+
-+ return r;
-+}
-+
-+/*
-+ * Generate a new unfragmented bio with the given size
-+ * This should never violate the device limitations
-+ * May return a smaller bio when running out of pages
-+ */
-+static struct bio *
-+oxcrypt_alloc_buffer(struct oxcrypt_config *cc, unsigned int size,
-+ struct bio *base_bio, unsigned int *bio_vec_idx)
-+{
-+ struct bio *bio;
-+ unsigned int nr_iovecs = dm_div_up(size, PAGE_SIZE);
-+ int gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
-+ unsigned long flags = current->flags;
-+ unsigned int i;
-+
-+ /*
-+ * Tell VM to act less aggressively and fail earlier.
-+ * This is not necessary but increases throughput.
-+ * FIXME: Is this really intelligent?
-+ */
-+ current->flags &= ~PF_MEMALLOC;
-+
-+ if (base_bio)
-+ bio = bio_clone(base_bio, GFP_NOIO);
-+ else
-+ bio = bio_alloc(GFP_NOIO, nr_iovecs);
-+ if (!bio) {
-+ if (flags & PF_MEMALLOC)
-+ current->flags |= PF_MEMALLOC;
-+ return NULL;
-+ }
-+
-+ /* if the last bio was not complete, continue where that one ended */
-+ bio->bi_idx = *bio_vec_idx;
-+ bio->bi_vcnt = *bio_vec_idx;
-+ bio->bi_size = 0;
-+ bio->bi_flags &= ~(1 << BIO_SEG_VALID);
-+
-+ /* bio->bi_idx pages have already been allocated */
-+ size -= bio->bi_idx * PAGE_SIZE;
-+
-+ for(i = bio->bi_idx; i < nr_iovecs; i++) {
-+ struct bio_vec *bv = bio_iovec_idx(bio, i);
-+
-+ bv->bv_page = mempool_alloc(cc->page_pool, gfp_mask);
-+ if (!bv->bv_page)
-+ break;
-+
-+ /*
-+ * if additional pages cannot be allocated without waiting,
-+ * return a partially allocated bio, the caller will then try
-+ * to allocate additional bios while submitting this partial bio
-+ */
-+ if ((i - bio->bi_idx) == (MIN_BIO_PAGES - 1))
-+ gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT;
-+
-+ bv->bv_offset = 0;
-+ if (size > PAGE_SIZE)
-+ bv->bv_len = PAGE_SIZE;
-+ else
-+ bv->bv_len = size;
-+
-+ bio->bi_size += bv->bv_len;
-+ bio->bi_vcnt++;
-+ size -= bv->bv_len;
-+ }
-+
-+ if (flags & PF_MEMALLOC)
-+ current->flags |= PF_MEMALLOC;
-+
-+ if (!bio->bi_size) {
-+ bio_put(bio);
-+ return NULL;
-+ }
-+
-+ /*
-+ * Remember the last bio_vec allocated to be able
-+ * to correctly continue after the splitting.
-+ */
-+ *bio_vec_idx = bio->bi_vcnt;
-+
-+ return bio;
-+}
-+
-+static void oxcrypt_free_buffer_pages(struct oxcrypt_config *cc,
-+ struct bio *bio, unsigned int bytes)
-+{
-+ unsigned int i, start, end;
-+ struct bio_vec *bv;
-+
-+ /*
-+ * This is ugly, but Jens Axboe thinks that using bi_idx in the
-+ * endio function is too dangerous at the moment, so I calculate the
-+ * correct position using bi_vcnt and bi_size.
-+ * The bv_offset and bv_len fields might already be modified but we
-+ * know that we always allocated whole pages.
-+ * A fix to the bi_idx issue in the kernel is in the works, so
-+ * we will hopefully be able to revert to the cleaner solution soon.
-+ */
-+ i = bio->bi_vcnt - 1;
-+ bv = bio_iovec_idx(bio, i);
-+ end = (i << PAGE_SHIFT) + (bv->bv_offset + bv->bv_len) - bio->bi_size;
-+ start = end - bytes;
-+
-+ start >>= PAGE_SHIFT;
-+ if (!bio->bi_size)
-+ end = bio->bi_vcnt;
-+ else
-+ end >>= PAGE_SHIFT;
-+
-+ for(i = start; i < end; i++) {
-+ bv = bio_iovec_idx(bio, i);
-+ BUG_ON(!bv->bv_page);
-+ mempool_free(bv->bv_page, cc->page_pool);
-+ bv->bv_page = NULL;
-+ }
-+}
-+
-+/*
-+ * One of the bios was finished. Check for completion of
-+ * the whole request and correctly clean up the buffer.
-+ */
-+static void dec_pending(struct oxcrypt_io *io, int error)
-+{
-+ struct oxcrypt_config *cc = (struct oxcrypt_config *) io->target->private;
-+
-+ if (error < 0)
-+ io->error = error;
-+
-+ if (!atomic_dec_and_test(&io->pending))
-+ return;
-+
-+ if (io->first_clone)
-+ bio_put(io->first_clone);
-+
-+ bio_endio(io->bio, io->bio->bi_size, io->error);
-+
-+ mempool_free(io, cc->io_pool);
-+}
-+
-+/*
-+ * kcryptd:
-+ *
-+ * Needed because it would be very unwise to do decryption in an
-+ * interrupt context, so bios returning from read requests get
-+ * queued here.
-+ */
-+static struct workqueue_struct *_kcryptd_workqueue;
-+
-+static void kcryptd_do_work(struct work_struct *work)
-+{
-+ struct oxcrypt_io *io = container_of(work, struct oxcrypt_io, work);
-+ struct oxcrypt_config *cc = (struct oxcrypt_config *) io->target->private;
-+ struct convert_context ctx;
-+ int r;
-+
-+ oxcrypt_convert_init(cc, &ctx, io->bio, io->bio,
-+ io->bio->bi_sector - io->target->begin, 0);
-+
-+ /* printk("kcryptd_do_work %d sectors\n", ctx.bio_in->bi_vcnt ); */
-+ r = oxcrypt_convert(cc, &ctx);
-+
-+ dec_pending(io, r);
-+}
-+
-+static void kcryptd_queue_io(struct oxcrypt_io *io)
-+{
-+ INIT_WORK(&io->work, kcryptd_do_work);
-+ queue_work(_kcryptd_workqueue, &io->work);
-+}
-+
-+/*
-+ * Decode key from its hex representation
-+ */
-+static int oxcrypt_decode_key(u8 *key, char *hex, unsigned int size)
-+{
-+ char buffer[3];
-+ char *endp;
-+ unsigned int i;
-+
-+ buffer[2] = '\0';
-+
-+ for(i = 0; i < size; i++) {
-+ buffer[0] = *hex++;
-+ buffer[1] = *hex++;
-+ key[i] = (u8)simple_strtoul(buffer, &endp, 16);
-+
-+ if (endp != &buffer[2])
-+ return -EINVAL;
-+ }
-+
-+ if (*hex != '\0')
-+ return -EINVAL;
-+
-+ /*
-+ printk(KERN_INFO"key =");
-+ for (i = 0; i < OX800DPE_KEYSIZE; ++i)
-+ printk("%02x", key[i]);
-+ printk("\n");
-+ */
-+
-+ return 0;
-+}
-+
-+/*
-+ * Encode key into its hex representation
-+ */
-+static void oxcrypt_encode_key(char *hex, u8 *key, unsigned int size)
-+{
-+ unsigned int i;
-+
-+ for(i = 0; i < size; i++) {
-+ sprintf(hex, "%02x", *key);
-+ hex += 2;
-+ key++;
-+ }
-+}
-+
-+/*
-+ * Construct an encryption mapping, much simpler:
-+ * <key> <iv-key> <iv_offset> <dev_path> <start>
-+ */
-+static int oxcrypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
-+{
-+ struct oxcrypt_config *cc;
-+ unsigned long long tmpll;
-+
-+ if (argc != 5) {
-+ ti->error = DM_MSG_PREFIX "Not enough arguments";
-+ return -EINVAL;
-+ }
-+
-+ cc = kmalloc(sizeof(*cc) , GFP_KERNEL);
-+ if (cc == NULL) {
-+ ti->error =
-+ DM_MSG_PREFIX "Cannot allocate transparent encryption context";
-+ return -ENOMEM;
-+ }
-+
-+ memset( cc, 0, sizeof(*cc) );
-+
-+ if (oxcrypt_decode_key(cc->key, argv[0], OX800DPE_KEYSIZE) < 0) {
-+ ti->error = DM_MSG_PREFIX "Error decoding key";
-+ goto bad1;
-+ }
-+
-+ if (oxcrypt_decode_key(cc->iv_key, argv[1], OX800DPE_KEYSIZE) < 0) {
-+ ti->error = DM_MSG_PREFIX "Error decoding iv key";
-+ goto bad1;
-+ }
-+
-+ /*
-+ * Force the ivmode to the ox-semi version
-+ */
-+ cc->iv_gen_ops = &oxcrypt_iv_oxsemi_ops;
-+
-+ cc->io_pool = mempool_create(MIN_IOS, mempool_alloc_slab,
-+ mempool_free_slab, _oxcrypt_io_pool);
-+ if (!cc->io_pool) {
-+ ti->error = DM_MSG_PREFIX "Cannot allocate crypt io mempool";
-+ goto bad3;
-+ }
-+
-+ cc->page_pool = mempool_create(MIN_POOL_PAGES, mempool_alloc_page,
-+ mempool_free_page, NULL);
-+ if (!cc->page_pool) {
-+ ti->error = DM_MSG_PREFIX "Cannot allocate page mempool";
-+ goto bad4;
-+ }
-+
-+ if (sscanf(argv[2], "%llu", &tmpll) != 1) {
-+ ti->error = DM_MSG_PREFIX "Invalid iv_offset sector";
-+ goto bad5;
-+ }
-+ cc->iv_offset = tmpll;
-+
-+ if (sscanf(argv[4], "%llu", &tmpll) != 1) {
-+ ti->error = DM_MSG_PREFIX "Invalid device sector";
-+ goto bad5;
-+ }
-+ cc->start = tmpll;
-+
-+ if (dm_get_device(ti, argv[3], cc->start, ti->len,
-+ dm_table_get_mode(ti->table), &cc->dev)) {
-+ ti->error = DM_MSG_PREFIX "Device lookup failed";
-+ goto bad5;
-+ }
-+
-+
-+ ti->private = cc;
-+
-+ return 0;
-+
-+bad5:
-+ mempool_destroy(cc->page_pool);
-+bad4:
-+ mempool_destroy(cc->io_pool);
-+bad3:
-+ if (cc->iv_gen_ops && cc->iv_gen_ops->dtr)
-+ cc->iv_gen_ops->dtr(cc);
-+bad1:
-+ kfree(cc);
-+ return -EINVAL;
-+}
-+
-+static void oxcrypt_dtr(struct dm_target *ti)
-+{
-+ struct oxcrypt_config *cc = (struct oxcrypt_config *) ti->private;
-+
-+ mempool_destroy(cc->page_pool);
-+ mempool_destroy(cc->io_pool);
-+
-+ if (cc->iv_gen_ops && cc->iv_gen_ops->dtr)
-+ cc->iv_gen_ops->dtr(cc);
-+ dm_put_device(ti, cc->dev);
-+
-+ kfree(cc);
-+}
-+
-+static int oxcrypt_endio(struct bio *bio, unsigned int done, int error)
-+{
-+ struct oxcrypt_io *io = (struct oxcrypt_io *) bio->bi_private;
-+ struct oxcrypt_config *cc = (struct oxcrypt_config *) io->target->private;
-+
-+ if (bio_data_dir(bio) == WRITE) {
-+ /*
-+ * free the processed pages, even if
-+ * it's only a partially completed write
-+ */
-+ oxcrypt_free_buffer_pages(cc, bio, done);
-+ }
-+
-+ if (bio->bi_size)
-+ return 1;
-+
-+ bio_put(bio);
-+
-+ /*
-+ * successful reads are decrypted by the worker thread
-+ */
-+ if ((bio_data_dir(bio) == READ)
-+ && bio_flagged(bio, BIO_UPTODATE)) {
-+ kcryptd_queue_io(io);
-+ return 0;
-+ }
-+
-+ dec_pending(io, error);
-+ return error;
-+}
-+
-+static struct bio *
-+oxcrypt_clone(struct oxcrypt_config *cc, struct oxcrypt_io *io, struct bio *bio,
-+ sector_t sector, unsigned int *bvec_idx,
-+ struct convert_context *ctx)
-+{
-+ struct bio *clone;
-+
-+ if (bio_data_dir(bio) == WRITE) {
-+ clone = oxcrypt_alloc_buffer(cc, bio->bi_size,
-+ io->first_clone, bvec_idx);
-+ if (clone) {
-+ ctx->bio_out = clone;
-+ if (oxcrypt_convert(cc, ctx) < 0) {
-+ oxcrypt_free_buffer_pages(cc, clone,
-+ clone->bi_size);
-+ bio_put(clone);
-+ return NULL;
-+ }
-+ }
-+ } else {
-+ /*
-+ * The block layer might modify the bvec array, so always
-+ * copy the required bvecs because we need the original
-+ * one in order to decrypt the whole bio data *afterwards*.
-+ */
-+ clone = bio_alloc(GFP_NOIO, bio_segments(bio));
-+ if (clone) {
-+ clone->bi_idx = 0;
-+ clone->bi_vcnt = bio_segments(bio);
-+ clone->bi_size = bio->bi_size;
-+ memcpy(clone->bi_io_vec, bio_iovec(bio),
-+ sizeof(struct bio_vec) * clone->bi_vcnt);
-+ }
-+ }
-+
-+ if (!clone)
-+ return NULL;
-+
-+ clone->bi_private = io;
-+ clone->bi_end_io = oxcrypt_endio;
-+ clone->bi_bdev = cc->dev->bdev;
-+ clone->bi_sector = cc->start + sector;
-+ clone->bi_rw = bio->bi_rw;
-+
-+ return clone;
-+}
-+
-+static int oxcrypt_map(struct dm_target *ti, struct bio *bio,
-+ union map_info *map_context)
-+{
-+ struct oxcrypt_config *cc = (struct oxcrypt_config *) ti->private;
-+ struct oxcrypt_io *io = mempool_alloc(cc->io_pool, GFP_NOIO);
-+ struct convert_context ctx;
-+ struct bio *clone;
-+ unsigned int remaining = bio->bi_size;
-+ sector_t sector = bio->bi_sector - ti->begin;
-+ unsigned int bvec_idx = 0;
-+
-+ io->target = ti;
-+ io->bio = bio;
-+ io->first_clone = NULL;
-+ io->error = 0;
-+ atomic_set(&io->pending, 1); /* hold a reference */
-+
-+ if (bio_data_dir(bio) == WRITE)
-+ oxcrypt_convert_init(cc, &ctx, NULL, bio, sector, 1);
-+
-+ /*
-+ * The allocated buffers can be smaller than the whole bio,
-+ * so repeat the whole process until all the data can be handled.
-+ */
-+ while (remaining) {
-+ clone = oxcrypt_clone(cc, io, bio, sector, &bvec_idx, &ctx);
-+ if (!clone)
-+ goto cleanup;
-+
-+ if (!io->first_clone) {
-+ /*
-+ * hold a reference to the first clone, because it
-+ * holds the bio_vec array and that can't be freed
-+ * before all other clones are released
-+ */
-+ bio_get(clone);
-+ io->first_clone = clone;
-+ }
-+ atomic_inc(&io->pending);
-+
-+ remaining -= clone->bi_size;
-+ sector += bio_sectors(clone);
-+
-+ generic_make_request(clone);
-+
-+ /* out of memory -> run queues */
-+ if (remaining)
-+ congestion_wait(bio_data_dir(clone), HZ/100);
-+ }
-+
-+ /* drop reference, clones could have returned before we reach this */
-+ dec_pending(io, 0);
-+ return 0;
-+
-+cleanup:
-+ if (io->first_clone) {
-+ dec_pending(io, -ENOMEM);
-+ return 0;
-+ }
-+
-+ /* if no bio has been dispatched yet, we can directly return the error */
-+ mempool_free(io, cc->io_pool);
-+ return -ENOMEM;
-+}
-+
-+static int oxcrypt_status(struct dm_target *ti, status_type_t type,
-+ char *result, unsigned int maxlen)
-+{
-+ struct oxcrypt_config *cc = (struct oxcrypt_config *) ti->private;
-+ char buffer[32];
-+ const char *cipher;
-+ const char *chainmode = NULL;
-+ unsigned int sz = 0;
-+
-+ switch (type) {
-+ case STATUSTYPE_INFO:
-+ result[0] = '\0';
-+ break;
-+
-+ case STATUSTYPE_TABLE:
-+ cipher = "AES";
-+
-+ chainmode = "ecb";
-+
-+ DMEMIT("%s-%s ", cipher, chainmode);
-+
-+ oxcrypt_encode_key(result + sz, cc->key, OX800DPE_KEYSIZE);
-+ sz += OX800DPE_KEYSIZE << 1;
-+
-+ format_dev_t(buffer, cc->dev->bdev->bd_dev);
-+ DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset,
-+ buffer, (unsigned long long)cc->start);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static struct target_type oxcrypt_target = {
-+ .name = "ox-crypt",
-+ .version= {1, 1, 0},
-+ .module = THIS_MODULE,
-+ .ctr = oxcrypt_ctr,
-+ .dtr = oxcrypt_dtr,
-+ .map = oxcrypt_map,
-+ .status = oxcrypt_status,
-+};
-+
-+static int __init dm_oxcrypt_init(void)
-+{
-+ int r;
-+
-+ _oxcrypt_io_pool = kmem_cache_create("dm-ox-oxcrypt_io",
-+ sizeof(struct oxcrypt_io),
-+ 0, 0, NULL);
-+ if (!_oxcrypt_io_pool)
-+ return -ENOMEM;
-+
-+ _kcryptd_workqueue = create_workqueue("kcryptd");
-+ if (!_kcryptd_workqueue) {
-+ r = -ENOMEM;
-+ DMERR("couldn't create kcryptd");
-+ goto bad1;
-+ }
-+
-+ r = dm_register_target(&oxcrypt_target);
-+ if (r < 0) {
-+ DMERR("register failed %d", r);
-+ goto bad2;
-+ }
-+
-+ return 0;
-+
-+bad2:
-+ destroy_workqueue(_kcryptd_workqueue);
-+bad1:
-+ kmem_cache_destroy(_oxcrypt_io_pool);
-+ return r;
-+}
-+
-+static void __exit dm_oxcrypt_exit(void)
-+{
-+ int r = dm_unregister_target(&oxcrypt_target);
-+
-+ if (r < 0)
-+ DMERR("unregister failed %d", r);
-+
-+ destroy_workqueue(_kcryptd_workqueue);
-+ kmem_cache_destroy(_oxcrypt_io_pool);
-+}
-+
-+module_init(dm_oxcrypt_init);
-+module_exit(dm_oxcrypt_exit);
-+
-+MODULE_AUTHOR("Oxford Semiconductor based on work of Christophe Saout");
-+MODULE_DESCRIPTION(DM_NAME " target for hardware encryption / decryption");
-+MODULE_LICENSE("GPL");
-diff -Nurd linux-2.6.24/drivers/md/raid1.c linux-2.6.24-oxe810/drivers/md/raid1.c
---- linux-2.6.24/drivers/md/raid1.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/md/raid1.c 2008-06-11 17:50:20.000000000 +0200
-@@ -34,6 +34,12 @@
- #include "dm-bio-list.h"
- #include <linux/raid/raid1.h>
- #include <linux/raid/bitmap.h>
-+#ifdef CONFIG_SATA_OX800
-+#include <asm/arch/sata.h>
-+#endif
-+#ifdef CONFIG_SATA_OX810
-+#include <asm/arch/ox810sata.h>
-+#endif
-
- #define DEBUG 0
- #if DEBUG
-@@ -67,6 +73,79 @@
- return r1_bio;
- }
-
-+/**
-+ * Assesses if the current raid configuration is suitable for implementation
-+ * by the raid HW, if so, will enable it
-+ */
-+static void raid1_hw_raidable(mddev_t *mddev)
-+{
-+ mdk_rdev_t *rdev0;
-+ mdk_rdev_t *rdev1;
-+ conf_t *conf = mddev_to_conf(mddev);
-+
-+ /*default to SW RAID */
-+ conf->hw_raid1_settings = 0;
-+
-+#if defined(CONFIG_SATA_OX800) || defined(CONFIG_SATA_OX810)
-+ /* if this drive is suitable for HW raid then enable it */
-+ if (mddev->raid_disks != 2) {
-+ printk(KERN_NOTICE"raid1 not hw raidable %d disks (needs to be 2)\n",mddev->raid_disks);
-+ return;
-+ }
-+
-+ rdev0 = rcu_dereference(conf->mirrors[0].rdev);
-+ rdev1 = rcu_dereference(conf->mirrors[1].rdev);
-+
-+ /* are there two working disks */
-+ if (!rdev0 ||
-+ !rdev1 ||
-+ test_bit(Faulty, &rdev0->flags) ||
-+ test_bit(Faulty, &rdev1->flags) ) {
-+ printk(KERN_NOTICE"raid1 not hw raidable, needs two working disks.\n");
-+ return;
-+ }
-+
-+ if (!rdev0->bdev ||
-+ !rdev1->bdev ||
-+ !rdev0->bdev->bd_part ||
-+ !rdev1->bdev->bd_part ) {
-+ printk(KERN_NOTICE"raid1 not hw raidable, mirrors not ready\n");
-+ return;
-+ }
-+
-+ if (rdev0->bdev->bd_part->start_sect !=
-+ rdev1->bdev->bd_part->start_sect) {
-+ printk(KERN_NOTICE"raid1 not hw raidable, partition start sectors differ %lu, %lu\n",
-+ rdev0->bdev->bd_part->start_sect,
-+ rdev1->bdev->bd_part->start_sect);
-+ return;
-+ }
-+
-+ if (!rdev0->bdev->bd_disk ||
-+ !rdev0->bdev->bd_disk->queue ||
-+ (oxnassata_get_port_no(rdev0->bdev->bd_disk->queue) < 0)) {
-+ printk(KERN_NOTICE"raid1 not hw raidable, RAID disk 0 not on internal SATA port.\n");
-+ return;
-+ }
-+
-+ if (!rdev1->bdev->bd_disk ||
-+ !rdev1->bdev->bd_disk->queue ||
-+ (oxnassata_get_port_no(rdev1->bdev->bd_disk->queue) < 0)) {
-+ printk(KERN_NOTICE"raid1 not hw raidable, RAID disk 1 not on internal SATA port.\n");
-+ return;
-+ }
-+
-+ /* cannot mix 28 and 48-bit LBA devices */
-+ if (!oxnassata_LBA_schemes_compatible()) {
-+ printk(KERN_NOTICE"raid0 not hw raidable, disks need to use same LBA size (28 vs 48)\n");
-+ return;
-+ }
-+
-+ conf->hw_raid1_settings = OXNASSATA_RAID1;
-+ printk(KERN_NOTICE"raid1 using hardware RAID 0x%08x\n",conf->hw_raid1_settings);
-+#endif /*CONFIG_SCSI_OX800SATA*/
-+}
-+
- static void r1bio_pool_free(void *r1_bio, void *data)
- {
- kfree(r1_bio);
-@@ -325,9 +404,29 @@
- r1_bio->bios[mirror] = NULL;
- to_put = bio;
- if (!uptodate) {
-+#if defined(CONFIG_SATA_OX800) || defined(CONFIG_SATA_OX810)
-+ if ((mirror == 0) && (bio->bi_raid)) {
-+ /* command was sent to part 0 for both drives, need to find
-+ * which drive caused the error */
-+ int device = oxnassata_RAID_faults();
-+
-+ /* it's unlikely, but both disks could fail at once */
-+ if (device & 1) md_error(r1_bio->mddev, conf->mirrors[0].rdev);
-+ if (device & 2) md_error(r1_bio->mddev, conf->mirrors[1].rdev);
-+
-+ /* an I/O failed, we can't clear the bitmap */
-+ set_bit(R1BIO_Degraded, &r1_bio->state);
-+
-+ if (!(device & 3))
-+ set_bit(R1BIO_Uptodate, &r1_bio->state);
-+ } else {
-+#endif // CONFIG_SCSI_OX800SATA
- md_error(r1_bio->mddev, conf->mirrors[mirror].rdev);
- /* an I/O failed, we can't clear the bitmap */
- set_bit(R1BIO_Degraded, &r1_bio->state);
-+#if defined(CONFIG_SATA_OX800) || defined(CONFIG_SATA_OX810)
-+ }
-+#endif // CONFIG_SCSI_OX800SATA
- } else
- /*
- * Set R1BIO_Uptodate in our master bio, so that
-@@ -824,6 +923,53 @@
- }
- #endif
- rcu_read_lock();
-+
-+ /* start of oxsemi hw raid code */
-+ if ((rcu_dereference(conf->mirrors[0].rdev)) &&
-+ (rcu_dereference(conf->mirrors[1].rdev)) &&
-+ !test_bit(Faulty, &rcu_dereference(conf->mirrors[0].rdev)->flags) &&
-+ !test_bit(Faulty, &rcu_dereference(conf->mirrors[1].rdev)->flags) &&
-+ (conf->hw_raid1_settings) )
-+ {
-+ struct bio *mbio;
-+
-+ rdev = rcu_dereference(conf->mirrors[0].rdev);
-+ atomic_inc(&rdev->nr_pending);
-+ r1_bio->bios[0] = bio;
-+ targets++;
-+
-+ rcu_read_unlock();
-+
-+ /* do behind I/O ? */
-+ if (bitmap &&
-+ atomic_read(&bitmap->behind_writes) < bitmap->max_write_behind &&
-+ (behind_pages = alloc_behind_pages(bio)) != NULL)
-+ set_bit(R1BIO_BehindIO, &r1_bio->state);
-+
-+ atomic_set(&r1_bio->remaining, 0);
-+ atomic_set(&r1_bio->behind_remaining, 0);
-+
-+ do_barriers = bio_barrier(bio);
-+ if (do_barriers)
-+ set_bit(R1BIO_Barrier, &r1_bio->state);
-+
-+ bio_list_init(&bl);
-+
-+ mbio = bio_clone(bio, GFP_NOIO);
-+ r1_bio->bios[0] = mbio;
-+
-+ mbio->bi_sector = r1_bio->sector + conf->mirrors[0].rdev->data_offset;
-+ mbio->bi_bdev = conf->mirrors[0].rdev->bdev;
-+ mbio->bi_end_io = raid1_end_write_request;
-+ mbio->bi_rw = WRITE | do_barriers | do_sync;
-+ mbio->bi_private = r1_bio;
-+ mbio->bi_raid = conf->hw_raid1_settings ;
-+
-+ atomic_inc(&r1_bio->remaining);
-+
-+ bio_list_add(&bl, mbio);
-+ /* end of hw_raid code */
-+ } else {
- for (i = 0; i < disks; i++) {
- if ((rdev=rcu_dereference(conf->mirrors[i].rdev)) != NULL &&
- !test_bit(Faulty, &rdev->flags)) {
-@@ -896,6 +1042,8 @@
-
- bio_list_add(&bl, mbio);
- }
-+ }
-+
- kfree(behind_pages); /* the behind pages are attached to the bios now */
-
- bitmap_startwrite(bitmap, bio->bi_sector, r1_bio->sectors,
-@@ -969,6 +1117,9 @@
- printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n"
- " Operation continuing on %d devices\n",
- bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded);
-+
-+ /* check to see if this new configuration is supported by hardware RAID */
-+ raid1_hw_raidable(mddev);
- }
-
- static void print_conf(conf_t *conf)
-@@ -1027,6 +1178,9 @@
- }
- }
-
-+ /* check to see if this new configuration is supported by hardware RAID */
-+ raid1_hw_raidable(mddev);
-+
- print_conf(conf);
- return 0;
- }
-@@ -1064,6 +1218,9 @@
- break;
- }
-
-+ /* check to see if this new configuration is supported by hardware RAID */
-+ raid1_hw_raidable(mddev);
-+
- print_conf(conf);
- return found;
- }
-@@ -1092,6 +1249,8 @@
- }
- }
- abort:
-+ /* check to see if this new configuration is supported by hardware RAID */
-+ raid1_hw_raidable(mddev);
-
- print_conf(conf);
- return err;
-@@ -1719,6 +1878,7 @@
- bio->bi_size = 0;
- bio->bi_end_io = NULL;
- bio->bi_private = NULL;
-+ bio->bi_raid = 0;
-
- rdev = rcu_dereference(conf->mirrors[i].rdev);
- if (rdev == NULL ||
-@@ -1966,6 +2126,9 @@
- */
- mddev->array_size = mddev->size;
-
-+ /* check to see if this new configuration is supported by hardware RAID */
-+ raid1_hw_raidable(mddev);
-+
- mddev->queue->unplug_fn = raid1_unplug;
- mddev->queue->backing_dev_info.congested_fn = raid1_congested;
- mddev->queue->backing_dev_info.congested_data = mddev;
-@@ -2035,6 +2198,9 @@
- }
- mddev->size = mddev->array_size;
- mddev->resync_max_sectors = sectors;
-+ /* check to see if this new configuration is supported by hardware RAID */
-+ raid1_hw_raidable(mddev);
-+
- return 0;
- }
-
-@@ -2138,6 +2304,9 @@
- mddev->delta_disks = 0;
-
- conf->last_used = 0; /* just make sure it is in-range */
-+ /* check to see if this new configuration is supported by hardware RAID */
-+ raid1_hw_raidable(mddev);
-+
- lower_barrier(conf);
-
- set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
-diff -Nurd linux-2.6.24/drivers/media/video/cx23885/cx23885-cards.c linux-2.6.24-oxe810/drivers/media/video/cx23885/cx23885-cards.c
---- linux-2.6.24/drivers/media/video/cx23885/cx23885-cards.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/media/video/cx23885/cx23885-cards.c 2008-06-11 17:48:59.000000000 +0200
-@@ -138,6 +138,10 @@
- .card = CX23885_BOARD_HAUPPAUGE_HVR1800,
- },{
- .subvendor = 0x0070,
-+ .subdevice = 0x7809,
-+ .card = CX23885_BOARD_HAUPPAUGE_HVR1800,
-+ },{
-+ .subvendor = 0x0070,
- .subdevice = 0x7911,
- .card = CX23885_BOARD_HAUPPAUGE_HVR1250,
- },{
-diff -Nurd linux-2.6.24/drivers/message/fusion/mptsas.c linux-2.6.24-oxe810/drivers/message/fusion/mptsas.c
---- linux-2.6.24/drivers/message/fusion/mptsas.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/message/fusion/mptsas.c 2008-06-11 17:49:11.000000000 +0200
-@@ -1699,6 +1699,11 @@
- if (error)
- goto out_free_consistent;
-
-+ if (!buffer->NumPhys) {
-+ error = -ENODEV;
-+ goto out_free_consistent;
-+ }
-+
- /* save config data */
- port_info->num_phys = buffer->NumPhys;
- port_info->phy_info = kcalloc(port_info->num_phys,
-diff -Nurd linux-2.6.24/drivers/net/Kconfig linux-2.6.24-oxe810/drivers/net/Kconfig
---- linux-2.6.24/drivers/net/Kconfig 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/Kconfig 2008-06-11 17:50:11.000000000 +0200
-@@ -2368,6 +2368,14 @@
- To compile this driver as a module, choose M here. The module
- will be called atl1.
-
-+config SYNOPSYS_GMAC
-+ tristate "Synopsys Gigabit MAC"
-+ select CRC32
-+ select MII
-+ depends on ARCH_OXNAS
-+ help
-+ Driver for the Synopsys Gigabit MAC
-+
- endif # NETDEV_1000
-
- #
-diff -Nurd linux-2.6.24/drivers/net/bonding/bond_main.c linux-2.6.24-oxe810/drivers/net/bonding/bond_main.c
---- linux-2.6.24/drivers/net/bonding/bond_main.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/bonding/bond_main.c 2008-06-11 17:50:00.000000000 +0200
-@@ -4883,14 +4883,16 @@
- down_write(&bonding_rwsem);
-
- /* Check to see if the bond already exists. */
-- list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
-- if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) {
-- printk(KERN_ERR DRV_NAME
-+ if (name) {
-+ list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
-+ if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) {
-+ printk(KERN_ERR DRV_NAME
- ": cannot add bond %s; it already exists\n",
-- name);
-- res = -EPERM;
-- goto out_rtnl;
-- }
-+ name);
-+ res = -EPERM;
-+ goto out_rtnl;
-+ }
-+ }
-
- bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "",
- ether_setup);
-diff -Nurd linux-2.6.24/drivers/net/dl2k.h linux-2.6.24-oxe810/drivers/net/dl2k.h
---- linux-2.6.24/drivers/net/dl2k.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/dl2k.h 2008-06-11 17:50:11.000000000 +0200
-@@ -388,8 +388,8 @@
- MII_MSSR_CFG_RES = 0x4000,
- MII_MSSR_LOCAL_RCV_STATUS = 0x2000,
- MII_MSSR_REMOTE_RCVR = 0x1000,
-- MII_MSSR_LP_1000BT_HD = 0x0800,
-- MII_MSSR_LP_1000BT_FD = 0x0400,
-+ MII_MSSR_LP_1000BT_FD = 0x0800,
-+ MII_MSSR_LP_1000BT_HD = 0x0400,
- MII_MSSR_IDLE_ERR_COUNT = 0x00ff,
- };
-
-diff -Nurd linux-2.6.24/drivers/net/e1000e/netdev.c linux-2.6.24-oxe810/drivers/net/e1000e/netdev.c
---- linux-2.6.24/drivers/net/e1000e/netdev.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/e1000e/netdev.c 2008-06-11 17:50:07.000000000 +0200
-@@ -1686,6 +1686,9 @@
- else
- rctl |= E1000_RCTL_LPE;
-
-+ /* Enable hardware CRC frame stripping */
-+ rctl |= E1000_RCTL_SECRC;
-+
- /* Setup buffer sizes */
- rctl &= ~E1000_RCTL_SZ_4096;
- rctl |= E1000_RCTL_BSEX;
-@@ -1751,9 +1754,6 @@
-
- /* Enable Packet split descriptors */
- rctl |= E1000_RCTL_DTYP_PS;
--
-- /* Enable hardware CRC frame stripping */
-- rctl |= E1000_RCTL_SECRC;
-
- psrctl |= adapter->rx_ps_bsize0 >>
- E1000_PSRCTL_BSIZE0_SHIFT;
-diff -Nurd linux-2.6.24/drivers/net/forcedeth.c linux-2.6.24-oxe810/drivers/net/forcedeth.c
---- linux-2.6.24/drivers/net/forcedeth.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/forcedeth.c 2008-06-11 17:50:11.000000000 +0200
-@@ -5593,35 +5593,35 @@
- },
- { /* MCP77 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32),
-- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
-+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
- },
- { /* MCP77 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33),
-- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
-+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
- },
- { /* MCP77 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34),
-- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
-+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
- },
- { /* MCP77 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35),
-- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
-+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
- },
- { /* MCP79 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36),
-- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
-+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
- },
- { /* MCP79 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37),
-- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
-+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
- },
- { /* MCP79 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38),
-- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
-+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
- },
- { /* MCP79 Ethernet Controller */
- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39),
-- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
-+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
- },
- {0,},
- };
-diff -Nurd linux-2.6.24/drivers/net/macb.c linux-2.6.24-oxe810/drivers/net/macb.c
---- linux-2.6.24/drivers/net/macb.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/macb.c 2008-06-11 17:50:11.000000000 +0200
-@@ -148,7 +148,7 @@
-
- if (phydev->duplex)
- reg |= MACB_BIT(FD);
-- if (phydev->speed)
-+ if (phydev->speed == SPEED_100)
- reg |= MACB_BIT(SPD);
-
- macb_writel(bp, NCFGR, reg);
-diff -Nurd linux-2.6.24/drivers/net/mii.c linux-2.6.24-oxe810/drivers/net/mii.c
---- linux-2.6.24/drivers/net/mii.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/mii.c 2008-06-11 17:50:11.000000000 +0200
-@@ -46,11 +46,13 @@
- u32 advert, bmcr, lpa, nego;
- u32 advert2 = 0, bmcr2 = 0, lpa2 = 0;
-
-+ int supports_gmii = mii->mdio_read(dev, mii->phy_id, MII_BMSR) & BMSR_ESTATEN;
-+
- ecmd->supported =
- (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
- SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII);
-- if (mii->supports_gmii)
-+ if (supports_gmii)
- ecmd->supported |= SUPPORTED_1000baseT_Half |
- SUPPORTED_1000baseT_Full;
-
-@@ -65,7 +67,7 @@
-
- ecmd->advertising = ADVERTISED_TP | ADVERTISED_MII;
- advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE);
-- if (mii->supports_gmii)
-+ if (supports_gmii)
- advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
-
- if (advert & ADVERTISE_10HALF)
-@@ -83,7 +85,7 @@
-
- bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
- lpa = mii->mdio_read(dev, mii->phy_id, MII_LPA);
-- if (mii->supports_gmii) {
-+ if (supports_gmii) {
- bmcr2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
- lpa2 = mii->mdio_read(dev, mii->phy_id, MII_STAT1000);
- }
-@@ -132,6 +134,8 @@
- {
- struct net_device *dev = mii->dev;
-
-+ int supports_gmii = mii->mdio_read(dev, mii->phy_id, MII_BMSR) & BMSR_ESTATEN;
-+
- if (ecmd->speed != SPEED_10 &&
- ecmd->speed != SPEED_100 &&
- ecmd->speed != SPEED_1000)
-@@ -146,7 +150,7 @@
- return -EINVAL;
- if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE)
- return -EINVAL;
-- if ((ecmd->speed == SPEED_1000) && (!mii->supports_gmii))
-+ if ((ecmd->speed == SPEED_1000) && (!supports_gmii))
- return -EINVAL;
-
- /* ignore supported, maxtxpkt, maxrxpkt */
-@@ -166,7 +170,7 @@
- /* advertise only what has been requested */
- advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE);
- tmp = advert & ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
-- if (mii->supports_gmii) {
-+ if (supports_gmii) {
- advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
- tmp2 = advert2 & ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
- }
-@@ -178,7 +182,7 @@
- tmp |= ADVERTISE_100HALF;
- if (ecmd->advertising & ADVERTISED_100baseT_Full)
- tmp |= ADVERTISE_100FULL;
-- if (mii->supports_gmii) {
-+ if (supports_gmii) {
- if (ecmd->advertising & ADVERTISED_1000baseT_Half)
- tmp2 |= ADVERTISE_1000HALF;
- if (ecmd->advertising & ADVERTISED_1000baseT_Full)
-@@ -188,7 +192,7 @@
- mii->mdio_write(dev, mii->phy_id, MII_ADVERTISE, tmp);
- mii->advertising = tmp;
- }
-- if ((mii->supports_gmii) && (advert2 != tmp2))
-+ if (advert2 != tmp2)
- mii->mdio_write(dev, mii->phy_id, MII_CTRL1000, tmp2);
-
- /* turn on autonegotiation, and force a renegotiate */
-@@ -312,6 +316,7 @@
- unsigned int old_carrier, new_carrier;
- int advertise, lpa, media, duplex;
- int lpa2 = 0;
-+ int supports_gmii = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR) & BMSR_ESTATEN;
-
- /* if forced media, go no further */
- if (mii->force_media)
-@@ -348,7 +353,7 @@
- mii->advertising = advertise;
- }
- lpa = mii->mdio_read(mii->dev, mii->phy_id, MII_LPA);
-- if (mii->supports_gmii)
-+ if (supports_gmii)
- lpa2 = mii->mdio_read(mii->dev, mii->phy_id, MII_STAT1000);
-
- /* figure out media and duplex from advertise and LPA values */
-@@ -373,6 +378,148 @@
- return 0; /* duplex did not change */
- }
-
-+
-+unsigned int mii_check_media_ex(
-+ struct mii_if_info *mii,
-+ unsigned int ok_to_print,
-+ unsigned int init_media,
-+ int *has_gigabit_changed,
-+ int *has_pause_changed,
-+ void (*link_state_change_callback)(int link_state, void* arg),
-+ void *link_state_change_arg)
-+{
-+ unsigned int old_carrier, new_carrier;
-+ int advertise, lpa;
-+ unsigned int negotiated_10_100;
-+ int advertise2 = 0, lpa2 = 0;
-+ unsigned int negotiated_1000;
-+ int duplex = 0;
-+ int using_100 = 0;
-+ int using_1000 = 0;
-+ int using_pause = 0;
-+ int duplex_changed = 0;
-+ int changed_100 = 0;
-+ int changed_1000 = 0;
-+ int changed_pause = 0;
-+ int supports_gmii = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR) & BMSR_ESTATEN;
-+
-+ // Initialise user's locations for returned gigabit and pause changed values
-+ // to no-change
-+ *has_gigabit_changed = 0;
-+ *has_pause_changed = 0;
-+
-+ /* if forced media, go no further */
-+ if (mii->force_media)
-+ return 0; /* duplex did not change */
-+
-+ /* check current and old link status */
-+ old_carrier = netif_carrier_ok(mii->dev) ? 1 : 0;
-+ new_carrier = (unsigned int) mii_link_ok(mii);
-+
-+ /* if carrier state did not change, this is a "bounce",
-+ * just exit as everything is already set correctly
-+ */
-+ if ((!init_media) && (old_carrier == new_carrier))
-+ return 0; /* duplex did not change */
-+
-+ /* no carrier, nothing much to do */
-+ if (!new_carrier) {
-+ netif_carrier_off(mii->dev);
-+ if (ok_to_print) {
-+ printk(KERN_INFO "%s: link down\n", mii->dev->name);
-+ }
-+ link_state_change_callback(0, link_state_change_arg);
-+ return 0; /* duplex did not change */
-+ }
-+
-+ /*
-+ * we have carrier, see who's on the other end
-+ */
-+ netif_carrier_on(mii->dev);
-+
-+ /* Get our advertise values */
-+ if ((!init_media) && (mii->advertising))
-+ advertise = mii->advertising;
-+ else {
-+ advertise = mii->mdio_read(mii->dev, mii->phy_id, MII_ADVERTISE);
-+ mii->advertising = advertise;
-+ }
-+//printk("mii_check_media_ex() MII_ADVERTISE read as 0x%08x\n", advertise);
-+ if (supports_gmii) {
-+ advertise2 = mii->mdio_read(mii->dev, mii->phy_id, MII_CTRL1000);
-+//printk("mii_check_media_ex() MII_CTRL1000 read as 0x%08x\n", advertise2);
-+ }
-+
-+ /* Get link partner advertise values */
-+ lpa = mii->mdio_read(mii->dev, mii->phy_id, MII_LPA);
-+//printk("mii_check_media_ex() MII_LPA read as 0x%08x\n", lpa);
-+ if (supports_gmii) {
-+ lpa2 = mii->mdio_read(mii->dev, mii->phy_id, MII_STAT1000);
-+//printk("mii_check_media_ex() MII_STAT1000 read as 0x%08x\n", lpa2);
-+ }
-+
-+//printk("Us pause = %d, async pause = %d\n", advertise & ADVERTISE_PAUSE_CAP, advertise & ADVERTISE_PAUSE_ASYM);
-+//printk("Link partner pause = %d, async pause = %d\n", lpa & LPA_PAUSE_CAP, lpa & LPA_PAUSE_ASYM);
-+
-+ /* Determine negotiated mode/duplex from our and link partner's advertise values */
-+ negotiated_10_100 = mii_nway_result(lpa & advertise);
-+ negotiated_1000 = mii_nway_result_1000(lpa2, advertise2);
-+
-+ /* Determine the rate we're operating at */
-+ if (negotiated_1000 & (LPA_1000FULL | LPA_1000HALF)) {
-+ using_1000 = 1;
-+ duplex = (negotiated_1000 & LPA_1000FULL) ? 1 : 0;
-+ } else {
-+ if (negotiated_10_100 & (LPA_100FULL | LPA_100HALF)) {
-+ using_100 = 1;
-+ }
-+ duplex = (negotiated_10_100 & ADVERTISE_FULL) ? 1 : 0;
-+ }
-+
-+ /* Does link partner advertise that we can send pause frames to it? */
-+ using_pause = (lpa & LPA_PAUSE_CAP) ? 1 : 0;
-+
-+ if (ok_to_print)
-+ printk(KERN_INFO "%s: link up, %sMbps, %s-duplex, %s pause, lpa 0x%04X\n",
-+ mii->dev->name,
-+ using_1000 ? "1000" :
-+ using_100 ? "100" : "10",
-+ duplex ? "full" : "half",
-+ using_pause ? "using" : "not using",
-+ lpa);
-+
-+ link_state_change_callback(1, link_state_change_arg);
-+
-+ if (mii->full_duplex != duplex) {
-+ duplex_changed = 1;
-+ }
-+ if (mii->using_100 != using_100) {
-+ changed_100 = 1;
-+ }
-+ if (mii->using_1000 != using_1000) {
-+ changed_1000 = 1;
-+ }
-+ if (mii->using_pause != using_pause) {
-+ changed_pause = 1;
-+ }
-+
-+ if (init_media || changed_100 || changed_1000 || changed_pause || duplex_changed) {
-+ mii->full_duplex = duplex;
-+ mii->using_100 = using_100;
-+ mii->using_1000 = using_1000;
-+ mii->using_pause = using_pause;
-+ if (init_media || changed_1000) {
-+ *has_gigabit_changed = 1;
-+ }
-+ if (init_media || changed_pause) {
-+ *has_pause_changed = 1;
-+ }
-+ return init_media || duplex_changed;
-+ }
-+
-+ return 0; /* duplex did not change */
-+}
-+
- /**
- * generic_mii_ioctl - main MII ioctl interface
- * @mii_if: the MII interface
-@@ -465,6 +612,7 @@
- EXPORT_SYMBOL(mii_ethtool_sset);
- EXPORT_SYMBOL(mii_check_link);
- EXPORT_SYMBOL(mii_check_media);
-+EXPORT_SYMBOL(mii_check_media_ex);
- EXPORT_SYMBOL(mii_check_gmii_support);
- EXPORT_SYMBOL(generic_mii_ioctl);
-
-diff -Nurd linux-2.6.24/drivers/net/niu.c linux-2.6.24-oxe810/drivers/net/niu.c
---- linux-2.6.24/drivers/net/niu.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/niu.c 2008-06-11 17:50:11.000000000 +0200
-@@ -33,8 +33,8 @@
-
- #define DRV_MODULE_NAME "niu"
- #define PFX DRV_MODULE_NAME ": "
--#define DRV_MODULE_VERSION "0.6"
--#define DRV_MODULE_RELDATE "January 5, 2008"
-+#define DRV_MODULE_VERSION "0.7"
-+#define DRV_MODULE_RELDATE "February 18, 2008"
-
- static char version[] __devinitdata =
- DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
-@@ -1616,12 +1616,13 @@
- if (index >= niu_num_alt_addr(np))
- return -EINVAL;
-
-- if (np->flags & NIU_FLAGS_XMAC)
-+ if (np->flags & NIU_FLAGS_XMAC) {
- reg = XMAC_ADDR_CMPEN;
-- else
-+ mask = 1 << index;
-+ } else {
- reg = BMAC_ADDR_CMPEN;
--
-- mask = 1 << index;
-+ mask = 1 << (index + 1);
-+ }
-
- val = nr64_mac(reg);
- if (on)
-@@ -5147,7 +5148,12 @@
- index++;
- }
- } else {
-- for (i = 0; i < niu_num_alt_addr(np); i++) {
-+ int alt_start;
-+ if (np->flags & NIU_FLAGS_XMAC)
-+ alt_start = 0;
-+ else
-+ alt_start = 1;
-+ for (i = alt_start; i < niu_num_alt_addr(np); i++) {
- err = niu_enable_alt_mac(np, i, 0);
- if (err)
- printk(KERN_WARNING PFX "%s: Error %d "
-diff -Nurd linux-2.6.24/drivers/net/niu.h linux-2.6.24-oxe810/drivers/net/niu.h
---- linux-2.6.24/drivers/net/niu.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/niu.h 2008-06-11 17:50:11.000000000 +0200
-@@ -499,7 +499,7 @@
- #define BMAC_ADDR2 0x00110UL
- #define BMAC_ADDR2_ADDR2 0x000000000000ffffULL
-
--#define BMAC_NUM_ALT_ADDR 7
-+#define BMAC_NUM_ALT_ADDR 6
-
- #define BMAC_ALT_ADDR0(NUM) (0x00118UL + (NUM)*0x18UL)
- #define BMAC_ALT_ADDR0_ADDR0 0x000000000000ffffULL
-diff -Nurd linux-2.6.24/drivers/net/pcmcia/smc91c92_cs.c linux-2.6.24-oxe810/drivers/net/pcmcia/smc91c92_cs.c
---- linux-2.6.24/drivers/net/pcmcia/smc91c92_cs.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/pcmcia/smc91c92_cs.c 2008-06-11 17:50:04.000000000 +0200
-@@ -559,8 +559,16 @@
-
- /* Read the station address from the CIS. It is stored as the last
- (fourth) string in the Version 1 Version/ID tuple. */
-- if (link->prod_id[3]) {
-- station_addr = link->prod_id[3];
-+ tuple->DesiredTuple = CISTPL_VERS_1;
-+ if (first_tuple(link, tuple, parse) != CS_SUCCESS) {
-+ rc = -1;
-+ goto free_cfg_mem;
-+ }
-+ /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
-+ if (next_tuple(link, tuple, parse) != CS_SUCCESS)
-+ first_tuple(link, tuple, parse);
-+ if (parse->version_1.ns > 3) {
-+ station_addr = parse->version_1.str + parse->version_1.ofs[3];
- if (cvt_ascii_address(dev, station_addr) == 0) {
- rc = 0;
- goto free_cfg_mem;
-diff -Nurd linux-2.6.24/drivers/net/sky2.c linux-2.6.24-oxe810/drivers/net/sky2.c
---- linux-2.6.24/drivers/net/sky2.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/sky2.c 2008-06-11 17:50:11.000000000 +0200
-@@ -621,6 +621,7 @@
- static const u32 phy_power[] = { PCI_Y2_PHY1_POWD, PCI_Y2_PHY2_POWD };
- static const u32 coma_mode[] = { PCI_Y2_PHY1_COMA, PCI_Y2_PHY2_COMA };
-
-+ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
- reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
- /* Turn on/off phy power saving */
- if (onoff)
-@@ -632,7 +633,8 @@
- reg1 |= coma_mode[port];
-
- sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
-- reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
-+ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-+ sky2_pci_read32(hw, PCI_DEV_REG1);
-
- udelay(100);
- }
-@@ -1412,6 +1414,7 @@
- imask |= portirq_msk[port];
- sky2_write32(hw, B0_IMSK, imask);
-
-+ sky2_set_multicast(dev);
- return 0;
-
- err_out:
-@@ -2426,6 +2429,7 @@
- if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) {
- u16 pci_err;
-
-+ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
- pci_err = sky2_pci_read16(hw, PCI_STATUS);
- if (net_ratelimit())
- dev_err(&pdev->dev, "PCI hardware error (0x%x)\n",
-@@ -2433,12 +2437,14 @@
-
- sky2_pci_write16(hw, PCI_STATUS,
- pci_err | PCI_STATUS_ERROR_BITS);
-+ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
- }
-
- if (status & Y2_IS_PCI_EXP) {
- /* PCI-Express uncorrectable Error occurred */
- u32 err;
-
-+ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
- err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
- sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
- 0xfffffffful);
-@@ -2446,6 +2452,7 @@
- dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err);
-
- sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
-+ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
- }
-
- if (status & Y2_HWE_L1_MASK)
-@@ -2811,6 +2818,7 @@
- }
-
- sky2_power_on(hw);
-+ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-
- for (i = 0; i < hw->ports; i++) {
- sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
-@@ -3533,8 +3541,6 @@
- err = sky2_up(dev);
- if (err)
- dev_close(dev);
-- else
-- sky2_set_multicast(dev);
- }
-
- return err;
-@@ -4368,8 +4374,6 @@
- dev_close(dev);
- goto out;
- }
--
-- sky2_set_multicast(dev);
- }
- }
-
-diff -Nurd linux-2.6.24/drivers/net/via-velocity.c linux-2.6.24-oxe810/drivers/net/via-velocity.c
---- linux-2.6.24/drivers/net/via-velocity.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/via-velocity.c 2008-06-11 17:50:11.000000000 +0200
-@@ -72,7 +72,6 @@
- #include <linux/mii.h>
- #include <linux/in.h>
- #include <linux/if_arp.h>
--#include <linux/if_vlan.h>
- #include <linux/ip.h>
- #include <linux/tcp.h>
- #include <linux/udp.h>
-@@ -81,170 +80,50 @@
-
- #include "via-velocity.h"
-
-+// Default MAC address
-+static const u8 DEFAULT_MAC_ADDRESS[] = { 0x00, 0x30, 0xe0, 0x00, 0x00, 0xff };
-+static u32 mac_hi=0;
-+static u32 mac_lo=0;
-
--static int velocity_nics = 0;
--static int msglevel = MSG_LEVEL_INFO;
--
--/**
-- * mac_get_cam_mask - Read a CAM mask
-- * @regs: register block for this velocity
-- * @mask: buffer to store mask
-- *
-- * Fetch the mask bits of the selected CAM and store them into the
-- * provided mask buffer.
-- */
--
--static void mac_get_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
--{
-- int i;
--
-- /* Select CAM mask */
-- BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
--
-- writeb(0, ®s->CAMADDR);
--
-- /* read mask */
-- for (i = 0; i < 8; i++)
-- *mask++ = readb(&(regs->MARCAM[i]));
--
-- /* disable CAMEN */
-- writeb(0, ®s->CAMADDR);
--
-- /* Select mar */
-- BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
--
--}
--
--
--/**
-- * mac_set_cam_mask - Set a CAM mask
-- * @regs: register block for this velocity
-- * @mask: CAM mask to load
-- *
-- * Store a new mask into a CAM
-- */
--
--static void mac_set_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
--{
-- int i;
-- /* Select CAM mask */
-- BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
--
-- writeb(CAMADDR_CAMEN, ®s->CAMADDR);
--
-- for (i = 0; i < 8; i++) {
-- writeb(*mask++, &(regs->MARCAM[i]));
-- }
-- /* disable CAMEN */
-- writeb(0, ®s->CAMADDR);
--
-- /* Select mar */
-- BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
--}
--
--static void mac_set_vlan_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
--{
-- int i;
-- /* Select CAM mask */
-- BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
--
-- writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL, ®s->CAMADDR);
--
-- for (i = 0; i < 8; i++) {
-- writeb(*mask++, &(regs->MARCAM[i]));
-- }
-- /* disable CAMEN */
-- writeb(0, ®s->CAMADDR);
--
-- /* Select mar */
-- BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
--}
--
--/**
-- * mac_set_cam - set CAM data
-- * @regs: register block of this velocity
-- * @idx: Cam index
-- * @addr: 2 or 6 bytes of CAM data
-- *
-- * Load an address or vlan tag into a CAM
-- */
--
--static void mac_set_cam(struct mac_regs __iomem * regs, int idx, const u8 *addr)
--{
-- int i;
--
-- /* Select CAM mask */
-- BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
--
-- idx &= (64 - 1);
--
-- writeb(CAMADDR_CAMEN | idx, ®s->CAMADDR);
--
-- for (i = 0; i < 6; i++) {
-- writeb(*addr++, &(regs->MARCAM[i]));
-- }
-- BYTE_REG_BITS_ON(CAMCR_CAMWR, ®s->CAMCR);
--
-- udelay(10);
-+#define EXTRA_RX_SKB_SPACE 32
-+#define MAX_HW_FRAGMENTS 6
-+//#define VELOCITY_ZERO_COPY_SUPPORT
-+//#define LOAD_FROM_EEPROM
-
-- writeb(0, ®s->CAMADDR);
-+#define VELOCITY_DESC_IN_SRAM
-
-- /* Select mar */
-- BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
--}
-+#ifdef VELOCITY_DESC_IN_SRAM
-+#include <asm/arch/desc_alloc.h>
-+#endif // VELOCITY_DESC_IN_SRAM
-
--static void mac_set_vlan_cam(struct mac_regs __iomem * regs, int idx,
-- const u8 *addr)
-+/* Parse netdev kernel cmdline options */
-+static int __init do_setup(char *str)
- {
-+ int i;
-+ int ints[5]; // Hold arg count and four args
-
-- /* Select CAM mask */
-- BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
--
-- idx &= (64 - 1);
--
-- writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, ®s->CAMADDR);
-- writew(*((u16 *) addr), ®s->MARCAM[0]);
--
-- BYTE_REG_BITS_ON(CAMCR_CAMWR, ®s->CAMCR);
--
-- udelay(10);
--
-- writeb(0, ®s->CAMADDR);
--
-- /* Select mar */
-- BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
-+ get_options(str, sizeof(ints)/sizeof(int), ints);
-+ for (i=1; i<=ints[0]; i++) {
-+ switch (i) {
-+ case 3:
-+ mac_hi = ints[i];
-+ break;
-+ case 4:
-+ mac_lo = ints[i];
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ return 0;
- }
-+__setup("netdev=",do_setup);
-
--
--/**
-- * mac_wol_reset - reset WOL after exiting low power
-- * @regs: register block of this velocity
-- *
-- * Called after we drop out of wake on lan mode in order to
-- * reset the Wake on lan features. This function doesn't restore
-- * the rest of the logic from the result of sleep/wakeup
-- */
--
--static void mac_wol_reset(struct mac_regs __iomem * regs)
--{
--
-- /* Turn off SWPTAG right after leaving power mode */
-- BYTE_REG_BITS_OFF(STICKHW_SWPTAG, ®s->STICKHW);
-- /* clear sticky bits */
-- BYTE_REG_BITS_OFF((STICKHW_DS1 | STICKHW_DS0), ®s->STICKHW);
--
-- BYTE_REG_BITS_OFF(CHIPGCR_FCGMII, ®s->CHIPGCR);
-- BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, ®s->CHIPGCR);
-- /* disable force PME-enable */
-- writeb(WOLCFG_PMEOVR, ®s->WOLCFGClr);
-- /* disable power-event config bit */
-- writew(0xFFFF, ®s->WOLCRClr);
-- /* clear power status */
-- writew(0xFFFF, ®s->WOLSRClr);
--}
-+static int velocity_nics = 0;
-+static int msglevel = MSG_LEVEL_INFO;
-
- static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
--static const struct ethtool_ops velocity_ethtool_ops;
-+static struct ethtool_ops velocity_ethtool_ops;
-
- /*
- Define module options
-@@ -269,6 +148,15 @@
- #define TX_DESC_DEF 64
- VELOCITY_PARAM(TxDescriptors, "Number of transmit descriptors");
-
-+#define VLAN_ID_MIN 0
-+#define VLAN_ID_MAX 4095
-+#define VLAN_ID_DEF 0
-+/* VID_setting[] is used for setting the VID of NIC.
-+ 0: default VID.
-+ 1-4094: other VIDs.
-+*/
-+VELOCITY_PARAM(VID_setting, "802.1Q VLAN ID");
-+
- #define RX_THRESH_MIN 0
- #define RX_THRESH_MAX 3
- #define RX_THRESH_DEF 0
-@@ -282,7 +170,8 @@
-
- #define DMA_LENGTH_MIN 0
- #define DMA_LENGTH_MAX 7
--#define DMA_LENGTH_DEF 0
-+#define DMA_LENGTH_100M_DEF 6
-+#define DMA_LENGTH_1000M_DEF 6
-
- /* DMA_length[] is used for controlling the DMA length
- 0: 8 DWORDs
-@@ -294,7 +183,15 @@
- 6: SF(flush till emply)
- 7: SF(flush till emply)
- */
--VELOCITY_PARAM(DMA_length, "DMA length");
-+VELOCITY_PARAM(DMA_length_100M, "DMA length 100M");
-+VELOCITY_PARAM(DMA_length_1000M, "DMA length 1000M");
-+
-+#define TAGGING_DEF 0
-+/* enable_tagging[] is used for enabling 802.1Q VID tagging.
-+ 0: disable VID seeting(default).
-+ 1: enable VID setting.
-+*/
-+VELOCITY_PARAM(enable_tagging, "Enable 802.1Q tagging");
-
- #define IP_ALIG_DEF 0
- /* IP_byte_align[] is used for IP header DWORD byte aligned
-@@ -378,7 +275,7 @@
- static int velocity_open(struct net_device *dev);
- static int velocity_change_mtu(struct net_device *dev, int mtu);
- static int velocity_xmit(struct sk_buff *skb, struct net_device *dev);
--static int velocity_intr(int irq, void *dev_instance);
-+static int velocity_intr(int irq, void *dev_instance, struct pt_regs *regs);
- static void velocity_set_multi(struct net_device *dev);
- static struct net_device_stats *velocity_get_stats(struct net_device *dev);
- static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-@@ -401,25 +298,23 @@
- static u32 mii_check_media_mode(struct mac_regs __iomem * regs);
- static u32 check_connection_type(struct mac_regs __iomem * regs);
- static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status);
-+static void hw_set_mac_address(struct velocity_info *vptr, unsigned char* addr);
-+static int set_mac_address(struct net_device *dev, void *p);
-
- #ifdef CONFIG_PM
-
- static int velocity_suspend(struct pci_dev *pdev, pm_message_t state);
- static int velocity_resume(struct pci_dev *pdev);
-
--static DEFINE_SPINLOCK(velocity_dev_list_lock);
--static LIST_HEAD(velocity_dev_list);
--
--#endif
--
--#if defined(CONFIG_PM) && defined(CONFIG_INET)
--
- static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr);
-
- static struct notifier_block velocity_inetaddr_notifier = {
- .notifier_call = velocity_netdev_event,
- };
-
-+static DEFINE_SPINLOCK(velocity_dev_list_lock);
-+static LIST_HEAD(velocity_dev_list);
-+
- static void velocity_register_notifier(void)
- {
- register_inetaddr_notifier(&velocity_inetaddr_notifier);
-@@ -430,12 +325,12 @@
- unregister_inetaddr_notifier(&velocity_inetaddr_notifier);
- }
-
--#else
-+#else /* CONFIG_PM */
-
- #define velocity_register_notifier() do {} while (0)
- #define velocity_unregister_notifier() do {} while (0)
-
--#endif
-+#endif /* !CONFIG_PM */
-
- /*
- * Internal board variants. At the moment we have only one
-@@ -466,7 +361,7 @@
- * a pointer a static string valid while the driver is loaded.
- */
-
--static const char __devinit *get_chip_name(enum chip_type chip_id)
-+static char __devinit *get_chip_name(enum chip_type chip_id)
- {
- int i;
- for (i = 0; chip_info_table[i].name != NULL; i++)
-@@ -557,11 +452,11 @@
- if (val == -1)
- *opt |= (def ? flag : 0);
- else if (val < 0 || val > 1) {
-- printk(KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (0-1)\n",
-+ printk(KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (0-1)\n",
- devname, name);
- *opt |= (def ? flag : 0);
- } else {
-- printk(KERN_INFO "%s: set parameter %s to %s\n",
-+ printk(KERN_INFO "%s: set parameter %s to %s\n",
- devname, name, val ? "TRUE" : "FALSE");
- *opt |= (val ? flag : 0);
- }
-@@ -581,10 +476,12 @@
- {
-
- velocity_set_int_opt(&opts->rx_thresh, rx_thresh[index], RX_THRESH_MIN, RX_THRESH_MAX, RX_THRESH_DEF, "rx_thresh", devname);
-- velocity_set_int_opt(&opts->DMA_length, DMA_length[index], DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_DEF, "DMA_length", devname);
-+ velocity_set_int_opt(&opts->DMA_length_100M, DMA_length_100M[index], DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_100M_DEF, "DMA_length 100M", devname);
-+ velocity_set_int_opt(&opts->DMA_length_1000M, DMA_length_1000M[index], DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_1000M_DEF, "DMA_length 1000M", devname);
- velocity_set_int_opt(&opts->numrx, RxDescriptors[index], RX_DESC_MIN, RX_DESC_MAX, RX_DESC_DEF, "RxDescriptors", devname);
- velocity_set_int_opt(&opts->numtx, TxDescriptors[index], TX_DESC_MIN, TX_DESC_MAX, TX_DESC_DEF, "TxDescriptors", devname);
--
-+ velocity_set_int_opt(&opts->vid, VID_setting[index], VLAN_ID_MIN, VLAN_ID_MAX, VLAN_ID_DEF, "VID_setting", devname);
-+ velocity_set_bool_opt(&opts->flags, enable_tagging[index], TAGGING_DEF, VELOCITY_FLAGS_TAGGING, "enable_tagging", devname);
- velocity_set_bool_opt(&opts->flags, txcsum_offload[index], TX_CSUM_DEF, VELOCITY_FLAGS_TX_CSUM, "txcsum_offload", devname);
- velocity_set_int_opt(&opts->flow_cntl, flow_control[index], FLOW_CNTL_MIN, FLOW_CNTL_MAX, FLOW_CNTL_DEF, "flow_control", devname);
- velocity_set_bool_opt(&opts->flags, IP_byte_align[index], IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN, "IP_byte_align", devname);
-@@ -606,61 +503,35 @@
- static void velocity_init_cam_filter(struct velocity_info *vptr)
- {
- struct mac_regs __iomem * regs = vptr->mac_regs;
-- unsigned short vid;
-
- /* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */
- WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, ®s->MCFG);
- WORD_REG_BITS_ON(MCFG_VIDFR, ®s->MCFG);
-
- /* Disable all CAMs */
-- memset(vptr->vCAMmask, 0, sizeof(u8) * 8);
-- memset(vptr->mCAMmask, 0, sizeof(u8) * 8);
-- mac_set_vlan_cam_mask(regs, vptr->vCAMmask);
-- mac_set_cam_mask(regs, vptr->mCAMmask);
-+ memset(vptr->vCAMmask, 0, VCAM_SIZE / 8);
-+ memset(vptr->mCAMmask, 0, MCAM_SIZE / 8);
-+ mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM);
-+ mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM);
-
- /* Enable first VCAM */
-- if (vptr->vlgrp) {
-- for (vid = 0; vid < VLAN_VID_MASK; vid++) {
-- if (vlan_group_get_device(vptr->vlgrp, vid)) {
-- /* If Tagging option is enabled and
-- VLAN ID is not zero, then
-- turn on MCFG_RTGOPT also */
-- if (vid != 0)
-- WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG);
-+ if (vptr->flags & VELOCITY_FLAGS_TAGGING) {
-+ /* If Tagging option is enabled and VLAN ID is not zero, then
-+ turn on MCFG_RTGOPT also */
-+ if (vptr->options.vid != 0)
-+ WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG);
-
-- mac_set_vlan_cam(regs, 0, (u8 *) &vid);
-- }
-- }
-+ mac_set_cam(regs, 0, (u8 *) & (vptr->options.vid), VELOCITY_VLAN_ID_CAM);
- vptr->vCAMmask[0] |= 1;
-- mac_set_vlan_cam_mask(regs, vptr->vCAMmask);
-+ mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM);
- } else {
- u16 temp = 0;
-- mac_set_vlan_cam(regs, 0, (u8 *) &temp);
-+ mac_set_cam(regs, 0, (u8 *) &temp, VELOCITY_VLAN_ID_CAM);
- temp = 1;
-- mac_set_vlan_cam_mask(regs, (u8 *) &temp);
-+ mac_set_cam_mask(regs, (u8 *) &temp, VELOCITY_VLAN_ID_CAM);
- }
- }
-
--static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
--{
-- struct velocity_info *vptr = netdev_priv(dev);
--
-- spin_lock_irq(&vptr->lock);
-- velocity_init_cam_filter(vptr);
-- spin_unlock_irq(&vptr->lock);
--}
--
--static void velocity_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
--{
-- struct velocity_info *vptr = netdev_priv(dev);
--
-- spin_lock_irq(&vptr->lock);
-- vlan_group_set_device(vptr->vlgrp, vid, NULL);
-- velocity_init_cam_filter(vptr);
-- spin_unlock_irq(&vptr->lock);
--}
--
--
- /**
- * velocity_rx_reset - handle a receive reset
- * @vptr: velocity we are resetting
-@@ -690,6 +561,61 @@
- }
-
- /**
-+ * Cause the eeprom to be read into the chip.
-+ * @returns Zero on success
-+ */
-+int mac_eeprom_reload(struct mac_regs __iomem *regs)
-+{
-+#if 0
-+{
-+int i;
-+unsigned char __iomem *ptr = (unsigned char __iomem *)regs;
-+printk("Before eeprom load regs:\n");
-+printk("0x00:\t");
-+for (i=0; i <= MAC_REG_BYTEMSK3_3; ++i) {
-+ printk("0x%02x\t", readb(&(ptr[i])));
-+ if (!((i+1) % 8)) {
-+ printk("\n0x%02x:\t", i+1);
-+ }
-+}
-+}
-+#endif
-+ BYTE_REG_BITS_ON(EECSR_RELOAD, &((regs)->EECSR));
-+ mdelay(100);
-+#if 0
-+{
-+int i;
-+unsigned char __iomem *ptr = (unsigned char __iomem *)regs;
-+printk("\nAfter eeprom load regs:\n");
-+printk("0x00:\t");
-+for (i=0; i <= MAC_REG_BYTEMSK3_3; ++i) {
-+ printk("0x%02x\t", readb(&(ptr[i])));
-+ if (!((i+1) % 8)) {
-+ printk("\n0x%02x:\t", i+1);
-+ }
-+}
-+}
-+#endif
-+ return BYTE_REG_BITS_IS_ON(EECSR_RELOAD, &((regs)->EECSR));
-+}
-+
-+
-+static inline void mac_set_dma_length(struct velocity_info *vptr)
-+{
-+ struct mac_regs __iomem *regs = vptr->mac_regs;
-+ int burst_size = vptr->options.DMA_length_100M;
-+
-+ if (!(vptr->mii_status & VELOCITY_LINK_FAIL) &&
-+ (vptr->options.spd_dpx == SPD_DPX_AUTO) &&
-+ (vptr->mii_status & VELOCITY_SPEED_1000)) {
-+ burst_size = vptr->options.DMA_length_1000M;
-+ }
-+
-+//printk("Setting fifo burst size to %d\n", burst_size);
-+ BYTE_REG_BITS_SET(burst_size, 0x07, &(regs->DCFG));
-+}
-+
-+/**
- * velocity_init_registers - initialise MAC registers
- * @vptr: velocity to init
- * @type: type of initialisation (hot or cold)
-@@ -698,7 +624,7 @@
- * hardware.
- */
-
--static void velocity_init_registers(struct velocity_info *vptr,
-+static void velocity_init_registers(struct velocity_info *vptr,
- enum velocity_init_type type)
- {
- struct mac_regs __iomem * regs = vptr->mac_regs;
-@@ -726,11 +652,12 @@
- netif_wake_queue(vptr->dev);
- }
-
-+ mac_set_dma_length(vptr);
- enable_flow_control_ability(vptr);
-
- mac_clear_isr(regs);
- writel(CR0_STOP, ®s->CR0Clr);
-- writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT),
-+ writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT),
- ®s->CR0Set);
-
- break;
-@@ -743,16 +670,27 @@
- velocity_soft_reset(vptr);
- mdelay(5);
-
-+#ifdef LOAD_FROM_EEPROM
- mac_eeprom_reload(regs);
-+#endif // LOAD_FROM_EEPROM
-+
- for (i = 0; i < 6; i++) {
- writeb(vptr->dev->dev_addr[i], &(regs->PAR[i]));
- }
-+
-+ // Initialise the hardware's record of our primary MAC address
-+ hw_set_mac_address(vptr, vptr->dev->dev_addr);
-+
-+ /*
-+ * Set LED Select bits to CASE_1
-+ */
-+ BYTE_REG_BITS_SET(CFGA_PHYLEDS1, (CFGA_PHYLEDS1 | CFGA_PHYLEDS0), &(regs->CFGA));
-+
- /*
- * clear Pre_ACPI bit.
- */
- BYTE_REG_BITS_OFF(CFGA_PACPI, &(regs->CFGA));
- mac_set_rx_thresh(regs, vptr->options.rx_thresh);
-- mac_set_dma_length(regs, vptr->options.DMA_length);
-
- writeb(WOLCFG_SAM | WOLCFG_SAB, ®s->WOLCFGSet);
- /*
-@@ -805,7 +743,9 @@
- netif_wake_queue(vptr->dev);
- }
-
-+ mac_set_dma_length(vptr);
- enable_flow_control_ability(vptr);
-+
- mac_hw_mibs_init(regs);
- mac_write_int_mask(vptr->int_mask, regs);
- mac_clear_isr(regs);
-@@ -866,7 +806,7 @@
- * can support more than MAX_UNITS.
- */
- if (velocity_nics >= MAX_UNITS) {
-- dev_notice(&pdev->dev, "already found %d NICs.\n",
-+ dev_notice(&pdev->dev, "already found %d NICs.\n",
- velocity_nics);
- return -ENODEV;
- }
-@@ -876,15 +816,16 @@
- dev_err(&pdev->dev, "allocate net device failed.\n");
- goto out;
- }
--
-+
- /* Chain it all together */
--
-+
-+ SET_MODULE_OWNER(dev);
- SET_NETDEV_DEV(dev, &pdev->dev);
- vptr = netdev_priv(dev);
-
-
- if (first) {
-- printk(KERN_INFO "%s Ver. %s\n",
-+ printk(KERN_INFO "%s Ver. %s\n",
- VELOCITY_FULL_DRV_NAM, VELOCITY_VERSION);
- printk(KERN_INFO "Copyright (c) 2002, 2003 VIA Networking Technologies, Inc.\n");
- printk(KERN_INFO "Copyright (c) 2004 Red Hat Inc.\n");
-@@ -898,7 +839,7 @@
- dev->irq = pdev->irq;
-
- ret = pci_enable_device(pdev);
-- if (ret < 0)
-+ if (ret < 0)
- goto err_free_dev;
-
- ret = velocity_get_pci_info(vptr, pdev);
-@@ -928,19 +869,32 @@
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = readb(®s->PAR[i]);
-
-+ // Tell the kernel of our MAC address
-+ if ((mac_hi==0)&&(mac_lo==0)) {
-+ memcpy(dev->dev_addr, DEFAULT_MAC_ADDRESS, dev->addr_len);
-+ } else {
-+ int i;
-+ for (i=0; i < dev->addr_len; i++) {
-+ if (i < sizeof(u32)) {
-+ dev->dev_addr[i] = ((mac_hi >> (((sizeof(u32)-1)-i)*8)) & 0xff);
-+ } else {
-+ dev->dev_addr[i] = ((mac_lo >> (((sizeof(u32)+1)-i)*8)) & 0xff);
-+ }
-+ }
-+ }
-
- velocity_get_options(&vptr->options, velocity_nics, dev->name);
-
-- /*
-+ /*
- * Mask out the options cannot be set to the chip
- */
--
-+
- vptr->options.flags &= info->flags;
-
- /*
- * Enable the chip specified capbilities
- */
--
-+
- vptr->flags = vptr->options.flags | (info->flags & 0xFF000000UL);
-
- vptr->wol_opts = vptr->options.wol_opts;
-@@ -957,17 +911,14 @@
- dev->do_ioctl = velocity_ioctl;
- dev->ethtool_ops = &velocity_ethtool_ops;
- dev->change_mtu = velocity_change_mtu;
--
-- dev->vlan_rx_add_vid = velocity_vlan_rx_add_vid;
-- dev->vlan_rx_kill_vid = velocity_vlan_rx_kill_vid;
--
-+ dev->set_mac_address = set_mac_address;
- #ifdef VELOCITY_ZERO_COPY_SUPPORT
- dev->features |= NETIF_F_SG;
- #endif
-- dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER;
-
-- if (vptr->flags & VELOCITY_FLAGS_TX_CSUM)
-+ if (vptr->flags & VELOCITY_FLAGS_TX_CSUM) {
- dev->features |= NETIF_F_IP_CSUM;
-+ }
-
- ret = register_netdev(dev);
- if (ret < 0)
-@@ -978,9 +929,9 @@
-
- velocity_print_info(vptr);
- pci_set_drvdata(pdev, dev);
--
-+
- /* and leave the chip powered down */
--
-+
- pci_set_power_state(pdev, PCI_D3hot);
- #ifdef CONFIG_PM
- {
-@@ -1019,9 +970,9 @@
- struct net_device *dev = vptr->dev;
-
- printk(KERN_INFO "%s: %s\n", dev->name, get_chip_name(vptr->chip_id));
-- printk(KERN_INFO "%s: Ethernet Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
-- dev->name,
-- dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
-+ printk(KERN_INFO "%s: Ethernet Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
-+ dev->name,
-+ dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
- dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
- }
-
-@@ -1044,7 +995,6 @@
- vptr->pdev = pdev;
- vptr->chip_id = info->chip_id;
- vptr->num_txq = info->txqueue;
-- vptr->multicast_limit = MCAM_SIZE;
- spin_lock_init(&vptr->lock);
- INIT_LIST_HEAD(&vptr->list);
- }
-@@ -1061,12 +1011,12 @@
- static int __devinit velocity_get_pci_info(struct velocity_info *vptr, struct pci_dev *pdev)
- {
- vptr->rev_id = pdev->revision;
--
-+
- pci_set_master(pdev);
-
- vptr->ioaddr = pci_resource_start(pdev, 0);
- vptr->memaddr = pci_resource_start(pdev, 1);
--
-+
- if (!(pci_resource_flags(pdev, 0) & IORESOURCE_IO)) {
- dev_err(&pdev->dev,
- "region #0 is not an I/O resource, aborting.\n");
-@@ -1105,20 +1055,25 @@
- u8 *pool;
-
- /*
-- * Allocate all RD/TD rings a single pool
-+ * Allocate all RD/TD rings a single pool
- */
--
-- psize = vptr->options.numrx * sizeof(struct rx_desc) +
-+
-+ psize = vptr->options.numrx * sizeof(struct rx_desc) +
- vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq;
-
- /*
- * pci_alloc_consistent() fulfills the requirement for 64 bytes
- * alignment
- */
-- pool = pci_alloc_consistent(vptr->pdev, psize, &pool_dma);
-+#ifdef VELOCITY_DESC_IN_SRAM
-+ pool = (u8*)GMAC_DESC_ALLOC_START;
-+ pool_dma = GMAC_DESC_ALLOC_START_PA;
-+#else
-+ pool = pci_alloc_consistent(vptr->pdev, psize, &pool_dma);
-+#endif // VELOCITY_DESC_IN_SRAM
-
- if (pool == NULL) {
-- printk(KERN_ERR "%s : DMA memory allocation failed.\n",
-+ printk(KERN_ERR "%s : DMA memory allocation failed.\n",
- vptr->dev->name);
- return -ENOMEM;
- }
-@@ -1130,13 +1085,15 @@
- vptr->rd_pool_dma = pool_dma;
-
- tsize = vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq;
-- vptr->tx_bufs = pci_alloc_consistent(vptr->pdev, tsize,
-+ vptr->tx_bufs = pci_alloc_consistent(vptr->pdev, tsize,
- &vptr->tx_bufs_dma);
-
- if (vptr->tx_bufs == NULL) {
-- printk(KERN_ERR "%s: DMA memory allocation failed.\n",
-+ printk(KERN_ERR "%s: DMA memory allocation failed.\n",
- vptr->dev->name);
-+#ifndef VELOCITY_DESC_IN_SRAM
- pci_free_consistent(vptr->pdev, psize, pool, pool_dma);
-+#endif // !VELOCITY_DESC_IN_SRAM
- return -ENOMEM;
- }
-
-@@ -1167,10 +1124,12 @@
- {
- int size;
-
-- size = vptr->options.numrx * sizeof(struct rx_desc) +
-+ size = vptr->options.numrx * sizeof(struct rx_desc) +
- vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq;
-
-+#ifndef VELOCITY_DESC_IN_SRAM
- pci_free_consistent(vptr->pdev, size, vptr->rd_ring, vptr->rd_pool_dma);
-+#endif // !VELOCITY_DESC_IN_SRAM
-
- size = vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq;
-
-@@ -1219,7 +1178,7 @@
- break;
- }
- done++;
-- dirty = (dirty < vptr->options.numrx - 1) ? dirty + 1 : 0;
-+ dirty = (dirty < vptr->options.numrx - 1) ? dirty + 1 : 0;
- } while (dirty != vptr->rd_curr);
-
- if (done) {
-@@ -1241,15 +1200,14 @@
-
- static int velocity_init_rd_ring(struct velocity_info *vptr)
- {
-- int ret;
-- int mtu = vptr->dev->mtu;
--
-- vptr->rx_buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32;
-+ int ret = -ENOMEM;
-+ unsigned int rsize = sizeof(struct velocity_rd_info) *
-+ vptr->options.numrx;
-
-- vptr->rd_info = kcalloc(vptr->options.numrx,
-- sizeof(struct velocity_rd_info), GFP_KERNEL);
-- if (!vptr->rd_info)
-- return -ENOMEM;
-+ vptr->rd_info = kmalloc(rsize, GFP_KERNEL);
-+ if(vptr->rd_info == NULL)
-+ goto out;
-+ memset(vptr->rd_info, 0, rsize);
-
- vptr->rd_filled = vptr->rd_dirty = vptr->rd_curr = 0;
-
-@@ -1259,7 +1217,7 @@
- "%s: failed to allocate RX buffer.\n", vptr->dev->name);
- velocity_free_rd_ring(vptr);
- }
--
-+out:
- return ret;
- }
-
-@@ -1306,26 +1264,28 @@
- * Returns zero on success or a negative posix errno code for
- * failure.
- */
--
-+
- static int velocity_init_td_ring(struct velocity_info *vptr)
- {
- int i, j;
- dma_addr_t curr;
- struct tx_desc *td;
- struct velocity_td_info *td_info;
-+ unsigned int tsize = sizeof(struct velocity_td_info) *
-+ vptr->options.numtx;
-
- /* Init the TD ring entries */
- for (j = 0; j < vptr->num_txq; j++) {
- curr = vptr->td_pool_dma[j];
-
-- vptr->td_infos[j] = kcalloc(vptr->options.numtx,
-- sizeof(struct velocity_td_info),
-- GFP_KERNEL);
-- if (!vptr->td_infos[j]) {
-+ vptr->td_infos[j] = kmalloc(tsize, GFP_KERNEL);
-+ if(vptr->td_infos[j] == NULL)
-+ {
- while(--j >= 0)
- kfree(vptr->td_infos[j]);
- return -ENOMEM;
- }
-+ memset(vptr->td_infos[j], 0, tsize);
-
- for (i = 0; i < vptr->options.numtx; i++, curr += sizeof(struct tx_desc)) {
- td = &(vptr->td_rings[j][i]);
-@@ -1340,31 +1300,12 @@
- return 0;
- }
-
--/*
-- * FIXME: could we merge this with velocity_free_tx_buf ?
-- */
--
--static void velocity_free_td_ring_entry(struct velocity_info *vptr,
-- int q, int n)
-+static void velocity_free_td_ring_entry(struct velocity_info *vptr, int q, int n)
- {
- struct velocity_td_info * td_info = &(vptr->td_infos[q][n]);
-- int i;
--
-- if (td_info == NULL)
-- return;
-
-- if (td_info->skb) {
-- for (i = 0; i < td_info->nskb_dma; i++)
-- {
-- if (td_info->skb_dma[i]) {
-- pci_unmap_single(vptr->pdev, td_info->skb_dma[i],
-- td_info->skb->len, PCI_DMA_TODEVICE);
-- td_info->skb_dma[i] = (dma_addr_t) NULL;
-- }
-- }
-- dev_kfree_skb(td_info->skb);
-- td_info->skb = NULL;
-- }
-+ if (td_info && td_info->skb)
-+ velocity_free_tx_buf(vptr, td_info);
- }
-
- /**
-@@ -1374,17 +1315,16 @@
- * Free up the transmit ring for this particular velocity adapter.
- * We free the ring contents but not the ring itself.
- */
--
-+
- static void velocity_free_td_ring(struct velocity_info *vptr)
- {
- int i, j;
-
-- for (j = 0; j < vptr->num_txq; j++) {
-+ for (j=0; j < vptr->num_txq; j++) {
- if (vptr->td_infos[j] == NULL)
- continue;
-- for (i = 0; i < vptr->options.numtx; i++) {
-+ for (i=0; i < vptr->options.numtx; i++) {
- velocity_free_td_ring_entry(vptr, j, i);
--
- }
- kfree(vptr->td_infos[j]);
- vptr->td_infos[j] = NULL;
-@@ -1400,14 +1340,14 @@
- * any received packets from the receive queue. Hand the ring
- * slots back to the adapter for reuse.
- */
--
-+
- static int velocity_rx_srv(struct velocity_info *vptr, int status)
- {
- struct net_device_stats *stats = &vptr->stats;
- int rd_curr = vptr->rd_curr;
- int works = 0;
-
-- do {
-+ while (1) {
- struct rx_desc *rd = vptr->rd_ring + rd_curr;
-
- if (!vptr->rd_info[rd_curr].skb)
-@@ -1422,15 +1362,19 @@
- * Don't drop CE or RL error frame although RXOK is off
- */
- if ((rd->rdesc0.RSR & RSR_RXOK) || (!(rd->rdesc0.RSR & RSR_RXOK) && (rd->rdesc0.RSR & (RSR_CE | RSR_RL)))) {
-- if (velocity_receive_frame(vptr, rd_curr) < 0)
-- stats->rx_dropped++;
-+ if (velocity_receive_frame(vptr, rd_curr) < 0) {
-+ /* velocity_receive_frame() has already recorded the type of */
-+ /* so just inc overall rx error count */
-+ ++stats->rx_errors;
-+ }
- } else {
- if (rd->rdesc0.RSR & RSR_CRC)
- stats->rx_crc_errors++;
- if (rd->rdesc0.RSR & RSR_FAE)
- stats->rx_frame_errors++;
-
-- stats->rx_dropped++;
-+ /* We've had an error of some sort so inc. overall rx error count */
-+ ++stats->rx_errors;
- }
-
- rd->inten = 1;
-@@ -1440,7 +1384,9 @@
- rd_curr++;
- if (rd_curr >= vptr->options.numrx)
- rd_curr = 0;
-- } while (++works <= 15);
-+
-+ ++works;
-+ }
-
- vptr->rd_curr = rd_curr;
-
-@@ -1461,14 +1407,14 @@
- * Process the status bits for the received packet and determine
- * if the checksum was computed and verified by the hardware
- */
--
-+
- static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb)
- {
- skb->ip_summed = CHECKSUM_NONE;
-
- if (rd->rdesc1.CSM & CSM_IPKT) {
- if (rd->rdesc1.CSM & CSM_IPOK) {
-- if ((rd->rdesc1.CSM & CSM_TCPKT) ||
-+ if ((rd->rdesc1.CSM & CSM_TCPKT) ||
- (rd->rdesc1.CSM & CSM_UDPKT)) {
- if (!(rd->rdesc1.CSM & CSM_TUPOK)) {
- return;
-@@ -1499,20 +1445,19 @@
- if (pkt_size < rx_copybreak) {
- struct sk_buff *new_skb;
-
-- new_skb = dev_alloc_skb(pkt_size + 2);
-+ /* Always realign IP header to quad boundary if copying anyway */
-+ new_skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
- if (new_skb) {
- new_skb->dev = vptr->dev;
- new_skb->ip_summed = rx_skb[0]->ip_summed;
-
-- if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN)
-- skb_reserve(new_skb, 2);
-+ skb_reserve(new_skb, NET_IP_ALIGN);
-
-- skb_copy_from_linear_data(rx_skb[0], new_skb->data,
-- pkt_size);
-+ memcpy(new_skb->data, rx_skb[0]->data, pkt_size);
- *rx_skb = new_skb;
- ret = 0;
- }
--
-+
- }
- return ret;
- }
-@@ -1529,13 +1474,10 @@
- static inline void velocity_iph_realign(struct velocity_info *vptr,
- struct sk_buff *skb, int pkt_size)
- {
-- /* FIXME - memmove ? */
- if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN) {
-- int i;
--
-- for (i = pkt_size; i >= 0; i--)
-- *(skb->data + i + 2) = *(skb->data + i);
-- skb_reserve(skb, 2);
-+//printk("velocity_iph_realign()\n");
-+ memmove(skb->data + NET_IP_ALIGN, skb->data, pkt_size);
-+ skb_reserve(skb, NET_IP_ALIGN);
- }
- }
-
-@@ -1543,11 +1485,11 @@
- * velocity_receive_frame - received packet processor
- * @vptr: velocity we are handling
- * @idx: ring index
-- *
-+ *
- * A packet has arrived. We process the packet and if appropriate
- * pass the frame up the network stack
- */
--
-+
- static int velocity_receive_frame(struct velocity_info *vptr, int idx)
- {
- void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int);
-@@ -1558,7 +1500,7 @@
- struct sk_buff *skb;
-
- if (rd->rdesc0.RSR & (RSR_STP | RSR_EDP)) {
-- VELOCITY_PRT(MSG_LEVEL_VERBOSE, KERN_ERR " %s : the received frame span multple RDs.\n", vptr->dev->name);
-+ VELOCITY_PRT(MSG_LEVEL_VERBOSE, KERN_ERR " %s : the received frame spans multple RDs.\n", vptr->dev->name);
- stats->rx_length_errors++;
- return -EINVAL;
- }
-@@ -1567,6 +1509,7 @@
- vptr->stats.multicast++;
-
- skb = rd_info->skb;
-+ skb->dev = vptr->dev;
-
- pci_dma_sync_single_for_cpu(vptr->pdev, rd_info->skb_dma,
- vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
-@@ -1574,7 +1517,6 @@
- /*
- * Drop frame not meeting IEEE 802.3
- */
--
- if (vptr->flags & VELOCITY_FLAGS_VAL_PKT_LEN) {
- if (rd->rdesc0.RSR & RSR_RL) {
- stats->rx_length_errors++;
-@@ -1596,9 +1538,11 @@
- PCI_DMA_FROMDEVICE);
-
- skb_put(skb, pkt_len - 4);
-- skb->protocol = eth_type_trans(skb, vptr->dev);
-+ skb->protocol = eth_type_trans(skb, skb->dev);
-
- stats->rx_bytes += pkt_len;
-+ ++stats->rx_packets;
-+
- netif_rx(skb);
-
- return 0;
-@@ -1614,7 +1558,7 @@
- * requires *64* byte alignment of the buffer which makes life
- * less fun than would be ideal.
- */
--
-+
- static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
- {
- struct rx_desc *rd = &(vptr->rd_ring[idx]);
-@@ -1631,11 +1575,10 @@
- skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->data & 63);
- rd_info->skb->dev = vptr->dev;
- rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
--
-+
- /*
- * Fill in the descriptor to match
-- */
--
-+ */
- *((u32 *) & (rd->rdesc0)) = 0;
- rd->len = cpu_to_le32(vptr->rx_buf_sz);
- rd->inten = 1;
-@@ -1651,9 +1594,9 @@
- *
- * Scan the queues looking for transmitted packets that
- * we can complete and clean up. Update any statistics as
-- * necessary/
-+ * neccessary/
- */
--
-+
- static int velocity_tx_srv(struct velocity_info *vptr, u32 status)
- {
- struct tx_desc *td;
-@@ -1665,7 +1608,7 @@
- struct net_device_stats *stats = &vptr->stats;
-
- for (qnum = 0; qnum < vptr->num_txq; qnum++) {
-- for (idx = vptr->td_tail[qnum]; vptr->td_used[qnum] > 0;
-+ for (idx = vptr->td_tail[qnum]; vptr->td_used[qnum] > 0;
- idx = (idx + 1) % vptr->options.numtx) {
-
- /*
-@@ -1677,8 +1620,7 @@
- if (td->tdesc0.owner == OWNED_BY_NIC)
- break;
-
-- if ((works++ > 15))
-- break;
-+ ++works;
-
- if (td->tdesc0.TSR & TSR0_TERR) {
- stats->tx_errors++;
-@@ -1730,7 +1672,7 @@
- if (vptr->mii_status & VELOCITY_LINK_FAIL) {
- VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: failed to detect cable link\n", vptr->dev->name);
- } else if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
-- VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link auto-negotiation", vptr->dev->name);
-+ VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link autonegation", vptr->dev->name);
-
- if (vptr->mii_status & VELOCITY_SPEED_1000)
- VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps");
-@@ -1765,17 +1707,48 @@
- }
-
- /**
-+ * velocity_update_hw_mibs - fetch MIB counters from chip
-+ * @vptr: velocity to update
-+ *
-+ * The velocity hardware keeps certain counters in the hardware
-+ * side. We need to read these when the user asks for statistics
-+ * or when they overflow (causing an interrupt). The read of the
-+ * statistic clears it, so we keep running master counters in user
-+ * space.
-+ */
-+static void velocity_update_hw_mibs(struct velocity_info *vptr)
-+{
-+ int i;
-+
-+ /* Toggle flush to update MIB SRAM from fast counters */
-+ BYTE_REG_BITS_ON(MIBCR_MIBFLSH, &(vptr->mac_regs->MIBCR));
-+ while (BYTE_REG_BITS_IS_ON(MIBCR_MIBFLSH, &(vptr->mac_regs->MIBCR)));
-+
-+ /* Toggle MIBINI to begin MIB SRAM read out. Datasheet says always reads as
-+ zero, so no point polling for it to return to zero after setting */
-+ BYTE_REG_BITS_ON(MIBCR_MPTRINI, &(vptr->mac_regs->MIBCR));
-+
-+ for (i=0; i < HW_MIB_SIZE; ++i) {
-+ /* Read MIB, preserving both index and count */
-+ u32 mib = readl(&(vptr->mac_regs->MIBData));
-+ int index = (mib & 0xff000000) >> 24;
-+ u32 count = mib & 0x00ffffff;
-+ vptr->mib_counter[index] += count;
-+ }
-+}
-+
-+/**
- * velocity_error - handle error from controller
- * @vptr: velocity
- * @status: card status
- *
- * Process an error report from the hardware and attempt to recover
-- * the card itself. At the moment we cannot recover from some
-+ * the card itself. At the moment we cannot recover from some
- * theoretically impossible errors but this could be fixed using
- * the pci_device_failed logic to bounce the hardware
- *
- */
--
-+
- static void velocity_error(struct velocity_info *vptr, int status)
- {
-
-@@ -1786,7 +1759,7 @@
- BYTE_REG_BITS_ON(TXESR_TDSTR, ®s->TXESR);
- writew(TRDCSR_RUN, ®s->TDCSRClr);
- netif_stop_queue(vptr->dev);
--
-+
- /* FIXME: port over the pci_device_failed code and use it
- here */
- }
-@@ -1799,7 +1772,7 @@
- vptr->mii_status = check_connection_type(regs);
-
- /*
-- * If it is a 3119, disable frame bursting in
-+ * If it is a 3119, disable frame bursting in
- * halfduplex mode and enable it in fullduplex
- * mode
- */
-@@ -1832,13 +1805,15 @@
- }
-
- velocity_print_link_status(vptr);
-+
-+ mac_set_dma_length(vptr);
- enable_flow_control_ability(vptr);
-
- /*
-- * Re-enable auto-polling because SRCI will disable
-+ * Re-enable auto-polling because SRCI will disable
- * auto-polling
- */
--
-+
- enable_mii_autopoll(regs);
-
- if (vptr->mii_status & VELOCITY_LINK_FAIL)
-@@ -1846,9 +1821,11 @@
- else
- netif_wake_queue(vptr->dev);
-
-- };
-+ }
-+
- if (status & ISR_MIBFI)
- velocity_update_hw_mibs(vptr);
-+
- if (status & ISR_LSTEI)
- mac_rx_queue_wake(vptr->mac_regs);
- }
-@@ -1858,29 +1835,35 @@
- * @vptr: velocity
- * @tdinfo: buffer
- *
-- * Release an transmit buffer. If the buffer was preallocated then
-+ * Release a transmit buffer. If the buffer was preallocated then
- * recycle it, if not then unmap the buffer.
- */
--
- static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *tdinfo)
- {
- struct sk_buff *skb = tdinfo->skb;
- int i;
-
-- /*
-- * Don't unmap the pre-allocated tx_bufs
-- */
-- if (tdinfo->skb_dma && (tdinfo->skb_dma[0] != tdinfo->buf_dma)) {
-+ /* Don't unmap the pre-allocated tx_bufs */
-+ if (tdinfo->skb_dma[0] && (tdinfo->skb_dma[0] != tdinfo->buf_dma)) {
-+ if (tdinfo->nskb_dma == 1) {
-+ /* Either no fragments originally, or was linearized because too
-+ many fragments */
-+ pci_unmap_single(vptr->pdev, tdinfo->skb_dma[0], skb->len, PCI_DMA_TODEVICE);
-+ tdinfo->skb_dma[0] = 0;
-+ } else {
-+ /* Unmap the head buffer */
-+ pci_unmap_single(vptr->pdev, tdinfo->skb_dma[0], skb_headlen(skb), PCI_DMA_TODEVICE);
-+ tdinfo->skb_dma[0] = 0;
-
-- for (i = 0; i < tdinfo->nskb_dma; i++) {
--#ifdef VELOCITY_ZERO_COPY_SUPPORT
-- pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], td->tdesc1.len, PCI_DMA_TODEVICE);
--#else
-- pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], skb->len, PCI_DMA_TODEVICE);
--#endif
-- tdinfo->skb_dma[i] = 0;
-- }
-+ /* Unmap the fragment buffers */
-+ for (i=0; i < tdinfo->nskb_dma-1; ++i) {
-+ pci_unmap_page(vptr->pdev, tdinfo->skb_dma[i+1],
-+ skb_shinfo(skb)->frags[i].size, PCI_DMA_TODEVICE);
-+ tdinfo->skb_dma[i+1] = 0;
-+ }
-+ }
- }
-+
- dev_kfree_skb_irq(skb);
- tdinfo->skb = NULL;
- }
-@@ -1895,12 +1878,14 @@
- * All the ring allocation and set up is done on open for this
- * adapter to minimise memory usage when inactive
- */
--
-+
- static int velocity_open(struct net_device *dev)
- {
- struct velocity_info *vptr = netdev_priv(dev);
- int ret;
-
-+ vptr->rx_buf_sz = dev->mtu + NET_IP_ALIGN + EXTRA_RX_SKB_SPACE;
-+
- ret = velocity_init_rings(vptr);
- if (ret < 0)
- goto out;
-@@ -1912,13 +1897,13 @@
- ret = velocity_init_td_ring(vptr);
- if (ret < 0)
- goto err_free_rd_ring;
--
-- /* Ensure chip is running */
-+
-+ /* Ensure chip is running */
- pci_set_power_state(vptr->pdev, PCI_D0);
--
-+
- velocity_init_registers(vptr, VELOCITY_INIT_COLD);
-
-- ret = request_irq(vptr->pdev->irq, &velocity_intr, IRQF_SHARED,
-+ ret = request_irq(vptr->pdev->irq, &velocity_intr, SA_SHIRQ,
- dev->name, dev);
- if (ret < 0) {
- /* Power down the chip */
-@@ -1941,7 +1926,7 @@
- goto out;
- }
-
--/**
-+/**
- * velocity_change_mtu - MTU change callback
- * @dev: network device
- * @new_mtu: desired MTU
-@@ -1950,7 +1935,7 @@
- * this interface. It gets called on a change by the network layer.
- * Return zero for success or negative posix error code.
- */
--
-+
- static int velocity_change_mtu(struct net_device *dev, int new_mtu)
- {
- struct velocity_info *vptr = netdev_priv(dev);
-@@ -1959,16 +1944,11 @@
- int ret = 0;
-
- if ((new_mtu < VELOCITY_MIN_MTU) || new_mtu > (VELOCITY_MAX_MTU)) {
-- VELOCITY_PRT(MSG_LEVEL_ERR, KERN_NOTICE "%s: Invalid MTU.\n",
-+ VELOCITY_PRT(MSG_LEVEL_ERR, KERN_NOTICE "%s: Invalid MTU.\n",
- vptr->dev->name);
- return -EINVAL;
- }
-
-- if (!netif_running(dev)) {
-- dev->mtu = new_mtu;
-- return 0;
-- }
--
- if (new_mtu != oldmtu) {
- spin_lock_irqsave(&vptr->lock, flags);
-
-@@ -1978,7 +1958,7 @@
- velocity_free_td_ring(vptr);
- velocity_free_rd_ring(vptr);
-
-- dev->mtu = new_mtu;
-+ dev->mtu = new_mtu + NET_IP_ALIGN + EXTRA_RX_SKB_SPACE;
-
- ret = velocity_init_rd_ring(vptr);
- if (ret < 0)
-@@ -2006,7 +1986,7 @@
- * Shuts down the internal operations of the velocity and
- * disables interrupts, autopolling, transmit and receive
- */
--
-+
- static void velocity_shutdown(struct velocity_info *vptr)
- {
- struct mac_regs __iomem * regs = vptr->mac_regs;
-@@ -2037,10 +2017,10 @@
- velocity_get_ip(vptr);
- if (dev->irq != 0)
- free_irq(dev->irq, dev);
--
-+
- /* Power down the chip */
- pci_set_power_state(vptr->pdev, PCI_D3hot);
--
-+
- /* Free the resources */
- velocity_free_td_ring(vptr);
- velocity_free_rd_ring(vptr);
-@@ -2058,7 +2038,7 @@
- * Called by the networ layer to request a packet is queued to
- * the velocity. Returns zero on success.
- */
--
-+
- static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
- {
- struct velocity_info *vptr = netdev_priv(dev);
-@@ -2067,16 +2047,22 @@
- struct velocity_td_info *tdinfo;
- unsigned long flags;
- int index;
--
-- int pktlen = skb->len;
--
-+ int pktlen;
-+printk("Tx");
- #ifdef VELOCITY_ZERO_COPY_SUPPORT
-- if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) {
-- kfree_skb(skb);
-- return 0;
-+ if (skb_shinfo(skb)->nr_frags > MAX_HW_FRAGMENTS) {
-+//printk("Too many fragments (%d), linearizing\n", skb_shinfo(skb)->nr_frags);
-+ if (__skb_linearize(skb, GFP_ATOMIC)) {
-+//printk("Linearization failed, dropping Tx packet\n");
-+ kfree_skb(skb);
-+ return 0;
-+ }
- }
- #endif
-
-+ // Get packet length after any linearization has occured
-+ pktlen = skb->len;
-+
- spin_lock_irqsave(&vptr->lock, flags);
-
- index = vptr->td_curr[qnum];
-@@ -2088,19 +2074,28 @@
- td_ptr->td_buf[0].queue = 0;
-
- /*
-- * Pad short frames.
-+ * Pad short frames.
- */
- if (pktlen < ETH_ZLEN) {
-- /* Cannot occur until ZC support */
-+ int pad_required = ETH_ZLEN - skb->len;
-+printk("Padding short Tx frame\n");
- pktlen = ETH_ZLEN;
-- skb_copy_from_linear_data(skb, tdinfo->buf, skb->len);
-- memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
- tdinfo->skb = skb;
-- tdinfo->skb_dma[0] = tdinfo->buf_dma;
-+
-+ if (skb_tailroom(skb) >= pad_required) {
-+//printk("Using short frame\n");
-+ tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, pktlen, PCI_DMA_TODEVICE);
-+ } else {
-+//printk("Copying short frame\n");
-+ memcpy(tdinfo->buf, skb->data, skb->len);
-+ memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
-+ tdinfo->skb_dma[0] = tdinfo->buf_dma;
-+ }
-+
- td_ptr->tdesc0.pktsize = pktlen;
- td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
- td_ptr->td_buf[0].pa_high = 0;
-- td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize;
-+ td_ptr->td_buf[0].bufsize = pktlen;
- tdinfo->nskb_dma = 1;
- td_ptr->tdesc1.CMDZ = 2;
- } else
-@@ -2108,41 +2103,46 @@
- if (skb_shinfo(skb)->nr_frags > 0) {
- int nfrags = skb_shinfo(skb)->nr_frags;
- tdinfo->skb = skb;
-- if (nfrags > 6) {
-- skb_copy_from_linear_data(skb, tdinfo->buf, skb->len);
-- tdinfo->skb_dma[0] = tdinfo->buf_dma;
-- td_ptr->tdesc0.pktsize =
-+ td_ptr->tdesc0.pktsize = pktlen;
-+
-+ if (nfrags > MAX_HW_FRAGMENTS) {
-+//printk("Using linearized skb\n");
-+ /* SKB has already been linearized above, so use direct from skb */
-+ tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, pktlen, PCI_DMA_TODEVICE);
- td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
- td_ptr->td_buf[0].pa_high = 0;
-- td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize;
-+ td_ptr->td_buf[0].bufsize = pktlen;
- tdinfo->nskb_dma = 1;
- td_ptr->tdesc1.CMDZ = 2;
- } else {
- int i = 0;
-- tdinfo->nskb_dma = 0;
-- tdinfo->skb_dma[i] = pci_map_single(vptr->pdev, skb->data, skb->len - skb->data_len, PCI_DMA_TODEVICE);
-
-- td_ptr->tdesc0.pktsize = pktlen;
-+ tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, skb_headlen(skb), PCI_DMA_TODEVICE);
-
-- /* FIXME: support 48bit DMA later */
-- td_ptr->td_buf[i].pa_low = cpu_to_le32(tdinfo->skb_dma);
-- td_ptr->td_buf[i].pa_high = 0;
-- td_ptr->td_buf[i].bufsize = skb->len->skb->data_len;
-+ td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
-+ td_ptr->td_buf[0].pa_high = 0;
-+ td_ptr->td_buf[0].bufsize = skb_headlen(skb);
-
-- for (i = 0; i < nfrags; i++) {
-+ for (i=0; i < nfrags; ++i) {
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-- void *addr = ((void *) page_address(frag->page + frag->page_offset));
-
-- tdinfo->skb_dma[i + 1] = pci_map_single(vptr->pdev, addr, frag->size, PCI_DMA_TODEVICE);
-+ tdinfo->skb_dma[i+1] = pci_map_page(vptr->pdev, frag->page, frag->page_offset, frag->size, PCI_DMA_TODEVICE);
-
-- td_ptr->td_buf[i + 1].pa_low = cpu_to_le32(tdinfo->skb_dma[i + 1]);
-- td_ptr->td_buf[i + 1].pa_high = 0;
-- td_ptr->td_buf[i + 1].bufsize = frag->size;
-+ td_ptr->td_buf[i+1].pa_low = cpu_to_le32(tdinfo->skb_dma[i+1]);
-+ td_ptr->td_buf[i+1].pa_high = 0;
-+ td_ptr->td_buf[i+1].bufsize = frag->size;
- }
-- tdinfo->nskb_dma = i - 1;
-- td_ptr->tdesc1.CMDZ = i;
-- }
-
-+ tdinfo->nskb_dma = nfrags+1;
-+ td_ptr->tdesc1.CMDZ = nfrags+2;
-+
-+//printk("Num frags = %d\n", nfrags);
-+//printk("skb: 0x%08lx:0x%08x, %d\n", (unsigned long)skb->data, tdinfo->skb_dma[0], skb_headlen(skb));
-+//for (i=0; i < nfrags; ++i) {
-+// skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-+// printk("frag: 0x%08lx:0x%08x, %d\n", (unsigned long)page_address(frag->page) + frag->page_offset, tdinfo->skb_dma[i+1], frag->size);
-+//}
-+ }
- } else
- #endif
- {
-@@ -2155,13 +2155,18 @@
- td_ptr->tdesc0.pktsize = pktlen;
- td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
- td_ptr->td_buf[0].pa_high = 0;
-- td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize;
-+ td_ptr->td_buf[0].bufsize = pktlen;
- tdinfo->nskb_dma = 1;
- td_ptr->tdesc1.CMDZ = 2;
-+printk("0x%08x:%u\n", td_ptr->td_buf[0].pa_low, td_ptr->td_buf[0].bufsize);
-+printk("TdInd0=0x%04hx\n", readw(&vptr->mac_regs->TDIdx[0]));
-+printk("TdInd1=0x%04hx\n", readw(&vptr->mac_regs->TDIdx[1]));
-+printk("TdInd2=0x%04hx\n", readw(&vptr->mac_regs->TDIdx[2]));
-+printk("TdInd3=0x%04hx\n", readw(&vptr->mac_regs->TDIdx[3]));
- }
-
-- if (vptr->vlgrp && vlan_tx_tag_present(skb)) {
-- td_ptr->tdesc1.pqinf.VID = vlan_tx_tag_get(skb);
-+ if (vptr->flags & VELOCITY_FLAGS_TAGGING) {
-+ td_ptr->tdesc1.pqinf.VID = (vptr->options.vid & 0xfff);
- td_ptr->tdesc1.pqinf.priority = 0;
- td_ptr->tdesc1.pqinf.CFI = 0;
- td_ptr->tdesc1.TCR |= TCR0_VETAG;
-@@ -2170,21 +2175,23 @@
- /*
- * Handle hardware checksum
- */
-- if ((vptr->flags & VELOCITY_FLAGS_TX_CSUM)
-- && (skb->ip_summed == CHECKSUM_PARTIAL)) {
-- const struct iphdr *ip = ip_hdr(skb);
-+ if ((vptr->flags & VELOCITY_FLAGS_TX_CSUM) &&
-+ (skb->ip_summed == CHECKSUM_HW)) {
-+ struct iphdr *ip = skb->nh.iph;
-+
- if (ip->protocol == IPPROTO_TCP)
- td_ptr->tdesc1.TCR |= TCR0_TCPCK;
- else if (ip->protocol == IPPROTO_UDP)
- td_ptr->tdesc1.TCR |= (TCR0_UDPCK);
-+
- td_ptr->tdesc1.TCR |= TCR0_IPCK;
- }
- {
--
- int prev = index - 1;
-
- if (prev < 0)
- prev = vptr->options.numtx - 1;
-+
- td_ptr->tdesc0.owner = OWNED_BY_NIC;
- vptr->td_used[qnum]++;
- vptr->td_curr[qnum] = (index + 1) % vptr->options.numtx;
-@@ -2196,8 +2203,10 @@
- td_ptr->td_buf[0].queue = 1;
- mac_tx_queue_wake(vptr->mac_regs, qnum);
- }
-+
- dev->trans_start = jiffies;
- spin_unlock_irqrestore(&vptr->lock, flags);
-+printk("xT\n");
- return 0;
- }
-
-@@ -2205,57 +2214,55 @@
- * velocity_intr - interrupt callback
- * @irq: interrupt number
- * @dev_instance: interrupting device
-+ * @pt_regs: CPU register state at interrupt
- *
- * Called whenever an interrupt is generated by the velocity
- * adapter IRQ line. We may not be the source of the interrupt
- * and need to identify initially if we are, and if not exit as
- * efficiently as possible.
- */
--
--static int velocity_intr(int irq, void *dev_instance)
-+
-+static int velocity_intr(int irq, void *dev_instance, struct pt_regs *regs)
- {
- struct net_device *dev = dev_instance;
- struct velocity_info *vptr = netdev_priv(dev);
- u32 isr_status;
- int max_count = 0;
-
--
-+printk("I");
- spin_lock(&vptr->lock);
- isr_status = mac_read_isr(vptr->mac_regs);
-+printk("0x%08x ", isr_status);
-
-- /* Not us ? */
-- if (isr_status == 0) {
-+ if (!isr_status) {
- spin_unlock(&vptr->lock);
-+printk("N ");
- return IRQ_NONE;
- }
-
- mac_disable_int(vptr->mac_regs);
-
-- /*
-- * Keep processing the ISR until we have completed
-- * processing and the isr_status becomes zero
-- */
--
-- while (isr_status != 0) {
-+ /* Process all pending interrupts */
-+ while (isr_status) {
-+ /* Ack all pending interrupt sources */
- mac_write_isr(vptr->mac_regs, isr_status);
-- if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI)))
-- velocity_error(vptr, isr_status);
-- if (isr_status & (ISR_PRXI | ISR_PPRXI))
-+
-+ velocity_error(vptr, isr_status);
-+ if (isr_status & (ISR_PRXI | ISR_PPRXI)) {
-+printk("R");
- max_count += velocity_rx_srv(vptr, isr_status);
-- if (isr_status & (ISR_PTXI | ISR_PPTXI))
-+ }
-+ if (isr_status & (ISR_PTXI | ISR_PPTXI)) {
-+printk("T");
- max_count += velocity_tx_srv(vptr, isr_status);
-- isr_status = mac_read_isr(vptr->mac_regs);
-- if (max_count > vptr->options.int_works)
-- {
-- printk(KERN_WARNING "%s: excessive work at interrupt.\n",
-- dev->name);
-- max_count = 0;
- }
-+ isr_status = mac_read_isr(vptr->mac_regs);
- }
-+
- spin_unlock(&vptr->lock);
-+printk("i");
- mac_enable_int(vptr->mac_regs);
- return IRQ_HANDLED;
--
- }
-
-
-@@ -2267,41 +2274,70 @@
- * for a velocity adapter. Reload the CAMs with the new address
- * filter ruleset.
- */
-+static void clear_all_multicast(struct velocity_info *vptr)
-+{
-+ struct mac_regs __iomem * regs = vptr->mac_regs;
-+
-+ /* Do not allow any multicast packets through the multicast hash table */
-+ writel(0x0, ®s->MARCAM[0]);
-+ writel(0x0, ®s->MARCAM[4]);
-+}
-+
-+static void set_all_multicast(struct velocity_info *vptr)
-+{
-+ struct mac_regs __iomem * regs = vptr->mac_regs;
-+
-+ /* Allow all multicast packets through the multicast hash table */
-+ writel(0xffffffff, ®s->MARCAM[0]);
-+ writel(0xffffffff, ®s->MARCAM[4]);
-+}
-
- static void velocity_set_multi(struct net_device *dev)
- {
- struct velocity_info *vptr = netdev_priv(dev);
- struct mac_regs __iomem * regs = vptr->mac_regs;
-- u8 rx_mode;
-- int i;
- struct dev_mc_list *mclist;
-+ int i;
-+ u8 rx_mode = RCR_AB; /* Always enable broadcast packet reception */
-
-- if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
-- writel(0xffffffff, ®s->MARCAM[0]);
-- writel(0xffffffff, ®s->MARCAM[4]);
-- rx_mode = (RCR_AM | RCR_AB | RCR_PROM);
-- } else if ((dev->mc_count > vptr->multicast_limit)
-- || (dev->flags & IFF_ALLMULTI)) {
-- writel(0xffffffff, ®s->MARCAM[0]);
-- writel(0xffffffff, ®s->MARCAM[4]);
-- rx_mode = (RCR_AM | RCR_AB);
-- } else {
-- int offset = MCAM_SIZE - vptr->multicast_limit;
-- mac_get_cam_mask(regs, vptr->mCAMmask);
-+ /* Clear out the multicast hash table */
-+ clear_all_multicast(vptr);
-
-+ /* Disable all multicast CAM entries */
-+ memset(vptr->mCAMmask, 0, MCAM_SIZE / 8);
-+ mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM);
-+
-+ if (dev->flags & IFF_PROMISC) {
-+ /* Enable promiscuous mode */
-+ printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
-+
-+ set_all_multicast(vptr);
-+ rx_mode |= (RCR_PROM | RCR_AM);
-+ } else if ((dev->mc_count > MCAM_SIZE) ||
-+ (dev->flags & IFF_ALLMULTI)) {
-+ /* ALL_MULTI or too many entries for perfect filtering, so allow all
-+ * multicast packets through hash table */
-+ set_all_multicast(vptr);
-+ rx_mode |= RCR_AM;
-+ } else {
-+ /* Write a CAM entry for each multicast address */
- for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) {
-- mac_set_cam(regs, i + offset, mclist->dmi_addr);
-- vptr->mCAMmask[(offset + i) / 8] |= 1 << ((offset + i) & 7);
-+ mac_set_cam(regs, i, mclist->dmi_addr, VELOCITY_MULTICAST_CAM);
-+ vptr->mCAMmask[i / 8] |= 1 << (i & 7);
- }
-
-- mac_set_cam_mask(regs, vptr->mCAMmask);
-- rx_mode = (RCR_AM | RCR_AB);
-+ /* Enable those multicast CAM entries just written */
-+ mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM);
-+
-+ /* Enable multicast perfect matching */
-+ rx_mode |= (RCR_AM | RCR_AP);
- }
-+
-+ /* Allow large packets if indicated by MTU */
- if (dev->mtu > 1500)
- rx_mode |= RCR_AL;
-
-- BYTE_REG_BITS_ON(rx_mode, ®s->RCR);
--
-+ BYTE_REG_BITS_SET(rx_mode, RCR_AM | RCR_AB | RCR_PROM | RCR_AL | RCR_AP, ®s->RCR);
- }
-
- /**
-@@ -2314,36 +2350,32 @@
- * the hardware into the counters before letting the network
- * layer display them.
- */
--
-+
- static struct net_device_stats *velocity_get_stats(struct net_device *dev)
- {
-- struct velocity_info *vptr = netdev_priv(dev);
--
-- /* If the hardware is down, don't touch MII */
-- if(!netif_running(dev))
-- return &vptr->stats;
--
-- spin_lock_irq(&vptr->lock);
-- velocity_update_hw_mibs(vptr);
-- spin_unlock_irq(&vptr->lock);
-+ struct velocity_info *vptr = dev->priv;
-
-- vptr->stats.rx_packets = vptr->mib_counter[HW_MIB_ifRxAllPkts];
-- vptr->stats.rx_errors = vptr->mib_counter[HW_MIB_ifRxErrorPkts];
-- vptr->stats.rx_length_errors = vptr->mib_counter[HW_MIB_ifInRangeLengthErrors];
-+#if 0
-+ /* Only access the MIBs if the hardware is up */
-+ if (netif_running(dev)) {
-+ int i;
-
--// unsigned long rx_dropped; /* no space in linux buffers */
-- vptr->stats.collisions = vptr->mib_counter[HW_MIB_ifTxEtherCollisions];
-- /* detailed rx_errors: */
--// unsigned long rx_length_errors;
--// unsigned long rx_over_errors; /* receiver ring buff overflow */
-- vptr->stats.rx_crc_errors = vptr->mib_counter[HW_MIB_ifRxPktCRCE];
--// unsigned long rx_frame_errors; /* recv'd frame alignment error */
--// unsigned long rx_fifo_errors; /* recv'r fifo overrun */
--// unsigned long rx_missed_errors; /* receiver missed packet */
-+ /* Transfer from fast counters to MIB SRAM, locking against
-+ simulatanous access by ISR due to MIB high threshold being
-+ exceeded */
-+ spin_lock_irq(&vptr->lock);
-+ velocity_update_hw_mibs(vptr);
-+ spin_unlock_irq(&vptr->lock);
-
-- /* detailed tx_errors */
--// unsigned long tx_fifo_errors;
-+ /* Print MIB statistics */
-+ printk("MIBs:\n");
-+ for (i=0; i < HW_MIB_SIZE; ++i) {
-+ printk("%02d: %08d\n", i, vptr->mib_counter[i]);
-+ }
-+ }
-+#endif
-
-+ /* Return only the statistics gathered by the driver, not MIBs */
- return &vptr->stats;
- }
-
-@@ -2357,7 +2389,7 @@
- * Called when the user issues an ioctl request to the network
- * device in question. The velocity interface supports MII.
- */
--
-+
- static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
- {
- struct velocity_info *vptr = netdev_priv(dev);
-@@ -2365,10 +2397,10 @@
-
- /* If we are asked for information and the device is power
- saving then we need to bring the device back up to talk to it */
--
-+
- if (!netif_running(dev))
- pci_set_power_state(vptr->pdev, PCI_D0);
--
-+
- switch (cmd) {
- case SIOCGMIIPHY: /* Get address of MII PHY in use. */
- case SIOCGMIIREG: /* Read MII PHY register. */
-@@ -2381,8 +2413,8 @@
- }
- if (!netif_running(dev))
- pci_set_power_state(vptr->pdev, PCI_D3hot);
--
--
-+
-+
- return ret;
- }
-
-@@ -2390,7 +2422,7 @@
- * Definition for our device driver. The PCI layer interface
- * uses this to handle all our card discover and plugging
- */
--
-+
- static struct pci_driver velocity_driver = {
- .name = VELOCITY_NAME,
- .id_table = velocity_id_table,
-@@ -2410,13 +2442,13 @@
- * the probe functions for each velocity adapter installed
- * in the system.
- */
--
-+
- static int __init velocity_init_module(void)
- {
- int ret;
-
- velocity_register_notifier();
-- ret = pci_register_driver(&velocity_driver);
-+ ret = pci_module_init(&velocity_driver);
- if (ret < 0)
- velocity_unregister_notifier();
- return ret;
-@@ -2426,11 +2458,11 @@
- * velocity_cleanup - module unload
- *
- * When the velocity hardware is unloaded this function is called.
-- * It will clean up the notifiers and the unregister the PCI
-+ * It will clean up the notifiers and the unregister the PCI
- * driver interface for this hardware. This in turn cleans up
- * all discovered interfaces before returning from the function
- */
--
-+
- static void __exit velocity_cleanup_module(void)
- {
- velocity_unregister_notifier();
-@@ -2444,8 +2476,8 @@
- /*
- * MII access , media link mode setting functions
- */
--
--
-+
-+
- /**
- * mii_init - set up MII
- * @vptr: velocity adapter
-@@ -2453,7 +2485,7 @@
- *
- * Set up the PHY for the current link state.
- */
--
-+
- static void mii_init(struct velocity_info *vptr, u32 mii_status)
- {
- u16 BMCR;
-@@ -2466,7 +2498,7 @@
- MII_REG_BITS_OFF((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
- /*
- * Turn on ECHODIS bit in NWay-forced full mode and turn it
-- * off it in NWay-forced half mode for NWay-forced v.s.
-+ * off it in NWay-forced half mode for NWay-forced v.s.
- * legacy-forced issue.
- */
- if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
-@@ -2486,7 +2518,7 @@
- MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
- /*
- * Turn on ECHODIS bit in NWay-forced full mode and turn it
-- * off it in NWay-forced half mode for NWay-forced v.s.
-+ * off it in NWay-forced half mode for NWay-forced v.s.
- * legacy-forced issue
- */
- if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
-@@ -2498,11 +2530,11 @@
- case PHYID_MARVELL_1000:
- case PHYID_MARVELL_1000S:
- /*
-- * Assert CRS on Transmit
-+ * Assert CRS on Transmit
- */
- MII_REG_BITS_ON(PSCR_ACRSTX, MII_REG_PSCR, vptr->mac_regs);
- /*
-- * Reset to hardware default
-+ * Reset to hardware default
- */
- MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
- break;
-@@ -2522,7 +2554,7 @@
- *
- * Turn off the autopoll and wait for it to disable on the chip
- */
--
-+
- static void safe_disable_mii_autopoll(struct mac_regs __iomem * regs)
- {
- u16 ww;
-@@ -2576,7 +2608,7 @@
- * Perform a single read of an MII 16bit register. Returns zero
- * on success or -ETIMEDOUT if the PHY did not respond.
- */
--
-+
- static int velocity_mii_read(struct mac_regs __iomem *regs, u8 index, u16 *data)
- {
- u16 ww;
-@@ -2612,7 +2644,7 @@
- * Perform a single write to an MII 16bit register. Returns zero
- * on success or -ETIMEDOUT if the PHY did not respond.
- */
--
-+
- static int velocity_mii_write(struct mac_regs __iomem *regs, u8 mii_addr, u16 data)
- {
- u16 ww;
-@@ -2651,7 +2683,7 @@
- * mii_status accordingly. The requested link state information
- * is also returned.
- */
--
-+
- static u32 velocity_get_opt_media_mode(struct velocity_info *vptr)
- {
- u32 status = 0;
-@@ -2683,7 +2715,7 @@
- *
- * Enable autonegotation on this interface
- */
--
-+
- static void mii_set_auto_on(struct velocity_info *vptr)
- {
- if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs))
-@@ -2707,7 +2739,7 @@
- * Set up the flow control on this interface according to
- * the supplied user/eeprom options.
- */
--
-+
- static void set_mii_flow_control(struct velocity_info *vptr)
- {
- /*Enable or Disable PAUSE in ANAR */
-@@ -2744,7 +2776,7 @@
- * PHY and also velocity hardware setup accordingly. In particular
- * we need to set up CD polling and frame bursting.
- */
--
-+
- static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status)
- {
- u32 curr_status;
-@@ -2854,7 +2886,7 @@
- * Check the current MII status and determine the link status
- * accordingly
- */
--
-+
- static u32 mii_check_media_mode(struct mac_regs __iomem * regs)
- {
- u32 status = 0;
-@@ -2986,14 +3018,14 @@
- * Called before an ethtool operation. We need to make sure the
- * chip is out of D3 state before we poke at it.
- */
--
-+
- static int velocity_ethtool_up(struct net_device *dev)
- {
- struct velocity_info *vptr = netdev_priv(dev);
- if (!netif_running(dev))
- pci_set_power_state(vptr->pdev, PCI_D0);
- return 0;
--}
-+}
-
- /**
- * velocity_ethtool_down - post hook for ethtool
-@@ -3002,7 +3034,7 @@
- * Called after an ethtool operation. Restore the chip back to D3
- * state if it isn't running.
- */
--
-+
- static void velocity_ethtool_down(struct net_device *dev)
- {
- struct velocity_info *vptr = netdev_priv(dev);
-@@ -3040,7 +3072,21 @@
- cmd->duplex = DUPLEX_FULL;
- else
- cmd->duplex = DUPLEX_HALF;
--
-+
-+#if 0
-+{
-+int i;
-+unsigned char __iomem *ptr = (unsigned char __iomem *)regs;
-+printk("Regs:\n");
-+printk("0x00:\t");
-+for (i=0; i <= MAC_REG_BYTEMSK3_3; ++i) {
-+ printk("0x%02x\t", readb(&(ptr[i])));
-+ if (!((i+1) % 8)) {
-+ printk("\n0x%02x:\t", i+1);
-+ }
-+}
-+}
-+#endif
- return 0;
- }
-
-@@ -3050,7 +3096,7 @@
- u32 curr_status;
- u32 new_status = 0;
- int ret = 0;
--
-+
- curr_status = check_connection_type(vptr->mac_regs);
- curr_status &= (~VELOCITY_LINK_FAIL);
-
-@@ -3061,8 +3107,10 @@
-
- if ((new_status & VELOCITY_AUTONEG_ENABLE) && (new_status != (curr_status | VELOCITY_AUTONEG_ENABLE)))
- ret = -EINVAL;
-- else
-+ else {
- velocity_set_media_mode(vptr, new_status);
-+ mac_set_dma_length(vptr);
-+ }
-
- return ret;
- }
-@@ -3139,7 +3187,7 @@
- msglevel = value;
- }
-
--static const struct ethtool_ops velocity_ethtool_ops = {
-+static struct ethtool_ops velocity_ethtool_ops = {
- .get_settings = velocity_get_settings,
- .set_settings = velocity_set_settings,
- .get_drvinfo = velocity_get_drvinfo,
-@@ -3162,7 +3210,7 @@
- * are used by tools like kudzu to interrogate the link state of the
- * hardware
- */
--
-+
- static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
- {
- struct velocity_info *vptr = netdev_priv(dev);
-@@ -3170,7 +3218,7 @@
- unsigned long flags;
- struct mii_ioctl_data *miidata = if_mii(ifr);
- int err;
--
-+
- switch (cmd) {
- case SIOCGMIIPHY:
- miidata->phy_id = readb(®s->MIIADR) & 0x1f;
-@@ -3197,11 +3245,36 @@
- return 0;
- }
-
-+static void hw_set_mac_address(struct velocity_info *vptr, unsigned char* p)
-+{
-+ struct mac_regs __iomem * regs = vptr->mac_regs;
-+
-+ int i;
-+ for (i = 0; i < 6; i++) {
-+ writeb(p[i], &(regs->PAR[i]));
-+ }
-+}
-+
-+static int set_mac_address(struct net_device *dev, void *p)
-+{
-+ struct sockaddr *addr = p;
-+ struct velocity_info *vptr = dev->priv;
-+
-+ if (!is_valid_ether_addr(addr->sa_data)) {
-+ return -EADDRNOTAVAIL;
-+ }
-+
-+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
-+ hw_set_mac_address(vptr, addr->sa_data);
-+
-+ return 0;
-+}
-+
- #ifdef CONFIG_PM
-
- /**
- * velocity_save_context - save registers
-- * @vptr: velocity
-+ * @vptr: velocity
- * @context: buffer for stored context
- *
- * Retrieve the current configuration from the velocity hardware
-@@ -3209,7 +3282,7 @@
- * restore functions. This allows us to save things we need across
- * power down states
- */
--
-+
- static void velocity_save_context(struct velocity_info *vptr, struct velocity_context * context)
- {
- struct mac_regs __iomem * regs = vptr->mac_regs;
-@@ -3229,13 +3302,13 @@
-
- /**
- * velocity_restore_context - restore registers
-- * @vptr: velocity
-+ * @vptr: velocity
- * @context: buffer for stored context
- *
-- * Reload the register configuration from the velocity context
-+ * Reload the register configuration from the velocity context
- * created by velocity_save_context.
- */
--
-+
- static void velocity_restore_context(struct velocity_info *vptr, struct velocity_context *context)
- {
- struct mac_regs __iomem * regs = vptr->mac_regs;
-@@ -3301,7 +3374,7 @@
- }
- /* Finally, invert the result once to get the correct data */
- crc = ~crc;
-- return bitrev32(crc) >> 16;
-+ return bitreverse(crc) >> 16;
- }
-
- /**
-@@ -3461,8 +3534,6 @@
- return 0;
- }
-
--#ifdef CONFIG_INET
--
- static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr)
- {
- struct in_ifaddr *ifa = (struct in_ifaddr *) ptr;
-@@ -3483,6 +3554,4 @@
- }
- return NOTIFY_DONE;
- }
--
--#endif
- #endif
-diff -Nurd linux-2.6.24/drivers/net/via-velocity.h linux-2.6.24-oxe810/drivers/net/via-velocity.h
---- linux-2.6.24/drivers/net/via-velocity.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/via-velocity.h 2008-06-11 17:50:11.000000000 +0200
-@@ -25,8 +25,6 @@
- #ifndef VELOCITY_H
- #define VELOCITY_H
-
--#define VELOCITY_TX_CSUM_SUPPORT
--
- #define VELOCITY_NAME "via-velocity"
- #define VELOCITY_FULL_DRV_NAM "VIA Networking Velocity Family Gigabit Ethernet Adapter Driver"
- #define VELOCITY_VERSION "1.14"
-@@ -35,6 +33,8 @@
-
- #define PKT_BUF_SZ 1540
-
-+#define PKT_BUF_SZ ETH_ZLEN
-+
- #define MAX_UNITS 8
- #define OPTION_DEFAULT { [0 ... MAX_UNITS-1] = -1}
-
-@@ -716,6 +716,8 @@
- /*
- * Bits in the CFGA register
- */
-+#define CFGA_PHYLEDS1 0x20
-+#define CFGA_PHYLEDS0 0x10
-
- #define CFGA_PMHCTG 0x08
- #define CFGA_GPIO1PD 0x04
-@@ -766,6 +768,7 @@
- #define DCFG_XMRM 0x4000
- #define DCFG_XMRL 0x2000
- #define DCFG_PERDIS 0x1000
-+#define DCFG_MRDPL 0x0800
- #define DCFG_MRWAIT 0x0400
- #define DCFG_MWWAIT 0x0200
- #define DCFG_LATMEN 0x0100
-@@ -1173,7 +1176,7 @@
-
- struct velocity_info_tbl {
- enum chip_type chip_id;
-- const char *name;
-+ char *name;
- int txqueue;
- u32 flags;
- };
-@@ -1194,8 +1197,12 @@
- #define mac_disable_int(regs) writel(CR0_GINTMSK1,&((regs)->CR0Clr))
- #define mac_enable_int(regs) writel(CR0_GINTMSK1,&((regs)->CR0Set))
-
--#define mac_set_dma_length(regs, n) {\
-- BYTE_REG_BITS_SET((n),0x07,&((regs)->DCFG));\
-+#define mac_hw_mibs_read(regs, MIBs) {\
-+ int i;\
-+ BYTE_REG_BITS_ON(MIBCR_MPTRINI,&((regs)->MIBCR));\
-+ for (i=0;i<HW_MIB_SIZE;i++) {\
-+ (MIBs)[i]=readl(&((regs)->MIBData));\
-+ }\
- }
-
- #define mac_set_rx_thresh(regs, n) {\
-@@ -1218,17 +1225,184 @@
- writew(TRDCSR_WAK<<(n*4),&((regs)->TDCSRSet));\
- }
-
--static inline void mac_eeprom_reload(struct mac_regs __iomem * regs) {
-- int i=0;
-+enum velocity_cam_type {
-+ VELOCITY_VLAN_ID_CAM = 0,
-+ VELOCITY_MULTICAST_CAM
-+};
-
-- BYTE_REG_BITS_ON(EECSR_RELOAD,&(regs->EECSR));
-- do {
-- udelay(10);
-- if (i++>0x1000)
-- break;
-- } while (BYTE_REG_BITS_IS_ON(EECSR_RELOAD,&(regs->EECSR)));
-+/**
-+ * mac_get_cam_mask - Read a CAM mask
-+ * @regs: register block for this velocity
-+ * @mask: buffer to store mask
-+ * @cam_type: CAM to fetch
-+ *
-+ * Fetch the mask bits of the selected CAM and store them into the
-+ * provided mask buffer.
-+ */
-+
-+static inline void mac_get_cam_mask(struct mac_regs __iomem * regs, u8 * mask, enum velocity_cam_type cam_type)
-+{
-+ int i;
-+ /* Select CAM mask */
-+ BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
-+
-+ if (cam_type == VELOCITY_VLAN_ID_CAM)
-+ writeb(CAMADDR_VCAMSL, ®s->CAMADDR);
-+ else
-+ writeb(0, ®s->CAMADDR);
-+
-+ /* read mask */
-+ for (i = 0; i < 8; i++)
-+ *mask++ = readb(&(regs->MARCAM[i]));
-+
-+ /* disable CAMEN */
-+ writeb(0, ®s->CAMADDR);
-+
-+ /* Select mar */
-+ BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
-+
-+}
-+
-+/**
-+ * mac_set_cam_mask - Set a CAM mask
-+ * @regs: register block for this velocity
-+ * @mask: CAM mask to load
-+ * @cam_type: CAM to store
-+ *
-+ * Store a new mask into a CAM
-+ */
-+
-+static inline void mac_set_cam_mask(struct mac_regs __iomem * regs, u8 * mask, enum velocity_cam_type cam_type)
-+{
-+ int i;
-+ /* Select CAM mask */
-+ BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
-+
-+ if (cam_type == VELOCITY_VLAN_ID_CAM)
-+ writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL, ®s->CAMADDR);
-+ else
-+ writeb(CAMADDR_CAMEN, ®s->CAMADDR);
-+
-+ for (i = 0; i < 8; i++) {
-+ writeb(*mask++, &(regs->MARCAM[i]));
-+ }
-+ /* disable CAMEN */
-+ writeb(0, ®s->CAMADDR);
-+
-+ /* Select mar */
-+ BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
- }
-
-+/**
-+ * mac_set_cam - set CAM data
-+ * @regs: register block of this velocity
-+ * @idx: Cam index
-+ * @addr: 2 or 6 bytes of CAM data
-+ * @cam_type: CAM to load
-+ *
-+ * Load an address or vlan tag into a CAM
-+ */
-+
-+static inline void mac_set_cam(struct mac_regs __iomem * regs, int idx, u8 *addr, enum velocity_cam_type cam_type)
-+{
-+ int i;
-+
-+ /* Select CAM mask */
-+ BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
-+
-+ idx &= (64 - 1);
-+
-+ if (cam_type == VELOCITY_VLAN_ID_CAM)
-+ writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, ®s->CAMADDR);
-+ else
-+ writeb(CAMADDR_CAMEN | idx, ®s->CAMADDR);
-+
-+ if (cam_type == VELOCITY_VLAN_ID_CAM)
-+ writew(*((u16 *) addr), ®s->MARCAM[0]);
-+ else {
-+ for (i = 0; i < 6; i++) {
-+ writeb(*addr++, &(regs->MARCAM[i]));
-+ }
-+ }
-+ BYTE_REG_BITS_ON(CAMCR_CAMWR, ®s->CAMCR);
-+
-+ udelay(10);
-+
-+ writeb(0, ®s->CAMADDR);
-+
-+ /* Select mar */
-+ BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
-+}
-+
-+/**
-+ * mac_get_cam - fetch CAM data
-+ * @regs: register block of this velocity
-+ * @idx: Cam index
-+ * @addr: buffer to hold up to 6 bytes of CAM data
-+ * @cam_type: CAM to load
-+ *
-+ * Load an address or vlan tag from a CAM into the buffer provided by
-+ * the caller. VLAN tags are 2 bytes the address cam entries are 6.
-+ */
-+
-+static inline void mac_get_cam(struct mac_regs __iomem * regs, int idx, u8 *addr, enum velocity_cam_type cam_type)
-+{
-+ int i;
-+
-+ /* Select CAM mask */
-+ BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
-+
-+ idx &= (64 - 1);
-+
-+ if (cam_type == VELOCITY_VLAN_ID_CAM)
-+ writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, ®s->CAMADDR);
-+ else
-+ writeb(CAMADDR_CAMEN | idx, ®s->CAMADDR);
-+
-+ BYTE_REG_BITS_ON(CAMCR_CAMRD, ®s->CAMCR);
-+
-+ udelay(10);
-+
-+ if (cam_type == VELOCITY_VLAN_ID_CAM)
-+ *((u16 *) addr) = readw(&(regs->MARCAM[0]));
-+ else
-+ for (i = 0; i < 6; i++, addr++)
-+ *((u8 *) addr) = readb(&(regs->MARCAM[i]));
-+
-+ writeb(0, ®s->CAMADDR);
-+
-+ /* Select mar */
-+ BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
-+}
-+
-+/**
-+ * mac_wol_reset - reset WOL after exiting low power
-+ * @regs: register block of this velocity
-+ *
-+ * Called after we drop out of wake on lan mode in order to
-+ * reset the Wake on lan features. This function doesn't restore
-+ * the rest of the logic from the result of sleep/wakeup
-+ */
-+
-+static inline void mac_wol_reset(struct mac_regs __iomem * regs)
-+{
-+
-+ /* Turn off SWPTAG right after leaving power mode */
-+ BYTE_REG_BITS_OFF(STICKHW_SWPTAG, ®s->STICKHW);
-+ /* clear sticky bits */
-+ BYTE_REG_BITS_OFF((STICKHW_DS1 | STICKHW_DS0), ®s->STICKHW);
-+
-+ BYTE_REG_BITS_OFF(CHIPGCR_FCGMII, ®s->CHIPGCR);
-+ BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, ®s->CHIPGCR);
-+ /* disable force PME-enable */
-+ writeb(WOLCFG_PMEOVR, ®s->WOLCFGClr);
-+ /* disable power-event config bit */
-+ writew(0xFFFF, ®s->WOLCRClr);
-+ /* clear power status */
-+ writew(0xFFFF, ®s->WOLSRClr);
-+}
-+
-+
- /*
- * Header for WOL definitions. Used to compute hashes
- */
-@@ -1515,8 +1689,9 @@
- int numrx; /* Number of RX descriptors */
- int numtx; /* Number of TX descriptors */
- enum speed_opt spd_dpx; /* Media link mode */
--
-- int DMA_length; /* DMA length */
-+ int vid; /* vlan id */
-+ int DMA_length_100M; /* DMA length at 100Mb/s */
-+ int DMA_length_1000M; /* DMA length at 1Gb/s */
- int rx_thresh; /* RX_THRESH */
- int flow_cntl;
- int wol_opts; /* Wake on lan options */
-@@ -1541,7 +1716,6 @@
- dma_addr_t tx_bufs_dma;
- u8 *tx_bufs;
-
-- struct vlan_group *vlgrp;
- u8 ip_addr[4];
- enum chip_type chip_id;
-
-@@ -1578,7 +1752,6 @@
- int rx_buf_sz;
- u32 mii_status;
- u32 phy_id;
-- int multicast_limit;
-
- u8 vCAMmask[(VCAM_SIZE / 8)];
- u8 mCAMmask[(MCAM_SIZE / 8)];
-@@ -1623,32 +1796,6 @@
- }
-
- /**
-- * velocity_update_hw_mibs - fetch MIB counters from chip
-- * @vptr: velocity to update
-- *
-- * The velocity hardware keeps certain counters in the hardware
-- * side. We need to read these when the user asks for statistics
-- * or when they overflow (causing an interrupt). The read of the
-- * statistic clears it, so we keep running master counters in user
-- * space.
-- */
--
--static inline void velocity_update_hw_mibs(struct velocity_info *vptr)
--{
-- u32 tmp;
-- int i;
-- BYTE_REG_BITS_ON(MIBCR_MIBFLSH, &(vptr->mac_regs->MIBCR));
--
-- while (BYTE_REG_BITS_IS_ON(MIBCR_MIBFLSH, &(vptr->mac_regs->MIBCR)));
--
-- BYTE_REG_BITS_ON(MIBCR_MPTRINI, &(vptr->mac_regs->MIBCR));
-- for (i = 0; i < HW_MIB_SIZE; i++) {
-- tmp = readl(&(vptr->mac_regs->MIBData)) & 0x00FFFFFFUL;
-- vptr->mib_counter[i] += tmp;
-- }
--}
--
--/**
- * init_flow_control_register - set up flow control
- * @vptr: velocity to configure
- *
-diff -Nurd linux-2.6.24/drivers/net/wireless/b43/dma.c linux-2.6.24-oxe810/drivers/net/wireless/b43/dma.c
---- linux-2.6.24/drivers/net/wireless/b43/dma.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/wireless/b43/dma.c 2008-06-11 17:49:58.000000000 +0200
-@@ -165,7 +165,7 @@
- addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK);
- addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK)
- >> SSB_DMA_TRANSLATION_SHIFT;
-- addrhi |= ssb_dma_translation(ring->dev->dev);
-+ addrhi |= (ssb_dma_translation(ring->dev->dev) << 1);
- if (slot == ring->nr_slots - 1)
- ctl0 |= B43_DMA64_DCTL0_DTABLEEND;
- if (start)
-@@ -426,9 +426,21 @@
- static int alloc_ringmemory(struct b43_dmaring *ring)
- {
- struct device *dev = ring->dev->dev->dev;
-+ gfp_t flags = GFP_KERNEL;
-
-+ /* The specs call for 4K buffers for 30- and 32-bit DMA with 4K
-+ * alignment and 8K buffers for 64-bit DMA with 8K alignment. Testing
-+ * has shown that 4K is sufficient for the latter as long as the buffer
-+ * does not cross an 8K boundary.
-+ *
-+ * For unknown reasons - possibly a hardware error - the BCM4311 rev
-+ * 02, which uses 64-bit DMA, needs the ring buffer in very low memory,
-+ * which accounts for the GFP_DMA flag below.
-+ */
-+ if (ring->dma64)
-+ flags |= GFP_DMA;
- ring->descbase = dma_alloc_coherent(dev, B43_DMA_RINGMEMSIZE,
-- &(ring->dmabase), GFP_KERNEL);
-+ &(ring->dmabase), flags);
- if (!ring->descbase) {
- b43err(ring->dev->wl, "DMA ringmemory allocation failed\n");
- return -ENOMEM;
-@@ -483,7 +495,7 @@
- return 0;
- }
-
--/* Reset the RX DMA channel */
-+/* Reset the TX DMA channel */
- int b43_dmacontroller_tx_reset(struct b43_wldev *dev, u16 mmio_base, int dma64)
- {
- int i;
-@@ -647,7 +659,7 @@
- b43_dma_write(ring, B43_DMA64_TXRINGHI,
- ((ringbase >> 32) &
- ~SSB_DMA_TRANSLATION_MASK)
-- | trans);
-+ | (trans << 1));
- } else {
- u32 ringbase = (u32) (ring->dmabase);
-
-@@ -680,8 +692,9 @@
- b43_dma_write(ring, B43_DMA64_RXRINGHI,
- ((ringbase >> 32) &
- ~SSB_DMA_TRANSLATION_MASK)
-- | trans);
-- b43_dma_write(ring, B43_DMA64_RXINDEX, 200);
-+ | (trans << 1));
-+ b43_dma_write(ring, B43_DMA64_RXINDEX, ring->nr_slots *
-+ sizeof(struct b43_dmadesc64));
- } else {
- u32 ringbase = (u32) (ring->dmabase);
-
-@@ -695,11 +708,12 @@
- b43_dma_write(ring, B43_DMA32_RXRING,
- (ringbase & ~SSB_DMA_TRANSLATION_MASK)
- | trans);
-- b43_dma_write(ring, B43_DMA32_RXINDEX, 200);
-+ b43_dma_write(ring, B43_DMA32_RXINDEX, ring->nr_slots *
-+ sizeof(struct b43_dmadesc32));
- }
- }
-
-- out:
-+out:
- return err;
- }
-
-@@ -1106,7 +1120,7 @@
- {
- const struct b43_dma_ops *ops = ring->ops;
- u8 *header;
-- int slot;
-+ int slot, old_top_slot, old_used_slots;
- int err;
- struct b43_dmadesc_generic *desc;
- struct b43_dmadesc_meta *meta;
-@@ -1116,20 +1130,31 @@
- #define SLOTS_PER_PACKET 2
- B43_WARN_ON(skb_shinfo(skb)->nr_frags);
-
-+ old_top_slot = ring->current_slot;
-+ old_used_slots = ring->used_slots;
-+
- /* Get a slot for the header. */
- slot = request_slot(ring);
- desc = ops->idx2desc(ring, slot, &meta_hdr);
- memset(meta_hdr, 0, sizeof(*meta_hdr));
-
- header = &(ring->txhdr_cache[slot * sizeof(struct b43_txhdr_fw4)]);
-- b43_generate_txhdr(ring->dev, header,
-+ err = b43_generate_txhdr(ring->dev, header,
- skb->data, skb->len, ctl,
- generate_cookie(ring, slot));
-+ if (unlikely(err)) {
-+ ring->current_slot = old_top_slot;
-+ ring->used_slots = old_used_slots;
-+ return err;
-+ }
-
- meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header,
- sizeof(struct b43_txhdr_fw4), 1);
-- if (dma_mapping_error(meta_hdr->dmaaddr))
-+ if (dma_mapping_error(meta_hdr->dmaaddr)) {
-+ ring->current_slot = old_top_slot;
-+ ring->used_slots = old_used_slots;
- return -EIO;
-+ }
- ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr,
- sizeof(struct b43_txhdr_fw4), 1, 0, 0);
-
-@@ -1147,6 +1172,8 @@
- if (dma_mapping_error(meta->dmaaddr)) {
- bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
- if (!bounce_skb) {
-+ ring->current_slot = old_top_slot;
-+ ring->used_slots = old_used_slots;
- err = -ENOMEM;
- goto out_unmap_hdr;
- }
-@@ -1157,6 +1184,8 @@
- meta->skb = skb;
- meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
- if (dma_mapping_error(meta->dmaaddr)) {
-+ ring->current_slot = old_top_slot;
-+ ring->used_slots = old_used_slots;
- err = -EIO;
- goto out_free_bounce;
- }
-@@ -1219,6 +1248,13 @@
- B43_WARN_ON(ring->stopped);
-
- err = dma_tx_fragment(ring, skb, ctl);
-+ if (unlikely(err == -ENOKEY)) {
-+ /* Drop this packet, as we don't have the encryption key
-+ * anymore and must not transmit it unencrypted. */
-+ dev_kfree_skb_any(skb);
-+ err = 0;
-+ goto out_unlock;
-+ }
- if (unlikely(err)) {
- b43err(dev->wl, "DMA tx mapping failure\n");
- goto out_unlock;
-diff -Nurd linux-2.6.24/drivers/net/wireless/b43/main.c linux-2.6.24-oxe810/drivers/net/wireless/b43/main.c
---- linux-2.6.24/drivers/net/wireless/b43/main.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/wireless/b43/main.c 2008-06-11 17:49:58.000000000 +0200
-@@ -101,6 +101,7 @@
- SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 7),
- SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 9),
- SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10),
-+ SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13),
- SSB_DEVTABLE_END
- };
-
-@@ -1800,6 +1801,18 @@
- err = -EOPNOTSUPP;
- goto out;
- }
-+ if (fwrev > 351) {
-+ b43err(dev->wl, "YOUR FIRMWARE IS TOO NEW. Please downgrade your "
-+ "firmware.\n");
-+ b43err(dev->wl, "Use this firmware tarball: "
-+ "http://downloads.openwrt.org/sources/broadcom-wl-4.80.53.0.tar.bz2\n");
-+ b43err(dev->wl, "Use this b43-fwcutter tarball: "
-+ "http://bu3sch.de/b43/fwcutter/b43-fwcutter-009.tar.bz2\n");
-+ b43err(dev->wl, "Read, understand and _do_ what this message says, please.\n");
-+ b43_write32(dev, B43_MMIO_MACCTL, 0);
-+ err = -EOPNOTSUPP;
-+ goto out;
-+ }
- b43dbg(dev->wl, "Loading firmware version %u.%u "
- "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
- fwrev, fwpatch,
-@@ -3067,7 +3080,7 @@
- unsupported = 1;
- break;
- case B43_PHYTYPE_G:
-- if (phy_rev > 8)
-+ if (phy_rev > 9)
- unsupported = 1;
- break;
- default:
-@@ -3395,8 +3408,6 @@
- b43_bluetooth_coext_enable(dev);
-
- ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */
-- memset(wl->bssid, 0, ETH_ALEN);
-- memset(wl->mac_addr, 0, ETH_ALEN);
- b43_upload_card_macaddress(dev);
- b43_security_init(dev);
- b43_rng_init(wl);
-@@ -3493,6 +3504,13 @@
- int did_init = 0;
- int err = 0;
-
-+ /* Kill all old instance specific information to make sure
-+ * the card won't use it in the short timeframe between start
-+ * and mac80211 reconfiguring it. */
-+ memset(wl->bssid, 0, ETH_ALEN);
-+ memset(wl->mac_addr, 0, ETH_ALEN);
-+ wl->filter_flags = 0;
-+
- /* First register RFkill.
- * LEDs that are registered later depend on it. */
- b43_rfkill_init(dev);
-diff -Nurd linux-2.6.24/drivers/net/wireless/b43/xmit.c linux-2.6.24-oxe810/drivers/net/wireless/b43/xmit.c
---- linux-2.6.24/drivers/net/wireless/b43/xmit.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/wireless/b43/xmit.c 2008-06-11 17:49:58.000000000 +0200
-@@ -177,7 +177,7 @@
- return 0;
- }
-
--static void generate_txhdr_fw4(struct b43_wldev *dev,
-+static int generate_txhdr_fw4(struct b43_wldev *dev,
- struct b43_txhdr_fw4 *txhdr,
- const unsigned char *fragment_data,
- unsigned int fragment_len,
-@@ -235,7 +235,15 @@
-
- B43_WARN_ON(key_idx >= dev->max_nr_keys);
- key = &(dev->key[key_idx]);
-- B43_WARN_ON(!key->keyconf);
-+
-+ if (unlikely(!key->keyconf)) {
-+ /* This key is invalid. This might only happen
-+ * in a short timeframe after machine resume before
-+ * we were able to reconfigure keys.
-+ * Drop this packet completely. Do not transmit it
-+ * unencrypted to avoid leaking information. */
-+ return -ENOKEY;
-+ }
-
- /* Hardware appends ICV. */
- plcp_fragment_len += txctl->icv_len;
-@@ -352,16 +360,18 @@
- txhdr->mac_ctl = cpu_to_le32(mac_ctl);
- txhdr->phy_ctl = cpu_to_le16(phy_ctl);
- txhdr->extra_ft = extra_ft;
-+
-+ return 0;
- }
-
--void b43_generate_txhdr(struct b43_wldev *dev,
-+int b43_generate_txhdr(struct b43_wldev *dev,
- u8 * txhdr,
- const unsigned char *fragment_data,
- unsigned int fragment_len,
- const struct ieee80211_tx_control *txctl, u16 cookie)
- {
-- generate_txhdr_fw4(dev, (struct b43_txhdr_fw4 *)txhdr,
-- fragment_data, fragment_len, txctl, cookie);
-+ return generate_txhdr_fw4(dev, (struct b43_txhdr_fw4 *)txhdr,
-+ fragment_data, fragment_len, txctl, cookie);
- }
-
- static s8 b43_rssi_postprocess(struct b43_wldev *dev,
-diff -Nurd linux-2.6.24/drivers/net/wireless/b43/xmit.h linux-2.6.24-oxe810/drivers/net/wireless/b43/xmit.h
---- linux-2.6.24/drivers/net/wireless/b43/xmit.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/wireless/b43/xmit.h 2008-06-11 17:49:58.000000000 +0200
-@@ -82,7 +82,7 @@
- #define B43_TX4_PHY_ANT1 0x0100 /* Use antenna 1 */
- #define B43_TX4_PHY_ANTLAST 0x0300 /* Use last used antenna */
-
--void b43_generate_txhdr(struct b43_wldev *dev,
-+int b43_generate_txhdr(struct b43_wldev *dev,
- u8 * txhdr,
- const unsigned char *fragment_data,
- unsigned int fragment_len,
-diff -Nurd linux-2.6.24/drivers/net/wireless/b43legacy/dma.c linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/dma.c
---- linux-2.6.24/drivers/net/wireless/b43legacy/dma.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/dma.c 2008-06-11 17:49:57.000000000 +0200
-@@ -1164,7 +1164,7 @@
- {
- const struct b43legacy_dma_ops *ops = ring->ops;
- u8 *header;
-- int slot;
-+ int slot, old_top_slot, old_used_slots;
- int err;
- struct b43legacy_dmadesc_generic *desc;
- struct b43legacy_dmadesc_meta *meta;
-@@ -1174,6 +1174,9 @@
- #define SLOTS_PER_PACKET 2
- B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags != 0);
-
-+ old_top_slot = ring->current_slot;
-+ old_used_slots = ring->used_slots;
-+
- /* Get a slot for the header. */
- slot = request_slot(ring);
- desc = ops->idx2desc(ring, slot, &meta_hdr);
-@@ -1181,9 +1184,14 @@
-
- header = &(ring->txhdr_cache[slot * sizeof(
- struct b43legacy_txhdr_fw3)]);
-- b43legacy_generate_txhdr(ring->dev, header,
-+ err = b43legacy_generate_txhdr(ring->dev, header,
- skb->data, skb->len, ctl,
- generate_cookie(ring, slot));
-+ if (unlikely(err)) {
-+ ring->current_slot = old_top_slot;
-+ ring->used_slots = old_used_slots;
-+ return err;
-+ }
-
- meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header,
- sizeof(struct b43legacy_txhdr_fw3), 1);
-@@ -1206,6 +1214,8 @@
- if (dma_mapping_error(meta->dmaaddr)) {
- bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
- if (!bounce_skb) {
-+ ring->current_slot = old_top_slot;
-+ ring->used_slots = old_used_slots;
- err = -ENOMEM;
- goto out_unmap_hdr;
- }
-@@ -1216,6 +1226,8 @@
- meta->skb = skb;
- meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
- if (dma_mapping_error(meta->dmaaddr)) {
-+ ring->current_slot = old_top_slot;
-+ ring->used_slots = old_used_slots;
- err = -EIO;
- goto out_free_bounce;
- }
-@@ -1282,6 +1294,13 @@
- B43legacy_BUG_ON(ring->stopped);
-
- err = dma_tx_fragment(ring, skb, ctl);
-+ if (unlikely(err == -ENOKEY)) {
-+ /* Drop this packet, as we don't have the encryption key
-+ * anymore and must not transmit it unencrypted. */
-+ dev_kfree_skb_any(skb);
-+ err = 0;
-+ goto out_unlock;
-+ }
- if (unlikely(err)) {
- b43legacyerr(dev->wl, "DMA tx mapping failure\n");
- goto out_unlock;
-diff -Nurd linux-2.6.24/drivers/net/wireless/b43legacy/main.c linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/main.c
---- linux-2.6.24/drivers/net/wireless/b43legacy/main.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/main.c 2008-06-11 17:49:57.000000000 +0200
-@@ -3215,8 +3215,6 @@
- b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, 0x0414, 0x01F4);
-
- ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */
-- memset(wl->bssid, 0, ETH_ALEN);
-- memset(wl->mac_addr, 0, ETH_ALEN);
- b43legacy_upload_card_macaddress(dev);
- b43legacy_security_init(dev);
- b43legacy_rng_init(wl);
-@@ -3311,6 +3309,13 @@
- int did_init = 0;
- int err = 0;
-
-+ /* Kill all old instance specific information to make sure
-+ * the card won't use it in the short timeframe between start
-+ * and mac80211 reconfiguring it. */
-+ memset(wl->bssid, 0, ETH_ALEN);
-+ memset(wl->mac_addr, 0, ETH_ALEN);
-+ wl->filter_flags = 0;
-+
- mutex_lock(&wl->mutex);
-
- if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) {
-diff -Nurd linux-2.6.24/drivers/net/wireless/b43legacy/pio.c linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/pio.c
---- linux-2.6.24/drivers/net/wireless/b43legacy/pio.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/pio.c 2008-06-11 17:49:57.000000000 +0200
-@@ -181,7 +181,7 @@
- struct b43legacy_txhdr_fw3 txhdr_fw3;
- };
-
--static void pio_tx_write_fragment(struct b43legacy_pioqueue *queue,
-+static int pio_tx_write_fragment(struct b43legacy_pioqueue *queue,
- struct sk_buff *skb,
- struct b43legacy_pio_txpacket *packet,
- size_t txhdr_size)
-@@ -189,14 +189,17 @@
- union txhdr_union txhdr_data;
- u8 *txhdr = NULL;
- unsigned int octets;
-+ int err;
-
- txhdr = (u8 *)(&txhdr_data.txhdr_fw3);
-
- B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags != 0);
-- b43legacy_generate_txhdr(queue->dev,
-+ err = b43legacy_generate_txhdr(queue->dev,
- txhdr, skb->data, skb->len,
- &packet->txstat.control,
- generate_cookie(queue, packet));
-+ if (err)
-+ return err;
-
- tx_start(queue);
- octets = skb->len + txhdr_size;
-@@ -204,6 +207,8 @@
- octets--;
- tx_data(queue, txhdr, (u8 *)skb->data, octets);
- tx_complete(queue, skb);
-+
-+ return 0;
- }
-
- static void free_txpacket(struct b43legacy_pio_txpacket *packet,
-@@ -226,6 +231,7 @@
- struct b43legacy_pioqueue *queue = packet->queue;
- struct sk_buff *skb = packet->skb;
- u16 octets;
-+ int err;
-
- octets = (u16)skb->len + sizeof(struct b43legacy_txhdr_fw3);
- if (queue->tx_devq_size < octets) {
-@@ -247,8 +253,14 @@
- if (queue->tx_devq_used + octets > queue->tx_devq_size)
- return -EBUSY;
- /* Now poke the device. */
-- pio_tx_write_fragment(queue, skb, packet,
-+ err = pio_tx_write_fragment(queue, skb, packet,
- sizeof(struct b43legacy_txhdr_fw3));
-+ if (unlikely(err == -ENOKEY)) {
-+ /* Drop this packet, as we don't have the encryption key
-+ * anymore and must not transmit it unencrypted. */
-+ free_txpacket(packet, 1);
-+ return 0;
-+ }
-
- /* Account for the packet size.
- * (We must not overflow the device TX queue)
-@@ -486,6 +498,9 @@
- queue = parse_cookie(dev, status->cookie, &packet);
- B43legacy_WARN_ON(!queue);
-
-+ if (!packet->skb)
-+ return;
-+
- queue->tx_devq_packets--;
- queue->tx_devq_used -= (packet->skb->len +
- sizeof(struct b43legacy_txhdr_fw3));
-diff -Nurd linux-2.6.24/drivers/net/wireless/b43legacy/xmit.c linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/xmit.c
---- linux-2.6.24/drivers/net/wireless/b43legacy/xmit.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/xmit.c 2008-06-11 17:49:57.000000000 +0200
-@@ -181,7 +181,7 @@
- return 0;
- }
-
--static void generate_txhdr_fw3(struct b43legacy_wldev *dev,
-+static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
- struct b43legacy_txhdr_fw3 *txhdr,
- const unsigned char *fragment_data,
- unsigned int fragment_len,
-@@ -252,6 +252,13 @@
- iv_len = min((size_t)txctl->iv_len,
- ARRAY_SIZE(txhdr->iv));
- memcpy(txhdr->iv, ((u8 *)wlhdr) + wlhdr_len, iv_len);
-+ } else {
-+ /* This key is invalid. This might only happen
-+ * in a short timeframe after machine resume before
-+ * we were able to reconfigure keys.
-+ * Drop this packet completely. Do not transmit it
-+ * unencrypted to avoid leaking information. */
-+ return -ENOKEY;
- }
- }
- b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *)
-@@ -344,16 +351,18 @@
- /* Apply the bitfields */
- txhdr->mac_ctl = cpu_to_le32(mac_ctl);
- txhdr->phy_ctl = cpu_to_le16(phy_ctl);
-+
-+ return 0;
- }
-
--void b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
-+int b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
- u8 *txhdr,
- const unsigned char *fragment_data,
- unsigned int fragment_len,
- const struct ieee80211_tx_control *txctl,
- u16 cookie)
- {
-- generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr,
-+ return generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr,
- fragment_data, fragment_len,
- txctl, cookie);
- }
-diff -Nurd linux-2.6.24/drivers/net/wireless/b43legacy/xmit.h linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/xmit.h
---- linux-2.6.24/drivers/net/wireless/b43legacy/xmit.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/xmit.h 2008-06-11 17:49:57.000000000 +0200
-@@ -76,7 +76,7 @@
-
-
-
--void b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
-+int b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
- u8 *txhdr,
- const unsigned char *fragment_data,
- unsigned int fragment_len,
-diff -Nurd linux-2.6.24/drivers/pci/hotplug/fakephp.c linux-2.6.24-oxe810/drivers/pci/hotplug/fakephp.c
---- linux-2.6.24/drivers/pci/hotplug/fakephp.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/pci/hotplug/fakephp.c 2008-06-11 17:49:28.000000000 +0200
-@@ -39,6 +39,7 @@
- #include <linux/init.h>
- #include <linux/string.h>
- #include <linux/slab.h>
-+#include <linux/workqueue.h>
- #include "../pci.h"
-
- #if !defined(MODULE)
-@@ -63,10 +64,16 @@
- struct list_head node;
- struct hotplug_slot *slot;
- struct pci_dev *dev;
-+ struct work_struct remove_work;
-+ unsigned long removed;
- };
-
- static int debug;
- static LIST_HEAD(slot_list);
-+static struct workqueue_struct *dummyphp_wq;
-+
-+static void pci_rescan_worker(struct work_struct *work);
-+static DECLARE_WORK(pci_rescan_work, pci_rescan_worker);
-
- static int enable_slot (struct hotplug_slot *slot);
- static int disable_slot (struct hotplug_slot *slot);
-@@ -109,7 +116,7 @@
- slot->name = &dev->dev.bus_id[0];
- dbg("slot->name = %s\n", slot->name);
-
-- dslot = kmalloc(sizeof(struct dummy_slot), GFP_KERNEL);
-+ dslot = kzalloc(sizeof(struct dummy_slot), GFP_KERNEL);
- if (!dslot)
- goto error_info;
-
-@@ -164,6 +171,14 @@
- err("Problem unregistering a slot %s\n", dslot->slot->name);
- }
-
-+/* called from the single-threaded workqueue handler to remove a slot */
-+static void remove_slot_worker(struct work_struct *work)
-+{
-+ struct dummy_slot *dslot =
-+ container_of(work, struct dummy_slot, remove_work);
-+ remove_slot(dslot);
-+}
-+
- /**
- * pci_rescan_slot - Rescan slot
- * @temp: Device template. Should be set: bus and devfn.
-@@ -267,11 +282,17 @@
- pci_rescan_buses(&pci_root_buses);
- }
-
-+/* called from the single-threaded workqueue handler to rescan all pci buses */
-+static void pci_rescan_worker(struct work_struct *work)
-+{
-+ pci_rescan();
-+}
-
- static int enable_slot(struct hotplug_slot *hotplug_slot)
- {
- /* mis-use enable_slot for rescanning of the pci bus */
-- pci_rescan();
-+ cancel_work_sync(&pci_rescan_work);
-+ queue_work(dummyphp_wq, &pci_rescan_work);
- return -ENODEV;
- }
-
-@@ -306,6 +327,10 @@
- err("Can't remove PCI devices with other PCI devices behind it yet.\n");
- return -ENODEV;
- }
-+ if (test_and_set_bit(0, &dslot->removed)) {
-+ dbg("Slot already scheduled for removal\n");
-+ return -ENODEV;
-+ }
- /* search for subfunctions and disable them first */
- if (!(dslot->dev->devfn & 7)) {
- for (func = 1; func < 8; func++) {
-@@ -328,8 +353,9 @@
- /* remove the device from the pci core */
- pci_remove_bus_device(dslot->dev);
-
-- /* blow away this sysfs entry and other parts. */
-- remove_slot(dslot);
-+ /* queue work item to blow away this sysfs entry and other parts. */
-+ INIT_WORK(&dslot->remove_work, remove_slot_worker);
-+ queue_work(dummyphp_wq, &dslot->remove_work);
-
- return 0;
- }
-@@ -340,6 +366,7 @@
- struct list_head *next;
- struct dummy_slot *dslot;
-
-+ destroy_workqueue(dummyphp_wq);
- list_for_each_safe (tmp, next, &slot_list) {
- dslot = list_entry (tmp, struct dummy_slot, node);
- remove_slot(dslot);
-@@ -351,6 +378,10 @@
- {
- info(DRIVER_DESC "\n");
-
-+ dummyphp_wq = create_singlethread_workqueue(MY_NAME);
-+ if (!dummyphp_wq)
-+ return -ENOMEM;
-+
- return pci_scan_buses();
- }
-
-diff -Nurd linux-2.6.24/drivers/pci/probe.c linux-2.6.24-oxe810/drivers/pci/probe.c
---- linux-2.6.24/drivers/pci/probe.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/pci/probe.c 2008-06-11 17:49:28.000000000 +0200
-@@ -991,8 +991,18 @@
- for (func = 0; func < 8; func++, devfn++) {
- struct pci_dev *dev;
-
-- dev = pci_scan_single_device(bus, devfn);
-- if (dev) {
-+#ifdef CONFIG_PCI_OXNAS_CARDBUS
-+ // printk(KERN_INFO "pci_scan_slot %u\n", PCI_SLOT(devfn) );
-+ scan_all_fns = 1;
-+ if ( PCI_SLOT(devfn) == 5 )
-+ dev = pci_scan_single_device(bus, devfn);
-+ else
-+ dev = 0;
-+#else /* ifndef CONFIG_OXNAS_CARDBUS */
-+ dev = pci_scan_single_device(bus, devfn);
-+#endif /* CONFIG_OXNAS_CARDBUS */
-+
-+ if (dev) {
- nr++;
-
- /*
-diff -Nurd linux-2.6.24/drivers/rtc/rtc-ds1307.c linux-2.6.24-oxe810/drivers/rtc/rtc-ds1307.c
---- linux-2.6.24/drivers/rtc/rtc-ds1307.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/rtc/rtc-ds1307.c 2008-06-11 17:49:41.000000000 +0200
-@@ -17,7 +17,7 @@
- #include <linux/rtc.h>
- #include <linux/bcd.h>
-
--
-+#define ACCEPT_UNINITIALIZED_DEVICE_IN_PROBE
-
- /* We can't determine type by probing, but if we expect pre-Linux code
- * to have set the chip up as a clock (turning on the oscillator and
-@@ -445,6 +445,7 @@
- break;
- }
-
-+#ifndef ACCEPT_UNINITIALIZED_DEVICE_IN_PROBE
- tmp = ds1307->regs[DS1307_REG_SECS];
- tmp = BCD2BIN(tmp & 0x7f);
- if (tmp > 60)
-@@ -460,6 +461,7 @@
- tmp = BCD2BIN(ds1307->regs[DS1307_REG_MONTH] & 0x1f);
- if (tmp == 0 || tmp > 12)
- goto exit_bad;
-+#endif // !ACCEPT_UNINITIALIZED_DEVICE_IN_PROBE
-
- tmp = ds1307->regs[DS1307_REG_HOUR];
- switch (ds1307->type) {
-diff -Nurd linux-2.6.24/drivers/s390/char/defkeymap.c linux-2.6.24-oxe810/drivers/s390/char/defkeymap.c
---- linux-2.6.24/drivers/s390/char/defkeymap.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/s390/char/defkeymap.c 2008-06-11 17:49:17.000000000 +0200
-@@ -151,8 +151,8 @@
- };
-
- struct kbdiacruc accent_table[MAX_DIACR] = {
-- {'^', 'c', '\003'}, {'^', 'd', '\004'},
-- {'^', 'z', '\032'}, {'^', '\012', '\000'},
-+ {'^', 'c', 0003}, {'^', 'd', 0004},
-+ {'^', 'z', 0032}, {'^', 0012, 0000},
- };
-
- unsigned int accent_table_size = 4;
-diff -Nurd linux-2.6.24/drivers/scsi/Kconfig linux-2.6.24-oxe810/drivers/scsi/Kconfig
---- linux-2.6.24/drivers/scsi/Kconfig 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/Kconfig 2008-06-11 17:50:29.000000000 +0200
-@@ -556,6 +556,15 @@
- To compile this driver as a module, choose M here: the
- module will be called arcmsr (modprobe arcmsr).
-
-+config SCSI_SATA_DISK_DETECTION_TENACITY
-+ int "The number of attempts to detect a disk."
-+ default 1
-+ depends on SCSI_SATA
-+ help
-+ Sets the number of times taken to repeat a 700 ms process of detecting a disk. Some disks will not respond to detection until they have spun-up and they won't spin-up untill they receive some communication from the host.
-+
-+ If unsure, use 1.
-+
- config SCSI_ARCMSR_AER
- bool "Enable PCI Error Recovery Capability in Areca Driver(ARCMSR)"
- depends on SCSI_ARCMSR && PCIEAER
-diff -Nurd linux-2.6.24/drivers/scsi/advansys.c linux-2.6.24-oxe810/drivers/scsi/advansys.c
---- linux-2.6.24/drivers/scsi/advansys.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/advansys.c 2008-06-11 17:50:28.000000000 +0200
-@@ -566,7 +566,7 @@
- ASC_SCSI_BIT_ID_TYPE unit_not_ready;
- ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
- ASC_SCSI_BIT_ID_TYPE start_motor;
-- uchar overrun_buf[ASC_OVERRUN_BSIZE] __aligned(8);
-+ uchar *overrun_buf;
- dma_addr_t overrun_dma;
- uchar scsi_reset_wait;
- uchar chip_no;
-@@ -6439,7 +6439,7 @@
- i += 2;
- len += 2;
- } else {
-- unsigned char off = buf[i] * 2;
-+ unsigned int off = buf[i] * 2;
- unsigned short word = (buf[off + 1] << 8) | buf[off];
- AdvWriteWordAutoIncLram(iop_base, word);
- len += 2;
-@@ -13833,6 +13833,12 @@
- */
- if (ASC_NARROW_BOARD(boardp)) {
- ASC_DBG(2, "AscInitAsc1000Driver()\n");
-+
-+ asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL);
-+ if (!asc_dvc_varp->overrun_buf) {
-+ ret = -ENOMEM;
-+ goto err_free_wide_mem;
-+ }
- warn_code = AscInitAsc1000Driver(asc_dvc_varp);
-
- if (warn_code || asc_dvc_varp->err_code) {
-@@ -13840,8 +13846,10 @@
- "warn 0x%x, error 0x%x\n",
- asc_dvc_varp->init_state, warn_code,
- asc_dvc_varp->err_code);
-- if (asc_dvc_varp->err_code)
-+ if (asc_dvc_varp->err_code) {
- ret = -ENODEV;
-+ kfree(asc_dvc_varp->overrun_buf);
-+ }
- }
- } else {
- if (advansys_wide_init_chip(shost))
-@@ -13894,6 +13902,7 @@
- dma_unmap_single(board->dev,
- board->dvc_var.asc_dvc_var.overrun_dma,
- ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
-+ kfree(board->dvc_var.asc_dvc_var.overrun_buf);
- } else {
- iounmap(board->ioremap_addr);
- advansys_wide_free_mem(board);
-diff -Nurd linux-2.6.24/drivers/scsi/aic94xx/aic94xx_scb.c linux-2.6.24-oxe810/drivers/scsi/aic94xx/aic94xx_scb.c
---- linux-2.6.24/drivers/scsi/aic94xx/aic94xx_scb.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/aic94xx/aic94xx_scb.c 2008-06-11 17:50:27.000000000 +0200
-@@ -458,13 +458,19 @@
- tc_abort = le16_to_cpu(tc_abort);
-
- list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) {
-- struct sas_task *task = ascb->uldd_task;
-+ struct sas_task *task = a->uldd_task;
-
-- if (task && a->tc_index == tc_abort) {
-+ if (a->tc_index != tc_abort)
-+ continue;
-+
-+ if (task) {
- failed_dev = task->dev;
- sas_task_abort(task);
-- break;
-+ } else {
-+ ASD_DPRINTK("R_T_A for non TASK scb 0x%x\n",
-+ a->scb->header.opcode);
- }
-+ break;
- }
-
- if (!failed_dev) {
-@@ -478,7 +484,7 @@
- * that the EH will wake up and do something.
- */
- list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) {
-- struct sas_task *task = ascb->uldd_task;
-+ struct sas_task *task = a->uldd_task;
-
- if (task &&
- task->dev == failed_dev &&
-diff -Nurd linux-2.6.24/drivers/scsi/arcmsr/arcmsr_hba.c linux-2.6.24-oxe810/drivers/scsi/arcmsr/arcmsr_hba.c
---- linux-2.6.24/drivers/scsi/arcmsr/arcmsr_hba.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/arcmsr/arcmsr_hba.c 2008-06-11 17:50:28.000000000 +0200
-@@ -1380,17 +1380,16 @@
- switch(controlcode) {
-
- case ARCMSR_MESSAGE_READ_RQBUFFER: {
-- unsigned long *ver_addr;
-- dma_addr_t buf_handle;
-+ unsigned char *ver_addr;
- uint8_t *pQbuffer, *ptmpQbuffer;
- int32_t allxfer_len = 0;
-
-- ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle);
-+ ver_addr = kmalloc(1032, GFP_ATOMIC);
- if (!ver_addr) {
- retvalue = ARCMSR_MESSAGE_FAIL;
- goto message_out;
- }
-- ptmpQbuffer = (uint8_t *) ver_addr;
-+ ptmpQbuffer = ver_addr;
- while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
- && (allxfer_len < 1031)) {
- pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
-@@ -1419,25 +1418,24 @@
- }
- arcmsr_iop_message_read(acb);
- }
-- memcpy(pcmdmessagefld->messagedatabuffer, (uint8_t *)ver_addr, allxfer_len);
-+ memcpy(pcmdmessagefld->messagedatabuffer, ver_addr, allxfer_len);
- pcmdmessagefld->cmdmessage.Length = allxfer_len;
- pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
-- pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle);
-+ kfree(ver_addr);
- }
- break;
-
- case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
-- unsigned long *ver_addr;
-- dma_addr_t buf_handle;
-+ unsigned char *ver_addr;
- int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
- uint8_t *pQbuffer, *ptmpuserbuffer;
-
-- ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle);
-+ ver_addr = kmalloc(1032, GFP_ATOMIC);
- if (!ver_addr) {
- retvalue = ARCMSR_MESSAGE_FAIL;
- goto message_out;
- }
-- ptmpuserbuffer = (uint8_t *)ver_addr;
-+ ptmpuserbuffer = ver_addr;
- user_len = pcmdmessagefld->cmdmessage.Length;
- memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len);
- wqbuf_lastindex = acb->wqbuf_lastindex;
-@@ -1483,7 +1481,7 @@
- retvalue = ARCMSR_MESSAGE_FAIL;
- }
- }
-- pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle);
-+ kfree(ver_addr);
- }
- break;
-
-diff -Nurd linux-2.6.24/drivers/scsi/gdth.c linux-2.6.24-oxe810/drivers/scsi/gdth.c
---- linux-2.6.24/drivers/scsi/gdth.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/gdth.c 2008-06-11 17:50:29.000000000 +0200
-@@ -160,7 +160,7 @@
- static void gdth_clear_events(void);
-
- static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
-- char *buffer, ushort count, int to_buffer);
-+ char *buffer, ushort count);
- static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp);
- static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive);
-
-@@ -183,7 +183,6 @@
- unsigned int cmd, unsigned long arg);
-
- static void gdth_flush(gdth_ha_str *ha);
--static int gdth_halt(struct notifier_block *nb, ulong event, void *buf);
- static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *));
- static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp,
- struct gdth_cmndinfo *cmndinfo);
-@@ -418,12 +417,6 @@
- #include "gdth_proc.h"
- #include "gdth_proc.c"
-
--/* notifier block to get a notify on system shutdown/halt/reboot */
--static struct notifier_block gdth_notifier = {
-- gdth_halt, NULL, 0
--};
--static int notifier_disabled = 0;
--
- static gdth_ha_str *gdth_find_ha(int hanum)
- {
- gdth_ha_str *ha;
-@@ -446,8 +439,8 @@
- for (i=0; i<GDTH_MAXCMDS; ++i) {
- if (ha->cmndinfo[i].index == 0) {
- priv = &ha->cmndinfo[i];
-- priv->index = i+1;
- memset(priv, 0, sizeof(*priv));
-+ priv->index = i+1;
- break;
- }
- }
-@@ -494,7 +487,6 @@
- gdth_ha_str *ha = shost_priv(sdev->host);
- Scsi_Cmnd *scp;
- struct gdth_cmndinfo cmndinfo;
-- struct scatterlist one_sg;
- DECLARE_COMPLETION_ONSTACK(wait);
- int rval;
-
-@@ -508,13 +500,10 @@
- /* use request field to save the ptr. to completion struct. */
- scp->request = (struct request *)&wait;
- scp->timeout_per_command = timeout*HZ;
-- sg_init_one(&one_sg, gdtcmd, sizeof(*gdtcmd));
-- gdth_set_sglist(scp, &one_sg);
-- gdth_set_sg_count(scp, 1);
-- gdth_set_bufflen(scp, sizeof(*gdtcmd));
- scp->cmd_len = 12;
- memcpy(scp->cmnd, cmnd, 12);
- cmndinfo.priority = IOCTL_PRI;
-+ cmndinfo.internal_cmd_str = gdtcmd;
- cmndinfo.internal_command = 1;
-
- TRACE(("__gdth_execute() cmd 0x%x\n", scp->cmnd[0]));
-@@ -2355,7 +2344,7 @@
- * buffers, kmap_atomic() as needed.
- */
- static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
-- char *buffer, ushort count, int to_buffer)
-+ char *buffer, ushort count)
- {
- ushort cpcount,i, max_sg = gdth_sg_count(scp);
- ushort cpsum,cpnow;
-@@ -2381,10 +2370,7 @@
- }
- local_irq_save(flags);
- address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset;
-- if (to_buffer)
-- memcpy(buffer, address, cpnow);
-- else
-- memcpy(address, buffer, cpnow);
-+ memcpy(address, buffer, cpnow);
- flush_dcache_page(sg_page(sl));
- kunmap_atomic(address, KM_BIO_SRC_IRQ);
- local_irq_restore(flags);
-@@ -2438,7 +2424,7 @@
- strcpy(inq.vendor,ha->oem_name);
- sprintf(inq.product,"Host Drive #%02d",t);
- strcpy(inq.revision," ");
-- gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data), 0);
-+ gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data));
- break;
-
- case REQUEST_SENSE:
-@@ -2448,7 +2434,7 @@
- sd.key = NO_SENSE;
- sd.info = 0;
- sd.add_length= 0;
-- gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data), 0);
-+ gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data));
- break;
-
- case MODE_SENSE:
-@@ -2460,7 +2446,7 @@
- mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16;
- mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8;
- mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff);
-- gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data), 0);
-+ gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data));
- break;
-
- case READ_CAPACITY:
-@@ -2470,7 +2456,7 @@
- else
- rdc.last_block_no = cpu_to_be32(ha->hdr[t].size-1);
- rdc.block_length = cpu_to_be32(SECTOR_SIZE);
-- gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data), 0);
-+ gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data));
- break;
-
- case SERVICE_ACTION_IN:
-@@ -2482,7 +2468,7 @@
- rdc16.last_block_no = cpu_to_be64(ha->hdr[t].size-1);
- rdc16.block_length = cpu_to_be32(SECTOR_SIZE);
- gdth_copy_internal_data(ha, scp, (char*)&rdc16,
-- sizeof(gdth_rdcap16_data), 0);
-+ sizeof(gdth_rdcap16_data));
- } else {
- scp->result = DID_ABORT << 16;
- }
-@@ -2852,6 +2838,7 @@
- static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
- {
- register gdth_cmd_str *cmdp;
-+ struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);
- int cmd_index;
-
- cmdp= ha->pccb;
-@@ -2860,7 +2847,7 @@
- if (ha->type==GDT_EISA && ha->cmd_cnt>0)
- return 0;
-
-- gdth_copy_internal_data(ha, scp, (char *)cmdp, sizeof(gdth_cmd_str), 1);
-+ *cmdp = *cmndinfo->internal_cmd_str;
- cmdp->RequestBuffer = scp;
-
- /* search free command index */
-@@ -3793,6 +3780,8 @@
- gdth_ha_str *ha;
- ulong flags;
-
-+ BUG_ON(list_empty(&gdth_instances));
-+
- ha = list_first_entry(&gdth_instances, gdth_ha_str, list);
- spin_lock_irqsave(&ha->smp_lock, flags);
-
-@@ -4668,45 +4657,6 @@
- }
- }
-
--/* shutdown routine */
--static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
--{
-- gdth_ha_str *ha;
--#ifndef __alpha__
-- gdth_cmd_str gdtcmd;
-- char cmnd[MAX_COMMAND_SIZE];
--#endif
--
-- if (notifier_disabled)
-- return NOTIFY_OK;
--
-- TRACE2(("gdth_halt() event %d\n",(int)event));
-- if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF)
-- return NOTIFY_DONE;
--
-- notifier_disabled = 1;
-- printk("GDT-HA: Flushing all host drives .. ");
-- list_for_each_entry(ha, &gdth_instances, list) {
-- gdth_flush(ha);
--
--#ifndef __alpha__
-- /* controller reset */
-- memset(cmnd, 0xff, MAX_COMMAND_SIZE);
-- gdtcmd.BoardNode = LOCALBOARD;
-- gdtcmd.Service = CACHESERVICE;
-- gdtcmd.OpCode = GDT_RESET;
-- TRACE2(("gdth_halt(): reset controller %d\n", ha->hanum));
-- gdth_execute(ha->shost, &gdtcmd, cmnd, 10, NULL);
--#endif
-- }
-- printk("Done.\n");
--
--#ifdef GDTH_STATISTICS
-- del_timer(&gdth_timer);
--#endif
-- return NOTIFY_OK;
--}
--
- /* configure lun */
- static int gdth_slave_configure(struct scsi_device *sdev)
- {
-@@ -4838,6 +4788,9 @@
- if (error)
- goto out_free_coal_stat;
- list_add_tail(&ha->list, &gdth_instances);
-+
-+ scsi_scan_host(shp);
-+
- return 0;
-
- out_free_coal_stat:
-@@ -4965,6 +4918,9 @@
- if (error)
- goto out_free_coal_stat;
- list_add_tail(&ha->list, &gdth_instances);
-+
-+ scsi_scan_host(shp);
-+
- return 0;
-
- out_free_ccb_phys:
-@@ -5102,6 +5058,9 @@
- if (error)
- goto out_free_coal_stat;
- list_add_tail(&ha->list, &gdth_instances);
-+
-+ scsi_scan_host(shp);
-+
- return 0;
-
- out_free_coal_stat:
-@@ -5132,13 +5091,13 @@
-
- scsi_remove_host(shp);
-
-+ gdth_flush(ha);
-+
- if (ha->sdev) {
- scsi_free_host_dev(ha->sdev);
- ha->sdev = NULL;
- }
-
-- gdth_flush(ha);
--
- if (shp->irq)
- free_irq(shp->irq,ha);
-
-@@ -5164,6 +5123,24 @@
- scsi_host_put(shp);
- }
-
-+static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
-+{
-+ gdth_ha_str *ha;
-+
-+ TRACE2(("gdth_halt() event %d\n", (int)event));
-+ if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF)
-+ return NOTIFY_DONE;
-+
-+ list_for_each_entry(ha, &gdth_instances, list)
-+ gdth_flush(ha);
-+
-+ return NOTIFY_OK;
-+}
-+
-+static struct notifier_block gdth_notifier = {
-+ gdth_halt, NULL, 0
-+};
-+
- static int __init gdth_init(void)
- {
- if (disable) {
-@@ -5226,7 +5203,6 @@
- add_timer(&gdth_timer);
- #endif
- major = register_chrdev(0,"gdth", &gdth_fops);
-- notifier_disabled = 0;
- register_reboot_notifier(&gdth_notifier);
- gdth_polling = FALSE;
- return 0;
-@@ -5236,14 +5212,15 @@
- {
- gdth_ha_str *ha;
-
-- list_for_each_entry(ha, &gdth_instances, list)
-- gdth_remove_one(ha);
-+ unregister_chrdev(major, "gdth");
-+ unregister_reboot_notifier(&gdth_notifier);
-
- #ifdef GDTH_STATISTICS
-- del_timer(&gdth_timer);
-+ del_timer_sync(&gdth_timer);
- #endif
-- unregister_chrdev(major,"gdth");
-- unregister_reboot_notifier(&gdth_notifier);
-+
-+ list_for_each_entry(ha, &gdth_instances, list)
-+ gdth_remove_one(ha);
- }
-
- module_init(gdth_init);
-diff -Nurd linux-2.6.24/drivers/scsi/gdth.h linux-2.6.24-oxe810/drivers/scsi/gdth.h
---- linux-2.6.24/drivers/scsi/gdth.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/gdth.h 2008-06-11 17:50:29.000000000 +0200
-@@ -915,6 +915,7 @@
- struct gdth_cmndinfo { /* per-command private info */
- int index;
- int internal_command; /* don't call scsi_done */
-+ gdth_cmd_str *internal_cmd_str; /* crier for internal messages*/
- dma_addr_t sense_paddr; /* sense dma-addr */
- unchar priority;
- int timeout;
-diff -Nurd linux-2.6.24/drivers/scsi/gdth_proc.c linux-2.6.24-oxe810/drivers/scsi/gdth_proc.c
---- linux-2.6.24/drivers/scsi/gdth_proc.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/gdth_proc.c 2008-06-11 17:50:29.000000000 +0200
-@@ -694,15 +694,13 @@
- {
- ulong flags;
-
-- spin_lock_irqsave(&ha->smp_lock, flags);
--
- if (buf == ha->pscratch) {
-+ spin_lock_irqsave(&ha->smp_lock, flags);
- ha->scratch_busy = FALSE;
-+ spin_unlock_irqrestore(&ha->smp_lock, flags);
- } else {
- pci_free_consistent(ha->pdev, size, buf, paddr);
- }
--
-- spin_unlock_irqrestore(&ha->smp_lock, flags);
- }
-
- #ifdef GDTH_IOCTL_PROC
-diff -Nurd linux-2.6.24/drivers/scsi/ips.c linux-2.6.24-oxe810/drivers/scsi/ips.c
---- linux-2.6.24/drivers/scsi/ips.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/ips.c 2008-06-11 17:50:29.000000000 +0200
-@@ -1580,7 +1580,7 @@
- METHOD_TRACE("ips_make_passthru", 1);
-
- scsi_for_each_sg(SC, sg, scsi_sg_count(SC), i)
-- length += sg[i].length;
-+ length += sg->length;
-
- if (length < sizeof (ips_passthru_t)) {
- /* wrong size */
-@@ -6842,13 +6842,10 @@
- if (request_irq(ha->irq, do_ipsintr, IRQF_SHARED, ips_name, ha)) {
- IPS_PRINTK(KERN_WARNING, ha->pcidev,
- "Unable to install interrupt handler\n");
-- scsi_host_put(sh);
-- return -1;
-+ goto err_out_sh;
- }
-
- kfree(oldha);
-- ips_sh[index] = sh;
-- ips_ha[index] = ha;
-
- /* Store away needed values for later use */
- sh->io_port = ha->io_addr;
-@@ -6867,10 +6864,21 @@
- sh->max_channel = ha->nbus - 1;
- sh->can_queue = ha->max_cmds - 1;
-
-- scsi_add_host(sh, NULL);
-+ if (scsi_add_host(sh, &ha->pcidev->dev))
-+ goto err_out;
-+
-+ ips_sh[index] = sh;
-+ ips_ha[index] = ha;
-+
- scsi_scan_host(sh);
-
- return 0;
-+
-+err_out:
-+ free_irq(ha->pcidev->irq, ha);
-+err_out_sh:
-+ scsi_host_put(sh);
-+ return -1;
- }
-
- /*---------------------------------------------------------------------------*/
-diff -Nurd linux-2.6.24/drivers/scsi/scsi_lib.c linux-2.6.24-oxe810/drivers/scsi/scsi_lib.c
---- linux-2.6.24/drivers/scsi/scsi_lib.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/scsi_lib.c 2008-06-11 17:50:29.000000000 +0200
-@@ -298,7 +298,6 @@
- page = sg_page(sg);
- off = sg->offset;
- len = sg->length;
-- data_len += len;
-
- while (len > 0 && data_len > 0) {
- /*
-diff -Nurd linux-2.6.24/drivers/scsi/sd.c linux-2.6.24-oxe810/drivers/scsi/sd.c
---- linux-2.6.24/drivers/scsi/sd.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/scsi/sd.c 2008-06-11 17:50:29.000000000 +0200
-@@ -907,6 +907,7 @@
- unsigned int xfer_size = SCpnt->request_bufflen;
- unsigned int good_bytes = result ? 0 : xfer_size;
- u64 start_lba = SCpnt->request->sector;
-+ u64 end_lba = SCpnt->request->sector + (xfer_size / 512);
- u64 bad_lba;
- struct scsi_sense_hdr sshdr;
- int sense_valid = 0;
-@@ -945,26 +946,23 @@
- goto out;
- if (xfer_size <= SCpnt->device->sector_size)
- goto out;
-- switch (SCpnt->device->sector_size) {
-- case 256:
-+ if (SCpnt->device->sector_size < 512) {
-+ /* only legitimate sector_size here is 256 */
- start_lba <<= 1;
-- break;
-- case 512:
-- break;
-- case 1024:
-- start_lba >>= 1;
-- break;
-- case 2048:
-- start_lba >>= 2;
-- break;
-- case 4096:
-- start_lba >>= 3;
-- break;
-- default:
-- /* Print something here with limiting frequency. */
-- goto out;
-- break;
-+ end_lba <<= 1;
-+ } else {
-+ /* be careful ... don't want any overflows */
-+ u64 factor = SCpnt->device->sector_size / 512;
-+ do_div(start_lba, factor);
-+ do_div(end_lba, factor);
- }
-+
-+ if (bad_lba < start_lba || bad_lba >= end_lba)
-+ /* the bad lba was reported incorrectly, we have
-+ * no idea where the error is
-+ */
-+ goto out;
-+
- /* This computation should always be done in terms of
- * the resolution of the device's medium.
- */
-diff -Nurd linux-2.6.24/drivers/serial/8250.c linux-2.6.24-oxe810/drivers/serial/8250.c
---- linux-2.6.24/drivers/serial/8250.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/serial/8250.c 2008-06-11 17:48:56.000000000 +0200
-@@ -2153,7 +2153,37 @@
- serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
- }
-
-- serial_dl_write(up, quot);
-+ if ((up->port.type == PORT_16550A) &&
-+ (serial_in(up, UART_XON_CHAR) == 0x11) &&
-+ (serial_in(up, UART_XOFF_CHAR) == 0x13))
-+ {
-+ /* We should now be dealing with an extended 16550A-type UART from
-+ * the Oxsemi 0x800 */
-+
-+ /* Calculate values for DLM,DLL,DLF divisor registers from clock
-+ * frequency in Hz and Baud rate in bits per second, and program them
-+ * into the UART */
-+ u32 tmp;
-+ u8 lcr, dlm, dll, dlf;
-+
-+ tmp = port->uartclk / baud;
-+ tmp = (tmp + 1) / 2;
-+ dlm = tmp >> (8 + 3);
-+ dll = (tmp >> 3) & 0xFF;
-+ dlf = (tmp & 7) << 5;
-+
-+ lcr = serial_in(up, UART_LSR); /* Store LCR */
-+
-+ serial_outp(up, UART_LCR, 0x80); /* Enable access to DLM DLL */
-+ serial_outp(up, UART_DLL, dll); /* LS of divisor */
-+ serial_outp(up, UART_DLM, dlm); /* MS of divisor */
-+ serial_outp(up, UART_DLF, dlf); /* Set non-standard fractional divisor */
-+ serial_outp(up, UART_LCR, lcr); /* Restore LCR */
-+
-+ printk(KERN_INFO "Using fractional divider baud %d, clock %d dlf %02x\n", baud, port->uartclk, dlf);
-+ } else {
-+ serial_dl_write(up, quot);
-+ }
-
- /*
- * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
-@@ -2519,7 +2549,11 @@
- static int __init serial8250_console_setup(struct console *co, char *options)
- {
- struct uart_port *port;
-- int baud = 9600;
-+#if defined (CONFIG_ARCH_OXNAS)
-+ int baud = 115200;
-+#else
-+ int baud = 9600;
-+#endif // defined (CONFIG_ARCH_OXNAS)
- int bits = 8;
- int parity = 'n';
- int flow = 'n';
-diff -Nurd linux-2.6.24/drivers/spi/atmel_spi.c linux-2.6.24-oxe810/drivers/spi/atmel_spi.c
---- linux-2.6.24/drivers/spi/atmel_spi.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/spi/atmel_spi.c 2008-06-11 17:49:13.000000000 +0200
-@@ -85,6 +85,16 @@
- unsigned gpio = (unsigned) spi->controller_data;
- unsigned active = spi->mode & SPI_CS_HIGH;
- u32 mr;
-+ int i;
-+ u32 csr;
-+ u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0;
-+
-+ /* Make sure clock polarity is correct */
-+ for (i = 0; i < spi->master->num_chipselect; i++) {
-+ csr = spi_readl(as, CSR0 + 4 * i);
-+ if ((csr ^ cpol) & SPI_BIT(CPOL))
-+ spi_writel(as, CSR0 + 4 * i, csr ^ SPI_BIT(CPOL));
-+ }
-
- mr = spi_readl(as, MR);
- mr = SPI_BFINS(PCS, ~(1 << spi->chip_select), mr);
-diff -Nurd linux-2.6.24/drivers/spi/pxa2xx_spi.c linux-2.6.24-oxe810/drivers/spi/pxa2xx_spi.c
---- linux-2.6.24/drivers/spi/pxa2xx_spi.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/spi/pxa2xx_spi.c 2008-06-11 17:49:13.000000000 +0200
-@@ -48,13 +48,19 @@
- #define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
- #define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0)
-
--/* for testing SSCR1 changes that require SSP restart, basically
-- * everything except the service and interrupt enables */
--#define SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_EBCEI | SSCR1_SCFR \
-+/*
-+ * for testing SSCR1 changes that require SSP restart, basically
-+ * everything except the service and interrupt enables, the pxa270 developer
-+ * manual says only SSCR1_SCFR, SSCR1_SPH, SSCR1_SPO need to be in this
-+ * list, but the PXA255 dev man says all bits without really meaning the
-+ * service and interrupt enables
-+ */
-+#define SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_SCFR \
- | SSCR1_ECRA | SSCR1_ECRB | SSCR1_SCLKDIR \
-- | SSCR1_RWOT | SSCR1_TRAIL | SSCR1_PINTE \
-- | SSCR1_STRF | SSCR1_EFWR |SSCR1_RFT \
-- | SSCR1_TFT | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM)
-+ | SSCR1_SFRMDIR | SSCR1_RWOT | SSCR1_TRAIL \
-+ | SSCR1_IFS | SSCR1_STRF | SSCR1_EFWR \
-+ | SSCR1_RFT | SSCR1_TFT | SSCR1_MWDS \
-+ | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM)
-
- #define DEFINE_SSP_REG(reg, off) \
- static inline u32 read_##reg(void *p) { return __raw_readl(p + (off)); } \
-@@ -961,9 +967,6 @@
- if (drv_data->ssp_type == PXA25x_SSP)
- DCMD(drv_data->tx_channel) |= DCMD_ENDIRQEN;
-
-- /* Fix me, need to handle cs polarity */
-- drv_data->cs_control(PXA2XX_CS_ASSERT);
--
- /* Clear status and start DMA engine */
- cr1 = chip->cr1 | dma_thresh | drv_data->dma_cr1;
- write_SSSR(drv_data->clear_sr, reg);
-@@ -973,9 +976,6 @@
- /* Ensure we have the correct interrupt handler */
- drv_data->transfer_handler = interrupt_transfer;
-
-- /* Fix me, need to handle cs polarity */
-- drv_data->cs_control(PXA2XX_CS_ASSERT);
--
- /* Clear status */
- cr1 = chip->cr1 | chip->threshold | drv_data->int_cr1;
- write_SSSR(drv_data->clear_sr, reg);
-@@ -986,16 +986,29 @@
- || (read_SSCR1(reg) & SSCR1_CHANGE_MASK) !=
- (cr1 & SSCR1_CHANGE_MASK)) {
-
-+ /* stop the SSP, and update the other bits */
- write_SSCR0(cr0 & ~SSCR0_SSE, reg);
- if (drv_data->ssp_type != PXA25x_SSP)
- write_SSTO(chip->timeout, reg);
-- write_SSCR1(cr1, reg);
-+ /* first set CR1 without interrupt and service enables */
-+ write_SSCR1(cr1 & SSCR1_CHANGE_MASK, reg);
-+ /* restart the SSP */
- write_SSCR0(cr0, reg);
-+
- } else {
- if (drv_data->ssp_type != PXA25x_SSP)
- write_SSTO(chip->timeout, reg);
-- write_SSCR1(cr1, reg);
- }
-+
-+ /* FIXME, need to handle cs polarity,
-+ * this driver uses struct pxa2xx_spi_chip.cs_control to
-+ * specify a CS handling function, and it ignores most
-+ * struct spi_device.mode[s], including SPI_CS_HIGH */
-+ drv_data->cs_control(PXA2XX_CS_ASSERT);
-+
-+ /* after chip select, release the data by enabling service
-+ * requests and interrupts, without changing any mode bits */
-+ write_SSCR1(cr1, reg);
- }
-
- static void pump_messages(struct work_struct *work)
-diff -Nurd linux-2.6.24/drivers/usb/Kconfig linux-2.6.24-oxe810/drivers/usb/Kconfig
---- linux-2.6.24/drivers/usb/Kconfig 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/Kconfig 2008-06-11 17:50:19.000000000 +0200
-@@ -36,6 +36,7 @@
- default y if ARCH_EP93XX
- default y if ARCH_AT91
- default y if ARCH_PNX4008
-+ default y if ARCH_OXNAS
- # PPC:
- default y if STB03xxx
- default y if PPC_MPC52xx
-@@ -49,6 +50,7 @@
- boolean
- default y if PPC_83xx
- default y if SOC_AU1200
-+ default y if ARCH_OXNAS
- default PCI
-
- # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
-diff -Nurd linux-2.6.24/drivers/usb/class/usblp.c linux-2.6.24-oxe810/drivers/usb/class/usblp.c
---- linux-2.6.24/drivers/usb/class/usblp.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/class/usblp.c 2008-06-11 17:50:16.000000000 +0200
-@@ -428,6 +428,7 @@
- usblp->rcomplete = 0;
-
- if (handle_bidir(usblp) < 0) {
-+ usb_autopm_put_interface(intf);
- usblp->used = 0;
- file->private_data = NULL;
- retval = -EIO;
-diff -Nurd linux-2.6.24/drivers/usb/core/driver.c linux-2.6.24-oxe810/drivers/usb/core/driver.c
---- linux-2.6.24/drivers/usb/core/driver.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/core/driver.c 2008-06-11 17:50:16.000000000 +0200
-@@ -534,8 +534,8 @@
- id->driver_info is the way to create an entry that
- indicates that the driver want to examine every
- device and interface. */
-- for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
-- id->driver_info; id++) {
-+ for (; id->idVendor || id->idProduct || id->bDeviceClass ||
-+ id->bInterfaceClass || id->driver_info; id++) {
- if (usb_match_one_id(interface, id))
- return id;
- }
-diff -Nurd linux-2.6.24/drivers/usb/core/hcd.h linux-2.6.24-oxe810/drivers/usb/core/hcd.h
---- linux-2.6.24/drivers/usb/core/hcd.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/core/hcd.h 2008-06-11 17:50:16.000000000 +0200
-@@ -312,7 +312,9 @@
- #define SetHubFeature (0x2000 | USB_REQ_SET_FEATURE)
- #define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE)
-
--
-+#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
-+#define ResetHubTT (0x2308)
-+#endif
- /*-------------------------------------------------------------------------*/
-
- /*
-@@ -359,6 +361,11 @@
-
- /*-------------------------------------------------------------------------*/
-
-+extern int usb_register_root_hub (struct usb_device *usb_dev,
-+ struct device *parent_dev);
-+
-+extern void usb_hcd_release (struct usb_bus *);
-+
- extern void usb_set_device_state(struct usb_device *udev,
- enum usb_device_state new_state);
-
-diff -Nurd linux-2.6.24/drivers/usb/core/hub.c linux-2.6.24-oxe810/drivers/usb/core/hub.c
---- linux-2.6.24/drivers/usb/core/hub.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/core/hub.c 2008-06-11 17:50:16.000000000 +0200
-@@ -2946,7 +2946,7 @@
- if (len < le16_to_cpu(udev->config[index].desc.wTotalLength))
- len = le16_to_cpu(udev->config[index].desc.wTotalLength);
- }
-- buf = kmalloc (len, GFP_KERNEL);
-+ buf = kmalloc(len, GFP_NOIO);
- if (buf == NULL) {
- dev_err(&udev->dev, "no mem to re-read configs after reset\n");
- /* assume the worst */
-diff -Nurd linux-2.6.24/drivers/usb/gadget/fsl_usb2_udc.c linux-2.6.24-oxe810/drivers/usb/gadget/fsl_usb2_udc.c
---- linux-2.6.24/drivers/usb/gadget/fsl_usb2_udc.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/gadget/fsl_usb2_udc.c 2008-06-11 17:50:17.000000000 +0200
-@@ -776,7 +776,7 @@
- VDBG("%s, bad params\n", __FUNCTION__);
- return -EINVAL;
- }
-- if (!_ep || (!ep->desc && ep_index(ep))) {
-+ if (unlikely(!_ep || !ep->desc)) {
- VDBG("%s, bad ep\n", __FUNCTION__);
- return -EINVAL;
- }
-diff -Nurd linux-2.6.24/drivers/usb/host/Kconfig linux-2.6.24-oxe810/drivers/usb/host/Kconfig
---- linux-2.6.24/drivers/usb/host/Kconfig 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/host/Kconfig 2008-06-11 17:50:19.000000000 +0200
-@@ -41,6 +41,7 @@
- config USB_EHCI_ROOT_HUB_TT
- bool "Root Hub Transaction Translators (EXPERIMENTAL)"
- depends on USB_EHCI_HCD && EXPERIMENTAL
-+ default y if ARCH_OXNAS
- ---help---
- Some EHCI chips have vendor-specific extensions to integrate
- transaction translators, so that no OHCI or UHCI companion
-diff -Nurd linux-2.6.24/drivers/usb/host/Makefile linux-2.6.24-oxe810/drivers/usb/host/Makefile
---- linux-2.6.24/drivers/usb/host/Makefile 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/host/Makefile 2008-06-11 17:50:19.000000000 +0200
-@@ -3,7 +3,11 @@
- #
-
- ifeq ($(CONFIG_USB_DEBUG),y)
-- EXTRA_CFLAGS += -DDEBUG
-+ EXTRA_CFLAGS += -DDEBUG
-+endif
-+
-+ifeq ($(CONFIG_EHCI_VERBOSE_DEBUG),y)
-+ EXTRA_CFLAGS += -DEHCI_VERBOSE_DEBUG
- endif
-
- obj-$(CONFIG_PCI) += pci-quirks.o
-@@ -16,4 +20,3 @@
- obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o
- obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o
- obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o
--
-diff -Nurd linux-2.6.24/drivers/usb/host/ehci-dbg.c linux-2.6.24-oxe810/drivers/usb/host/ehci-dbg.c
---- linux-2.6.24/drivers/usb/host/ehci-dbg.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/host/ehci-dbg.c 2008-06-11 17:50:19.000000000 +0200
-@@ -28,11 +28,11 @@
- dev_warn (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
-
- #ifdef EHCI_VERBOSE_DEBUG
--# define vdbg dbg
--# define ehci_vdbg ehci_dbg
-+ #define vdbg dbg
-+ #define ehci_vdbg ehci_dbg
- #else
--# define vdbg(fmt,args...) do { } while (0)
--# define ehci_vdbg(ehci, fmt, args...) do { } while (0)
-+ #define vdbg(fmt,args...) do { } while (0)
-+ #define ehci_vdbg(ehci, fmt, args...) do { } while (0)
- #endif
-
- #ifdef DEBUG
-@@ -242,6 +242,10 @@
- );
- }
-
-+#define PORT_SPD_HIGH (2 << 26)
-+#define PORT_SPD_FULL (1 << 26)
-+
-+
- static int
- dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status)
- {
-@@ -256,7 +260,7 @@
- }
-
- return scnprintf (buf, len,
-- "%s%sport %d status %06x%s%s sig=%s%s%s%s%s%s%s%s%s%s",
-+ "%s%sport %d status %06x%s%s sig=%s %s%s%s%s%s%s%s%s%s %s",
- label, label [0] ? " " : "", port, status,
- (status & PORT_POWER) ? " POWER" : "",
- (status & PORT_OWNER) ? " OWNER" : "",
-@@ -269,7 +273,9 @@
- (status & PORT_PEC) ? " PEC" : "",
- (status & PORT_PE) ? " PE" : "",
- (status & PORT_CSC) ? " CSC" : "",
-- (status & PORT_CONNECT) ? " CONNECT" : "");
-+ (status & PORT_CONNECT) ? " CONNECT" : "",
-+ (status & PORT_SPD_HIGH) ? ((status & PORT_SPD_FULL) ? "??" : "HIGH" ) : (status & PORT_SPD_FULL) ? "LOW" : "FULL"
-+ );
- }
-
- #else
-@@ -783,13 +789,38 @@
- size -= temp;
- next += temp;
- #endif
--
-+#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
-+ long unsigned tt_status =readl((u32)ehci->regs +TT_STATUS);
-+ temp = scnprintf (next, size,
-+ "tt status %08lx \n",
-+ tt_status);
-+ size -= temp;
-+ next += temp;
-+#endif
- done:
- spin_unlock_irqrestore (&ehci->lock, flags);
-
- return PAGE_SIZE - size;
- }
- static CLASS_DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
-+#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
-+static ssize_t
-+reset_tt (struct class_device *class_dev, const char *buf, size_t len)
-+{
-+ struct usb_bus *bus;
-+ struct usb_hcd *hcd;
-+ struct ehci_hcd *ehci;
-+
-+ bus = class_get_devdata(class_dev);
-+ hcd = bus->hcpriv;
-+ ehci = hcd_to_ehci (hcd);
-+
-+ *((u32 *) ((u32)ehci->regs +TT_STATUS)) = 2;
-+ return len;
-+}
-+
-+static CLASS_DEVICE_ATTR (tt_reset, S_IWUGO, NULL, reset_tt );
-+#endif
-
- static inline void create_debug_files (struct ehci_hcd *ehci)
- {
-@@ -799,6 +830,9 @@
- retval = class_device_create_file(cldev, &class_device_attr_async);
- retval = class_device_create_file(cldev, &class_device_attr_periodic);
- retval = class_device_create_file(cldev, &class_device_attr_registers);
-+#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
-+ class_device_create_file(cldev, &class_device_attr_tt_reset);
-+#endif
- }
-
- static inline void remove_debug_files (struct ehci_hcd *ehci)
-@@ -808,6 +842,9 @@
- class_device_remove_file(cldev, &class_device_attr_async);
- class_device_remove_file(cldev, &class_device_attr_periodic);
- class_device_remove_file(cldev, &class_device_attr_registers);
-+#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
-+ class_device_remove_file(cldev, &class_device_attr_tt_reset);
-+#endif
- }
-
- #endif /* STUB_DEBUG_FILES */
-diff -Nurd linux-2.6.24/drivers/usb/host/ehci-hcd.c linux-2.6.24-oxe810/drivers/usb/host/ehci-hcd.c
---- linux-2.6.24/drivers/usb/host/ehci-hcd.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/host/ehci-hcd.c 2008-06-11 17:50:19.000000000 +0200
-@@ -197,7 +197,7 @@
- u32 __iomem *reg_ptr;
- u32 tmp;
-
-- reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + USBMODE);
-+ reg_ptr = (u32 __iomem *)&ehci->regs->usbmode;
- tmp = ehci_readl(ehci, reg_ptr);
- tmp |= USBMODE_CM_HC;
- /* The default byte access to MMR space is LE after
-@@ -207,6 +207,20 @@
- if (ehci_big_endian_mmio(ehci))
- tmp |= USBMODE_BE;
- ehci_writel(ehci, tmp, reg_ptr);
-+
-+#ifdef CONFIG_ARCH_OXNAS
-+ reg_ptr = (u32 __iomem *)&ehci->regs->txfilltuning;
-+ tmp = ehci_readl(ehci, reg_ptr);
-+ tmp &= ~0x00ff0000;
-+ tmp |= 0x00200000; /* set burst pre load count to 16 */
-+ tmp |= 0x16; /* set sheduler overhead to 3 * 1.267us */
-+ ehci_writel(ehci, tmp, reg_ptr);
-+
-+ reg_ptr = (u32 __iomem *)&ehci->regs->txttfilltuning;
-+ tmp = readl (reg_ptr);
-+ tmp |= 0x2; /* set sheduler overhead to 2 * 6.333us */
-+ writel (tmp, reg_ptr);
-+#endif // CONFIG_ARCH_OXNAS
- }
-
- /* reset a non-running (STS_HALT == 1) controller */
-@@ -225,9 +239,17 @@
-
- if (retval)
- return retval;
-+ if (ehci->is_tdi_rh_tt)
-+ tdi_reset(ehci); /* set TDI EHCI internal registers */
-+#ifdef CONFIG_ARCH_OXNAS
-+ command=readl(&ehci->regs->port_status[1]);
-+ command |=0xc0000000; /* force use of serial PHY on 1st full speed port */
-+ writel(command,&ehci->regs->port_status[1]);
-
-- if (ehci_is_TDI(ehci))
-- tdi_reset (ehci);
-+ command=readl(&ehci->regs->port_status[2]);
-+ command |=0xc0000000; /* force use of serial PHY on 2nd full speed port */
-+ writel(command,&ehci->regs->port_status[2]);
-+#endif // CONFIG_ARCH_OXNAS
-
- return retval;
- }
-@@ -939,10 +961,15 @@
- MODULE_AUTHOR (DRIVER_AUTHOR);
- MODULE_LICENSE ("GPL");
-
-+#ifdef CONFIG_ARCH_OXNAS
-+#include "ehci-oxnas.c"
-+#define PLATFORM_DRIVER ehci_hcd_oxnas_driver
-+#else // CONFIG_ARCH_OXNAS
- #ifdef CONFIG_PCI
- #include "ehci-pci.c"
- #define PCI_DRIVER ehci_pci_driver
--#endif
-+#endif // CONFIG_PCI
-+#endif // CONFIG_ARCH_OXNAS
-
- #ifdef CONFIG_USB_EHCI_FSL
- #include "ehci-fsl.c"
-diff -Nurd linux-2.6.24/drivers/usb/host/ehci-hub.c linux-2.6.24-oxe810/drivers/usb/host/ehci-hub.c
---- linux-2.6.24/drivers/usb/host/ehci-hub.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/host/ehci-hub.c 2008-06-11 17:50:19.000000000 +0200
-@@ -769,6 +769,11 @@
- dbg_port (ehci, "GetStatus", wIndex + 1, temp);
- put_unaligned(cpu_to_le32 (status), (__le32 *) buf);
- break;
-+#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
-+ case ResetHubTT :
-+ *((u32 *) ((u32)ehci->regs +TT_STATUS)) = 2;
-+ break;
-+#endif
- case SetHubFeature:
- switch (wValue) {
- case C_HUB_LOCAL_POWER:
-@@ -825,6 +830,23 @@
- temp |= PORT_RESET;
- temp &= ~PORT_PE;
-
-+#if defined(CONFIG_USB_EHCI_ROOT_HUB_TT) & defined (CONFIG_ARCH_OXNAS) & 0
-+ printk(KERN_ERR "port using status raw %lx\n",temp);
-+ temp &= 0x0fffffffL; /* remove default data source */
-+ if (temp & (1 << 27 ))
-+ {
-+ /* set the input to the UTMI input */
-+ temp |= 0x20000000L;
-+ printk(KERN_ERR "port using UTMI %d\n",wIndex);
-+ }
-+ else
-+ {
-+ /* set the input to the serial PHY input */
-+ temp |= 0xE0000000L;
-+ printk(KERN_ERR "port using serial PHY %d\n",wIndex);
-+ }
-+ writel(temp, &ehci->regs->port_status [wIndex]);
-+#endif
- /*
- * caller must wait, then call GetPortStatus
- * usb 2.0 spec says 50 ms resets on root
-diff -Nurd linux-2.6.24/drivers/usb/host/ehci-oxnas.c linux-2.6.24-oxe810/drivers/usb/host/ehci-oxnas.c
---- linux-2.6.24/drivers/usb/host/ehci-oxnas.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/host/ehci-oxnas.c 2008-06-11 17:50:19.000000000 +0200
-@@ -0,0 +1,307 @@
-+/*
-+ * EHCI HCD (Host Controller Driver) for USB.
-+ *
-+ * (C) Copyright 2005 John Larkworthy <john.larkworthy@oxsemi.com>
-+ *
-+ * OXNAS Bus Glue
-+ *
-+ * Written by John Larkworthy
-+ *
-+ * This file is licenced under the GPL.
-+ */
-+
-+#include <linux/platform_device.h>
-+#include <asm/hardware.h>
-+
-+extern spinlock_t oxnas_gpio_spinlock;
-+
-+int usb_patch = 1;
-+
-+module_param(usb_patch, int, 1);
-+MODULE_PARM_DESC (usb_patch, "use usb hw patch");
-+
-+/* called during probe() after chip reset completes */
-+static int ehci_oxnas_setup(struct usb_hcd *hcd)
-+{
-+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
-+ int temp;
-+ int retval;
-+
-+ ehci->caps = hcd->regs;
-+ ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase));
-+ dbg_hcs_params(ehci, "reset");
-+ dbg_hcc_params(ehci, "reset");
-+
-+ /* cache this readonly data; minimize chip reads */
-+ ehci->hcs_params = readl(&ehci->caps->hcs_params);
-+
-+ retval = ehci_halt(ehci);
-+ if (retval)
-+ return retval;
-+
-+ /* data structure init */
-+ retval = ehci_init(hcd);
-+ if (retval)
-+ return retval;
-+
-+ if (ehci_is_TDI(ehci))
-+ ehci_reset(ehci);
-+
-+ /* at least the Genesys GL880S needs fixup here */
-+ temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params);
-+ temp &= 0x0f;
-+ if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) {
-+ ehci_dbg(ehci, "bogus port configuration: "
-+ "cc=%d x pcc=%d < ports=%d\n",
-+ HCS_N_CC(ehci->hcs_params),
-+ HCS_N_PCC(ehci->hcs_params),
-+ HCS_N_PORTS(ehci->hcs_params));
-+ }
-+
-+ ehci_port_power(ehci, 0);
-+
-+ return retval;
-+}
-+
-+static const struct hc_driver ehci_oxnas_driver = {
-+ .description = hcd_name,
-+ .product_desc = "OXNAS EHCI Host Controller",
-+ .hcd_priv_size = sizeof(struct ehci_hcd),
-+
-+ /*
-+ * generic hardware linkage
-+ */
-+ .irq = ehci_irq,
-+ .flags = HCD_MEMORY | HCD_USB2,
-+
-+ /*
-+ * basic lifecycle operations
-+ */
-+ .reset = ehci_oxnas_setup,
-+ .start = ehci_run,
-+#ifdef CONFIG_PM
-+ .suspend = ehci_suspend,
-+ .resume = ehci_resume,
-+#endif
-+ .stop = ehci_stop,
-+ .shutdown = ehci_shutdown,
-+
-+ /*
-+ * managing i/o requests and associated device resources
-+ */
-+ .urb_enqueue = ehci_urb_enqueue,
-+ .urb_dequeue = ehci_urb_dequeue,
-+ .endpoint_disable = ehci_endpoint_disable,
-+
-+ /*
-+ * scheduling support
-+ */
-+ .get_frame_number = ehci_get_frame,
-+
-+ /*
-+ * root hub support
-+ */
-+ .hub_status_data = ehci_hub_status_data,
-+ .hub_control = ehci_hub_control,
-+ .bus_suspend = ehci_bus_suspend,
-+ .bus_resume = ehci_bus_resume,
-+};
-+
-+static int start_oxnas_usb_ehci(struct platform_device *dev)
-+{
-+ unsigned long flags;
-+ unsigned long input_polarity = 0;
-+ unsigned long output_polarity = 0;
-+ unsigned long power_switch_mask = 0;
-+ unsigned long power_monitor_mask = 0;
-+ unsigned long power_lines_mask = 0;
-+
-+ if (usb_disabled())
-+ return -ENODEV;
-+
-+ pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
-+ hcd_name,
-+ sizeof (struct ehci_qh), sizeof (struct ehci_qtd),
-+ sizeof (struct ehci_itd), sizeof (struct ehci_sitd));
-+
-+#ifdef CONFIG_OXNAS_USB_PORTA_POWER_CONTROL
-+ power_switch_mask |= (1UL << USBA_POWO_GPIO);
-+ power_monitor_mask |= (1UL << USBA_OVERI_GPIO);
-+#endif // CONFIG_OXNAS_USB_PORTA_POWER_CONTROL
-+
-+#ifdef CONFIG_OXNAS_USB_PORTB_POWER_CONTROL
-+ power_switch_mask |= (1UL << USBB_POWO_GPIO);
-+ power_monitor_mask |= (1UL << USBB_OVERI_GPIO);
-+#endif // CONFIG_OXNAS_USB_PORTB_POWER_CONTROL
-+
-+#ifdef CONFIG_OXNAS_USB_PORTC_POWER_CONTROL
-+ power_switch_mask |= (1UL << USBC_POWO_GPIO);
-+ power_monitor_mask |= (1UL << USBC_OVERI_GPIO);
-+#endif // CONFIG_OXNAS_USB_PORTC_POWER_CONTROL
-+
-+ power_lines_mask = power_switch_mask | power_monitor_mask;
-+
-+ // Configure USB power monitoring input and switch output GPIOs
-+#ifdef CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE
-+ input_polarity = ((1UL << SYS_CTRL_USBHSMPH_IP_POL_A_BIT) |
-+ (1UL << SYS_CTRL_USBHSMPH_IP_POL_B_BIT) |
-+ (1UL << SYS_CTRL_USBHSMPH_IP_POL_C_BIT));
-+#endif // CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE
-+
-+#ifdef CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE
-+ output_polarity = ((1UL << SYS_CTRL_USBHSMPH_OP_POL_A_BIT) |
-+ (1UL << SYS_CTRL_USBHSMPH_OP_POL_B_BIT) |
-+ (1UL << SYS_CTRL_USBHSMPH_OP_POL_C_BIT));
-+#endif // CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE
-+
-+ // Enable primary function on USB power monitor and switch lines
-+ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
-+ writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) | power_lines_mask, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+ writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0) & ~power_lines_mask, SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+ writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0) & ~power_lines_mask, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
-+
-+ // Enable GPIO output on USB power switch output GPIOs
-+ writel(power_switch_mask, GPIO_A_OUTPUT_ENABLE_SET);
-+
-+ // Enable GPIO input on USB power monitoring input GPIOs
-+ writel(power_monitor_mask, GPIO_A_OUTPUT_ENABLE_CLEAR);
-+
-+ // Set the polarity of the USB power switch output and monitoring
-+ // inputs in system control
-+ if (usb_patch) {
-+ writel(input_polarity | output_polarity| (1<<6) , SYS_CTRL_USBHSMPH_CTRL);
-+ }
-+ else {
-+ writel(input_polarity | output_polarity, SYS_CTRL_USBHSMPH_CTRL);
-+ }
-+
-+ // Ensure the USB block is properly reset
-+ writel(1UL << SYS_CTRL_RSTEN_USBHS_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+ writel(1UL << SYS_CTRL_RSTEN_USBHS_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+ writel(1UL << SYS_CTRL_RSTEN_USBHSPHY_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+ writel(1UL << SYS_CTRL_RSTEN_USBHSPHY_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
-+
-+ // Force the high speed clock to be generated all the time, via serial
-+ // programming of the USB HS PHY
-+ writel((2UL << SYS_CTRL_USBHSPHY_TEST_ADD) |
-+ (0xe0UL << SYS_CTRL_USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
-+
-+ writel((1UL << SYS_CTRL_USBHSPHY_TEST_CLK) |
-+ (2UL << SYS_CTRL_USBHSPHY_TEST_ADD) |
-+ (0xe0UL << SYS_CTRL_USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
-+
-+ writel((0xfUL << SYS_CTRL_USBHSPHY_TEST_ADD) |
-+ (0xaaUL << SYS_CTRL_USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
-+
-+ writel((1UL << SYS_CTRL_USBHSPHY_TEST_CLK) |
-+ (0xfUL << SYS_CTRL_USBHSPHY_TEST_ADD) |
-+ (0xaaUL << SYS_CTRL_USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
-+
-+ // Enable the clock to the USB block
-+ writel(1UL << SYS_CTRL_CKEN_USBHS_BIT, SYS_CTRL_CKEN_SET_CTRL);
-+
-+ // Ensure reset and clock operations are complete
-+ wmb();
-+
-+ return 0;
-+}
-+
-+static void stop_oxnas_usb_ehci(struct platform_device *dev)
-+{
-+ // put usb core into reset
-+ writel(1UL << SYS_CTRL_RSTEN_USBHS_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+
-+ // Disable the clock to the USB block
-+ writel(1UL << SYS_CTRL_CKEN_USBHS_BIT, SYS_CTRL_CKEN_CLR_CTRL);
-+}
-+
-+/**
-+ * usb_hcd_oxnas_probe - initialize OXNAS-based HCD
-+ * Context: !in_interrupt()
-+ *
-+ * Allocates basic resources for this USB host controller.
-+ *
-+ */
-+static int usb_hcd_oxnas_probe(const struct hc_driver *driver, struct platform_device *dev)
-+{
-+ int retval;
-+ unsigned long ehci_id;
-+ struct usb_hcd *hcd = 0;
-+ struct ehci_hcd *ehci;
-+
-+ if (dev->num_resources != 2) {
-+ pr_debug("wrong number of resources %d, expected %d", dev->num_resources, 2);
-+ }
-+
-+ start_oxnas_usb_ehci(dev);
-+
-+ if (((ehci_id = readl(USB_BASE)) & 0x2f) != 0x05) {
-+ pr_debug("wrong chip ID found %lx", ehci_id);
-+ return -ENODEV;
-+ }
-+
-+ hcd = usb_create_hcd(driver, &dev->dev, "usb");
-+ if (!hcd) {
-+ pr_debug("usb_create_hcd() failed");
-+ retval = -ENOMEM;
-+ }
-+ hcd->regs = (void *)(USB_BASE + 0x100); /* adjust to point at cap length register */
-+
-+ printk(DRIVER_INFO "@%p Device ID register %lx\n", (void *)USB_BASE, *(unsigned long *)USB_BASE);
-+
-+ /* OXNAS device has a transaction translator */
-+ ehci = hcd_to_ehci(hcd);
-+ ehci->is_tdi_rh_tt = 1;
-+
-+ /* Finished initialisation and register */
-+ if ((retval = usb_add_hcd(hcd, dev->resource[1].start, 0))) {
-+ pr_debug("usb_add_hcd() failed");
-+ stop_oxnas_usb_ehci(dev);
-+ usb_put_hcd(hcd);
-+ return retval;
-+ }
-+ return 0;
-+}
-+
-+/**
-+ * usb_hcd_oxnas_remove - shutdown processing for OXNAS-based HCD
-+ * @dev: USB Host Controller being removed
-+ * Context: !in_interrupt()
-+ *
-+ * Reverses the effect of usb_hcd_oxnas_probe(), first invoking
-+ * the HCD's stop() method. It is always called from a thread
-+ * context, normally "rmmod", "apmd", or something similar.
-+ *
-+ */
-+static void usb_hcd_oxnas_remove(struct usb_hcd *hcd, struct platform_device *dev)
-+{
-+ usb_remove_hcd(hcd);
-+ usb_put_hcd(hcd);
-+ stop_oxnas_usb_ehci(dev);
-+}
-+
-+static int ehci_hcd_oxnas_drv_probe(struct platform_device *dev)
-+{
-+ if (usb_disabled())
-+ return -ENODEV;
-+
-+ return usb_hcd_oxnas_probe(&ehci_oxnas_driver, dev);
-+}
-+
-+static int ehci_hcd_oxnas_drv_remove(struct platform_device *dev)
-+{
-+ usb_hcd_oxnas_remove(platform_get_drvdata(dev), dev);
-+ return 0;
-+}
-+
-+MODULE_ALIAS("oxnas-ehci");
-+
-+static struct platform_driver ehci_hcd_oxnas_driver = {
-+ .probe = ehci_hcd_oxnas_drv_probe,
-+ .remove = ehci_hcd_oxnas_drv_remove,
-+ .shutdown = usb_hcd_platform_shutdown,
-+ .driver = {
-+ .name = "oxnas-ehci",
-+ },
-+};
-diff -Nurd linux-2.6.24/drivers/usb/host/ehci-q.c linux-2.6.24-oxe810/drivers/usb/host/ehci-q.c
---- linux-2.6.24/drivers/usb/host/ehci-q.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/host/ehci-q.c 2008-06-11 17:50:19.000000000 +0200
-@@ -315,10 +315,10 @@
- if (likely (last->urb != urb)) {
- ehci_urb_done(ehci, last->urb, last_status);
- count++;
-+ last_status = -EINPROGRESS;
- }
- ehci_qtd_free (ehci, last);
- last = NULL;
-- last_status = -EINPROGRESS;
- }
-
- /* ignore urbs submitted during completions we reported */
-diff -Nurd linux-2.6.24/drivers/usb/host/ehci-sched.c linux-2.6.24-oxe810/drivers/usb/host/ehci-sched.c
---- linux-2.6.24/drivers/usb/host/ehci-sched.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/host/ehci-sched.c 2008-06-11 17:50:19.000000000 +0200
-@@ -2109,6 +2109,7 @@
- {
- unsigned frame, clock, now_uframe, mod;
- unsigned modified;
-+ u8 uncompleted_td = 0;
-
- mod = ehci->periodic_size << 3;
-
-@@ -2188,8 +2189,10 @@
- q = *q_p;
- break;
- }
-- if (uf != 8)
-+ if (uf != 8){
-+ uncompleted_td = 1;
- break;
-+ }
-
- /* this one's ready ... HC won't cache the
- * pointer for much longer, if at all.
-@@ -2214,6 +2217,7 @@
- *q_p = q.sitd->sitd_next;
- *hw_p = q.sitd->hw_next;
- type = Q_NEXT_TYPE(ehci, q.sitd->hw_next);
-+ uncompleted_td = 1;
- wmb();
- modified = sitd_complete (ehci, q.sitd);
- q = *q_p;
-@@ -2239,6 +2243,12 @@
- // don't exceed periodic_size msec (default 1.024 sec).
-
- // FIXME: likewise assumes HC doesn't halt mid-scan
-+
-+ /* We must stat the next scan cycle at the first
-+ * uncompleted TD so that TDs are not lost.
-+ */
-+ if ((!uncompleted_td) && (ehci_to_hcd(ehci)->state == HC_STATE_RUNNING))
-+ ehci->next_uframe = now_uframe;
-
- if (now_uframe == clock) {
- unsigned now;
-diff -Nurd linux-2.6.24/drivers/usb/host/ehci.h linux-2.6.24-oxe810/drivers/usb/host/ehci.h
---- linux-2.6.24/drivers/usb/host/ehci.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/host/ehci.h 2008-06-11 17:50:19.000000000 +0200
-@@ -262,14 +262,22 @@
- /* ASYNCLISTADDR: offset 0x18 */
- u32 async_next; /* address of next async queue head */
-
-- u32 reserved [9];
-+ u32 ttctrl;
-+ u32 burstsize;
-+ u32 txfilltuning;
-+ u32 txttfilltuning;
-+ u32 reserved_1;
-+ u32 ulpi_viewport;
-+ u32 reserved_2;
-+ u32 endpknack;
-+ u32 endptnalek;
-
- /* CONFIGFLAG: offset 0x40 */
- u32 configured_flag;
- #define FLAG_CF (1<<0) /* true: we'll support "high speed" */
-
- /* PORTSC: offset 0x44 */
-- u32 port_status [0]; /* up to N_PORTS */
-+ u32 port_status [8]; /* up to N_PORTS, max 8 */
- /* 31:23 reserved */
- #define PORT_WKOC_E (1<<22) /* wake on overcurrent (enable) */
- #define PORT_WKDISC_E (1<<21) /* wake on disconnect (enable) */
-@@ -294,14 +302,22 @@
- #define PORT_CSC (1<<1) /* connect status change */
- #define PORT_CONNECT (1<<0) /* device connected */
- #define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC)
--} __attribute__ ((packed));
-
--#define USBMODE 0x68 /* USB Device mode */
-+ u32 otgsc;
-+ u32 usbmode;
- #define USBMODE_SDIS (1<<3) /* Stream disable */
--#define USBMODE_BE (1<<2) /* BE/LE endianness select */
-+#define USBMODE_BE (1<<2) /* BE/LE endianness select */
- #define USBMODE_CM_HC (3<<0) /* host controller mode */
- #define USBMODE_CM_IDLE (0<<0) /* idle state */
-
-+ u32 endptsetupstack;
-+ u32 endptprime;
-+ u32 endptflush;
-+ u32 endptstat;
-+ u32 endptcomplete;
-+ u32 endptctrl[8];
-+} __attribute__ ((packed));
-+
- /* Appendix C, Debug port ... intended for use with special "debug devices"
- * that can help if there's no serial console. (nonstandard enumeration.)
- */
-@@ -682,6 +698,11 @@
- }
- return (1<<USB_PORT_FEAT_HIGHSPEED);
- }
-+#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
-+/* TDI transaction translator status register and busy bit */
-+#define TT_BUSY 0x1
-+#define TT_STATUS (0x15c-0x140)
-+#endif
-
- #else
-
-diff -Nurd linux-2.6.24/drivers/usb/misc/usbtest.c linux-2.6.24-oxe810/drivers/usb/misc/usbtest.c
---- linux-2.6.24/drivers/usb/misc/usbtest.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/misc/usbtest.c 2008-06-11 17:50:18.000000000 +0200
-@@ -993,6 +993,7 @@
-
- u->context = &context;
- u->complete = ctrl_complete;
-+ u->transfer_flags |= URB_NO_SETUP_DMA_MAP;
- }
-
- /* queue the urbs */
-@@ -1151,6 +1152,7 @@
- dbg ("ep %02x couldn't get halt status, %d", ep, retval);
- return retval;
- }
-+ le16_to_cpus(&status);
- if (status != 1) {
- dbg ("ep %02x bogus status: %04x != 1", ep, status);
- return -EINVAL;
-@@ -1207,7 +1209,7 @@
- int retval = 0;
- struct urb *urb;
-
-- urb = simple_alloc_urb (testdev_to_usbdev (dev), 0, 512);
-+ urb = simple_alloc_urb (testdev_to_usbdev (dev), 0, 256);
- if (urb == NULL)
- return -ENOMEM;
-
-@@ -2100,6 +2102,10 @@
- /* EZ-USB devices which download firmware to replace (or in our
- * case augment) the default device implementation.
- */
-+ /* generic EZ-USB FX controller */
-+ { USB_DEVICE (0x0547, 0x2131),
-+ .driver_info = (unsigned long) &ez1_info,
-+ },
-
- /* generic EZ-USB FX controller */
- { USB_DEVICE (0x0547, 0x2235),
-diff -Nurd linux-2.6.24/drivers/usb/serial/cp2101.c linux-2.6.24-oxe810/drivers/usb/serial/cp2101.c
---- linux-2.6.24/drivers/usb/serial/cp2101.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/serial/cp2101.c 2008-06-11 17:50:15.000000000 +0200
-@@ -59,6 +59,7 @@
- { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */
- { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
- { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */
-+ { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */
- { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */
- { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */
- { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */
-@@ -76,8 +77,13 @@
- { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
- { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
- { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
-+ { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
-+ { USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */
-+ { USB_DEVICE(0x10C4, 0xF003) }, /* Elan Digital Systems USBpulse100 */
-+ { USB_DEVICE(0x10C4, 0xF004) }, /* Elan Digital Systems USBcount50 */
- { USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */
- { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
-+ { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */
- { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
- { } /* Terminating Entry */
- };
-diff -Nurd linux-2.6.24/drivers/usb/serial/ftdi_sio.c linux-2.6.24-oxe810/drivers/usb/serial/ftdi_sio.c
---- linux-2.6.24/drivers/usb/serial/ftdi_sio.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/serial/ftdi_sio.c 2008-06-11 17:50:15.000000000 +0200
-@@ -310,6 +310,7 @@
- };
-
- static int ftdi_olimex_probe (struct usb_serial *serial);
-+static int ftdi_mtxorb_hack_setup (struct usb_serial *serial);
- static void ftdi_USB_UIRT_setup (struct ftdi_private *priv);
- static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv);
-
-@@ -317,6 +318,10 @@
- .probe = ftdi_olimex_probe,
- };
-
-+static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = {
-+ .probe = ftdi_mtxorb_hack_setup,
-+};
-+
- static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
- .port_probe = ftdi_USB_UIRT_setup,
- };
-@@ -379,6 +384,8 @@
- { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) },
- { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
- { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
-+ { USB_DEVICE(MTXORB_VK_VID, MTXORB_VK_PID),
-+ .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
- { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) },
- { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) },
- { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) },
-@@ -471,30 +478,29 @@
- { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) },
- { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) },
- /*
-- * These will probably use user-space drivers. Uncomment them if
-- * you need them or use the user-specified vendor/product module
-- * parameters (see ftdi_sio.h for the numbers). Make a fuss if
-- * you think the driver should recognize any of them by default.
-+ * Due to many user requests for multiple ELV devices we enable
-+ * them by default.
- */
-- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) }, */
-- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) }, */
-- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) }, */
-- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UDF77_PID) }, */
-- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UIO88_PID) }, */
-- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UAD8_PID) }, */
-- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UDA7_PID) }, */
-- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_USI2_PID) }, */
-- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_T1100_PID) }, */
-- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCD200_PID) }, */
-- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_ULA200_PID) }, */
-- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_CSI8_PID) }, */
-- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1000DL_PID) }, */
-- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, */
-- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) }, */
-- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, */
-- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, */
-- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, */
-- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, */
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_UDF77_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_UIO88_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_UAD8_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_UDA7_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_USI2_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_T1100_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_PCD200_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_ULA200_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_CSI8_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1000DL_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) },
- { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) },
- { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },
- { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) },
-@@ -545,6 +551,7 @@
- { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) },
- { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) },
- { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HRC_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16IC_PID) },
- { USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) },
- { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) },
- { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) },
-@@ -569,6 +576,7 @@
- { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
- { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
- { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
-+ { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) },
- { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID),
- .driver_info = (kernel_ulong_t)&ftdi_olimex_quirk },
- { }, /* Optional parameter entry */
-@@ -1299,6 +1307,23 @@
- }
-
- return 0;
-+}
-+
-+/*
-+ * The Matrix Orbital VK204-25-USB has an invalid IN endpoint.
-+ * We have to correct it if we want to read from it.
-+ */
-+static int ftdi_mtxorb_hack_setup(struct usb_serial *serial)
-+{
-+ struct usb_host_endpoint *ep = serial->dev->ep_in[1];
-+ struct usb_endpoint_descriptor *ep_desc = &ep->desc;
-+
-+ if (ep->enabled && ep_desc->wMaxPacketSize == 0) {
-+ ep_desc->wMaxPacketSize = 0x40;
-+ info("Fixing invalid wMaxPacketSize on read pipe");
-+ }
-+
-+ return 0;
- }
-
- /* ftdi_shutdown is called from usbserial:usb_serial_disconnect
-diff -Nurd linux-2.6.24/drivers/usb/serial/ftdi_sio.h linux-2.6.24-oxe810/drivers/usb/serial/ftdi_sio.h
---- linux-2.6.24/drivers/usb/serial/ftdi_sio.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/serial/ftdi_sio.h 2008-06-11 17:50:15.000000000 +0200
-@@ -98,6 +98,13 @@
- #define FTDI_MTXORB_5_PID 0xFA05 /* Matrix Orbital Product Id */
- #define FTDI_MTXORB_6_PID 0xFA06 /* Matrix Orbital Product Id */
-
-+/*
-+ * The following are the values for the Matrix Orbital VK204-25-USB
-+ * display, which use the FT232RL.
-+ */
-+#define MTXORB_VK_VID 0x1b3d
-+#define MTXORB_VK_PID 0x0158
-+
- /* Interbiometrics USB I/O Board */
- /* Developed for Interbiometrics by Rudolf Gugler */
- #define INTERBIOMETRICS_VID 0x1209
-@@ -245,6 +252,7 @@
- #define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */
- #define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */
- #define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */
-+#define FTDI_ELV_EM1010PC_PID 0xE0EF /* Engery monitor EM 1010 PC */
-
- /*
- * Definitions for ID TECH (www.idt-net.com) devices
-@@ -278,6 +286,7 @@
- #define FTDI_ATIK_ATK16C_PID 0xDF32 /* ATIK ATK-16C Colour Camera */
- #define FTDI_ATIK_ATK16HR_PID 0xDF31 /* ATIK ATK-16HR Grayscale Camera */
- #define FTDI_ATIK_ATK16HRC_PID 0xDF33 /* ATIK ATK-16HRC Colour Camera */
-+#define FTDI_ATIK_ATK16IC_PID 0xDF35 /* ATIK ATK-16IC Grayscale Camera */
-
- /*
- * Protego product ids
-@@ -534,6 +543,8 @@
- #define OLIMEX_VID 0x15BA
- #define OLIMEX_ARM_USB_OCD_PID 0x0003
-
-+/* www.elsterelectricity.com Elster Unicom III Optical Probe */
-+#define FTDI_ELSTER_UNICOM_PID 0xE700 /* Product Id */
-
- /*
- * The Mobility Lab (TML)
-diff -Nurd linux-2.6.24/drivers/usb/serial/keyspan.c linux-2.6.24-oxe810/drivers/usb/serial/keyspan.c
---- linux-2.6.24/drivers/usb/serial/keyspan.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/serial/keyspan.c 2008-06-11 17:50:15.000000000 +0200
-@@ -838,7 +838,7 @@
-
- port = (struct usb_serial_port *) urb->context;
- tty = port->tty;
-- if (urb->actual_length) {
-+ if (tty && urb->actual_length) {
- /* 0x80 bit is error flag */
- if ((data[0] & 0x80) == 0) {
- /* no error on any byte */
-diff -Nurd linux-2.6.24/drivers/usb/serial/kobil_sct.c linux-2.6.24-oxe810/drivers/usb/serial/kobil_sct.c
---- linux-2.6.24/drivers/usb/serial/kobil_sct.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/serial/kobil_sct.c 2008-06-11 17:50:15.000000000 +0200
-@@ -114,6 +114,7 @@
- .usb_driver = &kobil_driver,
- .id_table = id_table,
- .num_interrupt_in = NUM_DONT_CARE,
-+ .num_interrupt_out = NUM_DONT_CARE,
- .num_bulk_in = 0,
- .num_bulk_out = 0,
- .num_ports = 1,
-diff -Nurd linux-2.6.24/drivers/usb/serial/option.c linux-2.6.24-oxe810/drivers/usb/serial/option.c
---- linux-2.6.24/drivers/usb/serial/option.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/serial/option.c 2008-06-11 17:50:15.000000000 +0200
-@@ -180,6 +180,7 @@
- { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */
-+ { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */
- { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },
- { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
-diff -Nurd linux-2.6.24/drivers/usb/serial/pl2303.c linux-2.6.24-oxe810/drivers/usb/serial/pl2303.c
---- linux-2.6.24/drivers/usb/serial/pl2303.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/serial/pl2303.c 2008-06-11 17:50:15.000000000 +0200
-@@ -65,6 +65,7 @@
- { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID_2080) },
- { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) },
- { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) },
-+ { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
- { USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) },
- { USB_DEVICE(RADIOSHACK_VENDOR_ID, RADIOSHACK_PRODUCT_ID) },
- { USB_DEVICE(DCU10_VENDOR_ID, DCU10_PRODUCT_ID) },
-@@ -84,9 +85,10 @@
- { USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) },
- { USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) },
- { USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) },
-- { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ID) },
- { USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) },
- { USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) },
-+ { USB_DEVICE(HL340_VENDOR_ID, HL340_PRODUCT_ID) },
-+ { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },
- { } /* Terminating entry */
- };
-
-diff -Nurd linux-2.6.24/drivers/usb/serial/pl2303.h linux-2.6.24-oxe810/drivers/usb/serial/pl2303.h
---- linux-2.6.24/drivers/usb/serial/pl2303.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/serial/pl2303.h 2008-06-11 17:50:15.000000000 +0200
-@@ -35,6 +35,7 @@
-
- #define RATOC_VENDOR_ID 0x0584
- #define RATOC_PRODUCT_ID 0xb000
-+#define RATOC_PRODUCT_ID_USB60F 0xb020
-
- #define TRIPP_VENDOR_ID 0x2478
- #define TRIPP_PRODUCT_ID 0x2008
-@@ -96,10 +97,6 @@
- #define ALCOR_VENDOR_ID 0x058F
- #define ALCOR_PRODUCT_ID 0x9720
-
--/* Huawei E620 UMTS/HSDPA card (ID: 12d1:1001) */
--#define HUAWEI_VENDOR_ID 0x12d1
--#define HUAWEI_PRODUCT_ID 0x1001
--
- /* Willcom WS002IN Data Driver (by NetIndex Inc.) */
- #define WS002IN_VENDOR_ID 0x11f6
- #define WS002IN_PRODUCT_ID 0x2001
-@@ -107,3 +104,11 @@
- /* Corega CG-USBRS232R Serial Adapter */
- #define COREGA_VENDOR_ID 0x07aa
- #define COREGA_PRODUCT_ID 0x002a
-+
-+/* HL HL-340 (ID: 4348:5523) */
-+#define HL340_VENDOR_ID 0x4348
-+#define HL340_PRODUCT_ID 0x5523
-+
-+/* Y.C. Cable U.S.A., Inc - USB to RS-232 */
-+#define YCCABLE_VENDOR_ID 0x05ad
-+#define YCCABLE_PRODUCT_ID 0x0fba
-diff -Nurd linux-2.6.24/drivers/usb/serial/sierra.c linux-2.6.24-oxe810/drivers/usb/serial/sierra.c
---- linux-2.6.24/drivers/usb/serial/sierra.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/serial/sierra.c 2008-06-11 17:50:15.000000000 +0200
-@@ -104,6 +104,7 @@
- { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
- { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
- { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */
-+ { USB_DEVICE(0x1199, 0x0023) }, /* Sierra Wireless AirCard */
-
- { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
- { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
-@@ -117,9 +118,15 @@
- { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */
- { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */
- { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */
-+ { USB_DEVICE(0x1199, 0x6855) }, /* Sierra Wireless AirCard 880 U */
-+ { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */
-+
-+ { USB_DEVICE(0x1199, 0x6468) }, /* Sierra Wireless MP3G - EVDO */
-+ { USB_DEVICE(0x1199, 0x6469) }, /* Sierra Wireless MP3G - UMTS/HSPA */
-
- { USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */
- { USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */
-+ { USB_DEVICE(0x05C6, 0x6613), .driver_info = DEVICE_1_PORT }, /* Onda H600/ZTE MF330 */
-
- { USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER},
- { }
-@@ -129,6 +136,7 @@
- static struct usb_device_id id_table_1port [] = {
- { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
- { USB_DEVICE(0x0F3D, 0x0112) }, /* AirPrime/Sierra PC 5220 */
-+ { USB_DEVICE(0x05C6, 0x6613) }, /* Onda H600/ZTE MF330 */
- { }
- };
-
-@@ -142,6 +150,7 @@
- { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
- { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
- { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U*/
-+ { USB_DEVICE(0x1199, 0x0023) }, /* Sierra Wireless AirCard */
-
- { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
- { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
-@@ -155,6 +164,10 @@
- { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */
- { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880E */
- { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881E */
-+ { USB_DEVICE(0x1199, 0x6855) }, /* Sierra Wireless AirCard 880 U */
-+ { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881U */
-+ { USB_DEVICE(0x1199, 0x6468) }, /* Sierra Wireless MP3G - EVDO */
-+ { USB_DEVICE(0x1199, 0x6469) }, /* Sierra Wireless MP3G - UMTS/HSPA */
- { }
- };
-
-diff -Nurd linux-2.6.24/drivers/usb/storage/protocol.c linux-2.6.24-oxe810/drivers/usb/storage/protocol.c
---- linux-2.6.24/drivers/usb/storage/protocol.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/storage/protocol.c 2008-06-11 17:50:16.000000000 +0200
-@@ -194,7 +194,7 @@
- * and the starting offset within the page, and update
- * the *offset and *index values for the next loop. */
- cnt = 0;
-- while (cnt < buflen) {
-+ while (cnt < buflen && sg) {
- struct page *page = sg_page(sg) +
- ((sg->offset + *offset) >> PAGE_SHIFT);
- unsigned int poff =
-@@ -249,7 +249,8 @@
- unsigned int offset = 0;
- struct scatterlist *sg = NULL;
-
-- usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
-+ buflen = min(buflen, srb->request_bufflen);
-+ buflen = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
- TO_XFER_BUF);
- if (buflen < srb->request_bufflen)
- srb->resid = srb->request_bufflen - buflen;
-diff -Nurd linux-2.6.24/drivers/usb/storage/unusual_devs.h linux-2.6.24-oxe810/drivers/usb/storage/unusual_devs.h
---- linux-2.6.24/drivers/usb/storage/unusual_devs.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/drivers/usb/storage/unusual_devs.h 2008-06-11 17:50:16.000000000 +0200
-@@ -86,6 +86,14 @@
- US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
- #endif
-
-+/* Reported by Grant Grundler <grundler@parisc-linux.org>
-+ * HP r707 camera in "Disk" mode with 2.00.23 or 2.00.24 firmware.
-+ */
-+UNUSUAL_DEV( 0x03f0, 0x4002, 0x0001, 0x0001,
-+ "HP",
-+ "PhotoSmart R707",
-+ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY),
-+
- /* Reported by Sebastian Kapfer <sebastian_kapfer@gmx.net>
- * and Olaf Hering <olh@suse.de> (different bcd's, same vendor/product)
- * for USB floppies that need the SINGLE_LUN enforcement.
-diff -Nurd linux-2.6.24/fs/adfs/file.c linux-2.6.24-oxe810/fs/adfs/file.c
---- linux-2.6.24/fs/adfs/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/adfs/file.c 2008-06-11 17:47:02.000000000 +0200
-@@ -33,6 +33,7 @@
- .fsync = file_fsync,
- .write = do_sync_write,
- .aio_write = generic_file_aio_write,
-+ .sendfile = generic_file_sendfile,
- .splice_read = generic_file_splice_read,
- };
-
-diff -Nurd linux-2.6.24/fs/affs/file.c linux-2.6.24-oxe810/fs/affs/file.c
---- linux-2.6.24/fs/affs/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/affs/file.c 2008-06-11 17:46:52.000000000 +0200
-@@ -35,6 +35,7 @@
- .open = affs_file_open,
- .release = affs_file_release,
- .fsync = file_fsync,
-+ .sendfile = generic_file_sendfile,
- .splice_read = generic_file_splice_read,
- };
-
-diff -Nurd linux-2.6.24/fs/afs/file.c linux-2.6.24-oxe810/fs/afs/file.c
---- linux-2.6.24/fs/afs/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/afs/file.c 2008-06-11 17:46:51.000000000 +0200
-@@ -32,6 +32,7 @@
- .aio_read = generic_file_aio_read,
- .aio_write = afs_file_write,
- .mmap = generic_file_readonly_mmap,
-+ .sendfile = generic_file_sendfile,
- .splice_read = generic_file_splice_read,
- .fsync = afs_fsync,
- .lock = afs_lock,
-diff -Nurd linux-2.6.24/fs/aio.c linux-2.6.24-oxe810/fs/aio.c
---- linux-2.6.24/fs/aio.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/aio.c 2008-06-11 17:47:10.000000000 +0200
-@@ -997,6 +997,14 @@
- /* everything turned out well, dispose of the aiocb. */
- ret = __aio_put_req(ctx, iocb);
-
-+ /*
-+ * We have to order our ring_info tail store above and test
-+ * of the wait list below outside the wait lock. This is
-+ * like in wake_up_bit() where clearing a bit has to be
-+ * ordered with the unlocked test.
-+ */
-+ smp_mb();
-+
- if (waitqueue_active(&ctx->wait))
- wake_up(&ctx->wait);
-
-diff -Nurd linux-2.6.24/fs/bio.c linux-2.6.24-oxe810/fs/bio.c
---- linux-2.6.24/fs/bio.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/bio.c 2008-06-11 17:47:10.000000000 +0200
-@@ -133,6 +133,7 @@
- memset(bio, 0, sizeof(*bio));
- bio->bi_flags = 1 << BIO_UPTODATE;
- atomic_set(&bio->bi_cnt, 1);
-+ bio->bi_raid = 0;
- }
-
- /**
-@@ -260,6 +261,7 @@
- bio->bi_vcnt = bio_src->bi_vcnt;
- bio->bi_size = bio_src->bi_size;
- bio->bi_idx = bio_src->bi_idx;
-+ bio->bi_raid = bio_src->bi_raid;
- bio_phys_segments(q, bio);
- bio_hw_segments(q, bio);
- }
-diff -Nurd linux-2.6.24/fs/coda/file.c linux-2.6.24-oxe810/fs/coda/file.c
---- linux-2.6.24/fs/coda/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/coda/file.c 2008-06-11 17:47:09.000000000 +0200
-@@ -238,6 +238,7 @@
- .open = coda_open,
- .release = coda_release,
- .fsync = coda_fsync,
-+ .sendfile = coda_file_sendfile,
- .splice_read = coda_file_splice_read,
- };
-
-diff -Nurd linux-2.6.24/fs/ecryptfs/file.c linux-2.6.24-oxe810/fs/ecryptfs/file.c
---- linux-2.6.24/fs/ecryptfs/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ecryptfs/file.c 2008-06-11 17:46:59.000000000 +0200
-@@ -292,6 +292,7 @@
- .release = ecryptfs_release,
- .fsync = ecryptfs_fsync,
- .fasync = ecryptfs_fasync,
-+ .sendfile = ecryptfs_sendfile,
- .splice_read = generic_file_splice_read,
- };
-
-@@ -309,6 +310,7 @@
- .release = ecryptfs_release,
- .fsync = ecryptfs_fsync,
- .fasync = ecryptfs_fasync,
-+ .sendfile = ecryptfs_sendfile,
- .splice_read = generic_file_splice_read,
- };
-
-diff -Nurd linux-2.6.24/fs/ecryptfs/mmap.c linux-2.6.24-oxe810/fs/ecryptfs/mmap.c
---- linux-2.6.24/fs/ecryptfs/mmap.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ecryptfs/mmap.c 2008-06-11 17:46:59.000000000 +0200
-@@ -263,52 +263,102 @@
- return 0;
- }
-
--/* This function must zero any hole we create */
-+/**
-+ * ecryptfs_prepare_write
-+ * @file: The eCryptfs file
-+ * @page: The eCryptfs page
-+ * @from: The start byte from which we will write
-+ * @to: The end byte to which we will write
-+ *
-+ * This function must zero any hole we create
-+ *
-+ * Returns zero on success; non-zero otherwise
-+ */
- static int ecryptfs_prepare_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
- {
-- int rc = 0;
- loff_t prev_page_end_size;
-+ int rc = 0;
-
- if (!PageUptodate(page)) {
-- rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
-- PAGE_CACHE_SIZE,
-- page->mapping->host);
-- if (rc) {
-- printk(KERN_ERR "%s: Error attemping to read lower "
-- "page segment; rc = [%d]\n", __FUNCTION__, rc);
-- ClearPageUptodate(page);
-- goto out;
-- } else
-+ struct ecryptfs_crypt_stat *crypt_stat =
-+ &ecryptfs_inode_to_private(
-+ file->f_path.dentry->d_inode)->crypt_stat;
-+
-+ if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)
-+ || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) {
-+ rc = ecryptfs_read_lower_page_segment(
-+ page, page->index, 0, PAGE_CACHE_SIZE,
-+ page->mapping->host);
-+ if (rc) {
-+ printk(KERN_ERR "%s: Error attemping to read "
-+ "lower page segment; rc = [%d]\n",
-+ __FUNCTION__, rc);
-+ ClearPageUptodate(page);
-+ goto out;
-+ } else
-+ SetPageUptodate(page);
-+ } else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) {
-+ if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) {
-+ rc = ecryptfs_copy_up_encrypted_with_header(
-+ page, crypt_stat);
-+ if (rc) {
-+ printk(KERN_ERR "%s: Error attempting "
-+ "to copy the encrypted content "
-+ "from the lower file whilst "
-+ "inserting the metadata from "
-+ "the xattr into the header; rc "
-+ "= [%d]\n", __FUNCTION__, rc);
-+ ClearPageUptodate(page);
-+ goto out;
-+ }
-+ SetPageUptodate(page);
-+ } else {
-+ rc = ecryptfs_read_lower_page_segment(
-+ page, page->index, 0, PAGE_CACHE_SIZE,
-+ page->mapping->host);
-+ if (rc) {
-+ printk(KERN_ERR "%s: Error reading "
-+ "page; rc = [%d]\n",
-+ __FUNCTION__, rc);
-+ ClearPageUptodate(page);
-+ goto out;
-+ }
-+ SetPageUptodate(page);
-+ }
-+ } else {
-+ rc = ecryptfs_decrypt_page(page);
-+ if (rc) {
-+ printk(KERN_ERR "%s: Error decrypting page "
-+ "at index [%ld]; rc = [%d]\n",
-+ __FUNCTION__, page->index, rc);
-+ ClearPageUptodate(page);
-+ goto out;
-+ }
- SetPageUptodate(page);
-+ }
- }
--
- prev_page_end_size = ((loff_t)page->index << PAGE_CACHE_SHIFT);
--
-- /*
-- * If creating a page or more of holes, zero them out via truncate.
-- * Note, this will increase i_size.
-- */
-+ /* If creating a page or more of holes, zero them out via truncate.
-+ * Note, this will increase i_size. */
- if (page->index != 0) {
- if (prev_page_end_size > i_size_read(page->mapping->host)) {
- rc = ecryptfs_truncate(file->f_path.dentry,
- prev_page_end_size);
- if (rc) {
-- printk(KERN_ERR "Error on attempt to "
-+ printk(KERN_ERR "%s: Error on attempt to "
- "truncate to (higher) offset [%lld];"
-- " rc = [%d]\n", prev_page_end_size, rc);
-+ " rc = [%d]\n", __FUNCTION__,
-+ prev_page_end_size, rc);
- goto out;
- }
- }
- }
-- /*
-- * Writing to a new page, and creating a small hole from start of page?
-- * Zero it out.
-- */
-- if ((i_size_read(page->mapping->host) == prev_page_end_size) &&
-- (from != 0)) {
-+ /* Writing to a new page, and creating a small hole from start
-+ * of page? Zero it out. */
-+ if ((i_size_read(page->mapping->host) == prev_page_end_size)
-+ && (from != 0))
- zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0);
-- }
- out:
- return rc;
- }
-diff -Nurd linux-2.6.24/fs/eventpoll.c linux-2.6.24-oxe810/fs/eventpoll.c
---- linux-2.6.24/fs/eventpoll.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/eventpoll.c 2008-06-11 17:47:10.000000000 +0200
-@@ -353,7 +353,7 @@
- spin_unlock_irqrestore(&psw->lock, flags);
-
- /* Do really wake up now */
-- wake_up(wq);
-+ wake_up_nested(wq, 1 + wake_nests);
-
- /* Remove the current task from the list */
- spin_lock_irqsave(&psw->lock, flags);
-diff -Nurd linux-2.6.24/fs/ext2/file.c linux-2.6.24-oxe810/fs/ext2/file.c
---- linux-2.6.24/fs/ext2/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ext2/file.c 2008-06-11 17:47:06.000000000 +0200
-@@ -56,6 +56,7 @@
- .open = generic_file_open,
- .release = ext2_release_file,
- .fsync = ext2_sync_file,
-+ .sendfile = generic_file_sendfile,
- .splice_read = generic_file_splice_read,
- .splice_write = generic_file_splice_write,
- };
-@@ -73,6 +74,7 @@
- .open = generic_file_open,
- .release = ext2_release_file,
- .fsync = ext2_sync_file,
-+ .sendfile = xip_file_sendfile,
- };
- #endif
-
-diff -Nurd linux-2.6.24/fs/ext3/file.c linux-2.6.24-oxe810/fs/ext3/file.c
---- linux-2.6.24/fs/ext3/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ext3/file.c 2008-06-11 17:47:06.000000000 +0200
-@@ -120,6 +120,7 @@
- .open = generic_file_open,
- .release = ext3_release_file,
- .fsync = ext3_sync_file,
-+ .sendfile = generic_file_sendfile,
- .splice_read = generic_file_splice_read,
- .splice_write = generic_file_splice_write,
- };
-diff -Nurd linux-2.6.24/fs/ext3/ialloc.c linux-2.6.24-oxe810/fs/ext3/ialloc.c
---- linux-2.6.24/fs/ext3/ialloc.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ext3/ialloc.c 2008-06-11 17:47:06.000000000 +0200
-@@ -543,7 +543,16 @@
- percpu_counter_inc(&sbi->s_dirs_counter);
- sb->s_dirt = 1;
-
-+#ifdef CONFIG_OXNAS_SUID_INHERIT
-+ if (dir->i_mode & S_ISUID) {
-+ inode->i_uid = dir->i_uid;
-+ if (S_ISDIR(mode))
-+ mode |= S_ISUID;
-+ } else
-+#else // CONFIG_OXNAS_SUID_INHERIT
- inode->i_uid = current->fsuid;
-+#endif // CONFIG_OXNAS_SUID_INHERIT
-+
- if (test_opt (sb, GRPID))
- inode->i_gid = dir->i_gid;
- else if (dir->i_mode & S_ISGID) {
-diff -Nurd linux-2.6.24/fs/ext4/file.c linux-2.6.24-oxe810/fs/ext4/file.c
---- linux-2.6.24/fs/ext4/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ext4/file.c 2008-06-11 17:47:07.000000000 +0200
-@@ -120,7 +120,8 @@
- .open = generic_file_open,
- .release = ext4_release_file,
- .fsync = ext4_sync_file,
-- .splice_read = generic_file_splice_read,
-+ .sendfile = generic_file_sendfile,
-+ .splice_read = generic_file_splice_read,
- .splice_write = generic_file_splice_write,
- };
-
-diff -Nurd linux-2.6.24/fs/fat/file.c linux-2.6.24-oxe810/fs/fat/file.c
---- linux-2.6.24/fs/fat/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/fat/file.c 2008-06-11 17:47:05.000000000 +0200
-@@ -134,6 +134,7 @@
- .release = fat_file_release,
- .ioctl = fat_generic_ioctl,
- .fsync = file_fsync,
-+ .sendfile = generic_file_sendfile,
- .splice_read = generic_file_splice_read,
- };
-
-diff -Nurd linux-2.6.24/fs/fuse/dir.c linux-2.6.24-oxe810/fs/fuse/dir.c
---- linux-2.6.24/fs/fuse/dir.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/fuse/dir.c 2008-06-11 17:47:00.000000000 +0200
-@@ -905,7 +905,7 @@
- }
-
- if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
-- int err = generic_permission(inode, mask, NULL);
-+ err = generic_permission(inode, mask, NULL);
-
- /* If permission is denied, try to refresh file
- attributes. This is also needed, because the root
-diff -Nurd linux-2.6.24/fs/fuse/file.c linux-2.6.24-oxe810/fs/fuse/file.c
---- linux-2.6.24/fs/fuse/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/fuse/file.c 2008-06-11 17:47:00.000000000 +0200
-@@ -920,6 +920,7 @@
- .fsync = fuse_fsync,
- .lock = fuse_file_lock,
- .flock = fuse_file_flock,
-+ .sendfile = generic_file_sendfile,
- .splice_read = generic_file_splice_read,
- };
-
-diff -Nurd linux-2.6.24/fs/gfs2/ops_file.c linux-2.6.24-oxe810/fs/gfs2/ops_file.c
---- linux-2.6.24/fs/gfs2/ops_file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/gfs2/ops_file.c 2008-06-11 17:47:09.000000000 +0200
-@@ -662,6 +662,7 @@
- .release = gfs2_close,
- .fsync = gfs2_fsync,
- .lock = gfs2_lock,
-+ .sendfile = generic_file_sendfile,
- .flock = gfs2_flock,
- .splice_read = generic_file_splice_read,
- .splice_write = generic_file_splice_write,
-diff -Nurd linux-2.6.24/fs/hpfs/file.c linux-2.6.24-oxe810/fs/hpfs/file.c
---- linux-2.6.24/fs/hpfs/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/hpfs/file.c 2008-06-11 17:46:57.000000000 +0200
-@@ -137,6 +137,7 @@
- .mmap = generic_file_mmap,
- .release = hpfs_file_release,
- .fsync = hpfs_file_fsync,
-+ .sendfile = generic_file_sendfile,
- .splice_read = generic_file_splice_read,
- };
-
-diff -Nurd linux-2.6.24/fs/inotify_user.c linux-2.6.24-oxe810/fs/inotify_user.c
---- linux-2.6.24/fs/inotify_user.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/inotify_user.c 2008-06-11 17:47:10.000000000 +0200
-@@ -269,7 +269,7 @@
- /* we can safely put the watch as we don't reference it while
- * generating the event
- */
-- if (mask & IN_IGNORED || mask & IN_ONESHOT)
-+ if (mask & IN_IGNORED || w->mask & IN_ONESHOT)
- put_inotify_watch(w); /* final put */
-
- /* coalescing: drop this event if it is a dupe of the previous */
-diff -Nurd linux-2.6.24/fs/isofs/compress.c linux-2.6.24-oxe810/fs/isofs/compress.c
---- linux-2.6.24/fs/isofs/compress.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/isofs/compress.c 2008-06-11 17:46:52.000000000 +0200
-@@ -72,6 +72,17 @@
- offset = index & ~zisofs_block_page_mask;
- blockindex = offset >> zisofs_block_page_shift;
- maxpage = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-+
-+ /*
-+ * If this page is wholly outside i_size we just return zero;
-+ * do_generic_file_read() will handle this for us
-+ */
-+ if (page->index >= maxpage) {
-+ SetPageUptodate(page);
-+ unlock_page(page);
-+ return 0;
-+ }
-+
- maxpage = min(zisofs_block_pages, maxpage-offset);
-
- for ( i = 0 ; i < maxpage ; i++, offset++ ) {
-diff -Nurd linux-2.6.24/fs/jbd/recovery.c linux-2.6.24-oxe810/fs/jbd/recovery.c
---- linux-2.6.24/fs/jbd/recovery.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/jbd/recovery.c 2008-06-11 17:47:07.000000000 +0200
-@@ -478,7 +478,7 @@
- memcpy(nbh->b_data, obh->b_data,
- journal->j_blocksize);
- if (flags & JFS_FLAG_ESCAPE) {
-- *((__be32 *)bh->b_data) =
-+ *((__be32 *)nbh->b_data) =
- cpu_to_be32(JFS_MAGIC_NUMBER);
- }
-
-diff -Nurd linux-2.6.24/fs/jbd2/recovery.c linux-2.6.24-oxe810/fs/jbd2/recovery.c
---- linux-2.6.24/fs/jbd2/recovery.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/jbd2/recovery.c 2008-06-11 17:46:49.000000000 +0200
-@@ -488,7 +488,7 @@
- memcpy(nbh->b_data, obh->b_data,
- journal->j_blocksize);
- if (flags & JBD2_FLAG_ESCAPE) {
-- *((__be32 *)bh->b_data) =
-+ *((__be32 *)nbh->b_data) =
- cpu_to_be32(JBD2_MAGIC_NUMBER);
- }
-
-diff -Nurd linux-2.6.24/fs/jffs2/file.c linux-2.6.24-oxe810/fs/jffs2/file.c
---- linux-2.6.24/fs/jffs2/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/jffs2/file.c 2008-06-11 17:47:10.000000000 +0200
-@@ -49,7 +49,8 @@
- .ioctl = jffs2_ioctl,
- .mmap = generic_file_readonly_mmap,
- .fsync = jffs2_fsync,
-- .splice_read = generic_file_splice_read,
-+ .sendfile = generic_file_sendfile
-+ .splice_read = generic_file_splice_read,
- };
-
- /* jffs2_file_inode_operations */
-diff -Nurd linux-2.6.24/fs/jfs/file.c linux-2.6.24-oxe810/fs/jfs/file.c
---- linux-2.6.24/fs/jfs/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/jfs/file.c 2008-06-11 17:46:58.000000000 +0200
-@@ -108,6 +108,7 @@
- .aio_read = generic_file_aio_read,
- .aio_write = generic_file_aio_write,
- .mmap = generic_file_mmap,
-+ .sendfile = generic_file_sendfile,
- .splice_read = generic_file_splice_read,
- .splice_write = generic_file_splice_write,
- .fsync = jfs_fsync,
-diff -Nurd linux-2.6.24/fs/minix/file.c linux-2.6.24-oxe810/fs/minix/file.c
---- linux-2.6.24/fs/minix/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/minix/file.c 2008-06-11 17:47:00.000000000 +0200
-@@ -23,6 +23,7 @@
- .aio_write = generic_file_aio_write,
- .mmap = generic_file_mmap,
- .fsync = minix_sync_file,
-+ .sendfile = generic_file_sendfile,
- .splice_read = generic_file_splice_read,
- };
-
-diff -Nurd linux-2.6.24/fs/ncpfs/mmap.c linux-2.6.24-oxe810/fs/ncpfs/mmap.c
---- linux-2.6.24/fs/ncpfs/mmap.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ncpfs/mmap.c 2008-06-11 17:47:09.000000000 +0200
-@@ -50,10 +50,6 @@
- pos = vmf->pgoff << PAGE_SHIFT;
-
- count = PAGE_SIZE;
-- if ((unsigned long)vmf->virtual_address + PAGE_SIZE > area->vm_end) {
-- WARN_ON(1); /* shouldn't happen? */
-- count = area->vm_end - (unsigned long)vmf->virtual_address;
-- }
- /* what we can read in one go */
- bufsize = NCP_SERVER(inode)->buffer_size;
-
-diff -Nurd linux-2.6.24/fs/nfs/write.c linux-2.6.24-oxe810/fs/nfs/write.c
---- linux-2.6.24/fs/nfs/write.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/nfs/write.c 2008-06-11 17:46:59.000000000 +0200
-@@ -701,6 +701,17 @@
- }
-
- /*
-+ * If the page cache is marked as unsafe or invalid, then we can't rely on
-+ * the PageUptodate() flag. In this case, we will need to turn off
-+ * write optimisations that depend on the page contents being correct.
-+ */
-+static int nfs_write_pageuptodate(struct page *page, struct inode *inode)
-+{
-+ return PageUptodate(page) &&
-+ !(NFS_I(inode)->cache_validity & (NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA));
-+}
-+
-+/*
- * Update and possibly write a cached page of an NFS file.
- *
- * XXX: Keep an eye on generic_file_read to make sure it doesn't do bad
-@@ -721,10 +732,13 @@
- (long long)(page_offset(page) +offset));
-
- /* If we're not using byte range locks, and we know the page
-- * is entirely in cache, it may be more efficient to avoid
-- * fragmenting write requests.
-+ * is up to date, it may be more efficient to extend the write
-+ * to cover the entire page in order to avoid fragmentation
-+ * inefficiencies.
- */
-- if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) {
-+ if (nfs_write_pageuptodate(page, inode) &&
-+ inode->i_flock == NULL &&
-+ !(file->f_mode & O_SYNC)) {
- count = max(count + offset, nfs_page_length(page));
- offset = 0;
- }
-diff -Nurd linux-2.6.24/fs/nfsd/nfsfh.c linux-2.6.24-oxe810/fs/nfsd/nfsfh.c
---- linux-2.6.24/fs/nfsd/nfsfh.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/nfsd/nfsfh.c 2008-06-11 17:47:05.000000000 +0200
-@@ -231,6 +231,7 @@
- fhp->fh_dentry = dentry;
- fhp->fh_export = exp;
- nfsd_nr_verified++;
-+ cache_get(&exp->h);
- } else {
- /*
- * just rechecking permissions
-@@ -240,6 +241,7 @@
- dprintk("nfsd: fh_verify - just checking\n");
- dentry = fhp->fh_dentry;
- exp = fhp->fh_export;
-+ cache_get(&exp->h);
- /*
- * Set user creds for this exportpoint; necessary even
- * in the "just checking" case because this may be a
-@@ -251,8 +253,6 @@
- if (error)
- goto out;
- }
-- cache_get(&exp->h);
--
-
- error = nfsd_mode_check(rqstp, dentry->d_inode->i_mode, type);
- if (error)
-diff -Nurd linux-2.6.24/fs/ntfs/file.c linux-2.6.24-oxe810/fs/ntfs/file.c
---- linux-2.6.24/fs/ntfs/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ntfs/file.c 2008-06-11 17:47:01.000000000 +0200
-@@ -2274,16 +2274,11 @@
- mounted filesystem. */
- .mmap = generic_file_mmap, /* Mmap file. */
- .open = ntfs_file_open, /* Open file. */
-- .splice_read = generic_file_splice_read /* Zero-copy data send with
-+ .sendfile = generic_file_sendfile, /* Zero-copy data send with
- the data source being on
- the ntfs partition. We do
- not need to care about the
- data destination. */
-- /*.sendpage = ,*/ /* Zero-copy data send with
-- the data destination being
-- on the ntfs partition. We
-- do not need to care about
-- the data source. */
- };
-
- const struct inode_operations ntfs_file_inode_ops = {
-diff -Nurd linux-2.6.24/fs/ocfs2/file.c linux-2.6.24-oxe810/fs/ocfs2/file.c
---- linux-2.6.24/fs/ocfs2/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ocfs2/file.c 2008-06-11 17:46:56.000000000 +0200
-@@ -2206,6 +2206,7 @@
- const struct file_operations ocfs2_fops = {
- .read = do_sync_read,
- .write = do_sync_write,
-+ .sendfile = generic_file_sendfile,
- .mmap = ocfs2_mmap,
- .fsync = ocfs2_sync_file,
- .release = ocfs2_file_release,
-diff -Nurd linux-2.6.24/fs/qnx4/file.c linux-2.6.24-oxe810/fs/qnx4/file.c
---- linux-2.6.24/fs/qnx4/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/qnx4/file.c 2008-06-11 17:46:56.000000000 +0200
-@@ -25,6 +25,7 @@
- .read = do_sync_read,
- .aio_read = generic_file_aio_read,
- .mmap = generic_file_mmap,
-+ .sendfile = generic_file_sendfile,
- .splice_read = generic_file_splice_read,
- #ifdef CONFIG_QNX4FS_RW
- .write = do_sync_write,
-diff -Nurd linux-2.6.24/fs/read_write.c linux-2.6.24-oxe810/fs/read_write.c
---- linux-2.6.24/fs/read_write.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/read_write.c 2008-06-11 17:47:10.000000000 +0200
-@@ -26,7 +26,8 @@
- .read = do_sync_read,
- .aio_read = generic_file_aio_read,
- .mmap = generic_file_readonly_mmap,
-- .splice_read = generic_file_splice_read,
-+ //.splice_read = generic_file_splice_read,
-+ .sendfile = generic_file_sendfile,
- };
-
- EXPORT_SYMBOL(generic_ro_fops);
-@@ -709,7 +710,7 @@
- struct inode * in_inode, * out_inode;
- loff_t pos;
- ssize_t retval;
-- int fput_needed_in, fput_needed_out, fl;
-+ int fput_needed_in, fput_needed_out;
-
- /*
- * Get input file, and verify that it is ok..
-@@ -724,7 +725,7 @@
- in_inode = in_file->f_path.dentry->d_inode;
- if (!in_inode)
- goto fput_in;
-- if (!in_file->f_op || !in_file->f_op->splice_read)
-+ if (!in_file->f_op || !in_file->f_op->sendfile)
- goto fput_in;
- retval = -ESPIPE;
- if (!ppos)
-@@ -777,7 +778,6 @@
- count = max - pos;
- }
-
-- fl = 0;
- #if 0
- /*
- * We need to debate whether we can enable this or not. The
-@@ -788,7 +788,7 @@
- if (in_file->f_flags & O_NONBLOCK)
- fl = SPLICE_F_NONBLOCK;
- #endif
-- retval = do_splice_direct(in_file, ppos, out_file, count, fl);
-+ retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file);
-
- if (retval > 0) {
- add_rchar(current, retval);
-diff -Nurd linux-2.6.24/fs/reiserfs/file.c linux-2.6.24-oxe810/fs/reiserfs/file.c
---- linux-2.6.24/fs/reiserfs/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/reiserfs/file.c 2008-06-11 17:46:50.000000000 +0200
-@@ -292,6 +292,7 @@
- .open = generic_file_open,
- .release = reiserfs_file_release,
- .fsync = reiserfs_sync_file,
-+ .sendfile = generic_file_sendfile,
- .aio_read = generic_file_aio_read,
- .aio_write = generic_file_aio_write,
- .splice_read = generic_file_splice_read,
-diff -Nurd linux-2.6.24/fs/smbfs/file.c linux-2.6.24-oxe810/fs/smbfs/file.c
---- linux-2.6.24/fs/smbfs/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/smbfs/file.c 2008-06-11 17:47:00.000000000 +0200
-@@ -283,6 +283,27 @@
- return status;
- }
-
-+static ssize_t
-+smb_file_sendfile(struct file *file, loff_t *ppos,
-+ size_t count, read_actor_t actor, void *target)
-+{
-+ struct dentry *dentry = file->f_path.dentry;
-+ ssize_t status;
-+
-+ VERBOSE("file %s/%s, pos=%Ld, count=%d\n",
-+ DENTRY_PATH(dentry), *ppos, count);
-+
-+ status = smb_revalidate_inode(dentry);
-+ if (status) {
-+ PARANOIA("%s/%s validation failed, error=%Zd\n",
-+ DENTRY_PATH(dentry), status);
-+ goto out;
-+ }
-+ status = generic_file_sendfile(file, ppos, count, actor, target);
-+out:
-+ return status;
-+}
-+
- /*
- * This does the "real" work of the write. The generic routine has
- * allocated the page, locked it, done all the page alignment stuff
-@@ -434,6 +455,7 @@
- .open = smb_file_open,
- .release = smb_file_release,
- .fsync = smb_fsync,
-+ .sendfile = smb_file_sendfile,
- .splice_read = smb_file_splice_read,
- };
-
-diff -Nurd linux-2.6.24/fs/splice.c linux-2.6.24-oxe810/fs/splice.c
---- linux-2.6.24/fs/splice.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/splice.c 2008-06-11 17:47:10.000000000 +0200
-@@ -1184,6 +1184,9 @@
- {
- int partial;
-
-+ if (!access_ok(VERIFY_READ, src, n))
-+ return -EFAULT;
-+
- pagefault_disable();
- partial = __copy_from_user_inatomic(dst, src, n);
- pagefault_enable();
-@@ -1236,7 +1239,7 @@
- if (unlikely(!len))
- break;
- error = -EFAULT;
-- if (unlikely(!base))
-+ if (!access_ok(VERIFY_READ, base, len))
- break;
-
- /*
-@@ -1391,6 +1394,11 @@
- error = -EFAULT;
- break;
- }
-+
-+ if (unlikely(!access_ok(VERIFY_WRITE, base, len))) {
-+ error = -EFAULT;
-+ break;
-+ }
-
- sd.len = 0;
- sd.total_len = len;
-diff -Nurd linux-2.6.24/fs/sysv/file.c linux-2.6.24-oxe810/fs/sysv/file.c
---- linux-2.6.24/fs/sysv/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/sysv/file.c 2008-06-11 17:47:00.000000000 +0200
-@@ -27,6 +27,7 @@
- .aio_write = generic_file_aio_write,
- .mmap = generic_file_mmap,
- .fsync = sysv_sync_file,
-+ .sendfile = generic_file_sendfile,
- .splice_read = generic_file_splice_read,
- };
-
-diff -Nurd linux-2.6.24/fs/udf/file.c linux-2.6.24-oxe810/fs/udf/file.c
---- linux-2.6.24/fs/udf/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/udf/file.c 2008-06-11 17:47:10.000000000 +0200
-@@ -246,6 +246,8 @@
- .aio_write = udf_file_aio_write,
- .release = udf_release_file,
- .fsync = udf_fsync_file,
-+ .sendfile = generic_file_sendfile,
-+ .sendfile = generic_file_sendfile,
- .splice_read = generic_file_splice_read,
- };
-
-diff -Nurd linux-2.6.24/fs/ufs/file.c linux-2.6.24-oxe810/fs/ufs/file.c
---- linux-2.6.24/fs/ufs/file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ufs/file.c 2008-06-11 17:46:54.000000000 +0200
-@@ -63,5 +63,6 @@
- .mmap = generic_file_mmap,
- .open = generic_file_open,
- .fsync = ufs_sync_file,
-+ .sendfile = generic_file_sendfile,
- .splice_read = generic_file_splice_read,
- };
-diff -Nurd linux-2.6.24/fs/ufs/util.h linux-2.6.24-oxe810/fs/ufs/util.h
---- linux-2.6.24/fs/ufs/util.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/ufs/util.h 2008-06-11 17:46:54.000000000 +0200
-@@ -58,7 +58,7 @@
- {
- switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
- case UFS_ST_SUNOS:
-- if (fs32_to_cpu(sb, usb3->fs_postblformat == UFS_42POSTBLFMT)) {
-+ if (fs32_to_cpu(sb, usb3->fs_postblformat) == UFS_42POSTBLFMT) {
- usb1->fs_u0.fs_sun.fs_state = cpu_to_fs32(sb, value);
- break;
- }
-diff -Nurd linux-2.6.24/fs/xfs/Makefile-linux-2.6 linux-2.6.24-oxe810/fs/xfs/Makefile-linux-2.6
---- linux-2.6.24/fs/xfs/Makefile-linux-2.6 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/Makefile-linux-2.6 2008-06-11 17:46:48.000000000 +0200
-@@ -15,13 +15,20 @@
- # along with this program; if not, write the Free Software Foundation,
- # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- #
-+CONFIG_XFS_DEBUG := n
-+CONFIG_XFS_TRACE := n
-
- EXTRA_CFLAGS += -Ifs/xfs -Ifs/xfs/linux-2.6 -funsigned-char
-
- XFS_LINUX := linux-2.6
-
-+ifeq ($(CONFIG_XFS_TRACE),y)
-+ EXTRA_CFLAGS += -DCONFIG_XFS_TRACE
-+endif
-+
- ifeq ($(CONFIG_XFS_DEBUG),y)
- EXTRA_CFLAGS += -g
-+ EXTRA_CFLAGS += -DCONFIG_XFS_DEBUG
- endif
-
- obj-$(CONFIG_XFS_FS) += xfs.o
-diff -Nurd linux-2.6.24/fs/xfs/linux-2.6/xfs_buf.c linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_buf.c
---- linux-2.6.24/fs/xfs/linux-2.6/xfs_buf.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_buf.c 2008-06-11 17:46:46.000000000 +0200
-@@ -330,20 +330,26 @@
-
- ASSERT(list_empty(&bp->b_hash_list));
-
-- if (bp->b_flags & (_XBF_PAGE_CACHE|_XBF_PAGES)) {
-+ if (bp->b_flags & _XBF_PAGE_CACHE) {
- uint i;
-
- if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1))
- free_address(bp->b_addr - bp->b_offset);
-
- for (i = 0; i < bp->b_page_count; i++) {
-- struct page *page = bp->b_pages[i];
--
-- if (bp->b_flags & _XBF_PAGE_CACHE)
-- ASSERT(!PagePrivate(page));
-+ struct page *page = bp->b_pages[i];
-+ ASSERT(!PagePrivate(page));
- page_cache_release(page);
- }
- _xfs_buf_free_pages(bp);
-+ } else if (bp->b_flags & _XBF_KMEM_ALLOC) {
-+ /*
-+ * XXX(hch): bp->b_count_desired might be incorrect (see
-+ * xfs_buf_associate_memory for details), but fortunately
-+ * the Linux version of kmem_free ignores the len argument..
-+ */
-+ kmem_free(bp->b_addr, bp->b_count_desired);
-+ _xfs_buf_free_pages(bp);
- }
-
- xfs_buf_deallocate(bp);
-@@ -766,44 +772,46 @@
- size_t len,
- xfs_buftarg_t *target)
- {
-- unsigned long page_count = PAGE_ALIGN(len) >> PAGE_SHIFT;
-- int error, i;
-+ size_t malloc_len = len;
- xfs_buf_t *bp;
-+ void *data;
-+ int error;
-
- bp = xfs_buf_allocate(0);
- if (unlikely(bp == NULL))
- goto fail;
- _xfs_buf_initialize(bp, target, 0, len, 0);
-
-- error = _xfs_buf_get_pages(bp, page_count, 0);
-- if (error)
-+ try_again:
-+ data = kmem_alloc(malloc_len, KM_SLEEP | KM_MAYFAIL | KM_LARGE);
-+ if (unlikely(data == NULL))
- goto fail_free_buf;
-
-- for (i = 0; i < page_count; i++) {
-- bp->b_pages[i] = alloc_page(GFP_KERNEL);
-- if (!bp->b_pages[i])
-- goto fail_free_mem;
-+ /* check whether alignment matches.. */
-+ if ((__psunsigned_t)data !=
-+ ((__psunsigned_t)data & ~target->bt_smask)) {
-+ /* .. else double the size and try again */
-+ kmem_free(data, malloc_len);
-+ malloc_len <<= 1;
-+ goto try_again;
- }
-- bp->b_flags |= _XBF_PAGES;
-
-- error = _xfs_buf_map_pages(bp, XBF_MAPPED);
-- if (unlikely(error)) {
-- printk(KERN_WARNING "%s: failed to map pages\n",
-- __FUNCTION__);
-+ /* Clear the memory contents */
-+ memset(data, 0, malloc_len);
-+
-+ error = xfs_buf_associate_memory(bp, data, len);
-+ if (error)
- goto fail_free_mem;
-- }
-+ bp->b_flags |= _XBF_KMEM_ALLOC;
-
- xfs_buf_unlock(bp);
-
-- XB_TRACE(bp, "no_daddr", len);
-+ XB_TRACE(bp, "no_daddr", data);
- return bp;
--
- fail_free_mem:
-- while (--i >= 0)
-- __free_page(bp->b_pages[i]);
-- _xfs_buf_free_pages(bp);
-+ kmem_free(data, malloc_len);
- fail_free_buf:
-- xfs_buf_deallocate(bp);
-+ xfs_buf_free(bp);
- fail:
- return NULL;
- }
-diff -Nurd linux-2.6.24/fs/xfs/linux-2.6/xfs_buf.h linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_buf.h
---- linux-2.6.24/fs/xfs/linux-2.6/xfs_buf.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_buf.h 2008-06-11 17:46:46.000000000 +0200
-@@ -63,7 +63,7 @@
-
- /* flags used only internally */
- _XBF_PAGE_CACHE = (1 << 17),/* backed by pagecache */
-- _XBF_PAGES = (1 << 18), /* backed by refcounted pages */
-+ _XBF_KMEM_ALLOC = (1 << 18),/* backed by kmem_alloc() */
- _XBF_RUN_QUEUES = (1 << 19),/* run block device task queue */
- _XBF_DELWRI_Q = (1 << 21), /* buffer on delwri queue */
- } xfs_buf_flags_t;
-diff -Nurd linux-2.6.24/fs/xfs/linux-2.6/xfs_file.c linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_file.c
---- linux-2.6.24/fs/xfs/linux-2.6/xfs_file.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_file.c 2008-06-11 17:46:46.000000000 +0200
-@@ -122,6 +122,28 @@
- }
-
- STATIC ssize_t
-+xfs_file_sendfile(
-+ struct file *filp,
-+ loff_t *pos,
-+ size_t count,
-+ read_actor_t actor,
-+ void *target)
-+{
-+ return xfs_sendfile(XFS_I(filp->f_path.dentry->d_inode), filp, pos, 0, count, actor, target);
-+}
-+
-+STATIC ssize_t
-+xfs_file_sendfile_invis(
-+ struct file *filp,
-+ loff_t *pos,
-+ size_t count,
-+ read_actor_t actor,
-+ void *target)
-+{
-+ return xfs_sendfile(XFS_I(filp->f_path.dentry->d_inode), filp, pos, IO_INVIS, count, actor, target);
-+}
-+
-+STATIC ssize_t
- xfs_file_splice_read(
- struct file *infilp,
- loff_t *ppos,
-@@ -350,8 +372,8 @@
-
- size = buf.used;
- de = (struct hack_dirent *)buf.dirent;
-- curr_offset = de->offset /* & 0x7fffffff */;
- while (size > 0) {
-+ curr_offset = de->offset /* & 0x7fffffff */;
- if (filldir(dirent, de->name, de->namlen,
- curr_offset & 0x7fffffff,
- de->ino, de->d_type)) {
-@@ -362,7 +384,6 @@
- sizeof(u64));
- size -= reclen;
- de = (struct hack_dirent *)((char *)de + reclen);
-- curr_offset = de->offset /* & 0x7fffffff */;
- }
- }
-
-@@ -502,8 +523,11 @@
- .llseek = generic_file_llseek,
- .read = do_sync_read,
- .write = do_sync_write,
-+// .readv = xfs_file_readv,
-+// .writev = xfs_file_writev,
- .aio_read = xfs_file_aio_read,
- .aio_write = xfs_file_aio_write,
-+ .sendfile = xfs_file_sendfile,
- .splice_read = xfs_file_splice_read,
- .splice_write = xfs_file_splice_write,
- .unlocked_ioctl = xfs_file_ioctl,
-@@ -525,6 +549,7 @@
- .write = do_sync_write,
- .aio_read = xfs_file_aio_read_invis,
- .aio_write = xfs_file_aio_write_invis,
-+ .sendfile = xfs_file_sendfile_invis,
- .splice_read = xfs_file_splice_read_invis,
- .splice_write = xfs_file_splice_write_invis,
- .unlocked_ioctl = xfs_file_ioctl_invis,
-diff -Nurd linux-2.6.24/fs/xfs/linux-2.6/xfs_lrw.c linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_lrw.c
---- linux-2.6.24/fs/xfs/linux-2.6/xfs_lrw.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_lrw.c 2008-06-11 17:46:46.000000000 +0200
-@@ -271,6 +271,48 @@
- }
-
- ssize_t
-+xfs_sendfile(
-+ xfs_inode_t *ip,
-+ struct file *filp,
-+ loff_t *offset,
-+ int ioflags,
-+ size_t count,
-+ read_actor_t actor,
-+ void *target)
-+{
-+ bhv_vnode_t *vp = XFS_ITOV(ip);
-+ xfs_mount_t *mp = ip->i_mount;
-+ ssize_t ret;
-+
-+ XFS_STATS_INC(xs_read_calls);
-+ if (XFS_FORCED_SHUTDOWN(mp))
-+ return -EIO;
-+
-+ xfs_ilock(ip, XFS_IOLOCK_SHARED);
-+
-+ if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
-+ (!(ioflags & IO_INVIS))) {
-+ bhv_vrwlock_t locktype = VRWLOCK_READ;
-+ int error;
-+
-+ error = XFS_SEND_DATA(mp, DM_EVENT_READ, vp,*offset, count,
-+ FILP_DELAY_FLAG(filp), &locktype);
-+ if (error) {
-+ xfs_iunlock(ip, XFS_IOLOCK_SHARED);
-+ return -error;
-+ }
-+ }
-+ xfs_rw_enter_trace(XFS_SENDFILE_ENTER, &ip->i_iocore,
-+ (void *)(unsigned long)target, count, *offset, ioflags);
-+ ret = generic_file_sendfile(filp, offset, count, actor, target);
-+ if (ret > 0)
-+ XFS_STATS_ADD(xs_read_bytes, ret);
-+
-+ xfs_iunlock(ip, XFS_IOLOCK_SHARED);
-+ return ret;
-+}
-+
-+ssize_t
- xfs_splice_read(
- xfs_inode_t *ip,
- struct file *infilp,
-diff -Nurd linux-2.6.24/fs/xfs/xfs_alloc.c linux-2.6.24-oxe810/fs/xfs/xfs_alloc.c
---- linux-2.6.24/fs/xfs/xfs_alloc.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_alloc.c 2008-06-11 17:46:48.000000000 +0200
-@@ -592,7 +592,7 @@
- if (!(args->wasfromfl)) {
-
- agf = XFS_BUF_TO_AGF(args->agbp);
-- be32_add(&agf->agf_freeblks, -(args->len));
-+ be32_add_cpu(&agf->agf_freeblks, -(args->len));
- xfs_trans_agblocks_delta(args->tp,
- -((long)(args->len)));
- args->pag->pagf_freeblks -= args->len;
-@@ -1720,7 +1720,7 @@
-
- agf = XFS_BUF_TO_AGF(agbp);
- pag = &mp->m_perag[agno];
-- be32_add(&agf->agf_freeblks, len);
-+ be32_add_cpu(&agf->agf_freeblks, len);
- xfs_trans_agblocks_delta(tp, len);
- pag->pagf_freeblks += len;
- XFS_WANT_CORRUPTED_GOTO(
-@@ -2008,18 +2008,18 @@
- * Get the block number and update the data structures.
- */
- bno = be32_to_cpu(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)]);
-- be32_add(&agf->agf_flfirst, 1);
-+ be32_add_cpu(&agf->agf_flfirst, 1);
- xfs_trans_brelse(tp, agflbp);
- if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp))
- agf->agf_flfirst = 0;
- pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)];
-- be32_add(&agf->agf_flcount, -1);
-+ be32_add_cpu(&agf->agf_flcount, -1);
- xfs_trans_agflist_delta(tp, -1);
- pag->pagf_flcount--;
-
- logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT;
- if (btreeblk) {
-- be32_add(&agf->agf_btreeblks, 1);
-+ be32_add_cpu(&agf->agf_btreeblks, 1);
- pag->pagf_btreeblks++;
- logflags |= XFS_AGF_BTREEBLKS;
- }
-@@ -2117,17 +2117,17 @@
- be32_to_cpu(agf->agf_seqno), &agflbp)))
- return error;
- agfl = XFS_BUF_TO_AGFL(agflbp);
-- be32_add(&agf->agf_fllast, 1);
-+ be32_add_cpu(&agf->agf_fllast, 1);
- if (be32_to_cpu(agf->agf_fllast) == XFS_AGFL_SIZE(mp))
- agf->agf_fllast = 0;
- pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)];
-- be32_add(&agf->agf_flcount, 1);
-+ be32_add_cpu(&agf->agf_flcount, 1);
- xfs_trans_agflist_delta(tp, 1);
- pag->pagf_flcount++;
-
- logflags = XFS_AGF_FLLAST | XFS_AGF_FLCOUNT;
- if (btreeblk) {
-- be32_add(&agf->agf_btreeblks, -1);
-+ be32_add_cpu(&agf->agf_btreeblks, -1);
- pag->pagf_btreeblks--;
- logflags |= XFS_AGF_BTREEBLKS;
- }
-diff -Nurd linux-2.6.24/fs/xfs/xfs_alloc_btree.c linux-2.6.24-oxe810/fs/xfs/xfs_alloc_btree.c
---- linux-2.6.24/fs/xfs/xfs_alloc_btree.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_alloc_btree.c 2008-06-11 17:46:48.000000000 +0200
-@@ -221,7 +221,7 @@
- */
- bno = be32_to_cpu(agf->agf_roots[cur->bc_btnum]);
- agf->agf_roots[cur->bc_btnum] = *lpp;
-- be32_add(&agf->agf_levels[cur->bc_btnum], -1);
-+ be32_add_cpu(&agf->agf_levels[cur->bc_btnum], -1);
- mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_levels[cur->bc_btnum]--;
- /*
- * Put this buffer/block on the ag's freelist.
-@@ -1256,9 +1256,9 @@
- /*
- * Bump and log left's numrecs, decrement and log right's numrecs.
- */
-- be16_add(&left->bb_numrecs, 1);
-+ be16_add_cpu(&left->bb_numrecs, 1);
- xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
-- be16_add(&right->bb_numrecs, -1);
-+ be16_add_cpu(&right->bb_numrecs, -1);
- xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
- /*
- * Slide the contents of right down one entry.
-@@ -1346,7 +1346,7 @@
-
- agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
- agf->agf_roots[cur->bc_btnum] = cpu_to_be32(nbno);
-- be32_add(&agf->agf_levels[cur->bc_btnum], 1);
-+ be32_add_cpu(&agf->agf_levels[cur->bc_btnum], 1);
- seqno = be32_to_cpu(agf->agf_seqno);
- mp->m_perag[seqno].pagf_levels[cur->bc_btnum]++;
- xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
-@@ -1558,9 +1558,9 @@
- /*
- * Decrement and log left's numrecs, bump and log right's numrecs.
- */
-- be16_add(&left->bb_numrecs, -1);
-+ be16_add_cpu(&left->bb_numrecs, -1);
- xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
-- be16_add(&right->bb_numrecs, 1);
-+ be16_add_cpu(&right->bb_numrecs, 1);
- xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
- /*
- * Using a temporary cursor, update the parent key values of the
-@@ -1643,7 +1643,7 @@
- */
- if ((be16_to_cpu(left->bb_numrecs) & 1) &&
- cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
-- be16_add(&right->bb_numrecs, 1);
-+ be16_add_cpu(&right->bb_numrecs, 1);
- i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
- /*
- * For non-leaf blocks, copy keys and addresses over to the new block.
-@@ -1689,7 +1689,7 @@
- * Adjust numrecs, sibling pointers.
- */
- lbno = XFS_DADDR_TO_AGBNO(cur->bc_mp, XFS_BUF_ADDR(lbp));
-- be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
-+ be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
- right->bb_rightsib = left->bb_rightsib;
- left->bb_rightsib = cpu_to_be32(rbno);
- right->bb_leftsib = cpu_to_be32(lbno);
-diff -Nurd linux-2.6.24/fs/xfs/xfs_attr_leaf.c linux-2.6.24-oxe810/fs/xfs/xfs_attr_leaf.c
---- linux-2.6.24/fs/xfs/xfs_attr_leaf.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_attr_leaf.c 2008-06-11 17:46:48.000000000 +0200
-@@ -319,7 +319,7 @@
- memcpy(sfe->nameval, args->name, args->namelen);
- memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen);
- sf->hdr.count++;
-- be16_add(&sf->hdr.totsize, size);
-+ be16_add_cpu(&sf->hdr.totsize, size);
- xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
-
- xfs_sbversion_add_attr2(mp, args->trans);
-@@ -365,7 +365,7 @@
- if (end != totsize)
- memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end);
- sf->hdr.count--;
-- be16_add(&sf->hdr.totsize, -size);
-+ be16_add_cpu(&sf->hdr.totsize, -size);
-
- /*
- * Fix up the start offset of the attribute fork
-@@ -1135,7 +1135,7 @@
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry)));
- }
-- be16_add(&hdr->count, 1);
-+ be16_add_cpu(&hdr->count, 1);
-
- /*
- * Allocate space for the new string (at the end of the run).
-@@ -1149,7 +1149,7 @@
- mp->m_sb.sb_blocksize, NULL));
- ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp));
- ASSERT((be16_to_cpu(map->size) & 0x3) == 0);
-- be16_add(&map->size,
-+ be16_add_cpu(&map->size,
- -xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
- mp->m_sb.sb_blocksize, &tmp));
- entry->nameidx = cpu_to_be16(be16_to_cpu(map->base) +
-@@ -1216,12 +1216,12 @@
- map = &hdr->freemap[0];
- for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; map++, i++) {
- if (be16_to_cpu(map->base) == tmp) {
-- be16_add(&map->base, sizeof(xfs_attr_leaf_entry_t));
-- be16_add(&map->size,
-+ be16_add_cpu(&map->base, sizeof(xfs_attr_leaf_entry_t));
-+ be16_add_cpu(&map->size,
- -((int)sizeof(xfs_attr_leaf_entry_t)));
- }
- }
-- be16_add(&hdr->usedbytes, xfs_attr_leaf_entsize(leaf, args->index));
-+ be16_add_cpu(&hdr->usedbytes, xfs_attr_leaf_entsize(leaf, args->index));
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr)));
- return(0);
-@@ -1729,9 +1729,9 @@
- ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp));
- ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp));
- if (be16_to_cpu(map->base) == tablesize) {
-- be16_add(&map->base,
-+ be16_add_cpu(&map->base,
- -((int)sizeof(xfs_attr_leaf_entry_t)));
-- be16_add(&map->size, sizeof(xfs_attr_leaf_entry_t));
-+ be16_add_cpu(&map->size, sizeof(xfs_attr_leaf_entry_t));
- }
-
- if ((be16_to_cpu(map->base) + be16_to_cpu(map->size))
-@@ -1753,19 +1753,19 @@
- if ((before >= 0) || (after >= 0)) {
- if ((before >= 0) && (after >= 0)) {
- map = &hdr->freemap[before];
-- be16_add(&map->size, entsize);
-- be16_add(&map->size,
-+ be16_add_cpu(&map->size, entsize);
-+ be16_add_cpu(&map->size,
- be16_to_cpu(hdr->freemap[after].size));
- hdr->freemap[after].base = 0;
- hdr->freemap[after].size = 0;
- } else if (before >= 0) {
- map = &hdr->freemap[before];
-- be16_add(&map->size, entsize);
-+ be16_add_cpu(&map->size, entsize);
- } else {
- map = &hdr->freemap[after];
- /* both on-disk, don't endian flip twice */
- map->base = entry->nameidx;
-- be16_add(&map->size, entsize);
-+ be16_add_cpu(&map->size, entsize);
- }
- } else {
- /*
-@@ -1790,7 +1790,7 @@
- * Compress the remaining entries and zero out the removed stuff.
- */
- memset(XFS_ATTR_LEAF_NAME(leaf, args->index), 0, entsize);
-- be16_add(&hdr->usedbytes, -entsize);
-+ be16_add_cpu(&hdr->usedbytes, -entsize);
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, XFS_ATTR_LEAF_NAME(leaf, args->index),
- entsize));
-@@ -1798,7 +1798,7 @@
- tmp = (be16_to_cpu(hdr->count) - args->index)
- * sizeof(xfs_attr_leaf_entry_t);
- memmove((char *)entry, (char *)(entry+1), tmp);
-- be16_add(&hdr->count, -1);
-+ be16_add_cpu(&hdr->count, -1);
- xfs_da_log_buf(args->trans, bp,
- XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry)));
- entry = &leaf->entries[be16_to_cpu(hdr->count)];
-@@ -2184,15 +2184,15 @@
- */
- if (entry_s->flags & XFS_ATTR_INCOMPLETE) { /* skip partials? */
- memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp);
-- be16_add(&hdr_s->usedbytes, -tmp);
-- be16_add(&hdr_s->count, -1);
-+ be16_add_cpu(&hdr_s->usedbytes, -tmp);
-+ be16_add_cpu(&hdr_s->count, -1);
- entry_d--; /* to compensate for ++ in loop hdr */
- desti--;
- if ((start_s + i) < offset)
- result++; /* insertion index adjustment */
- } else {
- #endif /* GROT */
-- be16_add(&hdr_d->firstused, -tmp);
-+ be16_add_cpu(&hdr_d->firstused, -tmp);
- /* both on-disk, don't endian flip twice */
- entry_d->hashval = entry_s->hashval;
- /* both on-disk, don't endian flip twice */
-@@ -2205,10 +2205,10 @@
- ASSERT(be16_to_cpu(entry_s->nameidx) + tmp
- <= XFS_LBSIZE(mp));
- memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp);
-- be16_add(&hdr_s->usedbytes, -tmp);
-- be16_add(&hdr_d->usedbytes, tmp);
-- be16_add(&hdr_s->count, -1);
-- be16_add(&hdr_d->count, 1);
-+ be16_add_cpu(&hdr_s->usedbytes, -tmp);
-+ be16_add_cpu(&hdr_d->usedbytes, tmp);
-+ be16_add_cpu(&hdr_s->count, -1);
-+ be16_add_cpu(&hdr_d->count, 1);
- tmp = be16_to_cpu(hdr_d->count)
- * sizeof(xfs_attr_leaf_entry_t)
- + sizeof(xfs_attr_leaf_hdr_t);
-@@ -2249,7 +2249,7 @@
- * Fill in the freemap information
- */
- hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t));
-- be16_add(&hdr_d->freemap[0].base, be16_to_cpu(hdr_d->count) *
-+ be16_add_cpu(&hdr_d->freemap[0].base, be16_to_cpu(hdr_d->count) *
- sizeof(xfs_attr_leaf_entry_t));
- hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused)
- - be16_to_cpu(hdr_d->freemap[0].base));
-diff -Nurd linux-2.6.24/fs/xfs/xfs_bmap_btree.c linux-2.6.24-oxe810/fs/xfs/xfs_bmap_btree.c
---- linux-2.6.24/fs/xfs/xfs_bmap_btree.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_bmap_btree.c 2008-06-11 17:46:48.000000000 +0200
-@@ -631,7 +631,7 @@
- memcpy(lrp, rrp, numrrecs * sizeof(*lrp));
- xfs_bmbt_log_recs(cur, lbp, numlrecs + 1, numlrecs + numrrecs);
- }
-- be16_add(&left->bb_numrecs, numrrecs);
-+ be16_add_cpu(&left->bb_numrecs, numrrecs);
- left->bb_rightsib = right->bb_rightsib;
- xfs_bmbt_log_block(cur, lbp, XFS_BB_RIGHTSIB | XFS_BB_NUMRECS);
- if (be64_to_cpu(left->bb_rightsib) != NULLDFSBNO) {
-@@ -924,7 +924,7 @@
- xfs_iroot_realloc(ip, i, cur->bc_private.b.whichfork);
- block = ifp->if_broot;
- }
-- be16_add(&block->bb_numrecs, i);
-+ be16_add_cpu(&block->bb_numrecs, i);
- ASSERT(block->bb_numrecs == cblock->bb_numrecs);
- kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
- ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur);
-@@ -947,7 +947,7 @@
- XFS_TRANS_DQ_BCOUNT, -1L);
- xfs_trans_binval(cur->bc_tp, cbp);
- cur->bc_bufs[level - 1] = NULL;
-- be16_add(&block->bb_level, -1);
-+ be16_add_cpu(&block->bb_level, -1);
- xfs_trans_log_inode(cur->bc_tp, ip,
- XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
- cur->bc_nlevels--;
-@@ -1401,9 +1401,9 @@
- key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp));
- rkp = &key;
- }
-- be16_add(&left->bb_numrecs, -1);
-+ be16_add_cpu(&left->bb_numrecs, -1);
- xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS);
-- be16_add(&right->bb_numrecs, 1);
-+ be16_add_cpu(&right->bb_numrecs, 1);
- #ifdef DEBUG
- if (level > 0)
- xfs_btree_check_key(XFS_BTNUM_BMAP, rkp, rkp + 1);
-@@ -1535,7 +1535,7 @@
- right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2);
- if ((be16_to_cpu(left->bb_numrecs) & 1) &&
- cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
-- be16_add(&right->bb_numrecs, 1);
-+ be16_add_cpu(&right->bb_numrecs, 1);
- i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
- if (level > 0) {
- lkp = XFS_BMAP_KEY_IADDR(left, i, cur);
-@@ -1562,7 +1562,7 @@
- xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
- *startoff = xfs_bmbt_disk_get_startoff(rrp);
- }
-- be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
-+ be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
- right->bb_rightsib = left->bb_rightsib;
- left->bb_rightsib = cpu_to_be64(args.fsbno);
- right->bb_leftsib = cpu_to_be64(lbno);
-@@ -2241,7 +2241,7 @@
- bp = xfs_btree_get_bufl(args.mp, cur->bc_tp, args.fsbno, 0);
- cblock = XFS_BUF_TO_BMBT_BLOCK(bp);
- *cblock = *block;
-- be16_add(&block->bb_level, 1);
-+ be16_add_cpu(&block->bb_level, 1);
- block->bb_numrecs = cpu_to_be16(1);
- cur->bc_nlevels++;
- cur->bc_ptrs[level + 1] = 1;
-diff -Nurd linux-2.6.24/fs/xfs/xfs_da_btree.c linux-2.6.24-oxe810/fs/xfs/xfs_da_btree.c
---- linux-2.6.24/fs/xfs/xfs_da_btree.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_da_btree.c 2008-06-11 17:46:48.000000000 +0200
-@@ -511,12 +511,12 @@
- * Move the req'd B-tree elements from high in node1 to
- * low in node2.
- */
-- be16_add(&node2->hdr.count, count);
-+ be16_add_cpu(&node2->hdr.count, count);
- tmp = count * (uint)sizeof(xfs_da_node_entry_t);
- btree_s = &node1->btree[be16_to_cpu(node1->hdr.count) - count];
- btree_d = &node2->btree[0];
- memcpy(btree_d, btree_s, tmp);
-- be16_add(&node1->hdr.count, -count);
-+ be16_add_cpu(&node1->hdr.count, -count);
- } else {
- /*
- * Move the req'd B-tree elements from low in node2 to
-@@ -527,7 +527,7 @@
- btree_s = &node2->btree[0];
- btree_d = &node1->btree[be16_to_cpu(node1->hdr.count)];
- memcpy(btree_d, btree_s, tmp);
-- be16_add(&node1->hdr.count, count);
-+ be16_add_cpu(&node1->hdr.count, count);
- xfs_da_log_buf(tp, blk1->bp,
- XFS_DA_LOGRANGE(node1, btree_d, tmp));
-
-@@ -539,7 +539,7 @@
- btree_s = &node2->btree[count];
- btree_d = &node2->btree[0];
- memmove(btree_d, btree_s, tmp);
-- be16_add(&node2->hdr.count, -count);
-+ be16_add_cpu(&node2->hdr.count, -count);
- }
-
- /*
-@@ -604,7 +604,7 @@
- btree->before = cpu_to_be32(newblk->blkno);
- xfs_da_log_buf(state->args->trans, oldblk->bp,
- XFS_DA_LOGRANGE(node, btree, tmp + sizeof(*btree)));
-- be16_add(&node->hdr.count, 1);
-+ be16_add_cpu(&node->hdr.count, 1);
- xfs_da_log_buf(state->args->trans, oldblk->bp,
- XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr)));
-
-@@ -959,7 +959,7 @@
- memset((char *)btree, 0, sizeof(xfs_da_node_entry_t));
- xfs_da_log_buf(state->args->trans, drop_blk->bp,
- XFS_DA_LOGRANGE(node, btree, sizeof(*btree)));
-- be16_add(&node->hdr.count, -1);
-+ be16_add_cpu(&node->hdr.count, -1);
- xfs_da_log_buf(state->args->trans, drop_blk->bp,
- XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr)));
-
-@@ -1018,7 +1018,7 @@
- */
- tmp = be16_to_cpu(drop_node->hdr.count) * (uint)sizeof(xfs_da_node_entry_t);
- memcpy(btree, &drop_node->btree[0], tmp);
-- be16_add(&save_node->hdr.count, be16_to_cpu(drop_node->hdr.count));
-+ be16_add_cpu(&save_node->hdr.count, be16_to_cpu(drop_node->hdr.count));
-
- xfs_da_log_buf(tp, save_blk->bp,
- XFS_DA_LOGRANGE(save_node, &save_node->hdr,
-diff -Nurd linux-2.6.24/fs/xfs/xfs_dir2_block.c linux-2.6.24-oxe810/fs/xfs/xfs_dir2_block.c
---- linux-2.6.24/fs/xfs/xfs_dir2_block.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_dir2_block.c 2008-06-11 17:46:48.000000000 +0200
-@@ -271,7 +271,7 @@
- }
- lfloglow = toidx + 1 - (be32_to_cpu(btp->stale) - 1);
- lfloghigh -= be32_to_cpu(btp->stale) - 1;
-- be32_add(&btp->count, -(be32_to_cpu(btp->stale) - 1));
-+ be32_add_cpu(&btp->count, -(be32_to_cpu(btp->stale) - 1));
- xfs_dir2_data_make_free(tp, bp,
- (xfs_dir2_data_aoff_t)((char *)blp - (char *)block),
- (xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)),
-@@ -326,7 +326,7 @@
- /*
- * Update the tail (entry count).
- */
-- be32_add(&btp->count, 1);
-+ be32_add_cpu(&btp->count, 1);
- /*
- * If we now need to rebuild the bestfree map, do so.
- * This needs to happen before the next call to use_free.
-@@ -387,7 +387,7 @@
- lfloglow = MIN(mid, lfloglow);
- lfloghigh = MAX(highstale, lfloghigh);
- }
-- be32_add(&btp->stale, -1);
-+ be32_add_cpu(&btp->stale, -1);
- }
- /*
- * Point to the new data entry.
-@@ -767,7 +767,7 @@
- /*
- * Fix up the block tail.
- */
-- be32_add(&btp->stale, 1);
-+ be32_add_cpu(&btp->stale, 1);
- xfs_dir2_block_log_tail(tp, bp);
- /*
- * Remove the leaf entry by marking it stale.
-diff -Nurd linux-2.6.24/fs/xfs/xfs_dir2_data.c linux-2.6.24-oxe810/fs/xfs/xfs_dir2_data.c
---- linux-2.6.24/fs/xfs/xfs_dir2_data.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_dir2_data.c 2008-06-11 17:46:48.000000000 +0200
-@@ -587,7 +587,7 @@
- /*
- * Fix up the new big freespace.
- */
-- be16_add(&prevdup->length, len + be16_to_cpu(postdup->length));
-+ be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length));
- *xfs_dir2_data_unused_tag_p(prevdup) =
- cpu_to_be16((char *)prevdup - (char *)d);
- xfs_dir2_data_log_unused(tp, bp, prevdup);
-@@ -621,7 +621,7 @@
- */
- else if (prevdup) {
- dfp = xfs_dir2_data_freefind(d, prevdup);
-- be16_add(&prevdup->length, len);
-+ be16_add_cpu(&prevdup->length, len);
- *xfs_dir2_data_unused_tag_p(prevdup) =
- cpu_to_be16((char *)prevdup - (char *)d);
- xfs_dir2_data_log_unused(tp, bp, prevdup);
-diff -Nurd linux-2.6.24/fs/xfs/xfs_dir2_leaf.c linux-2.6.24-oxe810/fs/xfs/xfs_dir2_leaf.c
---- linux-2.6.24/fs/xfs/xfs_dir2_leaf.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_dir2_leaf.c 2008-06-11 17:46:48.000000000 +0200
-@@ -359,7 +359,7 @@
- bestsp--;
- memmove(&bestsp[0], &bestsp[1],
- be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0]));
-- be32_add(<p->bestcount, 1);
-+ be32_add_cpu(<p->bestcount, 1);
- xfs_dir2_leaf_log_tail(tp, lbp);
- xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
- }
-@@ -445,7 +445,7 @@
- */
- lfloglow = index;
- lfloghigh = be16_to_cpu(leaf->hdr.count);
-- be16_add(&leaf->hdr.count, 1);
-+ be16_add_cpu(&leaf->hdr.count, 1);
- }
- /*
- * There are stale entries.
-@@ -523,7 +523,7 @@
- lfloglow = MIN(index, lfloglow);
- lfloghigh = MAX(highstale, lfloghigh);
- }
-- be16_add(&leaf->hdr.stale, -1);
-+ be16_add_cpu(&leaf->hdr.stale, -1);
- }
- /*
- * Fill in the new leaf entry.
-@@ -626,7 +626,7 @@
- * Update and log the header, log the leaf entries.
- */
- ASSERT(be16_to_cpu(leaf->hdr.stale) == from - to);
-- be16_add(&leaf->hdr.count, -(be16_to_cpu(leaf->hdr.stale)));
-+ be16_add_cpu(&leaf->hdr.count, -(be16_to_cpu(leaf->hdr.stale)));
- leaf->hdr.stale = 0;
- xfs_dir2_leaf_log_header(args->trans, bp);
- if (loglow != -1)
-@@ -728,7 +728,7 @@
- /*
- * Adjust the leaf header values.
- */
-- be16_add(&leaf->hdr.count, -(from - to));
-+ be16_add_cpu(&leaf->hdr.count, -(from - to));
- leaf->hdr.stale = cpu_to_be16(1);
- /*
- * Remember the low/high stale value only in the "right"
-@@ -1470,7 +1470,7 @@
- /*
- * We just mark the leaf entry stale by putting a null in it.
- */
-- be16_add(&leaf->hdr.stale, 1);
-+ be16_add_cpu(&leaf->hdr.stale, 1);
- xfs_dir2_leaf_log_header(tp, lbp);
- lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
- xfs_dir2_leaf_log_ents(tp, lbp, index, index);
-@@ -1531,7 +1531,7 @@
- */
- memmove(&bestsp[db - i], bestsp,
- (be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp));
-- be32_add(<p->bestcount, -(db - i));
-+ be32_add_cpu(<p->bestcount, -(db - i));
- xfs_dir2_leaf_log_tail(tp, lbp);
- xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
- } else
-@@ -1712,7 +1712,7 @@
- * Eliminate the last bests entry from the table.
- */
- bestsp = xfs_dir2_leaf_bests_p(ltp);
-- be32_add(<p->bestcount, -1);
-+ be32_add_cpu(<p->bestcount, -1);
- memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp));
- xfs_dir2_leaf_log_tail(tp, lbp);
- xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
-diff -Nurd linux-2.6.24/fs/xfs/xfs_dir2_node.c linux-2.6.24-oxe810/fs/xfs/xfs_dir2_node.c
---- linux-2.6.24/fs/xfs/xfs_dir2_node.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_dir2_node.c 2008-06-11 17:46:48.000000000 +0200
-@@ -254,7 +254,7 @@
- (be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep));
- lfloglow = index;
- lfloghigh = be16_to_cpu(leaf->hdr.count);
-- be16_add(&leaf->hdr.count, 1);
-+ be16_add_cpu(&leaf->hdr.count, 1);
- }
- /*
- * There are stale entries. We'll use one for the new entry.
-@@ -322,7 +322,7 @@
- lfloglow = MIN(index, lfloglow);
- lfloghigh = MAX(highstale, lfloghigh);
- }
-- be16_add(&leaf->hdr.stale, -1);
-+ be16_add_cpu(&leaf->hdr.stale, -1);
- }
- /*
- * Insert the new entry, log everything.
-@@ -697,10 +697,10 @@
- /*
- * Update the headers and log them.
- */
-- be16_add(&leaf_s->hdr.count, -(count));
-- be16_add(&leaf_s->hdr.stale, -(stale));
-- be16_add(&leaf_d->hdr.count, count);
-- be16_add(&leaf_d->hdr.stale, stale);
-+ be16_add_cpu(&leaf_s->hdr.count, -(count));
-+ be16_add_cpu(&leaf_s->hdr.stale, -(stale));
-+ be16_add_cpu(&leaf_d->hdr.count, count);
-+ be16_add_cpu(&leaf_d->hdr.stale, stale);
- xfs_dir2_leaf_log_header(tp, bp_s);
- xfs_dir2_leaf_log_header(tp, bp_d);
- xfs_dir2_leafn_check(args->dp, bp_s);
-@@ -885,7 +885,7 @@
- * Kill the leaf entry by marking it stale.
- * Log the leaf block changes.
- */
-- be16_add(&leaf->hdr.stale, 1);
-+ be16_add_cpu(&leaf->hdr.stale, 1);
- xfs_dir2_leaf_log_header(tp, bp);
- lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
- xfs_dir2_leaf_log_ents(tp, bp, index, index);
-@@ -971,7 +971,7 @@
- /*
- * One less used entry in the free table.
- */
-- be32_add(&free->hdr.nused, -1);
-+ be32_add_cpu(&free->hdr.nused, -1);
- xfs_dir2_free_log_header(tp, fbp);
- /*
- * If this was the last entry in the table, we can
-@@ -1642,7 +1642,7 @@
- * (this should always be true) then update the header.
- */
- if (be16_to_cpu(free->bests[findex]) == NULLDATAOFF) {
-- be32_add(&free->hdr.nused, 1);
-+ be32_add_cpu(&free->hdr.nused, 1);
- xfs_dir2_free_log_header(tp, fbp);
- }
- /*
-diff -Nurd linux-2.6.24/fs/xfs/xfs_fsops.c linux-2.6.24-oxe810/fs/xfs/xfs_fsops.c
---- linux-2.6.24/fs/xfs/xfs_fsops.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_fsops.c 2008-06-11 17:46:48.000000000 +0200
-@@ -318,7 +318,7 @@
- }
- ASSERT(bp);
- agi = XFS_BUF_TO_AGI(bp);
-- be32_add(&agi->agi_length, new);
-+ be32_add_cpu(&agi->agi_length, new);
- ASSERT(nagcount == oagcount ||
- be32_to_cpu(agi->agi_length) == mp->m_sb.sb_agblocks);
- xfs_ialloc_log_agi(tp, bp, XFS_AGI_LENGTH);
-@@ -331,7 +331,7 @@
- }
- ASSERT(bp);
- agf = XFS_BUF_TO_AGF(bp);
-- be32_add(&agf->agf_length, new);
-+ be32_add_cpu(&agf->agf_length, new);
- ASSERT(be32_to_cpu(agf->agf_length) ==
- be32_to_cpu(agi->agi_length));
- xfs_alloc_log_agf(tp, bp, XFS_AGF_LENGTH);
-diff -Nurd linux-2.6.24/fs/xfs/xfs_ialloc.c linux-2.6.24-oxe810/fs/xfs/xfs_ialloc.c
---- linux-2.6.24/fs/xfs/xfs_ialloc.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_ialloc.c 2008-06-11 17:46:48.000000000 +0200
-@@ -301,8 +301,8 @@
- }
- xfs_trans_inode_alloc_buf(tp, fbuf);
- }
-- be32_add(&agi->agi_count, newlen);
-- be32_add(&agi->agi_freecount, newlen);
-+ be32_add_cpu(&agi->agi_count, newlen);
-+ be32_add_cpu(&agi->agi_freecount, newlen);
- agno = be32_to_cpu(agi->agi_seqno);
- down_read(&args.mp->m_peraglock);
- args.mp->m_perag[agno].pagi_freecount += newlen;
-@@ -885,7 +885,7 @@
- if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount,
- rec.ir_free)))
- goto error0;
-- be32_add(&agi->agi_freecount, -1);
-+ be32_add_cpu(&agi->agi_freecount, -1);
- xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
- down_read(&mp->m_peraglock);
- mp->m_perag[tagno].pagi_freecount--;
-@@ -1065,8 +1065,8 @@
- * to be freed when the transaction is committed.
- */
- ilen = XFS_IALLOC_INODES(mp);
-- be32_add(&agi->agi_count, -ilen);
-- be32_add(&agi->agi_freecount, -(ilen - 1));
-+ be32_add_cpu(&agi->agi_count, -ilen);
-+ be32_add_cpu(&agi->agi_freecount, -(ilen - 1));
- xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT);
- down_read(&mp->m_peraglock);
- mp->m_perag[agno].pagi_freecount -= ilen - 1;
-@@ -1095,7 +1095,7 @@
- /*
- * Change the inode free counts and log the ag/sb changes.
- */
-- be32_add(&agi->agi_freecount, 1);
-+ be32_add_cpu(&agi->agi_freecount, 1);
- xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
- down_read(&mp->m_peraglock);
- mp->m_perag[agno].pagi_freecount++;
-diff -Nurd linux-2.6.24/fs/xfs/xfs_ialloc_btree.c linux-2.6.24-oxe810/fs/xfs/xfs_ialloc_btree.c
---- linux-2.6.24/fs/xfs/xfs_ialloc_btree.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_ialloc_btree.c 2008-06-11 17:46:48.000000000 +0200
-@@ -189,7 +189,7 @@
- */
- bno = be32_to_cpu(agi->agi_root);
- agi->agi_root = *pp;
-- be32_add(&agi->agi_level, -1);
-+ be32_add_cpu(&agi->agi_level, -1);
- /*
- * Free the block.
- */
-@@ -1132,7 +1132,7 @@
- /*
- * Bump and log left's numrecs, decrement and log right's numrecs.
- */
-- be16_add(&left->bb_numrecs, 1);
-+ be16_add_cpu(&left->bb_numrecs, 1);
- xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
- #ifdef DEBUG
- if (level > 0)
-@@ -1140,7 +1140,7 @@
- else
- xfs_btree_check_rec(cur->bc_btnum, lrp - 1, lrp);
- #endif
-- be16_add(&right->bb_numrecs, -1);
-+ be16_add_cpu(&right->bb_numrecs, -1);
- xfs_inobt_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
- /*
- * Slide the contents of right down one entry.
-@@ -1232,7 +1232,7 @@
- * Set the root data in the a.g. inode structure.
- */
- agi->agi_root = cpu_to_be32(args.agbno);
-- be32_add(&agi->agi_level, 1);
-+ be32_add_cpu(&agi->agi_level, 1);
- xfs_ialloc_log_agi(args.tp, cur->bc_private.i.agbp,
- XFS_AGI_ROOT | XFS_AGI_LEVEL);
- /*
-@@ -1426,9 +1426,9 @@
- /*
- * Decrement and log left's numrecs, bump and log right's numrecs.
- */
-- be16_add(&left->bb_numrecs, -1);
-+ be16_add_cpu(&left->bb_numrecs, -1);
- xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
-- be16_add(&right->bb_numrecs, 1);
-+ be16_add_cpu(&right->bb_numrecs, 1);
- #ifdef DEBUG
- if (level > 0)
- xfs_btree_check_key(cur->bc_btnum, rkp, rkp + 1);
-@@ -1529,7 +1529,7 @@
- */
- if ((be16_to_cpu(left->bb_numrecs) & 1) &&
- cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
-- be16_add(&right->bb_numrecs, 1);
-+ be16_add_cpu(&right->bb_numrecs, 1);
- i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
- /*
- * For non-leaf blocks, copy keys and addresses over to the new block.
-@@ -1565,7 +1565,7 @@
- * Find the left block number by looking in the buffer.
- * Adjust numrecs, sibling pointers.
- */
-- be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
-+ be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
- right->bb_rightsib = left->bb_rightsib;
- left->bb_rightsib = cpu_to_be32(args.agbno);
- right->bb_leftsib = cpu_to_be32(lbno);
-diff -Nurd linux-2.6.24/fs/xfs/xfs_inode.c linux-2.6.24-oxe810/fs/xfs/xfs_inode.c
---- linux-2.6.24/fs/xfs/xfs_inode.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_inode.c 2008-06-11 17:46:48.000000000 +0200
-@@ -1158,6 +1158,16 @@
- if ((prid != 0) && (ip->i_d.di_version == XFS_DINODE_VERSION_1))
- xfs_bump_ino_vers2(tp, ip);
-
-+#ifdef CONFIG_OXNAS_SUID_INHERIT
-+ /* Modification to propagate SUID down directory hierarchy */
-+ if (pip && XFS_INHERIT_UID(pip)) {
-+ ip->i_d.di_uid = pip->i_d.di_uid;
-+ if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) {
-+ ip->i_d.di_mode |= S_ISUID;
-+ }
-+ }
-+#endif // CONFIG_OXNAS_SUID_INHERIT
-+
- if (pip && XFS_INHERIT_GID(pip)) {
- ip->i_d.di_gid = pip->i_d.di_gid;
- if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) {
-diff -Nurd linux-2.6.24/fs/xfs/xfs_inode.h linux-2.6.24-oxe810/fs/xfs/xfs_inode.h
---- linux-2.6.24/fs/xfs/xfs_inode.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_inode.h 2008-06-11 17:46:48.000000000 +0200
-@@ -495,6 +495,11 @@
- #define XFS_INHERIT_GID(pip) \
- (((pip)->i_mount->m_flags & XFS_MOUNT_GRPID) || \
- ((pip)->i_d.di_mode & S_ISGID))
-+#ifdef CONFIG_OXNAS_SUID_INHERIT
-+/* Modification to propagate SUID down directory hierarchy */
-+#define XFS_INHERIT_UID(pip) \
-+ ((pip)->i_d.di_mode & S_ISUID)
-+#endif // CONFIG_OXNAS_SUID_INHERIT
-
- /*
- * Flags for xfs_iget()
-diff -Nurd linux-2.6.24/fs/xfs/xfs_log.c linux-2.6.24-oxe810/fs/xfs/xfs_log.c
---- linux-2.6.24/fs/xfs/xfs_log.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_log.c 2008-06-11 17:46:48.000000000 +0200
-@@ -399,10 +399,10 @@
- {
- xlog_t *log = mp->m_log;
- xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl;
-- int abortflg, spl;
-+ int abortflg;
-
- cb->cb_next = NULL;
-- spl = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
- abortflg = (iclog->ic_state & XLOG_STATE_IOERROR);
- if (!abortflg) {
- ASSERT_ALWAYS((iclog->ic_state == XLOG_STATE_ACTIVE) ||
-@@ -411,7 +411,7 @@
- *(iclog->ic_callback_tail) = cb;
- iclog->ic_callback_tail = &(cb->cb_next);
- }
-- LOG_UNLOCK(log, spl);
-+ spin_unlock(&log->l_icloglock);
- return abortflg;
- } /* xfs_log_notify */
-
-@@ -503,6 +503,8 @@
- xfs_daddr_t blk_offset,
- int num_bblks)
- {
-+ int error;
-+
- if (!(mp->m_flags & XFS_MOUNT_NORECOVERY))
- cmn_err(CE_NOTE, "XFS mounting filesystem %s", mp->m_fsname);
- else {
-@@ -519,7 +521,7 @@
- * just worked.
- */
- if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
-- int error, readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
-+ int readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
-
- if (readonly)
- mp->m_flags &= ~XFS_MOUNT_RDONLY;
-@@ -530,8 +532,8 @@
- mp->m_flags |= XFS_MOUNT_RDONLY;
- if (error) {
- cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error);
-- xlog_dealloc_log(mp->m_log);
-- return error;
-+
-+ goto error;
- }
- }
-
-@@ -540,6 +542,9 @@
-
- /* End mounting message in xfs_log_mount_finish */
- return 0;
-+error:
-+ xfs_log_unmount_dealloc(mp);
-+ return error;
- } /* xfs_log_mount */
-
- /*
-@@ -606,7 +611,6 @@
- xfs_log_ticket_t tic = NULL;
- xfs_lsn_t lsn;
- int error;
-- SPLDECL(s);
-
- /* the data section must be 32 bit size aligned */
- struct {
-@@ -659,24 +663,24 @@
- }
-
-
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
- iclog = log->l_iclog;
- iclog->ic_refcnt++;
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- xlog_state_want_sync(log, iclog);
- (void) xlog_state_release_iclog(log, iclog);
-
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
- if (!(iclog->ic_state == XLOG_STATE_ACTIVE ||
- iclog->ic_state == XLOG_STATE_DIRTY)) {
- if (!XLOG_FORCED_SHUTDOWN(log)) {
- sv_wait(&iclog->ic_forcesema, PMEM,
- &log->l_icloglock, s);
- } else {
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- }
- } else {
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- }
- if (tic) {
- xlog_trace_loggrant(log, tic, "unmount rec");
-@@ -697,15 +701,15 @@
- * a file system that went into forced_shutdown as
- * the result of an unmount..
- */
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
- iclog = log->l_iclog;
- iclog->ic_refcnt++;
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
-
- xlog_state_want_sync(log, iclog);
- (void) xlog_state_release_iclog(log, iclog);
-
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
-
- if ( ! ( iclog->ic_state == XLOG_STATE_ACTIVE
- || iclog->ic_state == XLOG_STATE_DIRTY
-@@ -714,7 +718,7 @@
- sv_wait(&iclog->ic_forcesema, PMEM,
- &log->l_icloglock, s);
- } else {
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- }
- }
-
-@@ -723,6 +727,9 @@
-
- /*
- * Deallocate log structures for unmount/relocation.
-+ *
-+ * We need to stop the aild from running before we destroy
-+ * and deallocate the log as the aild references the log.
- */
- void
- xfs_log_unmount_dealloc(xfs_mount_t *mp)
-@@ -762,20 +769,18 @@
- xlog_ticket_t *tic;
- xlog_t *log = mp->m_log;
- int need_bytes, free_bytes, cycle, bytes;
-- SPLDECL(s);
-
- if (XLOG_FORCED_SHUTDOWN(log))
- return;
-- ASSERT(!XFS_FORCED_SHUTDOWN(mp));
-
- if (tail_lsn == 0) {
- /* needed since sync_lsn is 64 bits */
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
- tail_lsn = log->l_last_sync_lsn;
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- }
-
-- s = GRANT_LOCK(log);
-+ spin_lock(&log->l_grant_lock);
-
- /* Also an invalid lsn. 1 implies that we aren't passing in a valid
- * tail_lsn.
-@@ -824,7 +829,7 @@
- tic = tic->t_next;
- } while (tic != log->l_reserve_headq);
- }
-- GRANT_UNLOCK(log, s);
-+ spin_unlock(&log->l_grant_lock);
- } /* xfs_log_move_tail */
-
- /*
-@@ -836,14 +841,13 @@
- int
- xfs_log_need_covered(xfs_mount_t *mp)
- {
-- SPLDECL(s);
- int needed = 0, gen;
- xlog_t *log = mp->m_log;
-
- if (!xfs_fs_writable(mp))
- return 0;
-
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
- if (((log->l_covered_state == XLOG_STATE_COVER_NEED) ||
- (log->l_covered_state == XLOG_STATE_COVER_NEED2))
- && !xfs_trans_first_ail(mp, &gen)
-@@ -856,7 +860,7 @@
- }
- needed = 1;
- }
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- return needed;
- }
-
-@@ -881,17 +885,16 @@
- xlog_assign_tail_lsn(xfs_mount_t *mp)
- {
- xfs_lsn_t tail_lsn;
-- SPLDECL(s);
- xlog_t *log = mp->m_log;
-
- tail_lsn = xfs_trans_tail_ail(mp);
-- s = GRANT_LOCK(log);
-+ spin_lock(&log->l_grant_lock);
- if (tail_lsn != 0) {
- log->l_tail_lsn = tail_lsn;
- } else {
- tail_lsn = log->l_tail_lsn = log->l_last_sync_lsn;
- }
-- GRANT_UNLOCK(log, s);
-+ spin_unlock(&log->l_grant_lock);
-
- return tail_lsn;
- } /* xlog_assign_tail_lsn */
-@@ -911,7 +914,7 @@
- * the tail. The details of this case are described below, but the end
- * result is that we return the size of the log as the amount of space left.
- */
--int
-+STATIC int
- xlog_space_left(xlog_t *log, int cycle, int bytes)
- {
- int free_bytes;
-@@ -1165,7 +1168,7 @@
- log->l_flags |= XLOG_ACTIVE_RECOVERY;
-
- log->l_prev_block = -1;
-- ASSIGN_ANY_LSN_HOST(log->l_tail_lsn, 1, 0);
-+ log->l_tail_lsn = xlog_assign_lsn(1, 0);
- /* log->l_tail_lsn = 0x100000000LL; cycle = 1; current block = 0 */
- log->l_last_sync_lsn = log->l_tail_lsn;
- log->l_curr_cycle = 1; /* 0 is bad since this is initial value */
-@@ -1193,8 +1196,8 @@
- ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
- log->l_xbuf = bp;
-
-- spinlock_init(&log->l_icloglock, "iclog");
-- spinlock_init(&log->l_grant_lock, "grhead_iclog");
-+ spin_lock_init(&log->l_icloglock);
-+ spin_lock_init(&log->l_grant_lock);
- initnsema(&log->l_flushsema, 0, "ic-flush");
- xlog_state_ticket_alloc(log); /* wait until after icloglock inited */
-
-@@ -1231,12 +1234,12 @@
-
- head = &iclog->ic_header;
- memset(head, 0, sizeof(xlog_rec_header_t));
-- INT_SET(head->h_magicno, ARCH_CONVERT, XLOG_HEADER_MAGIC_NUM);
-- INT_SET(head->h_version, ARCH_CONVERT,
-+ head->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM);
-+ head->h_version = cpu_to_be32(
- XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? 2 : 1);
-- INT_SET(head->h_size, ARCH_CONVERT, log->l_iclog_size);
-+ head->h_size = cpu_to_be32(log->l_iclog_size);
- /* new fields */
-- INT_SET(head->h_fmt, ARCH_CONVERT, XLOG_FMT);
-+ head->h_fmt = cpu_to_be32(XLOG_FMT);
- memcpy(&head->h_fs_uuid, &mp->m_sb.sb_uuid, sizeof(uuid_t));
-
-
-@@ -1293,7 +1296,7 @@
- * pushes on an lsn which is further along in the log once we reach the high
- * water mark. In this manner, we would be creating a low water mark.
- */
--void
-+STATIC void
- xlog_grant_push_ail(xfs_mount_t *mp,
- int need_bytes)
- {
-@@ -1305,11 +1308,10 @@
- int threshold_block; /* block in lsn we'd like to be at */
- int threshold_cycle; /* lsn cycle we'd like to be at */
- int free_threshold;
-- SPLDECL(s);
-
- ASSERT(BTOBB(need_bytes) < log->l_logBBsize);
-
-- s = GRANT_LOCK(log);
-+ spin_lock(&log->l_grant_lock);
- free_bytes = xlog_space_left(log,
- log->l_grant_reserve_cycle,
- log->l_grant_reserve_bytes);
-@@ -1331,8 +1333,7 @@
- threshold_block -= log->l_logBBsize;
- threshold_cycle += 1;
- }
-- ASSIGN_ANY_LSN_HOST(threshold_lsn, threshold_cycle,
-- threshold_block);
-+ threshold_lsn = xlog_assign_lsn(threshold_cycle, threshold_block);
-
- /* Don't pass in an lsn greater than the lsn of the last
- * log record known to be on disk.
-@@ -1340,7 +1341,7 @@
- if (XFS_LSN_CMP(threshold_lsn, log->l_last_sync_lsn) > 0)
- threshold_lsn = log->l_last_sync_lsn;
- }
-- GRANT_UNLOCK(log, s);
-+ spin_unlock(&log->l_grant_lock);
-
- /*
- * Get the transaction layer to kick the dirty buffers out to
-@@ -1378,19 +1379,18 @@
- * is added immediately before calling bwrite().
- */
-
--int
-+STATIC int
- xlog_sync(xlog_t *log,
- xlog_in_core_t *iclog)
- {
- xfs_caddr_t dptr; /* pointer to byte sized element */
- xfs_buf_t *bp;
-- int i, ops;
-+ int i;
- uint count; /* byte count of bwrite */
- uint count_init; /* initial count before roundup */
- int roundoff; /* roundoff to BB or stripe */
- int split = 0; /* split write into two regions */
- int error;
-- SPLDECL(s);
- int v2 = XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb);
-
- XFS_STATS_INC(xs_log_writes);
-@@ -1415,30 +1415,24 @@
- roundoff < BBTOB(1)));
-
- /* move grant heads by roundoff in sync */
-- s = GRANT_LOCK(log);
-+ spin_lock(&log->l_grant_lock);
- xlog_grant_add_space(log, roundoff);
-- GRANT_UNLOCK(log, s);
-+ spin_unlock(&log->l_grant_lock);
-
- /* put cycle number in every block */
- xlog_pack_data(log, iclog, roundoff);
-
- /* real byte length */
- if (v2) {
-- INT_SET(iclog->ic_header.h_len,
-- ARCH_CONVERT,
-- iclog->ic_offset + roundoff);
-+ iclog->ic_header.h_len = cpu_to_be32(iclog->ic_offset + roundoff);
- } else {
-- INT_SET(iclog->ic_header.h_len, ARCH_CONVERT, iclog->ic_offset);
-+ iclog->ic_header.h_len = cpu_to_be32(iclog->ic_offset);
- }
-
-- /* put ops count in correct order */
-- ops = iclog->ic_header.h_num_logops;
-- INT_SET(iclog->ic_header.h_num_logops, ARCH_CONVERT, ops);
--
- bp = iclog->ic_bp;
- ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) == (unsigned long)1);
- XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2);
-- XFS_BUF_SET_ADDR(bp, BLOCK_LSN(INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT)));
-+ XFS_BUF_SET_ADDR(bp, BLOCK_LSN(be64_to_cpu(iclog->ic_header.h_lsn)));
-
- XFS_STATS_ADD(xs_log_blocks, BTOBB(count));
-
-@@ -1450,11 +1444,13 @@
- } else {
- iclog->ic_bwritecnt = 1;
- }
-+
- XFS_BUF_SET_COUNT(bp, count);
- XFS_BUF_SET_FSPRIVATE(bp, iclog); /* save for later */
- XFS_BUF_ZEROFLAGS(bp);
- XFS_BUF_BUSY(bp);
- XFS_BUF_ASYNC(bp);
-+
- /*
- * Do an ordered write for the log block.
- * Its unnecessary to flush the first split block in the log wrap case.
-@@ -1480,6 +1476,7 @@
- XFS_BUF_ADDR(bp));
- return error;
- }
-+
- if (split) {
- bp = iclog->ic_log->l_xbuf;
- ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) ==
-@@ -1501,10 +1498,10 @@
- * a new cycle. Watch out for the header magic number
- * case, though.
- */
-- for (i=0; i<split; i += BBSIZE) {
-- INT_MOD(*(uint *)dptr, ARCH_CONVERT, +1);
-- if (INT_GET(*(uint *)dptr, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM)
-- INT_MOD(*(uint *)dptr, ARCH_CONVERT, +1);
-+ for (i = 0; i < split; i += BBSIZE) {
-+ be32_add_cpu((__be32 *)dptr, 1);
-+ if (be32_to_cpu(*(__be32 *)dptr) == XLOG_HEADER_MAGIC_NUM)
-+ be32_add_cpu((__be32 *)dptr, 1);
- dptr += BBSIZE;
- }
-
-@@ -1520,6 +1517,7 @@
- return error;
- }
- }
-+
- return 0;
- } /* xlog_sync */
-
-@@ -1527,7 +1525,7 @@
- /*
- * Deallocate a log structure
- */
--void
-+STATIC void
- xlog_dealloc_log(xlog_t *log)
- {
- xlog_in_core_t *iclog, *next_iclog;
-@@ -1592,14 +1590,12 @@
- int record_cnt,
- int copy_bytes)
- {
-- SPLDECL(s);
--
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
-
-- iclog->ic_header.h_num_logops += record_cnt;
-+ be32_add_cpu(&iclog->ic_header.h_num_logops, record_cnt);
- iclog->ic_offset += copy_bytes;
-
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- } /* xlog_state_finish_copy */
-
-
-@@ -1752,7 +1748,7 @@
- * we don't update ic_offset until the end when we know exactly how many
- * bytes have been written out.
- */
--int
-+STATIC int
- xlog_write(xfs_mount_t * mp,
- xfs_log_iovec_t reg[],
- int nentries,
-@@ -1823,7 +1819,7 @@
-
- /* start_lsn is the first lsn written to. That's all we need. */
- if (! *start_lsn)
-- *start_lsn = INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT);
-+ *start_lsn = be64_to_cpu(iclog->ic_header.h_lsn);
-
- /* This loop writes out as many regions as can fit in the amount
- * of space which was allocated by xlog_state_get_iclog_space().
-@@ -1839,7 +1835,7 @@
- */
- if (ticket->t_flags & XLOG_TIC_INITED) {
- logop_head = (xlog_op_header_t *)ptr;
-- INT_SET(logop_head->oh_tid, ARCH_CONVERT, ticket->t_tid);
-+ logop_head->oh_tid = cpu_to_be32(ticket->t_tid);
- logop_head->oh_clientid = ticket->t_clientid;
- logop_head->oh_len = 0;
- logop_head->oh_flags = XLOG_START_TRANS;
-@@ -1853,7 +1849,7 @@
-
- /* Copy log operation header directly into data section */
- logop_head = (xlog_op_header_t *)ptr;
-- INT_SET(logop_head->oh_tid, ARCH_CONVERT, ticket->t_tid);
-+ logop_head->oh_tid = cpu_to_be32(ticket->t_tid);
- logop_head->oh_clientid = ticket->t_clientid;
- logop_head->oh_res2 = 0;
-
-@@ -1888,13 +1884,14 @@
-
- copy_off = partial_copy_len;
- if (need_copy <= iclog->ic_size - log_offset) { /*complete write */
-- INT_SET(logop_head->oh_len, ARCH_CONVERT, copy_len = need_copy);
-+ copy_len = need_copy;
-+ logop_head->oh_len = cpu_to_be32(copy_len);
- if (partial_copy)
- logop_head->oh_flags|= (XLOG_END_TRANS|XLOG_WAS_CONT_TRANS);
- partial_copy_len = partial_copy = 0;
- } else { /* partial write */
- copy_len = iclog->ic_size - log_offset;
-- INT_SET(logop_head->oh_len, ARCH_CONVERT, copy_len);
-+ logop_head->oh_len = cpu_to_be32(copy_len);
- logop_head->oh_flags |= XLOG_CONTINUE_TRANS;
- if (partial_copy)
- logop_head->oh_flags |= XLOG_WAS_CONT_TRANS;
-@@ -1992,7 +1989,8 @@
- * We don't need to cover the dummy.
- */
- if (!changed &&
-- (INT_GET(iclog->ic_header.h_num_logops, ARCH_CONVERT) == XLOG_COVER_OPS)) {
-+ (be32_to_cpu(iclog->ic_header.h_num_logops) ==
-+ XLOG_COVER_OPS)) {
- changed = 1;
- } else {
- /*
-@@ -2060,7 +2058,7 @@
- lowest_lsn = 0;
- do {
- if (!(lsn_log->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_DIRTY))) {
-- lsn = INT_GET(lsn_log->ic_header.h_lsn, ARCH_CONVERT);
-+ lsn = be64_to_cpu(lsn_log->ic_header.h_lsn);
- if ((lsn && !lowest_lsn) ||
- (XFS_LSN_CMP(lsn, lowest_lsn) < 0)) {
- lowest_lsn = lsn;
-@@ -2089,9 +2087,8 @@
- int funcdidcallbacks; /* flag: function did callbacks */
- int repeats; /* for issuing console warnings if
- * looping too many times */
-- SPLDECL(s);
-
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
- first_iclog = iclog = log->l_iclog;
- ioerrors = 0;
- funcdidcallbacks = 0;
-@@ -2162,11 +2159,9 @@
- */
-
- lowest_lsn = xlog_get_lowest_lsn(log);
-- if (lowest_lsn && (
-- XFS_LSN_CMP(
-- lowest_lsn,
-- INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT)
-- )<0)) {
-+ if (lowest_lsn &&
-+ XFS_LSN_CMP(lowest_lsn,
-+ be64_to_cpu(iclog->ic_header.h_lsn)) < 0) {
- iclog = iclog->ic_next;
- continue; /* Leave this iclog for
- * another thread */
-@@ -2174,19 +2169,18 @@
-
- iclog->ic_state = XLOG_STATE_CALLBACK;
-
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
-
- /* l_last_sync_lsn field protected by
- * GRANT_LOCK. Don't worry about iclog's lsn.
- * No one else can be here except us.
- */
-- s = GRANT_LOCK(log);
-- ASSERT(XFS_LSN_CMP(
-- log->l_last_sync_lsn,
-- INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT)
-- )<=0);
-- log->l_last_sync_lsn = INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT);
-- GRANT_UNLOCK(log, s);
-+ spin_lock(&log->l_grant_lock);
-+ ASSERT(XFS_LSN_CMP(log->l_last_sync_lsn,
-+ be64_to_cpu(iclog->ic_header.h_lsn)) <= 0);
-+ log->l_last_sync_lsn =
-+ be64_to_cpu(iclog->ic_header.h_lsn);
-+ spin_unlock(&log->l_grant_lock);
-
- /*
- * Keep processing entries in the callback list
-@@ -2195,7 +2189,7 @@
- * empty and change the state to DIRTY so that
- * we don't miss any more callbacks being added.
- */
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
- } else {
- ioerrors++;
- }
-@@ -2204,14 +2198,14 @@
- while (cb) {
- iclog->ic_callback_tail = &(iclog->ic_callback);
- iclog->ic_callback = NULL;
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
-
- /* perform callbacks in the order given */
- for (; cb; cb = cb_next) {
- cb_next = cb->cb_next;
- cb->cb_func(cb->cb_arg, aborted);
- }
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
- cb = iclog->ic_callback;
- }
-
-@@ -2276,7 +2270,7 @@
- flushcnt = log->l_flushcnt;
- log->l_flushcnt = 0;
- }
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- while (flushcnt--)
- vsema(&log->l_flushsema);
- } /* xlog_state_do_callback */
-@@ -2296,15 +2290,14 @@
- * global state machine log lock. Assume that the calls to cvsema won't
- * take a long time. At least we know it won't sleep.
- */
--void
-+STATIC void
- xlog_state_done_syncing(
- xlog_in_core_t *iclog,
- int aborted)
- {
- xlog_t *log = iclog->ic_log;
-- SPLDECL(s);
-
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
-
- ASSERT(iclog->ic_state == XLOG_STATE_SYNCING ||
- iclog->ic_state == XLOG_STATE_IOERROR);
-@@ -2320,7 +2313,7 @@
- */
- if (iclog->ic_state != XLOG_STATE_IOERROR) {
- if (--iclog->ic_bwritecnt == 1) {
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- return;
- }
- iclog->ic_state = XLOG_STATE_DONE_SYNC;
-@@ -2332,7 +2325,7 @@
- * I/O, the others get to wait for the result.
- */
- sv_broadcast(&iclog->ic_writesema);
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- xlog_state_do_callback(log, aborted, iclog); /* also cleans log */
- } /* xlog_state_done_syncing */
-
-@@ -2357,7 +2350,7 @@
- * needs to be incremented, depending on the amount of data which
- * is copied.
- */
--int
-+STATIC int
- xlog_state_get_iclog_space(xlog_t *log,
- int len,
- xlog_in_core_t **iclogp,
-@@ -2365,23 +2358,22 @@
- int *continued_write,
- int *logoffsetp)
- {
-- SPLDECL(s);
- int log_offset;
- xlog_rec_header_t *head;
- xlog_in_core_t *iclog;
- int error;
-
- restart:
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
- if (XLOG_FORCED_SHUTDOWN(log)) {
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- return XFS_ERROR(EIO);
- }
-
- iclog = log->l_iclog;
- if (! (iclog->ic_state == XLOG_STATE_ACTIVE)) {
- log->l_flushcnt++;
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- xlog_trace_iclog(iclog, XLOG_TRACE_SLEEP_FLUSH);
- XFS_STATS_INC(xs_log_noiclogs);
- /* Ensure that log writes happen */
-@@ -2404,8 +2396,9 @@
- xlog_tic_add_region(ticket,
- log->l_iclog_hsize,
- XLOG_REG_TYPE_LRHEADER);
-- INT_SET(head->h_cycle, ARCH_CONVERT, log->l_curr_cycle);
-- ASSIGN_LSN(head->h_lsn, log);
-+ head->h_cycle = cpu_to_be32(log->l_curr_cycle);
-+ head->h_lsn = cpu_to_be64(
-+ xlog_assign_lsn(log->l_curr_cycle, log->l_curr_block));
- ASSERT(log->l_curr_block >= 0);
- }
-
-@@ -2423,12 +2416,12 @@
-
- /* If I'm the only one writing to this iclog, sync it to disk */
- if (iclog->ic_refcnt == 1) {
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- if ((error = xlog_state_release_iclog(log, iclog)))
- return error;
- } else {
- iclog->ic_refcnt--;
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- }
- goto restart;
- }
-@@ -2449,7 +2442,7 @@
- *iclogp = iclog;
-
- ASSERT(iclog->ic_offset <= iclog->ic_size);
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
-
- *logoffsetp = log_offset;
- return 0;
-@@ -2467,7 +2460,6 @@
- {
- int free_bytes;
- int need_bytes;
-- SPLDECL(s);
- #ifdef DEBUG
- xfs_lsn_t tail_lsn;
- #endif
-@@ -2479,7 +2471,7 @@
- #endif
-
- /* Is there space or do we need to sleep? */
-- s = GRANT_LOCK(log);
-+ spin_lock(&log->l_grant_lock);
- xlog_trace_loggrant(log, tic, "xlog_grant_log_space: enter");
-
- /* something is already sleeping; insert new transaction at end */
-@@ -2502,7 +2494,7 @@
- */
- xlog_trace_loggrant(log, tic,
- "xlog_grant_log_space: wake 1");
-- s = GRANT_LOCK(log);
-+ spin_lock(&log->l_grant_lock);
- }
- if (tic->t_flags & XFS_LOG_PERM_RESERV)
- need_bytes = tic->t_unit_res*tic->t_ocnt;
-@@ -2524,14 +2516,14 @@
- sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s);
-
- if (XLOG_FORCED_SHUTDOWN(log)) {
-- s = GRANT_LOCK(log);
-+ spin_lock(&log->l_grant_lock);
- goto error_return;
- }
-
- xlog_trace_loggrant(log, tic,
- "xlog_grant_log_space: wake 2");
- xlog_grant_push_ail(log->l_mp, need_bytes);
-- s = GRANT_LOCK(log);
-+ spin_lock(&log->l_grant_lock);
- goto redo;
- } else if (tic->t_flags & XLOG_TIC_IN_Q)
- xlog_del_ticketq(&log->l_reserve_headq, tic);
-@@ -2553,7 +2545,7 @@
- #endif
- xlog_trace_loggrant(log, tic, "xlog_grant_log_space: exit");
- xlog_verify_grant_head(log, 1);
-- GRANT_UNLOCK(log, s);
-+ spin_unlock(&log->l_grant_lock);
- return 0;
-
- error_return:
-@@ -2567,7 +2559,7 @@
- */
- tic->t_curr_res = 0;
- tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */
-- GRANT_UNLOCK(log, s);
-+ spin_unlock(&log->l_grant_lock);
- return XFS_ERROR(EIO);
- } /* xlog_grant_log_space */
-
-@@ -2581,7 +2573,6 @@
- xlog_regrant_write_log_space(xlog_t *log,
- xlog_ticket_t *tic)
- {
-- SPLDECL(s);
- int free_bytes, need_bytes;
- xlog_ticket_t *ntic;
- #ifdef DEBUG
-@@ -2599,7 +2590,7 @@
- panic("regrant Recovery problem");
- #endif
-
-- s = GRANT_LOCK(log);
-+ spin_lock(&log->l_grant_lock);
- xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: enter");
-
- if (XLOG_FORCED_SHUTDOWN(log))
-@@ -2638,14 +2629,14 @@
- /* If we're shutting down, this tic is already
- * off the queue */
- if (XLOG_FORCED_SHUTDOWN(log)) {
-- s = GRANT_LOCK(log);
-+ spin_lock(&log->l_grant_lock);
- goto error_return;
- }
-
- xlog_trace_loggrant(log, tic,
- "xlog_regrant_write_log_space: wake 1");
- xlog_grant_push_ail(log->l_mp, tic->t_unit_res);
-- s = GRANT_LOCK(log);
-+ spin_lock(&log->l_grant_lock);
- }
- }
-
-@@ -2665,14 +2656,14 @@
-
- /* If we're shutting down, this tic is already off the queue */
- if (XLOG_FORCED_SHUTDOWN(log)) {
-- s = GRANT_LOCK(log);
-+ spin_lock(&log->l_grant_lock);
- goto error_return;
- }
-
- xlog_trace_loggrant(log, tic,
- "xlog_regrant_write_log_space: wake 2");
- xlog_grant_push_ail(log->l_mp, need_bytes);
-- s = GRANT_LOCK(log);
-+ spin_lock(&log->l_grant_lock);
- goto redo;
- } else if (tic->t_flags & XLOG_TIC_IN_Q)
- xlog_del_ticketq(&log->l_write_headq, tic);
-@@ -2689,7 +2680,7 @@
-
- xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: exit");
- xlog_verify_grant_head(log, 1);
-- GRANT_UNLOCK(log, s);
-+ spin_unlock(&log->l_grant_lock);
- return 0;
-
-
-@@ -2704,7 +2695,7 @@
- */
- tic->t_curr_res = 0;
- tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */
-- GRANT_UNLOCK(log, s);
-+ spin_unlock(&log->l_grant_lock);
- return XFS_ERROR(EIO);
- } /* xlog_regrant_write_log_space */
-
-@@ -2720,14 +2711,12 @@
- xlog_regrant_reserve_log_space(xlog_t *log,
- xlog_ticket_t *ticket)
- {
-- SPLDECL(s);
--
- xlog_trace_loggrant(log, ticket,
- "xlog_regrant_reserve_log_space: enter");
- if (ticket->t_cnt > 0)
- ticket->t_cnt--;
-
-- s = GRANT_LOCK(log);
-+ spin_lock(&log->l_grant_lock);
- xlog_grant_sub_space(log, ticket->t_curr_res);
- ticket->t_curr_res = ticket->t_unit_res;
- xlog_tic_reset_res(ticket);
-@@ -2737,7 +2726,7 @@
-
- /* just return if we still have some of the pre-reserved space */
- if (ticket->t_cnt > 0) {
-- GRANT_UNLOCK(log, s);
-+ spin_unlock(&log->l_grant_lock);
- return;
- }
-
-@@ -2745,7 +2734,7 @@
- xlog_trace_loggrant(log, ticket,
- "xlog_regrant_reserve_log_space: exit");
- xlog_verify_grant_head(log, 0);
-- GRANT_UNLOCK(log, s);
-+ spin_unlock(&log->l_grant_lock);
- ticket->t_curr_res = ticket->t_unit_res;
- xlog_tic_reset_res(ticket);
- } /* xlog_regrant_reserve_log_space */
-@@ -2769,12 +2758,10 @@
- xlog_ungrant_log_space(xlog_t *log,
- xlog_ticket_t *ticket)
- {
-- SPLDECL(s);
--
- if (ticket->t_cnt > 0)
- ticket->t_cnt--;
-
-- s = GRANT_LOCK(log);
-+ spin_lock(&log->l_grant_lock);
- xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: enter");
-
- xlog_grant_sub_space(log, ticket->t_curr_res);
-@@ -2791,7 +2778,7 @@
-
- xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: exit");
- xlog_verify_grant_head(log, 1);
-- GRANT_UNLOCK(log, s);
-+ spin_unlock(&log->l_grant_lock);
- xfs_log_move_tail(log->l_mp, 1);
- } /* xlog_ungrant_log_space */
-
-@@ -2799,15 +2786,13 @@
- /*
- * Atomically put back used ticket.
- */
--void
-+STATIC void
- xlog_state_put_ticket(xlog_t *log,
- xlog_ticket_t *tic)
- {
-- unsigned long s;
--
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
- xlog_ticket_put(log, tic);
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- } /* xlog_state_put_ticket */
-
- /*
-@@ -2819,19 +2804,18 @@
- *
- *
- */
--int
-+STATIC int
- xlog_state_release_iclog(xlog_t *log,
- xlog_in_core_t *iclog)
- {
-- SPLDECL(s);
- int sync = 0; /* do we sync? */
-
- xlog_assign_tail_lsn(log->l_mp);
-
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
-
- if (iclog->ic_state & XLOG_STATE_IOERROR) {
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- return XFS_ERROR(EIO);
- }
-
-@@ -2843,12 +2827,12 @@
- iclog->ic_state == XLOG_STATE_WANT_SYNC) {
- sync++;
- iclog->ic_state = XLOG_STATE_SYNCING;
-- INT_SET(iclog->ic_header.h_tail_lsn, ARCH_CONVERT, log->l_tail_lsn);
-+ iclog->ic_header.h_tail_lsn = cpu_to_be64(log->l_tail_lsn);
- xlog_verify_tail_lsn(log, iclog, log->l_tail_lsn);
- /* cycle incremented when incrementing curr_block */
- }
-
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
-
- /*
- * We let the log lock go, so it's possible that we hit a log I/O
-@@ -2860,6 +2844,7 @@
- if (sync) {
- return xlog_sync(log, iclog);
- }
-+
- return 0;
-
- } /* xlog_state_release_iclog */
-@@ -2881,7 +2866,7 @@
- if (!eventual_size)
- eventual_size = iclog->ic_offset;
- iclog->ic_state = XLOG_STATE_WANT_SYNC;
-- INT_SET(iclog->ic_header.h_prev_block, ARCH_CONVERT, log->l_prev_block);
-+ iclog->ic_header.h_prev_block = cpu_to_be32(log->l_prev_block);
- log->l_prev_block = log->l_curr_block;
- log->l_prev_cycle = log->l_curr_cycle;
-
-@@ -2939,13 +2924,12 @@
- {
- xlog_in_core_t *iclog;
- xfs_lsn_t lsn;
-- SPLDECL(s);
-
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
-
- iclog = log->l_iclog;
- if (iclog->ic_state & XLOG_STATE_IOERROR) {
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- return XFS_ERROR(EIO);
- }
-
-@@ -2978,15 +2962,15 @@
- * the previous sync.
- */
- iclog->ic_refcnt++;
-- lsn = INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT);
-+ lsn = be64_to_cpu(iclog->ic_header.h_lsn);
- xlog_state_switch_iclogs(log, iclog, 0);
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
-
- if (xlog_state_release_iclog(log, iclog))
- return XFS_ERROR(EIO);
- *log_flushed = 1;
-- s = LOG_LOCK(log);
-- if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) == lsn &&
-+ spin_lock(&log->l_icloglock);
-+ if (be64_to_cpu(iclog->ic_header.h_lsn) == lsn &&
- iclog->ic_state != XLOG_STATE_DIRTY)
- goto maybe_sleep;
- else
-@@ -3016,7 +3000,7 @@
- * sleep was disturbed by a bad news.
- */
- if (iclog->ic_state & XLOG_STATE_IOERROR) {
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- return XFS_ERROR(EIO);
- }
- XFS_STATS_INC(xs_log_force_sleep);
-@@ -3033,7 +3017,7 @@
- } else {
-
- no_sleep:
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- }
- return 0;
- } /* xlog_state_sync_all */
-@@ -3051,7 +3035,7 @@
- * If filesystem activity goes to zero, the iclog will get flushed only by
- * bdflush().
- */
--int
-+STATIC int
- xlog_state_sync(xlog_t *log,
- xfs_lsn_t lsn,
- uint flags,
-@@ -3059,26 +3043,24 @@
- {
- xlog_in_core_t *iclog;
- int already_slept = 0;
-- SPLDECL(s);
--
-
- try_again:
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
- iclog = log->l_iclog;
-
- if (iclog->ic_state & XLOG_STATE_IOERROR) {
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- return XFS_ERROR(EIO);
- }
-
- do {
-- if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) != lsn) {
-- iclog = iclog->ic_next;
-- continue;
-+ if (be64_to_cpu(iclog->ic_header.h_lsn) != lsn) {
-+ iclog = iclog->ic_next;
-+ continue;
- }
-
- if (iclog->ic_state == XLOG_STATE_DIRTY) {
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- return 0;
- }
-
-@@ -3113,11 +3095,11 @@
- } else {
- iclog->ic_refcnt++;
- xlog_state_switch_iclogs(log, iclog, 0);
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- if (xlog_state_release_iclog(log, iclog))
- return XFS_ERROR(EIO);
- *log_flushed = 1;
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
- }
- }
-
-@@ -3129,7 +3111,7 @@
- * gotten a log write error.
- */
- if (iclog->ic_state & XLOG_STATE_IOERROR) {
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- return XFS_ERROR(EIO);
- }
- XFS_STATS_INC(xs_log_force_sleep);
-@@ -3143,13 +3125,13 @@
- return XFS_ERROR(EIO);
- *log_flushed = 1;
- } else { /* just return */
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- }
- return 0;
-
- } while (iclog != log->l_iclog);
-
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- return 0;
- } /* xlog_state_sync */
-
-@@ -3158,12 +3140,10 @@
- * Called when we want to mark the current iclog as being ready to sync to
- * disk.
- */
--void
-+STATIC void
- xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog)
- {
-- SPLDECL(s);
--
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
-
- if (iclog->ic_state == XLOG_STATE_ACTIVE) {
- xlog_state_switch_iclogs(log, iclog, 0);
-@@ -3172,7 +3152,7 @@
- (XLOG_STATE_WANT_SYNC|XLOG_STATE_IOERROR));
- }
-
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- } /* xlog_state_want_sync */
-
-
-@@ -3194,7 +3174,6 @@
- xlog_ticket_t *next;
- xfs_caddr_t buf;
- uint i = (NBPP / sizeof(xlog_ticket_t)) - 2;
-- SPLDECL(s);
-
- /*
- * The kmem_zalloc may sleep, so we shouldn't be holding the
-@@ -3202,7 +3181,7 @@
- */
- buf = (xfs_caddr_t) kmem_zalloc(NBPP, KM_SLEEP);
-
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
-
- /* Attach 1st ticket to Q, so we can keep track of allocated memory */
- t_list = (xlog_ticket_t *)buf;
-@@ -3231,7 +3210,7 @@
- }
- t_list->t_next = NULL;
- log->l_tail = t_list;
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- } /* xlog_state_ticket_alloc */
-
-
-@@ -3273,7 +3252,7 @@
- /*
- * Grab ticket off freelist or allocation some more
- */
--xlog_ticket_t *
-+STATIC xlog_ticket_t *
- xlog_ticket_get(xlog_t *log,
- int unit_bytes,
- int cnt,
-@@ -3282,15 +3261,14 @@
- {
- xlog_ticket_t *tic;
- uint num_headers;
-- SPLDECL(s);
-
- alloc:
- if (log->l_freelist == NULL)
- xlog_state_ticket_alloc(log); /* potentially sleep */
-
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
- if (log->l_freelist == NULL) {
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- goto alloc;
- }
- tic = log->l_freelist;
-@@ -3298,7 +3276,7 @@
- if (log->l_freelist == NULL)
- log->l_tail = NULL;
- log->l_ticket_cnt--;
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
-
- /*
- * Permanent reservations have up to 'cnt'-1 active log operations
-@@ -3476,7 +3454,7 @@
- SPLDECL(s);
-
- /* check validity of iclog pointers */
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
- icptr = log->l_iclog;
- for (i=0; i < log->l_iclog_bufs; i++) {
- if (icptr == NULL)
-@@ -3485,21 +3463,21 @@
- }
- if (icptr != log->l_iclog)
- xlog_panic("xlog_verify_iclog: corrupt iclog ring");
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
-
- /* check log magic numbers */
-- ptr = (xfs_caddr_t) &(iclog->ic_header);
-- if (INT_GET(*(uint *)ptr, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM)
-+ if (be32_to_cpu(iclog->ic_header.h_magicno) != XLOG_HEADER_MAGIC_NUM)
- xlog_panic("xlog_verify_iclog: invalid magic num");
-
-+ ptr = (xfs_caddr_t) &(iclog->ic_header);
- for (ptr += BBSIZE; ptr < ((xfs_caddr_t)&(iclog->ic_header))+count;
- ptr += BBSIZE) {
-- if (INT_GET(*(uint *)ptr, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM)
-+ if (be32_to_cpu(*(__be32 *)ptr) == XLOG_HEADER_MAGIC_NUM)
- xlog_panic("xlog_verify_iclog: unexpected magic num");
- }
-
- /* check fields */
-- len = INT_GET(iclog->ic_header.h_num_logops, ARCH_CONVERT);
-+ len = be32_to_cpu(iclog->ic_header.h_num_logops);
- ptr = iclog->ic_datap;
- base_ptr = ptr;
- ophead = (xlog_op_header_t *)ptr;
-@@ -3517,9 +3495,11 @@
- if (idx >= (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) {
- j = idx / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
- k = idx % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
-- clientid = GET_CLIENT_ID(xhdr[j].hic_xheader.xh_cycle_data[k], ARCH_CONVERT);
-+ clientid = xlog_get_client_id(
-+ xhdr[j].hic_xheader.xh_cycle_data[k]);
- } else {
-- clientid = GET_CLIENT_ID(iclog->ic_header.h_cycle_data[idx], ARCH_CONVERT);
-+ clientid = xlog_get_client_id(
-+ iclog->ic_header.h_cycle_data[idx]);
- }
- }
- if (clientid != XFS_TRANSACTION && clientid != XFS_LOG)
-@@ -3531,16 +3511,16 @@
- field_offset = (__psint_t)
- ((xfs_caddr_t)&(ophead->oh_len) - base_ptr);
- if (syncing == B_FALSE || (field_offset & 0x1ff)) {
-- op_len = INT_GET(ophead->oh_len, ARCH_CONVERT);
-+ op_len = be32_to_cpu(ophead->oh_len);
- } else {
- idx = BTOBBT((__psint_t)&ophead->oh_len -
- (__psint_t)iclog->ic_datap);
- if (idx >= (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) {
- j = idx / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
- k = idx % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
-- op_len = INT_GET(xhdr[j].hic_xheader.xh_cycle_data[k], ARCH_CONVERT);
-+ op_len = be32_to_cpu(xhdr[j].hic_xheader.xh_cycle_data[k]);
- } else {
-- op_len = INT_GET(iclog->ic_header.h_cycle_data[idx], ARCH_CONVERT);
-+ op_len = be32_to_cpu(iclog->ic_header.h_cycle_data[idx]);
- }
- }
- ptr += sizeof(xlog_op_header_t) + op_len;
-@@ -3597,8 +3577,6 @@
- xlog_t *log;
- int retval;
- int dummy;
-- SPLDECL(s);
-- SPLDECL(s2);
-
- log = mp->m_log;
-
-@@ -3627,8 +3605,8 @@
- * before we mark the filesystem SHUTDOWN and wake
- * everybody up to tell the bad news.
- */
-- s = GRANT_LOCK(log);
-- s2 = LOG_LOCK(log);
-+ spin_lock(&log->l_grant_lock);
-+ spin_lock(&log->l_icloglock);
- mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN;
- XFS_BUF_DONE(mp->m_sb_bp);
- /*
-@@ -3644,7 +3622,7 @@
- */
- if (logerror)
- retval = xlog_state_ioerror(log);
-- LOG_UNLOCK(log, s2);
-+ spin_unlock(&log->l_icloglock);
-
- /*
- * We don't want anybody waiting for log reservations
-@@ -3667,7 +3645,7 @@
- tic = tic->t_next;
- } while (tic != log->l_write_headq);
- }
-- GRANT_UNLOCK(log, s);
-+ spin_unlock(&log->l_grant_lock);
-
- if (! (log->l_iclog->ic_state & XLOG_STATE_IOERROR)) {
- ASSERT(!logerror);
-@@ -3676,9 +3654,9 @@
- * log down completely.
- */
- xlog_state_sync_all(log, XFS_LOG_FORCE|XFS_LOG_SYNC, &dummy);
-- s2 = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
- retval = xlog_state_ioerror(log);
-- LOG_UNLOCK(log, s2);
-+ spin_unlock(&log->l_icloglock);
- }
- /*
- * Wake up everybody waiting on xfs_log_force.
-@@ -3691,13 +3669,13 @@
- {
- xlog_in_core_t *iclog;
-
-- s = LOG_LOCK(log);
-+ spin_lock(&log->l_icloglock);
- iclog = log->l_iclog;
- do {
- ASSERT(iclog->ic_callback == 0);
- iclog = iclog->ic_next;
- } while (iclog != log->l_iclog);
-- LOG_UNLOCK(log, s);
-+ spin_unlock(&log->l_icloglock);
- }
- #endif
- /* return non-zero if log IOERROR transition had already happened */
-diff -Nurd linux-2.6.24/fs/xfs/xfs_log.h linux-2.6.24-oxe810/fs/xfs/xfs_log.h
---- linux-2.6.24/fs/xfs/xfs_log.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_log.h 2008-06-11 17:46:48.000000000 +0200
-@@ -23,7 +23,7 @@
- #define CYCLE_LSN(lsn) ((uint)((lsn)>>32))
- #define BLOCK_LSN(lsn) ((uint)(lsn))
- /* this is used in a spot where we might otherwise double-endian-flip */
--#define CYCLE_LSN_DISK(lsn) (((uint *)&(lsn))[0])
-+#define CYCLE_LSN_DISK(lsn) (((__be32 *)&(lsn))[0])
-
- #ifdef __KERNEL__
- /*
-diff -Nurd linux-2.6.24/fs/xfs/xfs_log_priv.h linux-2.6.24-oxe810/fs/xfs/xfs_log_priv.h
---- linux-2.6.24/fs/xfs/xfs_log_priv.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_log_priv.h 2008-06-11 17:46:48.000000000 +0200
-@@ -55,29 +55,19 @@
- BTOBB(XLOG_MAX_ICLOGS << (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? \
- XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT))
-
--/*
-- * set lsns
-- */
--
--#define ASSIGN_ANY_LSN_HOST(lsn,cycle,block) \
-- { \
-- (lsn) = ((xfs_lsn_t)(cycle)<<32)|(block); \
-- }
--#define ASSIGN_ANY_LSN_DISK(lsn,cycle,block) \
-- { \
-- INT_SET(((uint *)&(lsn))[0], ARCH_CONVERT, (cycle)); \
-- INT_SET(((uint *)&(lsn))[1], ARCH_CONVERT, (block)); \
-- }
--#define ASSIGN_LSN(lsn,log) \
-- ASSIGN_ANY_LSN_DISK(lsn,(log)->l_curr_cycle,(log)->l_curr_block);
-
--#define XLOG_SET(f,b) (((f) & (b)) == (b))
-+static inline xfs_lsn_t xlog_assign_lsn(uint cycle, uint block)
-+{
-+ return ((xfs_lsn_t)cycle << 32) | block;
-+}
-
--#define GET_CYCLE(ptr, arch) \
-- (INT_GET(*(uint *)(ptr), arch) == XLOG_HEADER_MAGIC_NUM ? \
-- INT_GET(*((uint *)(ptr)+1), arch) : \
-- INT_GET(*(uint *)(ptr), arch) \
-- )
-+static inline uint xlog_get_cycle(char *ptr)
-+{
-+ if (be32_to_cpu(*(__be32 *)ptr) == XLOG_HEADER_MAGIC_NUM)
-+ return be32_to_cpu(*((__be32 *)ptr + 1));
-+ else
-+ return be32_to_cpu(*(__be32 *)ptr);
-+}
-
- #define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1)
-
-@@ -97,18 +87,15 @@
- * this has endian issues, of course.
- */
-
--#ifndef XFS_NATIVE_HOST
--#define GET_CLIENT_ID(i,arch) \
-- ((i) & 0xff)
--#else
--#define GET_CLIENT_ID(i,arch) \
-- ((i) >> 24)
--#endif
-+static inline uint xlog_get_client_id(__be32 i)
-+{
-+ return be32_to_cpu(i) >> 24;
-+}
-
--#define GRANT_LOCK(log) mutex_spinlock(&(log)->l_grant_lock)
--#define GRANT_UNLOCK(log, s) mutex_spinunlock(&(log)->l_grant_lock, s)
--#define LOG_LOCK(log) mutex_spinlock(&(log)->l_icloglock)
--#define LOG_UNLOCK(log, s) mutex_spinunlock(&(log)->l_icloglock, s)
-+//#define GRANT_LOCK(log) mutex_spinlock(&(log)->l_grant_lock)
-+//#define GRANT_UNLOCK(log, s) mutex_spinunlock(&(log)->l_grant_lock, s)
-+//#define LOG_LOCK(log) mutex_spinlock(&(log)->l_icloglock)
-+//#define LOG_UNLOCK(log, s) mutex_spinunlock(&(log)->l_icloglock, s)
-
- #define xlog_panic(args...) cmn_err(CE_PANIC, ## args)
- #define xlog_exit(args...) cmn_err(CE_PANIC, ## args)
-@@ -285,11 +272,11 @@
-
-
- typedef struct xlog_op_header {
-- xlog_tid_t oh_tid; /* transaction id of operation : 4 b */
-- int oh_len; /* bytes in data region : 4 b */
-- __uint8_t oh_clientid; /* who sent me this : 1 b */
-- __uint8_t oh_flags; /* : 1 b */
-- ushort oh_res2; /* 32 bit align : 2 b */
-+ __be32 oh_tid; /* transaction id of operation : 4 b */
-+ __be32 oh_len; /* bytes in data region : 4 b */
-+ __u8 oh_clientid; /* who sent me this : 1 b */
-+ __u8 oh_flags; /* : 1 b */
-+ __u16 oh_res2; /* 32 bit align : 2 b */
- } xlog_op_header_t;
-
-
-@@ -307,25 +294,25 @@
- #endif
-
- typedef struct xlog_rec_header {
-- uint h_magicno; /* log record (LR) identifier : 4 */
-- uint h_cycle; /* write cycle of log : 4 */
-- int h_version; /* LR version : 4 */
-- int h_len; /* len in bytes; should be 64-bit aligned: 4 */
-- xfs_lsn_t h_lsn; /* lsn of this LR : 8 */
-- xfs_lsn_t h_tail_lsn; /* lsn of 1st LR w/ buffers not committed: 8 */
-- uint h_chksum; /* may not be used; non-zero if used : 4 */
-- int h_prev_block; /* block number to previous LR : 4 */
-- int h_num_logops; /* number of log operations in this LR : 4 */
-- uint h_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE];
-+ __be32 h_magicno; /* log record (LR) identifier : 4 */
-+ __be32 h_cycle; /* write cycle of log : 4 */
-+ __be32 h_version; /* LR version : 4 */
-+ __be32 h_len; /* len in bytes; should be 64-bit aligned: 4 */
-+ __be64 h_lsn; /* lsn of this LR : 8 */
-+ __be64 h_tail_lsn; /* lsn of 1st LR w/ buffers not committed: 8 */
-+ __be32 h_chksum; /* may not be used; non-zero if used : 4 */
-+ __be32 h_prev_block; /* block number to previous LR : 4 */
-+ __be32 h_num_logops; /* number of log operations in this LR : 4 */
-+ __be32 h_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE];
- /* new fields */
-- int h_fmt; /* format of log record : 4 */
-- uuid_t h_fs_uuid; /* uuid of FS : 16 */
-- int h_size; /* iclog size : 4 */
-+ __be32 h_fmt; /* format of log record : 4 */
-+ uuid_t h_fs_uuid; /* uuid of FS : 16 */
-+ __be32 h_size; /* iclog size : 4 */
- } xlog_rec_header_t;
-
- typedef struct xlog_rec_ext_header {
-- uint xh_cycle; /* write cycle of log : 4 */
-- uint xh_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /* : 256 */
-+ __be32 xh_cycle; /* write cycle of log : 4 */
-+ __be32 xh_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /* : 256 */
- } xlog_rec_ext_header_t;
-
- #ifdef __KERNEL__
-@@ -464,12 +451,12 @@
-
- #define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR)
-
--
- /* common routines */
- extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp);
- extern int xlog_find_tail(xlog_t *log,
- xfs_daddr_t *head_blk,
- xfs_daddr_t *tail_blk);
-+
- extern int xlog_recover(xlog_t *log);
- extern int xlog_recover_finish(xlog_t *log, int mfsi_flags);
- extern void xlog_pack_data(xlog_t *log, xlog_in_core_t *iclog, int);
-diff -Nurd linux-2.6.24/fs/xfs/xfs_log_recover.c linux-2.6.24-oxe810/fs/xfs/xfs_log_recover.c
---- linux-2.6.24/fs/xfs/xfs_log_recover.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_log_recover.c 2008-06-11 17:46:48.000000000 +0200
-@@ -198,7 +198,7 @@
- cmn_err(CE_DEBUG, " log : uuid = ");
- for (b = 0; b < 16; b++)
- cmn_err(CE_DEBUG, "%02x",((uchar_t *)&head->h_fs_uuid)[b]);
-- cmn_err(CE_DEBUG, ", fmt = %d\n", INT_GET(head->h_fmt, ARCH_CONVERT));
-+ cmn_err(CE_DEBUG, ", fmt = %d\n", be32_to_cpu(head->h_fmt));
- }
- #else
- #define xlog_header_check_dump(mp, head)
-@@ -212,14 +212,14 @@
- xfs_mount_t *mp,
- xlog_rec_header_t *head)
- {
-- ASSERT(INT_GET(head->h_magicno, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM);
-+ ASSERT(be32_to_cpu(head->h_magicno) == XLOG_HEADER_MAGIC_NUM);
-
- /*
- * IRIX doesn't write the h_fmt field and leaves it zeroed
- * (XLOG_FMT_UNKNOWN). This stops us from trying to recover
- * a dirty log created in IRIX.
- */
-- if (unlikely(INT_GET(head->h_fmt, ARCH_CONVERT) != XLOG_FMT)) {
-+ if (unlikely(be32_to_cpu(head->h_fmt) != XLOG_FMT)) {
- xlog_warn(
- "XFS: dirty log written in incompatible format - can't recover");
- xlog_header_check_dump(mp, head);
-@@ -245,7 +245,7 @@
- xfs_mount_t *mp,
- xlog_rec_header_t *head)
- {
-- ASSERT(INT_GET(head->h_magicno, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM);
-+ ASSERT(be32_to_cpu(head->h_magicno) == XLOG_HEADER_MAGIC_NUM);
-
- if (uuid_is_nil(&head->h_fs_uuid)) {
- /*
-@@ -311,7 +311,7 @@
- if ((error = xlog_bread(log, mid_blk, 1, bp)))
- return error;
- offset = xlog_align(log, mid_blk, 1, bp);
-- mid_cycle = GET_CYCLE(offset, ARCH_CONVERT);
-+ mid_cycle = xlog_get_cycle(offset);
- if (mid_cycle == cycle) {
- *last_blk = mid_blk;
- /* last_half_cycle == mid_cycle */
-@@ -371,7 +371,7 @@
-
- buf = xlog_align(log, i, bcount, bp);
- for (j = 0; j < bcount; j++) {
-- cycle = GET_CYCLE(buf, ARCH_CONVERT);
-+ cycle = xlog_get_cycle(buf);
- if (cycle == stop_on_cycle_no) {
- *new_blk = i+j;
- goto out;
-@@ -447,8 +447,7 @@
-
- head = (xlog_rec_header_t *)offset;
-
-- if (XLOG_HEADER_MAGIC_NUM ==
-- INT_GET(head->h_magicno, ARCH_CONVERT))
-+ if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(head->h_magicno))
- break;
-
- if (!smallmem)
-@@ -480,7 +479,7 @@
- * record do we update last_blk.
- */
- if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
-- uint h_size = INT_GET(head->h_size, ARCH_CONVERT);
-+ uint h_size = be32_to_cpu(head->h_size);
-
- xhdrs = h_size / XLOG_HEADER_CYCLE_SIZE;
- if (h_size % XLOG_HEADER_CYCLE_SIZE)
-@@ -489,8 +488,8 @@
- xhdrs = 1;
- }
-
-- if (*last_blk - i + extra_bblks
-- != BTOBB(INT_GET(head->h_len, ARCH_CONVERT)) + xhdrs)
-+ if (*last_blk - i + extra_bblks !=
-+ BTOBB(be32_to_cpu(head->h_len)) + xhdrs)
- *last_blk = i;
-
- out:
-@@ -550,13 +549,13 @@
- if ((error = xlog_bread(log, 0, 1, bp)))
- goto bp_err;
- offset = xlog_align(log, 0, 1, bp);
-- first_half_cycle = GET_CYCLE(offset, ARCH_CONVERT);
-+ first_half_cycle = xlog_get_cycle(offset);
-
- last_blk = head_blk = log_bbnum - 1; /* get cycle # of last block */
- if ((error = xlog_bread(log, last_blk, 1, bp)))
- goto bp_err;
- offset = xlog_align(log, last_blk, 1, bp);
-- last_half_cycle = GET_CYCLE(offset, ARCH_CONVERT);
-+ last_half_cycle = xlog_get_cycle(offset);
- ASSERT(last_half_cycle != 0);
-
- /*
-@@ -799,21 +798,27 @@
- * Find previous log record
- */
- if ((error = xlog_find_head(log, head_blk)))
-+ {
-+ xlog_warn("XFS: xlog_find_tail: couldn't find previous log record \n");
- return error;
-+ }
-
- bp = xlog_get_bp(log, 1);
- if (!bp)
-+ {
-+ xlog_warn("XFS: xlog_find_tail: ENOMEM \n");
- return ENOMEM;
-+ }
- if (*head_blk == 0) { /* special case */
- if ((error = xlog_bread(log, 0, 1, bp)))
- goto bread_err;
- offset = xlog_align(log, 0, 1, bp);
-- if (GET_CYCLE(offset, ARCH_CONVERT) == 0) {
-+ if (xlog_get_cycle(offset) == 0) {
- *tail_blk = 0;
- /* leave all other log inited values alone */
- goto exit;
- }
-- }
-+ }
-
- /*
- * Search backwards looking for log record header block
-@@ -823,8 +828,7 @@
- if ((error = xlog_bread(log, i, 1, bp)))
- goto bread_err;
- offset = xlog_align(log, i, 1, bp);
-- if (XLOG_HEADER_MAGIC_NUM ==
-- INT_GET(*(uint *)offset, ARCH_CONVERT)) {
-+ if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(*(__be32 *)offset)) {
- found = 1;
- break;
- }
-@@ -841,7 +845,7 @@
- goto bread_err;
- offset = xlog_align(log, i, 1, bp);
- if (XLOG_HEADER_MAGIC_NUM ==
-- INT_GET(*(uint*)offset, ARCH_CONVERT)) {
-+ be32_to_cpu(*(__be32 *)offset)) {
- found = 2;
- break;
- }
-@@ -855,7 +859,7 @@
-
- /* find blk_no of tail of log */
- rhead = (xlog_rec_header_t *)offset;
-- *tail_blk = BLOCK_LSN(INT_GET(rhead->h_tail_lsn, ARCH_CONVERT));
-+ *tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn));
-
- /*
- * Reset log values according to the state of the log when we
-@@ -869,11 +873,11 @@
- */
- log->l_prev_block = i;
- log->l_curr_block = (int)*head_blk;
-- log->l_curr_cycle = INT_GET(rhead->h_cycle, ARCH_CONVERT);
-+ log->l_curr_cycle = be32_to_cpu(rhead->h_cycle);
- if (found == 2)
- log->l_curr_cycle++;
-- log->l_tail_lsn = INT_GET(rhead->h_tail_lsn, ARCH_CONVERT);
-- log->l_last_sync_lsn = INT_GET(rhead->h_lsn, ARCH_CONVERT);
-+ log->l_tail_lsn = be64_to_cpu(rhead->h_tail_lsn);
-+ log->l_last_sync_lsn = be64_to_cpu(rhead->h_lsn);
- log->l_grant_reserve_cycle = log->l_curr_cycle;
- log->l_grant_reserve_bytes = BBTOB(log->l_curr_block);
- log->l_grant_write_cycle = log->l_curr_cycle;
-@@ -891,8 +895,8 @@
- * unmount record rather than the block after it.
- */
- if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
-- int h_size = INT_GET(rhead->h_size, ARCH_CONVERT);
-- int h_version = INT_GET(rhead->h_version, ARCH_CONVERT);
-+ int h_size = be32_to_cpu(rhead->h_size);
-+ int h_version = be32_to_cpu(rhead->h_version);
-
- if ((h_version & XLOG_VERSION_2) &&
- (h_size > XLOG_HEADER_CYCLE_SIZE)) {
-@@ -905,11 +909,12 @@
- } else {
- hblks = 1;
- }
-+
- after_umount_blk = (i + hblks + (int)
-- BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT))) % log->l_logBBsize;
-+ BTOBB(be32_to_cpu(rhead->h_len))) % log->l_logBBsize;
- tail_lsn = log->l_tail_lsn;
- if (*head_blk == after_umount_blk &&
-- INT_GET(rhead->h_num_logops, ARCH_CONVERT) == 1) {
-+ be32_to_cpu(rhead->h_num_logops) == 1) {
- umount_data_blk = (i + hblks) % log->l_logBBsize;
- if ((error = xlog_bread(log, umount_data_blk, 1, bp))) {
- goto bread_err;
-@@ -922,10 +927,12 @@
- * log records will point recovery to after the
- * current unmount record.
- */
-- ASSIGN_ANY_LSN_HOST(log->l_tail_lsn, log->l_curr_cycle,
-- after_umount_blk);
-- ASSIGN_ANY_LSN_HOST(log->l_last_sync_lsn, log->l_curr_cycle,
-- after_umount_blk);
-+ log->l_tail_lsn =
-+ xlog_assign_lsn(log->l_curr_cycle,
-+ after_umount_blk);
-+ log->l_last_sync_lsn =
-+ xlog_assign_lsn(log->l_curr_cycle,
-+ after_umount_blk);
- *tail_blk = after_umount_blk;
-
- /*
-@@ -986,7 +993,7 @@
- * -1 => use *blk_no as the first block of the log
- * >0 => error has occurred
- */
--int
-+STATIC int
- xlog_find_zeroed(
- xlog_t *log,
- xfs_daddr_t *blk_no)
-@@ -1007,7 +1014,7 @@
- if ((error = xlog_bread(log, 0, 1, bp)))
- goto bp_err;
- offset = xlog_align(log, 0, 1, bp);
-- first_cycle = GET_CYCLE(offset, ARCH_CONVERT);
-+ first_cycle = xlog_get_cycle(offset);
- if (first_cycle == 0) { /* completely zeroed log */
- *blk_no = 0;
- xlog_put_bp(bp);
-@@ -1018,7 +1025,7 @@
- if ((error = xlog_bread(log, log_bbnum-1, 1, bp)))
- goto bp_err;
- offset = xlog_align(log, log_bbnum-1, 1, bp);
-- last_cycle = GET_CYCLE(offset, ARCH_CONVERT);
-+ last_cycle = xlog_get_cycle(offset);
- if (last_cycle != 0) { /* log completely written to */
- xlog_put_bp(bp);
- return 0;
-@@ -1098,13 +1105,13 @@
- xlog_rec_header_t *recp = (xlog_rec_header_t *)buf;
-
- memset(buf, 0, BBSIZE);
-- INT_SET(recp->h_magicno, ARCH_CONVERT, XLOG_HEADER_MAGIC_NUM);
-- INT_SET(recp->h_cycle, ARCH_CONVERT, cycle);
-- INT_SET(recp->h_version, ARCH_CONVERT,
-+ recp->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM);
-+ recp->h_cycle = cpu_to_be32(cycle);
-+ recp->h_version = cpu_to_be32(
- XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? 2 : 1);
-- ASSIGN_ANY_LSN_DISK(recp->h_lsn, cycle, block);
-- ASSIGN_ANY_LSN_DISK(recp->h_tail_lsn, tail_cycle, tail_block);
-- INT_SET(recp->h_fmt, ARCH_CONVERT, XLOG_FMT);
-+ recp->h_lsn = cpu_to_be64(xlog_assign_lsn(cycle, block));
-+ recp->h_tail_lsn = cpu_to_be64(xlog_assign_lsn(tail_cycle, tail_block));
-+ recp->h_fmt = cpu_to_be32(XLOG_FMT);
- memcpy(&recp->h_fs_uuid, &log->l_mp->m_sb.sb_uuid, sizeof(uuid_t));
- }
-
-@@ -1214,6 +1221,11 @@
- head_cycle = log->l_curr_cycle;
- head_block = log->l_curr_block;
-
-+ /* Temp fix - to ensure that the tail cycle and tail blocks both are never 0
-+ */
-+ if ((tail_cycle == 0) && (tail_block == 0))
-+ tail_cycle = head_cycle;
-+
- /*
- * Figure out the distance between the new head of the log
- * and the tail. We want to write over any blocks beyond the
-@@ -1231,6 +1243,8 @@
- if (unlikely(head_block < tail_block || head_block >= log->l_logBBsize)) {
- XFS_ERROR_REPORT("xlog_clear_stale_blocks(1)",
- XFS_ERRLEVEL_LOW, log->l_mp);
-+ printk(KERN_INFO "XFS: head_blk %d tail_blk %d head_cycle %d tail_cycle %d \n",\
-+ head_block, tail_block, head_cycle, tail_cycle);
- return XFS_ERROR(EFSCORRUPTED);
- }
- tail_distance = tail_block + (log->l_logBBsize - head_block);
-@@ -1243,6 +1257,8 @@
- if (unlikely(head_block >= tail_block || head_cycle != (tail_cycle + 1))){
- XFS_ERROR_REPORT("xlog_clear_stale_blocks(2)",
- XFS_ERRLEVEL_LOW, log->l_mp);
-+ printk(KERN_INFO "XFS: head_blk %d tail_blk %d head_cycle %d tail_cycle %d \n",\
-+ head_block, tail_block, head_cycle, tail_cycle);
- return XFS_ERROR(EFSCORRUPTED);
- }
- tail_distance = tail_block - head_block;
-@@ -2211,7 +2227,7 @@
- * overlap with future reads of those inodes.
- */
- if (XFS_DINODE_MAGIC ==
-- INT_GET(*((__uint16_t *)(xfs_buf_offset(bp, 0))), ARCH_CONVERT) &&
-+ be16_to_cpu(*((__be16 *)xfs_buf_offset(bp, 0))) &&
- (XFS_BUF_COUNT(bp) != MAX(log->l_mp->m_sb.sb_blocksize,
- (__uint32_t)XFS_INODE_CLUSTER_SIZE(log->l_mp)))) {
- XFS_BUF_STALE(bp);
-@@ -2581,8 +2597,7 @@
- /*
- * This type of quotas was turned off, so ignore this record.
- */
-- type = INT_GET(recddq->d_flags, ARCH_CONVERT) &
-- (XFS_DQ_USER | XFS_DQ_PROJ | XFS_DQ_GROUP);
-+ type = recddq->d_flags & (XFS_DQ_USER | XFS_DQ_PROJ | XFS_DQ_GROUP);
- ASSERT(type);
- if (log->l_quotaoffs_flag & type)
- return (0);
-@@ -2736,21 +2751,13 @@
- * AIL lock.
- */
- xfs_trans_delete_ail(mp, lip, s);
-- break;
-+ xfs_efi_item_free(efip);
-+ return;
- }
- }
- lip = xfs_trans_next_ail(mp, lip, &gen, NULL);
- }
--
-- /*
-- * If we found it, then free it up. If it wasn't there, it
-- * must have been overwritten in the log. Oh well.
-- */
-- if (lip != NULL) {
-- xfs_efi_item_free(efip);
-- } else {
-- AIL_UNLOCK(mp, s);
-- }
-+ AIL_UNLOCK(mp, s);
- }
-
- /*
-@@ -2897,8 +2904,8 @@
- unsigned long hash;
- uint flags;
-
-- lp = dp + INT_GET(rhead->h_len, ARCH_CONVERT);
-- num_logops = INT_GET(rhead->h_num_logops, ARCH_CONVERT);
-+ lp = dp + be32_to_cpu(rhead->h_len);
-+ num_logops = be32_to_cpu(rhead->h_num_logops);
-
- /* check the log format matches our own - else we can't recover */
- if (xlog_header_check_recover(log->l_mp, rhead))
-@@ -2912,18 +2919,28 @@
- ohead->oh_clientid != XFS_LOG) {
- xlog_warn(
- "XFS: xlog_recover_process_data: bad clientid");
-+ printk(KERN_INFO "Ticket ID - %d\n", ohead->oh_tid);
-+ printk(KERN_INFO "Bytes in Data Region - %d\n", ohead->oh_len);
-+ printk(KERN_INFO "Client ID - %d\n", ohead->oh_clientid);
-+ printk(KERN_INFO "Flags - %d\n", ohead->oh_flags);
-+ printk(KERN_INFO "Unused - %d\n", ohead->oh_res2);
- ASSERT(0);
- return (XFS_ERROR(EIO));
- }
-- tid = INT_GET(ohead->oh_tid, ARCH_CONVERT);
-+ tid = be32_to_cpu(ohead->oh_tid);
- hash = XLOG_RHASH(tid);
- trans = xlog_recover_find_tid(rhash[hash], tid);
- if (trans == NULL) { /* not found; add new tid */
- if (ohead->oh_flags & XLOG_START_TRANS)
- xlog_recover_new_tid(&rhash[hash], tid,
-- INT_GET(rhead->h_lsn, ARCH_CONVERT));
-+ be64_to_cpu(rhead->h_lsn));
- } else {
-- ASSERT(dp+INT_GET(ohead->oh_len, ARCH_CONVERT) <= lp);
-+ if (dp + be32_to_cpu(ohead->oh_len) > lp) {
-+ xlog_warn(
-+ "XFS: xlog_recover_process_data: bad length");
-+ WARN_ON(1);
-+ return (XFS_ERROR(EIO));
-+ }
- flags = ohead->oh_flags & ~XLOG_END_TRANS;
- if (flags & XLOG_WAS_CONT_TRANS)
- flags &= ~XLOG_CONTINUE_TRANS;
-@@ -2937,8 +2954,7 @@
- break;
- case XLOG_WAS_CONT_TRANS:
- error = xlog_recover_add_to_cont_trans(trans,
-- dp, INT_GET(ohead->oh_len,
-- ARCH_CONVERT));
-+ dp, be32_to_cpu(ohead->oh_len));
- break;
- case XLOG_START_TRANS:
- xlog_warn(
-@@ -2949,8 +2965,7 @@
- case 0:
- case XLOG_CONTINUE_TRANS:
- error = xlog_recover_add_to_trans(trans,
-- dp, INT_GET(ohead->oh_len,
-- ARCH_CONVERT));
-+ dp, be32_to_cpu(ohead->oh_len));
- break;
- default:
- xlog_warn(
-@@ -2962,7 +2977,7 @@
- if (error)
- return error;
- }
-- dp += INT_GET(ohead->oh_len, ARCH_CONVERT);
-+ dp += be32_to_cpu(ohead->oh_len);
- num_logops--;
- }
- return 0;
-@@ -3315,16 +3330,16 @@
- int size)
- {
- int i;
-- uint *up;
-+ __be32 *up;
- uint chksum = 0;
-
-- up = (uint *)iclog->ic_datap;
-+ up = (__be32 *)iclog->ic_datap;
- /* divide length by 4 to get # words */
- for (i = 0; i < (size >> 2); i++) {
-- chksum ^= INT_GET(*up, ARCH_CONVERT);
-+ chksum ^= be32_to_cpu(*up);
- up++;
- }
-- INT_SET(iclog->ic_header.h_chksum, ARCH_CONVERT, chksum);
-+ iclog->ic_header.h_chksum = cpu_to_be32(chksum);
- }
- #else
- #define xlog_pack_data_checksum(log, iclog, size)
-@@ -3341,7 +3356,7 @@
- {
- int i, j, k;
- int size = iclog->ic_offset + roundoff;
-- uint cycle_lsn;
-+ __be32 cycle_lsn;
- xfs_caddr_t dp;
- xlog_in_core_2_t *xhdr;
-
-@@ -3352,8 +3367,8 @@
- dp = iclog->ic_datap;
- for (i = 0; i < BTOBB(size) &&
- i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) {
-- iclog->ic_header.h_cycle_data[i] = *(uint *)dp;
-- *(uint *)dp = cycle_lsn;
-+ iclog->ic_header.h_cycle_data[i] = *(__be32 *)dp;
-+ *(__be32 *)dp = cycle_lsn;
- dp += BBSIZE;
- }
-
-@@ -3362,8 +3377,8 @@
- for ( ; i < BTOBB(size); i++) {
- j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
- k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
-- xhdr[j].hic_xheader.xh_cycle_data[k] = *(uint *)dp;
-- *(uint *)dp = cycle_lsn;
-+ xhdr[j].hic_xheader.xh_cycle_data[k] = *(__be32 *)dp;
-+ *(__be32 *)dp = cycle_lsn;
- dp += BBSIZE;
- }
-
-@@ -3380,21 +3395,21 @@
- xfs_caddr_t dp,
- xlog_t *log)
- {
-- uint *up = (uint *)dp;
-+ __be32 *up = (__be32 *)dp;
- uint chksum = 0;
- int i;
-
- /* divide length by 4 to get # words */
-- for (i=0; i < INT_GET(rhead->h_len, ARCH_CONVERT) >> 2; i++) {
-- chksum ^= INT_GET(*up, ARCH_CONVERT);
-+ for (i=0; i < be32_to_cpu(rhead->h_len) >> 2; i++) {
-+ chksum ^= be32_to_cpu(*up);
- up++;
- }
-- if (chksum != INT_GET(rhead->h_chksum, ARCH_CONVERT)) {
-+ if (chksum != be32_to_cpu(rhead->h_chksum)) {
- if (rhead->h_chksum ||
- ((log->l_flags & XLOG_CHKSUM_MISMATCH) == 0)) {
- cmn_err(CE_DEBUG,
- "XFS: LogR chksum mismatch: was (0x%x) is (0x%x)\n",
-- INT_GET(rhead->h_chksum, ARCH_CONVERT), chksum);
-+ be32_to_cpu(rhead->h_chksum), chksum);
- cmn_err(CE_DEBUG,
- "XFS: Disregard message if filesystem was created with non-DEBUG kernel");
- if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
-@@ -3418,18 +3433,18 @@
- int i, j, k;
- xlog_in_core_2_t *xhdr;
-
-- for (i = 0; i < BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)) &&
-+ for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) &&
- i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) {
-- *(uint *)dp = *(uint *)&rhead->h_cycle_data[i];
-+ *(__be32 *)dp = *(__be32 *)&rhead->h_cycle_data[i];
- dp += BBSIZE;
- }
-
- if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
- xhdr = (xlog_in_core_2_t *)rhead;
-- for ( ; i < BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); i++) {
-+ for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) {
- j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
- k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
-- *(uint *)dp = xhdr[j].hic_xheader.xh_cycle_data[k];
-+ *(__be32 *)dp = xhdr[j].hic_xheader.xh_cycle_data[k];
- dp += BBSIZE;
- }
- }
-@@ -3445,24 +3460,21 @@
- {
- int hlen;
-
-- if (unlikely(
-- (INT_GET(rhead->h_magicno, ARCH_CONVERT) !=
-- XLOG_HEADER_MAGIC_NUM))) {
-+ if (unlikely(be32_to_cpu(rhead->h_magicno) != XLOG_HEADER_MAGIC_NUM)) {
- XFS_ERROR_REPORT("xlog_valid_rec_header(1)",
- XFS_ERRLEVEL_LOW, log->l_mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- if (unlikely(
- (!rhead->h_version ||
-- (INT_GET(rhead->h_version, ARCH_CONVERT) &
-- (~XLOG_VERSION_OKBITS)) != 0))) {
-+ (be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS))))) {
- xlog_warn("XFS: %s: unrecognised log version (%d).",
-- __FUNCTION__, INT_GET(rhead->h_version, ARCH_CONVERT));
-+ __FUNCTION__, be32_to_cpu(rhead->h_version));
- return XFS_ERROR(EIO);
- }
-
- /* LR body must have data or it wouldn't have been written */
-- hlen = INT_GET(rhead->h_len, ARCH_CONVERT);
-+ hlen = be32_to_cpu(rhead->h_len);
- if (unlikely( hlen <= 0 || hlen > INT_MAX )) {
- XFS_ERROR_REPORT("xlog_valid_rec_header(2)",
- XFS_ERRLEVEL_LOW, log->l_mp);
-@@ -3522,9 +3534,8 @@
- error = xlog_valid_rec_header(log, rhead, tail_blk);
- if (error)
- goto bread_err1;
-- h_size = INT_GET(rhead->h_size, ARCH_CONVERT);
-- if ((INT_GET(rhead->h_version, ARCH_CONVERT)
-- & XLOG_VERSION_2) &&
-+ h_size = be32_to_cpu(rhead->h_size);
-+ if ((be32_to_cpu(rhead->h_version) & XLOG_VERSION_2) &&
- (h_size > XLOG_HEADER_CYCLE_SIZE)) {
- hblks = h_size / XLOG_HEADER_CYCLE_SIZE;
- if (h_size % XLOG_HEADER_CYCLE_SIZE)
-@@ -3561,7 +3572,7 @@
- goto bread_err2;
-
- /* blocks in data section */
-- bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT));
-+ bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
- error = xlog_bread(log, blk_no + hblks, bblks, dbp);
- if (error)
- goto bread_err2;
-@@ -3636,7 +3647,7 @@
- if (error)
- goto bread_err2;
-
-- bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT));
-+ bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
- blk_no += hblks;
-
- /* Read in data for log record */
-@@ -3707,7 +3718,7 @@
- error = xlog_valid_rec_header(log, rhead, blk_no);
- if (error)
- goto bread_err2;
-- bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT));
-+ bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
- if ((error = xlog_bread(log, blk_no+hblks, bblks, dbp)))
- goto bread_err2;
- offset = xlog_align(log, blk_no+hblks, bblks, dbp);
-@@ -3878,7 +3889,12 @@
-
- /* find the tail of the log */
- if ((error = xlog_find_tail(log, &head_blk, &tail_blk)))
-+ {
-+ cmn_err(CE_NOTE, "Log head - 0x%llx Log Tail - 0x%llx \n",\
-+ (unsigned long long)head_blk, \
-+ (unsigned long long)tail_blk);
- return error;
-+ }
-
- if (tail_blk != head_blk) {
- /* There used to be a comment here:
-diff -Nurd linux-2.6.24/fs/xfs/xfs_trans.c linux-2.6.24-oxe810/fs/xfs/xfs_trans.c
---- linux-2.6.24/fs/xfs/xfs_trans.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_trans.c 2008-06-11 17:46:48.000000000 +0200
-@@ -567,26 +567,26 @@
- */
- if (!xfs_sb_version_haslazysbcount(&(tp->t_mountp->m_sb))) {
- if (tp->t_icount_delta)
-- be64_add(&sbp->sb_icount, tp->t_icount_delta);
-+ be64_add_cpu(&sbp->sb_icount, tp->t_icount_delta);
- if (tp->t_ifree_delta)
-- be64_add(&sbp->sb_ifree, tp->t_ifree_delta);
-+ be64_add_cpu(&sbp->sb_ifree, tp->t_ifree_delta);
- if (tp->t_fdblocks_delta)
-- be64_add(&sbp->sb_fdblocks, tp->t_fdblocks_delta);
-+ be64_add_cpu(&sbp->sb_fdblocks, tp->t_fdblocks_delta);
- if (tp->t_res_fdblocks_delta)
-- be64_add(&sbp->sb_fdblocks, tp->t_res_fdblocks_delta);
-+ be64_add_cpu(&sbp->sb_fdblocks, tp->t_res_fdblocks_delta);
- }
-
- if (tp->t_frextents_delta)
-- be64_add(&sbp->sb_frextents, tp->t_frextents_delta);
-+ be64_add_cpu(&sbp->sb_frextents, tp->t_frextents_delta);
- if (tp->t_res_frextents_delta)
-- be64_add(&sbp->sb_frextents, tp->t_res_frextents_delta);
-+ be64_add_cpu(&sbp->sb_frextents, tp->t_res_frextents_delta);
-
- if (tp->t_dblocks_delta) {
-- be64_add(&sbp->sb_dblocks, tp->t_dblocks_delta);
-+ be64_add_cpu(&sbp->sb_dblocks, tp->t_dblocks_delta);
- whole = 1;
- }
- if (tp->t_agcount_delta) {
-- be32_add(&sbp->sb_agcount, tp->t_agcount_delta);
-+ be32_add_cpu(&sbp->sb_agcount, tp->t_agcount_delta);
- whole = 1;
- }
- if (tp->t_imaxpct_delta) {
-@@ -594,19 +594,19 @@
- whole = 1;
- }
- if (tp->t_rextsize_delta) {
-- be32_add(&sbp->sb_rextsize, tp->t_rextsize_delta);
-+ be32_add_cpu(&sbp->sb_rextsize, tp->t_rextsize_delta);
- whole = 1;
- }
- if (tp->t_rbmblocks_delta) {
-- be32_add(&sbp->sb_rbmblocks, tp->t_rbmblocks_delta);
-+ be32_add_cpu(&sbp->sb_rbmblocks, tp->t_rbmblocks_delta);
- whole = 1;
- }
- if (tp->t_rblocks_delta) {
-- be64_add(&sbp->sb_rblocks, tp->t_rblocks_delta);
-+ be64_add_cpu(&sbp->sb_rblocks, tp->t_rblocks_delta);
- whole = 1;
- }
- if (tp->t_rextents_delta) {
-- be64_add(&sbp->sb_rextents, tp->t_rextents_delta);
-+ be64_add_cpu(&sbp->sb_rextents, tp->t_rextents_delta);
- whole = 1;
- }
- if (tp->t_rextslog_delta) {
-diff -Nurd linux-2.6.24/fs/xfs/xfs_vnodeops.c linux-2.6.24-oxe810/fs/xfs/xfs_vnodeops.c
---- linux-2.6.24/fs/xfs/xfs_vnodeops.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/fs/xfs/xfs_vnodeops.c 2008-06-11 17:46:48.000000000 +0200
-@@ -3558,11 +3558,11 @@
- if (iip && iip->ili_last_lsn) {
- xlog_t *log = mp->m_log;
- xfs_lsn_t sync_lsn;
-- int s, log_flags = XFS_LOG_FORCE;
-+ int log_flags = XFS_LOG_FORCE;
-
-- s = GRANT_LOCK(log);
-+ spin_lock(&log->l_grant_lock);
- sync_lsn = log->l_last_sync_lsn;
-- GRANT_UNLOCK(log, s);
-+ spin_unlock(&log->l_grant_lock);
-
- if ((XFS_LSN_CMP(iip->ili_last_lsn, sync_lsn) > 0)) {
- if (flags & FLUSH_SYNC)
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/GPIO_PST_FunctionEnables.inc linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/GPIO_PST_FunctionEnables.inc
---- linux-2.6.24/include/asm-arm/arch-oxnas/GPIO_PST_FunctionEnables.inc 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/GPIO_PST_FunctionEnables.inc 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,91 @@
-+/**
-+ * -- GPIO Function Enable Mappings --
-+ * Auto Generated by asic/chips/nas/root.user/docs/specs/map2CInlude
-+ */
-+// GPIO Primary Function Enables
-+#define PRIMARY_FUNCTION_ENABLE_SYSPCI_GNT_N0 (0) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_SYSPCI_GNT_N1 (1) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_SYSPCI_GNT_N2 (2) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_SYSPCI_GNT_N3 (3) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_SYSPCI_REQ_N0 (4) // As Input
-+#define PRIMARY_FUNCTION_ENABLE_SYSPCI_REQ_N1 (5) // As Input
-+#define PRIMARY_FUNCTION_ENABLE_SYSPCI_REQ_N2 (6) // As Input
-+#define PRIMARY_FUNCTION_ENABLE_SYSPCI_REQ_N3 (7) // As Input
-+#define PRIMARY_FUNCTION_ENABLE_PCI_CKO (8) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_STATIC_OE_N (12) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_STATIC_ADDR21 (13) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_STATIC_ADDR20 (14) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_STATIC_ADDR19 (15) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_STATIC_ADDR18 (16) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_STATIC_ADDR17 (17) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_STATIC_ADDR16 (18) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_STATIC_CS_N0 (19) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_STATIC_CS_N1 (20) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_STATIC_WE_N0 (21) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_STATIC_WE_N1 (22) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_USBA_PWRO (23) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_USBA_OVERI (24) // As Input
-+#define PRIMARY_FUNCTION_ENABLE_USBB_PWRO (25) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_USBB_OVERI (26) // As Input
-+#define PRIMARY_FUNCTION_ENABLE_USBC_PWRO (27) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_USBC_OVERI (28) // As Input
-+#define PRIMARY_FUNCTION_ENABLE_FAN_TEMP (29) // Is Bidirectional
-+#define PRIMARY_FUNCTION_ENABLE_FAN_TACHO (30) // As Input
-+#define PRIMARY_FUNCTION_ENABLE_FAN_PWM0 (31) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_FAN_PWM1 (32) // As Output
-+#define PRIMARY_FUNCTION_ENABLE_IBIW_D (33) // Is Bidirectional
-+#define PRIMARY_FUNCTION_ENABLE_IBIW_LED (34) // As Output
-+// GPIO Secondary Function Enables
-+#define SECONDARY_FUNCTION_ENABLE_SYSPCI_REQ_OUT_N (0) // As Output
-+#define SECONDARY_FUNCTION_ENABLE_SYSPCI_GNT_IN_N (1) // As Input
-+#define SECONDARY_FUNCTION_ENABLE_PCI_IDSEL (2) // As Input
-+#define SECONDARY_FUNCTION_ENABLE_IRRX_IN (3) // As Input
-+#define SECONDARY_FUNCTION_ENABLE_FAN_PWM3 (5) // As Output
-+#define SECONDARY_FUNCTION_ENABLE_AUDIO_TX_BITCK (6) // As Input
-+#define SECONDARY_FUNCTION_ENABLE_AUDIO_TXLRCK (7) // As Input
-+#define SECONDARY_FUNCTION_ENABLE_FAN_PWM2 (8) // As Output
-+#define SECONDARY_FUNCTION_ENABLE_USB_CKO (10) // As Output
-+#define SECONDARY_FUNCTION_ENABLE_PCI_CCLKRUN_N (12) // Is Bidirectional
-+#define SECONDARY_FUNCTION_ENABLE_PCI_LOCK_N (13) // As Input
-+#define SECONDARY_FUNCTION_ENABLE_PCI_PERR_N (14) // Is Bidirectional
-+#define SECONDARY_FUNCTION_ENABLE_PCI_SERR_N (15) // As Output
-+#define SECONDARY_FUNCTION_ENABLE_MEM_DLLTGL (16) // As Output
-+#define SECONDARY_FUNCTION_ENABLE_SATA_OBS_RBC0 (17) // As Output
-+#define SECONDARY_FUNCTION_ENABLE_PCI_CINT_N (18) // As Output
-+#define SECONDARY_FUNCTION_ENABLE_PCI_CSTSCHG_N (19) // As Output
-+#define SECONDARY_FUNCTION_ENABLE_PCI_CKO (23) // As Output
-+#define SECONDARY_FUNCTION_ENABLE_AUDIO_TXD0 (25) // As Output
-+#define SECONDARY_FUNCTION_ENABLE_AUDIO_RXD0 (26) // As Input
-+#define SECONDARY_FUNCTION_ENABLE_AUDIO_RXLRCK (27) // As Input
-+#define SECONDARY_FUNCTION_ENABLE_AUDIO_RX_BITCK (28) // As Input
-+#define SECONDARY_FUNCTION_ENABLE_AUDIO_TXD2 (29) // As Output
-+#define SECONDARY_FUNCTION_ENABLE_AUDIO_RXD2 (30) // As Input
-+#define SECONDARY_FUNCTION_ENABLE_AUDIO_TXD3 (31) // As Output
-+#define SECONDARY_FUNCTION_ENABLE_AUDIO_RXD3 (32) // As Input
-+#define SECONDARY_FUNCTION_ENABLE_AUDIO_RXD1 (33) // As Input
-+#define SECONDARY_FUNCTION_ENABLE_AUDIO_TXD1 (34) // As Output
-+// GPIO Tertiary Function Enables
-+#define TERTIARY_FUNCTION_ENABLE_UART3_RI_N (0) // As Input
-+#define TERTIARY_FUNCTION_ENABLE_UART3_CD_N (1) // As Input
-+#define TERTIARY_FUNCTION_ENABLE_UART3_CTS_N (2) // As Input
-+#define TERTIARY_FUNCTION_ENABLE_UART3_DSR_N (3) // As Input
-+#define TERTIARY_FUNCTION_ENABLE_UART3_DTR_N (4) // As Output
-+#define TERTIARY_FUNCTION_ENABLE_UART3_RTS_N (5) // As Output
-+#define TERTIARY_FUNCTION_ENABLE_UART3_SIN (6) // As Input
-+#define TERTIARY_FUNCTION_ENABLE_UART3_SOUT (7) // As Output
-+#define TERTIARY_FUNCTION_ENABLE_UART2_DSR_N (8) // As Input
-+#define TERTIARY_FUNCTION_ENABLE_UART2_RTS_N (9) // As Output
-+#define TERTIARY_FUNCTION_ENABLE_UART2_SOUT (20) // As Output
-+#define TERTIARY_FUNCTION_ENABLE_UART2_SIN (22) // As Input
-+#define TERTIARY_FUNCTION_ENABLE_UART2_RI_N (23) // As Input
-+#define TERTIARY_FUNCTION_ENABLE_UART2_CD_N (24) // As Input
-+#define TERTIARY_FUNCTION_ENABLE_UART2_DTR_N (25) // As Output
-+#define TERTIARY_FUNCTION_ENABLE_UART2_CTS_N (26) // As Input
-+#define TERTIARY_FUNCTION_ENABLE_UART1_RTS_N (27) // As Output
-+#define TERTIARY_FUNCTION_ENABLE_UART1_CTS_N (28) // As Input
-+#define TERTIARY_FUNCTION_ENABLE_UART1_DSR_N (29) // As Input
-+#define TERTIARY_FUNCTION_ENABLE_UART1_CD_N (30) // As Input
-+#define TERTIARY_FUNCTION_ENABLE_UART1_SOUT (31) // As Output
-+#define TERTIARY_FUNCTION_ENABLE_UART1_SIN (32) // As Input
-+#define TERTIARY_FUNCTION_ENABLE_UART1_RI_N (33) // As Input
-+#define TERTIARY_FUNCTION_ENABLE_UART1_DTR_N (34) // As Output
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/ahb_mon.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/ahb_mon.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/ahb_mon.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/ahb_mon.h 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,27 @@
-+/* linux/include/asm-arm/arch-oxnas/ahb_mon.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.
-+ */
-+#ifdef CONFIG_OXNAS_AHB_MON
-+
-+#if !defined(__AHB_MON_H__)
-+#define __AHB_MON_H__
-+
-+extern void init_ahb_monitors(
-+ AHB_MON_HWRITE_T ahb_mon_hwrite,
-+ unsigned hburst_mask,
-+ unsigned hburst_match,
-+ unsigned hprot_mask,
-+ unsigned hprot_match);
-+extern void restart_ahb_monitors(void);
-+extern void read_ahb_monitors(void);
-+#else // CONFIG_OXNAS_AHB_MON
-+#define init_ahb_monitors(a, b, c, d, e) {}
-+#define restart_ahb_monitors(x) {}
-+#define read_ahb_monitors(x) {}
-+
-+#endif // #if !defined(__AHB_MON_H__)
-+#endif // CONFIG_OXNAS_AHB_MON
-+
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/cipher.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/cipher.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/cipher.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/cipher.h 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,139 @@
-+/*
-+ * linux/include/asm-arm/arch-oxnas/cipher.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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
-+ *
-+ * Register locations in the cipher core
-+ *
-+ */
-+
-+#ifndef __ASM_ARCH_CIPHER_H
-+#define __ASM_ARCH_CIPHER_H
-+
-+#define OX800DPE_CTL_DIRECTION_ENC 0x002
-+#define OX800DPE_CTL_PRIMARY_IS_KEY3 0x004
-+#define OX800DPE_CTL_ENCRYPT_KEY 0x010
-+#define OX800DPE_CTL_ABORT 0x040
-+#define OX800DPE_CTL_MODE_ECB_AES 0x000
-+#define OX800DPE_CTL_MODE_LRW_AES 0x080
-+#define OX800DPE_CTL_MODE_CBC_AES 0x100
-+
-+
-+#define OX800DPE_STAT_IDLE 0x1
-+#define OX800DPE_STAT_RX_SPACE 0x4
-+#define OX800DPE_STAT_TX_NOTEMPTY 0x8
-+
-+
-+#define OX800DPE_KEYSIZE 16
-+typedef volatile u32 oxnas_cipher_key_t[4];
-+
-+#define OX800DPE_CONTROL ((DPE_REGS_BASE) + 0x00)
-+#define OX800DPE_STATUS ((DPE_REGS_BASE) + 0x04)
-+#define OX800DPE_KEY00 ((DPE_REGS_BASE) + 0x10)
-+#define OX800DPE_KEY01 ((DPE_REGS_BASE) + 0x14)
-+#define OX800DPE_KEY02 ((DPE_REGS_BASE) + 0x18)
-+#define OX800DPE_KEY03 ((DPE_REGS_BASE) + 0x1c)
-+#define OX800DPE_KEY10 ((DPE_REGS_BASE) + 0x20)
-+#define OX800DPE_KEY11 ((DPE_REGS_BASE) + 0x24)
-+#define OX800DPE_KEY12 ((DPE_REGS_BASE) + 0x28)
-+#define OX800DPE_KEY13 ((DPE_REGS_BASE) + 0x2c)
-+#define OX800DPE_KEY20 ((DPE_REGS_BASE) + 0x30)
-+#define OX800DPE_KEY21 ((DPE_REGS_BASE) + 0x34)
-+#define OX800DPE_KEY22 ((DPE_REGS_BASE) + 0x38)
-+#define OX800DPE_KEY23 ((DPE_REGS_BASE) + 0x3c)
-+#define OX800DPE_DATA_IN0 ((DPE_REGS_BASE) + 0x40)
-+#define OX800DPE_DATA_IN1 ((DPE_REGS_BASE) + 0x44)
-+#define OX800DPE_DATA_IN2 ((DPE_REGS_BASE) + 0x48)
-+#define OX800DPE_DATA_IN3 ((DPE_REGS_BASE) + 0x4c)
-+#define OX800DPE_DATA_OUT0 ((DPE_REGS_BASE) + 0x50)
-+#define OX800DPE_DATA_OUT1 ((DPE_REGS_BASE) + 0x54)
-+#define OX800DPE_DATA_OUT2 ((DPE_REGS_BASE) + 0x58)
-+#define OX800DPE_DATA_OUT3 ((DPE_REGS_BASE) + 0x5c)
-+#define OX800DPE_DATA_LRW0 ((DPE_REGS_BASE) + 0x60)
-+#define OX800DPE_DATA_LRW1 ((DPE_REGS_BASE) + 0x64)
-+#define OX800DPE_DATA_CBC0 ((DPE_REGS_BASE) + 0x68)
-+#define OX800DPE_DATA_CBC1 ((DPE_REGS_BASE) + 0x6c)
-+
-+
-+#define OX800IBW_STAT_AUTHENTICATED 0x10
-+
-+#define OX800IBW_CONTROL ((IBW_REGS_BASE) + 0x00)
-+#define OX800IBW_STATUS ((IBW_REGS_BASE) + 0x04)
-+#define OX800IBW_SERIAL_LO ((IBW_REGS_BASE) + 0x08)
-+#define OX800IBW_SERIAL_HI ((IBW_REGS_BASE) + 0x0C)
-+
-+
-+// IBIW Control register bits
-+
-+#define OX800IBW_CTRL_LOAD_AES_KEY 0x00100
-+#define OX800IBW_CTRL_BUFF_WR_SRC 0x00200
-+#define OX800IBW_CTRL_CRC_WR_SRC 0x00400
-+#define OX800IBW_CTRL_RESET 0x00800
-+#define OX800IBW_CTRL_WR 0x01000
-+#define OX800IBW_CTRL_RD 0x02000
-+#define OX800IBW_CTRL_RX_INIT 0x04000
-+#define OX800IBW_CTRL_TX_INIT 0x08000
-+#define OX800IBW_CTRL_DONE 0x10000
-+#define OX800IBW_CTRL_ENABLE 0x20000
-+
-+
-+// IBIW Status register bits
-+
-+#define OX800IBW_STATUS_PRESENT 0x0001
-+#define OX800IBW_STATUS_ARRIVAL 0x0002
-+#define OX800IBW_STATUS_DEPARTURE 0x0004
-+#define OX800IBW_STATUS_HOLDOFF 0x0008
-+#define OX800IBW_STATUS_CRC_OK 0x0010
-+#define OX800IBW_STATUS_SERIAL_MATCH 0x0020
-+#define OX800IBW_STATUS_KEY_MATCH 0x0040
-+#define OX800IBW_STATUS_VALID_KEY 0x0080
-+#define OX800IBW_STATUS_AUTHENTICATED 0x0100
-+#define OX800IBW_STATUS_RD_ENABLED 0x0200
-+
-+/*The number of storage fields in a DS1991 iButton */
-+#define DS1991_IBUTTON_FIELDS 4
-+#define DS1991_PASSWORD_SIZE 8
-+#define DS1991_ID_SIZE 8
-+#define DS1991_DATA_SIZE 48
-+#define DS1991_PLAINTEXT_SIZE 64
-+
-+/* DS1991 COMMANDS */
-+#define DS1991_WRITE_SCRATCHPAD 0x96
-+#define DS1991_READ_SCRATCHPAD 0x69
-+#define DS1991_COPY_SCRATCHPAD 0x3c
-+#define DS1991_READ_SUBKEY 0x66
-+#define DS1991_WRITE_SUBKEY 0x99
-+#define DS1991_WRITE_PASSWORD 0x5a
-+
-+/* prototype */
-+struct scatterlist;
-+
-+int ox800_aeslrw_encrypt( struct scatterlist* in,
-+ struct scatterlist* out,
-+ unsigned int length,
-+ u8 iv[],
-+ u8 cipher_key[],
-+ u8 tweak_key[]);
-+
-+int ox800_aeslrw_decrypt( struct scatterlist* in,
-+ struct scatterlist* out,
-+ unsigned int length,
-+ u8 iv[],
-+ u8 cipher_key[],
-+ u8 tweak_key[]);
-+
-+#endif
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/debug-macro.S linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/debug-macro.S
---- linux-2.6.24/include/asm-arm/arch-oxnas/debug-macro.S 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/debug-macro.S 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,47 @@
-+/* linux/include/asm-arm/arch-oxnas/debug-macro.S
-+ *
-+ * Debugging macro include header
-+ *
-+ * Copyright (C) 2005 B.H.Clarke
-+ *
-+ * 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 <asm/arch/hardware.h>
-+
-+ .macro addruart,rx
-+ mrc p15, 0, \rx, c1, c0
-+ tst \rx, #1 @ MMU enabled?
-+#ifdef CONFIG_ARCH_OXNAS_UART1
-+ ldreq \rx, =UART_1_BASE_PA @ physical base address
-+ ldrne \rx, =UART_1_BASE @ virtual address
-+#elif CONFIG_ARCH_OXNAS_UART2
-+ ldreq \rx, =UART_2_BASE_PA @ physical base address
-+ ldrne \rx, =UART_2_BASE @ virtual address
-+#elif CONFIG_ARCH_OXNAS_UART3
-+ ldreq \rx, =UART_3_BASE_PA @ physical base address
-+ ldrne \rx, =UART_3_BASE @ virtual address
-+#else
-+ ldreq \rx, =UART_4_BASE_PA @ physical base address
-+ ldrne \rx, =UART_4_BASE @ virtual address
-+#endif
-+ .endm
-+
-+ .macro senduart,rd,rx @ Load byte into Tx holding register
-+ strb \rd, [\rx, #0] @ THR
-+ .endm
-+
-+ .macro waituart,rd,rx @ Wait until there is space in the TX FIFO
-+1001: ldrb \rd, [\rx, #5] @ LSR
-+ tst \rd, #1 << 5 @ THR empty
-+ beq 1001b
-+ .endm
-+
-+ .macro busyuart,rd,rx @ Wait until the TX is idle
-+#1001: ldrb \rd, [\rx, #5] @ LSR
-+# tst \rd, #1 << 6 @ THR and Tx FIFO empty
-+# beq 1001b
-+ .endm
-+
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/desc_alloc.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/desc_alloc.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/desc_alloc.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/desc_alloc.h 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,62 @@
-+/*
-+ * linux/include/asm-arm/arch-oxnas/dma.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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
-+ *
-+ *
-+ * Here we partition the available internal SRAM between the GMAC and generic
-+ * DMA descriptors. This requires defining the gmac_dma_desc_t structure here,
-+ * rather than in its more natural position within gmac.h
-+ */
-+#if !defined(__DESC_ALLOC_H__)
-+#define __DESC_ALLOC_H__
-+
-+#include <asm/arch/hardware.h>
-+
-+// GMAC DMA in-memory descriptor structures
-+typedef struct gmac_dma_desc
-+{
-+ /** The encoded status field of the GMAC descriptor */
-+ u32 status;
-+ /** The encoded length field of GMAC descriptor */
-+ u32 length;
-+ /** Buffer 1 pointer field of GMAC descriptor */
-+ u32 buffer1;
-+ /** Buffer 2 pointer or next descriptor pointer field of GMAC descriptor */
-+ u32 buffer2;
-+} __attribute ((aligned(4),packed)) gmac_dma_desc_t;
-+
-+#define NUM_GMAC_DMA_DESCRIPTORS CONFIG_ARCH_OXNAS_NUM_GMAC_DESCRIPTORS
-+
-+#define GMAC_DESC_ALLOC_START (SRAM_BASE)
-+#define GMAC_DESC_ALLOC_START_PA (DESCRIPTORS_BASE_PA)
-+/** Must be modified to track gmac_dma_desc_t definition above */
-+#define GMAC_DESC_ALLOC_SIZE ((NUM_GMAC_DMA_DESCRIPTORS) * (4*4))
-+
-+#if ((GMAC_DESC_ALLOC_SIZE) > (DESCRIPTORS_SIZE))
-+#error "Too many GMAC descriptors - descriptor SRAM allocation exceeded"
-+#endif
-+
-+#define DMA_DESC_ALLOC_START ((GMAC_DESC_ALLOC_START) + (GMAC_DESC_ALLOC_SIZE))
-+#define DMA_DESC_ALLOC_START_PA ((GMAC_DESC_ALLOC_START_PA) + (GMAC_DESC_ALLOC_SIZE))
-+#define DMA_DESC_ALLOC_SIZE ((DESCRIPTORS_SIZE) - (GMAC_DESC_ALLOC_SIZE))
-+
-+#define descriptors_virt_to_phys(x) ((x) - (SRAM_BASE) + (DESCRIPTORS_BASE_PA))
-+#define descriptors_phys_to_virt(x) ((x) - (DESCRIPTORS_BASE_PA) + (SRAM_BASE))
-+
-+#endif // #if !defined(__DESC_ALLOC_H__)
-+
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/dma.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/dma.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/dma.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/dma.h 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,299 @@
-+/*
-+ * linux/include/asm-arm/arch-oxnas/dma.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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
-+ *
-+ *
-+ * We have a generic DMAC that is a two port, memory to memory design, supporting
-+ * multiple channels, each of which can transfer between any pair of memory
-+ * regions. This DMAC architecture does not sit well with the std. ARM DMA
-+ * architecture, thus we define a custom way of acquiring and operating on the
-+ * available channels of the DMAC
-+ */
-+
-+#ifndef __ASM_ARCH_DMA_H
-+#define __ASM_ARCH_DMA_H
-+
-+#include <asm/scatterlist.h>
-+#include <asm/semaphore.h>
-+#include <linux/ata.h>
-+#include <linux/interrupt.h>
-+#include <linux/spinlock.h>
-+
-+/* All memory DMAable */
-+#define MAX_DMA_ADDRESS (~0UL)
-+
-+/* Do not want to use the std. ARM DMA architecure */
-+#define MAX_DMA_CHANNELS 0
-+
-+#define MAX_OXNAS_DMA_CHANNELS 5
-+
-+#define MAX_OXNAS_DMA_TRANSFER_LENGTH ((1 << 21) - 1)
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+// Need to set this (unused) high order address bit in the start address of DMA
-+// transfers in order for checksum calculation to be performed
-+#define OXNAS_DMA_CSUM_ENABLE_ADR_BIT 28
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+//#define OXNAS_DMA_TEST
-+//#define OXNAS_DMA_TEST_ITERATIONS 1
-+//#define OXNAS_DMA_SG_TEST
-+//#define OXNAS_DMA_SG_TEST_2
-+//#define OXNAS_DMA_SG_TEST_ITERATIONS 1
-+//#define OXNAS_DMA_SG_TEST2_ITERATIONS 1
-+//#define OXNAS_DMA_SG_TEST_DUMP_BUFFERS
-+//#define OXNAS_DMA_SG_TEST_DUMP_DESCRIPTORS
-+//#define OXNAS_DMA_TEST_AFTER_SG_ITERATIONS 0
-+//#define OXNAS_DMA_OVERALL_TEST_LOOPS 1
-+
-+// All other error codes are generated by the SG engine - refer to its
-+// documentation for details
-+typedef enum oxnas_dma_callback_status {
-+ OXNAS_DMA_ERROR_CODE_NONE
-+} oxnas_dma_callback_status_t;
-+
-+typedef enum oxnas_dma_mode {
-+ OXNAS_DMA_MODE_FIXED,
-+ OXNAS_DMA_MODE_INC
-+} oxnas_dma_mode_t;
-+
-+typedef enum oxnas_dma_direction {
-+ OXNAS_DMA_TO_DEVICE,
-+ OXNAS_DMA_FROM_DEVICE
-+} oxnas_dma_direction_t;
-+
-+struct oxnas_dma_channel;
-+typedef struct oxnas_dma_channel oxnas_dma_channel_t;
-+
-+#define OXNAS_DMA_CHANNEL_NUL ((oxnas_dma_channel_t*)0)
-+
-+typedef void* oxnas_callback_arg_t;
-+
-+#define OXNAS_DMA_CALLBACK_ARG_NUL ((oxnas_callback_arg_t)0)
-+
-+typedef void (*oxnas_dma_callback_t)(oxnas_dma_channel_t*, oxnas_callback_arg_t, oxnas_dma_callback_status_t, u16 checksum, int interrupt_count);
-+
-+#define OXNAS_DMA_CALLBACK_NUL ((oxnas_dma_callback_t)0)
-+
-+typedef enum oxnas_dma_eot_type {
-+ OXNAS_DMA_EOT_NONE,
-+ OXNAS_DMA_EOT_ALL,
-+ OXNAS_DMA_EOT_FINAL
-+} oxnas_dma_eot_type_t;
-+
-+// Will be exchanged with SG DMA controller
-+typedef struct oxnas_dma_sg_entry {
-+ dma_addr_t addr_; // The physical address of the buffer described by this descriptor
-+ unsigned long length_; // The length of the buffer described by this descriptor
-+ dma_addr_t p_next_; // The physical address of the next descriptor
-+ struct oxnas_dma_sg_entry *v_next_; // The virtual address of the next descriptor
-+ dma_addr_t paddr_; // The physical address of this descriptor
-+ struct oxnas_dma_sg_entry *next_; // To allow insertion into single-linked list
-+} __attribute ((aligned(4),packed)) oxnas_dma_sg_entry_t;
-+
-+// Will be exchanged with SG DMA controller
-+typedef struct oxnas_dma_sg_info {
-+ unsigned long qualifer_;
-+ unsigned long control_;
-+ dma_addr_t p_srcEntries_; // The physical address of the first source SG descriptor
-+ dma_addr_t p_dstEntries_; // The physical address of the first destination SG descriptor
-+ oxnas_dma_sg_entry_t *v_srcEntries_; // The virtual address of the first source SG descriptor
-+ oxnas_dma_sg_entry_t *v_dstEntries_; // The virtual address of the first destination SG descriptor
-+} __attribute ((aligned(4),packed)) oxnas_dma_sg_info_t;
-+
-+struct oxnas_dma_channel {
-+ unsigned channel_number_;
-+ oxnas_dma_callback_t notification_callback_;
-+ oxnas_callback_arg_t notification_arg_;
-+ dma_addr_t p_sg_info_; // Physical address of sg_info structure
-+ oxnas_dma_sg_info_t *v_sg_info_; // Virtual address of sg_info structure
-+ oxnas_dma_callback_status_t error_code_;
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ int checksumming_;
-+ u16 checksum_;
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+ unsigned rps_interrupt_;
-+ struct oxnas_dma_channel *next_;
-+ struct semaphore default_semaphore_;
-+ atomic_t interrupt_count_;
-+ atomic_t active_count_;
-+ int auto_sg_entries_;
-+};
-+
-+typedef struct oxnas_dma_controller {
-+ oxnas_dma_channel_t channels_[MAX_OXNAS_DMA_CHANNELS];
-+ unsigned numberOfChannels_;
-+ int version_;
-+ atomic_t run_bh_;
-+ spinlock_t spinlock_;
-+ struct tasklet_struct tasklet_;
-+ dma_addr_t p_sg_infos_; // Physical address of the array of sg_info structures
-+ oxnas_dma_sg_info_t *v_sg_infos_; // Virtual address of the array of sg_info structures
-+ struct semaphore csum_engine_sem_;
-+ spinlock_t alloc_spinlock_; // Sync. for SG management
-+ spinlock_t channel_alloc_spinlock_; // Sync. for channel management
-+ oxnas_dma_sg_entry_t *sg_entry_head_; // Pointer to head of free list for oxnas_dma_sg_entry_t objects
-+ struct semaphore sg_entry_sem_;
-+ unsigned sg_entry_available_;
-+ oxnas_dma_channel_t *channel_head_;
-+ struct semaphore channel_sem_;
-+} oxnas_dma_controller_t;
-+
-+typedef struct oxnas_dma_device_settings {
-+ unsigned long address_;
-+ unsigned fifo_size_; // Chained transfers must take account of FIFO offset at end of previous transfer
-+ unsigned char dreq_;
-+ unsigned read_eot_policy_:2;
-+ unsigned write_eot_policy_:2;
-+ unsigned bus_:1;
-+ unsigned width_:2;
-+ unsigned transfer_mode_:1;
-+ unsigned address_mode_:1;
-+ unsigned address_really_fixed_:1;
-+} oxnas_dma_device_settings_t;
-+
-+/* Pre-defined settings for known DMA devices */
-+extern oxnas_dma_device_settings_t oxnas_pata_dma_settings;
-+extern oxnas_dma_device_settings_t oxnas_sata_dma_settings;
-+extern oxnas_dma_device_settings_t oxnas_dpe_rx_dma_settings;
-+extern oxnas_dma_device_settings_t oxnas_dpe_tx_dma_settings;
-+
-+extern void oxnas_dma_init(void);
-+
-+extern void oxnas_dma_shutdown(void);
-+
-+extern oxnas_dma_channel_t* oxnas_dma_request(int block);
-+
-+extern void oxnas_dma_free(oxnas_dma_channel_t*);
-+
-+extern int oxnas_dma_is_active(oxnas_dma_channel_t*);
-+
-+extern int oxnas_dma_raw_isactive(oxnas_dma_channel_t*);
-+
-+extern int oxnas_dma_raw_sg_isactive(oxnas_dma_channel_t*);
-+
-+extern int oxnas_dma_get_raw_direction(oxnas_dma_channel_t*);
-+
-+/**
-+ * @param do_checksum An int indicating that the checksum engine is required
-+ * and causing the OXNAS_DMA_CSUM_ENABLE_ADR_BIT to be set
-+ * automatically in the passed src and dst start addresses
-+ * @return An int which is zero on success. Non-zero will returned if the length
-+ * exceeds that allowed by the hardware
-+ */
-+extern int oxnas_dma_set(
-+ oxnas_dma_channel_t *channel,
-+ unsigned char *src_adr, // Physical address
-+ unsigned long length,
-+ unsigned char *dst_adr, // Physical address
-+ oxnas_dma_mode_t src_mode,
-+ oxnas_dma_mode_t dst_mode,
-+ int do_checksum,
-+ int paused);
-+
-+/**
-+ * @return An int which is zero on success. Non-zero will returned if the length
-+ * exceeds that allowed by the hardware
-+ */
-+extern int oxnas_dma_device_set(
-+ oxnas_dma_channel_t *channel,
-+ oxnas_dma_direction_t direction,
-+ unsigned char *mem_adr, // Physical address
-+ unsigned long length,
-+ oxnas_dma_device_settings_t *device_settings,
-+ oxnas_dma_mode_t mem_mode,
-+ int paused);
-+
-+/**
-+ * @return An int which is zero on success. Non-zero will returned if the length
-+ * exceeds that allowed by the hardware
-+ */
-+extern int oxnas_dma_device_pair_set(
-+ oxnas_dma_channel_t *channel,
-+ unsigned long length,
-+ oxnas_dma_device_settings_t *src_device_settings,
-+ oxnas_dma_device_settings_t *dst_device_settings,
-+ int paused);
-+
-+/**
-+ * @param do_checksum An int indicating that the checksum engine is required
-+ * for this SG transfer. For the individual SG transfer
-+ * components to contribute to the checksum result, their
-+ * start addresses contained within the scatterlist
-+ * structures must have the OXNAS_DMA_CSUM_ENABLE_ADR_BIT
-+ * bit set
-+ *
-+ * NB This function does not have an error return value, but if it is passed
-+ * a transfer segment longer than the maximum allowed by the hardware, that
-+ * entry will be zeroed in the SG descriptor list and a kernel warning
-+ * message generated
-+ */
-+extern int oxnas_dma_set_sg(
-+ oxnas_dma_channel_t* channel,
-+ struct scatterlist* src_sg,
-+ unsigned src_sg_count,
-+ struct scatterlist* dst_sg,
-+ unsigned dst_sg_count,
-+ oxnas_dma_mode_t src_mode,
-+ oxnas_dma_mode_t dst_mode,
-+ int do_checksum,
-+ int in_atomic);
-+
-+/**
-+ * NB This function does not have an error return value, but if it is passed
-+ * a transfer segment longer than the maximum allowed by the hardware, that
-+ * entry will be zeroed in the SG descriptor list and a kernel warning
-+ * message generated
-+ */
-+extern int oxnas_dma_device_set_sg(
-+ oxnas_dma_channel_t* channel,
-+ oxnas_dma_direction_t direction,
-+ struct scatterlist* mem_sg,
-+ unsigned mem_sg_count,
-+ oxnas_dma_device_settings_t* device_settings,
-+ oxnas_dma_mode_t mem_mode,
-+ int in_atomic);
-+
-+extern int oxnas_dma_device_set_prd(
-+ oxnas_dma_channel_t *channel,
-+ oxnas_dma_direction_t direction,
-+ struct ata_prd *prd,
-+ oxnas_dma_device_settings_t *device_settings,
-+ oxnas_dma_mode_t mem_mode,
-+ oxnas_dma_sg_entry_t *sg_entries);
-+
-+/**
-+ * The callback function should complete quickly and must not sleep
-+ */
-+extern void oxnas_dma_set_callback(
-+ oxnas_dma_channel_t*,
-+ oxnas_dma_callback_t callback,
-+ oxnas_callback_arg_t callback_arg);
-+
-+extern void oxnas_dma_abort(oxnas_dma_channel_t*, int in_atomic);
-+
-+extern void oxnas_dma_start(oxnas_dma_channel_t*);
-+
-+extern void oxnas_dma_dump_registers(void);
-+
-+extern void oxnas_dma_dump_registers_single(int channel_number);
-+
-+extern int oxnas_dma_alloc_sg_entries(oxnas_dma_sg_entry_t** entries, unsigned required, int in_atomic);
-+
-+extern void oxnas_dma_free_sg_entries(oxnas_dma_sg_entry_t* entries);
-+#endif // __ASM_ARCH_DMA_H
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/entry-macro.S linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/entry-macro.S
---- linux-2.6.24/include/asm-arm/arch-oxnas/entry-macro.S 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/entry-macro.S 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,40 @@
-+/*
-+ * include/asm-arm/arch-oxnas/entry-macro.S
-+ *
-+ * Low-level IRQ helper macros for Integrator platforms
-+ *
-+ * 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 <asm/arch/irqs.h>
-+#include <asm/arch/hardware.h>
-+
-+ .macro disable_fiq
-+ .endm
-+
-+ .macro get_irqnr_preamble, base, tmp
-+ .endm
-+
-+ .macro arch_ret_to_user, tmp1, tmp2
-+ .endm
-+
-+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
-+ ldr \irqstat, =RPS_IRQ_STATUS
-+ ldr \irqstat, [\irqstat, #0]
-+
-+ mov \irqnr, #0
-+1001:
-+ tst \irqstat, #1
-+ bne 1002f
-+ add \irqnr, \irqnr, #1
-+ mov \irqstat, \irqstat, lsr #1
-+ cmp \irqnr, #NR_IRQS
-+ bcc 1001b
-+
-+1002:
-+ .endm
-+
-+ .macro irq_prio_table
-+ .endm
-+
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/hardware.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/hardware.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/hardware.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/hardware.h 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,760 @@
-+/* linux/include/asm-arm/arch-oxnas/hardware.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.
-+ */
-+
-+#ifndef __ASM_ARCH_HARDWARE_H
-+#define __ASM_ARCH_HARDWARE_H
-+
-+#include <asm/page.h>
-+#include <asm/memory.h>
-+#include <asm/sizes.h>
-+#include <asm/arch/vmalloc.h>
-+#include <asm/arch/timex.h>
-+
-+// The base of virtual address mappings for hardware cores starts directly after
-+// the end of the vmalloc mapping region
-+#define OXNAS_HW_PA_TO_VA(x) (VMALLOC_END + (x))
-+
-+// Virtual address mapping of hardware cores
-+#define APB_BRIDGE_A_BASE OXNAS_HW_PA_TO_VA(0)
-+#define STATIC_CONTROL_BASE OXNAS_HW_PA_TO_VA(0x1000000)
-+#define CORE_MODULE_BASE OXNAS_HW_PA_TO_VA(0x2000000)
-+#define EXTERNAL_UART_BASE OXNAS_HW_PA_TO_VA(0x3000000)
-+#define EXTERNAL_UART_2_BASE OXNAS_HW_PA_TO_VA(0x3800000)
-+
-+/* 16 Mbyte address range on AMBA bus */
-+#define APB_BRIDGE_BASE_MASK 0x00FFFFFF
-+
-+#define APB_BRIDGE_B_BASE OXNAS_HW_PA_TO_VA(0x04000000)
-+#define SATA_DATA_BASE OXNAS_HW_PA_TO_VA(0x05000000)
-+#define DPE_BASE OXNAS_HW_PA_TO_VA(0x06000000)
-+#define USB_BASE OXNAS_HW_PA_TO_VA(0x07000000)
-+#define MAC_BASE OXNAS_HW_PA_TO_VA(0x08000000)
-+#define PCI_CSRS_BASE OXNAS_HW_PA_TO_VA(0x0A000000)
-+#define STATIC_CS0_BASE OXNAS_HW_PA_TO_VA(0x0B000000)
-+#define STATIC_CS1_BASE OXNAS_HW_PA_TO_VA(0x0C000000)
-+#define STATIC_CS2_BASE OXNAS_HW_PA_TO_VA(0x0D000000)
-+#define ROM_BASE OXNAS_HW_PA_TO_VA(0x0E000000)
-+#define SDRAM_CTRL_BASE OXNAS_HW_PA_TO_VA(0x0F000000)
-+#define LEON_IMAGE_BASE OXNAS_HW_PA_TO_VA(0x10000000)
-+#define SRAM_BASE OXNAS_HW_PA_TO_VA(0x11000000)
-+
-+#ifdef CONFIG_SUPPORT_LEON
-+#define LEON_IMAGE_SIZE (CONFIG_LEON_PAGES * PAGE_SIZE)
-+#define LEON_IMAGE_BASE_PA (((SRAM_END) + 1) - (LEON_IMAGE_SIZE))
-+#else // CONFIG_SUPPORT_LEON
-+#define LEON_IMAGE_SIZE 0
-+#define LEON_IMAGE_BASE_PA 0
-+#endif // CONFIG_SUPPORT_LEON
-+
-+#if (LEON_IMAGE_BASE_PA >= SRAM_PA) && (LEON_IMAGE_BASE_PA <= SRAM_END)
-+#define LEON_IMAGE_IN_SRAM
-+#endif
-+
-+#define DESCRIPTORS_SIZE (CONFIG_DESCRIPTORS_PAGES * PAGE_SIZE)
-+
-+#ifdef CONFIG_DESCRIPTORS_PAGES
-+#if (CONFIG_DESCRIPTORS_PAGES > CONFIG_SRAM_NUM_PAGES)
-+#error "Too many descriptor pages defined - greater than total SRAM pages"
-+#endif
-+#endif // CONFIG_DESCRIPTORS_PAGES
-+
-+#define DESCRIPTORS_BASE_PA (SRAM_PA)
-+#define DESCRIPTORS_END_PA (SRAM_PA + DESCRIPTORS_SIZE)
-+
-+#ifdef LEON_IMAGE_IN_SRAM
-+#if (DESCRIPTORS_END_PA > LEON_IMAGE_BASE_PA)
-+#error "Overlapping LEON and Descriptor areas in SRAM"
-+#endif
-+#endif
-+
-+#define CORE_MODULE_BASE_PA 0x10000000
-+
-+#define ROM_BASE_PA 0x40000000
-+#define USB_BASE_PA 0x40200000
-+#define MAC_BASE_PA 0x40400000
-+#define PCI_CSRS_BASE_PA 0x40600000
-+#define PCI_BASE_PA 0x40800000
-+
-+#define STATIC_CS0_BASE_PA 0x41000000
-+#define STATIC_CS1_BASE_PA 0x41400000
-+#define STATIC_CS2_BASE_PA 0x41800000
-+#define STATIC_CONTROL_BASE_PA 0x41C00000
-+
-+#define SATA_DATA_BASE_PA 0x42000000
-+#define DPE_BASE_PA 0x43000000
-+#define APB_BRIDGE_A_BASE_PA 0x44000000
-+#define APB_BRIDGE_B_BASE_PA 0x45000000
-+
-+#define UART_1_BASE_PA (APB_BRIDGE_A_BASE_PA + 0x200000)
-+#define UART_2_BASE_PA (APB_BRIDGE_A_BASE_PA + 0x300000)
-+#define UART_3_BASE_PA (APB_BRIDGE_A_BASE_PA + 0x900000)
-+#define UART_4_BASE_PA (APB_BRIDGE_A_BASE_PA + 0xA00000)
-+
-+#define GPIO_A_BASE APB_BRIDGE_A_BASE
-+#define GPIO_B_BASE (APB_BRIDGE_A_BASE + 0x100000)
-+#define UART_1_BASE (APB_BRIDGE_A_BASE + 0x200000)
-+#define UART_2_BASE (APB_BRIDGE_A_BASE + 0x300000)
-+#define UART_3_BASE (APB_BRIDGE_A_BASE + 0x900000)
-+#define UART_4_BASE (APB_BRIDGE_A_BASE + 0xA00000)
-+#define I2C_BASE (APB_BRIDGE_A_BASE + 0x400000)
-+#define I2S_BASE (APB_BRIDGE_A_BASE + 0x500000)
-+#define FAN_MON_BASE (APB_BRIDGE_A_BASE + 0x600000)
-+#define PWM_BASE (APB_BRIDGE_A_BASE + 0x700000)
-+#define IRRX_BASE (APB_BRIDGE_A_BASE + 0x800000)
-+
-+#define SYS_CONTROL_BASE APB_BRIDGE_B_BASE
-+#define CLOCK_CONTROL_BASE (APB_BRIDGE_B_BASE + 0x100000)
-+#define RTC_BASE (APB_BRIDGE_B_BASE + 0x200000)
-+#define RPS_BASE (APB_BRIDGE_B_BASE + 0x300000)
-+#define COPRO_RPS_BASE (APB_BRIDGE_B_BASE + 0x400000)
-+#define AHB_MON_BASE (APB_BRIDGE_B_BASE + 0x500000)
-+#define DMA_BASE (APB_BRIDGE_B_BASE + 0x600000)
-+#define DPE_REGS_BASE (APB_BRIDGE_B_BASE + 0x700000)
-+#define IBW_REGS_BASE (APB_BRIDGE_B_BASE + 0x780000)
-+#define DDR_REGS_BASE (APB_BRIDGE_B_BASE + 0x800000)
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+#define SATA0_REGS_BASE (APB_BRIDGE_B_BASE + 0x900000)
-+#define SATA0_LINK_REGS_BASE (APB_BRIDGE_B_BASE + 0x940000)
-+#define SATA1_REGS_BASE (APB_BRIDGE_B_BASE + 0x980000)
-+#define SATA1_LINK_REGS_BASE (APB_BRIDGE_B_BASE + 0x9C0000)
-+#elif CONFIG_OXNAS_VERSION_0X810
-+#define SATA_REG_BASE (APB_BRIDGE_B_BASE + 0x900000)
-+#define SATA0_REGS_BASE (SATA_REG_BASE)
-+#define SATA1_REGS_BASE (SATA_REG_BASE + 0x10000)
-+#define SATACORE_REGS_BASE (SATA_REG_BASE + 0xe0000)
-+#define SATARAID_REGS_BASE (SATA_REG_BASE + 0xf0000)
-+#endif // CONFIG_OXNAS_VERSION_0X8xx
-+
-+#define DMA_CHECKSUM_BASE (APB_BRIDGE_B_BASE + 0xA00000)
-+#define COPRO_REGS_BASE (APB_BRIDGE_B_BASE + 0xB00000)
-+#define DMA_SG_BASE (APB_BRIDGE_B_BASE + 0xC00000)
-+
-+/* Interrupt Controller registers */
-+#define RPS_IC_BASE RPS_BASE
-+#define RPS_IRQ_STATUS (RPS_IC_BASE)
-+#define RPS_IRQ_RAW_STATUS (RPS_IC_BASE + 0x04)
-+#define RPS_IRQ_ENABLE (RPS_IC_BASE + 0x08)
-+#define RPS_IRQ_DISABLE (RPS_IC_BASE + 0x0C)
-+#define RPS_IRQ_SOFT (RPS_IC_BASE + 0x10)
-+
-+/* FIQ registers */
-+#define RPS_FIQ_BASE (RPS_IC_BASE + 0x100)
-+#define RPS_FIQ_STATUS (RPS_FIQ_BASE + 0x00)
-+#define RPS_FIQ_RAW_STATUS (RPS_FIQ_BASE + 0x04)
-+#define RPS_FIQ_ENABLE (RPS_FIQ_BASE + 0x08)
-+#define RPS_FIQ_DISABLE (RPS_FIQ_BASE + 0x0C)
-+
-+/* Timer registers */
-+#define RPS_TIMER_BASE (RPS_BASE + 0x200)
-+#define RPS_TIMER1_BASE (RPS_TIMER_BASE)
-+#define RPS_TIMER2_BASE (RPS_TIMER_BASE + 0x20)
-+
-+#define TIMER1_LOAD (RPS_TIMER1_BASE + 0x0)
-+#define TIMER1_VALUE (RPS_TIMER1_BASE + 0x4)
-+#define TIMER1_CONTROL (RPS_TIMER1_BASE + 0x8)
-+#define TIMER1_CLEAR (RPS_TIMER1_BASE + 0xc)
-+
-+#define TIMER2_LOAD (RPS_TIMER2_BASE + 0x0)
-+#define TIMER2_VALUE (RPS_TIMER2_BASE + 0x4)
-+#define TIMER2_CONTROL (RPS_TIMER2_BASE + 0x8)
-+#define TIMER2_CLEAR (RPS_TIMER2_BASE + 0xc)
-+
-+#define TIMER_MODE_BIT 6
-+#define TIMER_MODE_FREE_RUNNING 0
-+#define TIMER_MODE_PERIODIC 1
-+#define TIMER_ENABLE_BIT 7
-+#define TIMER_ENABLE_DISABLE 0
-+#define TIMER_ENABLE_ENABLE 1
-+
-+/* System clock frequencies */
-+#ifdef CONFIG_ARCH_OXNAS_FPGA
-+/* FPGA CPU clock is entirely independent of rest of SoC */
-+#define NOMINAL_ARMCLK (CONFIG_OXNAS_CORE_CLK)
-+#else // CONFIG_ARCH_OXNAS_FPGA
-+/* ASIC CPU clock is derived from SoC master clock */
-+#define NOMINAL_ARMCLK (CONFIG_NOMINAL_PLL400_FREQ / 2)
-+#endif // CONFIG_ARCH_OXNAS_FPGA
-+
-+#define NOMINAL_SYSCLK (CONFIG_NOMINAL_PLL400_FREQ / 4)
-+#define NOMINAL_PCICLK 33000000
-+
-+#ifdef CONFIG_ARCH_OXNAS_FPGA
-+/* FPGA has no PCI clock divider */
-+#define PCI_CLOCK_DIVIDER 1
-+#else // CONFIG_ARCH_OXNAS_FPGA
-+/* ASIC PCI divider divides CONFIG_NOMINAL_PLL400_FREQ by 2(n + 1) to get 33MHz */
-+#define PCI_CLOCK_DIVIDER (((CONFIG_NOMINAL_PLL400_FREQ) / (2 * NOMINAL_PCICLK)) - 1)
-+#endif //CONFIG_ARCH_OXNAS_FPGA
-+
-+/* RPS timer setup */
-+#define TIMER_1_MODE TIMER_MODE_PERIODIC
-+#define TIMER_2_PRESCALE_ENUM TIMER_PRESCALE_256
-+#define TIMER_2_MODE TIMER_MODE_FREE_RUNNING
-+
-+/* Useful macros for dealing with sub timer-interrupt intervals - preserve
-+ * as much precision as possible without using floating point and minimising
-+ * runtime CPU requirement */
-+#define TIMER_1_LOAD_VALUE ((CLOCK_TICK_RATE) / HZ)
-+#define TICKS_TO_US_SCALING 1024
-+#define TICKS_TO_US_FACTOR (((2 * TICKS_TO_US_SCALING * 1000000) + CLOCK_TICK_RATE) / (2 * CLOCK_TICK_RATE))
-+#define TICKS_TO_US(ticks) ((((ticks) * TICKS_TO_US_FACTOR * 2) + TICKS_TO_US_SCALING) / (2 * TICKS_TO_US_SCALING))
-+
-+/* Remap and pause */
-+#define RPS_REMAP_AND_PAUSE (RPS_BASE + 0x300)
-+
-+/* GPIO */
-+#define GPIO_0 (0x00)
-+#define GPIO_1 (0x01)
-+#define GPIO_2 (0x02)
-+#define GPIO_3 (0x03)
-+#define GPIO_4 (0x04)
-+#define GPIO_5 (0x05)
-+#define GPIO_6 (0x06)
-+#define GPIO_7 (0x07)
-+#define GPIO_8 (0x08)
-+#define GPIO_9 (0x09)
-+#define GPIO_10 (0x0a)
-+#define GPIO_11 (0x0b)
-+#define GPIO_12 (0x0c)
-+#define GPIO_13 (0x0d)
-+#define GPIO_14 (0x0e)
-+#define GPIO_15 (0x0f)
-+#define GPIO_16 (0x10)
-+#define GPIO_17 (0x11)
-+#define GPIO_18 (0x12)
-+#define GPIO_19 (0x13)
-+#define GPIO_20 (0x14)
-+#define GPIO_21 (0x15)
-+#define GPIO_22 (0x16)
-+#define GPIO_23 (0x17)
-+#define GPIO_24 (0x18)
-+#define GPIO_25 (0x19)
-+#define GPIO_26 (0x1a)
-+#define GPIO_27 (0x1b)
-+#define GPIO_28 (0x1c)
-+#define GPIO_29 (0x1d)
-+#define GPIO_30 (0x1e)
-+#define GPIO_31 (0x1f)
-+#define GPIO_32 (0x00)
-+#define GPIO_33 (0x01)
-+#define GPIO_34 (0x02)
-+
-+/* Symbols for functions mapped onto GPIO lines */
-+#ifdef CONFIG_ARCH_OXNAS_FPGA
-+#define PCI_GPIO_INTA_PLANAR 8
-+#define PCI_GPIO_INTA_MINIPCI 9
-+#else // CONFIG_ARCH_OXNAS_FPGA
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+#define PCI_GPIO_INTA_PLANAR 3
-+#define PCI_GPIO_INTA_MINIPCI 9
-+#elif CONFIG_OXNAS_VERSION_0X810
-+#define PCI_GPIO_INTA_PLANAR 3
-+#define PCI_GPIO_INTA_MINIPCI 9
-+#endif // CONFIG_OXNAS_VERSION_0X8xx
-+#endif // CONFIG_ARCH_OXNAS_FPGA
-+
-+#define PCI_GPIO_CLKO_0 8
-+#define PCI_GPIO_CLKO_1 9
-+#define PCI_GPIO_CLKO_2 10
-+#define PCI_GPIO_CLKO_3 11
-+#define PCI_GPIO_CLKO_4 23
-+
-+#define PCI_GNT_N0 0
-+#define PCI_GNT_N1 1
-+#define PCI_GNT_N2 2
-+#define PCI_GNT_N3 3
-+#define PCI_REQ_N0 4
-+#define PCI_REQ_N1 5
-+#define PCI_REQ_N2 6
-+#define PCI_REQ_N3 7
-+
-+#define IBW_GPIO_DATA (GPIO_33)
-+
-+#define USBA_POWO_GPIO 23
-+#define USBA_OVERI_GPIO 24
-+#define USBB_POWO_GPIO 25
-+#define USBB_OVERI_GPIO 26
-+#define USBC_POWO_GPIO 27
-+#define USBC_OVERI_GPIO 28
-+
-+/* RPS GPIO registers */
-+#define RPS_GPIO_BASE GPIO_1_BASE /*(RPS_BASE + 0x3C0) ??????? */
-+
-+/* GPIO A registers */
-+#define GPIO_A_DATA GPIO_A_BASE
-+#define GPIO_A_OUTPUT_ENABLE (GPIO_A_BASE + 0x0004)
-+#define GPIO_A_INTERRUPT_ENABLE (GPIO_A_BASE + 0x0008)
-+#define GPIO_A_INTERRUPT_EVENT (GPIO_A_BASE + 0x000C)
-+#define GPIO_A_OUTPUT_VALUE (GPIO_A_BASE + 0x0010)
-+#define GPIO_A_OUTPUT_SET (GPIO_A_BASE + 0x0014)
-+#define GPIO_A_OUTPUT_CLEAR (GPIO_A_BASE + 0x0018)
-+#define GPIO_A_OUTPUT_ENABLE_SET (GPIO_A_BASE + 0x001C)
-+#define GPIO_A_OUTPUT_ENABLE_CLEAR (GPIO_A_BASE + 0x0020)
-+#define GPIO_A_INPUT_DEBOUNCE_ENABLE (GPIO_A_BASE + 0x0024)
-+#define GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE (GPIO_A_BASE + 0x0028)
-+#define GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE (GPIO_A_BASE + 0x002C)
-+#define GPIO_A_RISING_EDGE_DETECT (GPIO_A_BASE + 0x0030)
-+#define GPIO_A_FALLING_EDGE_DETECT (GPIO_A_BASE + 0x0034)
-+#define GPIO_A_LEVEL_INTERRUPT_ENABLE (GPIO_A_BASE + 0x0038)
-+#define GPIO_A_INTERRUPT_STATUS_REGISTER (GPIO_A_BASE + 0x003C)
-+
-+/* GPIO B registers */
-+#define GPIO_B_DATA GPIO_B_BASE
-+#define GPIO_B_OUTPUT_ENABLE (GPIO_B_BASE + 0x0004)
-+#define GPIO_B_INTERRUPT_ENABLE (GPIO_B_BASE + 0x0008)
-+#define GPIO_B_INTERRUPT_EVENT (GPIO_B_BASE + 0x000C)
-+#define GPIO_B_OUTPUT_VALUE (GPIO_B_BASE + 0x0010)
-+#define GPIO_B_OUTPUT_SET (GPIO_B_BASE + 0x0014)
-+#define GPIO_B_OUTPUT_CLEAR (GPIO_B_BASE + 0x0018)
-+#define GPIO_B_OUTPUT_ENABLE_SET (GPIO_B_BASE + 0x001C)
-+#define GPIO_B_OUTPUT_ENABLE_CLEAR (GPIO_B_BASE + 0x0020)
-+#define GPIO_B_INPUT_DEBOUNCE_ENABLE (GPIO_B_BASE + 0x0024)
-+#define GPIO_B_RISING_EDGE_ACTIVE_HIGH_ENABLE (GPIO_B_BASE + 0x0028)
-+#define GPIO_B_FALLING_EDGE_ACTIVE_LOW_ENABLE (GPIO_B_BASE + 0x002C)
-+#define GPIO_B_RISING_EDGE_DETECT (GPIO_B_BASE + 0x0030)
-+#define GPIO_B_FALLING_EDGE_DETECT (GPIO_B_BASE + 0x0034)
-+#define GPIO_B_LEVEL_INTERRUPT_ENABLE (GPIO_B_BASE + 0x0038)
-+#define GPIO_B_INTERRUPT_STATUS_REGISTER (GPIO_B_BASE + 0x003C)
-+
-+/* CoProcessor RPS GPIO registers */
-+#define COPRO_GPIO_A_BASE (COPRO_RPS_BASE + 0x3C0)
-+#define COPRO_GPIO_A_DATA COPRO_GPIO_A_BASE
-+#define COPRO_GPIO_A_OUTPUT_ENABLE (COPRO_GPIO_A_BASE + 0x04)
-+#define COPRO_GPIO_A_INTERRUPT_MASK (COPRO_GPIO_A_BASE + 0x08)
-+#define COPRO_GPIO_A_INTERRUPT_EVENT (COPRO_GPIO_A_BASE + 0x0C)
-+
-+/* Static bus registers */
-+#define STATIC_CONTROL_VERSION (STATIC_CONTROL_BASE + 0x0)
-+#define STATIC_CONTROL_BANK0 (STATIC_CONTROL_BASE + 0x4)
-+#define STATIC_CONTROL_BANK1 (STATIC_CONTROL_BASE + 0x8)
-+#define STATIC_CONTROL_BANK2 (STATIC_CONTROL_BASE + 0xC)
-+
-+/* System Control registers */
-+#define SYS_CTRL_USB11_CTRL (SYS_CONTROL_BASE + 0x00)
-+#define SYS_CTRL_PCI_CTRL0 (SYS_CONTROL_BASE + 0x04)
-+#define SYS_CTRL_PCI_CTRL1 (SYS_CONTROL_BASE + 0x08)
-+#define SYS_CTRL_GPIO_PRIMSEL_CTRL_0 (SYS_CONTROL_BASE + 0x0C)
-+#define SYS_CTRL_GPIO_PRIMSEL_CTRL_1 (SYS_CONTROL_BASE + 0x10)
-+#define SYS_CTRL_GPIO_SECSEL_CTRL_0 (SYS_CONTROL_BASE + 0x14)
-+#define SYS_CTRL_GPIO_SECSEL_CTRL_1 (SYS_CONTROL_BASE + 0x18)
-+#define SYS_CTRL_GPIO_TERTSEL_CTRL_0 (SYS_CONTROL_BASE + 0x8C)
-+#define SYS_CTRL_GPIO_TERTSEL_CTRL_1 (SYS_CONTROL_BASE + 0x90)
-+#define SYS_CTRL_USB11_STAT (SYS_CONTROL_BASE + 0x1c)
-+#define SYS_CTRL_PCI_STAT (SYS_CONTROL_BASE + 0x20)
-+#define SYS_CTRL_CKEN_CTRL (SYS_CONTROL_BASE + 0x24)
-+#define SYS_CTRL_RSTEN_CTRL (SYS_CONTROL_BASE + 0x28)
-+#define SYS_CTRL_CKEN_SET_CTRL (SYS_CONTROL_BASE + 0x2C)
-+#define SYS_CTRL_CKEN_CLR_CTRL (SYS_CONTROL_BASE + 0x30)
-+#define SYS_CTRL_RSTEN_SET_CTRL (SYS_CONTROL_BASE + 0x34)
-+#define SYS_CTRL_RSTEN_CLR_CTRL (SYS_CONTROL_BASE + 0x38)
-+#define SYS_CTRL_USBHSMPH_CTRL (SYS_CONTROL_BASE + 0x40)
-+#define SYS_CTRL_USBHSMPH_STAT (SYS_CONTROL_BASE + 0x44)
-+#define SYS_CTRL_PLLSYS_CTRL (SYS_CONTROL_BASE + 0x48)
-+#define SYS_CTRL_SEMA_STAT (SYS_CONTROL_BASE + 0x4C)
-+#define SYS_CTRL_SEMA_SET_CTRL (SYS_CONTROL_BASE + 0x50)
-+#define SYS_CTRL_SEMA_CLR_CTRL (SYS_CONTROL_BASE + 0x54)
-+#define SYS_CTRL_SEMA_MASKA_CTRL (SYS_CONTROL_BASE + 0x58)
-+#define SYS_CTRL_SEMA_MASKB_CTRL (SYS_CONTROL_BASE + 0x5C)
-+#define SYS_CTRL_SEMA_MASKC_CTRL (SYS_CONTROL_BASE + 0x60)
-+#define SYS_CTRL_CKCTRL_CTRL (SYS_CONTROL_BASE + 0x64)
-+#define SYS_CTRL_COPRO_CTRL (SYS_CONTROL_BASE + 0x68)
-+#define SYS_CTRL_PLLSYS_KEY_CTRL (SYS_CONTROL_BASE + 0x6C)
-+#define SYS_CTRL_GMAC_CTRL (SYS_CONTROL_BASE + 0x78)
-+#define SYS_CTRL_USBHSPHY_CTRL (SYS_CONTROL_BASE + 0x84)
-+#define SYS_CTRL_UART_CTRL (SYS_CONTROL_BASE + 0x94)
-+#define SYS_CTRL_GPIO_PWMSEL_CTRL_0 (SYS_CONTROL_BASE + 0x9C)
-+#define SYS_CTRL_GPIO_PWMSEL_CTRL_1 (SYS_CONTROL_BASE + 0xA0)
-+#define SYSCTRL_GPIO_MONSEL_CTRL_0 (SYS_CONTROL_BASE + 0xA4)
-+#define SYSCTRL_GPIO_MONSEL_CTRL_1 (SYS_CONTROL_BASE + 0xA8)
-+#define SYSCTRL_GPIO_PULLUP_CTRL_0 (SYS_CONTROL_BASE + 0xAC)
-+#define SYSCTRL_GPIO_PULLUP_CTRL_1 (SYS_CONTROL_BASE + 0xB0)
-+#define SYSCTRL_GPIO_ODRIVEHI_CTRL_0 (SYS_CONTROL_BASE + 0xB4)
-+#define SYSCTRL_GPIO_ODRIVEHI_CTRL_1 (SYS_CONTROL_BASE + 0xB8)
-+#define SYSCTRL_GPIO_ODRIVELO_CTRL_0 (SYS_CONTROL_BASE + 0xBC)
-+#define SYSCTRL_GPIO_ODRIVELO_CTRL_1 (SYS_CONTROL_BASE + 0xC0)
-+
-+
-+/* System control register field definitions */
-+#define SYSCTL_CB_CIS_OFFSET_0 SYS_CTRL_PCI_CTRL0
-+
-+#define SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO5 19
-+#define SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO4 18
-+#define SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO3 17
-+#define SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO2 16
-+#define SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO1 15
-+#define SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO0 14
-+#define SYSCTL_PCI_CTRL1_ENPU 13
-+#define SYSCTL_PCI_CTRL1_ENCB 12
-+#define SYSCTL_PCI_CTRL1_SYSPCI_STATIC_REQ 11
-+#define SYSCTL_PCI_CTRL1_SS_HOST_E 10
-+#define SYSCTL_PCI_CTRL1_SYSPCI_PAKING_ENABLE 9
-+#define SYSCTL_PCI_CTRL1_SYSPCI_PAKING_MASTE 7
-+#define SYSCTL_PCI_CTRL1_SS_CADBUS_E 6
-+#define SYSCTL_PCI_CTRL1_SS_MINIPCI_ 5
-+#define SYSCTL_PCI_CTRL1_SS_INT_MASK_0 4
-+#define SYSCTL_PCI_CTRL1_INT_STATUS_0 3
-+#define SYSCTL_PCI_CTRL1_APP_EQUIES_NOM_CLK 2
-+#define SYSCTL_PCI_CTRL1_APP_CBUS_INT_N 1
-+#define SYSCTL_PCI_CTRL1_APP_CSTSCHG_N 0
-+
-+#define SYSCTL_PCI_STAT_SYSPCI_CLKCHG_EQ 3
-+#define SYSCTL_PCI_STAT_SYSPCI_STATIC_GNT 2
-+#define SYSCTL_PCI_STAT_INT_DISABLE_0 1
-+#define SYSCTL_PCI_STAT_CLK_CHANGED 0
-+
-+#define SYS_CTRL_CKEN_COPRO_BIT 0
-+#define SYS_CTRL_CKEN_DMA_BIT 1
-+#define SYS_CTRL_CKEN_DPE_BIT 2
-+#define SYS_CTRL_CKEN_DDR_BIT 3
-+#define SYS_CTRL_CKEN_SATA_BIT 4
-+#define SYS_CTRL_CKEN_I2S_BIT 5
-+#define SYS_CTRL_CKEN_USBHS_BIT 6
-+#define SYS_CTRL_CKEN_MAC_BIT 7
-+#define SYS_CTRL_CKEN_PCI_BIT 8
-+#define SYS_CTRL_CKEN_STATIC_BIT 9
-+
-+#define SYS_CTRL_RSTEN_ARM_BIT 0
-+#define SYS_CTRL_RSTEN_COPRO_BIT 1
-+#define SYS_CTRL_RSTEN_USBHS_BIT 4
-+#define SYS_CTRL_RSTEN_USBHSPHY_BIT 5
-+#define SYS_CTRL_RSTEN_MAC_BIT 6
-+#define SYS_CTRL_RSTEN_PCI_BIT 7
-+#define SYS_CTRL_RSTEN_DMA_BIT 8
-+#define SYS_CTRL_RSTEN_DPE_BIT 9
-+#define SYS_CTRL_RSTEN_DDR_BIT 10
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+ #define SYS_CTRL_RSTEN_SATA_BIT 11
-+ #define SYS_CTRL_RSTEN_SATA_PHY_BIT 12
-+#elif CONFIG_OXNAS_VERSION_0X810
-+ #define SYS_CTRL_RSTEN_SATA_BIT 11
-+ #define SYS_CTRL_RSTEN_SATA_LINK_BIT 12
-+ #define SYS_CTRL_RSTEN_SATA_PHY_BIT 13
-+#endif
-+
-+#define SYS_CTRL_RSTEN_STATIC_BIT 15
-+#define SYS_CTRL_RSTEN_GPIO_BIT 16
-+#define SYS_CTRL_RSTEN_UART1_BIT 17
-+#define SYS_CTRL_RSTEN_UART2_BIT 18
-+#define SYS_CTRL_RSTEN_MISC_BIT 19
-+#define SYS_CTRL_RSTEN_I2S_BIT 20
-+#define SYS_CTRL_RSTEN_AHB_MON_BIT 21
-+#define SYS_CTRL_RSTEN_UART3_BIT 22
-+#define SYS_CTRL_RSTEN_UART4_BIT 23
-+#define SYS_CTRL_RSTEN_SGDMA_BIT 24
-+#define SYS_CTRL_RSTEN_BUS_BIT 31
-+
-+#define SYS_CTRL_USBHSMPH_IP_POL_A_BIT 0
-+#define SYS_CTRL_USBHSMPH_IP_POL_B_BIT 1
-+#define SYS_CTRL_USBHSMPH_IP_POL_C_BIT 2
-+#define SYS_CTRL_USBHSMPH_OP_POL_A_BIT 3
-+#define SYS_CTRL_USBHSMPH_OP_POL_B_BIT 4
-+#define SYS_CTRL_USBHSMPH_OP_POL_C_BIT 5
-+
-+#define SYS_CTRL_GMAC_RGMII 2
-+#define SYS_CTRL_GMAC_SIMPLE_MAX 1
-+#define SYS_CTRL_GMAC_CKEN_GTX 0
-+
-+#define SYS_CTRL_CKCTRL_CTRL_PCIDIV_BIT 0
-+#define SYS_CTRL_CKCTRL_CTRL_PCIDIV_NUM_BITS 4
-+
-+#define SYS_CTRL_USBHSPHY_SUSPENDM_MANUAL_ENABLE 16
-+#define SYS_CTRL_USBHSPHY_SUSPENDM_MANUAL_STATE 15
-+#define SYS_CTRL_USBHSPHY_ATE_ESET 14
-+#define SYS_CTRL_USBHSPHY_TEST_DIN 6
-+#define SYS_CTRL_USBHSPHY_TEST_ADD 2
-+#define SYS_CTRL_USBHSPHY_TEST_DOUT_SEL 1
-+#define SYS_CTRL_USBHSPHY_TEST_CLK 0
-+
-+#define SYS_CTRL_UART2_DEQ_EN 0
-+#define SYS_CTRL_UART3_DEQ_EN 1
-+#define SYS_CTRL_UART3_IQ_EN 2
-+#define SYS_CTRL_UART4_IQ_EN 3
-+#define SYS_CTRL_UART4_NOT_PCI_MODE 4
-+
-+/* DDR core registers */
-+#define DDR_CFG_REG (DDR_REGS_BASE + 0x00)
-+#define DDR_BLKEN_REG (DDR_REGS_BASE + 0x04)
-+#define DDR_STAT_REG (DDR_REGS_BASE + 0x08)
-+#define DDR_CMD_REG (DDR_REGS_BASE + 0x0C)
-+#define DDR_AHB_REG (DDR_REGS_BASE + 0x10)
-+#define DDR_DLL_REG (DDR_REGS_BASE + 0x14)
-+#define DDR_MON_REG (DDR_REGS_BASE + 0x18)
-+#define DDR_DIAG_REG (DDR_REGS_BASE + 0x1C)
-+#define DDR_DIAG2_REG (DDR_REGS_BASE + 0x20)
-+#define DDR_IOC_REG (DDR_REGS_BASE + 0x24)
-+#define DDR_ARB_REG (DDR_REGS_BASE + 0x28)
-+#define DDR_AHB2_REG (DDR_REGS_BASE + 0x2C)
-+#define DDR_BUSY_REG (DDR_REGS_BASE + 0x30)
-+#define DDR_TIMING0_REG (DDR_REGS_BASE + 0x34)
-+#define DDR_TIMING1_REG (DDR_REGS_BASE + 0x38)
-+#define DDR_TIMING2_REG (DDR_REGS_BASE + 0x3C)
-+#define DDR_AHB3_REG (DDR_REGS_BASE + 0x40)
-+#define DDR_AHB4_REG (DDR_REGS_BASE + 0x44)
-+#define DDR_PHY0_REG (DDR_REGS_BASE + 0x48)
-+#define DDR_PHY1_REG (DDR_REGS_BASE + 0x4C)
-+#define DDR_PHY2_REG (DDR_REGS_BASE + 0x50)
-+#define DDR_PHY3_REG (DDR_REGS_BASE + 0x54)
-+
-+/* DDR core register field definitions */
-+#define DDR_BLKEN_CLIENTS_BIT 0
-+#define DDR_BLKEN_CLIENTS_NUM_BITS 16
-+#define DDR_BLKEN_DDR_BIT 31
-+
-+#define DDR_AHB_FLUSH_RCACHE_BIT 0
-+#define DDR_AHB_FLUSH_RCACHE_NUM_BITS 16
-+
-+#define DDR_AHB_FLUSH_RCACHE_ARMD_BIT 0
-+#define DDR_AHB_FLUSH_RCACHE_ARMI_BIT 1
-+#define DDR_AHB_FLUSH_RCACHE_COPRO_BIT 2
-+#define DDR_AHB_FLUSH_RCACHE_DMAA_BIT 3
-+#define DDR_AHB_FLUSH_RCACHE_DMAB_BIT 4
-+#define DDR_AHB_FLUSH_RCACHE_PCI_BIT 5
-+#define DDR_AHB_FLUSH_RCACHE_GMAC_BIT 6
-+#define DDR_AHB_FLUSH_RCACHE_USB_BIT 7
-+
-+#define DDR_AHB_NO_RCACHE_BIT 16
-+#define DDR_AHB_NO_RCACHE_NUM_BITS 16
-+
-+#define DDR_AHB_NO_RCACHE_ARMD_BIT 16
-+#define DDR_AHB_NO_RCACHE_ARMI_BIT 17
-+#define DDR_AHB_NO_RCACHE_COPRO_BIT 18
-+#define DDR_AHB_NO_RCACHE_DMAA_BIT 19
-+#define DDR_AHB_NO_RCACHE_DMAB_BIT 20
-+#define DDR_AHB_NO_RCACHE_PCI_BIT 21
-+#define DDR_AHB_NO_RCACHE_GMAC_BIT 22
-+#define DDR_AHB_NO_RCACHE_USB_BIT 23
-+
-+#define DDR_MON_CLIENT_BIT 0
-+#define DDR_MON_ALL_BIT 4
-+
-+#define DDR_DIAG_HOLDOFFS_BIT 20
-+#define DDR_DIAG_HOLDOFFS_NUM_BITS 12
-+#define DDR_DIAG_WRITES_BIT 10
-+#define DDR_DIAG_WRITES_NUM_BITS 10
-+#define DDR_DIAG_READS_BIT 0
-+#define DDR_DIAG_READS_NUM_BITS 10
-+
-+#define DDR_DIAG2_DIRCHANGES_BIT 0
-+#define DDR_DIAG2_DIRCHANGES_NUM_BITS 10
-+
-+#define DDR_ARB_DATDIR_NCH_BIT 0
-+#define DDR_ARB_DATDIR_EN_BIT 1
-+#define DDR_ARB_REQAGE_EN_BIT 2
-+#define DDR_ARB_LRUBANK_EN_BIT 3
-+#define DDR_ARB_MIDBUF_BIT 4
-+
-+#define DDR_AHB2_IGNORE_HPROT_BIT 0
-+#define DDR_AHB2_IGNORE_HPROT_NUM_BITS 16
-+
-+#define DDR_AHB2_IGNORE_HPROT_ARMD_BIT 0
-+#define DDR_AHB2_IGNORE_HPROT_ARMI_BIT 1
-+#define DDR_AHB2_IGNORE_HPROT_COPRO_BIT 2
-+#define DDR_AHB2_IGNORE_HPROT_DMAA_BIT 3
-+#define DDR_AHB2_IGNORE_HPROT_DMAB_BIT 4
-+#define DDR_AHB2_IGNORE_HPROT_PCI_BIT 5
-+#define DDR_AHB2_IGNORE_HPROT_GMAC_BIT 6
-+#define DDR_AHB2_IGNORE_HPROT_USB_BIT 7
-+
-+#define DDR_AHB2_IGNORE_WRAP_BIT 16
-+#define DDR_AHB2_IGNORE_WRAP_NUM_BITS 16
-+
-+#define DDR_AHB2_IGNORE_WRAP_ARMD_BIT 16
-+#define DDR_AHB2_IGNORE_WRAP_ARMI_BIT 17
-+#define DDR_AHB2_IGNORE_WRAP_COPRO_BIT 18
-+#define DDR_AHB2_IGNORE_WRAP_DMAA_BIT 19
-+#define DDR_AHB2_IGNORE_WRAP_DMAB_BIT 20
-+#define DDR_AHB2_IGNORE_WRAP_PCI_BIT 21
-+#define DDR_AHB2_IGNORE_WRAP_GMAC_BIT 22
-+#define DDR_AHB2_IGNORE_WRAP_US_BIT 23
-+
-+#define DDR_AHB3_DIS_BURST_BIT 0
-+#define DDR_AHB3_DIS_BURST_NUM_BITS 16
-+
-+#define DDR_AHB3_DIS_BURST_ARMD_BIT 0
-+#define DDR_AHB3_DIS_BURST_ARMI_BIT 1
-+#define DDR_AHB3_DIS_BURST_COPRO_BIT 2
-+#define DDR_AHB3_DIS_BURST_DMAA_BIT 3
-+#define DDR_AHB3_DIS_BURST_DMAB_BIT 4
-+#define DDR_AHB3_DIS_BURST_PCI_BIT 5
-+#define DDR_AHB3_DIS_BURST_GMAC_BIT 6
-+#define DDR_AHB3_DIS_BURST_USB_BIT 7
-+
-+#define DDR_AHB3_DIS_NONCACHE_BIT 16
-+#define DDR_AHB3_DIS_NONCACHE_NUM_BITS 16
-+
-+#define DDR_AHB3_DIS_NONCACHE_ARMD_BIT 16
-+#define DDR_AHB3_DIS_NONCACHE_ARMI_BIT 17
-+#define DDR_AHB3_DIS_NONCACHE_COPRO_BIT 18
-+#define DDR_AHB3_DIS_NONCACHE_DMAA_BIT 19
-+#define DDR_AHB3_DIS_NONCACHE_DMAB_BIT 20
-+#define DDR_AHB3_DIS_NONCACHE_PCI_BIT 21
-+#define DDR_AHB3_DIS_NONCACHE_GMAC_BIT 22
-+#define DDR_AHB3_DIS_NONCACHE_USB_BIT 23
-+
-+#define DDR_AHB4_EN_TIMEOUT_BIT 0
-+#define DDR_AHB4_EN_TIMEOUT_NUM_BITS 16
-+
-+#define DDR_AHB4_EN_TIMEOUT_ARMD_BIT 0
-+#define DDR_AHB4_EN_TIMEOUT_ARMI_BIT 1
-+#define DDR_AHB4_EN_TIMEOUT_COPRO_BIT 2
-+#define DDR_AHB4_EN_TIMEOUT_DMAA_BIT 3
-+#define DDR_AHB4_EN_TIMEOUT_DMAB_BIT 4
-+#define DDR_AHB4_EN_TIMEOUT_PCI_BIT 5
-+#define DDR_AHB4_EN_TIMEOUT_GMAC_BIT 6
-+#define DDR_AHB4_EN_TIMEOUT_USB_BIT 7
-+
-+#define DDR_AHB4_EN_WRBEHIND_BIT 16
-+#define DDR_AHB4_EN_WRBEHIND_NUM_BITS 16
-+
-+#define DDR_AHB4_EN_WRBEHIND_ARMD_BIT 16
-+#define DDR_AHB4_EN_WRBEHIND_ARMI_BIT 17
-+#define DDR_AHB4_EN_WRBEHIND_COPRO_BIT 18
-+#define DDR_AHB4_EN_WRBEHIND_DMAA_BIT 19
-+#define DDR_AHB4_EN_WRBEHIND_DMAB_BIT 20
-+#define DDR_AHB4_EN_WRBEHIND_PCI_BIT 21
-+#define DDR_AHB4_EN_WRBEHIND_GMAC_BIT 22
-+#define DDR_AHB4_EN_WRBEHIND_USB_BIT 23
-+
-+/* AHB monitor base addresses */
-+#define AHB_MON_ARM_D (AHB_MON_BASE + 0x00000)
-+#define AHB_MON_ARM_I (AHB_MON_BASE + 0x10000)
-+#define AHB_MON_DMA_A (AHB_MON_BASE + 0x20000)
-+#define AHB_MON_DMA_B (AHB_MON_BASE + 0x30000)
-+#define AHB_MON_LEON (AHB_MON_BASE + 0x40000)
-+#define AHB_MON_USB (AHB_MON_BASE + 0x50000)
-+#define AHB_MON_MAC (AHB_MON_BASE + 0x60000)
-+#define AHB_MON_PCI (AHB_MON_BASE + 0x70000)
-+
-+/* AHB write monitor registers */
-+#define AHB_MON_MODE_REG_OFFSET 0x00
-+#define AHB_MON_HWRITE_REG_OFFSET 0x04
-+#define AHB_MON_HADDR_LOW_REG_OFFSET 0x08
-+#define AHB_MON_HADDR_HIGH_REG_OFFSET 0x0C
-+#define AHB_MON_HBURST_REG_OFFSET 0x10
-+#define AHB_MON_HPROT_REG_OFFSET 0x14
-+
-+/* AHB monitor write register field definitions */
-+#define AHB_MON_MODE_MODE_BIT 0
-+#define AHB_MON_MODE_MODE_NUM_BITS 2
-+#define AHB_MON_HWRITE_COUNT_BIT 0
-+#define AHB_MON_HWRITE_COUNT_NUM_BITS 2
-+#define AHB_MON_HBURST_MASK_BIT 0
-+#define AHB_MON_HBURST_MASK_NUM_BITS 3
-+#define AHB_MON_HBURST_MATCH_BIT 4
-+#define AHB_MON_HBURST_MATCH_NUM_BITS 3
-+#define AHB_MON_HPROT_MASK_BIT 0
-+#define AHB_MON_HPROT_MASK_NUM_BITS 4
-+#define AHB_MON_HPROT_MATCH_BIT 4
-+#define AHB_MON_HPROT_MATCH_NUM_BITS 4
-+
-+#ifndef __ASSEMBLY__
-+typedef enum AHB_MON_MODES {
-+ AHB_MON_MODE_IDLE,
-+ AHB_MON_MODE_ACTIVE,
-+ AHB_MON_MODE_RESET
-+} AHB_MON_MODES_T;
-+
-+typedef enum AHB_MON_HWRITE {
-+ AHB_MON_HWRITE_INACTIVE,
-+ AHB_MON_HWRITE_WRITES,
-+ AHB_MON_HWRITE_READS,
-+ AHB_MON_HWRITE_READS_AND_WRITES
-+} AHB_MON_HWRITE_T;
-+
-+typedef enum AHB_MON_HBURST {
-+ AHB_MON_HBURST_SINGLE,
-+ AHB_MON_HBURST_INCR,
-+ AHB_MON_HBURST_WRAP4,
-+ AHB_MON_HBURST_INCR4,
-+ AHB_MON_HBURST_WRAP8,
-+ AHB_MON_HBURST_INCR8,
-+ AHB_MON_HBURST_WRAP16,
-+ AHB_MON_HBURST_INCR16
-+} AHB_MON_HBURST_T;
-+#endif // __ASSEMBLY__
-+
-+/* AHB read monitor registers */
-+#define AHB_MON_CYCLES_REG_OFFSET 0x00
-+#define AHB_MON_TRANSFERS_REG_OFFSET 0x04
-+#define AHB_MON_WAITS_REG_OFFSET 0x08
-+
-+#define STATIC_BUS1_CONTROL_VALUE 0x04010484 /* 200nS rd/wr cycles to allow DMAing to SMC91x on static bus */
-+
-+/* PCI bus definitions */
-+#define pcibios_assign_all_busses() 1
-+#define PCIBIOS_MIN_IO 0x1000 /* used for memory alignememnt guesstimate */
-+#define PCIBIOS_MIN_MEM 0x00100000 /* used for memory alignememnt guesstimate */
-+
-+/* PCI bus commands - see pci spec */
-+#define PCI_BUS_CMD_INTERRUPT_ACKNOWLEDGE 0x00
-+#define PCI_BUS_CMD_SPECIAL_CYCLE 0x01
-+#define PCI_BUS_CMD_IO_READ 0x02
-+#define PCI_BUS_CMD_IO_WRITE 0x03
-+/*#define PCI_BUS_RESERVED 0x04 */
-+/*#define PCI_BUS_RESERVED 0x05 */
-+#define PCI_BUS_CMD_MEMORY_READ 0x06
-+#define PCI_BUS_CMD_MEMORY_WRITE 0x07
-+/*#define PCI_BUS_RESERVED 0x08 */
-+/*#define PCI_BUS_RESERVED 0x09 */
-+#define PCI_BUS_CMD_CONFIGURATION_READ 0x0a
-+#define PCI_BUS_CMD_CONFIGURATION_WRITE 0x0b
-+#define PCI_BUS_CMD_MEMORY_READ_MULTIPLE 0x0c
-+#define PCI_BUS_CMD_DUAL_ADDRESS_CYCLE 0x0d
-+#define PCI_BUS_CMD_MEMORY_READ_LINE 0x0e
-+#define PCI_BUS_CMD_MEMORY_WRITE_AND_INVALIDATE 0x0f
-+
-+/* synopsis PCI core register set */
-+#define PCI_CORE_REG_START PCI_CSRS_BASE
-+#define PCI_CRP_CMD_AND_ADDR PCI_CORE_REG_START
-+#define PCI_CRP_WRITE_DATA (PCI_CRP_CMD_AND_ADDR + 4)
-+#define PCI_CRP_READ_DATA (PCI_CRP_WRITE_DATA + 4)
-+#define PCI_CONFIG_IO_CYCLE_ADDR (PCI_CRP_READ_DATA + 4)
-+#define PCI_CONFIG_IO_BYTE_CMD (PCI_CONFIG_IO_CYCLE_ADDR + 4)
-+#define PCI_CONFIG_IO_WRITE_DATA (PCI_CONFIG_IO_BYTE_CMD + 4)
-+#define PCI_CONFIG_IO_READ_DATA (PCI_CONFIG_IO_WRITE_DATA + 4)
-+#define PCI_ERROR_MSG (PCI_CONFIG_IO_READ_DATA + 4)
-+#define PCI_TRANS_ERROR_START_ADDR (PCI_ERROR_MSG + 4)
-+#define PCI_AHB_ERROR_LSB (PCI_TRANS_ERROR_START_ADDR + 4)
-+#define PCI_AHB_ERROR_START_ADDR (PCI_AHB_ERROR_LSB + 4)
-+#define PCI_FLUSH_FIFO_ON_ERR (PCI_AHB_ERROR_START_ADDR + 4)
-+#define PCI_TAR_ID (PCI_FLUSH_FIFO_ON_ERR + 4)
-+#define PCI_MAS_ID_IN (PCI_TAR_ID + 4)
-+#define PCI_CORE_REG_END (PCI_MAS_ID_IN + 4)
-+
-+/* register bit offsets */
-+#define PCI_CRP_ADDRESS_START 0
-+#define PCI_CRP_ADDRESS_END 10
-+#define PCI_CRP_CMD_START 16
-+#define PCI_CRP_CMD_END 19
-+#define PCI_CRP_BYTE_ENABLES_START 20
-+#define PCI_CRP_BYTE_ENABLES_END 23
-+
-+#define PCI_CONFIG_IO_CMD_START 0
-+#define PCI_CONFIG_IO_CMD_END 3
-+#define PCI_CONFIG_IO_BYTE_ENABLES_START 4
-+#define PCI_CONFIG_IO_BYTE_ENABLES_END 7
-+
-+#define PCI_ERR_MESSAGE_START 0
-+#define PCI_ERR_MESSAGE_END 1
-+
-+#define PCI_AHB_ERR_BIT 0
-+
-+#define PCI_FLUSH_FIFO_ON_ERR_BIT 0
-+
-+#define PCI_TAR_ID_START 0
-+#define PCI_TAR_ID_END 2
-+
-+#define PCI_MAS_ID_IN_START 0
-+#define PCI_MAS_ID_IN_END 2
-+
-+/* PWM register definitions */
-+#define PWM_DATA_REGISTER_BASE (PWM_BASE)
-+#define PWM_CLOCK_REGISTER (PWM_BASE+0X400)
-+
-+#endif // __ASM_ARCH_HARDWARE_H
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/i2s.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/i2s.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/i2s.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/i2s.h 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,1023 @@
-+/*
-+ * linux/include/asm-arm/arch-oxnas/i2s.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.
-+ */
-+
-+#ifndef __ASM_ARM_ARCH_I2S_H
-+#define __ASM_ARM_ARCH_I2S_H
-+
-+#include "hardware.h"
-+
-+/* Routines ----------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+
-+extern void DumpI2SRegisters(void);
-+
-+
-+
-+/* Registers ---------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+
-+
-+#define TX_CONTROL (0x0000 + I2S_BASE)
-+#define TX_SETUP (0x0004 + I2S_BASE)
-+#define TX_SETUP1 (0x0008 + I2S_BASE)
-+#define TX_STATUS (0x000C + I2S_BASE)
-+#define RX_CONTROL (0x0010 + I2S_BASE)
-+#define RX_SETUP (0x0014 + I2S_BASE)
-+#define RX_SETUP1 (0x0018 + I2S_BASE)
-+#define RX_STATUS (0x001C + I2S_BASE)
-+#define TX_DEBUG (0x0020 + I2S_BASE)
-+#define TX_DEBUG2 (0x0024 + I2S_BASE)
-+#define TX_DEBUG3 (0x0028 + I2S_BASE)
-+#define RX_DEBUG_ (0x0030 + I2S_BASE)
-+#define RX_DEBUG2 (0x0034 + I2S_BASE)
-+#define RX_DEBUG3 (0x0038 + I2S_BASE)
-+#define TX_BUFFER_LEVEL (0x0040 + I2S_BASE)
-+#define TX_BUFFER_INTERRUPT_LEVEL (0x0048 + I2S_BASE)
-+#define RX_BUFFER_LEVEL (0x0050 + I2S_BASE)
-+#define RX_BUFFER_INTERRUPT_LEVEL (0x0058 + I2S_BASE)
-+#define RX_SPDIF_DEBUG (0x0070 + I2S_BASE)
-+#define RX_SPDIF_DEBUG2 (0x0074 + I2S_BASE)
-+#define INTERRUPT_CONTROL_STATUS (0x0080 + I2S_BASE)
-+#define INTERRUPT_MASK (0x0084 + I2S_BASE)
-+#define VERSION (0x008C + I2S_BASE)
-+#define TX_DATA_IN_FORMAT (0x0100 + I2S_BASE)
-+#define TX_CHANNELS_ENABLE (0x0104 + I2S_BASE)
-+#define TX_WRITES_TO (0x0108 + I2S_BASE)
-+#define RX_DATA_OUT_FORMAT (0x0200 + I2S_BASE)
-+#define RX_CHANNELS_ENABLE (0x0204 + I2S_BASE)
-+#define RX_READS_FROM (0x0208 + I2S_BASE)
-+#define TX_CPU_DATA_WRITES_ALT (0x04FF + I2S_BASE)
-+#define RX_CPU_DATA_READS_ALT (0x08FF + I2S_BASE)
-+#define TX_CPU_DATA_WRITES (0x1FFF + I2S_BASE)
-+#define RX_CPU_DATA_READS (0x2FFF + I2S_BASE)
-+
-+
-+
-+/* TX_CONTROL ------------ */
-+#define TX_CONTROL_ENABLE 0
-+ /**
-+ * 0 - Audio transmit is disabled
-+ * 1 - Audio transmit is enabled.
-+ */
-+#define TX_CONTROL_FLUSH 1
-+ /**
-+ * 0 - Normal Operation
-+ * 1 - Flush TX buffer
-+ */
-+#define TX_CONTROL_MUTE 2
-+ /**
-+ * 0 - Normal Operation
-+ * 1 - Muted operation
-+ */
-+#define TX_CONTROL_TRICK 3
-+ /**
-+ * (UNTESTED FEATURE)
-+ * 0 - Trickplay features disabled
-+ * 1 - Trickplay features enabled
-+ */
-+#define TX_CONTROL_SPEED 4
-+ /**
-+ * (UNTESTED FEATURE)
-+ * 00 - Quarter speed playback - DOESN\92T WORK
-+ * 01 - Half speed playback - DOESN\92T WORK
-+ * 10 - Double speed playback
-+ * 11 - Quadruple speed playback.
-+ */
-+ #define QUARTER_SPEED_PLAYBACK 0x00
-+ #define HALF_SPEED_PLAYBACK 0x01
-+ #define DOUBLE_SPEED_PLAYBACK 0x02
-+ #define QUADRUPLE_SPEED_PLAYBACK 0x03
-+#define TX_CONTROL_ABORT_DMA 6
-+ /**
-+ * Write a 1 to abort any outstanding DMAs (self-clearing)
-+ */
-+#define TX_CONTROL_AHB_ENABLE 8
-+ /**
-+ * 0 - AHB disabled (APB only)
-+ * 1 - AHB enabled (APB disabled for data plane)
-+ */
-+#define TX_CONTROL_QUAD_BURSTS 9
-+ /**
-+ * 0 - DMA transfers up to Single Quads
-+ * 1 - DMA transfers up to Bursts of 4 Quads
-+ */
-+
-+
-+/* TX_SETUP ------------ */
-+/**
-+ * In order for the changes made to the fields in bold to propagate to the Tx
-+ * audio clock domain, a write must be performed to TX_SETUP1 And the TX_CLK
-+ * must be running.
-+ */
-+
-+#define TX_SETUP_FORMAT 0
-+ /**
-+ * 00 - True/Early-I2S (standard format)
-+ * 01 - Late-I2S
-+ * 10 - MP3 Valid
-+ * 11 - MP3 Start
-+ */
-+ #define TRUE_I2S 0x00
-+ #define LATE_I2S 0x01
-+ #define MP3_VALID 0x02
-+ #define MP3_START 0x03
-+#define TX_SETUP_MODE 2
-+ /**
-+ * 0 - Slave
-+ * 1 - Master
-+ */
-+ #define I2S_SLAVE 0x00
-+ #define I2S_MASTER 0x01
-+#define TX_SETUP_FLOW_INVERT 3
-+ /**
-+ * 0 - Flow Control is active high
-+ * (ie. Audio core is held off when TX_FLOW_CONTROL=\921\92)
-+ * 1 - Flow Control is active low
-+ * (ie. Audio core is held off when TX_FLOW_CONTROL=\920\92)
-+ */
-+ #define FLOW_CONTROL_ACTIVE_HIGH 0
-+ #define FLOW_CONTROL_ACTIVE_LOW 1
-+#define TX_SETUP_POS_EDGE 4
-+ /**
-+ * 0 - Data is output on the negative edge of the TX Audio clock
-+ * 1 - Data is output on the positive edge of the TX Audio clock
-+ */
-+#define TX_SETUP_CLOCK_STOP 5
-+ /**
-+ * 0 - Audio TX clock should not be stopped during flow control hold off
-+ * 1 - Audio TX clock should be stopped during flow control hold off
-+ */
-+#define TX_SETUP_SPLIT_QUAD 6
-+ /**
-+ * 0 - No splitting
-+ * 1 - Split quadlet into two 16 bit samples - NOT VALID FOR S/PDIF
-+ */
-+#define TX_SETUP_INSPECT_WORD_CLOCK 7
-+ /**
-+ * Used when recovering from underrun. This bit is set to look for either
-+ * a high or low word clock before the hardware carries on as normal.
-+ */
-+#define TX_SETUP_SPDIF_EN 8
-+ /**
-+ * 0 - No SPDIF on Channel 0 (disables biphase coding on output)
-+ * 1 - SPDIF on Channel 0 (enables the biphase coding even when Tx disabled)
-+ */
-+
-+
-+/* TX_SETUP1 ------------ */
-+#define TX_SETUP1_INPUT 0
-+ /**
-+ * 00 - Twos Compliment (pass-thru)
-+ * 01 - Offset Binary
-+ * 10 - Sign Magnitude
-+ * 11 - Reserved
-+ */
-+ #define TWOS_COMPLIMENT 0x00
-+ #define OFFSET_BINARY 0x01
-+ #define SIGN_MAGNITUDE 0x02
-+ #define RESERVED 0x03
-+#define TX_SETUP1_REVERSE 2
-+ /**
-+ * 0 - Normal operation
-+ * 1 - Reverse Stereo - DOES NOT WORK FOR NON- SPLIT_QUAD/MP3
-+ */
-+#define TX_SETUP1_INVERT 3
-+ /**
-+ * 0 - Normal operation
-+ * 1 - Inverted word clock
-+ */
-+#define TX_SETUP1_BIG_ENDIAN 4
-+ /**
-+ * 0 - System data is in little endian format
-+ * 1 - System data is in big endian format
-+ */
-+#define TX_SETUP1_QUAD_ENDIAN 5
-+ /**
-+ * 0 - System data is 16 bit.
-+ * 1 - System data is 32 bit
-+ */
-+#define TX_SETUP1_QUAD_SAMPLES 6
-+ /**
-+ * 0 - I2S Master word clock uses 16 bit samples - NOT VALID FOR S/PDIF
-+ * 1 - I2S Master word clock uses 32 bit samples
-+ */
-+#define TX_SETUP1_FLOW_CONTROL 7
-+ /**
-+ * 0 - No flow control (MP3 only)
-+ * 1 - Flow control (MP3 only)
-+ */
-+
-+/* TX_STATUS ------------ */
-+#define TX_STATUS_UNDERRUN 0
-+ /**
-+ * 0 - Underrun has not occurred.
-+ * 1 - Underrun has occurred. (Note that this bit must be written to with
-+ * a \911\92 to clear)
-+ */
-+#define TX_STATUS_OVERRUN 1
-+ /**
-+ * 0 - Overrun has not occurred.
-+ * 1 - Overrun has occurred. (Note that this bit must be written to with
-+ * a \911\92 to clear)
-+ */
-+#define TX_STATUS_FIFO_UNDERRUN 2
-+
-+ /**
-+ * 0 - FIFO Underrun has not occurred.
-+ * 1 - FIFO Underrun has occurred. (Note that this bit must be written to
-+ * with a \911\92 to clear)
-+ */
-+#define TX_STATUS_FIFO_OVERRUN 3
-+ /**
-+ * 0 - FIFO Overrun has not occurred.
-+ * 1 - FIFO Overrun has occurred. (Note that this bit must be written to
-+ * with a \911\92 to clear)
-+ */
-+#define TX_STATUS_HW_READ 8
-+ /**
-+ * 0 - H/W Read of FIFO has not occurred.
-+ * 1 - H/W Read of FIFO has occurred. (Note that this bit must be written
-+ * to with a \911\92 to clear)
-+ */
-+#define TX_STATUS_BUFFER_LEVEL_MET 9
-+ /**
-+ * 0 - Fill level of FIFO does not match BUFFER_INTERRUPT_LEVEL.
-+ * 1 - Fill level of FIFO matches BUFFER_INTERRUPT_LEVEL
-+ */
-+
-+
-+/* RX_CONTROL ------------ */
-+#define RX_CONTROL_ENABLE 0
-+ /**
-+ * 0 - Audio receive is disabled
-+ * 1 - Audio receive is enabled.
-+ */
-+#define RX_CONTROL_FLUSH 1
-+ /**
-+ * 0 - Normal Operation
-+ * 1 - Flush RX buffer
-+ */
-+#define RX_CONTROL_MUTE 2
-+ /**
-+ * 0 - Normal Operation
-+ * 1 - Muted operation
-+ */
-+#define RX_CONTROL_TRICK 3
-+ /**
-+ * (UNTESTED FEATURE)
-+ * 0 - Trickplay features disabled
-+ * 1 - Trickplay features enabled
-+ */
-+#define RX_CONTROL_SPEED 4
-+ /**
-+ * (UNTESTED FEATURE)
-+ * 00 - Quarter speed playback - DOESN\92T WORK
-+ * 01 - Half speed playback - DOESN\92T WORK
-+ * 10 - Double speed playback
-+ * 11 - Quadruple speed playback.
-+ */
-+#define RX_CONTROL_ABORT_DMA 6
-+ /**
-+ * Write a 1 to abort any outstanding DMAs (self-clearing)
-+ */
-+#define RX_CONTROL_AHB_ENABLE 8
-+ /**
-+ * 0 - AHB disabled (APB only)
-+ * 1 - AHB enabled (APB disabled for data plane)
-+ */
-+#define RX_CONTROL_QUAD_BURSTS 9
-+ /**
-+ * 0 - DMA transfers up to Single Quads
-+ * 1 - DMA transfers up to Bursts of 4 Quads
-+ */
-+
-+
-+/* RX_SETUP ------------ */
-+/**
-+ * In order for the changes made to the fields in bold to propagate to the Rx
-+ * audio clock domain, a write must be performed to RX_SETUP1 And the RX_CLK
-+ * must be running.
-+ */
-+
-+#define RX_SETUP_FORMAT 0
-+ /**
-+ * 00 - True/Early-I2S (standard format)
-+ * 01 - Late-I2S
-+ * 10 - MP3 Valid
-+ * 11 - MP3 Start
-+ */
-+#define RX_SETUP_MODE 2
-+ /**
-+ * 0 - Slave
-+ * 1 - Master - NOT VALID FOR S/PDIF
-+ */
-+#define RX_SETUP_POS_EDGE 4
-+ /**
-+ * 0 - Data is output on the negative edge of the RX Audio clock
-+ * 1 - Data is output on the positive edge of the RX Audio clock
-+ */
-+#define RX_SETUP_COMBINE_QUAD 6
-+ /**
-+ * 0 - No combining
-+ * 1 - Combine two 16 bit samples into single quadlet - NOT VALID FOR S/PDIF
-+ */
-+#define RX_SETUP_INSPECT_WORD_CLOCK 7
-+ /**
-+ * Used when recovering from overrun. This bit is set to look for either
-+ * a high or low word clock before the hardware carries on as normal.
-+ */
-+#define RX_SETUP_SPDIF_EN 8
-+ /**
-+ * 0 - No SPDIF on Channel 0 (disables biphase decoding and clk recovery on input)
-+ * 1 - SPDIF on Channel 0 (enables the biphase decoding and clk recovery even when Rx disabled)
-+ */
-+#define RX_SETUP_SPDIF_DEBUG_EN 9
-+ /**
-+ * Provides direct control over RX_SPDIF_OE Output signal
-+ */
-+
-+
-+/* RX_SETUP1 ------------ */
-+#define RX_SETUP1_INPUT 0
-+ /**
-+ * 00 - Twos Compliment (pass-thru)
-+ * 01 - Offset Binary
-+ * 10 - Sign Magnitude
-+ * 11 - Reserved
-+ */
-+#define RX_SETUP1_REVERSE 2
-+ /**
-+ * 0 - Normal operation
-+ * 1 - Reverse Stereo - DOES NOT WORK FOR NON- SPLIT_QUAD/MP3
-+ */
-+#define RX_SETUP1_INVERT 3
-+ /**
-+ * 0 - Normal operation
-+ * 1 - Inverted word clock
-+ */
-+#define RX_SETUP1_BIG_ENDIAN 4
-+ /**
-+ * 0 - System data is in little endian format
-+ * 1 - System data is in big endian format
-+ */
-+#define RX_SETUP1_QUAD_ENDIAN 5
-+ /**
-+ * 0 - System data is 16 bit.
-+ * 1 - System data is 32 bit
-+ */
-+#define RX_SETUP1_QUAD_SAMPLES 6
-+ /**
-+ * 0 - I2S Master word clock uses 16 bit samples - NOT VALID FOR S/PDIF
-+ * 1 - I2S Master word clock uses 32 bit samples
-+ */
-+
-+
-+/* RX_STATUS ------------ */
-+#define RX_STATUS_UNDERRUN 0
-+ /**
-+ * 0 - Underrun has not occurred.
-+ * 1 - Underrun has occurred. (Note that this bit must be written to with
-+ * a \911\92 to clear)
-+ */
-+#define RX_STATUS_OVERRUN 1
-+ /**
-+ * 0 - Overrun has not occurred.
-+ * 1 - Overrun has occurred. (Note that this bit must be written to with
-+ * a \911\92 to clear)
-+ */
-+#define RX_STATUS_FIFO_UNDERRUN 2
-+ /**
-+ * 0 - FIFO Underrun has not occurred.
-+ * 1 - FIFO Underrun has occurred. (Note that this bit must be written to
-+ * with a \911\92 to clear)
-+ */
-+#define RX_STATUS_FIFO_OVERRUN 3
-+ /**
-+ * 0 - FIFO Overrun has not occurred.
-+ * 1 - FIFO Overrun has occurred. (Note that this bit must be written to
-+ * with a \911\92 to clear)
-+ */
-+#define RX_STATUS_SPDIF_PARITY_ERROR 4
-+ /**
-+ * 0 - Rx S/PDIF Parity Error has not occurred.
-+ * 1 - Rx S/PDIF Parity Error has occurred. (Note that this bit must be
-+ * written to with a \911\92 to clear)
-+ */
-+#define RX_STATUS_SPDIF_PREAMBLE_ERROR 5
-+ /**
-+ * 0 - Rx S/PDIF Preamble Error has not occurred.
-+ * 1 - Rx S/PDIF Preamble Error has occurred. (Note that this bit must be
-+ * written to with a \911\92 to clear)
-+ */
-+#define RX_STATUS_SPDIF_FRAMING_ERROR 6
-+ /**
-+ * 0 - Rx S/PDIF Framing Error has not occurred.
-+ * 1 - Rx S/PDIF Framing Error has occurred. (Note that this bit must be
-+ * written to with a \911\92 to clear)
-+ */
-+#define RX_STATUS_SPDIF_LOCK_EVENT 7
-+ /**
-+ * 0 - Rx S/PDIF Lock status has not changed.
-+ * 1 - Rx S/PDIF Lock status has changed. (Note that this bit must be
-+ * written to with a \911\92 to clear)
-+ */
-+#define RX_STATUS_HW_WRITE 8
-+ /**
-+ * 0 - H/W Write of FIFO has not occurred.
-+ * 1 - H/W Write of FIFO has occurred. (Note that this bit must be written
-+ * to with a \911\92 to clear)
-+ */
-+#define RX_STATUS_BUFFER_LEVEL_MET 9
-+ /**
-+ * 0 - Fill level of FIFO does not match BUFFER_INTERRUPT_LEVEL.
-+ * 1 - Fill level of FIFO matches BUFFER_INTERRUPT_LEVEL
-+ */
-+#define RX_STATUS_SPDIF_LOCK 10
-+ /**
-+ * 0 - Rx S/PDIF timing is not locked.
-+ * 1 - Rx S/PDIF timing is locked.
-+ */
-+
-+
-+/* TX_DEBUG ------------ */
-+#define TX_DEBUG_TX_DMA_STATE 0
-+ /**
-+ * 00 - START
-+ * 01 - IDLE
-+ * 10 - BURST
-+ * 11 - NON_ALIGNED
-+ */
-+#define TX_DEBUG_WRITE_OFFSET 4
-+ /**
-+ * Write Offset Determines the alignment of the writes
-+ * (0=quad aligned; 1/3=bytes aligned; 2 doublet aligned)
-+ */
-+#define TX_DEBUG_TX_DREQ 31
-+ /**
-+ * Set if DMA request for Tx is set
-+ */
-+
-+
-+/* TX_DEBUG2 ------------ */
-+#define TX_DEBUG2_TX_CTRL_STATE 0
-+ /**
-+ * 000 - WAITING
-+ * 001 - WAITING_HALF
-+ * 010 - Invalid
-+ * 011 - WAIT_LEFT
-+ * 100 - READ_FIFO
-+ * 101 - WAIT_TILL_DATA_TAKEN
-+ * 11x - Invalid
-+ */
-+#define TX_DEBUG2_FIFO_READER_2ND_STAGE 3
-+ /**
-+ * 0 - First stage (L) of FIFO read
-+ * 1 - Second stage (R) of FIFO read
-+ */
-+#define TX_DEBUG2_FIFO_READER_CHANNEL 4
-+ /**
-+ * Current channel being read from FIFO
-+ */
-+#define TX_DEBUG2_NUM_WRITES 8
-+ /**
-+ * Number of writes to be performed every interrupt
-+ */
-+#define TX_DEBUG2_SAFE_TO_UPDATE_REGS 12
-+ /**
-+ * 0 - Changes to registers will be deferred
-+ * 1 - Changes to registers will be immediate
-+ */
-+#define TX_DEBUG2_WR_DMARQ 13
-+ /**
-+ * 0 - No writes being requested
-+ * 1 - Writes being requested (=DMA DREQ when using APB)
-+ */
-+#define TX_DEBUG2_FIFO_READ_ADDRESS 16
-+ /**
-+ * 19 - 16 Current read pointer of FIFO
-+ */
-+#define TX_DEBUG2_FIFO_WRITE_ADDRESS 24
-+ /**
-+ * 27 - 24 Current write pointer of FIFO
-+ */
-+#define TX_DEBUG2_WORD_CLK 31
-+ /**
-+ * State of internal safe TX_WORD_CLK
-+ */
-+
-+
-+/* TX_DEBUG3 ------------ */
-+/**
-+ * This register is a read back of status directly from the TX_CLK domain.
-+ * For this reason it may be unstable during operation. Several back-to-back
-+ * reads might need to be made to get an accurate reflection of the status
-+ * during operation.
-+ */
-+
-+#define TX_DEBUG3_TX_STATE 0
-+ /**
-+ * 000 - DISABLED
-+ * 001 - WAITING
-+ * 010 - WAIT_FOR_8
-+ * 011 - SAMPLE_8
-+ * 100 - WAIT_FOR_LEFT
-+ * 101 - SAMPLE_LEFT
-+ * 110 - WAIT_FOR_RIGHT
-+ * 111 - SAMPLE_RIGHT
-+ */
-+#define TX_DEBUG3_TX_IN_RESET 31
-+ /**
-+ * 0 - Tx domain is out of reset
-+ * 1 - Tx domain is in reset
-+ */
-+
-+
-+
-+/* RX_DEBUG ------------ */
-+#define RX_DEBUG_RX_DMA_STATE 0
-+ /**
-+ * 00 - START
-+ * 01 - IDLE
-+ * 10 - BURST
-+ * 11 - NON_ALIGNED
-+ */
-+#define RX_DEBUG_READ_OFFSET 4
-+ /**
-+ * 5 - 4 Determines the alignment of the reads
-+ * (0=quad aligned; 1/3=bytes aligned; 2 doublet aligned)
-+ */
-+#define RX_DEBUG_RX_DREQ 31
-+ /**
-+ * Set if DMA request for Rx is set
-+ */
-+
-+
-+/* RX_DEBUG2 ------------ */
-+#define RX_DEBUG2_RX_CTRL_STATE 0
-+ /**
-+ * 000 - WAITING
-+ * 001 - WAITING_HALF
-+ * 01x - Invalid
-+ * 100 - WRITE_FIFO
-+ * 101 - WAIT_TILL_DATA_PUT
-+ * 11x - Invalid
-+ */
-+#define RX_DEBUG2_FIFO_WRITER_2ND_STAGE 3
-+ /**
-+ * 0 - First stage (L) of FIFO write
-+ * 1 - Second stage (R) of FIFO write
-+ */
-+#define RX_DEBUG2_FIFO_WRITER_CHANNEL 4
-+ /**
-+ * 7 - 4 Current channel being written to FIFO
-+ */
-+#define RX_DEBUG2_NUM_READS 8
-+ /**
-+ * 11 - 8 Number of reads to be performed every interrupt
-+ */
-+#define RX_DEBUG2_SAFE_TO_UPDATE_REGS 12
-+ /**
-+ * 0 - Changes to registers will be deferred
-+ * 1 - Changes to registers will be immediate
-+ */
-+#define RX_DEBUG2_RD_DMARQ 13
-+ /**
-+ * 0 - No reads being requested
-+ * 1 - Reads being requested (=DMA DREQ when using APB)
-+ */
-+#define RX_DEBUG2_FIFO_READ_ADDRESS 16
-+ /**
-+ * 19 - 16 Current read pointer of FIFO
-+ */
-+#define RX_DEBUG2_FIFO_WRITE_ADDRESS 24
-+ /**
-+ * 27 - 24 Current write pointer of FIFO
-+ */
-+#define RX_DEBUG2_WORD_CLK 31
-+ /**
-+ * State of internal safe RX_WORD_CLK
-+ */
-+
-+
-+/* RX_DEBUG3 ------------ */
-+/**
-+ * This register is a read back of status directly from the RX_CLK domain.
-+ * For this reason it may be unstable during operation. Several back-to-back
-+ * reads might need to be made to get an accurate reflection of the status
-+ * during operation.
-+ */
-+
-+#define RX_DEBUG3_RX_STATE 0
-+ /**
-+ * 000 - DISABLED
-+ * 001 - WAITING
-+ * 010 - WAIT_FOR_8
-+ * 011 - SAMPLE_8
-+ * 100 - WAIT_FOR_LEFT
-+ * 101 - SAMPLE_LEFT
-+ * 110 - WAIT_FOR_RIGHT
-+ * 111 - SAMPLE_RIGHT
-+ */
-+#define RX_DEBUG3_RX_IN_RESET 31
-+ /**
-+ * 0 - Rx domain is out of reset
-+ * 1 - Rx domain is in reset
-+ */
-+
-+
-+/**
-+ * VERSION* ------------
-+ * Refer to VERSION. ??
-+ */
-+
-+
-+/* TX_BUFFER_LEVEL ------------ */
-+/**
-+ * When this register is read it returns the current fill level of the buffer
-+ * within the audio core, when a \911\92 is written to the lower bit, the buffer
-+ * fill level, read and write pointers are all set to zero.
-+ * FT - 0 Buffer Level Fill level of Tx buffer
-+ */
-+
-+/**
-+ * INTERRUPT_CONTROL* ------------
-+ * Refer to INTERRUPT_CONTROL_STATUS. ??
-+ */
-+
-+/* TX_BUFFER_INTERRUPT_LEVEL ------------ */
-+/**
-+ * FT - 0 Interrupt Level Programmable Buffer Level to initiate Interrupt
-+ */
-+
-+
-+/* RX_BUFFER_LEVEL ------------ */
-+/**
-+ * When this register is read it returns the current fill level of the buffer
-+ * within the audio core, when a \911\92 is written to the lower bit, the buffer
-+ * fill level, read and write pointers are all set to zero.
-+ * FR - 0 Buffer Level Fill level of Rx buffer
-+ */
-+
-+
-+/* RX_BUFFER_INTERRUPT_LEVEL ------------ */
-+/**
-+ * FR - 0 Interrupt Level Programmable Buffer Level to initiate Interrupt
-+ */
-+
-+
-+/* RX_SPDIF_DEBUG ------------ */
-+#define RX_SPDIF_DEBUG_MAX_PULSE 0
-+ /**
-+ * 7 - 0 Number of cycles of RX_SPDIF_OSAMP_CLK in maximum pulse width
-+ * detected (=1.5x BIT_CLK)
-+ */
-+#define RX_SPDIF_DEBUG_MIN_PULSE 8
-+ /**
-+ * 15 - 8 Number of cycles of RX_SPDIF_OSAMP_CLK in minimum pulse width
-+ * detected (=0.5x BIT_CLK)
-+ */
-+#define RX_SPDIF_DEBUG_VALID 16
-+ /**
-+ * 0 - Min Pulse is not valid (<2) for doing recovery
-+ * 1 - Min Pulse is valid (?2) and recovery is possible
-+ */
-+#define RX_SPDIF_DEBUG_LOCK 17
-+ /**
-+ * 0 - Rx S/PDIF timing is not locked.
-+ * 1 - Rx S/PDIF timing is locked.
-+ */
-+#define RX_SPDIF_DEBUG_NO_PULSE 18
-+ /**
-+ * 0 - Pulse detected
-+ * 1 - Pulse detection has timed out
-+ */
-+#define RX_SPDIF_DEBUG_BLOCK_START 20
-+ /**
-+ * 0 - Current frame is not at start of block
-+ * 1 - Current frame is at start of block
-+ */
-+#define RX_SPDIF_DEBUG_CHAN_A 21
-+ /**
-+ * 0 - Current subframe is B
-+ * 1 - Current subframe is A
-+ */
-+
-+
-+/* RX_SPDIF_DEBUG2 ------------ */
-+#define RX_SPDIF_DEBUG2_FRAME 0
-+ /**
-+ * 7 - 0 Current frame counter (0 to 191)
-+ */
-+#define RX_SPDIF_DEBUG2_BLOCK_SYNC 8
-+ /**
-+ * 0 - Not yet achieved block sync
-+ * 1 - Block sync has been achieved (i.e. received a start of block)
-+ */
-+
-+
-+/* INTERRUPT_CONTROL_STATUS ------------ */
-+#define INTERRUPT_CONTROL_STATUS_AUDIO_IRQ 0
-+ /**
-+ * ** BACKWARDS COMPATIBLE, DO NOT USE
-+ * Set if the Audio Core Interrupt is set. Write \910\92 to clear
-+ */
-+#define INTERRUPT_CONTROL_STATUS_AUTO_CLEAR 2
-+ /**
-+ * 0 - Auto Clear disabled
-+ * 1 - Auto clear of H/W read/write interrupt on next data write/read (Tx/Rx)
-+ */
-+#define INTERRUPT_CONTROL_STATUS_TX_IRQ 8
-+ /**
-+ * Set if the Audio Core Tx Interrupt is set
-+ * Set to \911\92 to trigger a Normal Interrupt (TX_READ/RX_WRITE IRQ Enable
-+ * must be set)
-+ */
-+#define INTERRUPT_CONTROL_STATUS_TX_ERR_IRQ 9
-+ /**
-+ * Set if the Audio Core Tx Error Interrupt is set
-+ * Set to \911\92 to trigger an Error Interrupt (TX_URUN/RX_ORUN IRQ Enable
-+ * must be set)
-+ */
-+#define INTERRUPT_CONTROL_STATUS_RX_IRQ 16
-+ /**
-+ * Set if the Audio Core Rx Interrupt is set
-+ * Set to \911\92 to trigger a Normal Interrupt (RX_WRITE/TX_READ IRQ Enable
-+ * must be set)
-+ */
-+#define INTERRUPT_CONTROL_STATUS_RX_ERR_IRQ 17
-+ /**
-+ * Set if the Audio Core Rx Error Interrupt is set
-+ * Set to \911\92 to trigger an Error Interrupt (RX_ORUN/TX_URUN IRQ Enable must
-+ * be set)
-+ */
-+
-+
-+/* INTERRUPT_MASK ------------ */
-+#define INTERRUPT_MASK_TX_READ_IRQ_ENABLE 0
-+ /**
-+ * 0 - No Normal Interrupt generated by TX_READ
-+ * 1 - Normal Interrupt generated by TX_READ
-+ */
-+#define INTERRUPT_MASK_TX_LEVEL_IRQ_ENABLE 1
-+ /**
-+ * 0 - No Normal Interrupt generated by TX_BUFFER_LEVEL
-+ * 1 - Normal Interrupt generated by TX_BUFFER_LEVEL
-+ */
-+#define INTERRUPT_MASK_TX_ERROR_IRQ_ENABLE 2
-+ /**
-+ * 0 - No Normal Interrupt generated by TX_ERROR
-+ * 1 - Normal Interrupt generated by TX_ERROR
-+ */
-+#define INTERRUPT_MASK_RX_WRITE_IRQ_ENABLE 8
-+ /**
-+ * 0 - No Normal Interrupt generated by RX_WRITE
-+ * 1 - Normal Interrupt generated by RX_WRITE
-+ */
-+#define INTERRUPT_MASK_RX_LEVEL_IRQ_ENABLE 9
-+ /**
-+ * 0 - No Normal Interrupt generated by RX_BUFFER_LEVEL
-+ * 1 - Normal Interrupt generated by RX_BUFFER_LEVEL
-+ */
-+#define INTERRUPT_MASK_RX_ERROR_IRQ_ENABLE 10
-+ /**
-+ * 0 - No Normal Interrupt generated by RX_ERROR
-+ * 1 - Normal Interrupt generated by RX_ERROR
-+ */
-+#define INTERRUPT_MASK_TX_URUN_IRQ_ENABLE 16
-+ /**
-+ * 0 - No Error Interrupt generated by Tx Underrun
-+ * 1 - Error Interrupt generated by Tx Underrun
-+ */
-+#define INTERRUPT_MASK_TX_ORUN_IRQ_ENABLE 17
-+ /**
-+ * 0 - No Error Interrupt generated by Tx Overrun
-+ * 1 - Error Interrupt generated by Tx Overrun
-+ */
-+#define INTERRUPT_MASK_TX_FIFO_URUN_ERR_IRQ_ENABLE 18
-+ /**
-+ * 0 - No Error Interrupt generated by Tx FIFO Underrun
-+ * 1 - Error Interrupt generated by Tx FIFO Underrun
-+ */
-+#define INTERRUPT_MASK_TX_FIFO_ORUN_ERR_IRQ_ENABLE 19
-+ /**
-+ * 0 - No Error Interrupt generated by Tx FIFO Overrun
-+ * 1 - Error Interrupt generated by Tx FIFO Overrun
-+ */
-+#define INTERRUPT_MASK_RX_URUN_ERR_IRQ_ENABLE 24
-+ /**
-+ * 0 - No Error Interrupt generated by Rx Underrun
-+ * 1 - Error Interrupt generated by Rx Underrun
-+ */
-+#define INTERRUPT_MASK_RX_ORUN_ERR_IRQ_ENABLE 25
-+ /**
-+ * 0 - No Error Interrupt generated by Rx Overrun
-+ * 1 - Error Interrupt generated by Rx Overrun
-+ */
-+#define INTERRUPT_MASK_RX_FIFO_URUN_ERR_IRQ_ENABLE 26
-+ /**
-+ * 0 - No Error Interrupt generated by Rx FIFO Underrun
-+ * 1 - Error Interrupt generated by Rx FIFO Underrun
-+ */
-+#define INTERRUPT_MASK_RX_FIFO_ORUN_ERR_IRQ_ENABLE 27
-+ /**
-+ * 0 - No Error Interrupt generated by Rx FIFO Overrun
-+ * 1 - Error Interrupt generated by Rx FIFO Overrun
-+ */
-+#define INTERRUPT_MASK_SPDIF_RX_ERROR 28
-+ /**
-+ * 0 - No Error Interrupt generated by Rx S/PDIF Error (Parity/Preamble/Framing)
-+ * 1 - Error Interrupt generated by Rx S/PDIF Error (Parity/Preamble/ Framing)
-+ */
-+#define INTERRUPT_MASK_SPDIF_RX_LOCK 29
-+ /**
-+ * 0 - No Error Interrupt generated by Rx S/PDIF Lock event
-+ * 1 - Error Interrupt generated by Rx S/PDIF Lock event
-+ */
-+
-+
-+/* VERSION ------------ */
-+/**
-+ * Returns a 32 bit value that indicates the version and build options of the
-+ * audio core being used. See the version list at the end of the document to
-+ * find out how they translate.
-+ */
-+
-+#define VERSION_NUMBER 0
-+ /**
-+ * 0 - 7 Version of the core
-+ */
-+#define VERSION_AUX_APB 12
-+ /**
-+ * AUX_APB build option
-+ */
-+#define VERSION_RX_SPDIF 13
-+ /**
-+ * RX_SPDIF build option
-+ */
-+#define VERSION_TX_SPDIF 14
-+ /**
-+ * TX_SPDIF build option
-+ */
-+#define VERSION_AHB_DMA 15
-+ /**
-+ * DMA_AHB build option
-+ */
-+#define VERSION_RX_FIFO_ADDR_BITS 19
-+ /**
-+ * 16 - 19 G_RX_FIFO_A_BITS generic
-+ */
-+#define VERSION_RX_CHANS 23
-+ /**
-+ * 20 - 23 G_RX_CHANNELS generic
-+ */
-+#define VERSION_TX_FIFO_ADDR_BITS 27
-+ /**
-+ * 24 - 27 G_TX_FIFO_A_BITS generic
-+ */
-+#define VERSION_TX_CHANS 31
-+ /**
-+ * 28 - 31 G_TX_CHANNELS generic
-+ */
-+
-+
-+
-+/* TX_DATA_IN_FORMAT ------------ */
-+#define TX_DATA_IN_FORMAT_SAMPLE_ORDER 0
-+ /**
-+ * 0 - Samples written in as left/right pairs
-+ * 1 - All left channels written then all right
-+ */
-+#define TX_DATA_IN_FORMAT_24_BIT_SAMPLE 1
-+ /**
-+ * Set to \911\92 to indicate write contains 24 bit data (used in conjunction
-+ * with following setting)
-+ * ** NOT VALID FOR S/PDIF
-+ */
-+#define TX_DATA_IN_FORMAT_PAD_TOP_BYTE 2
-+ /**
-+ * 0 - Output data becomes WRITE_DATA(23 downto 0) & \9300000000\94
-+ * 1 - Output data becomes \930000000\94 & WRITE_DATA(23 downto 0)
-+ */
-+#define TX_DATA_IN_FORMAT_WAIT_FOR_HALF 4
-+ /**
-+ * 0 - Hardware waits for full number of writes before progressing
-+ * 1 - Hardware waits for half the number of writes before progressing
-+ */
-+
-+
-+/* TX_CHANNELS_ENABLE ------------ */
-+/**
-+ * If a channel is disabled, then no new data is presented to the data line of
-+ * that I2S channel
-+ * 0 - Tx Channel N disabled
-+ * 1 - Tx Channel N enabled
-+ */
-+
-+
-+/* TX_WRITES_TO ------------ */
-+/**
-+ * Can be used in conjunction with the Tx Channel Enable, whereby if an output
-+ * channel is disabled then software can select whether or not it still wishes
-+ * to write to this channel or not, effectively reduces its number of writes
-+ * per interrupt. If it chooses to still write to this location then the write
-+ * data is effectively ignored.
-+ * 0 - Tx Channel N not included in data
-+ * 1 - Tx Channel N included in data
-+ */
-+
-+
-+/* RX_DATA_OUT_FORMAT ------------ */
-+#define RX_DATA_OUT_FORMAT_SAMPLE_ORDER 0
-+ /**
-+ * 0 - Samples read in as left/right pairs
-+ * 1 - All left channels read then all right
-+ */
-+#define RX_DATA_OUT_FORMAT_24_BIT_SAMPLE 1
-+ /**
-+ * Set to \911\92 to indicate read contains 24 bit data (used in conjunction
-+ * with following setting)
-+ * ** NOT VALID FOR S/PDIF
-+ */
-+#define RX_DATA_OUT_FORMAT_PAD_TOP_BYTE 2
-+ /**
-+ * 0 - Read data becomes RX_DATA(23 downto 0) & \9300000000\94
-+ * 1 - Read data becomes \930000000\94 & RX_DATA(23 downto 0)
-+ */
-+#define RX_DATA_OUT_FORMAT_WAIT_FOR_HALF 4
-+ /**
-+ * 0 - Hardware waits for full number of reads before progressing
-+ * 1 - Hardware waits for half the number of reads before progressing
-+ */
-+
-+
-+/* RX_CHANNELS_ENABLE ------------ */
-+/**
-+ * If a channel is disabled, then no new data is presented to the data line of
-+ * that I2S channel
-+ * 0 - Rx Channel N disabled
-+ * 1 - Rx Channel N enabled
-+ */
-+
-+
-+/* RX_READS_FROM ------------ */
-+/**
-+ * Can be used in conjunction with the Rx Channel Enable, whereby if an input
-+ * channel is disabled then software can select whether or not it still wishes
-+ * to read from this channel or not, effectively reduces its number of reads
-+ * per interrupt. If it chooses to still read from this location then the read
-+ * data is invalid.
-+ * 0 - Rx Channel N not included in data
-+ * 1 - Rx Channel N included in data
-+ */
-+
-+
-+
-+/* TX_CPU_DATA_WRITES_ALT ------------ */
-+/**
-+ * See TX_CPU_DATA_WRITES.
-+ * This alternative address has been provided as it may be referenced within a
-+ * 13 bit immediate address (which may have benefits when being accessed by a
-+ * CPU with only a 13 bit immediate offset such as the LEON2 IU).
-+ * 0x0400-0x04FF TX_CPU_DATA_WRITES_ALT
-+ */
-+
-+
-+/* RX_CPU_DATA_READS_ALT ------------ */
-+/**
-+ * See RX_CPU_DATA_READS. This alternative address has been provided as it may
-+ * be referenced within a 13 bit immediate address (which may have benefits
-+ * when being accessed by a CPU with only a 13 bit immediate offset such as the
-+ * LEON2 IU).
-+ * 0x0800-0x08FF RX_CPU_DATA_READS_ALT
-+ */
-+
-+
-+/* TX_CPU_DATA_WRITES ------------ */
-+/**
-+ * Any writes to this location writes a valid sample into the internal buffer
-+ * of the audio core. All writes should be the full 32 bits.
-+ * This address is WRITE ONLY - any reads will return the previous read value
-+ * on the bus.
-+ * 0x1000-0x1FFF TX_CPU_DATA_WRITES
-+ */
-+
-+
-+/* RX_CPU_DATA_READS ------------ */
-+/**
-+ * Any reads from this location read a valid sample from the internal buffer of
-+ * the audio core. All reads should be the full 32 bits.
-+ * This address is READ ONLY - any writes will be ignored.
-+ * 0x2000-0x2FFF RX_CPU_DATA_READS
-+ */
-+
-+#endif /* __ASM_ARM_ARCH_I2S_H */
-+
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/io.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/io.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/io.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/io.h 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,17 @@
-+/*
-+ * linux/include/asm-arm/arch-oxnas/io.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.
-+ */
-+
-+#ifndef __ASM_ARM_ARCH_IO_H
-+#define __ASM_ARM_ARCH_IO_H
-+
-+#define IO_SPACE_LIMIT 0xffffffff
-+
-+#define __io(a) ((void __iomem*)(a))
-+#define __mem_pci(a) (a)
-+
-+#endif //__ASM_ARM_ARCH_IO_H
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/irqs.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/irqs.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/irqs.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/irqs.h 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,42 @@
-+/* linux/include/asm-arm/arch-oxnas/irqs.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.
-+ */
-+
-+#ifndef __ASM_ARCH_IRQS_H
-+#define __ASM_ARCH_IRQS_H
-+
-+#define FIQ_INTERRUPT 0
-+#define SOFTWARE_INTERRUPT 1
-+#define TIMER_1_INTERRUPT 4
-+#define TIMER_2_INTERRUPT 5
-+#define USB_FS_INTERRUPT 7
-+#define MAC_INTERRUPT 8
-+#define SEM_A_INTERRUPT 10
-+#define SEM_B_INTERRUPT 11
-+#define DMA_INTERRUPT_0 13
-+#define DMA_INTERRUPT_1 14
-+#define DMA_INTERRUPT_2 15
-+#define DMA_INTERRUPT_3 16
-+#define DPE_INTERRUPT 17
-+#define SATA_1_INTERRUPT 18
-+#define SATA_2_INTERRUPT 19
-+#define DMA_INTERRUPT_4 20
-+#define GPIO_1_INTERRUPT 21
-+#define GPIO_2_INTERRUPT 22
-+#define UART_1_INTERRUPT 23
-+#define UART_2_INTERRUPT 24
-+#define I2S_INTERRUPT 25
-+#define SATA_1_ERROR 26
-+#define SATA_2_ERROR 27
-+#define I2C_INTERRUPT 28
-+#define UART_3_INTERRUPT 29
-+#define UART_4_INTERRUPT 30
-+
-+#define PCI_A_INTERRUPT GPIO_1_INTERRUPT
-+
-+#define NR_IRQS 32
-+
-+#endif // __ASM_ARCH_IRQ_H
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/leon-power-button-prog.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/leon-power-button-prog.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/leon-power-button-prog.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/leon-power-button-prog.h 2008-07-01 09:46:51.000000000 +0200
-@@ -0,0 +1,73 @@
-+static const s8 leon_srec[] =
-+"S01400006C656F6E2D706F7765722D627574746F6E1A\n"
-+"S3159801E00081D820000326007881984000821020C08C\n"
-+"S3159801E010818840008190000003116C008210601481\n"
-+"S3159801E020213D4040A014200FE02040001D26007F8E\n"
-+"S3159801E0309C13A3F0BC10000E8E1000008C100000EB\n"
-+"S30D9801E0404000004501000000B3\n"
-+"S3159801E110A7480000A8100001AA100002AC1000033D\n"
-+"S3159801E120AE100004A14000009C10001E400000EAB9\n"
-+"S3159801E13001000000818400008810001786100016DF\n"
-+"S3159801E1408410001582100014818CC00081C440008F\n"
-+"S3099801E15081CC80005F\n"
-+"S3159801E1549C03BFB8FE23A020BE23BFB8DE23A02408\n"
-+"S3159801E164E03BA028E43BA030E823A03803160076C8\n"
-+"S3159801E17484102030821063FCC42840002511500075\n"
-+"S3159801E18486103FFF8214A00CC62040008414A10C6B\n"
-+"S3159801E1940316007FC6208000821063FC4000008924\n"
-+"S3159801E1A4E600400090102000921020004000008E56\n"
-+"S3159801E1B4941023E88210200083306008821060202E\n"
-+"S3159801E1C4A21020FFA3346008A1480000A02C0011D6\n"
-+"S3159801E1D4A0140001818C0000A0102010A414A0089A\n"
-+"S3159801E1E4E0248000400000950100000009114000D8\n"
-+"S3159801E1F49A11200CC203400082087FFEC223400074\n"
-+"S3159801E20498112014C203000082087FFEC2230000DD\n"
-+"S3159801E2148811208CC201000082087FFEC221000069\n"
-+"S3159801E224C40340008408BFEFC4234000C20300001E\n"
-+"S3159801E23482087FEFC2230000C40100008408BFEF5F\n"
-+"S3159801E244C4210000073F7FFFC20340008610E3FF05\n"
-+"S3159801E25482084003C2234000C40300008408800353\n"
-+"S3159801E264C4230000C201000082084003C2210000B1\n"
-+"S3159801E2741B1100008610200188136014C621000022\n"
-+"S3159801E2848213601CC620400084136020E02080001D\n"
-+"S3159801E29480A4E0000280003C030080008413601887\n"
-+"S3159801E2A4C2208000071100008410E01C030080003E\n"
-+"S3159801E2B4C2208000A8100003C2050000808860105F\n"
-+"S3159801E2C40280000DA0102000C2050000808860100D\n"
-+"S3159801E2D41280000925000009231100004000005E00\n"
-+"S3159801E2E49014A310C20440008088601002BFFFFCFA\n"
-+"S3159801E2F40100000023000009251100004000005682\n"
-+"S3159801E30490146310C20480008088601012800021E2\n"
-+"S3159801E31480A42031A004200180A4203104BFFFF8F1\n"
-+"S3159801E324031100000500800080A4E0001280000516\n"
-+"S3159801E3348210601403110000050080008210601891\n"
-+"S3159801E344C420400023000009A01020634000004225\n"
-+"S3159801E35490146310A0843FFF1CBFFFFD031600763B\n"
-+"S3159801E364821063FC84102031C428400003110000F4\n"
-+"S3159801E3748610200182106018C62040001080000083\n"
-+"S3159801E38401000000C221000010BFFFC80711000058\n"
-+"S3159801E39404BFFFCA0311000010BFFFE40500800003\n"
-+"S3159801E3A49C07FFB8FE03A020DE03A024E01BA02847\n"
-+"S3159801E3B4E41BA030E803A03881C3E0089C23BFB8C6\n"
-+"S3159801E3C4051150008610A20882102044C220C0006C\n"
-+"S3159801E3D48410A22882102088C220800081C3E00874\n"
-+"S3159801E3E401000000932A601003000061821062A064\n"
-+"S3159801E3F493326010925A4001952AA010030005F5AC\n"
-+"S3159801E40482106384900A20FF9532A010905A0001D5\n"
-+"S3159801E41493326006945AA320900200099532A00972\n"
-+"S3159801E424031150009002000A82106200D020400025\n"
-+"S3159801E43481C3E00801000000051150008410A20868\n"
-+"S3159801E444C200800082106080C220800081C3E008E7\n"
-+"S3159801E4540100000003041893821061D380520001CD\n"
-+"S3159801E46491400000913220068810000682380008EF\n"
-+"S3159801E47480A040041A80000D8401000882020004D9\n"
-+"S3159801E484900060018210000680A0400486603FFFD8\n"
-+"S3159801E49480A2000184603FFF8090C00212BFFFFAF8\n"
-+"S3159801E4A401000000308000098210000680A0400215\n"
-+"S3159801E4B41A800006010000008210000680A040021E\n"
-+"S3159801E4C40ABFFFFA0100000081C3E00801000000B9\n"
-+"S3159801E4D405115000C200800080A060000280000BE4\n"
-+"S3159801E4E48610A20C80886010028000040100000046\n"
-+"S3159801E4F4C020C0008C01A001C200800080A06000E9\n"
-+"S3159801E50412BFFFFA8088601081C3E00801000000F9\n"
-+"S7059801E00081\n";
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/leon-program.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/leon-program.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/leon-program.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/leon-program.h 2008-07-01 09:46:44.000000000 +0200
-@@ -0,0 +1,404 @@
-+static const s8 leon_srec[] =
-+"S00700006C656F6E4A\n"
-+"S3159801E00081D820000326007881984000821020C08C\n"
-+"S3159801E010818840008190000003116C008210601481\n"
-+"S3159801E020213FC040A014200FE02040001D26007F0C\n"
-+"S3159801E0309C13A3F0BC10000E8E1000008C100000EB\n"
-+"S30D9801E0404000005A010000009E\n"
-+"S3159801E050051150008410A208C200800082106080C9\n"
-+"S3159801E060C220800081C3E00801000000051150001C\n"
-+"S3159801E0708610A20882102044C220C0008410A228CB\n"
-+"S3159801E08082102088C220800081C3E0080100000028\n"
-+"S3159801E110A7480000A8100001AA100002AC1000033D\n"
-+"S3159801E120AE100004A14000009C10001E4000007F24\n"
-+"S3159801E13001000000818400008810001786100016DF\n"
-+"S3159801E1408410001582100014818CC00081C440008F\n"
-+"S3099801E15081CC80005F\n"
-+"S3159801E154932A601003000061821062A093326010C2\n"
-+"S3159801E164925A4001952AA010030005F582106384FA\n"
-+"S3159801E174900A20FF9532A010905A000193326006B6\n"
-+"S3159801E184945AA320900200099532A00903115000CC\n"
-+"S3159801E1949002000A82106200D020400081C3E008F0\n"
-+"S3159801E1A4010000009C03BFB8FE23A020BE23BFB87C\n"
-+"S3159801E1B4DE23A024E03BA028E43BA030033D404065\n"
-+"S3159801E1C48210600FA610200021116C00A01420144F\n"
-+"S3159801E1D4C2240000400001BF2511500086103FFF5C\n"
-+"S3159801E1E48214A00CC62040008414A10CC620800079\n"
-+"S3159801E1F47FFFFF9E010000009010200092102000DE\n"
-+"S3159801E2047FFFFFD4941023E8400001A30100000086\n"
-+"S3159801E2148A1000130326007EC60061700926007EC3\n"
-+"S3159801E224841061708211219CDA00A004C6206008CA\n"
-+"S3159801E234C621219C400001D5DA206004A734E00860\n"
-+"S3159801E244A614E020A21020FFA3346008A148000078\n"
-+"S3159801E254A02C0011A0140013818C000082102010A8\n"
-+"S3159801E264A414A008C224800084102400C424800025\n"
-+"S3159801E27482102100C22480004000055C0100000040\n"
-+"S3159801E2847FFFFF73010000008210000780A06000E1\n"
-+"S3159801E29402BFFFFEA6100001308000071280000F0E\n"
-+"S3159801E2A40100000082100007A690600002BFFFF7E4\n"
-+"S3159801E2B4010000008E29C013808CE00202BFFFF88A\n"
-+"S3159801E2C4808CE0014000020001000000808CE0018E\n"
-+"S3159801E2D402BFFFF5010000004000025B0100000047\n"
-+"S3159801E2E430BFFFF19C07FFB8FE03A020DE03A024EC\n"
-+"S3159801E2F4E01BA028E41BA03081C3E0089C23BFB887\n"
-+"S3159801E3049801E6949801E7A09801E7689801E724AB\n"
-+"S3159801E3149801E6B49801E8589801E83C9801E7EC25\n"
-+"S3159801E3249801E7C49C03BFA0FE23A020BE23BFA0E7\n"
-+"S3159801E334DE23A024E03BA028E43BA030E83BA038A8\n"
-+"S3159801E34403115000E400400080A4A0000280014A11\n"
-+"S3159801E354808CA1000280004E808CA01007101004B6\n"
-+"S3159801E364C400E014C200E01C88088001808920104A\n"
-+"S3159801E3749A1020009810200002800003841020002F\n"
-+"S3159801E3848410201080892080328000028410A08015\n"
-+"S3159801E39480892040328000028410A04080A0A00089\n"
-+"S3159801E3A40280000603000060C200E01C8228400235\n"
-+"S3159801E3B4C220E01C03000060821100010500006080\n"
-+"S3159801E3C4C220E014882900028143C000C2000000DB\n"
-+"S3159801E3D480892401028000068089202882102002DF\n"
-+"S3159801E3E48E11C00188093BFE808920280280000984\n"
-+"S3159801E3F480892002821020028E11C001808920080A\n"
-+"S3159801E40422800003981020019A1020018089200205\n"
-+"S3159801E414128000060310100480A360000280007F16\n"
-+"S3159801E42480A3200003101004C40060180700000894\n"
-+"S3159801E43484108003C4206018821000058210400459\n"
-+"S3159801E4448A100001091140008211204CC400400031\n"
-+"S3159801E4548088A1001280000E808CA0100326007E6D\n"
-+"S3159801E464C600617884100005C420C0008143C000A9\n"
-+"S3159801E474C20000008410210086112050C420C000D7\n"
-+"S3159801E484821020008A100001808CA0100280001C42\n"
-+"S3159801E494808CA400031150008210620CC0204000A5\n"
-+"S3159801E4A48C01A0018210000580A0600002800014EE\n"
-+"S3159801E4B4808CA400091140008211204CC4004000AC\n"
-+"S3159801E4C48088A1001280000E808CA4000326007E09\n"
-+"S3159801E4D4C600617884100005C420C0008143C00039\n"
-+"S3159801E4E4C20000008410210086112050C420C00067\n"
-+"S3159801E4F4821020008A100001808CA40002800039C1\n"
-+"S3159801E50403000400031140008410604CE600800067\n"
-+"S3159801E51482106054840CE003C4204000808CE0018E\n"
-+"S3159801E5240280002B808CE0022326007EAA07FFF442\n"
-+"S3159801E534A007FFF0A807FFEC9A14619C96103FFF79\n"
-+"S3159801E544C8036008108000051908000080A2E0003D\n"
-+"S3159801E55402800011C4236008C601000080A0E0006F\n"
-+"S3159801E564168000178088C00C028000418401200817\n"
-+"S3159801E574C2036004C624000080A0800112BFFFF480\n"
-+"S3159801E58488100002C803400080A2E00012BFFFF37E\n"
-+"S3159801E594C8236008C807FFF080A1200818800024C2\n"
-+"S3159801E5A40720000005260078832920028410A304F5\n"
-+"S3159801E5B4C600800181C0C0000100000080A2E0006D\n"
-+"S3159801E5C402BFFFF5C6240000808CE0020280000594\n"
-+"S3159801E5D403000400821020018E11C0010300040077\n"
-+"S3159801E5E4808C8001028000080311500003115800A1\n"
-+"S3159801E5F482106090C0204000841020048E11C002BD\n"
-+"S3159801E60403115000E400400080A4A00012BFFF52F9\n"
-+"S3159801E614808CA1003080009802BFFF8803101004F3\n"
-+"S3159801E624C020600430BFFF850720000086290003B7\n"
-+"S3159801E6349A14619CC807FFF48143C000C200000084\n"
-+"S3159801E644C40360088400A008C2036004C6210000BC\n"
-+"S3159801E65480A0800102800004C204619C10BFFFB7A8\n"
-+"S3159801E664C423600810BFFFB5C22360080507FFFFDE\n"
-+"S3159801E6748410A3FF031000008408C0028208C00115\n"
-+"S3159801E684C8254000C225000010BFFFC3C42400005A\n"
-+"S3159801E6940326007EC40061A880A0A000028000061B\n"
-+"S3159801E6A4C207FFEC400000E401000000C807FFF030\n"
-+"S3159801E6B4C207FFEC0708000080A0600002BFFFDBD9\n"
-+"S3159801E6C486110003C807FFF4032000008410200173\n"
-+"S3159801E6D48628C001C42120049A14619C8143C000F0\n"
-+"S3159801E6E4C2000000C62100008143C000C200000098\n"
-+"S3159801E6F4C40360088800A00803114000C603600497\n"
-+"S3159801E7040500004082106050C420400080A1000397\n"
-+"S3159801E71402BFFFD5C204619C10BFFF88C823600855\n"
-+"S3159801E724C807FFF4C601200405101004C200A01CF2\n"
-+"S3159801E7349A284003C207FFECDA20A01C80A0600047\n"
-+"S3159801E74402800013C607FFF0030800008610C00173\n"
-+"S3159801E754052000008628C002DA21200410BFFFE0B4\n"
-+"S3159801E7649A14619CC807FFF4C60120040510100485\n"
-+"S3159801E774C200A01C9A104003C207FFECDA20A01C21\n"
-+"S3159801E78480A0600012BFFFF1C607FFF003200000C6\n"
-+"S3159801E7948628C00110BFFFA99A14619C400000AF56\n"
-+"S3159801E7A401000000C207FFEC80A060000280000C03\n"
-+"S3159801E7B4C607FFF00308000010BFFFC38610C00107\n"
-+"S3159801E7C4821023D005101004C607FFECC220A014AA\n"
-+"S3159801E7D480A0E00012BFFFF8C607FFF003200000EF\n"
-+"S3159801E7E410BFFF948628C001C807FFF4C20120040C\n"
-+"S3159801E7F480A060000280001D05101004C200A018B4\n"
-+"S3159801E80482106002C220A018C207FFEC80A06000A3\n"
-+"S3159801E81402BFFFDFC607FFF0030800008610C00198\n"
-+"S3159801E82405200000821020018628C002C2212004F6\n"
-+"S3159801E83410BFFFAB9A14619CC207FFF4D000600421\n"
-+"S3159801E8444000003301000000C207FFEC10BFFFD857\n"
-+"S3159801E85480A060004000001201000000C207FFEC8E\n"
-+"S3159801E86410BFFFD380A06000C200A01810BFFFE6B6\n"
-+"S3159801E87482087FFD9C07FFA0FE03A020DE03A02447\n"
-+"S3159801E884E01BA028E41BA030E81BA03881C3E0084C\n"
-+"S3159801E8949C23BFA081C3E008010000000326007EE3\n"
-+"S3159801E8A40526007EC60061988410A17088102009F7\n"
-+"S3159801E8B4C200C000C22080008600E00488813FFF20\n"
-+"S3159801E8C41CBFFFFC8400A00481C3E008010000007A\n"
-+"S3159801E8D49C03BFD0FE23A01CBE23BFD0DE23A02059\n"
-+"S3159801E8E40316007F821063FCC60040000526007E4D\n"
-+"S3159801E8F47FFFFFEBC620A1989C07FFD0FE03A01CBF\n"
-+"S3159801E904DE03A02081C3E0089C23BFD00310100422\n"
-+"S3159801E914C6006018050000088428C002C42060183F\n"
-+"S3159801E9248610000105001C00C200E014808840028C\n"
-+"S3159801E93412BFFFFE80A22000228000090310100056\n"
-+"S3159801E94407101000C400C00003000020822880012B\n"
-+"S3159801E954C220C0001080000703101004C4004000B0\n"
-+"S3159801E9640700002084108003C422000103101004B8\n"
-+"S3159801E974C40060180700000884108003C420601836\n"
-+"S3159801E98481C3E008010000009C03BFD0FE23A01CAC\n"
-+"S3159801E994BE23BFD0DE23A020E023A0240326007E35\n"
-+"S3159801E9A4821061701B26007E1926007E841361C429\n"
-+"S3159801E9B4C600600C881321B4D60060102126007E07\n"
-+"S3159801E9C4D0006014C621200CC02361C4C020A010B5\n"
-+"S3159801E9D4C62321B4D6212004C020A004C020A008AF\n"
-+"S3159801E9E4C020A00CC6212008400003A9D02421B038\n"
-+"S3159801E9F4D02421B0400003BA921020360326007E13\n"
-+"S3159801EA04D02421B0C02061A88143C000C20000006F\n"
-+"S3159801EA140526007EC020A1ACD00421B09C07FFD066\n"
-+"S3159801EA24FE03A01CDE03A020E003A02481C3E00812\n"
-+"S3159801EA349C23BFD00526007EC200A1AC80A06000AD\n"
-+"S3159801EA441280000482102001C220A1AC8E11C0014B\n"
-+"S3159801EA5481C3E008010000009C03BFD0FE23A01CDB\n"
-+"S3159801EA64BE23BFD0DE23A0207FFFFFC8010000008C\n"
-+"S3159801EA748810201807101004C20100030500000825\n"
-+"S3159801EA8482104002C2210003841020010326007ECD\n"
-+"S3159801EA94C42061A89C07FFD0FE03A01CDE03A02016\n"
-+"S3159801EAA481C3E0089C23BFD0832A2010913060103B\n"
-+"S3159801EAB4900A20FF83306018912A200881C3E008C0\n"
-+"S3159801EAC4901040089C03BFD8DE23A008F43BA010FD\n"
-+"S3159801EAD4F83BA0180326007E3926007E961061D845\n"
-+"S3159801EAE4BA1721C43526007EF60061D89010200005\n"
-+"S3159801EAF49810000B9210001DC402E008C202E00CA3\n"
-+"S3159801EB0480A0800102800032D406A1ECC200800064\n"
-+"S3159801EB1480A0600026800047D426A1ECDA03200859\n"
-+"S3159801EB2484036010C203200480A080010280003F00\n"
-+"S3159801EB348610000CC4232008C200E01080A060004F\n"
-+"S3159801EB4432800002C020E010DE034000030000205A\n"
-+"S3159801EB54808BC00102800024808BE200028000052C\n"
-+"S3159801EB64808BEC00C202600882006001C2226008B0\n"
-+"S3159801EB7402800005808BE100C202600C820060016C\n"
-+"S3159801EB84C222600C0280000501000000C2026010D6\n"
-+"S3159801EB9482006010C2226010C203600C80A06000DB\n"
-+"S3159801EBA422800007C402E008C203600CD4206008DE\n"
-+"S3159801EBB4C020600494100001C402E008C202E00C6B\n"
-+"S3159801EBC480A0800112BFFFD290102001C202E010EA\n"
-+"S3159801EBD480A0600012BFFFCE0100000010800015CE\n"
-+"S3159801EBE4D426A1ECC8036004C60721C4820927FF69\n"
-+"S3159801EBF48600C001051000008089000202BFFFE764\n"
-+"S3159801EC04C62721C48333E003C4076004C60760108A\n"
-+"S3159801EC14820860078600C0018400A001C4276004A5\n"
-+"S3159801EC2410BFFFDEC627601010BFFFC4F623200865\n"
-+"S3159801EC34DE03A008F41BA010F81BA01881C3E008F2\n"
-+"S3159801EC449C23BFD89C03BF40FE23A020BE23BF406C\n"
-+"S3159801EC54DE23A024E03BA028E43BA030E83BA0387F\n"
-+"S3159801EC64EC3BA040F03BA048F43BA050F83BA0589D\n"
-+"S3159801EC740526007EC200A1A880A0600002800173C7\n"
-+"S3159801EC840726007EC200E1AC80A060001280017064\n"
-+"S3159801EC94010000003326007EB41661B4C606A008A6\n"
-+"S3159801ECA4C210E01A8328601083306010808860024D\n"
-+"S3159801ECB41280016680886001028001648800E08C74\n"
-+"S3159801ECC4C210E01A82106002C406A00480A1000250\n"
-+"S3159801ECD4028001F9C230E01AC826A008AE90E00075\n"
-+"S3159801ECE42280015B0726007EC215E01A808860049B\n"
-+"S3159801ECF432800028F005E0102326007EC405E0043E\n"
-+"S3159801ED04C205E008A21461D8A6208001A0100002C9\n"
-+"S3159801ED14E405E00CA8102000B8100011B605E01C13\n"
-+"S3159801ED24B005E0641B26007EFA036168AA100013F5\n"
-+"S3159801ED34AC100012E6160000E406C000B0062002E4\n"
-+"S3159801ED44B606E004A0240015C204601080A06000F1\n"
-+"S3159801ED541280000701000000C404600CC200800000\n"
-+"S3159801ED6480A06000168000A69A00A0108210000761\n"
-+"S3159801ED748288600202BFFFFE010000008E29C0014D\n"
-+"S3159801ED847FFFFF510100000010BFFFF1C20460101C\n"
-+"S3159801ED94C20E0000C405E00CC427FFB08208600FB8\n"
-+"S3159801EDA483286002C80E2009842600028400800103\n"
-+"S3159801EDB4860920FF80A0E006BA060001028001C3F5\n"
-+"S3159801EDC4C437FFF680A0E011228001BE8400A00812\n"
-+"S3159801EDD480A12006C027FFEC028001A0C027FFE886\n"
-+"S3159801EDE4C417FFF6DA15E018C215E0168528A0109F\n"
-+"S3159801EDF4DA27FFE080A36000C227FFE41280000CA3\n"
-+"S3159801EE04C427FFB40326007EC617FFF6C40061889B\n"
-+"S3159801EE148728E0108400A00E8330E01084208001B6\n"
-+"S3159801EE249A102001C427FFE0DA27FFE4C607FFB446\n"
-+"S3159801EE34E205E004C205E0088530E0108224400129\n"
-+"S3159801EE4482204002C427FFCCDA07FFB0840340022C\n"
-+"S3159801EE54C227FFD0C427FFD47FFFFF14D0162004FE\n"
-+"S3159801EE64912A2010C607FFB09132201082102000F3\n"
-+"S3159801EE74C407FFE48608E003C027FFBCD037FFC662\n"
-+"S3159801EE8480A04002C027FFDCC027FFD816800099CE\n"
-+"S3159801EE94C627FFACDA07FFCCA224400DC207FFE0D0\n"
-+"S3159801EEA480A4400104800003E227FFB8C227FFB873\n"
-+"S3159801EEB4D017FFC6912A20107FFFFEFC91322010AD\n"
-+"S3159801EEC4C407FFB8C617FFF68200800382007FF253\n"
-+"S3159801EED483286010D03620047FFFFEF491306010A9\n"
-+"S3159801EEE4DA17FFC6C20E20099A036001D0362002AA\n"
-+"S3159801EEF480A0600602800110DA37FFC680A06011EF\n"
-+"S3159801EF0402800145C207FFB8C407FFB8C036200A74\n"
-+"S3159801EF14C427FFDCA41000020726007EE200E1EC78\n"
-+"S3159801EF2480A460000280002D84102004C204600825\n"
-+"S3159801EF34C220E1ECC207FFB49B306010E0044000A4\n"
-+"S3159801EF44820C200382208001C607FFAC84208003AB\n"
-+"S3159801EF5480A04002DA246004C607FFB0028000CF7D\n"
-+"S3159801EF64881000101080000698102000C22900000D\n"
-+"S3159801EF74980320018600E0018801200180A3000DF1\n"
-+"S3159801EF842ABFFFFBC208C0002726007EA614E1D833\n"
-+"S3159801EF94C204E01080A060001280000701000000FE\n"
-+"S3159801EFA4C204E00CC400400080A0A0003680014C45\n"
-+"S3159801EFB41B26007E821000078288600202BFFFFE2C\n"
-+"S3159801EFC4010000008E29C0017FFFFEBF01000000E9\n"
-+"S3159801EFD410BFFFF1C204E010821000078288600214\n"
-+"S3159801EFE402BFFFFE010000008E29C0017FFFFEB615\n"
-+"S3159801EFF40100000010BFFFCA0726007EC20720043D\n"
-+"S3159801F0048810000280A34001028001E99810001C2F\n"
-+"S3159801F014C20120048208401DC2212004C40120048F\n"
-+"S3159801F0248408B800C4212004872D6010C2012004E5\n"
-+"S3159801F0348730E01082104003C2212004EC21200875\n"
-+"S3159801F044C021200CC6012004031800008228C0019F\n"
-+"S3159801F054C4032008C2212004841B400280A0000214\n"
-+"S3159801F064C60120040306000084603FFF8228C0017C\n"
-+"S3159801F074DA23200CC4232010C221200480A4200062\n"
-+"S3159801F0841280000780A52000C20120040510000003\n"
-+"S3159801F09482104002C221200480A52000028001BE6C\n"
-+"S3159801F0A4010000008143C000C20000000320000053\n"
-+"S3159801F0B4C401000084108001C421000080A42000AA\n"
-+"S3159801F0C412BFFF1CAA1000138143C000C20000009E\n"
-+"S3159801F0D403200000C405000084108001C4250000A3\n"
-+"S3159801F0E48143C000C200000005101004C020A0048A\n"
-+"S3159801F0F40726007E1B00003FC400E1C49A1363FFF0\n"
-+"S3159801F10480A0800D8810E1C4088000048210000252\n"
-+"S3159801F1141B26007EC403616C82204002C220E1C48E\n"
-+"S3159801F124C425E088C401200480A0A03F0880000378\n"
-+"S3159801F134821000028410203F82204002C2212004BA\n"
-+"S3159801F1448528A010C205E08882104002C225E0886D\n"
-+"S3159801F154C401200880A0A007088000038210000239\n"
-+"S3159801F1648410200782204002C22120088528A016EF\n"
-+"S3159801F174C205E08882104002C225E088C401200CA9\n"
-+"S3159801F18480A0A0070880000382100002841020073B\n"
-+"S3159801F19482204002C221200C8528A019C205E08844\n"
-+"S3159801F1A482104002C225E088C401201080A0A00FD5\n"
-+"S3159801F1B408800003821000028410200F82204002E6\n"
-+"S3159801F1C4C2212010C205E0888528A01C821040021D\n"
-+"S3159801F1D4C225E0888143C000C20000000326007E50\n"
-+"S3159801F1E4881061B4C215E01AC401200C82087FFC08\n"
-+"S3159801F1F48400A08CC6012004C235E01A80A080033D\n"
-+"S3159801F2042280008B0526007EC421200C8143C000F0\n"
-+"S3159801F214C20000000311400005000080821060506E\n"
-+"S3159801F224C42040001B26007EC60361A880A0E00086\n"
-+"S3159801F234028000060526007EC200A1AC80A060006B\n"
-+"S3159801F24422BFFE98C606A0080726007EC200E1AC36\n"
-+"S3159801F25480A0600002800159051150008210A00C0B\n"
-+"S3159801F2649A102400DA20400009101004C6012018C7\n"
-+"S3159801F274030000088228C001C22120188410A0081E\n"
-+"S3159801F28403114000DA2080000700010082106050C3\n"
-+"S3159801F294C62040003080014980A0A0041280000A4B\n"
-+"S3159801F2A4981020001080000C8423400C02BFFF376D\n"
-+"S3159801F2B498032001C208C000C22900008600E00113\n"
-+"S3159801F2C48801200180A300020ABFFFF980A3000DDB\n"
-+"S3159801F2D48423400C8530A0028328A002822340010E\n"
-+"S3159801F2E49A20400C1080000698102000C221000034\n"
-+"S3159801F2F4980320018600E0048801200480A3000273\n"
-+"S3159801F3042ABFFFFBC200C000108000069810200097\n"
-+"S3159801F314C2290000980320018600E0018801200192\n"
-+"S3159801F32480A3000D2ABFFFFBC208C00010BFFF18B7\n"
-+"S3159801F3342726007E0300003FC807600482106300F5\n"
-+"S3159801F344860900011B003FC0852920188209000DF2\n"
-+"S3159801F3548728E0088410800383306008841080012C\n"
-+"S3159801F3648931201888108004C407FFDC80A0A00086\n"
-+"S3159801F37422800012DA07FFE80700003F880100029D\n"
-+"S3159801F3848610E300840900038528A0088329201898\n"
-+"S3159801F394821040028609000D053FC0008730E008B7\n"
-+"S3159801F3A484090002821040038530A0188210400215\n"
-+"S3159801F3B4C2276004DA07FFE880A1000D1A80001FAE\n"
-+"S3159801F3C4C207FFE89023400490023FFF912A201038\n"
-+"S3159801F3D47FFFFDB691322010D0376012C407FFEC37\n"
-+"S3159801F3E480A0A00002BFFECAC407FFB8C607FFE4FF\n"
-+"S3159801F3F48200FFFFDA07FFBC80A0400D32BFFEC52D\n"
-+"S3159801F404C036200AC217600C8210610010BFFEBF75\n"
-+"S3159801F414C237600C90006008912A20107FFFFDA3E3\n"
-+"S3159801F4249132201010BFFEB9D0376004C200A1B43E\n"
-+"S3159801F43410BFFF77C221200C80A0600002BFFFE9AC\n"
-+"S3159801F444C407FFECC417600C033FFFC882288001E8\n"
-+"S3159801F45410BFFFE3C237600CE217600C0300000883\n"
-+"S3159801F464808C40010280000E0700003F7FFFFD8FCC\n"
-+"S3159801F474D0176012A12A20107FFFFD8CD017600641\n"
-+"S3159801F484912A2010A134201091322010A00400084A\n"
-+"S3159801F494A0042001E027FFE80700003F8610E2FF59\n"
-+"S3159801F4A4820C4003A20C6100C237600C10BFFE4D5A\n"
-+"S3159801F4B4E227FFECC20661B410BFFE09C226A00872\n"
-+"S3159801F4C410BFFE44C437FFF6C217600C833060023E\n"
-+"S3159801F4D48208603C10BFFFFB84008001981361D8B1\n"
-+"S3159801F4E4E803200C88052010C203200480A100019A\n"
-+"S3159801F4F422800002C80361D8053FF001C2052004A1\n"
-+"S3159801F5048410A3FF82084002C2252004C40520045E\n"
-+"S3159801F5148408B800C4252004C607FFB4C20520048C\n"
-+"S3159801F5248530E01082104002C2252004E025200887\n"
-+"S3159801F534E225200CC205200405060000821040022B\n"
-+"S3159801F544C2252004C605200403180000C403200814\n"
-+"S3159801F5548228C00184190002C2252004DA07FFD83B\n"
-+"S3159801F56480A00002C823200CC6052004852B6002BE\n"
-+"S3159801F5748803400D030800008610C0019A603FFF76\n"
-+"S3159801F5848400801788010017DA232010C6252004E1\n"
-+"S3159801F594B800A01CB6012064C207FFD080A48001DC\n"
-+"S3159801F5A406800076E207FFD4DA07FFD8C416C000AE\n"
-+"S3159801F5B4C60700009A036001A0100001C427FFD072\n"
-+"S3159801F5C4C627FFD4DA27FFD8B606E002B80720047F\n"
-+"S3159801F5D42726007EA614E1D80726007E80A420005B\n"
-+"S3159801F5E4AC1000130280003FEA00E168C204E010FF\n"
-+"S3159801F5F480A060001280005501000000C404E00C4C\n"
-+"S3159801F604C200800080A06000068000508810000225\n"
-+"S3159801F6148400A010C205A00480A080010280005431\n"
-+"S3159801F62486100016C200E0088218800180A00001A5\n"
-+"S3159801F634C420E00C84603FFFC420E01080A427FF17\n"
-+"S3159801F644188000039A1027FF9A100010C20120040B\n"
-+"S3159801F65482084015C2212004C40120048408B800F4\n"
-+"S3159801F664C4212004872B6010C20120048730E0103E\n"
-+"S3159801F67482104003C2212004E2212008C021200CD3\n"
-+"S3159801F684C20120040506000082104002C22120040A\n"
-+"S3159801F694C40120040318000082288001C221200491\n"
-+"S3159801F6A4A4A4800D1280000601000000C201200462\n"
-+"S3159801F6B40510000082104002C22120048143C00033\n"
-+"S3159801F6C4C200000003200000C401000084108001D8\n"
-+"S3159801F6D4C4210000A0A4000D12BFFFC5A204400DC9\n"
-+"S3159801F6E480A4A00012BFFFAEC207FFD08143C00019\n"
-+"S3159801F6F4C200000003200000C405000084108001A4\n"
-+"S3159801F704C42500008143C000C2000000C207FFBCA3\n"
-+"S3159801F71482006001C227FFBC03101004C407FFCC02\n"
-+"S3159801F724C0206004C607FFB884008003DA07FFBCCB\n"
-+"S3159801F734C207FFE480A3400116BFFE6EC427FFCC1F\n"
-+"S3159801F74410BFFDD5E205E0048210000782886002A5\n"
-+"S3159801F75402BFFFFE010000008E29C0017FFFFCDA7B\n"
-+"S3159801F7640100000010BFFFA3C204E0101B26007E0F\n"
-+"S3159801F77410BFFFADC40361D8C207FFD082204012DF\n"
-+"S3159801F78484044012C227FFD0A010001210BFFF9123\n"
-+"S3159801F794C427FFD4C2012004050800008210400240\n"
-+"S3159801F7A4C221200410BFFE46A81000040326007E39\n"
-+"S3159801F7B410BFFE18DA0061D89C07FF40FE03A0200B\n"
-+"S3159801F7C4DE03A024E01BA028E41BA030E81BA03884\n"
-+"S3159801F7D4EC1BA040F01BA048F41BA050F81BA058A2\n"
-+"S3159801F7E481C3E0089C23BF40031140008410200381\n"
-+"S3159801F7F482106060C420400081C3E00801000000C3\n"
-+"S3159801F8049C03BFF0DE23A0041F26007E84102000EB\n"
-+"S3159801F814C603E1D8092000008328A004C020C001AA\n"
-+"S3159801F8248200C001C8206004C02060088400A00139\n"
-+"S3159801F834C020600C80A0A03404BFFFF98328A004DB\n"
-+"S3159801F844C020E3508600E350C820E004C200E004D7\n"
-+"S3159801F8540500800082104002C220E004C020E0081E\n"
-+"S3159801F8648213E1D8C020E00CC02060108143C00007\n"
-+"S3159801F874C200000003101004C403E1D8C420601028\n"
-+"S3159801F884DE03A00481C3E0089C23BFF09C03BFD088\n"
-+"S3159801F894FE23A01CBE23BFD0DE23A020E023A024F0\n"
-+"S3159801F8A40326007EA01061D884022360D02061D8F3\n"
-+"S3159801F8B4D024200CD02420087FFFFFD2C42420040E\n"
-+"S3159801F8C4D00420049C07FFD0FE03A01CDE03A020CD\n"
-+"S3159801F8D4E003A02481C3E0089C23BFD09C03BFF016\n"
-+"S3159801F8E4DE23A0048202400982004009832860022B\n"
-+"S3159801F8F4860200010526007E8600E0041926007E0C\n"
-+"S3159801F9049A1020000326007ED020A1F4D22061F01B\n"
-+"S3159801F9148608FFFC80A340091680000FC02321ECBA\n"
-+"S3159801F9249E1020008810200084010008C621000832\n"
-+"S3159801F934DE20A0089A036001C020A0048600E04A4C\n"
-+"S3159801F9448801200C80A3400906BFFFF89E10000287\n"
-+"S3159801F954C42321EC90100003DE03A00481C3E008BC\n"
-+"S3099801F9649C23BFF092\n"
-+"S30D9801F968FFC007FF0000FFFF35\n"
-+"S7059801E00081\n";
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/leon.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/leon.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/leon.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/leon.h 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,36 @@
-+/*
-+ * linux/arch/arm/mach-oxnas/leon.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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
-+ */
-+#ifdef CONFIG_SUPPORT_LEON
-+
-+#if !defined(__LEON_H__)
-+#define __LEON_H__
-+
-+/**
-+ * Load the LEON's program image into the memory as defined by the s-records
-+ * holding the LEON program image, and begin execution at the start address
-+ * defined by the s-records
-+ */
-+extern void init_copro(const s8 *srec, unsigned long arg);
-+
-+extern void shutdown_copro(void);
-+
-+#endif // #if !defined(__LEON_H__)
-+#endif // CONFIG_SUPPORT_LEON
-+
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/memory.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/memory.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/memory.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/memory.h 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,107 @@
-+/*
-+ * linux/include/asm-arm/arch-oxnas/memory.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.
-+ */
-+
-+#ifndef __ASM_ARCH_MEMORY_H
-+#define __ASM_ARCH_MEMORY_H
-+
-+/* Max. size of each memory node */
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+#define NODE_MAX_MEM_SHIFT (26) /* 64MB*/
-+#elif defined (CONFIG_OXNAS_VERSION_0X810)
-+#define NODE_MAX_MEM_SHIFT (28) /* 256MB */
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X800
-+#define MEM_MAP_ALIAS_SHIFT 28
-+#elif defined (CONFIG_OXNAS_VERSION_0X810)
-+#define MEM_MAP_ALIAS_SHIFT 30
-+#endif // CONFIG_OXNAS_VERSION_0X800
-+
-+/* All current OXNAS versions have two memory nodes; SDRAM followed contiguously
-+ * by SRAM */
-+#define SDRAM_PA (0x48000000)
-+#define SDRAM_SIZE (1UL << (NODE_MAX_MEM_SHIFT))
-+#define SRAM_PA ((SDRAM_PA) + (SDRAM_SIZE))
-+
-+/* Only a portion of the SRAM may be available for the use of Linux */
-+#define SRAM_SIZE (CONFIG_SRAM_NUM_PAGES * PAGE_SIZE)
-+
-+#define SDRAM_END (SDRAM_PA + SDRAM_SIZE - 1)
-+#define SRAM_END (SRAM_PA + SRAM_SIZE - 1)
-+
-+#define PHYS_OFFSET SDRAM_PA
-+#define PAGE_OFFSET 0xC0000000
-+
-+#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
-+#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
-+
-+#define __virt_to_bus(x) __virt_to_phys(x)
-+#define __bus_to_virt(x) __phys_to_virt(x)
-+
-+#ifdef CONFIG_DISCONTIGMEM
-+/*
-+ * Memory map aliased every 1GByte, i.e. top 2 bits are ignored.
-+ *
-+ * Currently (0X800) we have:
-+ *
-+ * Start of physical memory: 0x08000000
-+ * 0x48000000 - alias
-+ * 0x88000000 - alias
-+ * 0xC8000000 - alias
-+ *
-+ * Node 0 SDRAM: 0x08000000 - 0x09FFFFFF 32MB populated
-+ * : 0x48000000 - alias
-+ * : 0x88000000 - alias
-+ * : 0xC8000000 - alias
-+ *
-+ * Node 1 SRAM : 0x0C000000 - 0x00008000 32KB populated
-+ * : 0x4C000000 - alias
-+ * : 0x8C000000 - alias
-+ * : 0xCC000000 - alias
-+ *
-+ * It will be assumed that no single memory node can be larger than
-+ * (1 << NODE_MAX_MEM_SIZE) and that nodes will be contiguous, although
-+ * individual nodes may not be fully populated
-+ */
-+
-+/*
-+ * Given a kernel address, find the home node of the underlying memory.
-+ */
-+#define KVADDR_TO_NID(addr) (((unsigned long)(addr) - PAGE_OFFSET) >> NODE_MAX_MEM_SHIFT)
-+
-+/*
-+ * Given a page frame number, convert it to a node id.
-+ */
-+#define PFN_TO_NID(pfn) (((pfn) - PHYS_PFN_OFFSET) >> (NODE_MAX_MEM_SHIFT - PAGE_SHIFT))
-+
-+/*
-+ * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
-+ * and return the mem_map of that node.
-+ */
-+#define ADDR_TO_MAPBASE(kaddr) NODE_MEM_MAP(KVADDR_TO_NID(kaddr))
-+
-+/*
-+ * Given a page frame number, find the owning node of the memory
-+ * and return the mem_map of that node.
-+ */
-+#define PFN_TO_MAPBASE(pfn) NODE_MEM_MAP(PFN_TO_NID(pfn))
-+
-+/*
-+ * Given a kaddr, LOCAL_MAP_NR finds the owning node of the memory
-+ * and returns the index corresponding to the appropriate page in the
-+ * node's mem_map.
-+ */
-+#define LOCAL_MAP_NR(addr) (((unsigned long)(addr) & ((1 << NODE_MAX_MEM_SHIFT) - 1)) >> PAGE_SHIFT)
-+
-+#else
-+
-+#define PFN_TO_NID(addr) (0)
-+
-+#endif
-+
-+#endif // __ASM_ARCH_MEMORY_H
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/ox810sata.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/ox810sata.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/ox810sata.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/ox810sata.h 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,162 @@
-+/*
-+ * linux/include/asm-arm/arch-oxnas/sata.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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
-+ *
-+ * Definitions for using the SATA core in the ox800
-+ */
-+
-+#ifndef __ASM_ARCH_SATA_H__
-+#define __ASM_ARCH_SATA_H__
-+
-+/* number of ports per interface */
-+#define OX810SATA_MAX_PORTS 1
-+
-+
-+/** sata host port register offsets */
-+#define OX810SATA_ORB1 (0x00 / sizeof(u32))
-+#define OX810SATA_ORB2 (0x04 / sizeof(u32))
-+#define OX810SATA_ORB3 (0x08 / sizeof(u32))
-+#define OX810SATA_ORB4 (0x0C / sizeof(u32))
-+#define OX810SATA_ORB5 (0x10 / sizeof(u32))
-+
-+#define OX810SATA_MASTER_STATUS (0x10 / sizeof(u32))
-+#define OX810SATA_FIS_CTRL (0x18 / sizeof(u32))
-+#define OX810SATA_FIS_DATA (0x1C / sizeof(u32))
-+
-+#define OX810SATA_INT_STATUS (0x30 / sizeof(u32))
-+#define OX810SATA_INT_CLEAR (0x30 / sizeof(u32))
-+#define OX810SATA_INT_ENABLE (0x34 / sizeof(u32))
-+#define OX810SATA_INT_DISABLE (0x38 / sizeof(u32))
-+#define OX810SATA_VERSION (0x3C / sizeof(u32))
-+#define OX810SATA_SATA_CONTROL (0x5C / sizeof(u32))
-+#define OX810SATA_SATA_COMMAND (0x60 / sizeof(u32))
-+#define OX810SATA_HID_FEATURES (0x64 / sizeof(u32))
-+#define OX810SATA_PORT_CONTROL (0x68 / sizeof(u32))
-+#define OX810SATA_DRIVE_CONTROL (0x6C / sizeof(u32))
-+
-+/** These registers allow access to the link layer registers
-+that reside in a different clock domain to the processor bus */
-+#define OX810SATA_LINK_DATA (0x70 / sizeof(u32))
-+#define OX810SATA_LINK_RD_ADDR (0x74 / sizeof(u32))
-+#define OX810SATA_LINK_WR_ADDR (0x78 / sizeof(u32))
-+#define OX810SATA_LINK_CONTROL (0x7C / sizeof(u32))
-+
-+/** Backup registers contain a copy of the command sent to the disk */
-+#define OX810SATA_BACKUP1 (0xB0 / sizeof(u32))
-+#define OX810SATA_BACKUP2 (0xB4 / sizeof(u32))
-+#define OX810SATA_BACKUP3 (0xB8 / sizeof(u32))
-+#define OX810SATA_BACKUP4 (0xBC / sizeof(u32))
-+
-+/**
-+ * commands to issue in the master status to tell it to move shadow
-+ * registers to the actual device
-+ */
-+#define SATA_OPCODE_MASK 0x00000007
-+#define CMD_WRITE_TO_ORB_REGS_NO_COMMAND 0x4
-+#define CMD_WRITE_TO_ORB_REGS 0x2
-+#define CMD_SYNC_ESCAPE 0x7
-+#define CMD_CORE_BUSY (1 << 7)
-+
-+/** interrupt bits */
-+#define OX810SATA_INT_END_OF_CMD (1 << 0)
-+#define OX810SATA_INT_LINK_SERROR (1 << 1)
-+#define OX810SATA_INT_ERROR (1 << 2)
-+#define OX810SATA_INT_LINK_IRQ (1 << 3)
-+#define OX810SATA_INT_REG_ACCESS_ERR (1 << 7)
-+#define OX810SATA_INT_BIST_FIS (1 << 11)
-+#define OX810SATA_INT_MASKABLE (OX810SATA_INT_END_OF_CMD |\
-+ OX810SATA_INT_LINK_SERROR |\
-+ OX810SATA_INT_ERROR |\
-+ OX810SATA_INT_LINK_IRQ |\
-+ OX810SATA_INT_REG_ACCESS_ERR |\
-+ OX810SATA_INT_BIST_FIS )
-+
-+#define OX810SATA_INT_WANT (OX810SATA_INT_END_OF_CMD |\
-+ OX810SATA_INT_LINK_SERROR |\
-+ OX810SATA_INT_REG_ACCESS_ERR |\
-+ OX810SATA_INT_ERROR )
-+
-+/** raw interrupt bits, unmaskable, but do not generate interrupts */
-+#define OX810SATA_RAW_END_OF_CMD (OX810SATA_INT_END_OF_CMD << 16)
-+#define OX810SATA_RAW_LINK_SERROR (OX810SATA_INT_LINK_SERROR << 16)
-+#define OX810SATA_RAW_ERROR (OX810SATA_INT_ERROR << 16)
-+#define OX810SATA_RAW_LINK_IRQ (OX810SATA_INT_LINK_IRQ << 16)
-+#define OX810SATA_RAW_REG_ACCESS_ERR (OX810SATA_INT_REG_ACCESS_ERR << 16)
-+#define OX810SATA_RAW_BIST_FIS (OX810SATA_INT_BIST_FIS << 16)
-+
-+/** SATA core register offsets */
-+#define OX810SATA_DM_DEBUG1 ( SATACORE_REGS_BASE + 0x000 )
-+#define OX810SATA_RAID_SET ( SATACORE_REGS_BASE + 0x004 )
-+#define OX810SATA_DM_DEBUG2 ( SATACORE_REGS_BASE + 0x008 )
-+#define OX810SATA_CORE_ISR ( SATACORE_REGS_BASE + 0x030 )
-+#define OX810SATA_CORE_IES ( SATACORE_REGS_BASE + 0x034 )
-+#define OX810SATA_CORE_IEC ( SATACORE_REGS_BASE + 0x038 )
-+#define OX810SATA_DEVICE_CONTROL ( SATACORE_REGS_BASE + 0x068 )
-+#define OX810SATA_EXCESS ( SATACORE_REGS_BASE + 0x06C )
-+#define OX810SATA_IDLE_STATUS ( SATACORE_REGS_BASE + 0x07C )
-+#define OX810SATA_RAID_CONTROL ( SATACORE_REGS_BASE + 0x090 )
-+
-+/** sata core control register bits */
-+#define OX810SATA_SCTL_CLR_ERR (0x00003016)
-+
-+/* Interrupts direct from the ports */
-+#define OX810SATA_NORMAL_INTS_WANTED (0x00000003)
-+
-+/* Interrupts from the RAID controller only */
-+#define OX810SATA_RAID_INTS_WANTED (0x00008000)
-+
-+/* The bits in the OX810SATA_IDLE_STATUS that, when set indicate an idle core */
-+#define OX810SATA_IDLE_CORES ((1 << 18) | (1 << 19))
-+
-+/** Device Control register bits */
-+#define OX810SATA_DEVICE_CONTROL_ABORT (1 << 2)
-+#define OX810SATA_DEVICE_CONTROL_PAD (1 << 3)
-+#define OX810SATA_DEVICE_CONTROL_PADPAT (1 << 16)
-+
-+/** ORB4 register bits */
-+#define OX810SATA_ORB4_SRST (1 << 26)
-+
-+/** standard HW raid flags */
-+#define OXNASSATA_NOTRAID 3
-+#define OXNASSATA_RAID1 1
-+#define OXNASSATA_RAID0 0
-+#define OXNASSATA_RAID_TWODISKS 3
-+
-+/**
-+ * variables to write to the device control register to set the current device
-+ * ie, master or slave
-+ */
-+#define OX810SATA_DR_CON_48 2
-+#define OX810SATA_DR_CON_28 0
-+
-+/** A ficticious device id used for matching device and driver */
-+#define OX810SATA_DEVICEID 0x00100002
-+
-+/** The different Oxsemi SATA core version numbers */
-+#define OX810SATA_CORE_VERSION 0x1f2
-+
-+/** Occasionally we get interrupts, even though there is no outstanding command,
-+these can be caused by dodgy SATA cables, this is a divider for reporting these
-+interrupts */
-+#define OX810SATA_NO_CMD_ERROR_RPT_COUNT 8
-+
-+extern int oxnassata_RAID_faults( void );
-+extern int oxnassata_get_port_no(struct request_queue* );
-+extern int oxnassata_LBA_schemes_compatible( void );
-+
-+#endif /* #if !defined(__ASM_ARCH_SATA_H__) */
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/sata.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/sata.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/sata.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/sata.h 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,181 @@
-+/*
-+ * linux/include/asm-arm/arch-oxnas/sata.h
-+ *
-+ * Copyright (C) 2005 Oxford Semiconductor Ltd
-+ *
-+ * 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
-+ *
-+ * Definitions for using the SATA core in the ox800
-+ */
-+
-+#ifndef __ASM_ARCH_SATA_H__
-+#define __ASM_ARCH_SATA_H__
-+
-+#include <linux/blkdev.h>
-+
-+/* number of ports per interface */
-+#define OX800SATA_MAX_PORTS 1
-+
-+
-+/** ata core register offsets */
-+#define OX800SATA_ORB1 (0x00 / sizeof(u32))
-+#define OX800SATA_ORB2 (0x04 / sizeof(u32))
-+#define OX800SATA_ORB3 (0x08 / sizeof(u32))
-+#define OX800SATA_ORB4 (0x0C / sizeof(u32))
-+#define OX800SATA_ORB5 (0x10 / sizeof(u32))
-+
-+#define OX800SATA_MASTER_STATUS (0x10 / sizeof(u32))
-+#define OX800SATA_DEVICE_CTRL (0x18 / sizeof(u32))
-+#define OX800SATA_REG_ACCESS (0x2c / sizeof(u32))
-+#define OX800SATA_INT_STATUS (0x30 / sizeof(u32))
-+#define OX800SATA_INT_CLEAR (0x30 / sizeof(u32))
-+#define OX800SATA_INT_ENABLE (0x34 / sizeof(u32))
-+#define OX800SATA_INT_DISABLE (0x38 / sizeof(u32))
-+#define OX800SATA_VERSION (0x3C / sizeof(u32))
-+#define OX800SATA_SATA_CONTROL (0x5C / sizeof(u32))
-+#define OX800SATA_SATA_COMMAND (0x60 / sizeof(u32))
-+#define OX800SATA_DEVICE_SELECT (0x64 / sizeof(u32))
-+#define OX800SATA_DEVICE_CONTROL (0x68 / sizeof(u32))
-+#define OX800SATA_DRIVE_CONTROL (0x6C / sizeof(u32))
-+
-+/** ata core registers that only work on port 0 */
-+#define OX800SATA_BURST_BUFFER (0x1C / sizeof(u32))
-+#define OX800SATA_BURST_CONTROL (0x48 / sizeof(u32))
-+#define OX800SATA_RAID_CONTROL (0x70 / sizeof(u32))
-+
-+
-+
-+
-+/** These registers allow access to the link layer registers
-+that reside in a different clock domain to the processor bus */
-+#define OX800SATA_LINK_DATA (0x00000000)
-+#define OX800SATA_LINK_RD_ADDR (0x00000001)
-+#define OX800SATA_LINK_WR_ADDR (0x00000002)
-+#define OX800SATA_LINK_CONTROL (0x00000003)
-+
-+/**
-+ * commands to issue in the master status to tell it to move shhadow
-+ * registers to the actual device
-+ */
-+#define OX800SATA_MASTER_STATUS_WRITEOP 6 | (1 << 31)
-+#define OX800SATA_MASTER_STATUS_READOP 5 | (1 << 31) | (1 << 29)
-+#define OX800SATA_MASTER_STATUS_ORBWRITEOP 1 | (1 << 31)
-+#define OX800SATA_MASTER_STATUS_ORBWRITE_RUN 2 | (1 << 31) | (1 << 29)
-+#define OX800SATA_MASTER_STATUS_READY 64
-+#define OX800SATA_MASTER_STATUS_BUSY 128
-+
-+#define OX800SATA_ORB2_SECTORS_MASK (0x0000ffff)
-+
-+#define SATA_OPCODE_MASK 0x00000003
-+#define CMD_WRITE_TO_ORB_REGS_NO_COMMAND 0x01
-+#define CMD_WRITE_TO_ORB_REGS 0x02
-+#define CMD_READ_ALL_REGISTERS 0x03
-+#define CMD_READ_STATUS_REG 0x04
-+#define CMD_CORE_BUSY (1 << 7)
-+
-+/** interrupt bits */
-+#define OX800SATA_INT_END_OF_CMD (1 << 0)
-+#define OX800SATA_INT_END_OF_DATA_CMD (1 << 1)
-+#define OX800SATA_INT_ERROR (1 << 2)
-+#define OX800SATA_INT_FIFO_EMPTY (1 << 3)
-+#define OX800SATA_INT_FIFO_FULL (1 << 4)
-+#define OX800SATA_INT_END_OF_TRANSF (1 << 5)
-+#define OX800SATA_INT_MASKABLE (OX800SATA_INT_END_OF_CMD |\
-+ OX800SATA_INT_END_OF_DATA_CMD |\
-+ OX800SATA_INT_ERROR |\
-+ OX800SATA_INT_FIFO_EMPTY |\
-+ OX800SATA_INT_FIFO_FULL |\
-+ OX800SATA_INT_END_OF_TRANSF )
-+
-+/** raw interrupt bits, unmaskable, but do not generate interrupts */
-+#define OX800SATA_RAW_END_OF_CMD (1 << 8)
-+#define OX800SATA_RAW_END_OF_DATA_CMD (1 << 9)
-+#define OX800SATA_RAW_ERROR (1 << 10)
-+#define OX800SATA_RAW_FIFO_EMPTY (1 << 11)
-+#define OX800SATA_RAW_FIFO_FULL (1 << 12)
-+#define OX800SATA_RAW_END_OF_TRANSF (1 << 13)
-+
-+/** burst buffer control bits */
-+#define OX800SATA_BBC_FORCE_EOT (1 << 0)
-+#define OX800SATA_BBC_DIRECTION (1 << 2)
-+#define OX800SATA_BBC_FIFO_DIS (1 << 4)
-+#define OX800SATA_BBC_DREQ_DIS (1 << 5)
-+#define OX800SATA_BBC_DREQ (1 << 6)
-+
-+/** sata control register bits */
-+#define OX800SATA_SCTL_RESET (1 << 0)
-+#define OX800SATA_SCTL_ABORT (1 << 2)
-+
-+/** Device Control register bits */
-+#define OX800SATA_DEVICE_CONTROL_ABORT (1 << 2)
-+
-+/** ORB4 register bits */
-+#define OX800SATA_ORB4_SRST (1 << 26)
-+
-+/** SATA control transport state machine mask */
-+#define OX800SATA_SATA_CONTROL_TRANS_MASK (0x0000001e)
-+#define OX800SATA_TRANS_CHECKTYPE (0x00000008)
-+#define OX800SATA_TRANS_PIOITRANS (0x00000018)
-+#define OX800SATA_TRANS_PIOOTRANS (0x0000001C)
-+
-+/** RAID control bit definitions */
-+#define OX800SATA_RAID_SPAN_EN (1 << 0)
-+#define OX800SATA_RAID_STRI_EN (1 << 1)
-+#define OX800SATA_RAID_STRI16 (1 << 2)
-+#define OX800SATA_RAID_STRI32 (1 << 3)
-+#define OX800SATA_RAID_STRI64 (1 << 4)
-+#define OX800SATA_RAID_STRI128 (1 << 5)
-+#define OX800SATA_RAID_STRI256 (1 << 6)
-+#define OX800SATA_RAID_STRI512 (1 << 7)
-+#define OX800SATA_RAID_STRI1M (1 << 8)
-+#define OX800SATA_RAID_STRI2M (1 << 9)
-+#define OX800SATA_RAID_STRI_TEST (1 << 10)
-+#define OX800SATA_RAID_XSOFF2 (0 << 11)
-+#define OX800SATA_RAID_XSOFF4 (1 << 11)
-+#define OX800SATA_RAID_XSOFF6 (2 << 11)
-+#define OX800SATA_RAID_XSOFF8 (3 << 11)
-+#define OX800SATA_RAID_LOOP_BK (1 << 12)
-+#define OX800SATA_RAID_MIR0 (0 << 13)
-+#define OX800SATA_RAID_MIR1 (1 << 13)
-+#define OX800SATA_RAID_MIRALT (2 << 13)
-+#define OX800SATA_RAID_MIR_EN (1 << 16)
-+#define OX800SATA_RAID_OVERLAP (1 << 23)
-+
-+/* standard HW raid flags */
-+#define OXNASSATA_RAID1 (OX800SATA_RAID_MIR0 | OX800SATA_RAID_MIR_EN | OX800SATA_RAID_OVERLAP )
-+#define OXNASSATA_RAID0 (OX800SATA_RAID_OVERLAP | OX800SATA_RAID_STRI_EN )
-+/**
-+ * variables to write to the device control register to set the current device
-+ * ie, master or slave
-+ */
-+#define OX800SATA_DEVICE_CONTROL_MASTER 0
-+#define OX800SATA_DEVICE_CONTROL_SLAVE 1
-+
-+/** A ficticious device id used for matching device and driver */
-+#define OX800SATA_DEVICEID 0x00100001
-+
-+/** The different Oxsemi SATA core version numbers */
-+#define OX800SATA_CORE_VERSION 0xf0
-+
-+/** Occasionally we get interrupts, even though there is no outstanding command,
-+these can be caused by dodgy SATA cables, this is a divider for reporting these
-+interrupts */
-+#define OX800SATA_NO_CMD_ERROR_RPT_COUNT 8
-+
-+extern int oxnassata_RAID_faults( void );
-+extern int oxnassata_get_port_no(struct request_queue* );
-+extern int oxnassata_LBA_schemes_compatible( void );
-+
-+#endif /* #if !defined(__ASM_ARCH_SATA_H__) */
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/system.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/system.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/system.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/system.h 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,103 @@
-+/* linux/include/asm-arm/arch-oxnas/system.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.
-+ */
-+
-+#ifndef __ASM_ARCH_SYSTEM_H
-+#define __ASM_ARCH_SYSTEM_H
-+
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+
-+extern void sata_power_off(void);
-+extern int oxnas_global_invert_leds;
-+
-+#if defined(CONFIG_LEON_POWER_BUTTON_MONITOR) || defined(CONFIG_LEON_POWER_BUTTON_MONITOR_MODULE)
-+#include <asm/arch/leon.h>
-+#include <asm/arch/leon-power-button-prog.h>
-+#endif // CONFIG_LEON_POWER_BUTTON_MONITOR
-+
-+static inline void arch_idle(void)
-+{
-+ /*
-+ * This should do all the clock switching
-+ * and wait for interrupt tricks
-+ */
-+ cpu_do_idle();
-+}
-+
-+static void disable_gmac(void)
-+{
-+ writel((1UL << SYS_CTRL_RSTEN_MAC_BIT), SYS_CTRL_RSTEN_SET_CTRL);
-+ writel((1UL << SYS_CTRL_CKEN_MAC_BIT), SYS_CTRL_CKEN_CLR_CTRL);
-+}
-+
-+static void arch_poweroff(void)
-+{
-+ disable_gmac();
-+
-+#if defined(CONFIG_LEON_POWER_BUTTON_MONITOR) || defined(CONFIG_LEON_POWER_BUTTON_MONITOR_MODULE)
-+ // Load CoPro program and start it running
-+ init_copro(leon_srec, oxnas_global_invert_leds);
-+#endif // CONFIG_LEON_POWER_BUTTON_MONITOR
-+
-+ // Turn of power to SATA disk if possible
-+ sata_power_off();
-+}
-+
-+static void arch_reset(char mode)
-+{
-+ // Assert reset to cores as per power on defaults
-+ writel((1UL << SYS_CTRL_RSTEN_COPRO_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_USBHS_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_USBHSPHY_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_MAC_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_PCI_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_DMA_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_DPE_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_SATA_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_STATIC_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_UART1_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_UART2_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_MISC_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_I2S_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_AHB_MON_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_UART3_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_UART4_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_SGDMA_BIT), SYS_CTRL_RSTEN_SET_CTRL);
-+
-+ // Release reset to cores as per power on defaults
-+ writel((1UL << SYS_CTRL_RSTEN_GPIO_BIT), SYS_CTRL_RSTEN_CLR_CTRL);
-+
-+ // Disable clocks to cores as per power-on defaults
-+ writel((1UL << SYS_CTRL_CKEN_COPRO_BIT) |
-+ (1UL << SYS_CTRL_CKEN_DMA_BIT) |
-+ (1UL << SYS_CTRL_CKEN_DPE_BIT) |
-+ (1UL << SYS_CTRL_CKEN_SATA_BIT) |
-+ (1UL << SYS_CTRL_CKEN_I2S_BIT) |
-+ (1UL << SYS_CTRL_CKEN_USBHS_BIT) |
-+ (1UL << SYS_CTRL_CKEN_MAC_BIT) |
-+ (1UL << SYS_CTRL_CKEN_STATIC_BIT), SYS_CTRL_CKEN_CLR_CTRL);
-+
-+ // Enable clocks to cores as per power-on defaults
-+ writel((1UL << SYS_CTRL_CKEN_PCI_BIT), SYS_CTRL_CKEN_SET_CTRL);
-+
-+ // Set sys-control pin mux'ing as per power-on defaults
-+ writel(0x800UL, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
-+ writel(0x0UL, SYS_CTRL_GPIO_PRIMSEL_CTRL_1);
-+ writel(0x0UL, SYS_CTRL_GPIO_SECSEL_CTRL_0);
-+ writel(0x0UL, SYS_CTRL_GPIO_SECSEL_CTRL_1);
-+ writel(0x0UL, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
-+ writel(0x0UL, SYS_CTRL_GPIO_TERTSEL_CTRL_1);
-+
-+ // No need to save any state, as the ROM loader can determine whether reset
-+ // is due to power cycling or programatic action, just hit the (self-
-+ // clearing) CPU reset bit of the block reset register
-+ writel(1UL << SYS_CTRL_RSTEN_ARM_BIT, SYS_CTRL_RSTEN_SET_CTRL);
-+}
-+
-+#endif // __ASM_ARCH_SYSTEM_H
-+
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/taco.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/taco.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/taco.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/taco.h 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,227 @@
-+/*
-+ * linux/include/asm-arm/arch-oxnas/tacho.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.
-+ */
-+
-+#ifndef __ASM_ARM_ARCH_TACHO_H
-+#define __ASM_ARM_ARCH_TACHO_H
-+
-+#include "hardware.h"
-+
-+/* Routines ----------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+
-+/**
-+ * DumpTachoRegisters is a debug function used to inspect hte tacho registers.
-+ */
-+extern void DumpTachoRegisters(void);
-+
-+
-+/**
-+ * GetTemperature will read the thermistor register and convert the value to
-+ * kelvin.
-+ * @return an int that represents the thermister temperature in Kelvin, or a
-+ * negative value in the case of error.
-+ */
-+extern int GetTemperature(void);
-+
-+
-+/**
-+ * GetFanRPM will read the fan tacho register and convert the value to
-+ * RPM.
-+ * @return an int that represents the fan speed in RPM, or a
-+ * negative value in the case of error.
-+ */
-+extern int GetFanRPM(void);
-+
-+#ifdef CONFIG_OXNAS_VERSION_0X810
-+#define OXNAS_TACHO_Ox810
-+#endif
-+
-+
-+#ifndef OXNAS_TACHO_Ox810
-+#define DEGREES_C_0 273
-+#define TACHO_TARGET_THERM_FREQ_HZ 1000000
-+#define TACHO_CORE_THERM_DIVIDER_VALUE (((NOMINAL_SYSCLK / TACHO_TARGET_THERM_FREQ_HZ) - 1))
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+#define TACHO_TARGET_CORE_FREQ_HZ 128000
-+#define TACHO_CORE_TACHO_DIVIDER_VALUE (((NOMINAL_SYSCLK / TACHO_TARGET_CORE_FREQ_HZ) - 1))
-+
-+#ifndef OXNAS_TACHO_Ox810
-+#define TACHO_FAN_SPEED_DIVIDER (64)
-+#endif /*OXNAS_TACHO_Ox810 */
-+
-+#define SECONDARY_FUNCTION_ENABLE_FAN_PWM2 8
-+#define PRIMARY_FUNCTION_ENABLE_FAN_TEMP 29
-+#define PRIMARY_FUNCTION_ENABLE_FAN_TACHO 30
-+
-+#ifdef OXNAS_TACHO_Ox810
-+#define TEMP_TACHO_PULLUP_CTRL_VALUE 0x20000000
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+
-+// 256kHz with 50MHz pclk (reset value)
-+#ifdef OXNAS_TACHO_Ox810
-+#define PWM_CORE_CLK_DIVIDER_VALUE (130)
-+#else /* OXNAS_TACHO_Ox810 */
-+#define PWM_CORE_CLK_DIVIDER_VALUE (194)
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+/* Registers ---------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+/* -------------------------------------------------------------------------- */
-+
-+/* FAN Speed Counter ----------------------------------- */
-+
-+#ifdef OXNAS_TACHO_Ox810
-+
-+#define TACHO_FAN_SPEED_COUNTER (FAN_MON_BASE + 0x00)
-+ // 31:17 - RO - Unused (0x00)
-+ // 16 - R0 - Fan Count Valid - used in one shot mode
-+ // 15:10 - R0 - Unused
-+ // 9:0 - RO - Fan counter value. (See DD for conversion to rpm)
-+ #define TACHO_FAN_SPEED_COUNTER_FAN_COUNT 0
-+ #define TACHO_FAN_SPEED_COUNTER_COUNT_VALID 16
-+
-+#else /* OXNAS_TACHO_Ox810 */
-+
-+#define TACHO_FAN_SPEED_COUNTER (FAN_MON_BASE + 0x00)
-+ // 31:10 - RO - Unused (0x00)
-+ // 9:0 - RO - Fan counter value. (See DD for conversion to rpm)
-+ #define TACHO_FAN_SPEED_COUNTER_FAN_COUNT 0
-+
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+ #define TACHO_FAN_SPEED_COUNTER_MASK 1023
-+
-+/* Thermistor RC Counter ------------------------------- */
-+#define TACHO_THERMISTOR_RC_COUNTER (FAN_MON_BASE + 0x04)
-+ // 31:10 - RO - Unused (0x00)
-+ // 9:0 - RO - Thermistor counter value (See DD for conversion to temperature)
-+ #define TACHO_THERMISTOR_RC_COUNTER_THERM_COUNT 0
-+
-+ #define TACHO_THERMISTOR_RC_COUNTER_MASK 1023
-+
-+
-+/* Thermistor Control ---------------------------------- */
-+#define TACHO_THERMISTOR_CONTROL (FAN_MON_BASE + 0x08)
-+ // 31:2 - RO - Unused (0x00)
-+ // 1:1 - R0 � THERM_COUNT value is valid
-+ // 0:0 - RW - Set to 1 to enable thermistor PWM output
-+ #define TACHO_THERMISTOR_CONTROL_THERM_VALID 1
-+ #define TACHO_THERMISTOR_CONTROL_THERM_ENABLE 0
-+
-+
-+/* Clock divider ---------------------------- */
-+#define TACHO_CLOCK_DIVIDER (FAN_MON_BASE + 0x0C)
-+ // 31:10 - RO - Unused (0x00)
-+ // 0:9 - RW - set PWM effective clock frequency to a division of pclk (0x030C )
-+ // 0000 � pclk divided by 1 (=pclk)
-+ // 0001 - pclk divided by 2
-+ // 0780 - ~128kHz with 100MHz pclk (reset value)
-+ // 1023 - pclk divided by 1024
-+ #define TACHO_CLOCK_DIVIDER_PWM_DIVIDER 0
-+ #define TACHO_CLOCK_DIVIDER_MASK 1023
-+
-+
-+/* New hardware registers added for 810 */
-+#ifdef OXNAS_TACHO_Ox810
-+
-+/* Fan Speed Control ..........................*/
-+#define TACHO_FAN_SPEED_CONTROL (FAN_MON_BASE + 0x10)
-+ // 31:N+16 - R0 - Unused (0x0000)
-+ // N+15:16 - RW - Select PWM which controls FAN speed
-+ // 15:1 - Unused 0
-+ // 0 - RW - Fan Count mode 0 - Continuous running mode 1 - One shot mode
-+ #define TACHO_FAN_SPEED_CONTROL_PWM_ENABLE_BASE 16
-+ #define TACHO_FAN_SPEED_CONTROL_PWM_USED 2
-+ #define TACHO_FAN_SPEED_CONTROL_FAN_COUNT_MODE 0
-+
-+
-+/* Fan One Shot Control .........................*/
-+#define TACHO_FAN_ONE_SHOT_CONTROL (FAN_MON_BASE + 0x14)
-+ // 31:1 - R - Unused
-+ // 0 - W - Start One-shot - Tacho - Self Clearing bit
-+ #define TACHO_FAN_ONE_SHOT_CONTROL_START 0
-+
-+
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+/* PWM SECTION ------------------------------ */
-+
-+// 0x00 Channel 0 PWM data
-+// 7:0 R/W 0x00
-+// 31:8 Unused R 0x00000 Unused
-+#define PWM_DATA_0 (PWM_BASE+0x00)
-+ // value 0 � Output aways lo
-+ // value 1 � hi for 1 clock, lo for 255
-+ // . . .
-+ // value 127 � 50:50 hi/lo
-+ // . . .
-+ // value 255 � hi for 255 clocks, lo for 1
-+
-+// 0x04 Channel 1 PWM data
-+// 7:0 R/W 0x00
-+// 31:8 Unused R 0x00000 Unused
-+#define PWM_DATA_1 (PWM_BASE+0x04)
-+ // value 0 � Output aways lo
-+ // value 1 � hi for 1 clock, lo for 255
-+ // . . .
-+ // value 127 � 50:50 hi/lo
-+ // . . .
-+ // value 255 � hi for 255 clocks, lo for 1
-+
-+// 0x08 Channel 2 PWM data
-+// 7:0 R/W 0x00
-+// 31:8 Unused R 0x00000 Unused
-+#define PWM_DATA_2 (PWM_BASE+0x08)
-+ // value 0 � Output aways lo
-+ // value 1 � hi for 1 clock, lo for 255
-+ // . . .
-+ // value 127 � 50:50 hi/lo
-+ // . . .
-+ // value 255 � hi for 255 clocks, lo for 1
-+
-+// 0x0C Channel 3 PWM data
-+// 7:0 R/W 0x00
-+// 31:8 Unused R 0x00000 Unused
-+#define PWM_DATA_3 (PWM_BASE+0x0C)
-+ // value 0 � Output aways lo
-+ // value 1 � hi for 1 clock, lo for 255
-+ // . . .
-+ // value 127 � 50:50 hi/lo
-+ // . . .
-+ // value 255 � hi for 255 clocks, lo for 1
-+
-+#ifdef OXNAS_TACHO_Ox810
-+//0x400 PWM Clock Divider
-+// 15:0 R/W 0x00C2
-+// 31:16 Unused R 0x0000 Unused
-+#define PWM_CLOCK_DIVIDER (PWM_BASE+0x400)
-+
-+#else /* OXNAS_TACHO_Ox810 */
-+
-+// 0x10 PWM clock divider
-+// 15:0 R/W 0x00C2
-+// 31:16 Unused R 0x0000 Unused
-+#define PWM_CLOCK_DIVIDER (PWM_BASE+0x10)
-+ // set PWM effective clock frequency to a division of pclk
-+ // value 0 � pclk divided by 1 (=pclk)
-+ // value 1 � pclk divided by 2
-+ // value 194 � 256kHz with 50MHz pclk (reset value)
-+ // . . .
-+ // value 65535 � pclk divided by 65536
-+
-+#endif /* OXNAS_TACHO_Ox810 */
-+
-+#endif // __ASM_ARM_ARCH_TACHO_H
-+
-+/* End oF File */
-+
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/timex.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/timex.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/timex.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/timex.h 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,23 @@
-+/* linux/include/asm-arm/arch-oxnas/timex.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.
-+*/
-+
-+#ifndef __ASM_ARCH_TIMEX_H
-+#define __ASM_ARCH_TIMEX_H
-+
-+#define TIMER_PRESCALE_BIT 2
-+#define TIMER_PRESCALE_1 0
-+#define TIMER_PRESCALE_16 1
-+#define TIMER_PRESCALE_256 2
-+
-+#define TIMER_INPUT_CLOCK CONFIG_NOMINAL_RPSCLK_FREQ
-+#define TIMER_1_PRESCALE_ENUM TIMER_PRESCALE_16
-+#define TIMER_1_PRESCALE_VALUE (1 << (TIMER_1_PRESCALE_ENUM * 4))
-+#define TIMER_1_PRESCALED_CLK (TIMER_INPUT_CLOCK / TIMER_1_PRESCALE_VALUE)
-+
-+#define CLOCK_TICK_RATE (TIMER_1_PRESCALED_CLK)
-+
-+#endif // __ASM_ARCH_TIMEX_H
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/uncompress.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/uncompress.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/uncompress.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/uncompress.h 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,43 @@
-+/* linux/include/asm-arm/arch-oxnas0/uncompress.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.
-+*/
-+
-+#ifndef __ASM_ARCH_UNCOMPRESS_H
-+#define __ASM_ARCH_UNCOMPRESS_H
-+
-+#include <asm/arch/hardware.h>
-+
-+static inline void putc(int c)
-+{
-+#ifdef CONFIG_ARCH_OXNAS_UART1
-+ static volatile unsigned char* uart = (volatile unsigned char*)UART_1_BASE_PA;
-+#elif defined(CONFIG_ARCH_OXNAS_UART2)
-+ static volatile unsigned char* uart = (volatile unsigned char*)UART_2_BASE_PA;
-+#elif defined(CONFIG_ARCH_OXNAS_UART3)
-+ static volatile unsigned char* uart = (volatile unsigned char*)UART_3_BASE_PA;
-+#elif defined(CONFIG_ARCH_OXNAS_UART4)
-+ static volatile unsigned char* uart = (volatile unsigned char*)UART_4_BASE_PA;
-+#else
-+#define NO_UART
-+#endif
-+
-+#ifndef NO_UART
-+ while (!(uart[5] & 0x20)) { /* LSR reg THR empty bit */
-+ barrier();
-+ }
-+ uart[0] = c; /* THR register */
-+#endif // NO_UART
-+}
-+
-+static inline void flush(void)
-+{
-+}
-+
-+#define arch_decomp_setup()
-+
-+#define arch_decomp_wdog()
-+
-+#endif // __ASM_ARCH_UNCOMPRESS_H
-diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/vmalloc.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/vmalloc.h
---- linux-2.6.24/include/asm-arm/arch-oxnas/vmalloc.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/vmalloc.h 2008-06-11 17:45:12.000000000 +0200
-@@ -0,0 +1,29 @@
-+/* linux/include/asm-arm/arch-oxnas/vmalloc.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.
-+ */
-+
-+#ifndef __ASM_ARCH_VMALLOC_H
-+#define __ASM_ARCH_VMALLOC_H
-+
-+/*
-+ * Just any arbitrary offset to the start of the vmalloc VM area: the
-+ * current 8MB value just means that there will be a 8MB "hole" after the
-+ * physical memory until the kernel virtual memory starts. That means that
-+ * any out-of-bounds memory accesses will hopefully be caught.
-+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
-+ * area for the same reason. ;)
-+ */
-+
-+#define VMALLOC_OFFSET (8*1024*1024)
-+/* Fix the VMALLOC start adr from the maximum possible SDRAM adr, so that
-+ * it's possible to have Linux use only part of the available SDRAM without
-+ * vmalloc/ioremap aliasing with the kernel mapping of the entire SDRAM */
-+#define MAX_SDRAM_ADR (__phys_to_virt(SDRAM_PA) + (SDRAM_SIZE))
-+#define VMALLOC_START (((unsigned long)MAX_SDRAM_ADR + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
-+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
-+#define VMALLOC_END (0xE0000000)
-+
-+#endif // __ASM_ARCH_VMALLOC_H
-diff -Nurd linux-2.6.24/include/asm-arm/arch-pxa/pxa-regs.h linux-2.6.24-oxe810/include/asm-arm/arch-pxa/pxa-regs.h
---- linux-2.6.24/include/asm-arm/arch-pxa/pxa-regs.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/arch-pxa/pxa-regs.h 2008-06-11 17:45:03.000000000 +0200
-@@ -1669,6 +1669,7 @@
- #define SSCR1_RSRE (1 << 20) /* Receive Service Request Enable */
- #define SSCR1_TINTE (1 << 19) /* Receiver Time-out Interrupt enable */
- #define SSCR1_PINTE (1 << 18) /* Peripheral Trailing Byte Interupt Enable */
-+#define SSCR1_IFS (1 << 16) /* Invert Frame Signal */
- #define SSCR1_STRF (1 << 15) /* Select FIFO or EFWR */
- #define SSCR1_EFWR (1 << 14) /* Enable FIFO Write/Read */
-
-diff -Nurd linux-2.6.24/include/asm-arm/assembler.h linux-2.6.24-oxe810/include/asm-arm/assembler.h
---- linux-2.6.24/include/asm-arm/assembler.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/assembler.h 2008-06-11 17:45:14.000000000 +0200
-@@ -48,8 +48,10 @@
-
- /*
- * Data preload for architectures that support it
-+ * OXNAS altered to >= 6 from >= 5 as 926 supports pld, but implements it as
-+ * nop, so wastes instruction cycles to include pld support
- */
--#if __LINUX_ARM_ARCH__ >= 5
-+#if __LINUX_ARM_ARCH__ >= 6
- #define PLD(code...) code
- #else
- #define PLD(code...)
-diff -Nurd linux-2.6.24/include/asm-arm/io.h linux-2.6.24-oxe810/include/asm-arm/io.h
---- linux-2.6.24/include/asm-arm/io.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/io.h 2008-06-11 17:45:14.000000000 +0200
-@@ -108,27 +108,24 @@
- *
- * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space.
- */
--#ifdef __io
--#define outb(v,p) __raw_writeb(v,__io(p))
--#define outw(v,p) __raw_writew((__force __u16) \
-- cpu_to_le16(v),__io(p))
--#define outl(v,p) __raw_writel((__force __u32) \
-- cpu_to_le32(v),__io(p))
-+extern unsigned int pciio_read( u32 addr, unsigned int size );
-+extern void pciio_write(unsigned int data, u32 addr, unsigned int size );
-
--#define inb(p) ({ __u8 __v = __raw_readb(__io(p)); __v; })
--#define inw(p) ({ __u16 __v = le16_to_cpu((__force __le16) \
-- __raw_readw(__io(p))); __v; })
--#define inl(p) ({ __u32 __v = le32_to_cpu((__force __le32) \
-- __raw_readl(__io(p))); __v; })
-+extern void outb(unsigned char v, u32 p);
-+extern void outw(unsigned short v, u32 p);
-+extern void outl(unsigned long v, u32 p);
-
--#define outsb(p,d,l) __raw_writesb(__io(p),d,l)
--#define outsw(p,d,l) __raw_writesw(__io(p),d,l)
--#define outsl(p,d,l) __raw_writesl(__io(p),d,l)
-+extern unsigned char inb(u32 p);
-+extern unsigned short inw(u32 p);
-+extern unsigned long inl(u32 p);
-
--#define insb(p,d,l) __raw_readsb(__io(p),d,l)
--#define insw(p,d,l) __raw_readsw(__io(p),d,l)
--#define insl(p,d,l) __raw_readsl(__io(p),d,l)
--#endif
-+extern void outsb(u32 p, unsigned char * from, u32 len);
-+extern void outsw(u32 p, unsigned short * from, u32 len);
-+extern void outsl(u32 p, unsigned long * from, u32 len);
-+
-+extern void insb(u32 p, unsigned char * to, u32 len);
-+extern void insw(u32 p, unsigned short * to, u32 len);
-+extern void insl(u32 p, unsigned long * to, u32 len);
-
- #define outb_p(val,port) outb((val),(port))
- #define outw_p(val,port) outw((val),(port))
-diff -Nurd linux-2.6.24/include/asm-arm/uaccess.h linux-2.6.24-oxe810/include/asm-arm/uaccess.h
---- linux-2.6.24/include/asm-arm/uaccess.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/uaccess.h 2008-06-11 17:45:14.000000000 +0200
-@@ -383,9 +383,30 @@
-
-
- #ifdef CONFIG_MMU
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+extern unsigned long __must_check __copy_from_user_alt(void *to, const void __user *from, unsigned long n);
-+static inline unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n)
-+{
-+ if (n >= CONFIG_OXNAS_INSTRUMENT_COPIES_THRESHOLD) printk("__copy_from_user() %lu bytes\n", n);
-+ return __copy_from_user_alt(to, from , n);
-+}
-+extern unsigned long __must_check __copy_to_user_alt(void __user *to, const void *from, unsigned long n);
-+static inline unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n)
-+{
-+ if (n >= CONFIG_OXNAS_INSTRUMENT_COPIES_THRESHOLD) printk("__copy_to_user() %lu bytes\n", n);
-+ return __copy_to_user_alt(to, from , n);
-+}
-+extern unsigned long __must_check __clear_user_alt(void __user *addr, unsigned long n);
-+static inline unsigned long __must_check __clear_user(void __user *addr, unsigned long n)
-+{
-+ if (n >= CONFIG_OXNAS_INSTRUMENT_COPIES_THRESHOLD) printk("__clear_user() %lu bytes\n", n);
-+ return __clear_user_alt(addr, n);
-+}
-+#else // CONFIG_OXNAS_INSTRUMENT_COPIES
- extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n);
- extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n);
- extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n);
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
- #else
- #define __copy_from_user(to,from,n) (memcpy(to, (void __force *)from, n), 0)
- #define __copy_to_user(to,from,n) (memcpy((void __force *)to, from, n), 0)
-@@ -397,8 +418,15 @@
-
- static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
- {
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+ if (n >= CONFIG_OXNAS_INSTRUMENT_COPIES_THRESHOLD) printk("copy_from_user() %lu bytes\n", n);
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
- if (access_ok(VERIFY_READ, from, n))
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+ n = __copy_from_user_alt(to, from, n);
-+#else // CONFIG_OXNAS_INSTRUMENT_COPIES
- n = __copy_from_user(to, from, n);
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
- else /* security hole - plug it */
- memzero(to, n);
- return n;
-@@ -406,8 +434,15 @@
-
- static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
- {
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+ if (n >= CONFIG_OXNAS_INSTRUMENT_COPIES_THRESHOLD) printk("copy_to_user() %lu bytes\n", n);
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
- if (access_ok(VERIFY_WRITE, to, n))
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+ n = __copy_to_user_alt(to, from, n);
-+#else // CONFIG_OXNAS_INSTRUMENT_COPIES
- n = __copy_to_user(to, from, n);
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
- return n;
- }
-
-@@ -416,8 +451,15 @@
-
- static inline unsigned long __must_check clear_user(void __user *to, unsigned long n)
- {
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+ if (n >= CONFIG_OXNAS_INSTRUMENT_COPIES_THRESHOLD) printk("clear_user() %lu bytes\n", n);
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
- if (access_ok(VERIFY_WRITE, to, n))
-+#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
-+ n = __clear_user_alt(to, n);
-+#else // CONFIG_OXNAS_INSTRUMENT_COPIES
- n = __clear_user(to, n);
-+#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
- return n;
- }
-
-diff -Nurd linux-2.6.24/include/asm-arm/unaligned.h linux-2.6.24-oxe810/include/asm-arm/unaligned.h
---- linux-2.6.24/include/asm-arm/unaligned.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/unaligned.h 2008-06-11 17:45:14.000000000 +0200
-@@ -40,16 +40,16 @@
- */
-
- #define __get_unaligned_2_le(__p) \
-- (__p[0] | __p[1] << 8)
-+ (unsigned int)(__p[0] | __p[1] << 8)
-
- #define __get_unaligned_2_be(__p) \
-- (__p[0] << 8 | __p[1])
-+ (unsigned int)(__p[0] << 8 | __p[1])
-
- #define __get_unaligned_4_le(__p) \
-- (__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24)
-+ (unsigned int)(__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24)
-
- #define __get_unaligned_4_be(__p) \
-- (__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3])
-+ (unsigned int)(__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3])
-
- #define __get_unaligned_8_le(__p) \
- ((unsigned long long)__get_unaligned_4_le((__p+4)) << 32 | \
-diff -Nurd linux-2.6.24/include/asm-arm/unistd.h linux-2.6.24-oxe810/include/asm-arm/unistd.h
---- linux-2.6.24/include/asm-arm/unistd.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-arm/unistd.h 2008-06-11 17:45:14.000000000 +0200
-@@ -379,6 +379,7 @@
- #define __NR_timerfd (__NR_SYSCALL_BASE+350)
- #define __NR_eventfd (__NR_SYSCALL_BASE+351)
- #define __NR_fallocate (__NR_SYSCALL_BASE+352)
-+#define __NR_samba_reserve (__NR_SYSCALL_BASE+353)
-
- /*
- * The following SWIs are ARM private.
-diff -Nurd linux-2.6.24/include/asm-powerpc/pmac_feature.h linux-2.6.24-oxe810/include/asm-powerpc/pmac_feature.h
---- linux-2.6.24/include/asm-powerpc/pmac_feature.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-powerpc/pmac_feature.h 2008-06-11 17:44:57.000000000 +0200
-@@ -392,6 +392,14 @@
- #define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v)))
- #define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v)))
-
-+/* Uninorth variant:
-+ *
-+ * 0 = not uninorth
-+ * 1 = U1.x or U2.x
-+ * 3 = U3
-+ * 4 = U4
-+ */
-+extern int pmac_get_uninorth_variant(void);
-
- #endif /* __ASM_POWERPC_PMAC_FEATURE_H */
- #endif /* __KERNEL__ */
-diff -Nurd linux-2.6.24/include/asm-x86/apic_32.h linux-2.6.24-oxe810/include/asm-x86/apic_32.h
---- linux-2.6.24/include/asm-x86/apic_32.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-x86/apic_32.h 2008-06-11 17:44:30.000000000 +0200
-@@ -109,7 +109,7 @@
- extern void setup_secondary_APIC_clock (void);
- extern int APIC_init_uniprocessor (void);
-
--extern void enable_NMI_through_LVT0 (void * dummy);
-+extern void enable_NMI_through_LVT0(void);
-
- #define ARCH_APICTIMER_STOPS_ON_C3 1
-
-diff -Nurd linux-2.6.24/include/asm-x86/futex_32.h linux-2.6.24-oxe810/include/asm-x86/futex_32.h
---- linux-2.6.24/include/asm-x86/futex_32.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-x86/futex_32.h 2008-06-11 17:44:30.000000000 +0200
-@@ -28,7 +28,7 @@
- "1: movl %2, %0\n\
- movl %0, %3\n" \
- insn "\n" \
--"2: " LOCK_PREFIX "cmpxchgl %3, %2\n\
-+"2: lock ; cmpxchgl %3, %2\n\
- jnz 1b\n\
- 3: .section .fixup,\"ax\"\n\
- 4: mov %5, %1\n\
-@@ -68,7 +68,7 @@
- #endif
- switch (op) {
- case FUTEX_OP_ADD:
-- __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret,
-+ __futex_atomic_op1("lock ; xaddl %0, %2", ret,
- oldval, uaddr, oparg);
- break;
- case FUTEX_OP_OR:
-@@ -111,7 +111,7 @@
- return -EFAULT;
-
- __asm__ __volatile__(
-- "1: " LOCK_PREFIX "cmpxchgl %3, %1 \n"
-+ "1: lock ; cmpxchgl %3, %1 \n"
-
- "2: .section .fixup, \"ax\" \n"
- "3: mov %2, %0 \n"
-diff -Nurd linux-2.6.24/include/asm-x86/futex_64.h linux-2.6.24-oxe810/include/asm-x86/futex_64.h
---- linux-2.6.24/include/asm-x86/futex_64.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-x86/futex_64.h 2008-06-11 17:44:30.000000000 +0200
-@@ -27,7 +27,7 @@
- "1: movl %2, %0\n\
- movl %0, %3\n" \
- insn "\n" \
--"2: " LOCK_PREFIX "cmpxchgl %3, %2\n\
-+"2: lock ; cmpxchgl %3, %2\n\
- jnz 1b\n\
- 3: .section .fixup,\"ax\"\n\
- 4: mov %5, %1\n\
-@@ -62,7 +62,7 @@
- __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
- break;
- case FUTEX_OP_ADD:
-- __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval,
-+ __futex_atomic_op1("lock ; xaddl %0, %2", ret, oldval,
- uaddr, oparg);
- break;
- case FUTEX_OP_OR:
-@@ -101,7 +101,7 @@
- return -EFAULT;
-
- __asm__ __volatile__(
-- "1: " LOCK_PREFIX "cmpxchgl %3, %1 \n"
-+ "1: lock ; cmpxchgl %3, %1 \n"
-
- "2: .section .fixup, \"ax\" \n"
- "3: mov %2, %0 \n"
-diff -Nurd linux-2.6.24/include/asm-x86/io_apic_64.h linux-2.6.24-oxe810/include/asm-x86/io_apic_64.h
---- linux-2.6.24/include/asm-x86/io_apic_64.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-x86/io_apic_64.h 2008-06-11 17:44:30.000000000 +0200
-@@ -129,7 +129,7 @@
-
- extern int sis_apic_bug; /* dummy */
-
--void enable_NMI_through_LVT0 (void * dummy);
-+void enable_NMI_through_LVT0(void);
-
- extern spinlock_t i8259A_lock;
-
-diff -Nurd linux-2.6.24/include/asm-x86/processor_32.h linux-2.6.24-oxe810/include/asm-x86/processor_32.h
---- linux-2.6.24/include/asm-x86/processor_32.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/asm-x86/processor_32.h 2008-06-11 17:44:30.000000000 +0200
-@@ -712,9 +712,10 @@
- #define ASM_NOP6 K7_NOP6
- #define ASM_NOP7 K7_NOP7
- #define ASM_NOP8 K7_NOP8
--#elif defined(CONFIG_M686) || defined(CONFIG_MPENTIUMII) || \
-+#elif (defined(CONFIG_M686) || defined(CONFIG_MPENTIUMII) || \
- defined(CONFIG_MPENTIUMIII) || defined(CONFIG_MPENTIUMM) || \
-- defined(CONFIG_MCORE2) || defined(CONFIG_PENTIUM4)
-+ defined(CONFIG_MCORE2) || defined(CONFIG_PENTIUM4)) && \
-+ !defined(CONFIG_X86_GENERIC)
- #define ASM_NOP1 P6_NOP1
- #define ASM_NOP2 P6_NOP2
- #define ASM_NOP3 P6_NOP3
-diff -Nurd linux-2.6.24/include/linux/bio.h linux-2.6.24-oxe810/include/linux/bio.h
---- linux-2.6.24/include/linux/bio.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/bio.h 2008-06-11 17:45:39.000000000 +0200
-@@ -114,6 +114,15 @@
- void *bi_private;
-
- bio_destructor_t *bi_destructor; /* destructor */
-+
-+ /*
-+ * The raid settings for the bio, this should only be used by the oxsemi
-+ * sata driver to control raid hardware and the request merging code in
-+ * ll_rw_blk.c to prevent merging of requests to hwraid and non-hwraid
-+ *partitions.
-+ */
-+ u32 bi_raid;
-+
- };
-
- /*
-diff -Nurd linux-2.6.24/include/linux/byteorder/generic.h linux-2.6.24-oxe810/include/linux/byteorder/generic.h
---- linux-2.6.24/include/linux/byteorder/generic.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/byteorder/generic.h 2008-06-11 17:45:26.000000000 +0200
-@@ -146,6 +146,36 @@
- #define htons(x) ___htons(x)
- #define ntohs(x) ___ntohs(x)
-
-+static inline void le16_add_cpu(__le16 *var, u16 val)
-+{
-+ *var = cpu_to_le16(le16_to_cpu(*var) + val);
-+}
-+
-+static inline void le32_add_cpu(__le32 *var, u32 val)
-+{
-+ *var = cpu_to_le32(le32_to_cpu(*var) + val);
-+}
-+
-+static inline void le64_add_cpu(__le64 *var, u64 val)
-+{
-+ *var = cpu_to_le64(le64_to_cpu(*var) + val);
-+}
-+
-+static inline void be16_add_cpu(__be16 *var, u16 val)
-+{
-+ *var = cpu_to_be16(be16_to_cpu(*var) + val);
-+}
-+
-+static inline void be32_add_cpu(__be32 *var, u32 val)
-+{
-+ *var = cpu_to_be32(be32_to_cpu(*var) + val);
-+}
-+
-+static inline void be64_add_cpu(__be64 *var, u64 val)
-+{
-+ *var = cpu_to_be64(be64_to_cpu(*var) + val);
-+}
-+
- #endif /* KERNEL */
-
- #endif /* _LINUX_BYTEORDER_GENERIC_H */
-diff -Nurd linux-2.6.24/include/linux/byteorder/swab.h linux-2.6.24-oxe810/include/linux/byteorder/swab.h
---- linux-2.6.24/include/linux/byteorder/swab.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/byteorder/swab.h 2008-06-11 17:45:26.000000000 +0200
-@@ -61,26 +61,37 @@
- * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
- */
-
--static __inline__ __attribute_const__ __u16 ___swab16(__u16 x)
--{
-- return x<<8 | x>>8;
--}
--static __inline__ __attribute_const__ __u32 ___swab32(__u32 x)
--{
-- return x<<24 | x>>24 |
-- (x & (__u32)0x0000ff00UL)<<8 |
-- (x & (__u32)0x00ff0000UL)>>8;
--}
--static __inline__ __attribute_const__ __u64 ___swab64(__u64 x)
--{
-- return x<<56 | x>>56 |
-- (x & (__u64)0x000000000000ff00ULL)<<40 |
-- (x & (__u64)0x0000000000ff0000ULL)<<24 |
-- (x & (__u64)0x00000000ff000000ULL)<< 8 |
-- (x & (__u64)0x000000ff00000000ULL)>> 8 |
-- (x & (__u64)0x0000ff0000000000ULL)>>24 |
-- (x & (__u64)0x00ff000000000000ULL)>>40;
--}
-+#define ___swab16(x) \
-+({ \
-+ __u16 __x = (x); \
-+ ((__u16)( \
-+ (((__u16)(__x) & (__u16)0x00ffU) << 8) | \
-+ (((__u16)(__x) & (__u16)0xff00U) >> 8) )); \
-+})
-+
-+#define ___swab32(x) \
-+({ \
-+ __u32 __x = (x); \
-+ ((__u32)( \
-+ (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \
-+ (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | \
-+ (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | \
-+ (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \
-+})
-+
-+#define ___swab64(x) \
-+({ \
-+ __u64 __x = (x); \
-+ ((__u64)( \
-+ (__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \
-+ (__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \
-+ (__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \
-+ (__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) | \
-+ (__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) | \
-+ (__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
-+ (__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \
-+ (__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56) )); \
-+})
-
- #define ___constant_swab16(x) \
- ((__u16)( \
-@@ -103,6 +114,7 @@
- (__u64)(((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \
- (__u64)(((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56) ))
-
-+
- /*
- * provide defaults when no architecture-specific optimization is detected
- */
-diff -Nurd linux-2.6.24/include/linux/dmi.h linux-2.6.24-oxe810/include/linux/dmi.h
---- linux-2.6.24/include/linux/dmi.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/dmi.h 2008-06-11 17:45:39.000000000 +0200
-@@ -79,7 +79,6 @@
- extern int dmi_get_year(int field);
- extern int dmi_name_in_vendors(const char *str);
- extern int dmi_available;
--extern char *dmi_get_slot(int slot);
-
- #else
-
-@@ -90,7 +89,6 @@
- static inline int dmi_get_year(int year) { return 0; }
- static inline int dmi_name_in_vendors(const char *s) { return 0; }
- #define dmi_available 0
--static inline char *dmi_get_slot(int slot) { return NULL; }
-
- #endif
-
-diff -Nurd linux-2.6.24/include/linux/fs.h linux-2.6.24-oxe810/include/linux/fs.h
---- linux-2.6.24/include/linux/fs.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/fs.h 2008-06-11 17:45:39.000000000 +0200
-@@ -1147,7 +1147,7 @@
- int error;
- } read_descriptor_t;
-
--typedef int (*read_actor_t)(read_descriptor_t *, struct page *, unsigned long, unsigned long);
-+typedef int (*read_actor_t)(read_descriptor_t *, struct page **, unsigned long, unsigned long);
-
- /* These macros are for out of kernel modules to test that
- * the kernel supports the unlocked_ioctl and compat_ioctl
-@@ -1180,7 +1180,9 @@
- int (*aio_fsync) (struct kiocb *, int datasync);
- int (*fasync) (int, struct file *, int);
- int (*lock) (struct file *, int, struct file_lock *);
-+ ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *);
- ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
-+ ssize_t (*sendpages) (struct file *, struct page **, int, size_t, loff_t *, int);
- unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- int (*check_flags)(int);
- int (*dir_notify)(struct file *filp, unsigned long arg);
-@@ -1791,7 +1793,8 @@
-
- extern int generic_file_mmap(struct file *, struct vm_area_struct *);
- extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *);
--extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
-+extern int file_read_actor(read_descriptor_t * desc, struct page **page, unsigned long offset, unsigned long size);
-+extern int file_send_actor(read_descriptor_t * desc, struct page **page, unsigned long offset, unsigned long size);
- int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk);
- extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t);
- extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t);
-@@ -1803,12 +1806,14 @@
- unsigned long, loff_t, loff_t *, size_t, ssize_t);
- extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos);
- extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos);
-+extern ssize_t generic_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *);
- extern void do_generic_mapping_read(struct address_space *mapping,
- struct file_ra_state *, struct file *,
- loff_t *, read_descriptor_t *, read_actor_t);
- extern int generic_segment_checks(const struct iovec *iov,
- unsigned long *nr_segs, size_t *count, int access_flags);
-
-+
- /* fs/splice.c */
- extern ssize_t generic_file_splice_read(struct file *, loff_t *,
- struct pipe_inode_info *, size_t, unsigned int);
-diff -Nurd linux-2.6.24/include/linux/futex.h linux-2.6.24-oxe810/include/linux/futex.h
---- linux-2.6.24/include/linux/futex.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/futex.h 2008-06-11 17:45:38.000000000 +0200
-@@ -153,6 +153,7 @@
- #ifdef CONFIG_FUTEX
- extern void exit_robust_list(struct task_struct *curr);
- extern void exit_pi_state_list(struct task_struct *curr);
-+extern int futex_cmpxchg_enabled;
- #else
- static inline void exit_robust_list(struct task_struct *curr)
- {
-diff -Nurd linux-2.6.24/include/linux/hrtimer.h linux-2.6.24-oxe810/include/linux/hrtimer.h
---- linux-2.6.24/include/linux/hrtimer.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/hrtimer.h 2008-06-11 17:45:39.000000000 +0200
-@@ -300,7 +300,7 @@
-
- /* Precise sleep: */
- extern long hrtimer_nanosleep(struct timespec *rqtp,
-- struct timespec *rmtp,
-+ struct timespec __user *rmtp,
- const enum hrtimer_mode mode,
- const clockid_t clockid);
- extern long hrtimer_nanosleep_restart(struct restart_block *restart_block);
-diff -Nurd linux-2.6.24/include/linux/hugetlb.h linux-2.6.24-oxe810/include/linux/hugetlb.h
---- linux-2.6.24/include/linux/hugetlb.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/hugetlb.h 2008-06-11 17:45:39.000000000 +0200
-@@ -17,6 +17,7 @@
- }
-
- int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *);
-+int hugetlb_overcommit_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *);
- int hugetlb_treat_movable_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *);
- int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *);
- int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int, int);
-diff -Nurd linux-2.6.24/include/linux/i2c-id.h linux-2.6.24-oxe810/include/linux/i2c-id.h
---- linux-2.6.24/include/linux/i2c-id.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/i2c-id.h 2008-06-11 17:45:39.000000000 +0200
-@@ -203,6 +203,7 @@
- #define I2C_HW_B_CX2341X 0x010020 /* Conexant CX2341X MPEG encoder cards */
- #define I2C_HW_B_INTELFB 0x010021 /* intel framebuffer driver */
- #define I2C_HW_B_CX23885 0x010022 /* conexant 23885 based tv cards (bus1) */
-+#define I2C_HW_B_OXNAS 0x010023 /* Oxford Semiconductor OX800 */
-
- /* --- PCF 8584 based algorithms */
- #define I2C_HW_P_LP 0x020000 /* Parallel port interface */
-diff -Nurd linux-2.6.24/include/linux/irq.h linux-2.6.24-oxe810/include/linux/irq.h
---- linux-2.6.24/include/linux/irq.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/irq.h 2008-06-11 17:45:39.000000000 +0200
-@@ -367,6 +367,9 @@
- __set_irq_handler(irq, handle, 1, NULL);
- }
-
-+extern void set_irq_noprobe(unsigned int irq);
-+extern void set_irq_probe(unsigned int irq);
-+
- /* Handle dynamic irq creation and destruction */
- extern int create_irq(void);
- extern void destroy_irq(unsigned int irq);
-diff -Nurd linux-2.6.24/include/linux/ktime.h linux-2.6.24-oxe810/include/linux/ktime.h
---- linux-2.6.24/include/linux/ktime.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/ktime.h 2008-06-11 17:45:39.000000000 +0200
-@@ -310,6 +310,8 @@
- return ktime_sub_ns(kt, usec * 1000);
- }
-
-+extern ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs);
-+
- /*
- * The resolution of the clocks. The resolution value is returned in
- * the clock_getres() system call to give application programmers an
-diff -Nurd linux-2.6.24/include/linux/leds.h linux-2.6.24-oxe810/include/linux/leds.h
---- linux-2.6.24/include/linux/leds.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/leds.h 2008-06-11 17:45:38.000000000 +0200
-@@ -123,5 +123,11 @@
- struct gpio_led *leds;
- };
-
-+/* Trigger specific functions */
-+#ifdef CONFIG_WDC_LEDS_TRIGGER_SATA_DISK
-+extern void wdc_ledtrig_sata_activity(void);
-+#else
-+#define wdc_ledtrig_sata_activity() do {} while(0)
-+#endif
-
- #endif /* __LINUX_LEDS_H_INCLUDED */
-diff -Nurd linux-2.6.24/include/linux/libata.h linux-2.6.24-oxe810/include/linux/libata.h
---- linux-2.6.24/include/linux/libata.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/libata.h 2008-06-11 17:45:39.000000000 +0200
-@@ -238,7 +238,7 @@
- /* various lengths of time */
- ATA_TMOUT_BOOT = 30 * HZ, /* heuristic */
- ATA_TMOUT_BOOT_QUICK = 7 * HZ, /* heuristic */
-- ATA_TMOUT_INTERNAL = 30 * HZ,
-+ ATA_TMOUT_INTERNAL = 10 * HZ,
- ATA_TMOUT_INTERNAL_QUICK = 5 * HZ,
-
- /* FIXME: GoVault needs 2s but we can't afford that without
-@@ -662,7 +662,7 @@
- };
-
- struct ata_port_operations {
-- void (*dev_config) (struct ata_device *);
-+ void (*dev_config) (struct ata_port *, struct ata_device *);
-
- void (*set_piomode) (struct ata_port *, struct ata_device *);
- void (*set_dmamode) (struct ata_port *, struct ata_device *);
-@@ -675,6 +675,7 @@
- u8 (*check_status)(struct ata_port *ap);
- u8 (*check_altstatus)(struct ata_port *ap);
- void (*dev_select)(struct ata_port *ap, unsigned int device);
-+ unsigned int (*dev_chk)(struct ata_port *ap, unsigned int device);
-
- void (*phy_reset) (struct ata_port *ap); /* obsolete */
- int (*set_mode) (struct ata_link *link, struct ata_device **r_failed_dev);
-@@ -689,6 +690,8 @@
- void (*data_xfer) (struct ata_device *, unsigned char *, unsigned int, int);
-
- int (*qc_defer) (struct ata_queued_cmd *qc);
-+ struct ata_queued_cmd* (*qc_new)(struct ata_port *ap);
-+ void (*qc_free)(struct ata_queued_cmd *qc);
- void (*qc_prep) (struct ata_queued_cmd *qc);
- unsigned int (*qc_issue) (struct ata_queued_cmd *qc);
-
-@@ -724,6 +727,7 @@
-
- void (*bmdma_stop) (struct ata_queued_cmd *qc);
- u8 (*bmdma_status) (struct ata_port *ap);
-+ void (*pio_task)(struct work_struct *work);
- };
-
- struct ata_port_info {
-diff -Nurd linux-2.6.24/include/linux/mii.h linux-2.6.24-oxe810/include/linux/mii.h
---- linux-2.6.24/include/linux/mii.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/mii.h 2008-06-11 17:45:39.000000000 +0200
-@@ -21,18 +21,18 @@
- #define MII_EXPANSION 0x06 /* Expansion register */
- #define MII_CTRL1000 0x09 /* 1000BASE-T control */
- #define MII_STAT1000 0x0a /* 1000BASE-T status */
--#define MII_ESTATUS 0x0f /* Extended Status */
--#define MII_DCOUNTER 0x12 /* Disconnect counter */
--#define MII_FCSCOUNTER 0x13 /* False carrier counter */
--#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
--#define MII_RERRCOUNTER 0x15 /* Receive error counter */
--#define MII_SREVISION 0x16 /* Silicon revision */
--#define MII_RESV1 0x17 /* Reserved... */
--#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
--#define MII_PHYADDR 0x19 /* PHY address */
--#define MII_RESV2 0x1a /* Reserved... */
--#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
--#define MII_NCONFIG 0x1c /* Network interface config */
-+#define MII_ESTATUS 0x0f /* Extended Status */
-+//#define MII_DCOUNTER 0x12 /* Disconnect counter */
-+//#define MII_FCSCOUNTER 0x13 /* False carrier counter */
-+//#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
-+//#define MII_RERRCOUNTER 0x15 /* Receive error counter */
-+//#define MII_SREVISION 0x16 /* Silicon revision */
-+//#define MII_RESV1 0x17 /* Reserved... */
-+//#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
-+//#define MII_PHYADDR 0x19 /* PHY address */
-+//#define MII_RESV2 0x1a /* Reserved... */
-+//#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
-+//#define MII_NCONFIG 0x1c /* Network interface config */
-
- /* Basic mode control register. */
- #define BMCR_RESV 0x003f /* Unused... */
-@@ -121,9 +121,9 @@
- #define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */
-
- /* N-way test register. */
--#define NWAYTEST_RESV1 0x00ff /* Unused... */
--#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */
--#define NWAYTEST_RESV2 0xfe00 /* Unused... */
-+//#define NWAYTEST_RESV1 0x00ff /* Unused... */
-+//#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */
-+//#define NWAYTEST_RESV2 0xfe00 /* Unused... */
-
- /* 1000BASE-T Control register */
- #define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */
-@@ -157,7 +157,9 @@
-
- unsigned int full_duplex : 1; /* is full duplex? */
- unsigned int force_media : 1; /* is autoneg. disabled? */
-- unsigned int supports_gmii : 1; /* are GMII registers supported? */
-+ unsigned int using_1000 : 1; /* the PHY is using 1000Mb rate */
-+ unsigned int using_100 : 1; /* the PHY is using 100Mb rate */
-+ unsigned int using_pause : 1; /* the PHY will generate pause frames */
-
- struct net_device *dev;
- int (*mdio_read) (struct net_device *dev, int phy_id, int location);
-@@ -170,9 +172,16 @@
- extern int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
- extern int mii_check_gmii_support(struct mii_if_info *mii);
- extern void mii_check_link (struct mii_if_info *mii);
--extern unsigned int mii_check_media (struct mii_if_info *mii,
-- unsigned int ok_to_print,
-- unsigned int init_media);
-+extern unsigned int mii_check_media(struct mii_if_info *mii,
-+ unsigned int ok_to_print,
-+ unsigned int init_media);
-+extern unsigned int mii_check_media_ex(struct mii_if_info *mii,
-+ unsigned int ok_to_print,
-+ unsigned int init_media,
-+ int *has_gigabit_changed,
-+ int *has_pause_changed,
-+ void (*link_state_change_callback)(int link_state, void* arg),
-+ void *link_state_change_arg);
- extern int generic_mii_ioctl(struct mii_if_info *mii_if,
- struct mii_ioctl_data *mii_data, int cmd,
- unsigned int *duplex_changed);
-@@ -216,6 +225,23 @@
- return ret;
- }
-
-+static inline unsigned int mii_nway_result_1000(unsigned int lpa_1000, unsigned int advertised_1000)
-+{
-+ int full_negotiated = (lpa_1000 & LPA_1000FULL) &&
-+ (advertised_1000 & ADVERTISE_1000FULL);
-+
-+ int half_negotiated = (lpa_1000 & LPA_1000HALF) &&
-+ (advertised_1000 & ADVERTISE_1000HALF);
-+
-+ if (full_negotiated) {
-+ return LPA_1000FULL;
-+ } else if (half_negotiated) {
-+ return LPA_1000HALF;
-+ } else {
-+ return 0;
-+ }
-+}
-+
- /**
- * mii_duplex
- * @duplex_lock: Non-zero if duplex is locked at full
-diff -Nurd linux-2.6.24/include/linux/moduleparam.h linux-2.6.24-oxe810/include/linux/moduleparam.h
---- linux-2.6.24/include/linux/moduleparam.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/moduleparam.h 2008-06-11 17:45:39.000000000 +0200
-@@ -62,6 +62,16 @@
- void *elem;
- };
-
-+/* On alpha, ia64 and ppc64 relocations to global data cannot go into
-+ read-only sections (which is part of respective UNIX ABI on these
-+ platforms). So 'const' makes no sense and even causes compile failures
-+ with some compilers. */
-+#if defined(CONFIG_ALPHA) || defined(CONFIG_IA64) || defined(CONFIG_PPC64)
-+#define __moduleparam_const
-+#else
-+#define __moduleparam_const const
-+#endif
-+
- /* This is the fundamental function for registering boot/module
- parameters. perm sets the visibility in sysfs: 000 means it's
- not there, read bits mean it's readable, write bits mean it's
-@@ -71,7 +81,7 @@
- static int __param_perm_check_##name __attribute__((unused)) = \
- BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)); \
- static const char __param_str_##name[] = prefix #name; \
-- static struct kernel_param const __param_##name \
-+ static struct kernel_param __moduleparam_const __param_##name \
- __attribute_used__ \
- __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
- = { __param_str_##name, perm, set, get, { arg } }
-diff -Nurd linux-2.6.24/include/linux/net.h linux-2.6.24-oxe810/include/linux/net.h
---- linux-2.6.24/include/linux/net.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/net.h 2008-06-11 17:45:39.000000000 +0200
-@@ -172,6 +172,8 @@
- struct vm_area_struct * vma);
- ssize_t (*sendpage) (struct socket *sock, struct page *page,
- int offset, size_t size, int flags);
-+ ssize_t (*sendpages) (struct socket *sock, struct page **page,
-+ int offset, size_t size, int flags);
- };
-
- struct net_proto_family {
-diff -Nurd linux-2.6.24/include/linux/raid/raid1.h linux-2.6.24-oxe810/include/linux/raid/raid1.h
---- linux-2.6.24/include/linux/raid/raid1.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/raid/raid1.h 2008-06-11 17:45:26.000000000 +0200
-@@ -61,6 +61,10 @@
-
- mempool_t *r1bio_pool;
- mempool_t *r1buf_pool;
-+
-+ /** This contains flags that can be included with the BIOs generated by
-+ writes to set the correct hardware RAID modes */
-+ u32 hw_raid1_settings;
- };
-
- typedef struct r1_private_data_s conf_t;
-diff -Nurd linux-2.6.24/include/linux/serial_reg.h linux-2.6.24-oxe810/include/linux/serial_reg.h
---- linux-2.6.24/include/linux/serial_reg.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/serial_reg.h 2008-06-11 17:45:39.000000000 +0200
-@@ -133,6 +133,15 @@
-
- #define UART_SCR 7 /* I/O: Scratch Register */
-
-+/* Oxsemi NAS UART extra registers */
-+#define UART_DLF 0x09 /* Oxsemi 16550 fractional divider */
-+#define UART_RX_FILL 0x0a
-+#define UART_TX_SPACE 0x0b
-+#define UART_WIDE_ACCESS 0x0c
-+#define UART_XON_CHAR 0x10
-+#define UART_XOFF_CHAR 0x11
-+#define UART_DMA 0x12
-+
- /*
- * DLAB=1
- */
-diff -Nurd linux-2.6.24/include/linux/syscalls.h linux-2.6.24-oxe810/include/linux/syscalls.h
---- linux-2.6.24/include/linux/syscalls.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/syscalls.h 2008-06-11 17:45:39.000000000 +0200
-@@ -611,6 +611,7 @@
- const struct itimerspec __user *utmr);
- asmlinkage long sys_eventfd(unsigned int count);
- asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len);
-+asmlinkage long sys_samba_reserve(int fd, void __user *info);
-
- int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
-
-diff -Nurd linux-2.6.24/include/linux/trustees.h linux-2.6.24-oxe810/include/linux/trustees.h
---- linux-2.6.24/include/linux/trustees.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/trustees.h 2008-06-11 17:45:39.000000000 +0200
-@@ -0,0 +1,108 @@
-+/*
-+ * Trustees ACL Project
-+ *
-+ * Copyright (c) 1999-2000 Vyacheslav Zavadsky
-+ * Copyright (c) 2004 Andrew Ruder (aeruder@ksu.edu)
-+ *
-+ * 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, version 2.
-+ *
-+ * Structs, defines and function definitions intended for export
-+ *
-+ */
-+
-+#ifndef _LINUX_TRUSTEE_STRUCT_H
-+
-+#define _LINUX_TRUSTEE_STRUCT_H
-+#include <linux/types.h>
-+
-+#define TRUSTEES_APIVERSION 2
-+#define TRUSTEES_APIVERSION_STR "2"
-+
-+#define TRUSTEE_EXECUTE_BIT 0
-+#define TRUSTEE_READ_BIT 1
-+#define TRUSTEE_WRITE_BIT 2
-+#define TRUSTEE_BROWSE_BIT 3
-+#define TRUSTEE_READ_DIR_BIT 4
-+#define TRUSTEE_USE_UNIX_BIT 5
-+#define TRUSTEE_NUM_ACL_BITS (TRUSTEE_USE_UNIX_BIT+1)
-+#define TRUSTEE_EXECUTE_MASK (1 << TRUSTEE_EXECUTE_BIT)
-+#define TRUSTEE_READ_MASK (1 << TRUSTEE_READ_BIT)
-+#define TRUSTEE_WRITE_MASK (1 << TRUSTEE_WRITE_BIT)
-+#define TRUSTEE_BROWSE_MASK (1 << TRUSTEE_BROWSE_BIT)
-+#define TRUSTEE_READ_DIR_MASK (1 << TRUSTEE_READ_DIR_BIT)
-+#define TRUSTEE_USE_UNIX_MASK (1 << TRUSTEE_USE_UNIX_BIT)
-+#define TRUSTEE_ACL_MASK ((1 << TRUSTEE_NUM_ACL_BITS)-1)
-+
-+#define TRUSTEE_ALLOW_DENY_BIT 7
-+#define TRUSTEE_IS_GROUP_BIT 6
-+#define TRUSTEE_CLEAR_SET_BIT 8
-+#define TRUSTEE_ONE_LEVEL_BIT 9
-+#define TRUSTEE_NOT_BIT 10
-+#define TRUSTEE_ALL_BIT 11
-+#define TRUSTEE_ALLOW_DENY_MASK (1 << TRUSTEE_ALLOW_DENY_BIT) /* set if deny */
-+#define TRUSTEE_IS_GROUP_MASK (1 << TRUSTEE_IS_GROUP_BIT)
-+#define TRUSTEE_CLEAR_SET_MASK (1 << TRUSTEE_CLEAR_SET_BIT) /* set if clear */
-+#define TRUSTEE_ONE_LEVEL_MASK (1 << TRUSTEE_ONE_LEVEL_BIT)
-+#define TRUSTEE_NOT_MASK (1 << TRUSTEE_NOT_BIT)
-+#define TRUSTEE_ALL_MASK (1 << TRUSTEE_ALL_BIT)
-+
-+#define trustee_acl __u16
-+#define trustee_default_acl TRUSTEE_USE_UNIX_MASK
-+
-+struct trustee_permission {
-+ trustee_acl mask;
-+ union {
-+ __kernel_uid32_t uid;
-+ __kernel_gid32_t gid;
-+ } u;
-+};
-+
-+#ifndef __KERNEL__
-+#ifndef __user
-+#define __user
-+#endif
-+#endif
-+
-+struct trustee_command {
-+ unsigned command;
-+ unsigned numargs;
-+};
-+
-+/* Most arguments that any command will take */
-+
-+#define TRUSTEE_MAX_ARGS 6
-+
-+/* Starts a table
-+ * No arguments
-+ */
-+#define TRUSTEE_COMMAND_TABLE_START 1
-+
-+/* Ends a table successfully.
-+ * No arguments
-+ */
-+#define TRUSTEE_COMMAND_TABLE_STOP 2
-+
-+/* Adds a trustee
-+ * Arguments:
-+ * filename (char [])
-+ * struct trustee_permission
-+ * device-name (char [])
-+ * device number (u32)
-+ */
-+#define TRUSTEE_COMMAND_ADD 3
-+
-+/* Removes all trustees
-+ * No arguments
-+ */
-+#define TRUSTEE_COMMAND_REMOVE_ALL 2
-+
-+/* Makes a filesystem ignorecase
-+ * Arguments:
-+ * device-name (char [])
-+ * device number (u32)
-+ */
-+#define TRUSTEE_COMMAND_MAKE_IC 5
-+
-+#endif /* _LINUX_TRUSTEE_STRUCT_H */
-diff -Nurd linux-2.6.24/include/linux/wait.h linux-2.6.24-oxe810/include/linux/wait.h
---- linux-2.6.24/include/linux/wait.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/linux/wait.h 2008-06-11 17:45:39.000000000 +0200
-@@ -161,6 +161,22 @@
- #define wake_up_locked(x) __wake_up_locked((x), TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE)
- #define wake_up_interruptible_sync(x) __wake_up_sync((x),TASK_INTERRUPTIBLE, 1)
-
-+#ifdef CONFIG_DEBUG_LOCK_ALLOC
-+/*
-+ * macro to avoid include hell
-+ */
-+#define wake_up_nested(x, s) \
-+do { \
-+ unsigned long flags; \
-+ \
-+ spin_lock_irqsave_nested(&(x)->lock, flags, (s)); \
-+ wake_up_locked(x); \
-+ spin_unlock_irqrestore(&(x)->lock, flags); \
-+} while (0)
-+#else
-+#define wake_up_nested(x, s) wake_up(x)
-+#endif
-+
- #define __wait_event(wq, condition) \
- do { \
- DEFINE_WAIT(__wait); \
-diff -Nurd linux-2.6.24/include/net/inet_sock.h linux-2.6.24-oxe810/include/net/inet_sock.h
---- linux-2.6.24/include/net/inet_sock.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/net/inet_sock.h 2008-06-11 17:44:45.000000000 +0200
-@@ -175,7 +175,8 @@
- static inline unsigned int inet_ehashfn(const __be32 laddr, const __u16 lport,
- const __be32 faddr, const __be16 fport)
- {
-- return jhash_2words((__force __u32) laddr ^ (__force __u32) faddr,
-+ return jhash_3words((__force __u32) laddr,
-+ (__force __u32) faddr,
- ((__u32) lport) << 16 | (__force __u32)fport,
- inet_ehash_secret);
- }
-diff -Nurd linux-2.6.24/include/net/sock.h linux-2.6.24-oxe810/include/net/sock.h
---- linux-2.6.24/include/net/sock.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/net/sock.h 2008-06-11 17:44:45.000000000 +0200
-@@ -549,6 +549,8 @@
- int *addr_len);
- int (*sendpage)(struct sock *sk, struct page *page,
- int offset, size_t size, int flags);
-+ int (*sendpages)(struct sock *sk, struct page **page,
-+ int offset, size_t size, int flags);
- int (*bind)(struct sock *sk,
- struct sockaddr *uaddr, int addr_len);
-
-diff -Nurd linux-2.6.24/include/net/tcp.h linux-2.6.24-oxe810/include/net/tcp.h
---- linux-2.6.24/include/net/tcp.h 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/include/net/tcp.h 2008-06-11 17:44:45.000000000 +0200
-@@ -285,6 +285,7 @@
- extern int tcp_sendmsg(struct kiocb *iocb, struct socket *sock,
- struct msghdr *msg, size_t size);
- extern ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags);
-+extern ssize_t tcp_sendpages(struct socket *sock, struct page **page, int offset, size_t size, int flags);
-
- extern int tcp_ioctl(struct sock *sk,
- int cmd,
-diff -Nurd linux-2.6.24/kernel/audit.c linux-2.6.24-oxe810/kernel/audit.c
---- linux-2.6.24/kernel/audit.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/audit.c 2008-06-11 17:43:47.000000000 +0200
-@@ -1200,13 +1200,17 @@
- static inline int audit_expand(struct audit_buffer *ab, int extra)
- {
- struct sk_buff *skb = ab->skb;
-- int ret = pskb_expand_head(skb, skb_headroom(skb), extra,
-- ab->gfp_mask);
-+ int oldtail = skb_tailroom(skb);
-+ int ret = pskb_expand_head(skb, 0, extra, ab->gfp_mask);
-+ int newtail = skb_tailroom(skb);
-+
- if (ret < 0) {
- audit_log_lost("out of memory in audit_expand");
- return 0;
- }
-- return skb_tailroom(skb);
-+
-+ skb->truesize += newtail - oldtail;
-+ return newtail;
- }
-
- /*
-diff -Nurd linux-2.6.24/kernel/compat.c linux-2.6.24-oxe810/kernel/compat.c
---- linux-2.6.24/kernel/compat.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/compat.c 2008-06-11 17:43:47.000000000 +0200
-@@ -40,10 +40,36 @@
- __put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
- }
-
-+static long compat_nanosleep_restart(struct restart_block *restart)
-+{
-+ struct compat_timespec __user *rmtp;
-+ struct timespec rmt;
-+ mm_segment_t oldfs;
-+ long ret;
-+
-+ rmtp = (struct compat_timespec __user *)(restart->arg1);
-+ restart->arg1 = (unsigned long)&rmt;
-+ oldfs = get_fs();
-+ set_fs(KERNEL_DS);
-+ ret = hrtimer_nanosleep_restart(restart);
-+ set_fs(oldfs);
-+
-+ if (ret) {
-+ restart->fn = compat_nanosleep_restart;
-+ restart->arg1 = (unsigned long)rmtp;
-+
-+ if (rmtp && put_compat_timespec(&rmt, rmtp))
-+ return -EFAULT;
-+ }
-+
-+ return ret;
-+}
-+
- asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp,
- struct compat_timespec __user *rmtp)
- {
- struct timespec tu, rmt;
-+ mm_segment_t oldfs;
- long ret;
-
- if (get_compat_timespec(&tu, rqtp))
-@@ -52,11 +78,21 @@
- if (!timespec_valid(&tu))
- return -EINVAL;
-
-- ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL,
-- CLOCK_MONOTONIC);
-+ oldfs = get_fs();
-+ set_fs(KERNEL_DS);
-+ ret = hrtimer_nanosleep(&tu,
-+ rmtp ? (struct timespec __user *)&rmt : NULL,
-+ HRTIMER_MODE_REL, CLOCK_MONOTONIC);
-+ set_fs(oldfs);
-
-- if (ret && rmtp) {
-- if (put_compat_timespec(&rmt, rmtp))
-+ if (ret) {
-+ struct restart_block *restart
-+ = ¤t_thread_info()->restart_block;
-+
-+ restart->fn = compat_nanosleep_restart;
-+ restart->arg1 = (unsigned long)rmtp;
-+
-+ if (rmtp && put_compat_timespec(&rmt, rmtp))
- return -EFAULT;
- }
-
-diff -Nurd linux-2.6.24/kernel/futex.c linux-2.6.24-oxe810/kernel/futex.c
---- linux-2.6.24/kernel/futex.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/futex.c 2008-06-11 17:43:47.000000000 +0200
-@@ -60,6 +60,8 @@
-
- #include "rtmutex_common.h"
-
-+int __read_mostly futex_cmpxchg_enabled;
-+
- #define FUTEX_HASHBITS (CONFIG_BASE_SMALL ? 4 : 8)
-
- /*
-@@ -466,6 +468,8 @@
- struct futex_hash_bucket *hb;
- union futex_key key;
-
-+ if (!futex_cmpxchg_enabled)
-+ return;
- /*
- * We are a ZOMBIE and nobody can enqueue itself on
- * pi_state_list anymore, but we have to be careful
-@@ -1854,6 +1858,8 @@
- sys_set_robust_list(struct robust_list_head __user *head,
- size_t len)
- {
-+ if (!futex_cmpxchg_enabled)
-+ return -ENOSYS;
- /*
- * The kernel knows only one size for now:
- */
-@@ -1878,6 +1884,9 @@
- struct robust_list_head __user *head;
- unsigned long ret;
-
-+ if (!futex_cmpxchg_enabled)
-+ return -ENOSYS;
-+
- if (!pid)
- head = current->robust_list;
- else {
-@@ -1980,6 +1989,9 @@
- unsigned long futex_offset;
- int rc;
-
-+ if (!futex_cmpxchg_enabled)
-+ return;
-+
- /*
- * Fetch the list head (which was registered earlier, via
- * sys_set_robust_list()):
-@@ -2034,7 +2046,7 @@
- long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
- u32 __user *uaddr2, u32 val2, u32 val3)
- {
-- int ret;
-+ int ret = -ENOSYS;
- int cmd = op & FUTEX_CMD_MASK;
- struct rw_semaphore *fshared = NULL;
-
-@@ -2062,13 +2074,16 @@
- ret = futex_wake_op(uaddr, fshared, uaddr2, val, val2, val3);
- break;
- case FUTEX_LOCK_PI:
-- ret = futex_lock_pi(uaddr, fshared, val, timeout, 0);
-+ if (futex_cmpxchg_enabled)
-+ ret = futex_lock_pi(uaddr, fshared, val, timeout, 0);
- break;
- case FUTEX_UNLOCK_PI:
-- ret = futex_unlock_pi(uaddr, fshared);
-+ if (futex_cmpxchg_enabled)
-+ ret = futex_unlock_pi(uaddr, fshared);
- break;
- case FUTEX_TRYLOCK_PI:
-- ret = futex_lock_pi(uaddr, fshared, 0, timeout, 1);
-+ if (futex_cmpxchg_enabled)
-+ ret = futex_lock_pi(uaddr, fshared, 0, timeout, 1);
- break;
- default:
- ret = -ENOSYS;
-@@ -2094,7 +2109,7 @@
-
- t = timespec_to_ktime(ts);
- if (cmd == FUTEX_WAIT)
-- t = ktime_add(ktime_get(), t);
-+ t = ktime_add_safe(ktime_get(), t);
- tp = &t;
- }
- /*
-@@ -2123,8 +2138,29 @@
-
- static int __init init(void)
- {
-- int i = register_filesystem(&futex_fs_type);
-+ u32 curval;
-+ int i;
-+
-+ /*
-+ * This will fail and we want it. Some arch implementations do
-+ * runtime detection of the futex_atomic_cmpxchg_inatomic()
-+ * functionality. We want to know that before we call in any
-+ * of the complex code paths. Also we want to prevent
-+ * registration of robust lists in that case. NULL is
-+ * guaranteed to fault and we get -EFAULT on functional
-+ * implementation, the non functional ones will return
-+ * -ENOSYS.
-+ */
-+ curval = cmpxchg_futex_value_locked(NULL, 0, 0);
-+ if (curval == -EFAULT)
-+ futex_cmpxchg_enabled = 1;
-
-+ for (i = 0; i < ARRAY_SIZE(futex_queues); i++) {
-+ plist_head_init(&futex_queues[i].chain, &futex_queues[i].lock);
-+ spin_lock_init(&futex_queues[i].lock);
-+ }
-+
-+ i = register_filesystem(&futex_fs_type);
- if (i)
- return i;
-
-@@ -2134,10 +2170,6 @@
- return PTR_ERR(futex_mnt);
- }
-
-- for (i = 0; i < ARRAY_SIZE(futex_queues); i++) {
-- plist_head_init(&futex_queues[i].chain, &futex_queues[i].lock);
-- spin_lock_init(&futex_queues[i].lock);
-- }
- return 0;
- }
- __initcall(init);
-diff -Nurd linux-2.6.24/kernel/futex_compat.c linux-2.6.24-oxe810/kernel/futex_compat.c
---- linux-2.6.24/kernel/futex_compat.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/futex_compat.c 2008-06-11 17:43:47.000000000 +0200
-@@ -54,6 +54,9 @@
- compat_long_t futex_offset;
- int rc;
-
-+ if (!futex_cmpxchg_enabled)
-+ return;
-+
- /*
- * Fetch the list head (which was registered earlier, via
- * sys_set_robust_list()):
-@@ -115,6 +118,9 @@
- compat_sys_set_robust_list(struct compat_robust_list_head __user *head,
- compat_size_t len)
- {
-+ if (!futex_cmpxchg_enabled)
-+ return -ENOSYS;
-+
- if (unlikely(len != sizeof(*head)))
- return -EINVAL;
-
-@@ -130,6 +136,9 @@
- struct compat_robust_list_head __user *head;
- unsigned long ret;
-
-+ if (!futex_cmpxchg_enabled)
-+ return -ENOSYS;
-+
- if (!pid)
- head = current->compat_robust_list;
- else {
-@@ -175,7 +184,7 @@
-
- t = timespec_to_ktime(ts);
- if (cmd == FUTEX_WAIT)
-- t = ktime_add(ktime_get(), t);
-+ t = ktime_add_safe(ktime_get(), t);
- tp = &t;
- }
- if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE)
-diff -Nurd linux-2.6.24/kernel/hrtimer.c linux-2.6.24-oxe810/kernel/hrtimer.c
---- linux-2.6.24/kernel/hrtimer.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/hrtimer.c 2008-06-11 17:43:47.000000000 +0200
-@@ -325,6 +325,24 @@
- }
- #endif /* BITS_PER_LONG >= 64 */
-
-+/*
-+ * Add two ktime values and do a safety check for overflow:
-+ */
-+
-+ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs)
-+{
-+ ktime_t res = ktime_add(lhs, rhs);
-+
-+ /*
-+ * We use KTIME_SEC_MAX here, the maximum timeout which we can
-+ * return to user space in a timespec:
-+ */
-+ if (res.tv64 < 0 || res.tv64 < lhs.tv64 || res.tv64 < rhs.tv64)
-+ res = ktime_set(KTIME_SEC_MAX, 0);
-+
-+ return res;
-+}
-+
- /* High resolution timer related functions */
- #ifdef CONFIG_HIGH_RES_TIMERS
-
-@@ -409,6 +427,8 @@
- ktime_t expires = ktime_sub(timer->expires, base->offset);
- int res;
-
-+ WARN_ON_ONCE(timer->expires.tv64 < 0);
-+
- /*
- * When the callback is running, we do not reprogram the clock event
- * device. The timer callback is either running on a different CPU or
-@@ -419,6 +439,15 @@
- if (hrtimer_callback_running(timer))
- return 0;
-
-+ /*
-+ * CLOCK_REALTIME timer might be requested with an absolute
-+ * expiry time which is less than base->offset. Nothing wrong
-+ * about that, just avoid to call into the tick code, which
-+ * has now objections against negative expiry values.
-+ */
-+ if (expires.tv64 < 0)
-+ return -ETIME;
-+
- if (expires.tv64 >= expires_next->tv64)
- return 0;
-
-@@ -682,13 +711,7 @@
- */
- orun++;
- }
-- timer->expires = ktime_add(timer->expires, interval);
-- /*
-- * Make sure, that the result did not wrap with a very large
-- * interval.
-- */
-- if (timer->expires.tv64 < 0)
-- timer->expires = ktime_set(KTIME_SEC_MAX, 0);
-+ timer->expires = ktime_add_safe(timer->expires, interval);
-
- return orun;
- }
-@@ -839,7 +862,7 @@
- new_base = switch_hrtimer_base(timer, base);
-
- if (mode == HRTIMER_MODE_REL) {
-- tim = ktime_add(tim, new_base->get_time());
-+ tim = ktime_add_safe(tim, new_base->get_time());
- /*
- * CONFIG_TIME_LOW_RES is a temporary way for architectures
- * to signal that they simply return xtime in
-@@ -848,16 +871,8 @@
- * timeouts. This will go away with the GTOD framework.
- */
- #ifdef CONFIG_TIME_LOW_RES
-- tim = ktime_add(tim, base->resolution);
-+ tim = ktime_add_safe(tim, base->resolution);
- #endif
-- /*
-- * Careful here: User space might have asked for a
-- * very long sleep, so the add above might result in a
-- * negative number, which enqueues the timer in front
-- * of the queue.
-- */
-- if (tim.tv64 < 0)
-- tim.tv64 = KTIME_MAX;
- }
- timer->expires = tim;
-
-@@ -1291,11 +1306,26 @@
- return t->task == NULL;
- }
-
-+static int update_rmtp(struct hrtimer *timer, struct timespec __user *rmtp)
-+{
-+ struct timespec rmt;
-+ ktime_t rem;
-+
-+ rem = ktime_sub(timer->expires, timer->base->get_time());
-+ if (rem.tv64 <= 0)
-+ return 0;
-+ rmt = ktime_to_timespec(rem);
-+
-+ if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
-+ return -EFAULT;
-+
-+ return 1;
-+}
-+
- long __sched hrtimer_nanosleep_restart(struct restart_block *restart)
- {
- struct hrtimer_sleeper t;
-- struct timespec *rmtp;
-- ktime_t time;
-+ struct timespec __user *rmtp;
-
- restart->fn = do_no_restart_syscall;
-
-@@ -1305,12 +1335,11 @@
- if (do_nanosleep(&t, HRTIMER_MODE_ABS))
- return 0;
-
-- rmtp = (struct timespec *)restart->arg1;
-+ rmtp = (struct timespec __user *)restart->arg1;
- if (rmtp) {
-- time = ktime_sub(t.timer.expires, t.timer.base->get_time());
-- if (time.tv64 <= 0)
-- return 0;
-- *rmtp = ktime_to_timespec(time);
-+ int ret = update_rmtp(&t.timer, rmtp);
-+ if (ret <= 0)
-+ return ret;
- }
-
- restart->fn = hrtimer_nanosleep_restart;
-@@ -1319,12 +1348,11 @@
- return -ERESTART_RESTARTBLOCK;
- }
-
--long hrtimer_nanosleep(struct timespec *rqtp, struct timespec *rmtp,
-+long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
- const enum hrtimer_mode mode, const clockid_t clockid)
- {
- struct restart_block *restart;
- struct hrtimer_sleeper t;
-- ktime_t rem;
-
- hrtimer_init(&t.timer, clockid, mode);
- t.timer.expires = timespec_to_ktime(*rqtp);
-@@ -1336,10 +1364,9 @@
- return -ERESTARTNOHAND;
-
- if (rmtp) {
-- rem = ktime_sub(t.timer.expires, t.timer.base->get_time());
-- if (rem.tv64 <= 0)
-- return 0;
-- *rmtp = ktime_to_timespec(rem);
-+ int ret = update_rmtp(&t.timer, rmtp);
-+ if (ret <= 0)
-+ return ret;
- }
-
- restart = ¤t_thread_info()->restart_block;
-@@ -1355,8 +1382,7 @@
- asmlinkage long
- sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp)
- {
-- struct timespec tu, rmt;
-- int ret;
-+ struct timespec tu;
-
- if (copy_from_user(&tu, rqtp, sizeof(tu)))
- return -EFAULT;
-@@ -1364,15 +1390,7 @@
- if (!timespec_valid(&tu))
- return -EINVAL;
-
-- ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL,
-- CLOCK_MONOTONIC);
--
-- if (ret && rmtp) {
-- if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
-- return -EFAULT;
-- }
--
-- return ret;
-+ return hrtimer_nanosleep(&tu, rmtp, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
- }
-
- /*
-diff -Nurd linux-2.6.24/kernel/irq/chip.c linux-2.6.24-oxe810/kernel/irq/chip.c
---- linux-2.6.24/kernel/irq/chip.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/irq/chip.c 2008-06-11 17:43:44.000000000 +0200
-@@ -246,6 +246,17 @@
- }
-
- /*
-+ * default shutdown function
-+ */
-+static void default_shutdown(unsigned int irq)
-+{
-+ struct irq_desc *desc = irq_desc + irq;
-+
-+ desc->chip->mask(irq);
-+ desc->status |= IRQ_MASKED;
-+}
-+
-+/*
- * Fixup enable/disable function pointers
- */
- void irq_chip_set_defaults(struct irq_chip *chip)
-@@ -256,8 +267,15 @@
- chip->disable = default_disable;
- if (!chip->startup)
- chip->startup = default_startup;
-+ /*
-+ * We use chip->disable, when the user provided its own. When
-+ * we have default_disable set for chip->disable, then we need
-+ * to use default_shutdown, otherwise the irq line is not
-+ * disabled on free_irq():
-+ */
- if (!chip->shutdown)
-- chip->shutdown = chip->disable;
-+ chip->shutdown = chip->disable != default_disable ?
-+ chip->disable : default_shutdown;
- if (!chip->name)
- chip->name = chip->typename;
- if (!chip->end)
-@@ -589,3 +607,39 @@
- set_irq_chip(irq, chip);
- __set_irq_handler(irq, handle, 0, name);
- }
-+
-+void __init set_irq_noprobe(unsigned int irq)
-+{
-+ struct irq_desc *desc;
-+ unsigned long flags;
-+
-+ if (irq >= NR_IRQS) {
-+ printk(KERN_ERR "Trying to mark IRQ%d non-probeable\n", irq);
-+
-+ return;
-+ }
-+
-+ desc = irq_desc + irq;
-+
-+ spin_lock_irqsave(&desc->lock, flags);
-+ desc->status |= IRQ_NOPROBE;
-+ spin_unlock_irqrestore(&desc->lock, flags);
-+}
-+
-+void __init set_irq_probe(unsigned int irq)
-+{
-+ struct irq_desc *desc;
-+ unsigned long flags;
-+
-+ if (irq >= NR_IRQS) {
-+ printk(KERN_ERR "Trying to mark IRQ%d probeable\n", irq);
-+
-+ return;
-+ }
-+
-+ desc = irq_desc + irq;
-+
-+ spin_lock_irqsave(&desc->lock, flags);
-+ desc->status &= ~IRQ_NOPROBE;
-+ spin_unlock_irqrestore(&desc->lock, flags);
-+}
-diff -Nurd linux-2.6.24/kernel/posix-timers.c linux-2.6.24-oxe810/kernel/posix-timers.c
---- linux-2.6.24/kernel/posix-timers.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/posix-timers.c 2008-06-11 17:43:47.000000000 +0200
-@@ -766,9 +766,11 @@
- /* SIGEV_NONE timers are not queued ! See common_timer_get */
- if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) {
- /* Setup correct expiry time for relative timers */
-- if (mode == HRTIMER_MODE_REL)
-- timer->expires = ktime_add(timer->expires,
-- timer->base->get_time());
-+ if (mode == HRTIMER_MODE_REL) {
-+ timer->expires =
-+ ktime_add_safe(timer->expires,
-+ timer->base->get_time());
-+ }
- return 0;
- }
-
-@@ -981,20 +983,9 @@
- static int common_nsleep(const clockid_t which_clock, int flags,
- struct timespec *tsave, struct timespec __user *rmtp)
- {
-- struct timespec rmt;
-- int ret;
--
-- ret = hrtimer_nanosleep(tsave, rmtp ? &rmt : NULL,
-- flags & TIMER_ABSTIME ?
-- HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
-- which_clock);
--
-- if (ret && rmtp) {
-- if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
-- return -EFAULT;
-- }
--
-- return ret;
-+ return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ?
-+ HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
-+ which_clock);
- }
-
- asmlinkage long
-diff -Nurd linux-2.6.24/kernel/printk.c linux-2.6.24-oxe810/kernel/printk.c
---- linux-2.6.24/kernel/printk.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/printk.c 2008-06-11 17:43:47.000000000 +0200
-@@ -625,6 +625,11 @@
- return r;
- }
-
-+#if defined(CONFIG_DEBUG_LL) && defined(CONFIG_OXNAS_EARLY_PRINTK)
-+/* Declare the printascii function that is specific to ARM platforms */
-+extern void printascii(const char *);
-+#endif
-+
- /* cpu currently holding logbuf_lock */
- static volatile unsigned int printk_cpu = UINT_MAX;
-
-@@ -653,6 +658,11 @@
- /* Emit the output into the temporary buffer */
- printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args);
-
-+#if defined(CONFIG_DEBUG_LL) && defined(CONFIG_OXNAS_EARLY_PRINTK)
-+ /* Send output down the early UART */
-+ printascii(printk_buf);
-+#endif
-+
- /*
- * Copy the output into log_buf. If the caller didn't provide
- * appropriate log level tags, we insert them here
-diff -Nurd linux-2.6.24/kernel/relay.c linux-2.6.24-oxe810/kernel/relay.c
---- linux-2.6.24/kernel/relay.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/relay.c 2008-06-11 17:43:47.000000000 +0200
-@@ -92,6 +92,7 @@
- return -EINVAL;
-
- vma->vm_ops = &relay_file_mmap_ops;
-+ vma->vm_flags |= VM_DONTEXPAND;
- vma->vm_private_data = buf;
- buf->chan->cb->buf_mapped(buf, filp);
-
-@@ -1071,7 +1072,7 @@
- unsigned int flags,
- int *nonpad_ret)
- {
-- unsigned int pidx, poff, total_len, subbuf_pages, ret;
-+ unsigned int pidx, poff, total_len, subbuf_pages, nr_pages, ret;
- struct rchan_buf *rbuf = in->private_data;
- unsigned int subbuf_size = rbuf->chan->subbuf_size;
- uint64_t pos = (uint64_t) *ppos;
-@@ -1102,8 +1103,9 @@
- subbuf_pages = rbuf->chan->alloc_size >> PAGE_SHIFT;
- pidx = (read_start / PAGE_SIZE) % subbuf_pages;
- poff = read_start & ~PAGE_MASK;
-+ nr_pages = min_t(unsigned int, subbuf_pages, PIPE_BUFFERS);
-
-- for (total_len = 0; spd.nr_pages < subbuf_pages; spd.nr_pages++) {
-+ for (total_len = 0; spd.nr_pages < nr_pages; spd.nr_pages++) {
- unsigned int this_len, this_end, private;
- unsigned int cur_pos = read_start + total_len;
-
-diff -Nurd linux-2.6.24/kernel/sched.c linux-2.6.24-oxe810/kernel/sched.c
---- linux-2.6.24/kernel/sched.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/sched.c 2008-06-11 17:43:47.000000000 +0200
-@@ -4028,11 +4028,10 @@
- oldprio = p->prio;
- on_rq = p->se.on_rq;
- running = task_current(rq, p);
-- if (on_rq) {
-+ if (on_rq)
- dequeue_task(rq, p, 0);
-- if (running)
-- p->sched_class->put_prev_task(rq, p);
-- }
-+ if (running)
-+ p->sched_class->put_prev_task(rq, p);
-
- if (rt_prio(prio))
- p->sched_class = &rt_sched_class;
-@@ -4041,9 +4040,9 @@
-
- p->prio = prio;
-
-+ if (running)
-+ p->sched_class->set_curr_task(rq);
- if (on_rq) {
-- if (running)
-- p->sched_class->set_curr_task(rq);
- enqueue_task(rq, p, 0);
- /*
- * Reschedule if we are currently running on this runqueue and
-@@ -4339,18 +4338,17 @@
- update_rq_clock(rq);
- on_rq = p->se.on_rq;
- running = task_current(rq, p);
-- if (on_rq) {
-+ if (on_rq)
- deactivate_task(rq, p, 0);
-- if (running)
-- p->sched_class->put_prev_task(rq, p);
-- }
-+ if (running)
-+ p->sched_class->put_prev_task(rq, p);
-
- oldprio = p->prio;
- __setscheduler(rq, p, policy, param->sched_priority);
-
-+ if (running)
-+ p->sched_class->set_curr_task(rq);
- if (on_rq) {
-- if (running)
-- p->sched_class->set_curr_task(rq);
- activate_task(rq, p, 0);
- /*
- * Reschedule if we are currently running on this runqueue and
-@@ -7110,19 +7108,17 @@
- running = task_current(rq, tsk);
- on_rq = tsk->se.on_rq;
-
-- if (on_rq) {
-+ if (on_rq)
- dequeue_task(rq, tsk, 0);
-- if (unlikely(running))
-- tsk->sched_class->put_prev_task(rq, tsk);
-- }
-+ if (unlikely(running))
-+ tsk->sched_class->put_prev_task(rq, tsk);
-
- set_task_cfs_rq(tsk, task_cpu(tsk));
-
-- if (on_rq) {
-- if (unlikely(running))
-- tsk->sched_class->set_curr_task(rq);
-+ if (unlikely(running))
-+ tsk->sched_class->set_curr_task(rq);
-+ if (on_rq)
- enqueue_task(rq, tsk, 0);
-- }
-
- done:
- task_rq_unlock(rq, &flags);
-diff -Nurd linux-2.6.24/kernel/sched_fair.c linux-2.6.24-oxe810/kernel/sched_fair.c
---- linux-2.6.24/kernel/sched_fair.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/sched_fair.c 2008-06-11 17:43:47.000000000 +0200
-@@ -511,7 +511,7 @@
-
- if (!initial) {
- /* sleeps upto a single latency don't count. */
-- if (sched_feat(NEW_FAIR_SLEEPERS) && entity_is_task(se))
-+ if (sched_feat(NEW_FAIR_SLEEPERS))
- vruntime -= sysctl_sched_latency;
-
- /* ensure we never gain time by being placed backwards. */
-@@ -867,7 +867,11 @@
- }
-
- gran = sysctl_sched_wakeup_granularity;
-- if (unlikely(se->load.weight != NICE_0_LOAD))
-+ /*
-+ * More easily preempt - nice tasks, while not making
-+ * it harder for + nice tasks.
-+ */
-+ if (unlikely(se->load.weight > NICE_0_LOAD))
- gran = calc_delta_fair(gran, &se->load);
-
- if (pse->vruntime + gran < se->vruntime)
-diff -Nurd linux-2.6.24/kernel/softirq.c linux-2.6.24-oxe810/kernel/softirq.c
---- linux-2.6.24/kernel/softirq.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/softirq.c 2008-06-11 17:43:47.000000000 +0200
-@@ -72,7 +72,7 @@
- {
- unsigned long flags;
-
-- WARN_ON_ONCE(in_irq());
-+ //WARN_ON_ONCE(in_irq());
-
- raw_local_irq_save(flags);
- add_preempt_count(SOFTIRQ_OFFSET);
-@@ -134,9 +134,9 @@
- #ifdef CONFIG_TRACE_IRQFLAGS
- unsigned long flags;
-
-- WARN_ON_ONCE(in_irq());
-+ //WARN_ON_ONCE(in_irq());
- #endif
-- WARN_ON_ONCE(irqs_disabled());
-+ //WARN_ON_ONCE(irqs_disabled());
-
- #ifdef CONFIG_TRACE_IRQFLAGS
- local_irq_save(flags);
-diff -Nurd linux-2.6.24/kernel/sysctl.c linux-2.6.24-oxe810/kernel/sysctl.c
---- linux-2.6.24/kernel/sysctl.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/kernel/sysctl.c 2008-06-11 17:43:47.000000000 +0200
-@@ -306,7 +306,7 @@
- .procname = "sched_nr_migrate",
- .data = &sysctl_sched_nr_migrate,
- .maxlen = sizeof(unsigned int),
-- .mode = 644,
-+ .mode = 0644,
- .proc_handler = &proc_dointvec,
- },
- #endif
-@@ -910,7 +910,7 @@
- .data = &nr_overcommit_huge_pages,
- .maxlen = sizeof(nr_overcommit_huge_pages),
- .mode = 0644,
-- .proc_handler = &proc_doulongvec_minmax,
-+ .proc_handler = &hugetlb_overcommit_handler,
- },
- #endif
- {
-diff -Nurd linux-2.6.24/mm/filemap.c linux-2.6.24-oxe810/mm/filemap.c
---- linux-2.6.24/mm/filemap.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/mm/filemap.c 2008-06-11 17:47:28.000000000 +0200
-@@ -884,12 +884,31 @@
- unsigned int prev_offset;
- int error;
-
-- index = *ppos >> PAGE_CACHE_SHIFT;
-+ // Page table mod's
-+#define MAX_QUEUED_PAGES (65536/PAGE_CACHE_SIZE)
-+ // Create the page table
-+ struct page* page_table[MAX_QUEUED_PAGES];
-+ pgoff_t start_index;
-+ unsigned long loop_offset;
-+ unsigned long transfer_count;
-+ unsigned long start_desc_count;
-+ unsigned long index_count;
-+ unsigned long desc_remaining;
-+
-+
-+ index = *ppos >> PAGE_CACHE_SHIFT;
- prev_index = ra->prev_pos >> PAGE_CACHE_SHIFT;
- prev_offset = ra->prev_pos & (PAGE_CACHE_SIZE-1);
- last_index = (*ppos + desc->count + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT;
- offset = *ppos & ~PAGE_CACHE_MASK;
-
-+ // Page table mod's
-+ start_index = index;
-+ index_count = 0;
-+ transfer_count = 0;
-+ desc_remaining = desc->count;
-+ loop_offset = offset;
-+
- for (;;) {
- struct page *page;
- pgoff_t end_index;
-@@ -935,12 +954,12 @@
- nr = PAGE_CACHE_SIZE;
- if (index == end_index) {
- nr = ((isize - 1) & ~PAGE_CACHE_MASK) + 1;
-- if (nr <= offset) {
-+ if (nr <= loop_offset) {
- page_cache_release(page);
- goto out;
- }
- }
-- nr = nr - offset;
-+ nr = nr - loop_offset;
-
- /* If users can be writing to this page using arbitrary
- * virtual addresses, take care about potential aliasing
-@@ -953,30 +972,84 @@
- * When a sequential read accesses a page several times,
- * only mark it as accessed the first time.
- */
-- if (prev_index != index || offset != prev_offset)
-+ if (prev_index != index || loop_offset != prev_offset)
- mark_page_accessed(page);
- prev_index = index;
-
- /*
- * Ok, we have the page, and it's up-to-date, so
-- * now we can copy it to user space...
-- *
-- * The actor routine returns how many bytes were actually used..
-- * NOTE! This may not be the same as how much of a user buffer
-- * we filled up (we may be padding etc), so we can only update
-- * "pos" here (the actor routine has to update the user buffer
-- * pointers and the remaining count).
-+ * now we can mark it for copy it to user space...
- */
-- ret = actor(desc, page, offset, nr);
-- offset += ret;
-- index += offset >> PAGE_CACHE_SHIFT;
-- offset &= ~PAGE_CACHE_MASK;
-- prev_offset = offset;
-+ page_table[index_count] = page;
-
-- page_cache_release(page);
-- if (ret == nr && desc->count)
-- continue;
-- goto out;
-+ index_count++;
-+
-+ transfer_count += nr;
-+
-+ if (transfer_count >= desc->count) {
-+ loop_offset += desc_remaining;
-+ index += loop_offset >> PAGE_CACHE_SHIFT;
-+ loop_offset &= ~PAGE_CACHE_MASK;
-+ desc_remaining = 0;
-+ } else {
-+ loop_offset = 0;
-+ index++;
-+ desc_remaining -= nr;
-+ }
-+
-+ prev_offset = loop_offset;
-+ //ra.prev_offset = loop_offset;
-+
-+ /**
-+ * Do we have enough data in the pages so far, or enough
-+ * pages left, to satisfy the count specified in the descriptor ?
-+ */
-+ if ((transfer_count < desc->count) && (index <= end_index) && (index_count < MAX_QUEUED_PAGES)) {
-+ continue;
-+ }
-+
-+ /*
-+ * The actor routine returns how many bytes were actually used..
-+ * NOTE! This may not be the same as how much of a user buffer
-+ * we filled up (we may be padding etc), so we can only update
-+ * "pos" here (the actor routine has to update the user buffer
-+ * pointers and the remaining count).
-+ */
-+
-+ start_desc_count = desc->count;
-+
-+ ret = actor(desc, page_table, offset, transfer_count);
-+
-+ /*
-+ * Some debug to test if our assumptions about the transfer length are correct
-+ * We shouldn't see this message under normal execution
-+ */
-+
-+ if ((start_desc_count != ret) && (transfer_count != ret)) {
-+ printk("desc_count %#x, ret %#x, transfer_count %#x\n",start_desc_count,ret, transfer_count);
-+ }
-+
-+ offset += ret;
-+ index = start_index + (offset >> PAGE_CACHE_SHIFT);
-+
-+ offset &= ~PAGE_CACHE_MASK;
-+ //ra.prev_offset = offset;
-+
-+ while (index_count) {
-+ index_count--;
-+ page_cache_release(page_table[index_count]);
-+ }
-+
-+ if (ret == transfer_count && desc->count) {
-+ // should probably think of what to do...
-+ index_count = 0;
-+ start_index = index;
-+ transfer_count = 0;
-+ loop_offset = offset;
-+ desc_remaining = desc->count;
-+ continue;
-+ }
-+ goto out;
-
- page_not_up_to_date:
- /* Get exclusive access to the page ... */
-@@ -1056,6 +1129,7 @@
- goto readpage;
- }
-
-+
- out:
- ra->prev_pos = prev_index;
- ra->prev_pos <<= PAGE_CACHE_SHIFT;
-@@ -1067,42 +1141,96 @@
- }
- EXPORT_SYMBOL(do_generic_mapping_read);
-
--int file_read_actor(read_descriptor_t *desc, struct page *page,
-+int file_read_actor(read_descriptor_t *desc, struct page **page,
- unsigned long offset, unsigned long size)
- {
- char *kaddr;
- unsigned long left, count = desc->count;
-+ unsigned char* dst;
-+ unsigned long ret_size;
-+
-
- if (size > count)
- size = count;
-
-+ ret_size = size;
-+
-+ dst = desc->arg.buf;
-+
- /*
- * Faults on the destination of a read are common, so do it before
- * taking the kmap.
- */
-- if (!fault_in_pages_writeable(desc->arg.buf, size)) {
-- kaddr = kmap_atomic(page, KM_USER0);
-- left = __copy_to_user_inatomic(desc->arg.buf,
-- kaddr + offset, size);
-- kunmap_atomic(kaddr, KM_USER0);
-- if (left == 0)
-- goto success;
-- }
-+ while (size) {
-+ unsigned long psize = PAGE_CACHE_SIZE - offset;
-+ struct page *page_it;
-+
-+ psize = PAGE_CACHE_SIZE - offset;
-+ if (size <= psize) {
-+ psize = size;
-+ }
-+
-+ if (fault_in_pages_writeable(dst, psize))
-+ break;
-+
-+ page_it = *page;
-+
-+ kaddr = kmap_atomic(page_it, KM_USER0);
-+ left = __copy_to_user_inatomic(dst,
-+ kaddr + offset, psize);
-+ kunmap_atomic(kaddr, KM_USE R0);
-+ if (left != 0)
-+ break;
-+
-+ size -= psize;
-+ page++;
-+ offset += psize;
-+ dst += psize;
-+ offset &= (PAGE_CACHE_SIZE - 1);
-+ }
-+
-+ if (size == 0)
-+ goto success;
-+
-
- /* Do it the slow way */
-- kaddr = kmap(page);
-- left = __copy_to_user(desc->arg.buf, kaddr + offset, size);
-- kunmap(page);
-
-- if (left) {
-- size -= left;
-- desc->error = -EFAULT;
-- }
-+
-+ while (size) {
-+ unsigned long psize;
-+ struct page *page_it;
-+
-+ psize = PAGE_CACHE_SIZE - offset;
-+ if (size <= psize) {
-+ psize = size;
-+ }
-+
-+
-+ page_it = *page;
-+
-+ kaddr = kmap(page_it);
-+
-+ left = __copy_to_user(dst, kaddr + offset, psize);
-+ kunmap(page_it);
-+
-+ if (left) {
-+ size -= left;
-+ desc->error = -EFAULT;
-+ break;
-+ }
-+ page++;
-+ offset += psize;
-+ dst += psize;
-+ offset &= (PAGE_CACHE_SIZE - 1);
-+
-+ size -= psize;
-+ }
-+
- success:
-- desc->count = count - size;
-- desc->written += size;
-- desc->arg.buf += size;
-- return size;
-+ desc->count = count - ret_size;
-+ desc->written += ret_size;
-+ desc->arg.buf += ret_size;
-+ return ret_size;
- }
-
- /*
-@@ -1219,6 +1347,46 @@
- }
- EXPORT_SYMBOL(generic_file_aio_read);
-
-+int file_send_actor(read_descriptor_t * desc, struct page **page, unsigned long offset, unsigned long size)
-+{
-+ ssize_t written;
-+ unsigned long count = desc->count;
-+ struct file *file = desc->arg.data;
-+
-+ if (size > count)
-+ size = count;
-+
-+ written = file->f_op->sendpages(file, page, offset,
-+ size, &file->f_pos, size<count);
-+ if (written < 0) {
-+ desc->error = written;
-+ written = 0;
-+ }
-+ desc->count = count - written;
-+ desc->written += written;
-+ return written;
-+}
-+
-+ssize_t generic_file_sendfile(struct file *in_file, loff_t *ppos,
-+ size_t count, read_actor_t actor, void *target)
-+{
-+ read_descriptor_t desc;
-+
-+ if (!count)
-+ return 0;
-+
-+ desc.written = 0;
-+ desc.count = count;
-+ desc.arg.data = target;
-+ desc.error = 0;
-+
-+ do_generic_file_read(in_file, ppos, &desc, actor);
-+ if (desc.written)
-+ return desc.written;
-+ return desc.error;
-+}
-+EXPORT_SYMBOL(generic_file_sendfile);
-+
- static ssize_t
- do_readahead(struct address_space *mapping, struct file *filp,
- pgoff_t index, unsigned long nr)
-@@ -1725,17 +1893,27 @@
- }
- EXPORT_SYMBOL(iov_iter_copy_from_user);
-
--static void __iov_iter_advance_iov(struct iov_iter *i, size_t bytes)
-+void iov_iter_advance(struct iov_iter *i, size_t bytes)
- {
-+ BUG_ON(i->count < bytes);
-+
- if (likely(i->nr_segs == 1)) {
- i->iov_offset += bytes;
-+ i->count -= bytes;
- } else {
- const struct iovec *iov = i->iov;
- size_t base = i->iov_offset;
-
-- while (bytes) {
-- int copy = min(bytes, iov->iov_len - base);
-+ /*
-+ * The !iov->iov_len check ensures we skip over unlikely
-+ * zero-length segments (without overruning the iovec).
-+ */
-+ while (bytes || unlikely(!iov->iov_len && i->count)) {
-+ int copy;
-
-+ copy = min(bytes, iov->iov_len - base);
-+ BUG_ON(!i->count || i->count < copy);
-+ i->count -= copy;
- bytes -= copy;
- base += copy;
- if (iov->iov_len == base) {
-@@ -1747,14 +1925,6 @@
- i->iov_offset = base;
- }
- }
--
--void iov_iter_advance(struct iov_iter *i, size_t bytes)
--{
-- BUG_ON(i->count < bytes);
--
-- __iov_iter_advance_iov(i, bytes);
-- i->count -= bytes;
--}
- EXPORT_SYMBOL(iov_iter_advance);
-
- /*
-@@ -2251,6 +2421,7 @@
-
- cond_resched();
-
-+ iov_iter_advance(i, copied);
- if (unlikely(copied == 0)) {
- /*
- * If we were unable to copy any data at all, we must
-@@ -2264,7 +2435,6 @@
- iov_iter_single_seg_count(i));
- goto again;
- }
-- iov_iter_advance(i, copied);
- pos += copied;
- written += copied;
-
-diff -Nurd linux-2.6.24/mm/fremap.c linux-2.6.24-oxe810/mm/fremap.c
---- linux-2.6.24/mm/fremap.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/mm/fremap.c 2008-06-11 17:47:28.000000000 +0200
-@@ -190,10 +190,13 @@
- */
- if (mapping_cap_account_dirty(mapping)) {
- unsigned long addr;
-+ struct file *file = vma->vm_file;
-
- flags &= MAP_NONBLOCK;
-- addr = mmap_region(vma->vm_file, start, size,
-+ get_file(file);
-+ addr = mmap_region(file, start, size,
- flags, vma->vm_flags, pgoff, 1);
-+ fput(file);
- if (IS_ERR_VALUE(addr)) {
- err = addr;
- } else {
-diff -Nurd linux-2.6.24/mm/hugetlb.c linux-2.6.24-oxe810/mm/hugetlb.c
---- linux-2.6.24/mm/hugetlb.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/mm/hugetlb.c 2008-06-11 17:47:28.000000000 +0200
-@@ -119,6 +119,7 @@
- struct address_space *mapping;
-
- mapping = (struct address_space *) page_private(page);
-+ set_page_private(page, 0);
- BUG_ON(page_count(page));
- INIT_LIST_HEAD(&page->lru);
-
-@@ -133,7 +134,6 @@
- spin_unlock(&hugetlb_lock);
- if (mapping)
- hugetlb_put_quota(mapping, 1);
-- set_page_private(page, 0);
- }
-
- /*
-@@ -605,6 +605,16 @@
- return 0;
- }
-
-+int hugetlb_overcommit_handler(struct ctl_table *table, int write,
-+ struct file *file, void __user *buffer,
-+ size_t *length, loff_t *ppos)
-+{
-+ spin_lock(&hugetlb_lock);
-+ proc_doulongvec_minmax(table, write, file, buffer, length, ppos);
-+ spin_unlock(&hugetlb_lock);
-+ return 0;
-+}
-+
- #endif /* CONFIG_SYSCTL */
-
- int hugetlb_report_meminfo(char *buf)
-diff -Nurd linux-2.6.24/mm/memory.c linux-2.6.24-oxe810/mm/memory.c
---- linux-2.6.24/mm/memory.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/mm/memory.c 2008-06-11 17:47:28.000000000 +0200
-@@ -980,6 +980,8 @@
- int i;
- unsigned int vm_flags;
-
-+ if (len <= 0)
-+ return 0;
- /*
- * Require read or write permissions.
- * If 'force' is set, we only require the "MAY" flags.
-diff -Nurd linux-2.6.24/mm/mmap.c linux-2.6.24-oxe810/mm/mmap.c
---- linux-2.6.24/mm/mmap.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/mm/mmap.c 2008-06-11 17:47:28.000000000 +0200
-@@ -2215,7 +2215,7 @@
- vma->vm_start = addr;
- vma->vm_end = addr + len;
-
-- vma->vm_flags = vm_flags | mm->def_flags;
-+ vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
- vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
-
- vma->vm_ops = &special_mapping_vmops;
-diff -Nurd linux-2.6.24/mm/shmem.c linux-2.6.24-oxe810/mm/shmem.c
---- linux-2.6.24/mm/shmem.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/mm/shmem.c 2008-06-11 17:47:28.000000000 +0200
-@@ -1681,7 +1681,7 @@
- * "pos" here (the actor routine has to update the user buffer
- * pointers and the remaining count).
- */
-- ret = actor(desc, page, offset, nr);
-+ ret = actor(desc, &page, offset, nr);
- offset += ret;
- index += offset >> PAGE_CACHE_SHIFT;
- offset &= ~PAGE_CACHE_MASK;
-diff -Nurd linux-2.6.24/mm/slab.c linux-2.6.24-oxe810/mm/slab.c
---- linux-2.6.24/mm/slab.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/mm/slab.c 2008-06-11 17:47:28.000000000 +0200
-@@ -304,11 +304,11 @@
- /*
- * Need this for bootstrapping a per node allocator.
- */
--#define NUM_INIT_LISTS (2 * MAX_NUMNODES + 1)
-+#define NUM_INIT_LISTS (3 * MAX_NUMNODES)
- struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
- #define CACHE_CACHE 0
--#define SIZE_AC 1
--#define SIZE_L3 (1 + MAX_NUMNODES)
-+#define SIZE_AC MAX_NUMNODES
-+#define SIZE_L3 (2 * MAX_NUMNODES)
-
- static int drain_freelist(struct kmem_cache *cache,
- struct kmem_list3 *l3, int tofree);
-@@ -1410,6 +1410,22 @@
- }
-
- /*
-+ * For setting up all the kmem_list3s for cache whose buffer_size is same as
-+ * size of kmem_list3.
-+ */
-+static void __init set_up_list3s(struct kmem_cache *cachep, int index)
-+{
-+ int node;
-+
-+ for_each_online_node(node) {
-+ cachep->nodelists[node] = &initkmem_list3[index + node];
-+ cachep->nodelists[node]->next_reap = jiffies +
-+ REAPTIMEOUT_LIST3 +
-+ ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
-+ }
-+}
-+
-+/*
- * Initialisation. Called after the page allocator have been initialised and
- * before smp_init().
- */
-@@ -1432,6 +1448,7 @@
- if (i < MAX_NUMNODES)
- cache_cache.nodelists[i] = NULL;
- }
-+ set_up_list3s(&cache_cache, CACHE_CACHE);
-
- /*
- * Fragmentation resistance on low memory - only use bigger
-@@ -1587,10 +1604,9 @@
- {
- int nid;
-
-- /* Replace the static kmem_list3 structures for the boot cpu */
-- init_list(&cache_cache, &initkmem_list3[CACHE_CACHE], node);
--
- for_each_online_node(nid) {
-+ init_list(&cache_cache, &initkmem_list3[CACHE_CACHE], nid);
-+
- init_list(malloc_sizes[INDEX_AC].cs_cachep,
- &initkmem_list3[SIZE_AC + nid], nid);
-
-@@ -1960,22 +1976,6 @@
- }
- }
-
--/*
-- * For setting up all the kmem_list3s for cache whose buffer_size is same as
-- * size of kmem_list3.
-- */
--static void __init set_up_list3s(struct kmem_cache *cachep, int index)
--{
-- int node;
--
-- for_each_online_node(node) {
-- cachep->nodelists[node] = &initkmem_list3[index + node];
-- cachep->nodelists[node]->next_reap = jiffies +
-- REAPTIMEOUT_LIST3 +
-- ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
-- }
--}
--
- static void __kmem_cache_destroy(struct kmem_cache *cachep)
- {
- int i;
-@@ -2099,7 +2099,7 @@
- g_cpucache_up = PARTIAL_L3;
- } else {
- int node;
-- for_each_node_state(node, N_NORMAL_MEMORY) {
-+ for_each_online_node(node) {
- cachep->nodelists[node] =
- kmalloc_node(sizeof(struct kmem_list3),
- GFP_KERNEL, node);
-@@ -2961,11 +2961,10 @@
- struct array_cache *ac;
- int node;
-
-- node = numa_node_id();
--
-+retry:
- check_irq_off();
-+ node = numa_node_id();
- ac = cpu_cache_get(cachep);
--retry:
- batchcount = ac->batchcount;
- if (!ac->touched && batchcount > BATCHREFILL_LIMIT) {
- /*
-diff -Nurd linux-2.6.24/mm/slub.c linux-2.6.24-oxe810/mm/slub.c
---- linux-2.6.24/mm/slub.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/mm/slub.c 2008-06-11 17:47:28.000000000 +0200
-@@ -2592,6 +2592,7 @@
- void kfree(const void *x)
- {
- struct page *page;
-+ void *object = (void *)x;
-
- if (unlikely(ZERO_OR_NULL_PTR(x)))
- return;
-@@ -2601,7 +2602,7 @@
- put_page(page);
- return;
- }
-- slab_free(page->slab, page, (void *)x, __builtin_return_address(0));
-+ slab_free(page->slab, page, object, __builtin_return_address(0));
- }
- EXPORT_SYMBOL(kfree);
-
-diff -Nurd linux-2.6.24/net/bluetooth/hci_sysfs.c linux-2.6.24-oxe810/net/bluetooth/hci_sysfs.c
---- linux-2.6.24/net/bluetooth/hci_sysfs.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/bluetooth/hci_sysfs.c 2008-06-11 17:46:02.000000000 +0200
-@@ -12,6 +12,8 @@
- #undef BT_DBG
- #define BT_DBG(D...)
- #endif
-+static struct workqueue_struct *btaddconn;
-+static struct workqueue_struct *btdelconn;
-
- static inline char *typetostr(int type)
- {
-@@ -279,6 +281,8 @@
- struct hci_conn *conn = container_of(work, struct hci_conn, work);
- int i;
-
-+ flush_workqueue(btdelconn);
-+
- if (device_add(&conn->dev) < 0) {
- BT_ERR("Failed to register connection device");
- return;
-@@ -313,7 +317,7 @@
-
- INIT_WORK(&conn->work, add_conn);
-
-- schedule_work(&conn->work);
-+ queue_work(btaddconn, &conn->work);
- }
-
- static int __match_tty(struct device *dev, void *data)
-@@ -349,7 +353,7 @@
-
- INIT_WORK(&conn->work, del_conn);
-
-- schedule_work(&conn->work);
-+ queue_work(btdelconn, &conn->work);
- }
-
- int hci_register_sysfs(struct hci_dev *hdev)
-@@ -398,28 +402,54 @@
- {
- int err;
-
-+ btaddconn = create_singlethread_workqueue("btaddconn");
-+ if (!btaddconn) {
-+ err = -ENOMEM;
-+ goto out;
-+ }
-+
-+ btdelconn = create_singlethread_workqueue("btdelconn");
-+ if (!btdelconn) {
-+ err = -ENOMEM;
-+ goto out_del;
-+ }
-+
- bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0);
-- if (IS_ERR(bt_platform))
-- return PTR_ERR(bt_platform);
-+ if (IS_ERR(bt_platform)) {
-+ err = PTR_ERR(bt_platform);
-+ goto out_platform;
-+ }
-
- err = bus_register(&bt_bus);
-- if (err < 0) {
-- platform_device_unregister(bt_platform);
-- return err;
-- }
-+ if (err < 0)
-+ goto out_bus;
-
- bt_class = class_create(THIS_MODULE, "bluetooth");
- if (IS_ERR(bt_class)) {
-- bus_unregister(&bt_bus);
-- platform_device_unregister(bt_platform);
-- return PTR_ERR(bt_class);
-+ err = PTR_ERR(bt_class);
-+ goto out_class;
- }
-
- return 0;
-+
-+out_class:
-+ bus_unregister(&bt_bus);
-+out_bus:
-+ platform_device_unregister(bt_platform);
-+out_platform:
-+ destroy_workqueue(btdelconn);
-+out_del:
-+ destroy_workqueue(btaddconn);
-+out:
-+ return err;
- }
-
- void bt_sysfs_cleanup(void)
- {
-+ destroy_workqueue(btaddconn);
-+
-+ destroy_workqueue(btdelconn);
-+
- class_destroy(bt_class);
-
- bus_unregister(&bt_bus);
-diff -Nurd linux-2.6.24/net/bridge/netfilter/ebt_dnat.c linux-2.6.24-oxe810/net/bridge/netfilter/ebt_dnat.c
---- linux-2.6.24/net/bridge/netfilter/ebt_dnat.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/bridge/netfilter/ebt_dnat.c 2008-06-11 17:46:12.000000000 +0200
-@@ -20,8 +20,8 @@
- {
- struct ebt_nat_info *info = (struct ebt_nat_info *)data;
-
-- if (skb_make_writable(skb, 0))
-- return NF_DROP;
-+ if (!skb_make_writable(skb, 0))
-+ return EBT_DROP;
-
- memcpy(eth_hdr(skb)->h_dest, info->mac, ETH_ALEN);
- return info->target;
-diff -Nurd linux-2.6.24/net/bridge/netfilter/ebt_redirect.c linux-2.6.24-oxe810/net/bridge/netfilter/ebt_redirect.c
---- linux-2.6.24/net/bridge/netfilter/ebt_redirect.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/bridge/netfilter/ebt_redirect.c 2008-06-11 17:46:12.000000000 +0200
-@@ -21,8 +21,8 @@
- {
- struct ebt_redirect_info *info = (struct ebt_redirect_info *)data;
-
-- if (skb_make_writable(skb, 0))
-- return NF_DROP;
-+ if (!skb_make_writable(skb, 0))
-+ return EBT_DROP;
-
- if (hooknr != NF_BR_BROUTING)
- memcpy(eth_hdr(skb)->h_dest,
-diff -Nurd linux-2.6.24/net/bridge/netfilter/ebt_snat.c linux-2.6.24-oxe810/net/bridge/netfilter/ebt_snat.c
---- linux-2.6.24/net/bridge/netfilter/ebt_snat.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/bridge/netfilter/ebt_snat.c 2008-06-11 17:46:12.000000000 +0200
-@@ -22,8 +22,8 @@
- {
- struct ebt_nat_info *info = (struct ebt_nat_info *) data;
-
-- if (skb_make_writable(skb, 0))
-- return NF_DROP;
-+ if (!skb_make_writable(skb, 0))
-+ return EBT_DROP;
-
- memcpy(eth_hdr(skb)->h_source, info->mac, ETH_ALEN);
- if (!(info->target & NAT_ARP_BIT) &&
-diff -Nurd linux-2.6.24/net/core/dev.c linux-2.6.24-oxe810/net/core/dev.c
---- linux-2.6.24/net/core/dev.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/core/dev.c 2008-06-11 17:45:57.000000000 +0200
-@@ -1068,8 +1068,6 @@
- */
- call_netdevice_notifiers(NETDEV_GOING_DOWN, dev);
-
-- dev_deactivate(dev);
--
- clear_bit(__LINK_STATE_START, &dev->state);
-
- /* Synchronize to scheduled poll. We cannot touch poll list,
-@@ -1080,6 +1078,8 @@
- */
- smp_mb__after_clear_bit(); /* Commit netif_running(). */
-
-+ dev_deactivate(dev);
-+
- /*
- * Call the device specific close. This cannot fail.
- * Only if device is UP
-@@ -2906,7 +2906,7 @@
- }
- }
-
-- da = kmalloc(sizeof(*da), GFP_ATOMIC);
-+ da = kzalloc(sizeof(*da), GFP_ATOMIC);
- if (da == NULL)
- return -ENOMEM;
- memcpy(da->da_addr, addr, alen);
-diff -Nurd linux-2.6.24/net/ipv4/af_inet.c linux-2.6.24-oxe810/net/ipv4/af_inet.c
---- linux-2.6.24/net/ipv4/af_inet.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/af_inet.c 2008-06-11 17:46:09.000000000 +0200
-@@ -838,6 +838,7 @@
- .recvmsg = sock_common_recvmsg,
- .mmap = sock_no_mmap,
- .sendpage = tcp_sendpage,
-+ .sendpages = tcp_sendpages,
- #ifdef CONFIG_COMPAT
- .compat_setsockopt = compat_sock_common_setsockopt,
- .compat_getsockopt = compat_sock_common_getsockopt,
-diff -Nurd linux-2.6.24/net/ipv4/fib_hash.c linux-2.6.24-oxe810/net/ipv4/fib_hash.c
---- linux-2.6.24/net/ipv4/fib_hash.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/fib_hash.c 2008-06-11 17:46:09.000000000 +0200
-@@ -434,19 +434,43 @@
-
- if (fa && fa->fa_tos == tos &&
- fa->fa_info->fib_priority == fi->fib_priority) {
-- struct fib_alias *fa_orig;
-+ struct fib_alias *fa_first, *fa_match;
-
- err = -EEXIST;
- if (cfg->fc_nlflags & NLM_F_EXCL)
- goto out;
-
-+ /* We have 2 goals:
-+ * 1. Find exact match for type, scope, fib_info to avoid
-+ * duplicate routes
-+ * 2. Find next 'fa' (or head), NLM_F_APPEND inserts before it
-+ */
-+ fa_match = NULL;
-+ fa_first = fa;
-+ fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
-+ list_for_each_entry_continue(fa, &f->fn_alias, fa_list) {
-+ if (fa->fa_tos != tos)
-+ break;
-+ if (fa->fa_info->fib_priority != fi->fib_priority)
-+ break;
-+ if (fa->fa_type == cfg->fc_type &&
-+ fa->fa_scope == cfg->fc_scope &&
-+ fa->fa_info == fi) {
-+ fa_match = fa;
-+ break;
-+ }
-+ }
-+
- if (cfg->fc_nlflags & NLM_F_REPLACE) {
- struct fib_info *fi_drop;
- u8 state;
-
-- if (fi->fib_treeref > 1)
-+ fa = fa_first;
-+ if (fa_match) {
-+ if (fa == fa_match)
-+ err = 0;
- goto out;
--
-+ }
- write_lock_bh(&fib_hash_lock);
- fi_drop = fa->fa_info;
- fa->fa_info = fi;
-@@ -469,20 +493,11 @@
- * uses the same scope, type, and nexthop
- * information.
- */
-- fa_orig = fa;
-- fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
-- list_for_each_entry_continue(fa, &f->fn_alias, fa_list) {
-- if (fa->fa_tos != tos)
-- break;
-- if (fa->fa_info->fib_priority != fi->fib_priority)
-- break;
-- if (fa->fa_type == cfg->fc_type &&
-- fa->fa_scope == cfg->fc_scope &&
-- fa->fa_info == fi)
-- goto out;
-- }
-+ if (fa_match)
-+ goto out;
-+
- if (!(cfg->fc_nlflags & NLM_F_APPEND))
-- fa = fa_orig;
-+ fa = fa_first;
- }
-
- err = -ENOENT;
-diff -Nurd linux-2.6.24/net/ipv4/fib_trie.c linux-2.6.24-oxe810/net/ipv4/fib_trie.c
---- linux-2.6.24/net/ipv4/fib_trie.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/fib_trie.c 2008-06-11 17:46:09.000000000 +0200
-@@ -1203,20 +1203,45 @@
- * and we need to allocate a new one of those as well.
- */
-
-- if (fa && fa->fa_info->fib_priority == fi->fib_priority) {
-- struct fib_alias *fa_orig;
-+ if (fa && fa->fa_tos == tos &&
-+ fa->fa_info->fib_priority == fi->fib_priority) {
-+ struct fib_alias *fa_first, *fa_match;
-
- err = -EEXIST;
- if (cfg->fc_nlflags & NLM_F_EXCL)
- goto out;
-
-+ /* We have 2 goals:
-+ * 1. Find exact match for type, scope, fib_info to avoid
-+ * duplicate routes
-+ * 2. Find next 'fa' (or head), NLM_F_APPEND inserts before it
-+ */
-+ fa_match = NULL;
-+ fa_first = fa;
-+ fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
-+ list_for_each_entry_continue(fa, fa_head, fa_list) {
-+ if (fa->fa_tos != tos)
-+ break;
-+ if (fa->fa_info->fib_priority != fi->fib_priority)
-+ break;
-+ if (fa->fa_type == cfg->fc_type &&
-+ fa->fa_scope == cfg->fc_scope &&
-+ fa->fa_info == fi) {
-+ fa_match = fa;
-+ break;
-+ }
-+ }
-+
- if (cfg->fc_nlflags & NLM_F_REPLACE) {
- struct fib_info *fi_drop;
- u8 state;
-
-- if (fi->fib_treeref > 1)
-+ fa = fa_first;
-+ if (fa_match) {
-+ if (fa == fa_match)
-+ err = 0;
- goto out;
--
-+ }
- err = -ENOBUFS;
- new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
- if (new_fa == NULL)
-@@ -1228,7 +1253,7 @@
- new_fa->fa_type = cfg->fc_type;
- new_fa->fa_scope = cfg->fc_scope;
- state = fa->fa_state;
-- new_fa->fa_state &= ~FA_S_ACCESSED;
-+ new_fa->fa_state = state & ~FA_S_ACCESSED;
-
- list_replace_rcu(&fa->fa_list, &new_fa->fa_list);
- alias_free_mem_rcu(fa);
-@@ -1245,20 +1270,11 @@
- * uses the same scope, type, and nexthop
- * information.
- */
-- fa_orig = fa;
-- list_for_each_entry(fa, fa_orig->fa_list.prev, fa_list) {
-- if (fa->fa_tos != tos)
-- break;
-- if (fa->fa_info->fib_priority != fi->fib_priority)
-- break;
-- if (fa->fa_type == cfg->fc_type &&
-- fa->fa_scope == cfg->fc_scope &&
-- fa->fa_info == fi) {
-- goto out;
-- }
-- }
-+ if (fa_match)
-+ goto out;
-+
- if (!(cfg->fc_nlflags & NLM_F_APPEND))
-- fa = fa_orig;
-+ fa = fa_first;
- }
- err = -ENOENT;
- if (!(cfg->fc_nlflags & NLM_F_CREATE))
-@@ -1614,9 +1630,8 @@
- pr_debug("Deleting %08x/%d tos=%d t=%p\n", key, plen, tos, t);
-
- fa_to_delete = NULL;
-- fa_head = fa->fa_list.prev;
--
-- list_for_each_entry(fa, fa_head, fa_list) {
-+ fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
-+ list_for_each_entry_continue(fa, fa_head, fa_list) {
- struct fib_info *fi = fa->fa_info;
-
- if (fa->fa_tos != tos)
-diff -Nurd linux-2.6.24/net/ipv4/inet_diag.c linux-2.6.24-oxe810/net/ipv4/inet_diag.c
---- linux-2.6.24/net/ipv4/inet_diag.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/inet_diag.c 2008-06-11 17:46:09.000000000 +0200
-@@ -259,8 +259,10 @@
- const struct inet_diag_handler *handler;
-
- handler = inet_diag_lock_handler(nlh->nlmsg_type);
-- if (!handler)
-- return -ENOENT;
-+ if (IS_ERR(handler)) {
-+ err = PTR_ERR(handler);
-+ goto unlock;
-+ }
-
- hashinfo = handler->idiag_hashinfo;
- err = -EINVAL;
-@@ -708,8 +710,8 @@
- struct inet_hashinfo *hashinfo;
-
- handler = inet_diag_lock_handler(cb->nlh->nlmsg_type);
-- if (!handler)
-- goto no_handler;
-+ if (IS_ERR(handler))
-+ goto unlock;
-
- hashinfo = handler->idiag_hashinfo;
-
-@@ -838,7 +840,6 @@
- cb->args[2] = num;
- unlock:
- inet_diag_unlock_handler(handler);
--no_handler:
- return skb->len;
- }
-
-diff -Nurd linux-2.6.24/net/ipv4/ip_output.c linux-2.6.24-oxe810/net/ipv4/ip_output.c
---- linux-2.6.24/net/ipv4/ip_output.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/ip_output.c 2008-06-11 17:46:09.000000000 +0200
-@@ -462,6 +462,7 @@
- if (skb_shinfo(skb)->frag_list) {
- struct sk_buff *frag;
- int first_len = skb_pagelen(skb);
-+ int truesizes = 0;
-
- if (first_len - hlen > mtu ||
- ((first_len - hlen) & 7) ||
-@@ -485,7 +486,7 @@
- sock_hold(skb->sk);
- frag->sk = skb->sk;
- frag->destructor = sock_wfree;
-- skb->truesize -= frag->truesize;
-+ truesizes += frag->truesize;
- }
- }
-
-@@ -496,6 +497,7 @@
- frag = skb_shinfo(skb)->frag_list;
- skb_shinfo(skb)->frag_list = NULL;
- skb->data_len = first_len - skb_headlen(skb);
-+ skb->truesize -= truesizes;
- skb->len = first_len;
- iph->tot_len = htons(first_len);
- iph->frag_off = htons(IP_MF);
-diff -Nurd linux-2.6.24/net/ipv4/ip_sockglue.c linux-2.6.24-oxe810/net/ipv4/ip_sockglue.c
---- linux-2.6.24/net/ipv4/ip_sockglue.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/ip_sockglue.c 2008-06-11 17:46:09.000000000 +0200
-@@ -514,11 +514,6 @@
- val &= ~3;
- val |= inet->tos & 3;
- }
-- if (IPTOS_PREC(val) >= IPTOS_PREC_CRITIC_ECP &&
-- !capable(CAP_NET_ADMIN)) {
-- err = -EPERM;
-- break;
-- }
- if (inet->tos != val) {
- inet->tos = val;
- sk->sk_priority = rt_tos2priority(val);
-diff -Nurd linux-2.6.24/net/ipv4/ipcomp.c linux-2.6.24-oxe810/net/ipv4/ipcomp.c
---- linux-2.6.24/net/ipv4/ipcomp.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/ipcomp.c 2008-06-11 17:46:09.000000000 +0200
-@@ -74,6 +74,7 @@
-
- static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb)
- {
-+ int nexthdr;
- int err = -ENOMEM;
- struct ip_comp_hdr *ipch;
-
-@@ -84,13 +85,15 @@
-
- /* Remove ipcomp header and decompress original payload */
- ipch = (void *)skb->data;
-+ nexthdr = ipch->nexthdr;
-+
- skb->transport_header = skb->network_header + sizeof(*ipch);
- __skb_pull(skb, sizeof(*ipch));
- err = ipcomp_decompress(x, skb);
- if (err)
- goto out;
-
-- err = ipch->nexthdr;
-+ err = nexthdr;
-
- out:
- return err;
-@@ -105,8 +108,11 @@
- const int cpu = get_cpu();
- u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu);
- struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu);
-- int err = crypto_comp_compress(tfm, start, plen, scratch, &dlen);
-+ int err;
-
-+ local_bh_disable();
-+ err = crypto_comp_compress(tfm, start, plen, scratch, &dlen);
-+ local_bh_enable();
- if (err)
- goto out;
-
-diff -Nurd linux-2.6.24/net/ipv4/ipconfig.c linux-2.6.24-oxe810/net/ipv4/ipconfig.c
---- linux-2.6.24/net/ipv4/ipconfig.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/ipconfig.c 2008-06-11 17:46:09.000000000 +0200
-@@ -739,9 +739,9 @@
- printk("Unknown ARP type 0x%04x for device %s\n", dev->type, dev->name);
- b->htype = dev->type; /* can cause undefined behavior */
- }
-+
-+ /* server_ip and your_ip address are both already zero per RFC2131 */
- b->hlen = dev->addr_len;
-- b->your_ip = NONE;
-- b->server_ip = NONE;
- memcpy(b->hw_addr, dev->dev_addr, dev->addr_len);
- b->secs = htons(jiffies_diff / HZ);
- b->xid = d->xid;
-diff -Nurd linux-2.6.24/net/ipv4/netfilter/arpt_mangle.c linux-2.6.24-oxe810/net/ipv4/netfilter/arpt_mangle.c
---- linux-2.6.24/net/ipv4/netfilter/arpt_mangle.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/netfilter/arpt_mangle.c 2008-06-11 17:46:07.000000000 +0200
-@@ -19,7 +19,7 @@
- unsigned char *arpptr;
- int pln, hln;
-
-- if (skb_make_writable(skb, skb->len))
-+ if (!skb_make_writable(skb, skb->len))
- return NF_DROP;
-
- arp = arp_hdr(skb);
-diff -Nurd linux-2.6.24/net/ipv4/netfilter/ip_queue.c linux-2.6.24-oxe810/net/ipv4/netfilter/ip_queue.c
---- linux-2.6.24/net/ipv4/netfilter/ip_queue.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/netfilter/ip_queue.c 2008-06-11 17:46:07.000000000 +0200
-@@ -336,8 +336,8 @@
- ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
- {
- int diff;
-- int err;
- struct iphdr *user_iph = (struct iphdr *)v->payload;
-+ struct sk_buff *nskb;
-
- if (v->data_len < sizeof(*user_iph))
- return 0;
-@@ -349,14 +349,16 @@
- if (v->data_len > 0xFFFF)
- return -EINVAL;
- if (diff > skb_tailroom(e->skb)) {
-- err = pskb_expand_head(e->skb, 0,
-+ nskb = skb_copy_expand(e->skb, 0,
- diff - skb_tailroom(e->skb),
- GFP_ATOMIC);
-- if (err) {
-+ if (!nskb) {
- printk(KERN_WARNING "ip_queue: error "
-- "in mangle, dropping packet: %d\n", -err);
-- return err;
-+ "in mangle, dropping packet\n");
-+ return -ENOMEM;
- }
-+ kfree_skb(e->skb);
-+ e->skb = nskb;
- }
- skb_put(e->skb, diff);
- }
-diff -Nurd linux-2.6.24/net/ipv4/sysctl_net_ipv4.c linux-2.6.24-oxe810/net/ipv4/sysctl_net_ipv4.c
---- linux-2.6.24/net/ipv4/sysctl_net_ipv4.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/sysctl_net_ipv4.c 2008-06-11 17:46:09.000000000 +0200
-@@ -248,7 +248,7 @@
-
- tcp_get_available_congestion_control(tbl.data, tbl.maxlen);
- ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen);
-- if (ret == 0 && newval && newlen)
-+ if (ret == 1 && newval && newlen)
- ret = tcp_set_allowed_congestion_control(tbl.data);
- kfree(tbl.data);
-
-diff -Nurd linux-2.6.24/net/ipv4/tcp.c linux-2.6.24-oxe810/net/ipv4/tcp.c
---- linux-2.6.24/net/ipv4/tcp.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/tcp.c 2008-06-11 17:46:09.000000000 +0200
-@@ -269,6 +269,8 @@
- #include <asm/uaccess.h>
- #include <asm/ioctls.h>
-
-+#include <linux/pagemap.h>
-+
- int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT;
-
- DEFINE_SNMP_STAT(struct tcp_mib, tcp_statistics) __read_mostly;
-@@ -636,6 +638,48 @@
- return res;
- }
-
-+ssize_t tcp_sendpages(struct socket *sock, struct page **page, int offset,
-+ size_t size, int flags)
-+{
-+ ssize_t res;
-+ struct sock *sk = sock->sk;
-+
-+#define TCP_ZC_CSUM_FLAGS (NETIF_F_IP_CSUM | NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
-+
-+ if (!(sk->sk_route_caps & NETIF_F_SG) ||
-+ !(sk->sk_route_caps & TCP_ZC_CSUM_FLAGS)) {
-+ // Iterate through each page
-+ ssize_t ret = 0;
-+
-+ while (size) {
-+ unsigned long psize = PAGE_CACHE_SIZE - offset;
-+ struct page *page_it;
-+
-+ psize = PAGE_CACHE_SIZE - offset;
-+ if (size <= psize) {
-+ psize = size;
-+ }
-+ page_it = *page;
-+ ret += sock_no_sendpage(sock, page_it, offset, psize, flags);
-+ size -= psize;
-+ page++;
-+ offset += psize;
-+ offset &= (PAGE_CACHE_SIZE - 1);
-+ }
-+ return ret;
-+ }
-+
-+#undef TCP_ZC_CSUM_FLAGS
-+
-+ lock_sock(sk);
-+ TCP_CHECK_TIMER(sk);
-+ res = do_tcp_sendpages(sk, page, offset, size, flags);
-+ TCP_CHECK_TIMER(sk);
-+
-+ release_sock(sk);
-+ return res;
-+}
-+
- #define TCP_PAGE(sk) (sk->sk_sndmsg_page)
- #define TCP_OFF(sk) (sk->sk_sndmsg_off)
-
-diff -Nurd linux-2.6.24/net/ipv4/xfrm4_tunnel.c linux-2.6.24-oxe810/net/ipv4/xfrm4_tunnel.c
---- linux-2.6.24/net/ipv4/xfrm4_tunnel.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv4/xfrm4_tunnel.c 2008-06-11 17:46:09.000000000 +0200
-@@ -50,7 +50,7 @@
-
- static int xfrm_tunnel_rcv(struct sk_buff *skb)
- {
-- return xfrm4_rcv_spi(skb, IPPROTO_IP, ip_hdr(skb)->saddr);
-+ return xfrm4_rcv_spi(skb, IPPROTO_IPIP, ip_hdr(skb)->saddr);
- }
-
- static int xfrm_tunnel_err(struct sk_buff *skb, u32 info)
-diff -Nurd linux-2.6.24/net/ipv6/ip6_output.c linux-2.6.24-oxe810/net/ipv6/ip6_output.c
---- linux-2.6.24/net/ipv6/ip6_output.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv6/ip6_output.c 2008-06-11 17:46:11.000000000 +0200
-@@ -593,7 +593,7 @@
- * or if the skb it not generated by a local socket. (This last
- * check should be redundant, but it's free.)
- */
-- if (!np || np->pmtudisc >= IPV6_PMTUDISC_DO) {
-+ if (!skb->local_df) {
- skb->dev = skb->dst->dev;
- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
- IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
-@@ -609,6 +609,7 @@
-
- if (skb_shinfo(skb)->frag_list) {
- int first_len = skb_pagelen(skb);
-+ int truesizes = 0;
-
- if (first_len - hlen > mtu ||
- ((first_len - hlen) & 7) ||
-@@ -631,7 +632,7 @@
- sock_hold(skb->sk);
- frag->sk = skb->sk;
- frag->destructor = sock_wfree;
-- skb->truesize -= frag->truesize;
-+ truesizes += frag->truesize;
- }
- }
-
-@@ -662,6 +663,7 @@
-
- first_len = skb_pagelen(skb);
- skb->data_len = first_len - skb_headlen(skb);
-+ skb->truesize -= truesizes;
- skb->len = first_len;
- ipv6_hdr(skb)->payload_len = htons(first_len -
- sizeof(struct ipv6hdr));
-@@ -1387,6 +1389,10 @@
- tmp_skb->sk = NULL;
- }
-
-+ /* Allow local fragmentation. */
-+ if (np->pmtudisc < IPV6_PMTUDISC_DO)
-+ skb->local_df = 1;
-+
- ipv6_addr_copy(final_dst, &fl->fl6_dst);
- __skb_pull(skb, skb_network_header_len(skb));
- if (opt && opt->opt_flen)
-diff -Nurd linux-2.6.24/net/ipv6/ip6_tunnel.c linux-2.6.24-oxe810/net/ipv6/ip6_tunnel.c
---- linux-2.6.24/net/ipv6/ip6_tunnel.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv6/ip6_tunnel.c 2008-06-11 17:46:11.000000000 +0200
-@@ -550,6 +550,7 @@
- ip_rt_put(rt);
- goto out;
- }
-+ skb2->dst = (struct dst_entry *)rt;
- } else {
- ip_rt_put(rt);
- if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos,
-diff -Nurd linux-2.6.24/net/ipv6/ipcomp6.c linux-2.6.24-oxe810/net/ipv6/ipcomp6.c
---- linux-2.6.24/net/ipv6/ipcomp6.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv6/ipcomp6.c 2008-06-11 17:46:11.000000000 +0200
-@@ -64,6 +64,7 @@
-
- static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
- {
-+ int nexthdr;
- int err = -ENOMEM;
- struct ip_comp_hdr *ipch;
- int plen, dlen;
-@@ -79,6 +80,8 @@
-
- /* Remove ipcomp header and decompress original payload */
- ipch = (void *)skb->data;
-+ nexthdr = ipch->nexthdr;
-+
- skb->transport_header = skb->network_header + sizeof(*ipch);
- __skb_pull(skb, sizeof(*ipch));
-
-@@ -108,7 +111,7 @@
- skb->truesize += dlen - plen;
- __skb_put(skb, dlen - plen);
- skb_copy_to_linear_data(skb, scratch, dlen);
-- err = ipch->nexthdr;
-+ err = nexthdr;
-
- out_put_cpu:
- put_cpu();
-@@ -143,7 +146,9 @@
- scratch = *per_cpu_ptr(ipcomp6_scratches, cpu);
- tfm = *per_cpu_ptr(ipcd->tfms, cpu);
-
-+ local_bh_disable();
- err = crypto_comp_compress(tfm, start, plen, scratch, &dlen);
-+ local_bh_enable();
- if (err || (dlen + sizeof(*ipch)) >= plen) {
- put_cpu();
- goto out_ok;
-diff -Nurd linux-2.6.24/net/ipv6/netfilter/ip6_queue.c linux-2.6.24-oxe810/net/ipv6/netfilter/ip6_queue.c
---- linux-2.6.24/net/ipv6/netfilter/ip6_queue.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv6/netfilter/ip6_queue.c 2008-06-11 17:46:10.000000000 +0200
-@@ -333,8 +333,8 @@
- ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
- {
- int diff;
-- int err;
- struct ipv6hdr *user_iph = (struct ipv6hdr *)v->payload;
-+ struct sk_buff *nskb;
-
- if (v->data_len < sizeof(*user_iph))
- return 0;
-@@ -346,14 +346,16 @@
- if (v->data_len > 0xFFFF)
- return -EINVAL;
- if (diff > skb_tailroom(e->skb)) {
-- err = pskb_expand_head(e->skb, 0,
-+ nskb = skb_copy_expand(e->skb, 0,
- diff - skb_tailroom(e->skb),
- GFP_ATOMIC);
-- if (err) {
-+ if (!nskb) {
- printk(KERN_WARNING "ip6_queue: OOM "
- "in mangle, dropping packet\n");
-- return err;
-+ return -ENOMEM;
- }
-+ kfree_skb(e->skb);
-+ e->skb = nskb;
- }
- skb_put(e->skb, diff);
- }
-diff -Nurd linux-2.6.24/net/ipv6/xfrm6_output.c linux-2.6.24-oxe810/net/ipv6/xfrm6_output.c
---- linux-2.6.24/net/ipv6/xfrm6_output.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/ipv6/xfrm6_output.c 2008-06-11 17:46:11.000000000 +0200
-@@ -34,7 +34,7 @@
- if (mtu < IPV6_MIN_MTU)
- mtu = IPV6_MIN_MTU;
-
-- if (skb->len > mtu) {
-+ if (!skb->local_df && skb->len > mtu) {
- skb->dev = dst->dev;
- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
- ret = -EMSGSIZE;
-diff -Nurd linux-2.6.24/net/netfilter/nf_conntrack_proto_tcp.c linux-2.6.24-oxe810/net/netfilter/nf_conntrack_proto_tcp.c
---- linux-2.6.24/net/netfilter/nf_conntrack_proto_tcp.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/netfilter/nf_conntrack_proto_tcp.c 2008-06-11 17:46:00.000000000 +0200
-@@ -135,7 +135,7 @@
- * CLOSE_WAIT: ACK seen (after FIN)
- * LAST_ACK: FIN seen (after FIN)
- * TIME_WAIT: last ACK seen
-- * CLOSE: closed connection
-+ * CLOSE: closed connection (RST)
- *
- * LISTEN state is not used.
- *
-@@ -834,8 +834,21 @@
- case TCP_CONNTRACK_SYN_SENT:
- if (old_state < TCP_CONNTRACK_TIME_WAIT)
- break;
-- if ((conntrack->proto.tcp.seen[!dir].flags &
-- IP_CT_TCP_FLAG_CLOSE_INIT)
-+ /* RFC 1122: "When a connection is closed actively,
-+ * it MUST linger in TIME-WAIT state for a time 2xMSL
-+ * (Maximum Segment Lifetime). However, it MAY accept
-+ * a new SYN from the remote TCP to reopen the connection
-+ * directly from TIME-WAIT state, if..."
-+ * We ignore the conditions because we are in the
-+ * TIME-WAIT state anyway.
-+ *
-+ * Handle aborted connections: we and the server
-+ * think there is an existing connection but the client
-+ * aborts it and starts a new one.
-+ */
-+ if (((conntrack->proto.tcp.seen[dir].flags
-+ | conntrack->proto.tcp.seen[!dir].flags)
-+ & IP_CT_TCP_FLAG_CLOSE_INIT)
- || (conntrack->proto.tcp.last_dir == dir
- && conntrack->proto.tcp.last_index == TCP_RST_SET)) {
- /* Attempt to reopen a closed/aborted connection.
-@@ -848,18 +861,25 @@
- }
- /* Fall through */
- case TCP_CONNTRACK_IGNORE:
-- /* Ignored packets:
-+ /* Ignored packets:
-+ *
-+ * Our connection entry may be out of sync, so ignore
-+ * packets which may signal the real connection between
-+ * the client and the server.
- *
- * a) SYN in ORIGINAL
- * b) SYN/ACK in REPLY
- * c) ACK in reply direction after initial SYN in original.
-+ *
-+ * If the ignored packet is invalid, the receiver will send
-+ * a RST we'll catch below.
- */
- if (index == TCP_SYNACK_SET
- && conntrack->proto.tcp.last_index == TCP_SYN_SET
- && conntrack->proto.tcp.last_dir != dir
- && ntohl(th->ack_seq) ==
- conntrack->proto.tcp.last_end) {
-- /* This SYN/ACK acknowledges a SYN that we earlier
-+ /* b) This SYN/ACK acknowledges a SYN that we earlier
- * ignored as invalid. This means that the client and
- * the server are both in sync, while the firewall is
- * not. We kill this session and block the SYN/ACK so
-@@ -884,7 +904,7 @@
- write_unlock_bh(&tcp_lock);
- if (LOG_INVALID(IPPROTO_TCP))
- nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
-- "nf_ct_tcp: invalid packed ignored ");
-+ "nf_ct_tcp: invalid packet ignored ");
- return NF_ACCEPT;
- case TCP_CONNTRACK_MAX:
- /* Invalid packet */
-@@ -938,8 +958,7 @@
-
- conntrack->proto.tcp.state = new_state;
- if (old_state != new_state
-- && (new_state == TCP_CONNTRACK_FIN_WAIT
-- || new_state == TCP_CONNTRACK_CLOSE))
-+ && new_state == TCP_CONNTRACK_FIN_WAIT)
- conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
- timeout = conntrack->proto.tcp.retrans >= nf_ct_tcp_max_retrans
- && *tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans
-diff -Nurd linux-2.6.24/net/netfilter/nfnetlink_log.c linux-2.6.24-oxe810/net/netfilter/nfnetlink_log.c
---- linux-2.6.24/net/netfilter/nfnetlink_log.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/netfilter/nfnetlink_log.c 2008-06-11 17:46:00.000000000 +0200
-@@ -594,7 +594,7 @@
- /* FIXME: do we want to make the size calculation conditional based on
- * what is actually present? way more branches and checks, but more
- * memory efficient... */
-- size = NLMSG_ALIGN(sizeof(struct nfgenmsg))
-+ size = NLMSG_SPACE(sizeof(struct nfgenmsg))
- + nla_total_size(sizeof(struct nfulnl_msg_packet_hdr))
- + nla_total_size(sizeof(u_int32_t)) /* ifindex */
- + nla_total_size(sizeof(u_int32_t)) /* ifindex */
-diff -Nurd linux-2.6.24/net/netfilter/nfnetlink_queue.c linux-2.6.24-oxe810/net/netfilter/nfnetlink_queue.c
---- linux-2.6.24/net/netfilter/nfnetlink_queue.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/netfilter/nfnetlink_queue.c 2008-06-11 17:46:00.000000000 +0200
-@@ -353,7 +353,7 @@
-
- QDEBUG("entered\n");
-
-- size = NLMSG_ALIGN(sizeof(struct nfgenmsg))
-+ size = NLMSG_SPACE(sizeof(struct nfgenmsg))
- + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr))
- + nla_total_size(sizeof(u_int32_t)) /* ifindex */
- + nla_total_size(sizeof(u_int32_t)) /* ifindex */
-@@ -616,8 +616,8 @@
- static int
- nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e)
- {
-+ struct sk_buff *nskb;
- int diff;
-- int err;
-
- diff = data_len - e->skb->len;
- if (diff < 0) {
-@@ -627,14 +627,16 @@
- if (data_len > 0xFFFF)
- return -EINVAL;
- if (diff > skb_tailroom(e->skb)) {
-- err = pskb_expand_head(e->skb, 0,
-+ nskb = skb_copy_expand(e->skb, 0,
- diff - skb_tailroom(e->skb),
- GFP_ATOMIC);
-- if (err) {
-+ if (!nskb) {
- printk(KERN_WARNING "nf_queue: OOM "
- "in mangle, dropping packet\n");
-- return err;
-+ return -ENOMEM;
- }
-+ kfree_skb(e->skb);
-+ e->skb = nskb;
- }
- skb_put(e->skb, diff);
- }
-diff -Nurd linux-2.6.24/net/netfilter/xt_time.c linux-2.6.24-oxe810/net/netfilter/xt_time.c
---- linux-2.6.24/net/netfilter/xt_time.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/netfilter/xt_time.c 2008-06-11 17:46:00.000000000 +0200
-@@ -95,8 +95,11 @@
- */
- r->dse = time / 86400;
-
-- /* 1970-01-01 (w=0) was a Thursday (4). */
-- r->weekday = (4 + r->dse) % 7;
-+ /*
-+ * 1970-01-01 (w=0) was a Thursday (4).
-+ * -1 and +1 map Sunday properly onto 7.
-+ */
-+ r->weekday = (4 + r->dse - 1) % 7 + 1;
- }
-
- static void localtime_3(struct xtm *r, time_t time)
-diff -Nurd linux-2.6.24/net/sched/em_meta.c linux-2.6.24-oxe810/net/sched/em_meta.c
---- linux-2.6.24/net/sched/em_meta.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/sched/em_meta.c 2008-06-11 17:45:56.000000000 +0200
-@@ -719,11 +719,13 @@
-
- static inline void meta_delete(struct meta_match *meta)
- {
-- struct meta_type_ops *ops = meta_type_ops(&meta->lvalue);
-+ if (meta) {
-+ struct meta_type_ops *ops = meta_type_ops(&meta->lvalue);
-
-- if (ops && ops->destroy) {
-- ops->destroy(&meta->lvalue);
-- ops->destroy(&meta->rvalue);
-+ if (ops && ops->destroy) {
-+ ops->destroy(&meta->lvalue);
-+ ops->destroy(&meta->rvalue);
-+ }
- }
-
- kfree(meta);
-diff -Nurd linux-2.6.24/net/sched/ematch.c linux-2.6.24-oxe810/net/sched/ematch.c
---- linux-2.6.24/net/sched/ematch.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/sched/ematch.c 2008-06-11 17:45:56.000000000 +0200
-@@ -305,10 +305,9 @@
- struct tcf_ematch_tree_hdr *tree_hdr;
- struct tcf_ematch *em;
-
-- if (!rta) {
-- memset(tree, 0, sizeof(*tree));
-+ memset(tree, 0, sizeof(*tree));
-+ if (!rta)
- return 0;
-- }
-
- if (rtattr_parse_nested(tb, TCA_EMATCH_TREE_MAX, rta) < 0)
- goto errout;
-diff -Nurd linux-2.6.24/net/socket.c linux-2.6.24-oxe810/net/socket.c
---- linux-2.6.24/net/socket.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/net/socket.c 2008-06-11 17:46:19.000000000 +0200
-@@ -113,6 +113,9 @@
- static ssize_t sock_sendpage(struct file *file, struct page *page,
- int offset, size_t size, loff_t *ppos, int more);
-
-+static ssize_t sock_sendpages(struct file *file, struct page **page,
-+ int offset, size_t size, loff_t *ppos, int more);
-+
- /*
- * Socket files have a set of 'special' operations as well as the generic file ones. These don't appear
- * in the operation structures but are done directly via the socketcall() multiplexor.
-@@ -133,6 +136,7 @@
- .release = sock_close,
- .fasync = sock_fasync,
- .sendpage = sock_sendpage,
-+ .sendpages = sock_sendpages,
- .splice_write = generic_splice_sendpage,
- };
-
-@@ -691,6 +695,21 @@
- return sock->ops->sendpage(sock, page, offset, size, flags);
- }
-
-+static ssize_t sock_sendpages(struct file *file, struct page **page,
-+ int offset, size_t size, loff_t *ppos, int more)
-+{
-+ struct socket *sock;
-+ int flags;
-+
-+ sock = file->private_data;
-+
-+ flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
-+ if (more)
-+ flags |= MSG_MORE;
-+
-+ return sock->ops->sendpages(sock, page, offset, size, flags);
-+}
-+
- static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb,
- struct sock_iocb *siocb)
- {
-diff -Nurd linux-2.6.24/scripts/mod/file2alias.c linux-2.6.24-oxe810/scripts/mod/file2alias.c
---- linux-2.6.24/scripts/mod/file2alias.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/scripts/mod/file2alias.c 2008-06-11 17:46:20.000000000 +0200
-@@ -155,7 +155,7 @@
- * Some modules (visor) have empty slots as placeholder for
- * run-time specification that results in catch-all alias
- */
-- if (!(id->idVendor | id->bDeviceClass | id->bInterfaceClass))
-+ if (!(id->idVendor | id->idProduct | id->bDeviceClass | id->bInterfaceClass))
- return;
-
- /* Convert numeric bcdDevice range into fnmatch-able pattern(s) */
-diff -Nurd linux-2.6.24/security/Kconfig linux-2.6.24-oxe810/security/Kconfig
---- linux-2.6.24/security/Kconfig 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/security/Kconfig 2008-06-11 17:46:44.000000000 +0200
-@@ -103,6 +103,32 @@
-
- If you are unsure how to answer this question, answer N.
-
-+config SECURITY_TRUSTEES
-+ bool "Linux Trustees ACLs"
-+ depends on SECURITY
-+ help
-+ Implements a system similar to Netware ACLs. Trustees
-+ allows a global configuration of recursive ACLs via a
-+ centralized file. ACLs can be added to an entire
-+ directory tree and masked out on subdirectories.
-+
-+ Trustees allows complex permissions to be enforced
-+ system-wide without needing to touch every file or
-+ maintain thousands of ugly POSIX ACLs. See
-+ http://trustees.sourceforge.net for more information on
-+ trustees and the associated user-space tools.
-+
-+ If you are unsure how to answer this question, answer N.
-+
-+config SECURITY_TRUSTEES_DEBUG
-+ bool "Enable debugging code and messages"
-+ depends on SECURITY_TRUSTEES
-+ help
-+ Turns on certain diagnostic messages and debugging code
-+ in trustees.
-+
-+ If you are unsure how to answer this question, answer N.
-+
- source security/selinux/Kconfig
-
- endmenu
-diff -Nurd linux-2.6.24/security/Makefile linux-2.6.24-oxe810/security/Makefile
---- linux-2.6.24/security/Makefile 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/security/Makefile 2008-06-11 17:46:44.000000000 +0200
-@@ -12,6 +12,7 @@
-
- # Object file lists
- obj-$(CONFIG_SECURITY) += security.o dummy.o inode.o
-+obj-$(CONFIG_SECURITY_TRUSTEES) += trustees/
- # Must precede capability.o in order to stack properly.
- obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
- obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o
-diff -Nurd linux-2.6.24/security/commoncap.c linux-2.6.24-oxe810/security/commoncap.c
---- linux-2.6.24/security/commoncap.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/security/commoncap.c 2008-06-11 17:46:44.000000000 +0200
-@@ -539,7 +539,7 @@
- * allowed.
- * We must preserve legacy signal behavior in this case.
- */
-- if (p->euid == 0 && p->uid == current->uid)
-+ if (p->uid == current->uid)
- return 0;
-
- /* sigcont is permitted within same session */
-diff -Nurd linux-2.6.24/security/selinux/ss/services.c linux-2.6.24-oxe810/security/selinux/ss/services.c
---- linux-2.6.24/security/selinux/ss/services.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/security/selinux/ss/services.c 2008-06-11 17:46:43.000000000 +0200
-@@ -1744,6 +1744,9 @@
- struct ocontext *c;
- int rc = 0, cmp = 0;
-
-+ while (path[0] == '/' && path[1] == '/')
-+ path++;
-+
- POLICY_RDLOCK;
-
- for (genfs = policydb.genfs; genfs; genfs = genfs->next) {
-@@ -2626,7 +2629,6 @@
-
- netlbl_sid_to_secattr_failure:
- POLICY_RDUNLOCK;
-- netlbl_secattr_destroy(secattr);
- return rc;
- }
- #endif /* CONFIG_NETLABEL */
-diff -Nurd linux-2.6.24/security/trustees/Makefile linux-2.6.24-oxe810/security/trustees/Makefile
---- linux-2.6.24/security/trustees/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/security/trustees/Makefile 2008-06-11 17:46:44.000000000 +0200
-@@ -0,0 +1,8 @@
-+ifeq ($(CONFIG_SECURITY_TRUSTEES_DEBUG),y)
-+ EXTRA_CFLAGS += -DTRUSTEES_DEBUG
-+endif
-+
-+obj-$(CONFIG_SECURITY_TRUSTEES) := trustees.o
-+trustees-objs := \
-+ security.o fs.o \
-+ init.o funcs.o ../commoncap.o
-diff -Nurd linux-2.6.24/security/trustees/fs.c linux-2.6.24-oxe810/security/trustees/fs.c
---- linux-2.6.24/security/trustees/fs.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/security/trustees/fs.c 2008-06-11 17:46:44.000000000 +0200
-@@ -0,0 +1,273 @@
-+/*
-+ * Trustees ACL Project
-+ *
-+ * Copyright (c) 1999-2000 Vyacheslav Zavadsky
-+ * Copyright (c) 2004 Andrew Ruder (aeruder@ksu.edu)
-+ *
-+ * 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, version 2.
-+ *
-+ * This code handles the virtual filesystem for trustees.
-+ *
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/fs.h>
-+#include <linux/vmalloc.h>
-+#include <linux/security.h>
-+#include <asm/atomic.h>
-+#include <asm/uaccess.h>
-+
-+#include "internal.h"
-+
-+
-+/* initialization code for the trustees filesystem */
-+
-+/* File operations
-+ *
-+ * this is all the code for handling the file operations done on the few files
-+ * in the trustees filesystem
-+ */
-+static int trustees_open(struct inode *inode, struct file *filp);
-+static ssize_t trustees_read_bogus(struct file *filp, char __user * buf,
-+ size_t count, loff_t * offset);
-+static ssize_t trustees_write_bogus(struct file *filp,
-+ const char __user * buf, size_t count,
-+ loff_t * offset);
-+static ssize_t trustees_read_status(struct file *filp, char __user * buf,
-+ size_t count, loff_t * offset);
-+static ssize_t trustees_read_apiversion(struct file *filp, char __user * buf,
-+ size_t count, loff_t * offset);
-+static ssize_t trustees_write_trustees(struct file *filp,
-+ const char __user * buf,
-+ size_t count, loff_t * offset);
-+static int trustees_open_trustees(struct inode *inode, struct file *file);
-+static int trustees_release_trustees(struct inode *inode, struct file *file);
-+
-+/* Various structs
-+ */
-+
-+static struct file_operations trustees_ops_apiversion = {
-+ .open = trustees_open,
-+ .read = trustees_read_apiversion,
-+ .write = trustees_write_bogus,
-+};
-+
-+static struct file_operations trustees_ops_status = {
-+ .open = trustees_open,
-+ .read = trustees_read_status,
-+ .write = trustees_write_bogus
-+};
-+
-+static struct file_operations trustees_ops_trustees = {
-+ .open = trustees_open_trustees,
-+ .read = trustees_read_bogus,
-+ .write = trustees_write_trustees,
-+ .release = trustees_release_trustees
-+};
-+
-+static struct trustees_file_info {
-+ const char *name;
-+ struct file_operations *fops;
-+ int mode;
-+ struct dentry *dentry;
-+} trustees_files[] = {
-+ {.name = "device",
-+ .fops = &trustees_ops_trustees,
-+ .mode = S_IWUSR,
-+ .dentry = 0
-+ },
-+ {.name = "status",
-+ .fops = &trustees_ops_status,
-+ .mode = S_IRUSR,
-+ .dentry = 0
-+ },
-+ {.name = "apiversion",
-+ .fops = &trustees_ops_apiversion,
-+ .mode = S_IRUSR | S_IRGRP | S_IROTH,
-+ .dentry = 0
-+ },
-+ {"", NULL, 0, 0}
-+};
-+
-+struct trustee_command_reader {
-+ struct trustee_command command;
-+ unsigned curarg;
-+ void *arg[TRUSTEE_MAX_ARGS];
-+ size_t argsize[TRUSTEE_MAX_ARGS];
-+};
-+
-+
-+static struct dentry *toplevel = NULL;
-+
-+int trustees_init_fs(void)
-+{
-+ struct trustees_file_info *iter;
-+ toplevel = securityfs_create_dir("trustees", NULL);
-+ if (!toplevel) trustees_deinit_fs();
-+ for (iter = trustees_files; iter->fops && toplevel; iter++) {
-+ iter->dentry = securityfs_create_file(
-+ iter->name, iter->mode, toplevel, NULL, iter->fops);
-+ if (!iter->dentry) trustees_deinit_fs();
-+ }
-+ return !toplevel;
-+}
-+
-+void trustees_deinit_fs(void)
-+{
-+ struct trustees_file_info *iter;
-+ for (iter = trustees_files; iter->fops; iter++) {
-+ securityfs_remove(iter->dentry);
-+ iter->dentry = NULL;
-+ }
-+ securityfs_remove(toplevel);
-+ toplevel = NULL;
-+}
-+
-+/*
-+ * They're opening the file...
-+ */
-+
-+static int trustees_open(struct inode *inode, struct file *filp)
-+{
-+ return 0;
-+}
-+
-+static int trustees_open_trustees(struct inode *inode, struct file *file)
-+{
-+ file->private_data = vmalloc(sizeof(struct trustee_command_reader));
-+ if (!file->private_data)
-+ return -ENOMEM;
-+
-+ memset(file->private_data, 0, sizeof(struct trustee_command_reader));
-+
-+ return 0;
-+}
-+
-+static int trustees_release_trustees(struct inode *inode, struct file *file)
-+{
-+ vfree(file->private_data);
-+ return 0;
-+}
-+
-+/* Do a read on a bogus file. Just return nothing :) */
-+static ssize_t trustees_read_bogus(struct file *filp, char __user * buf,
-+ size_t count, loff_t * offset)
-+{
-+ return 0;
-+}
-+
-+/* Similar way to handle writes. Just say we wrote the data and return */
-+static ssize_t trustees_write_bogus(struct file *filp,
-+ const char __user * buf, size_t count,
-+ loff_t * offset)
-+{
-+ return count;
-+}
-+
-+/* Function for handling reading of the status. */
-+static ssize_t trustees_read_status(struct file *filp, char __user * buf,
-+ size_t count, loff_t * offset)
-+{
-+ static const char msg[] = "Damnit, it works, OK?!\n";
-+ unsigned long nocopy;
-+
-+ if (*offset >= (sizeof(msg) - 1)) {
-+ return 0;
-+ }
-+
-+ if (count > (sizeof(msg) - 1 - *offset)) {
-+ count = sizeof(msg) - 1 - *offset;
-+ }
-+ nocopy = copy_to_user(buf, msg, count);
-+ (*offset) += count;
-+ (*offset) -= nocopy;
-+
-+ return count;
-+}
-+
-+/* Function for handling reading of the apiversion. */
-+static ssize_t trustees_read_apiversion(struct file *filp, char __user * buf,
-+ size_t count, loff_t * offset)
-+{
-+ static const char msg[] = TRUSTEES_APIVERSION_STR "\n";
-+ unsigned long nocopy;
-+
-+ if (*offset >= (sizeof(msg) - 1)) {
-+ return 0;
-+ }
-+
-+ if (count > (sizeof(msg) - 1 - *offset)) {
-+ count = sizeof(msg) - 1 - *offset;
-+ }
-+ nocopy = copy_to_user(buf, msg, count);
-+ (*offset) += count;
-+ (*offset) -= nocopy;
-+
-+ return count;
-+}
-+
-+/* Cleanup our reader (deallocate all the allocated memory) */
-+static void cleanup_reader(struct trustee_command_reader *reader) {
-+ int z;
-+ if (!reader) {
-+ TS_ERR_MSG("How does reader disappear on us?\n");
-+ return;
-+ }
-+
-+ for (z = reader->curarg - 1; z >= 0; z--) {
-+ vfree(reader->arg[z]);
-+ reader->argsize[z] = 0;
-+ }
-+ reader->command.command = 0;
-+ reader->curarg = 0;
-+}
-+
-+static ssize_t trustees_write_trustees(struct file *filp,
-+ const char __user * buf,
-+ size_t count, loff_t * offset)
-+{
-+ struct trustee_command_reader *reader = filp->private_data;
-+
-+ if (reader->command.command == 0) {
-+ reader->curarg = 0;
-+ if (count != sizeof(struct trustee_command)) {
-+ return -EIO;
-+ }
-+ if (copy_from_user(&reader->command, buf, count)) {
-+ reader->command.command = 0;
-+ TS_ERR_MSG("copy_from_user failed on command\n");
-+ return -EIO;
-+ }
-+ if (reader->command.numargs > TRUSTEE_MAX_ARGS) {
-+ TS_ERR_MSG("Too many arguments specified for command %d\n",
-+ reader->command.command);
-+ return -EIO;
-+ }
-+ } else {
-+ unsigned curarg = reader->curarg;
-+ if (!(reader->arg[curarg] = vmalloc(count+1))) {
-+ cleanup_reader(reader);
-+ return -EIO;
-+ }
-+ reader->argsize[curarg] = count;
-+ ((char *)reader->arg[curarg])[count] = '\0';
-+ reader->curarg++;
-+ if (copy_from_user(reader->arg[curarg], buf, count)) {
-+ cleanup_reader(reader);
-+ TS_ERR_MSG("copy_from_user failed on arg\n");
-+ return -EIO;
-+ }
-+ }
-+
-+ if (reader->command.command && reader->curarg == reader->command.numargs) {
-+ int ret = trustees_process_command(reader->command, reader->arg,
-+ reader->argsize);
-+ cleanup_reader(reader);
-+ if (ret) return -EIO;
-+ }
-+
-+ return count;
-+}
-diff -Nurd linux-2.6.24/security/trustees/funcs.c linux-2.6.24-oxe810/security/trustees/funcs.c
---- linux-2.6.24/security/trustees/funcs.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/security/trustees/funcs.c 2008-06-11 17:46:44.000000000 +0200
-@@ -0,0 +1,810 @@
-+/*
-+ * Trustees ACL Project
-+ *
-+ * Copyright (c) 1999-2000 Vyacheslav Zavadsky
-+ * Copyright (c) 2004 Andrew Ruder (aeruder@ksu.edu)
-+ *
-+ * 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, version 2.
-+ *
-+ * This code contains the functions for handling the actual trustees data
-+ * and returning the permissions for a given file, etc.
-+ *
-+ *
-+ */
-+
-+#include <linux/fs.h>
-+#include <linux/mount.h>
-+#include <linux/dcache.h>
-+#include <linux/string.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/smp_lock.h>
-+#include <linux/poll.h>
-+#include <linux/sched.h>
-+#include <linux/limits.h>
-+#include <linux/list.h>
-+#include <linux/vmalloc.h>
-+#include <linux/ctype.h>
-+
-+#include "internal.h"
-+
-+/*
-+ * This is a hash of all the trustee_names currently added. These values
-+ * are hashed on a combination of device/filename. Before reading/writing
-+ * be sure to take care of the locking of trustee_hash_lock.
-+ */
-+rwlock_t trustee_hash_lock;
-+static struct hlist_head *trustee_hash = NULL;
-+
-+/*
-+ * This is the deepest level trustee. When calculating filenames, we can
-+ * skip several of the levels in many case since we know it won't be any
-+ * deeper than this.
-+ *
-+ * Kept up to date by calculate_deepest_level
-+ *
-+ * / => 0
-+ * /test => 1
-+ * /test/blah => 2
-+ */
-+static int deepest_level = 0;
-+
-+/*
-+ * A list of filesystems that need to have their case
-+ * ignored. This is protected by trustee_hash_lock.
-+ */
-+static LIST_HEAD(trustee_ic_list);
-+
-+
-+/* The calling method needs to free the buffer created by this function
-+ * This method returns the filename for a dentry. This is, of course,
-+ * relative to the device. The filename can be truncated to be as deep as
-+ * the deepest trustee. The depth returned in d will always be the true
-+ * depth, however.
-+ *
-+ * Args:
-+ * dentry: The dentry we are interested in.
-+ * d: a pointer to the place where the depth can be stored.
-+ * trunc: ok to truncate the name to the longest that needs to be figured out.
-+ */
-+
-+#define FN_CHUNK_SIZE 64
-+char *trustees_filename_for_dentry(struct dentry *dentry, int *d, int trunc)
-+{
-+ char *buffer = NULL, *tmpbuf = NULL;
-+ int bufsize = FN_CHUNK_SIZE;
-+ char c;
-+ int i, j, k;
-+ int depth = 0;
-+ struct dentry *temp_dentry;
-+
-+ if (dentry->d_parent == NULL) {
-+ TS_ERR_MSG("d_parent is null\n");
-+ return NULL;
-+ }
-+
-+ if (dentry->d_name.name == NULL) {
-+ TS_ERR_MSG("name is null\n");
-+ return NULL;
-+ }
-+
-+ buffer = kmalloc(FN_CHUNK_SIZE, GFP_KERNEL);
-+ if (!buffer) {
-+ TS_ERR_MSG("could not allocate filename buffer\n");
-+ return NULL;
-+ }
-+
-+ buffer[0] = '/';
-+ buffer[i = 1] = '\0';
-+ for (temp_dentry = dentry; !IS_ROOT(temp_dentry); temp_dentry = temp_dentry->d_parent)
-+ depth++;
-+ if (d) *d = depth;
-+ if (deepest_level <= 0) return buffer;
-+
-+ for (;;) {
-+ if (IS_ROOT(dentry))
-+ break;
-+ if (depth-- > deepest_level) continue;
-+
-+ j = i + strlen(dentry->d_name.name);
-+ if ((j + 2) > bufsize) { /* reallocate - won't fit */
-+ bufsize = (((j + 2) / FN_CHUNK_SIZE) + 1) * FN_CHUNK_SIZE;
-+ tmpbuf = kmalloc(bufsize, GFP_KERNEL);
-+ if (!tmpbuf) {
-+ kfree(buffer);
-+ TS_ERR_MSG
-+ ("Out of memory allocating tmpbuf\n");
-+ return NULL;
-+ }
-+ memcpy(tmpbuf, buffer, i);
-+ kfree(buffer);
-+ buffer = tmpbuf;
-+ }
-+ /* Throw the name in there backward */
-+ for (k = 0; dentry->d_name.name[k]; k++) {
-+ buffer[j - 1 - k] = dentry->d_name.name[k];
-+ }
-+ i = j;
-+ buffer[i++] = '/';
-+ dentry = dentry->d_parent;
-+ }
-+ buffer[i] = 0;
-+
-+ /* buffer is backwards, reverse it */
-+ for (j = 0; j < (i / 2); ++j) {
-+ c = buffer[j];
-+ buffer[j] = buffer[i - j - 1];
-+ buffer[i - j - 1] = c;
-+ }
-+
-+ return buffer;
-+}
-+
-+/**
-+ * Allocate memory using vmalloc and return a duplicate of the passed in string.
-+ * Returns NULL if a problem occurs
-+ */
-+static char *vmalloc_strdup(const char *str, size_t len)
-+{
-+ char *r;
-+
-+ if (!str) return NULL;
-+ len = strlen(str);
-+ r = vmalloc(len + 1);
-+ if (!r) return NULL;
-+ memcpy(r, str, len + 1);
-+
-+ return r;
-+}
-+
-+/*
-+ * Add a filesystem as a ignored-case dev.
-+ */
-+static inline void add_ic_dev(u32 dev, char *devname)
-+{
-+ char *devname2;
-+ struct trustee_ic *ic;
-+ size_t dev_len;
-+
-+ dev_len = strlen(devname);
-+
-+ if (dev_len > PATH_MAX) {
-+ TS_ERR_MSG("devname bad, add_ic_dev ignored.\n");
-+ return;
-+ }
-+
-+ if (!dev_len) {
-+ TS_ERR_MSG("No devname specified in add_ic_dev.\n");
-+ return;
-+ }
-+
-+ devname2 = vmalloc_strdup(devname, dev_len);
-+ if (!devname2) {
-+ TS_ERR_MSG
-+ ("Seems that we have ran out of memory adding ic dev!\n");
-+ return;
-+ }
-+
-+ ic = vmalloc(sizeof(struct trustee_ic));
-+ if (!ic) {
-+ TS_ERR_MSG
-+ ("Seems that we ran out of memory allocating ic!\n");
-+ return;
-+ }
-+
-+ ic->dev = new_decode_dev(dev);
-+ ic->devname = devname2;
-+
-+ write_lock(&trustee_hash_lock);
-+ list_add(&ic->ic_list, &trustee_ic_list);
-+ write_unlock(&trustee_hash_lock);
-+}
-+
-+/*
-+ * Remove all ignored-case filesystems.
-+ */
-+static inline void remove_ic_devs(void)
-+{
-+ struct trustee_ic *ic, *temp_ic;
-+ struct list_head temp_ic_list;
-+
-+ INIT_LIST_HEAD(&temp_ic_list);
-+ list_splice_init(&trustee_ic_list, &temp_ic_list);
-+
-+ list_for_each_entry_safe(ic, temp_ic, &temp_ic_list, ic_list) {
-+ vfree(ic->devname);
-+ vfree(ic);
-+ }
-+}
-+
-+/*
-+ * This frees all the capsules in a trustee element.
-+ */
-+static inline void free_hash_element_list(struct trustee_hash_element *e)
-+{
-+ struct trustee_permission_capsule *capsule, *temp;
-+
-+ list_for_each_entry_safe(capsule, temp, &e->perm_list, perm_list) {
-+ list_del(&capsule->perm_list);
-+ vfree(capsule);
-+ }
-+}
-+
-+/*
-+ * Free a trustee name. This frees the devname and the filename
-+ */
-+static inline void free_trustee_name(struct trustee_name *name)
-+{
-+ vfree(name->filename);
-+ vfree(name->devname);
-+}
-+
-+/*
-+ * Frees the capsules, and the filenames for a trustee hash element.
-+ * Also marks it as unused in the hash.
-+ */
-+static inline void free_hash_element(struct trustee_hash_element *e)
-+{
-+ free_hash_element_list(e);
-+ free_trustee_name(&e->name);
-+ vfree(e);
-+}
-+
-+/**
-+ * Copies from src to dest (duplicating the strings in the
-+ * trustee_name structure. Returns zero for unsuccesful.
-+ */
-+static int copy_trustee_name(struct trustee_name *dst, struct trustee_name *src)
-+{
-+ *dst = *src;
-+ if (dst->filename) {
-+ dst->filename = vmalloc_strdup(src->filename, strlen(src->filename));
-+ if (!dst->filename) {
-+ TS_ERR_MSG("Ran out of memory duplicating src->filename\n");
-+ return 0;
-+ }
-+ }
-+
-+ if (dst->devname) {
-+ dst->devname = vmalloc_strdup(src->devname, strlen(src->devname));
-+ if (!dst->devname) {
-+ TS_ERR_MSG("Ran out of memory duplicating src->devname\n");
-+ vfree(dst->filename);
-+ return 0;
-+ }
-+ }
-+
-+ return 1;
-+}
-+
-+
-+/*
-+ * hashing function researched by Karl Nelson <kenelson @ ece ucdavis edu>
-+ * and is used in glib.
-+ */
-+static inline unsigned int hash_string(const char *s)
-+{
-+ unsigned int v = 0;
-+
-+ while (*s) {
-+ v = (v << 5) - v + tolower(*s);
-+ s++;
-+ }
-+
-+ return v;
-+}
-+
-+/*
-+ * Return the hash for a device.
-+ */
-+static inline unsigned int hash_device(const char *name, dev_t device)
-+{
-+ if (MAJOR(device) == 0) {
-+ return hash_string(name);
-+ }
-+
-+ return new_encode_dev(device);
-+}
-+
-+/*
-+ * Return the hash for a file. This is a combination of the
-+ * hash of the filename and the hash for the device.
-+ */
-+static inline unsigned int hash(const struct trustee_name *name)
-+{
-+ return hash_string(name->filename) ^
-+ hash_device(name->devname, name->dev);
-+}
-+
-+/*
-+ * Return the slot in the trustees_hash where a trustee is located
-+ */
-+static inline unsigned int hash_slot(const struct trustee_name *name)
-+{
-+ return hash(name) % trustee_hash_size;
-+}
-+
-+/*
-+ * Compare two devices. Return 1 if they are equal otherwise return 0
-+ */
-+static inline int trustee_dev_cmp(dev_t dev1, dev_t dev2, char *devname1,
-+ char *devname2)
-+{
-+ if ((MAJOR(dev1) == 0) && (MAJOR(dev2) == 0))
-+ return (strcmp(devname1, devname2) == 0);
-+ else if ((MAJOR(dev1) != 0) && (MAJOR(dev2) != 0))
-+ return (dev1 == dev2);
-+ return 0;
-+}
-+
-+/*
-+ * Compare two trustee_name's. Returns 1 if they are are equal
-+ * otherwise return 0
-+ */
-+static inline int trustee_name_cmp(const struct trustee_name *n1,
-+ const struct trustee_name *n2,
-+ unsigned ignore_case)
-+{
-+ if (trustee_dev_cmp(n1->dev, n2->dev, n1->devname, n2->devname))
-+ return ignore_case ?
-+ (strnicmp(n1->filename, n2->filename, PATH_MAX) == 0) :
-+ (strcmp(n1->filename, n2->filename) == 0);
-+ return 0;
-+}
-+
-+/*
-+ * Calculate the deepest level.
-+ */
-+static inline void calculate_deepest_level(const struct trustee_name *name)
-+{
-+ char *fn = name->filename;
-+ char *x;
-+ int level = 0;
-+
-+ for (x = fn; *x; ++x) {
-+ if (*x == '/')
-+ ++level;
-+ }
-+
-+ /* If it is the root, it should have
-+ * a level of 0.
-+ */
-+ if (x == (fn + 1)) level = 0;
-+
-+ if (level > deepest_level) deepest_level = level;
-+}
-+
-+/*
-+ * Return the trustee element for a name.
-+ * This should be called with a lock on the trustee_hash (which should
-+ * not be released until you are done with the returned hash_element)!
-+ */
-+static struct trustee_hash_element *get_trustee_for_name(const struct trustee_name *name,
-+ unsigned ignore_case)
-+{
-+ struct trustee_hash_element *item = NULL;
-+ struct hlist_node *iter = NULL;
-+
-+ hlist_for_each_entry(item, iter, &trustee_hash[hash_slot(name)], hash_list) {
-+ if (trustee_name_cmp(&item->name, name, ignore_case))
-+ return item;
-+ }
-+
-+ return NULL;
-+}
-+
-+/**
-+ * Add a new blank trustee to the hash.
-+ *
-+ * If this returns zero, then the adding failed and name should be freed
-+ * (assuming must_copy is 0), otherwise assume we used its memory.
-+ */
-+static unsigned add_trustee(struct trustee_name *name, int must_copy) {
-+ struct trustee_name newname;
-+ struct trustee_name rootname;
-+ unsigned is_root = 1;
-+ unsigned r = 0;
-+ struct trustee_hash_element *new;
-+ struct trustee_hash_element *root;
-+
-+ if (!name->filename || !name->filename[0]) goto err0;
-+
-+ if (!copy_trustee_name(&rootname, name)) goto err0;
-+ rootname.filename[1] = '\0';
-+
-+ if (strlen(name->filename) > 1 && strcmp(name->filename, "/")) {
-+ add_trustee(&rootname, 1);
-+ is_root = 0;
-+ }
-+
-+ if (must_copy) {
-+ if (!copy_trustee_name(&newname, name)) goto err1;
-+ } else {
-+ newname = *name;
-+ }
-+
-+ new = vmalloc(sizeof(struct trustee_hash_element));
-+ if (!new) goto err2;
-+ new->name = newname;
-+ INIT_HLIST_NODE(&new->hash_list);
-+ INIT_LIST_HEAD(&new->perm_list);
-+ INIT_LIST_HEAD(&new->device_list);
-+
-+ write_lock(&trustee_hash_lock);
-+ if (get_trustee_for_name(&newname, 0)) goto err3;
-+
-+ if (is_root) {
-+ root = NULL;
-+ } else if (!(root = get_trustee_for_name(&rootname, 0))) {
-+ TS_ERR_MSG("Root trustee disappeared on us!\n");
-+ goto err3;
-+ }
-+ hlist_add_head(&new->hash_list, &trustee_hash[hash_slot(name)]);
-+ if (!is_root) {
-+ list_add_tail(&new->device_list, &root->device_list);
-+ }
-+ calculate_deepest_level(&newname);
-+ TS_DEBUG_MSG("Created '%s' trustee\n", newname.filename);
-+ r = 1;
-+err3:
-+ write_unlock(&trustee_hash_lock);
-+ if (!r) vfree(new);
-+err2:
-+ if (must_copy && !r) free_trustee_name(&newname);
-+err1:
-+ free_trustee_name(&rootname);
-+err0:
-+ return r;
-+}
-+
-+/**
-+ * Add a permissions module to the trustee specified by name.
-+ */
-+static unsigned add_trustee_perm
-+ (struct trustee_name *name, struct trustee_permission acl)
-+{
-+ struct trustee_hash_element *r = NULL;
-+ struct trustee_permission_capsule *capsule;
-+
-+ capsule = vmalloc(sizeof(struct trustee_permission_capsule));
-+ if (!capsule) {
-+ TS_ERR_MSG
-+ ("Can not allocate memory for trustee capsule\n");
-+ return 0;
-+ }
-+ capsule->permission = acl;
-+
-+ write_lock(&trustee_hash_lock);
-+ r = get_trustee_for_name(name, 0);
-+
-+ if (r) {
-+ list_add_tail(&capsule->perm_list, &r->perm_list);
-+ write_unlock(&trustee_hash_lock);
-+ TS_DEBUG_MSG("Added permission capsule to '%s' trustee\n", name->filename);
-+ return 1;
-+ }
-+ write_unlock(&trustee_hash_lock);
-+ TS_ERR_MSG("trustee disappeared under us while trying to add perms\n");
-+ vfree(capsule);
-+
-+ return 0;
-+}
-+
-+/*
-+ * Get the mask for a trustee name.
-+ * This should be called with a lock on the trustee_hash (which should
-+ * not be released until you are done with the returned hash_element)!
-+ */
-+static int get_trustee_mask_for_name(struct trustee_name *name,
-+ int oldmask, int height,
-+ struct trustee_hash_element **element,
-+ unsigned ignore_case)
-+{
-+ struct trustee_hash_element *e;
-+ int m;
-+ struct trustee_permission_capsule *l;
-+ int appl;
-+ e = get_trustee_for_name(name, ignore_case);
-+ if (!e) {
-+ return oldmask;
-+ }
-+ list_for_each_entry(l, &e->perm_list, perm_list) {
-+ if ((height < 0)
-+ && (l->permission.mask & TRUSTEE_ONE_LEVEL_MASK))
-+ continue;
-+ if (element) {
-+ *element = e;
-+ element = NULL;
-+ }
-+ appl = ((!(l->permission.mask & TRUSTEE_IS_GROUP_MASK))
-+ && (current->fsuid == l->permission.u.uid))
-+ || (((l->permission.mask & TRUSTEE_IS_GROUP_MASK))
-+ && (in_group_p(l->permission.u.gid)))
-+ || (l->permission.mask & TRUSTEE_ALL_MASK);
-+ if (l->permission.mask & TRUSTEE_NOT_MASK)
-+ appl = !appl;
-+
-+ if (!appl)
-+ continue;
-+
-+ m = l->permission.mask & TRUSTEE_ACL_MASK;
-+
-+ if (l->permission.mask & TRUSTEE_ALLOW_DENY_MASK)
-+ m <<= TRUSTEE_NUM_ACL_BITS;
-+
-+ oldmask =
-+ l->permission.
-+ mask & TRUSTEE_CLEAR_SET_MASK ? (oldmask & (~m))
-+ : (oldmask | m);
-+ }
-+
-+ return oldmask;
-+}
-+
-+/*
-+ * Return non-zero if a trustee exists in a subpath.
-+ *
-+ * WARNING!
-+ * This function requires that you lock/unlock the trustees_hash_lock
-+ */
-+int trustee_has_child(struct vfsmount *mnt, char *file_name)
-+{
-+ struct trustee_name trustee_name;
-+ char tempchar;
-+ unsigned ignore_case = 0;
-+ struct trustee_hash_element *root;
-+ size_t len;
-+ struct trustee_ic *iter;
-+ struct trustee_hash_element *r;
-+
-+ if (!file_name || !*file_name) return 0;
-+
-+ list_for_each_entry(iter, &trustee_ic_list, ic_list) {
-+ if (trustee_dev_cmp
-+ (iter->dev, trustee_name.dev, iter->devname,
-+ trustee_name.devname)) {
-+ ignore_case = 1;
-+ break;
-+ }
-+ }
-+
-+ trustee_name.dev = mnt->mnt_sb->s_dev;
-+ trustee_name.devname = mnt->mnt_devname;
-+ trustee_name.filename = file_name;
-+ tempchar = file_name[1];
-+ file_name[1] = '\0';
-+
-+ root = get_trustee_for_name(&trustee_name, ignore_case);
-+ if (!root) return 0;
-+
-+ file_name[1] = tempchar;
-+
-+ len = strlen(file_name);
-+
-+ list_for_each_entry(r, &root->device_list, device_list) {
-+ size_t this_len = strlen(r->name.filename);
-+ if (this_len <= len) continue;
-+ if (!strncmp(file_name, r->name.filename, len) &&
-+ r->name.filename[len] != '\0')
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+/*
-+ * Return the mask for a file.
-+ *
-+ * WARNING!
-+ * This function requires that you lock/unlock the trustees_hash_lock
-+ */
-+int trustee_perm(struct dentry *dentry, struct vfsmount *mnt,
-+ char *file_name, int unix_ret, int depth, int is_dir,
-+ struct trustee_hash_element **deepest)
-+{
-+ static char dbl_nul_slash[3] = { '/', '\0', '\0' };
-+ int oldmask = trustee_default_acl;
-+ int height = 0;
-+ char *filecount;
-+ char c;
-+ struct trustee_name trustee_name;
-+ struct trustee_ic *iter;
-+ unsigned ignore_case = 0;
-+
-+ trustee_name.dev = mnt->mnt_sb->s_dev;
-+ trustee_name.devname = mnt->mnt_devname;
-+ trustee_name.filename = file_name;
-+
-+ list_for_each_entry(iter, &trustee_ic_list, ic_list) {
-+ if (trustee_dev_cmp
-+ (iter->dev, trustee_name.dev, iter->devname,
-+ trustee_name.devname)) {
-+ ignore_case = 1;
-+ break;
-+ }
-+ }
-+
-+ if (deepest) *deepest = NULL;
-+
-+ filecount = file_name + 1;
-+ /* Try to handle the unlikely case where the string will be '/'
-+ * out here to simplify the logic inside the loop. We do this
-+ * by giving it a string with two nul byte terminators so that it
-+ * will gracefully (and safely) make it through the loop below.
-+ */
-+ if (*filecount == '\0') {
-+ file_name = dbl_nul_slash;
-+ filecount = file_name + 1;
-+ }
-+ do {
-+ c = *filecount;
-+ *filecount = 0;
-+ oldmask =
-+ get_trustee_mask_for_name(&trustee_name, oldmask,
-+ height - depth + !is_dir,
-+ deepest, ignore_case);
-+ height++;
-+ *filecount = c;
-+ ++filecount;
-+ while ((*filecount) && (*filecount != '/')) filecount++;
-+
-+ } while(*filecount);
-+
-+ return oldmask;
-+}
-+
-+/* Clear out the hash of trustees and release the hash itself.
-+ * Also gets rid of the ignore-case list
-+ */
-+static void trustees_clear_all(void)
-+{
-+ struct trustee_hash_element *item = NULL;
-+ struct hlist_node *iter, *temp = NULL;
-+ unsigned i;
-+ write_lock(&trustee_hash_lock);
-+
-+ for (i = 0; i < trustee_hash_size; i++) {
-+ hlist_for_each_entry_safe(item, iter, temp, &trustee_hash[i], hash_list) {
-+ free_hash_element(item);
-+ }
-+ INIT_HLIST_HEAD(&trustee_hash[i]);
-+ }
-+
-+ deepest_level = 0;
-+
-+ remove_ic_devs();
-+
-+ write_unlock(&trustee_hash_lock);
-+}
-+
-+/*
-+ * Initialize globals
-+ */
-+int trustees_funcs_init_globals(void)
-+{
-+ unsigned int iter;
-+
-+ if (trustee_hash_size <= 0)
-+ return 1;
-+
-+ rwlock_init(&trustee_hash_lock);
-+
-+ trustee_hash = vmalloc(sizeof(*trustee_hash) * trustee_hash_size);
-+ if (!trustee_hash)
-+ return 1;
-+
-+ for (iter = 0; iter < trustee_hash_size; iter++)
-+ INIT_HLIST_HEAD(trustee_hash + iter);
-+
-+ return 0;
-+}
-+
-+/*
-+ * Clear globals
-+ */
-+int trustees_funcs_cleanup_globals(void)
-+{
-+ trustees_clear_all();
-+
-+ vfree(trustee_hash);
-+
-+ return 0;
-+}
-+
-+/*
-+ * Prepare a trustee name from a passed in trustee name.
-+ */
-+static int prepare_trustee_name(u32 device, char *devname, char *filename, struct trustee_name *name)
-+{
-+ size_t devl, filel;
-+ char *devb = NULL, *fileb = NULL;
-+
-+ if ((!name))
-+ return 0;
-+
-+ filel = strlen(filename);
-+ devl = strlen(devname);
-+
-+ if (devl > PATH_MAX) {
-+ TS_ERR_MSG("device name bad, command ignored.\n");
-+ return 0;
-+ }
-+ if (filel > PATH_MAX) {
-+ TS_ERR_MSG("file name bad, command ignored.\n");
-+ return 0;
-+ }
-+
-+ devb = vmalloc_strdup(devname, devl);
-+ if (!devb) {
-+ TS_ERR_MSG("Couldn't allocate mem for devb.\n");
-+ return 0;
-+ }
-+
-+ fileb = vmalloc_strdup(filename, filel);
-+ if (!fileb) {
-+ TS_ERR_MSG("Couldn't allocate mem for fileb.\n");
-+ return 0;
-+ }
-+
-+ name->devname = devb;
-+ name->filename = fileb;
-+
-+ name->dev = new_decode_dev(device);
-+
-+ return 1;
-+}
-+
-+/*
-+ * Process a user command
-+ */
-+extern int trustees_process_command(struct trustee_command command,
-+ void **arg,
-+ size_t *argsize)
-+{
-+ int r = -ENOSYS;
-+ int must_free = 0;
-+ struct trustee_name name;
-+
-+ if ((current->euid != 0) && !capable(CAP_SYS_ADMIN)) {
-+ r = -EACCES;
-+ return r;
-+ }
-+
-+ switch (command.command) {
-+ case TRUSTEE_COMMAND_MAKE_IC:
-+ if (command.numargs != 2 ||
-+ argsize[1] != sizeof(u32)) goto unlk;
-+ add_ic_dev(*(u32 *)arg[1], arg[0]);
-+ r = 0;
-+ break;
-+ case TRUSTEE_COMMAND_REMOVE_ALL:
-+ if (command.numargs != 0) goto unlk;
-+ trustees_clear_all();
-+ r = 0;
-+ break;
-+ case TRUSTEE_COMMAND_ADD:
-+ if (command.numargs != 4 ||
-+ argsize[3] != sizeof(u32) ||
-+ argsize[1] != sizeof(struct trustee_permission))
-+ goto unlk;
-+ if (!prepare_trustee_name(*(u32 *)arg[3], arg[2], arg[0], &name)) {
-+ r = -ENOMEM;
-+ goto unlk;
-+ }
-+ if (!add_trustee(&name, 0)) {
-+ must_free = 1;
-+ }
-+ if (!add_trustee_perm(&name, *(struct trustee_permission *)arg[1]))
-+ r = -ENOMEM;
-+ else
-+ r = 0;
-+
-+ if (must_free) free_trustee_name(&name);
-+ break;
-+ }
-+ unlk:
-+
-+ return r;
-+}
-diff -Nurd linux-2.6.24/security/trustees/init.c linux-2.6.24-oxe810/security/trustees/init.c
---- linux-2.6.24/security/trustees/init.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/security/trustees/init.c 2008-06-11 17:46:44.000000000 +0200
-@@ -0,0 +1,57 @@
-+/*
-+ * Trustees ACL Project
-+ *
-+ * Copyright (c) 1999-2000 Vyacheslav Zavadsky
-+ * Copyright (c) 2004 Andrew Ruder (aeruder@ksu.edu)
-+ *
-+ * 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, version 2.
-+ *
-+ * Module initialization and cleanup
-+ *
-+ * History:
-+ * 2002-12-16 trustees 2.10 released by Vyacheslav Zavadsky
-+ *
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/security.h>
-+#include <linux/capability.h>
-+
-+#include "internal.h"
-+
-+unsigned int trustee_hash_size = 256;
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("Trustees ACL System");
-+MODULE_AUTHOR("Vyacheslav Zavadsky and Andrew E. Ruder <aeruder@ksu.edu>");
-+MODULE_VERSION("2.11");
-+
-+MODULE_PARM_DESC(hash_size, "Trustees hash size");
-+module_param_named(hash_size, trustee_hash_size, uint, 0444);
-+
-+
-+static int __init trustees_init(void)
-+{
-+ if (trustees_funcs_init_globals() != 0) {
-+ return -EINVAL;
-+ }
-+
-+ if (trustees_init_fs() != 0) {
-+ trustees_funcs_cleanup_globals();
-+ return -EINVAL;
-+ }
-+
-+ if (trustees_init_security() != 0) {
-+ trustees_deinit_fs();
-+ trustees_funcs_cleanup_globals();
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+fs_initcall(trustees_init);
-diff -Nurd linux-2.6.24/security/trustees/internal.h linux-2.6.24-oxe810/security/trustees/internal.h
---- linux-2.6.24/security/trustees/internal.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/security/trustees/internal.h 2008-06-11 17:46:44.000000000 +0200
-@@ -0,0 +1,100 @@
-+/*
-+ * Trustees ACL Project
-+ *
-+ * Copyright (c) 1999-2000 Vyacheslav Zavadsky
-+ * Copyright (c) 2004 Andrew Ruder (aeruder@ksu.edu)
-+ *
-+ * 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, version 2.
-+ *
-+ * Private methods and definitions used only within the module.
-+ *
-+ */
-+
-+#ifndef _LINUX_TRUSTEES_H
-+#define _LINUX_TRUSTEES_H
-+#include <linux/types.h>
-+#include <linux/dcache.h>
-+#include <linux/kdev_t.h>
-+#include <linux/list.h>
-+#include <linux/version.h>
-+#include <linux/trustees.h>
-+
-+#define TRUSTEE_DEFAULT_MASK TRUSTEE_USE_UNIX_MASK
-+
-+struct trustee_ic {
-+ dev_t dev;
-+ char *devname; /* ONLY if MAJOR(dev)==0 */
-+ struct list_head ic_list;
-+};
-+
-+struct trustee_name {
-+ dev_t dev;
-+ char *filename;
-+ char *devname; /* ONLY if MAJOR(dev)==0 */
-+};
-+
-+struct trustee_permission_capsule {
-+ struct list_head perm_list;
-+ struct trustee_permission permission;
-+};
-+
-+/* For the usage field */
-+#define TRUSTEE_HASH_ELEMENT_USED 2
-+#define TRUSTEE_HASH_ELEMENT_DELETED 1
-+#define TRUSTEE_HASH_ELEMENT_NOTUSED 0
-+
-+struct trustee_hash_element {
-+ struct trustee_name name;
-+ struct list_head perm_list;
-+ struct hlist_node hash_list;
-+ struct list_head device_list;
-+};
-+
-+extern char *trustees_filename_for_dentry(struct dentry *dentry, int *d, int trunc);
-+
-+extern int trustees_funcs_init_globals(void);
-+extern int trustees_funcs_cleanup_globals(void);
-+
-+int trustee_has_child(struct vfsmount *mnt, char *file_name);
-+int trustee_perm(struct dentry *dentry, struct vfsmount *mnt,
-+ char *file_name, int unix_ret, int depth, int is_dir,
-+ struct trustee_hash_element **deepest);
-+
-+extern int trustees_process_command(struct trustee_command command,
-+ void **arg, size_t *argsize);
-+
-+extern unsigned int trustee_hash_size;
-+extern rwlock_t trustee_hash_lock;
-+
-+#define TRUSTEE_INITIAL_NAME_BUFFER 256
-+#define TRUSTEE_HASDEVNAME(TNAME) (MAJOR((TNAME).dev)==0)
-+
-+#define TS_ERR_MSG(...) printk(KERN_ERR "Trustees: " __VA_ARGS__)
-+
-+#ifdef TRUSTEES_DEBUG
-+#define TS_DEBUG_MSG(...) printk(KERN_ERR "Trustees: " __VA_ARGS__)
-+#else
-+#define TS_DEBUG_MSG(...)
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
-+#define NAMESPACE_SEM(_ns) (namespace_sem)
-+#else
-+#define NAMESPACE_SEM(_ns) ((_ns)->sem)
-+#endif
-+
-+/*
-+ * Magic number!
-+ *
-+ * FIXME: Do I just make this up or is there some system for coming
-+ * up with magic numbers?
-+ */
-+#define TRUSTEES_MAGIC 0x32236975
-+
-+int trustees_init_fs(void);
-+void trustees_deinit_fs(void);
-+
-+int trustees_init_security(void);
-+#endif /* _LINUX_TRUSTEES_H */
-diff -Nurd linux-2.6.24/security/trustees/security.c linux-2.6.24-oxe810/security/trustees/security.c
---- linux-2.6.24/security/trustees/security.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.24-oxe810/security/trustees/security.c 2008-06-11 17:46:44.000000000 +0200
-@@ -0,0 +1,423 @@
-+/*
-+ * Trustees ACL Project
-+ *
-+ * Copyright (c) 1999-2000 Vyacheslav Zavadsky
-+ * Copyright (c) 2004 Andrew Ruder (aeruder@ksu.edu)
-+ *
-+ * 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, version 2.
-+ *
-+ * The security module (LSM API) component of the trustees system
-+ *
-+ * One quick note: generally security modules with the LSM are supposed
-+ * to be solely restrictive modules. Unless the trustees module were to
-+ * require that people set all files rwx by all, it could not function
-+ * as it is meant to function as a solely restrictive module.
-+ *
-+ * To compensate, every process is given the capability CAP_DAC_OVERRIDE.
-+ * In other words, every process is first given full rights to the filesystem.
-+ * This is the only non-restricting portion of this module, since it -does-
-+ * in fact give additional permissions. However, in the inode_permission hook,
-+ * any rights the user should not have are taken away.
-+ *
-+ * Side effects: Posix ACLs or other filesystem-specific permissions are not
-+ * honored. Trustees ACLs can (and do) take into account the standard unix
-+ * permissions, but any permissions further than that are difficult, to say
-+ * the least, to take into account. I, personally, do not find this to
-+ * be a problem since if you are using Trustees ACLs, why also require the use
-+ * of another ACL system?
-+ */
-+
-+#include <linux/security.h>
-+#include <linux/capability.h>
-+#include <linux/mount.h>
-+#include <linux/namei.h>
-+#include <linux/fs.h>
-+#include <linux/slab.h>
-+#include <linux/smp_lock.h>
-+#include <linux/nsproxy.h>
-+#include <linux/mnt_namespace.h>
-+
-+#include "internal.h"
-+
-+static int trustees_capable(struct task_struct *tsk, int cap);
-+static int trustees_inode_permission(struct inode *inode,
-+ int mask, struct nameidata *nd);
-+
-+/* Checks if user has access to the inode due to root status
-+ */
-+static inline int has_root_perm(struct inode *inode, int mask)
-+{
-+ umode_t mode = inode->i_mode;
-+
-+ if (!(mask & MAY_EXEC) || (mode & S_IXUGO) || S_ISDIR(mode))
-+ if (current->fsuid == 0)
-+ return 0;
-+
-+ return -EACCES;
-+}
-+
-+/* The logic for this was mostly stolen from vfs_permission. The security API
-+ * doesn't give a good way to use the actual vfs_permission for this since our
-+ * CAP_DAC_OVERRIDE causes it to always return 0. But if we didn't return
-+ * CAP_DAC_OVERRIDE, we'd never get to handle permissions! Since we don't need
-+ * to handle capabilities and dealing with ACLs with trustees loaded isn't an
-+ * issue for me, the function ends up being pretty simple.
-+ */
-+
-+static inline int has_unix_perm(struct inode *inode, int mask)
-+{
-+ umode_t mode = inode->i_mode;
-+ mask &= ~MAY_APPEND;
-+
-+ if (current->fsuid == inode->i_uid)
-+ mode >>= 6;
-+ else if (in_group_p(inode->i_gid))
-+ mode >>= 3;
-+
-+ if (((mode & mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == mask))
-+ return 0;
-+
-+ return -EACCES;
-+}
-+
-+/* Find a vfsmount given an inode */
-+static inline struct vfsmount *find_inode_mnt(struct inode *inode,
-+ struct nameidata *nd)
-+{
-+ struct mnt_namespace *ns = NULL;
-+ struct vfsmount *mnt = NULL;
-+
-+ if (likely(nd))
-+ return mntget(nd->mnt);
-+
-+ /* Okay, we need to find the vfsmount by looking
-+ * at the namespace now.
-+ */
-+ task_lock(current);
-+ if (current->nsproxy) {
-+ ns = current->nsproxy->mnt_ns;
-+ if (ns)
-+ get_mnt_ns(ns);
-+ }
-+ task_unlock(current);
-+
-+ if (!ns) return NULL;
-+
-+ list_for_each_entry(mnt, &ns->list, mnt_list) {
-+ if (mnt->mnt_sb == inode->i_sb) {
-+ mntget(mnt);
-+ goto out;
-+ }
-+ }
-+
-+ out:
-+ put_mnt_ns(ns);
-+
-+ return mnt;
-+}
-+
-+/* Find a dentry given an inode */
-+static inline struct dentry *find_inode_dentry(struct inode *inode,
-+ struct nameidata *nd)
-+{
-+ struct dentry *dentry;
-+
-+ if (likely(nd))
-+ return dget(nd->dentry);
-+
-+ dentry = d_find_alias(inode);
-+
-+ return dentry;
-+}
-+
-+/*
-+ * Return 1 if they are under the same set of trustees
-+ * otherwise return 0. In the case that we are handling
-+ * a directory, we also check to see if there are subdirectories
-+ * with trustees.
-+ */
-+static inline int have_same_trustees(struct dentry *old_dentry,
-+ struct dentry *new_dentry)
-+{
-+ struct vfsmount *mnt;
-+ char *old_file_name, *new_file_name;
-+ int old_depth, new_depth;
-+ struct trustee_hash_element *old_deep, *new_deep;
-+ int is_dir;
-+ int ret = 0;
-+
-+ mnt = find_inode_mnt(old_dentry->d_inode, NULL);
-+ if (unlikely(!mnt)) {
-+ TS_ERR_MSG("inode does not have a mnt!\n");
-+ return 0;
-+ }
-+
-+ old_file_name = trustees_filename_for_dentry(old_dentry, &old_depth, 1);
-+ if (!old_file_name) {
-+ TS_ERR_MSG("Couldn't allocate filename\n");
-+ goto out_old_dentry;
-+ }
-+
-+ new_file_name = trustees_filename_for_dentry(new_dentry, &new_depth, 1);
-+ if (!new_file_name) {
-+ TS_ERR_MSG("Couldn't allocate filename\n");
-+ goto out_new_dentry;
-+ }
-+
-+ is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
-+
-+ read_lock(&trustee_hash_lock);
-+ trustee_perm(old_dentry, mnt, old_file_name, ret, old_depth, is_dir,
-+ &old_deep);
-+ trustee_perm(new_dentry, mnt, new_file_name, ret, new_depth, is_dir,
-+ &new_deep);
-+ if (old_deep == new_deep) {
-+ ret = 1;
-+ if (is_dir) {
-+ if (trustee_has_child(mnt, old_file_name) ||
-+ trustee_has_child(mnt, new_file_name)) ret = 0;
-+ }
-+ }
-+ read_unlock(&trustee_hash_lock);
-+
-+ kfree(new_file_name);
-+out_new_dentry:
-+ kfree(old_file_name);
-+out_old_dentry:
-+ mntput(mnt);
-+
-+ return ret;
-+}
-+
-+
-+static int trustees_inode_rename(struct inode *old_dir,
-+ struct dentry *old_dentry,
-+ struct inode *new_dir,
-+ struct dentry *new_dentry);
-+static int trustees_inode_link(struct dentry *old_dentry,
-+ struct inode *dir,
-+ struct dentry *new_dentry);
-+
-+/* Structure where we fill in the various hooks we are implementing in this module
-+ */
-+struct security_operations trustees_security_ops = {
-+ .capable = trustees_capable,
-+ .inode_permission = trustees_inode_permission,
-+ .inode_link = trustees_inode_link,
-+ .inode_rename = trustees_inode_rename,
-+
-+ .ptrace = cap_ptrace,
-+ .capget = cap_capget,
-+ .capset_check = cap_capset_check,
-+ .capset_set = cap_capset_set,
-+ .settime = cap_settime,
-+ .netlink_send = cap_netlink_send,
-+ .netlink_recv = cap_netlink_recv,
-+
-+ .bprm_apply_creds = cap_bprm_apply_creds,
-+ .bprm_set_security = cap_bprm_set_security,
-+ .bprm_secureexec = cap_bprm_secureexec,
-+
-+ .inode_setxattr = cap_inode_setxattr,
-+ .inode_removexattr = cap_inode_removexattr,
-+
-+ .task_post_setuid = cap_task_post_setuid,
-+ .task_reparent_to_init = cap_task_reparent_to_init,
-+
-+ .syslog = cap_syslog,
-+
-+ .vm_enough_memory = cap_vm_enough_memory
-+};
-+
-+#define ALL_MAYS (MAY_WRITE | MAY_EXEC | MAY_READ)
-+/* Converts a trustee_mask to a normal unix mask
-+ */
-+static int inline trustee_mask_to_normal_mask(int mask, int isdir)
-+{
-+ int r = 0;
-+ if ((mask & TRUSTEE_READ_MASK) && !isdir)
-+ r |= MAY_READ;
-+ if ((mask & TRUSTEE_READ_DIR_MASK) && isdir)
-+ r |= MAY_READ;
-+ if (mask & TRUSTEE_WRITE_MASK)
-+ r |= MAY_WRITE;
-+ if ((mask & TRUSTEE_BROWSE_MASK) && isdir)
-+ r |= MAY_EXEC;
-+ if ((mask & TRUSTEE_EXECUTE_MASK) && !isdir)
-+ r |= MAY_EXEC;
-+ return r;
-+}
-+
-+/* This is the meat of the permissions checking. First it checks for root,
-+ * otherwise it first checks for any errors finding the dentry/vfsmount for
-+ * the inode, and then it looks up the dentry in the trustees hash.
-+ */
-+static int trustees_inode_permission(struct inode *inode,
-+ int mask, struct nameidata *nd)
-+{
-+ struct dentry *dentry;
-+ struct vfsmount *mnt;
-+ char *file_name;
-+ int is_dir;
-+ int ret;
-+ int depth;
-+ int amask;
-+ int dmask;
-+ umode_t mode = inode->i_mode;
-+
-+ if (has_root_perm(inode, mask) == 0)
-+ return 0;
-+
-+ ret = has_unix_perm(inode, mask);
-+
-+ mnt = find_inode_mnt(inode, nd);
-+ if (unlikely(!mnt)) {
-+ TS_ERR_MSG("inode does not have a mnt!\n");
-+ return -EACCES; /* has_unix_perm(inode, mask); */
-+ }
-+
-+ dentry = find_inode_dentry(inode, nd);
-+ if (unlikely(!dentry)) {
-+ /* Most of the time when this happens, it is the /
-+ * If it is not, we need to dump as much information
-+ * as possible on it and dump it to logs, because
-+ * I'm really not sure how it happens.
-+ */
-+ if (inode == mnt->mnt_root->d_inode) {
-+ dentry = dget(mnt->mnt_root);
-+ } else {
-+ /* I have seen this happen once but I did not have any
-+ * way to see what caused it. I am gonna dump_stack
-+ * until I have that happen again to see if the cause
-+ * is something that I need to worry about.
-+ */
-+ dump_stack(); /* DEBUG FIXME */
-+ TS_ERR_MSG("Inode number: %ld\n", inode->i_ino);
-+ TS_ERR_MSG("dentry does not exist!\n");
-+ goto out_mnt;
-+ }
-+ }
-+ file_name = trustees_filename_for_dentry(dentry, &depth, 1);
-+ if (!file_name) {
-+ TS_ERR_MSG("Couldn't allocate filename\n");
-+ ret = -EACCES;
-+ goto out_dentry;
-+ }
-+
-+ is_dir = S_ISDIR(inode->i_mode);
-+
-+ read_lock(&trustee_hash_lock);
-+ amask = trustee_perm(dentry, mnt, file_name, ret, depth, is_dir,
-+ (struct trustee_hash_element **)NULL);
-+ read_unlock(&trustee_hash_lock);
-+ dmask = amask >> TRUSTEE_NUM_ACL_BITS;
-+
-+ /* no permission if denied */
-+ if (trustee_mask_to_normal_mask(dmask, is_dir) & mask & ALL_MAYS) {
-+ ret = -EACCES;
-+ goto out;
-+ }
-+ /* use unix perms */
-+ if (!(dmask & TRUSTEE_USE_UNIX_MASK) &&
-+ (amask & TRUSTEE_USE_UNIX_MASK) && (!ret))
-+ goto out;
-+
-+ /* if the file isn't executable, then the trustees shouldn't
-+ * make it executable
-+ */
-+ if ((mask & MAY_EXEC) && !(mode & S_IXOTH) &&
-+ !((mode >> 3) & S_IXOTH) & !((mode >> 6) & S_IXOTH) &&
-+ (!is_dir)) {
-+ ret = -EACCES;
-+ goto out;
-+ }
-+ /* Check trustees for permission
-+ */
-+ if ((trustee_mask_to_normal_mask(amask, is_dir) & mask & ALL_MAYS)
-+ == mask) {
-+ ret = 0;
-+ goto out;
-+ } else
-+ ret = -EACCES;
-+
-+ out:
-+ kfree(file_name);
-+ out_dentry:
-+ dput(dentry);
-+ out_mnt:
-+ mntput(mnt);
-+
-+ return ret;
-+}
-+
-+/* We should only allow hard links under one of two conditions:
-+ * 1. Its in the same trustee
-+ * - if the two dentries are covered by the same trustee, there shouldn't
-+ * be much of a problem with allowing the hardlink to occur.
-+ * 2. fsuid = 0
-+ */
-+static int trustees_inode_link(struct dentry *old_dentry,
-+ struct inode *dir,
-+ struct dentry *new_dentry)
-+{
-+ if (current->fsuid == 0)
-+ return 0;
-+
-+ if (have_same_trustees(old_dentry, new_dentry))
-+ return 0;
-+
-+ return -EXDEV;
-+}
-+
-+/* We have a few renames to protect against:
-+ * 1. Any file or directory that is affected by different trustees at its
-+ * old location than at its new location.
-+ * 2. In the case of a directory, we should protect against moving a directory
-+ * that has trustees set inside of it.
-+ *
-+ * In any case above, we return -EXDEV which signifies to the calling program that
-+ * the files are on different devices, and assuming the program is written correctly
-+ * it should then handle the situation by copying the files and removing the originals
-+ * ( which will then use the trustees permissions as they are meant to be used )
-+ */
-+static int trustees_inode_rename(struct inode *old_dir,
-+ struct dentry *old_dentry,
-+ struct inode *new_dir,
-+ struct dentry *new_dentry)
-+{
-+ if (current->fsuid == 0)
-+ return 0;
-+
-+ if (have_same_trustees(old_dentry, new_dentry)) return 0;
-+
-+ return -EXDEV;
-+}
-+
-+/* Return CAP_DAC_OVERRIDE on everything. We want to handle our own
-+ * permissions (overriding those normally allowed by unix permissions)
-+ */
-+static int trustees_capable(struct task_struct *tsk, int cap)
-+{
-+ if (cap == CAP_DAC_OVERRIDE)
-+ return 0;
-+
-+ return cap_capable(tsk, cap);
-+}
-+
-+/* Register the security module
-+ */
-+int trustees_init_security(void)
-+{
-+ /* FIXME: add in secondary module register
-+ * not worry about it now since I have better
-+ * things to worry about. Comprende?
-+ */
-+ if (register_security(&trustees_security_ops)) {
-+ TS_ERR_MSG("Could not register security component\n");
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-diff -Nurd linux-2.6.24/sound/oss/via82cxxx_audio.c linux-2.6.24-oxe810/sound/oss/via82cxxx_audio.c
---- linux-2.6.24/sound/oss/via82cxxx_audio.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/sound/oss/via82cxxx_audio.c 2008-06-11 17:46:29.000000000 +0200
-@@ -2104,6 +2104,7 @@
- {
- struct via_info *card = vma->vm_private_data;
- struct via_channel *chan = &card->ch_out;
-+ unsigned long max_bufs;
- struct page *dmapage;
- unsigned long pgoff;
- int rd, wr;
-@@ -2127,14 +2128,11 @@
- rd = card->ch_in.is_mapped;
- wr = card->ch_out.is_mapped;
-
--#ifndef VIA_NDEBUG
-- {
-- unsigned long max_bufs = chan->frag_number;
-- if (rd && wr) max_bufs *= 2;
-- /* via_dsp_mmap() should ensure this */
-- assert (pgoff < max_bufs);
-- }
--#endif
-+ max_bufs = chan->frag_number;
-+ if (rd && wr)
-+ max_bufs *= 2;
-+ if (pgoff >= max_bufs)
-+ return NOPAGE_SIGBUS;
-
- /* if full-duplex (read+write) and we have two sets of bufs,
- * then the playback buffers come first, sez soundcard.c */
-diff -Nurd linux-2.6.24/sound/usb/usx2y/usX2Yhwdep.c linux-2.6.24-oxe810/sound/usb/usx2y/usX2Yhwdep.c
---- linux-2.6.24/sound/usb/usx2y/usX2Yhwdep.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/sound/usb/usx2y/usX2Yhwdep.c 2008-06-11 17:46:26.000000000 +0200
-@@ -88,7 +88,7 @@
- us428->us428ctls_sharedmem->CtlSnapShotLast = -2;
- }
- area->vm_ops = &us428ctls_vm_ops;
-- area->vm_flags |= VM_RESERVED;
-+ area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
- area->vm_private_data = hw->private_data;
- return 0;
- }
-diff -Nurd linux-2.6.24/sound/usb/usx2y/usx2yhwdeppcm.c linux-2.6.24-oxe810/sound/usb/usx2y/usx2yhwdeppcm.c
---- linux-2.6.24/sound/usb/usx2y/usx2yhwdeppcm.c 2008-01-24 23:58:37.000000000 +0100
-+++ linux-2.6.24-oxe810/sound/usb/usx2y/usx2yhwdeppcm.c 2008-06-11 17:46:26.000000000 +0200
-@@ -728,7 +728,7 @@
- return -ENODEV;
- }
- area->vm_ops = &snd_usX2Y_hwdep_pcm_vm_ops;
-- area->vm_flags |= VM_RESERVED;
-+ area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
- area->vm_private_data = hw->private_data;
- return 0;
- }
--- /dev/null
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.24.4
+# Fri Oct 17 14:41:04 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_GENERIC_GPIO is not set
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=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_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_FAIR_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# 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_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+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 is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+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"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+CONFIG_ARCH_OXNAS=y
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Oxford Semiconductor NAS Options
+#
+# CONFIG_ARCH_OXNAS_FPGA is not set
+CONFIG_NOMINAL_PLL400_FREQ=733333333
+CONFIG_NOMINAL_RPSCLK_FREQ=25000000
+# CONFIG_OXNAS_VERSION_0X800 is not set
+CONFIG_OXNAS_VERSION_0X810=y
+# CONFIG_OXNAS_VERSION_0X850 is not set
+# CONFIG_ARCH_OXNAS_UART1 is not set
+CONFIG_ARCH_OXNAS_UART2=y
+# CONFIG_ARCH_OXNAS_UART2_MODEM is not set
+# CONFIG_ARCH_OXNAS_UART3 is not set
+# CONFIG_ARCH_OXNAS_PCI_REQGNT_0 is not set
+# CONFIG_ARCH_OXNAS_PCI_REQGNT_1 is not set
+# CONFIG_ARCH_OXNAS_PCI_REQGNT_2 is not set
+# CONFIG_ARCH_OXNAS_PCI_REQGNT_3 is not set
+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_0 is not set
+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_1 is not set
+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_2 is not set
+# CONFIG_ARCH_OXNAS_PCI_CLKOUT_3 is not set
+# CONFIG_OXNAS_PCI_RESET is not set
+# CONFIG_OXNAS_SATA_POWER_1 is not set
+# CONFIG_OXNAS_SATA_POWER_2 is not set
+CONFIG_FORCE_MAX_ZONEORDER=10
+CONFIG_SRAM_NUM_PAGES=32
+CONFIG_SUPPORT_LEON=y
+CONFIG_LEON_PAGES=2
+CONFIG_LEON_COPRO=y
+CONFIG_LEON_OFFLOAD_TX=y
+# CONFIG_LEON_RESERVE_DMA_CHANNEL is not set
+CONFIG_LEON_OFFLOAD_TSO=y
+# CONFIG_LEON_START_EARLY is not set
+CONFIG_LEON_POWER_BUTTON_MONITOR=m
+CONFIG_OXNAS_POWER_BUTTON_GPIO=4
+CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
+CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO=32
+# CONFIG_OXNAS_DDR_MON is not set
+# CONFIG_OXNAS_AHB_MON is not set
+# CONFIG_OXNAS_CACHE_LOCKDOWN is not set
+# CONFIG_DO_MEM_TEST is not set
+# CONFIG_CRYPTO_OXAESLRW is not set
+CONFIG_DESCRIPTORS_PAGES=6
+CONFIG_ARCH_OXNAS_NUM_GMAC_DESCRIPTORS=192
+CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES=256
+CONFIG_TACHO_THERM_AND_FAN=m
+# CONFIG_GPIO_TEST is not set
+CONFIG_OXNAS_RTC=y
+# CONFIG_I2S is not set
+# CONFIG_DPE_TEST is not set
+# CONFIG_OXNAS_INSTRUMENT_COPIES is not set
+# CONFIG_OXNAS_DMA_COPIES is not set
+# CONFIG_OXNAS_AHB_MONITOR_MODULE is not set
+# CONFIG_OXNAS_USB_TEST_MODES is not set
+# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
+# CONFIG_OXNAS_LED_TEST is not set
+CONFIG_OXNAS_I2C_SDA=6
+CONFIG_OXNAS_I2C_SCL=7
+# CONFIG_OXNAS_USB_PORTA_POWER_CONTROL is not set
+# CONFIG_OXNAS_USB_PORTB_POWER_CONTROL is not set
+# CONFIG_OXNAS_USB_PORTC_POWER_CONTROL is not set
+# CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE is not set
+# CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE is not set
+# CONFIG_WDC_FAN_OXNAS800 is not set
+# CONFIG_OXNAS_MAP_SRAM is not set
+# CONFIG_OXNAS_SUID_INHERIT is not set
+# CONFIG_OXNAS_USB_HUB_SUPPORT is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+CONFIG_PCI=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+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_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE 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=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE 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_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT=y
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 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=y
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 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=10240
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+# 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=y
+
+#
+# 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 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=y
+# 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=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+CONFIG_SATA_OX810=y
+# CONFIG_SATA_OXNAS_SINGLE_SATA is not set
+# CONFIG_SATA_OXNAS_DISK_LIGHT is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=y
+# CONFIG_MD_RAID0 is not set
+CONFIG_MD_RAID1=y
+# CONFIG_MD_RAID10 is not set
+# CONFIG_MD_RAID456 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_MD_FAULTY is not set
+CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=y
+# CONFIG_DM_SNAPSHOT is not set
+# CONFIG_DM_MIRROR is not set
+# CONFIG_DM_ZERO is not set
+# CONFIG_DM_MULTIPATH is not set
+# CONFIG_DM_DELAY is not set
+# CONFIG_DM_UEVENT is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# 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_ARCNET is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_MII=y
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+CONFIG_SYNOPSYS_GMAC=y
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# 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_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER 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
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# 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 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=m
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+# CONFIG_I2C_ALGOOXSEMI is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+CONFIG_I2C_OXNAS_BITBASH=m
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 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
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+# 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_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# 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
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# 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_AUERSWALD 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_PHIDGET 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=m
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=m
+
+#
+# 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=m
+# 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
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PL031 is not set
+# CONFIG_DMADEVICES is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=y
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_SECURITY is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+CONFIG_HFSPLUS_FS=m
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+# CONFIG_NFS_FS is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+# CONFIG_SUNRPC_BIND34 is not set
+# 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+CONFIG_LDM_PARTITION=y
+# CONFIG_LDM_DEBUG is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+CONFIG_EFI_PARTITION=y
+# CONFIG_SYSV68_PARTITION is not set
+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 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=y
+# CONFIG_DLM is not set
+# CONFIG_INSTRUMENTATION is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_SAMPLES is not set
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_CAPABILITIES is not set
+CONFIG_SECURITY_TRUSTEES=y
+# CONFIG_SECURITY_TRUSTEES_DEBUG is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
--- /dev/null
+diff -Nurd linux-2.6.24.org/arch/arm/configs/oxnas_810_eabi_dse_defconfig linux-2.6.24/arch/arm/configs/oxnas_810_eabi_dse_defconfig
+--- linux-2.6.24.org/arch/arm/configs/oxnas_810_eabi_dse_defconfig 2009-02-05 12:06:15.000000000 +0100
++++ linux-2.6.24/arch/arm/configs/oxnas_810_eabi_dse_defconfig 2009-02-05 12:08:36.000000000 +0100
+@@ -160,6 +160,8 @@
+ # CONFIG_OXNAS_VERSION_0X850 is not set
+ # CONFIG_ARCH_OXNAS_UART1 is not set
+ CONFIG_ARCH_OXNAS_UART2=y
++CONFIG_ARCH_OXNAS_UART2_DEBUG=y
++CONFIG_ARCH_OXNAS_UART2_BOOTPROGRESS=y
+ # CONFIG_ARCH_OXNAS_UART2_MODEM is not set
+ # CONFIG_ARCH_OXNAS_UART3 is not set
+ # CONFIG_ARCH_OXNAS_PCI_REQGNT_0 is not set
+diff -Nurd linux-2.6.24.org/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig linux-2.6.24/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig
+--- linux-2.6.24.org/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig 2009-02-05 12:06:15.000000000 +0100
++++ linux-2.6.24/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig 2009-02-05 12:08:36.000000000 +0100
+@@ -152,6 +152,8 @@
+ # CONFIG_OXNAS_VERSION_0X850 is not set
+ # CONFIG_ARCH_OXNAS_UART1 is not set
+ CONFIG_ARCH_OXNAS_UART2=y
++CONFIG_ARCH_OXNAS_UART2_DEBUG=y
++CONFIG_ARCH_OXNAS_UART2_BOOTPROGRESS=y
+ # CONFIG_ARCH_OXNAS_UART2_MODEM is not set
+ # CONFIG_ARCH_OXNAS_UART3 is not set
+ # CONFIG_ARCH_OXNAS_PCI_REQGNT_0 is not set
+diff -Nurd linux-2.6.24.org/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig
+--- linux-2.6.24.org/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig 2009-02-05 12:06:15.000000000 +0100
++++ linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig 2009-02-05 12:08:36.000000000 +0100
+@@ -160,6 +160,8 @@
+ # CONFIG_OXNAS_VERSION_0X850 is not set
+ # CONFIG_ARCH_OXNAS_UART1 is not set
+ CONFIG_ARCH_OXNAS_UART2=y
++CONFIG_ARCH_OXNAS_UART2_DEBUG=y
++CONFIG_ARCH_OXNAS_UART2_BOOTPROGRESS=y
+ # CONFIG_ARCH_OXNAS_UART2_MODEM is not set
+ # CONFIG_ARCH_OXNAS_UART3 is not set
+ # CONFIG_ARCH_OXNAS_UART4 is not set
+diff -Nurd linux-2.6.24.org/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig
+--- linux-2.6.24.org/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig 2009-02-05 12:06:15.000000000 +0100
++++ linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig 2009-02-05 12:08:36.000000000 +0100
+@@ -158,6 +158,8 @@
+ # CONFIG_OXNAS_VERSION_0X850 is not set
+ # CONFIG_ARCH_OXNAS_UART1 is not set
+ CONFIG_ARCH_OXNAS_UART2=y
++CONFIG_ARCH_OXNAS_UART2_DEBUG=y
++CONFIG_ARCH_OXNAS_UART2_BOOTPROGRESS=y
+ # CONFIG_ARCH_OXNAS_UART2_MODEM is not set
+ # CONFIG_ARCH_OXNAS_UART3 is not set
+ # CONFIG_ARCH_OXNAS_UART4 is not set
+diff -Nurd linux-2.6.24.org/arch/arm/mach-oxnas/Kconfig linux-2.6.24/arch/arm/mach-oxnas/Kconfig
+--- linux-2.6.24.org/arch/arm/mach-oxnas/Kconfig 2009-02-05 12:06:15.000000000 +0100
++++ linux-2.6.24/arch/arm/mach-oxnas/Kconfig 2009-02-05 12:08:34.000000000 +0100
+@@ -66,6 +66,20 @@
+ UARTs will be mapped to ttySn numbers from UART1 to UART4, only
+ including those UARTs selected to be present
+
++config ARCH_OXNAS_UART1_DEBUG
++ bool "Use UART1 as debug channel"
++ depends on ARCH_OXNAS_UART1
++ default n
++ help
++ This enables UART1 to be usable as debug channel.
++
++config ARCH_OXNAS_UART1_BOOTPROGRESS
++ bool "Display boot progress over UART1"
++ depends on ARCH_OXNAS_UART1
++ default n
++ help
++ This enables displaying boot progress over UART1.
++
+ config ARCH_OXNAS_UART1_MODEM
+ bool "Support UART1 modem control lines"
+ depends on ARCH_OXNAS_UART1
+@@ -81,6 +95,20 @@
+ UARTs will be mapped to ttySn numbers from UART1 to UART4, only
+ including those UARTs selected to be present
+
++config ARCH_OXNAS_UART2_DEBUG
++ bool "Use UART2 as debug channel"
++ depends on ARCH_OXNAS_UART2
++ default n
++ help
++ This enables UART2 to be usable as debug channel.
++
++config ARCH_OXNAS_UART2_BOOTPROGRESS
++ bool "Display boot progress over UART2"
++ depends on ARCH_OXNAS_UART2
++ default n
++ help
++ This enables displaying boot progress over UART2.
++
+ config ARCH_OXNAS_UART2_MODEM
+ bool "Support UART2 modem control lines"
+ depends on ARCH_OXNAS_UART2
+@@ -96,6 +124,20 @@
+ UARTs will be mapped to ttySn numbers from UART1 to UART4, only
+ including those UARTs selected to be present
+
++config ARCH_OXNAS_UART3_DEBUG
++ bool "Use UART3 as debug channel"
++ depends on ARCH_OXNAS_UART3
++ default n
++ help
++ This enables UART3 to be usable as debug channel.
++
++config ARCH_OXNAS_UART3_BOOTPROGRESS
++ bool "Display boot progress over UART3"
++ depends on ARCH_OXNAS_UART3
++ default n
++ help
++ This enables displaying boot progress over UART3.
++
+ config ARCH_OXNAS_UART3_MODEM
+ bool "Support UART3 modem control lines"
+ depends on ARCH_OXNAS_UART3
+@@ -114,6 +156,20 @@
+ UART4 always has its modem control lines available on external pins
+ when selected (overlaying PCI functions)
+
++config ARCH_OXNAS_UART4_DEBUG
++ bool "Use UART4 as debug channel"
++ depends on ARCH_OXNAS_UART4
++ default n
++ help
++ This enables UART4 to be usable as debug channel.
++
++config ARCH_OXNAS_UART4_BOOTPROGRESS
++ bool "Display boot progress over UART4"
++ depends on ARCH_OXNAS_UART4
++ default n
++ help
++ This enables displaying boot progress over UART4.
++
+ config ARCH_OXNAS_PCI_REQGNT_0
+ bool "Enable req/gnt for PCI device 0"
+ depends on PCI
+diff -Nurd linux-2.6.24.org/include/asm-arm/arch-oxnas/debug-macro.S linux-2.6.24/include/asm-arm/arch-oxnas/debug-macro.S
+--- linux-2.6.24.org/include/asm-arm/arch-oxnas/debug-macro.S 2009-02-05 12:06:19.000000000 +0100
++++ linux-2.6.24/include/asm-arm/arch-oxnas/debug-macro.S 2009-02-05 12:08:34.000000000 +0100
+@@ -14,13 +14,13 @@
+ .macro addruart,rx
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+-#ifdef CONFIG_ARCH_OXNAS_UART1
++#ifdef CONFIG_ARCH_OXNAS_UART1_DEBUG
+ ldreq \rx, =UART_1_BASE_PA @ physical base address
+ ldrne \rx, =UART_1_BASE @ virtual address
+-#elif CONFIG_ARCH_OXNAS_UART2
++#elif CONFIG_ARCH_OXNAS_UART2_DEBUG
+ ldreq \rx, =UART_2_BASE_PA @ physical base address
+ ldrne \rx, =UART_2_BASE @ virtual address
+-#elif CONFIG_ARCH_OXNAS_UART3
++#elif CONFIG_ARCH_OXNAS_UART3_DEBUG
+ ldreq \rx, =UART_3_BASE_PA @ physical base address
+ ldrne \rx, =UART_3_BASE @ virtual address
+ #else
+diff -Nurd linux-2.6.24.org/include/asm-arm/arch-oxnas/uncompress.h linux-2.6.24/include/asm-arm/arch-oxnas/uncompress.h
+--- linux-2.6.24.org/include/asm-arm/arch-oxnas/uncompress.h 2009-02-05 12:06:19.000000000 +0100
++++ linux-2.6.24/include/asm-arm/arch-oxnas/uncompress.h 2009-02-05 12:08:34.000000000 +0100
+@@ -12,13 +12,13 @@
+
+ static inline void putc(int c)
+ {
+-#ifdef CONFIG_ARCH_OXNAS_UART1
++#ifdef CONFIG_ARCH_OXNAS_UART1_BOOTPROGRESS
+ static volatile unsigned char* uart = (volatile unsigned char*)UART_1_BASE_PA;
+-#elif defined(CONFIG_ARCH_OXNAS_UART2)
++#elif defined(CONFIG_ARCH_OXNAS_UART2_BOOTPROGRESS)
+ static volatile unsigned char* uart = (volatile unsigned char*)UART_2_BASE_PA;
+-#elif defined(CONFIG_ARCH_OXNAS_UART3)
++#elif defined(CONFIG_ARCH_OXNAS_UART3_BOOTPROGRESS)
+ static volatile unsigned char* uart = (volatile unsigned char*)UART_3_BASE_PA;
+-#elif defined(CONFIG_ARCH_OXNAS_UART4)
++#elif defined(CONFIG_ARCH_OXNAS_UART4_BOOTPROGRESS)
+ static volatile unsigned char* uart = (volatile unsigned char*)UART_4_BASE_PA;
+ #else
+ #define NO_UART
--- /dev/null
+diff -Nurd linux-2.6.24/.gitignore linux-2.6.24-oxe810/.gitignore
+--- linux-2.6.24/.gitignore 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/.gitignore 1970-01-01 01:00:00.000000000 +0100
+@@ -1,54 +0,0 @@
+-#
+-# NOTE! Don't add files that are generated in specific
+-# subdirectories here. Add them in the ".gitignore" file
+-# in that subdirectory instead.
+-#
+-# Normal rules
+-#
+-.*
+-*.o
+-*.o.*
+-*.a
+-*.s
+-*.ko
+-*.so
+-*.so.dbg
+-*.mod.c
+-*.i
+-*.lst
+-*.symtypes
+-
+-#
+-# Top-level generic files
+-#
+-tags
+-TAGS
+-vmlinux*
+-!vmlinux.lds.S
+-System.map
+-Module.symvers
+-!.gitignore
+-
+-#
+-# Generated include files
+-#
+-include/asm
+-include/asm-*/asm-offsets.h
+-include/config
+-include/linux/autoconf.h
+-include/linux/compile.h
+-include/linux/version.h
+-include/linux/utsrelease.h
+-
+-# stgit generated dirs
+-patches-*
+-
+-# quilt's files
+-patches
+-series
+-
+-# cscope files
+-cscope.*
+-
+-*.orig
+-*.rej
+diff -Nurd linux-2.6.24/.mailmap linux-2.6.24-oxe810/.mailmap
+--- linux-2.6.24/.mailmap 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/.mailmap 1970-01-01 01:00:00.000000000 +0100
+@@ -1,98 +0,0 @@
+-#
+-# This list is used by git-shortlog to fix a few botched name translations
+-# in the git archive, either because the author's full name was messed up
+-# and/or not always written the same way, making contributions from the
+-# same person appearing not to be so or badly displayed.
+-#
+-# repo-abbrev: /pub/scm/linux/kernel/git/
+-#
+-
+-Aaron Durbin <adurbin@google.com>
+-Adam Oldham <oldhamca@gmail.com>
+-Adam Radford <aradford@gmail.com>
+-Adrian Bunk <bunk@stusta.de>
+-Alan Cox <alan@lxorguk.ukuu.org.uk>
+-Alan Cox <root@hraefn.swansea.linux.org.uk>
+-Aleksey Gorelov <aleksey_gorelov@phoenix.com>
+-Al Viro <viro@ftp.linux.org.uk>
+-Al Viro <viro@zenIV.linux.org.uk>
+-Andreas Herrmann <aherrman@de.ibm.com>
+-Andrew Morton <akpm@osdl.org>
+-Andrew Vasquez <andrew.vasquez@qlogic.com>
+-Andy Adamson <andros@citi.umich.edu>
+-Arnaud Patard <arnaud.patard@rtp-net.org>
+-Arnd Bergmann <arnd@arndb.de>
+-Axel Dyks <xl@xlsigned.net>
+-Ben Gardner <bgardner@wabtec.com>
+-Ben M Cahill <ben.m.cahill@intel.com>
+-Björn Steinbrink <B.Steinbrink@gmx.de>
+-Brian Avery <b.avery@hp.com>
+-Brian King <brking@us.ibm.com>
+-Christoph Hellwig <hch@lst.de>
+-Corey Minyard <minyard@acm.org>
+-David Brownell <david-b@pacbell.net>
+-David Woodhouse <dwmw2@shinybook.infradead.org>
+-Domen Puncer <domen@coderock.org>
+-Douglas Gilbert <dougg@torque.net>
+-Ed L. Cashin <ecashin@coraid.com>
+-Evgeniy Polyakov <johnpol@2ka.mipt.ru>
+-Felipe W Damasio <felipewd@terra.com.br>
+-Felix Kuhling <fxkuehl@gmx.de>
+-Felix Moeller <felix@derklecks.de>
+-Filipe Lautert <filipe@icewall.org>
+-Franck Bui-Huu <vagabon.xyz@gmail.com>
+-Frank Zago <fzago@systemfabricworks.com>
+-Greg Kroah-Hartman <greg@echidna.(none)>
+-Greg Kroah-Hartman <gregkh@suse.de>
+-Greg Kroah-Hartman <greg@kroah.com>
+-Henk Vergonet <Henk.Vergonet@gmail.com>
+-Henrik Kretzschmar <henne@nachtwindheim.de>
+-Herbert Xu <herbert@gondor.apana.org.au>
+-Jacob Shin <Jacob.Shin@amd.com>
+-James Bottomley <jejb@mulgrave.(none)>
+-James Bottomley <jejb@titanic.il.steeleye.com>
+-James E Wilson <wilson@specifix.com>
+-James Ketrenos <jketreno@io.(none)>
+-Jean Tourrilhes <jt@hpl.hp.com>
+-Jeff Garzik <jgarzik@pretzel.yyz.us>
+-Jens Axboe <axboe@suse.de>
+-Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
+-John Stultz <johnstul@us.ibm.com>
+-Juha Yrjola <at solidboot.com>
+-Juha Yrjola <juha.yrjola@nokia.com>
+-Juha Yrjola <juha.yrjola@solidboot.com>
+-Kay Sievers <kay.sievers@vrfy.org>
+-Kenneth W Chen <kenneth.w.chen@intel.com>
+-Koushik <raghavendra.koushik@neterion.com>
+-Leonid I Ananiev <leonid.i.ananiev@intel.com>
+-Linas Vepstas <linas@austin.ibm.com>
+-Matthieu CASTET <castet.matthieu@free.fr>
+-Michael Buesch <mb@bu3sch.de>
+-Michael Buesch <mbuesch@freenet.de>
+-Michel Dänzer <michel@tungstengraphics.com>
+-Mitesh shah <mshah@teja.com>
+-Morten Welinder <terra@gnome.org>
+-Morten Welinder <welinder@anemone.rentec.com>
+-Morten Welinder <welinder@darter.rentec.com>
+-Morten Welinder <welinder@troll.com>
+-Nguyen Anh Quynh <aquynh@gmail.com>
+-Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
+-Patrick Mochel <mochel@digitalimplant.org>
+-Peter A Jonsson <pj@ludd.ltu.se>
+-Praveen BP <praveenbp@ti.com>
+-Rajesh Shah <rajesh.shah@intel.com>
+-Ralf Baechle <ralf@linux-mips.org>
+-Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+-Rémi Denis-Courmont <rdenis@simphalempin.com>
+-Rudolf Marek <R.Marek@sh.cvut.cz>
+-Rui Saraiva <rmps@joel.ist.utl.pt>
+-Sachin P Sant <ssant@in.ibm.com>
+-Sam Ravnborg <sam@mars.ravnborg.org>
+-Simon Kelley <simon@thekelleys.org.uk>
+-Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr>
+-Stephen Hemminger <shemminger@osdl.org>
+-Tejun Heo <htejun@gmail.com>
+-Thomas Graf <tgraf@suug.ch>
+-Tony Luck <tony.luck@intel.com>
+-Tsuneo Yoshioka <Tsuneo.Yoshioka@f-secure.com>
+-Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
+diff -Nurd linux-2.6.24/Documentation/video4linux/CARDLIST.cx23885 linux-2.6.24-oxe810/Documentation/video4linux/CARDLIST.cx23885
+--- linux-2.6.24/Documentation/video4linux/CARDLIST.cx23885 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/Documentation/video4linux/CARDLIST.cx23885 2008-06-11 17:47:23.000000000 +0200
+@@ -1,5 +1,5 @@
+ 0 -> UNKNOWN/GENERIC [0070:3400]
+ 1 -> Hauppauge WinTV-HVR1800lp [0070:7600]
+- 2 -> Hauppauge WinTV-HVR1800 [0070:7800,0070:7801]
++ 2 -> Hauppauge WinTV-HVR1800 [0070:7800,0070:7801,0070:7809]
+ 3 -> Hauppauge WinTV-HVR1250 [0070:7911]
+ 4 -> DViCO FusionHDTV5 Express [18ac:d500]
+diff -Nurd linux-2.6.24/Makefile linux-2.6.24-oxe810/Makefile
+--- linux-2.6.24/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/Makefile 2008-06-11 17:50:34.000000000 +0200
+@@ -1,8 +1,8 @@
+ VERSION = 2
+ PATCHLEVEL = 6
+ SUBLEVEL = 24
+-EXTRAVERSION =
+-NAME = Arr Matey! A Hairy Bilge Rat!
++EXTRAVERSION = .4
++NAME = Err Metey! A Heury Beelge-a Ret!
+
+ # *DOCUMENTATION*
+ # To see a list of typical targets execute "make help"
+@@ -190,8 +190,8 @@
+ # Default value for CROSS_COMPILE is not to prefix executables
+ # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
+
+-ARCH ?= $(SUBARCH)
+-CROSS_COMPILE ?=
++ARCH ?= arm
++CROSS_COMPILE ?= arm-linux-uclibcgnueabi-
+
+ # Architecture as present in compile.h
+ UTS_MACHINE := $(ARCH)
+diff -Nurd linux-2.6.24/arch/arm/Kconfig linux-2.6.24-oxe810/arch/arm/Kconfig
+--- linux-2.6.24/arch/arm/Kconfig 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/Kconfig 2008-06-11 17:47:58.000000000 +0200
+@@ -409,6 +409,10 @@
+ help
+ Support for TI's OMAP platform (OMAP1 and OMAP2).
+
++config ARCH_OXNAS
++ bool "Oxford Semiconductor NAS SoC"
++ help
++ This enables support for Oxsemi NAS SoC
+ endchoice
+
+ source "arch/arm/mach-clps711x/Kconfig"
+@@ -461,6 +465,8 @@
+
+ source "arch/arm/mach-versatile/Kconfig"
+
++source "arch/arm/mach-oxnas/Kconfig"
++
+ source "arch/arm/mach-aaec2000/Kconfig"
+
+ source "arch/arm/mach-realview/Kconfig"
+@@ -537,7 +543,7 @@
+ bool
+
+ config PCI
+- bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE
++ bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE || ARCH_OXNAS
+ help
+ Find out whether you have a PCI motherboard. PCI is the name of a
+ bus system, i.e. the way the CPU talks to the other stuff inside
+@@ -653,11 +659,13 @@
+ to have accurate timekeeping with dynamic tick.
+
+ config HZ
+- int
++ int "Kernel timer tick rate"
+ default 128 if ARCH_L7200
+ default 200 if ARCH_EBSA110 || ARCH_S3C2410
+ default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER
+ default 100
++ help
++ Sets the number of timer tick interrupts per second
+
+ config AEABI
+ bool "Use the ARM EABI to compile the kernel"
+@@ -1010,7 +1018,7 @@
+ if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \
+ || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
+ || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
+- || ARCH_IXP23XX
++ || ARCH_IXP23XX || ARCH_OXNAS
+ source "drivers/ide/Kconfig"
+ endif
+
+diff -Nurd linux-2.6.24/arch/arm/Makefile linux-2.6.24-oxe810/arch/arm/Makefile
+--- linux-2.6.24/arch/arm/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/Makefile 2008-06-11 17:47:58.000000000 +0200
+@@ -127,6 +127,7 @@
+ machine-$(CONFIG_ARCH_VERSATILE) := versatile
+ machine-$(CONFIG_ARCH_IMX) := imx
+ machine-$(CONFIG_ARCH_H720X) := h720x
++ machine-$(CONFIG_ARCH_OXNAS) := oxnas
+ machine-$(CONFIG_ARCH_AAEC2000) := aaec2000
+ machine-$(CONFIG_ARCH_REALVIEW) := realview
+ machine-$(CONFIG_ARCH_AT91) := at91
+diff -Nurd linux-2.6.24/arch/arm/configs/oxnas_810_eabi_dse_defconfig linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_dse_defconfig
+--- linux-2.6.24/arch/arm/configs/oxnas_810_eabi_dse_defconfig 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_dse_defconfig 2008-06-11 17:47:52.000000000 +0200
+@@ -0,0 +1,1233 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.24.4
++# Mon Jun 2 12:34:33 2008
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++# CONFIG_GENERIC_GPIO is not set
++# CONFIG_GENERIC_TIME is not set
++# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ZONE_DMA=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=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_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++# CONFIG_FAIR_GROUP_SCHED is not set
++# CONFIG_FAIR_USER_SCHED is not set
++# CONFIG_FAIR_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# 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_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_SLOB is not set
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++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 is not set
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++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"
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++CONFIG_ARCH_OXNAS=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Oxford Semiconductor NAS Options
++#
++# CONFIG_ARCH_OXNAS_FPGA is not set
++CONFIG_NOMINAL_PLL400_FREQ=733333333
++CONFIG_NOMINAL_RPSCLK_FREQ=25000000
++# CONFIG_OXNAS_VERSION_0X800 is not set
++CONFIG_OXNAS_VERSION_0X810=y
++# CONFIG_OXNAS_VERSION_0X850 is not set
++# CONFIG_ARCH_OXNAS_UART1 is not set
++CONFIG_ARCH_OXNAS_UART2=y
++# CONFIG_ARCH_OXNAS_UART2_MODEM is not set
++# CONFIG_ARCH_OXNAS_UART3 is not set
++# CONFIG_ARCH_OXNAS_PCI_REQGNT_0 is not set
++# CONFIG_ARCH_OXNAS_PCI_REQGNT_1 is not set
++# CONFIG_ARCH_OXNAS_PCI_REQGNT_2 is not set
++# CONFIG_ARCH_OXNAS_PCI_REQGNT_3 is not set
++# CONFIG_ARCH_OXNAS_PCI_CLKOUT_0 is not set
++# CONFIG_ARCH_OXNAS_PCI_CLKOUT_1 is not set
++# CONFIG_ARCH_OXNAS_PCI_CLKOUT_2 is not set
++# CONFIG_ARCH_OXNAS_PCI_CLKOUT_3 is not set
++# CONFIG_OXNAS_PCI_RESET is not set
++CONFIG_FORCE_MAX_ZONEORDER=10
++CONFIG_SRAM_NUM_PAGES=32
++CONFIG_SUPPORT_LEON=y
++CONFIG_LEON_PAGES=2
++CONFIG_LEON_COPRO=y
++CONFIG_LEON_OFFLOAD_TX=y
++# CONFIG_LEON_RESERVE_DMA_CHANNEL is not set
++CONFIG_LEON_OFFLOAD_TSO=y
++# CONFIG_LEON_START_EARLY is not set
++CONFIG_LEON_POWER_BUTTON_MONITOR=m
++CONFIG_OXNAS_POWER_BUTTON_GPIO=4
++CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
++CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO=32
++# CONFIG_OXNAS_DDR_MON is not set
++# CONFIG_OXNAS_AHB_MON is not set
++# CONFIG_OXNAS_CACHE_LOCKDOWN is not set
++# CONFIG_DO_MEM_TEST is not set
++# CONFIG_CRYPTO_OXAESLRW is not set
++CONFIG_DESCRIPTORS_PAGES=6
++CONFIG_ARCH_OXNAS_NUM_GMAC_DESCRIPTORS=192
++CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES=256
++CONFIG_TACHO_THERM_AND_FAN=m
++# CONFIG_GPIO_TEST is not set
++CONFIG_OXNAS_RTC=m
++# CONFIG_I2S is not set
++# CONFIG_DPE_TEST is not set
++# CONFIG_OXNAS_INSTRUMENT_COPIES is not set
++# CONFIG_OXNAS_DMA_COPIES is not set
++# CONFIG_OXNAS_AHB_MONITOR_MODULE is not set
++# CONFIG_OXNAS_USB_TEST_MODES is not set
++# CONFIG_OXNAS_FRONT_LAMP_CONTROL is not set
++# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
++# CONFIG_OXNAS_LED_TEST is not set
++CONFIG_OXNAS_I2C_SDA=6
++CONFIG_OXNAS_I2C_SCL=7
++# CONFIG_OXNAS_USB_PORTA_POWER_CONTROL is not set
++# CONFIG_OXNAS_USB_PORTB_POWER_CONTROL is not set
++# CONFIG_OXNAS_USB_PORTC_POWER_CONTROL is not set
++# CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE is not set
++# CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE is not set
++# CONFIG_WDC_FAN_OXNAS800 is not set
++# CONFIG_OXNAS_MAP_SRAM is not set
++# CONFIG_OXNAS_SUID_INHERIT is not set
++# CONFIG_OXNAS_USB_HUB_SUPPORT is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++CONFIG_PCI=y
++CONFIG_PCI_SYSCALL=y
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++CONFIG_PCI_LEGACY=y
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++# CONFIG_TICK_ONESHOT is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_NO_IDLE_HZ is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++# CONFIG_VFP is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_SUSPEND_UP_POSSIBLE=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++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_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++# CONFIG_IP_PNP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE 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=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IP_VS is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETLABEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++
++#
++# Core Netfilter Configuration
++#
++# CONFIG_NETFILTER_NETLINK is not set
++# CONFIG_NF_CONNTRACK_ENABLED is not set
++# CONFIG_NF_CONNTRACK is not set
++# CONFIG_NETFILTER_XTABLES is not set
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE 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_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++CONFIG_WIRELESS_EXT=y
++# CONFIG_MAC80211 is not set
++# CONFIG_IEEE80211 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=y
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++# CONFIG_MTD is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_NBD is not set
++# CONFIG_BLK_DEV_SX8 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=10240
++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MISC_DEVICES is not set
++# 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=y
++
++#
++# 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 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=y
++# 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=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
++# CONFIG_SCSI_3W_9XXX is not set
++# CONFIG_SCSI_ACARD is not set
++# CONFIG_SCSI_AACRAID is not set
++# CONFIG_SCSI_AIC7XXX is not set
++# CONFIG_SCSI_AIC7XXX_OLD is not set
++# CONFIG_SCSI_AIC79XX is not set
++# CONFIG_SCSI_AIC94XX is not set
++# CONFIG_SCSI_DPT_I2O is not set
++# CONFIG_SCSI_ADVANSYS is not set
++# CONFIG_SCSI_ARCMSR is not set
++# CONFIG_MEGARAID_NEWGEN is not set
++# CONFIG_MEGARAID_LEGACY is not set
++# CONFIG_MEGARAID_SAS is not set
++# CONFIG_SCSI_HPTIOP is not set
++# CONFIG_SCSI_DMX3191D is not set
++# CONFIG_SCSI_FUTURE_DOMAIN is not set
++# CONFIG_SCSI_IPS is not set
++# CONFIG_SCSI_INITIO is not set
++# CONFIG_SCSI_INIA100 is not set
++# CONFIG_SCSI_STEX is not set
++# CONFIG_SCSI_SYM53C8XX_2 is not set
++# CONFIG_SCSI_IPR is not set
++# CONFIG_SCSI_QLOGIC_1280 is not set
++# CONFIG_SCSI_QLA_FC is not set
++# CONFIG_SCSI_QLA_ISCSI is not set
++# CONFIG_SCSI_LPFC is not set
++# CONFIG_SCSI_DC395x is not set
++# CONFIG_SCSI_DC390T is not set
++# CONFIG_SCSI_NSP32 is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_SRP is not set
++CONFIG_ATA=y
++# CONFIG_ATA_NONSTANDARD is not set
++# CONFIG_SATA_AHCI is not set
++# CONFIG_SATA_SVW is not set
++# CONFIG_ATA_PIIX is not set
++# CONFIG_SATA_MV is not set
++# CONFIG_SATA_NV is not set
++# CONFIG_PDC_ADMA is not set
++# CONFIG_SATA_QSTOR is not set
++# CONFIG_SATA_PROMISE is not set
++# CONFIG_SATA_SX4 is not set
++# CONFIG_SATA_SIL is not set
++# CONFIG_SATA_SIL24 is not set
++# CONFIG_SATA_SIS is not set
++# CONFIG_SATA_ULI is not set
++# CONFIG_SATA_VIA is not set
++# CONFIG_SATA_VITESSE is not set
++# CONFIG_SATA_INIC162X is not set
++CONFIG_SATA_OX810=y
++# CONFIG_SATA_OXNAS_SINGLE_SATA is not set
++# CONFIG_SATA_OXNAS_DISK_LIGHT is not set
++# CONFIG_PATA_ALI is not set
++# CONFIG_PATA_AMD is not set
++# CONFIG_PATA_ARTOP is not set
++# CONFIG_PATA_ATIIXP is not set
++# CONFIG_PATA_CMD640_PCI is not set
++# CONFIG_PATA_CMD64X is not set
++# CONFIG_PATA_CS5520 is not set
++# CONFIG_PATA_CS5530 is not set
++# CONFIG_PATA_CYPRESS is not set
++# CONFIG_PATA_EFAR is not set
++# CONFIG_ATA_GENERIC is not set
++# CONFIG_PATA_HPT366 is not set
++# CONFIG_PATA_HPT37X is not set
++# CONFIG_PATA_HPT3X2N is not set
++# CONFIG_PATA_HPT3X3 is not set
++# CONFIG_PATA_IT821X is not set
++# CONFIG_PATA_IT8213 is not set
++# CONFIG_PATA_JMICRON is not set
++# CONFIG_PATA_TRIFLEX is not set
++# CONFIG_PATA_MARVELL is not set
++# CONFIG_PATA_MPIIX is not set
++# CONFIG_PATA_OLDPIIX is not set
++# CONFIG_PATA_NETCELL is not set
++# CONFIG_PATA_NS87410 is not set
++# CONFIG_PATA_NS87415 is not set
++# CONFIG_PATA_OPTI is not set
++# CONFIG_PATA_OPTIDMA is not set
++# CONFIG_PATA_PDC_OLD is not set
++# CONFIG_PATA_RADISYS is not set
++# CONFIG_PATA_RZ1000 is not set
++# CONFIG_PATA_SC1200 is not set
++# CONFIG_PATA_SERVERWORKS is not set
++# CONFIG_PATA_PDC2027X is not set
++# CONFIG_PATA_SIL680 is not set
++# CONFIG_PATA_SIS is not set
++# CONFIG_PATA_VIA is not set
++# CONFIG_PATA_WINBOND is not set
++CONFIG_MD=y
++CONFIG_BLK_DEV_MD=y
++CONFIG_MD_LINEAR=y
++# CONFIG_MD_RAID0 is not set
++CONFIG_MD_RAID1=y
++# CONFIG_MD_RAID10 is not set
++# CONFIG_MD_RAID456 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_MD_FAULTY is not set
++CONFIG_BLK_DEV_DM=y
++# CONFIG_DM_DEBUG is not set
++CONFIG_DM_CRYPT=y
++# CONFIG_DM_SNAPSHOT is not set
++# CONFIG_DM_MIRROR is not set
++# CONFIG_DM_ZERO is not set
++# CONFIG_DM_MULTIPATH is not set
++# CONFIG_DM_DELAY is not set
++# CONFIG_DM_UEVENT is not set
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# CONFIG_FIREWIRE is not set
++# CONFIG_IEEE1394 is not set
++# CONFIG_I2O is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# 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_ARCNET is not set
++# CONFIG_NET_ETHERNET is not set
++CONFIG_MII=y
++CONFIG_NETDEV_1000=y
++# CONFIG_ACENIC is not set
++# CONFIG_DL2K is not set
++# CONFIG_E1000 is not set
++# CONFIG_E1000E is not set
++# CONFIG_IP1000 is not set
++# CONFIG_NS83820 is not set
++# CONFIG_HAMACHI is not set
++# CONFIG_YELLOWFIN is not set
++# CONFIG_R8169 is not set
++# CONFIG_SIS190 is not set
++# CONFIG_SKGE is not set
++# CONFIG_SKY2 is not set
++# CONFIG_SK98LIN is not set
++# CONFIG_VIA_VELOCITY is not set
++# CONFIG_TIGON3 is not set
++# CONFIG_BNX2 is not set
++# CONFIG_QLA3XXX is not set
++# CONFIG_ATL1 is not set
++CONFIG_SYNOPSYS_GMAC=y
++# CONFIG_NETDEV_10000 is not set
++# CONFIG_TR is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++
++#
++# 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_FDDI is not set
++# CONFIG_HIPPI is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NET_FC is not set
++# CONFIG_SHAPER 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
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# 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 is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_PCI=y
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
++CONFIG_UNIX98_PTYS=y
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=m
++# CONFIG_NVRAM is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_DEVPORT=y
++CONFIG_I2C=m
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_CHARDEV is not set
++
++#
++# I2C Algorithms
++#
++CONFIG_I2C_ALGOBIT=m
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++# CONFIG_I2C_ALGOOXSEMI is not set
++
++#
++# I2C Hardware Bus support
++#
++# CONFIG_I2C_ALI1535 is not set
++# CONFIG_I2C_ALI1563 is not set
++# CONFIG_I2C_ALI15X3 is not set
++# CONFIG_I2C_AMD756 is not set
++# CONFIG_I2C_AMD8111 is not set
++# CONFIG_I2C_I801 is not set
++# CONFIG_I2C_I810 is not set
++# CONFIG_I2C_PIIX4 is not set
++# CONFIG_I2C_NFORCE2 is not set
++CONFIG_I2C_OXNAS_BITBASH=m
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_PROSAVAGE is not set
++# CONFIG_I2C_SAVAGE4 is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_SIS5595 is not set
++# CONFIG_I2C_SIS630 is not set
++# CONFIG_I2C_SIS96X is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_TINY_USB is not set
++# CONFIG_I2C_VIA is not set
++# CONFIG_I2C_VIAPRO is not set
++# CONFIG_I2C_VOODOO3 is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_SENSORS_DS1337 is not set
++# CONFIG_SENSORS_DS1374 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 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
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++CONFIG_DAB=y
++# CONFIG_USB_DABUSB is not set
++
++#
++# Graphics support
++#
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++CONFIG_VIDEO_OUTPUT_CONTROL=m
++# 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_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++# CONFIG_HID_SUPPORT is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++CONFIG_USB_EHCI_HCD=m
++# CONFIG_USB_EHCI_SPLIT_ISO is not set
++CONFIG_USB_EHCI_ROOT_HUB_TT=y
++# CONFIG_USB_EHCI_TT_NEWSCHED is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_OHCI_HCD is not set
++# CONFIG_USB_UHCI_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=m
++# 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
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_MON is not set
++
++#
++# USB port drivers
++#
++
++#
++# USB Serial Converter support
++#
++# 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_AUERSWALD 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_PHIDGET 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=m
++
++#
++# USB DSL modem support
++#
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++# CONFIG_MMC is not set
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=m
++
++#
++# 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=m
++# 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
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_PL031 is not set
++# CONFIG_DMADEVICES is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_XFS_FS=y
++# CONFIG_XFS_QUOTA is not set
++# CONFIG_XFS_SECURITY is not set
++# CONFIG_XFS_POSIX_ACL is not set
++# CONFIG_XFS_RT is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++CONFIG_DNOTIFY=y
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++CONFIG_FUSE_FS=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=m
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=m
++# CONFIG_NTFS_DEBUG is not set
++# CONFIG_NTFS_RW is not set
++
++#
++# Pseudo filesystems
++#
++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_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++CONFIG_HFSPLUS_FS=m
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++# CONFIG_NFS_FS is not set
++CONFIG_NFSD=m
++CONFIG_NFSD_V2_ACL=y
++CONFIG_NFSD_V3=y
++CONFIG_NFSD_V3_ACL=y
++# CONFIG_NFSD_V4 is not set
++CONFIG_NFSD_TCP=y
++CONFIG_LOCKD=m
++CONFIG_LOCKD_V4=y
++CONFIG_EXPORTFS=m
++CONFIG_NFS_ACL_SUPPORT=m
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=m
++# CONFIG_SUNRPC_BIND34 is not set
++# 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=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++CONFIG_MAC_PARTITION=y
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++CONFIG_LDM_PARTITION=y
++# CONFIG_LDM_DEBUG is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++CONFIG_EFI_PARTITION=y
++# CONFIG_SYSV68_PARTITION is not set
++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 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=y
++# CONFIG_DLM is not set
++# CONFIG_INSTRUMENTATION is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_SAMPLES is not set
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++CONFIG_SECURITY=y
++# CONFIG_SECURITY_NETWORK is not set
++# CONFIG_SECURITY_CAPABILITIES is not set
++CONFIG_SECURITY_TRUSTEES=y
++# CONFIG_SECURITY_TRUSTEES_DEBUG is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=m
++CONFIG_CRYPTO_CBC=y
++CONFIG_CRYPTO_PCBC=m
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++CONFIG_CRYPTO_AES=m
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++CONFIG_CRYPTO_ARC4=m
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++CONFIG_CRYPTO_MICHAEL_MIC=m
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++CONFIG_CRYPTO_HW=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_CRC_CCITT=y
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Nurd linux-2.6.24/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig
+--- linux-2.6.24/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_upgrade_defconfig 2008-06-11 17:47:52.000000000 +0200
+@@ -0,0 +1,901 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.24.4
++# Thu May 15 10:43:48 2008
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++# CONFIG_GENERIC_GPIO is not set
++# CONFIG_GENERIC_TIME is not set
++# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ZONE_DMA=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++CONFIG_FAIR_GROUP_SCHED=y
++CONFIG_FAIR_USER_SCHED=y
++# CONFIG_FAIR_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# 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_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_SLOB is not set
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++# CONFIG_MODULES is not set
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++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"
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++CONFIG_ARCH_OXNAS=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Oxford Semiconductor NAS Options
++#
++# CONFIG_ARCH_OXNAS_FPGA is not set
++CONFIG_NOMINAL_PLL400_FREQ=733333333
++CONFIG_NOMINAL_RPSCLK_FREQ=25000000
++# CONFIG_OXNAS_VERSION_0X800 is not set
++CONFIG_OXNAS_VERSION_0X810=y
++# CONFIG_OXNAS_VERSION_0X850 is not set
++# CONFIG_ARCH_OXNAS_UART1 is not set
++CONFIG_ARCH_OXNAS_UART2=y
++# CONFIG_ARCH_OXNAS_UART2_MODEM is not set
++# CONFIG_ARCH_OXNAS_UART3 is not set
++# CONFIG_ARCH_OXNAS_PCI_REQGNT_0 is not set
++# CONFIG_ARCH_OXNAS_PCI_REQGNT_1 is not set
++# CONFIG_ARCH_OXNAS_PCI_REQGNT_2 is not set
++# CONFIG_ARCH_OXNAS_PCI_REQGNT_3 is not set
++# CONFIG_ARCH_OXNAS_PCI_CLKOUT_0 is not set
++# CONFIG_ARCH_OXNAS_PCI_CLKOUT_1 is not set
++# CONFIG_ARCH_OXNAS_PCI_CLKOUT_2 is not set
++# CONFIG_ARCH_OXNAS_PCI_CLKOUT_3 is not set
++# CONFIG_OXNAS_PCI_RESET is not set
++CONFIG_FORCE_MAX_ZONEORDER=10
++CONFIG_SRAM_NUM_PAGES=32
++CONFIG_SUPPORT_LEON=y
++CONFIG_LEON_PAGES=2
++# CONFIG_LEON_COPRO is not set
++# CONFIG_LEON_START_EARLY is not set
++CONFIG_LEON_POWER_BUTTON_MONITOR=y
++CONFIG_OXNAS_POWER_BUTTON_GPIO=4
++CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
++CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO=32
++# CONFIG_OXNAS_DDR_MON is not set
++# CONFIG_OXNAS_AHB_MON is not set
++# CONFIG_OXNAS_CACHE_LOCKDOWN is not set
++# CONFIG_DO_MEM_TEST is not set
++# CONFIG_CRYPTO_OXAESLRW is not set
++CONFIG_DESCRIPTORS_PAGES=6
++CONFIG_ARCH_OXNAS_NUM_GMAC_DESCRIPTORS=192
++CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES=256
++# CONFIG_TACHO_THERM_AND_FAN is not set
++# CONFIG_GPIO_TEST is not set
++# CONFIG_OXNAS_RTC is not set
++# CONFIG_I2S is not set
++# CONFIG_DPE_TEST is not set
++# CONFIG_OXNAS_INSTRUMENT_COPIES is not set
++# CONFIG_OXNAS_DMA_COPIES is not set
++# CONFIG_OXNAS_AHB_MONITOR_MODULE is not set
++# CONFIG_OXNAS_USB_TEST_MODES is not set
++# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
++# CONFIG_OXNAS_LED_TEST is not set
++CONFIG_OXNAS_I2C_SDA=6
++CONFIG_OXNAS_I2C_SCL=7
++# CONFIG_OXNAS_USB_PORTA_POWER_CONTROL is not set
++# CONFIG_OXNAS_USB_PORTB_POWER_CONTROL is not set
++# CONFIG_OXNAS_USB_PORTC_POWER_CONTROL is not set
++# CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE is not set
++# CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE is not set
++# CONFIG_WDC_FAN_OXNAS800 is not set
++# CONFIG_OXNAS_MAP_SRAM is not set
++# CONFIG_OXNAS_SUID_INHERIT is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++CONFIG_PCI=y
++CONFIG_PCI_SYSCALL=y
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++CONFIG_PCI_LEGACY=y
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++# CONFIG_TICK_ONESHOT is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_NO_IDLE_HZ is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_VFP=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_SUSPEND_UP_POSSIBLE=y
++
++#
++# Networking
++#
++# CONFIG_NET 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_SYS_HYPERVISOR is not set
++# CONFIG_MTD is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_CPQ_DA is not set
++# CONFIG_BLK_CPQ_CISS_DA is not set
++# CONFIG_BLK_DEV_DAC960 is not set
++# CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_SX8 is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=1
++CONFIG_BLK_DEV_RAM_SIZE=10240
++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_MISC_DEVICES is not set
++# 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=y
++
++#
++# 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 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=y
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++# CONFIG_SCSI_SCAN_ASYNC is not set
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++CONFIG_SCSI_LOWLEVEL=y
++# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
++# CONFIG_SCSI_3W_9XXX is not set
++# CONFIG_SCSI_ACARD is not set
++# CONFIG_SCSI_AACRAID is not set
++# CONFIG_SCSI_AIC7XXX is not set
++# CONFIG_SCSI_AIC7XXX_OLD is not set
++# CONFIG_SCSI_AIC79XX is not set
++# CONFIG_SCSI_AIC94XX is not set
++# CONFIG_SCSI_DPT_I2O is not set
++# CONFIG_SCSI_ADVANSYS is not set
++# CONFIG_SCSI_ARCMSR is not set
++# CONFIG_MEGARAID_NEWGEN is not set
++# CONFIG_MEGARAID_LEGACY is not set
++# CONFIG_MEGARAID_SAS is not set
++# CONFIG_SCSI_HPTIOP is not set
++# CONFIG_SCSI_DMX3191D is not set
++# CONFIG_SCSI_FUTURE_DOMAIN is not set
++# CONFIG_SCSI_IPS is not set
++# CONFIG_SCSI_INITIO is not set
++# CONFIG_SCSI_INIA100 is not set
++# CONFIG_SCSI_STEX is not set
++# CONFIG_SCSI_SYM53C8XX_2 is not set
++# CONFIG_SCSI_IPR is not set
++# CONFIG_SCSI_QLOGIC_1280 is not set
++# CONFIG_SCSI_QLA_FC is not set
++# CONFIG_SCSI_LPFC is not set
++# CONFIG_SCSI_DC395x is not set
++# CONFIG_SCSI_DC390T is not set
++# CONFIG_SCSI_NSP32 is not set
++# CONFIG_SCSI_DEBUG is not set
++# CONFIG_SCSI_SRP is not set
++CONFIG_ATA=y
++# CONFIG_ATA_NONSTANDARD is not set
++# CONFIG_SATA_AHCI is not set
++# CONFIG_SATA_SVW is not set
++# CONFIG_ATA_PIIX is not set
++# CONFIG_SATA_MV is not set
++# CONFIG_SATA_NV is not set
++# CONFIG_PDC_ADMA is not set
++# CONFIG_SATA_QSTOR is not set
++# CONFIG_SATA_PROMISE is not set
++# CONFIG_SATA_SX4 is not set
++# CONFIG_SATA_SIL is not set
++# CONFIG_SATA_SIL24 is not set
++# CONFIG_SATA_SIS is not set
++# CONFIG_SATA_ULI is not set
++# CONFIG_SATA_VIA is not set
++# CONFIG_SATA_VITESSE is not set
++# CONFIG_SATA_INIC162X is not set
++CONFIG_SATA_OX810=y
++# CONFIG_SATA_OXNAS_SINGLE_SATA is not set
++# CONFIG_SATA_OXNAS_DISK_LIGHT is not set
++# CONFIG_PATA_ALI is not set
++# CONFIG_PATA_AMD is not set
++# CONFIG_PATA_ARTOP is not set
++# CONFIG_PATA_ATIIXP is not set
++# CONFIG_PATA_CMD640_PCI is not set
++# CONFIG_PATA_CMD64X is not set
++# CONFIG_PATA_CS5520 is not set
++# CONFIG_PATA_CS5530 is not set
++# CONFIG_PATA_CYPRESS is not set
++# CONFIG_PATA_EFAR is not set
++# CONFIG_ATA_GENERIC is not set
++# CONFIG_PATA_HPT366 is not set
++# CONFIG_PATA_HPT37X is not set
++# CONFIG_PATA_HPT3X2N is not set
++# CONFIG_PATA_HPT3X3 is not set
++# CONFIG_PATA_IT821X is not set
++# CONFIG_PATA_IT8213 is not set
++# CONFIG_PATA_JMICRON is not set
++# CONFIG_PATA_TRIFLEX is not set
++# CONFIG_PATA_MARVELL is not set
++# CONFIG_PATA_MPIIX is not set
++# CONFIG_PATA_OLDPIIX is not set
++# CONFIG_PATA_NETCELL is not set
++# CONFIG_PATA_NS87410 is not set
++# CONFIG_PATA_NS87415 is not set
++# CONFIG_PATA_OPTI is not set
++# CONFIG_PATA_OPTIDMA is not set
++# CONFIG_PATA_PDC_OLD is not set
++# CONFIG_PATA_RADISYS is not set
++# CONFIG_PATA_RZ1000 is not set
++# CONFIG_PATA_SC1200 is not set
++# CONFIG_PATA_SERVERWORKS is not set
++# CONFIG_PATA_PDC2027X is not set
++# CONFIG_PATA_SIL680 is not set
++# CONFIG_PATA_SIS is not set
++# CONFIG_PATA_VIA is not set
++# CONFIG_PATA_WINBOND is not set
++CONFIG_MD=y
++CONFIG_BLK_DEV_MD=y
++CONFIG_MD_LINEAR=y
++# CONFIG_MD_RAID0 is not set
++CONFIG_MD_RAID1=y
++# CONFIG_MD_RAID10 is not set
++# CONFIG_MD_RAID456 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_MD_FAULTY is not set
++CONFIG_BLK_DEV_DM=y
++# CONFIG_DM_DEBUG is not set
++# CONFIG_DM_CRYPT is not set
++# CONFIG_DM_SNAPSHOT is not set
++# CONFIG_DM_MIRROR is not set
++# CONFIG_DM_ZERO is not set
++# CONFIG_DM_MULTIPATH is not set
++# CONFIG_DM_DELAY is not set
++# CONFIG_DM_UEVENT is not set
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++# CONFIG_FIREWIRE is not set
++# CONFIG_IEEE1394 is not set
++# CONFIG_I2O 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=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# 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 is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_PCI=y
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++# CONFIG_SERIAL_JSM is not set
++CONFIG_UNIX98_PTYS=y
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=y
++# CONFIG_NVRAM is not set
++# CONFIG_R3964 is not set
++# CONFIG_APPLICOM is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_DEVPORT=y
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_CHARDEV is not set
++
++#
++# I2C Algorithms
++#
++CONFIG_I2C_ALGOBIT=y
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++# CONFIG_I2C_ALGOOXSEMI is not set
++
++#
++# I2C Hardware Bus support
++#
++# CONFIG_I2C_ALI1535 is not set
++# CONFIG_I2C_ALI1563 is not set
++# CONFIG_I2C_ALI15X3 is not set
++# CONFIG_I2C_AMD756 is not set
++# CONFIG_I2C_AMD8111 is not set
++# CONFIG_I2C_I801 is not set
++# CONFIG_I2C_I810 is not set
++# CONFIG_I2C_PIIX4 is not set
++# CONFIG_I2C_NFORCE2 is not set
++CONFIG_I2C_OXNAS_BITBASH=y
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_PROSAVAGE is not set
++# CONFIG_I2C_SAVAGE4 is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_SIS5595 is not set
++# CONFIG_I2C_SIS630 is not set
++# CONFIG_I2C_SIS96X is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_VIA is not set
++# CONFIG_I2C_VIAPRO is not set
++# CONFIG_I2C_VOODOO3 is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_SENSORS_DS1337 is not set
++# CONFIG_SENSORS_DS1374 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 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
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++CONFIG_DAB=y
++
++#
++# Graphics support
++#
++# CONFIG_DRM is not set
++# CONFIG_VGASTATE is not set
++CONFIG_VIDEO_OUTPUT_CONTROL=y
++# 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_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++# CONFIG_HID_SUPPORT is not set
++# CONFIG_USB_SUPPORT is not set
++# CONFIG_MMC is not set
++# CONFIG_NEW_LEDS 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=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_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
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_PL031 is not set
++# CONFIG_DMADEVICES is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=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_GFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_INOTIFY is not set
++# CONFIG_QUOTA is not set
++# CONFIG_DNOTIFY is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++# CONFIG_MSDOS_FS is not set
++# CONFIG_VFAT_FS is not set
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++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_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_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_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=y
++# 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=y
++# 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=y
++# CONFIG_INSTRUMENTATION is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++# CONFIG_ENABLE_MUST_CHECK is not set
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_SAMPLES is not set
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++# CONFIG_CRYPTO_ECB is not set
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++# CONFIG_CRYPTO_HW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_CRC_CCITT=y
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Nurd linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig
+--- linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_wd_eval_defconfig 2008-06-11 17:47:52.000000000 +0200
+@@ -0,0 +1,1096 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.24.4
++# Mon Jun 2 12:33:10 2008
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++# CONFIG_GENERIC_GPIO is not set
++# CONFIG_GENERIC_TIME is not set
++# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ZONE_DMA=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=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_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++# CONFIG_FAIR_GROUP_SCHED is not set
++# CONFIG_FAIR_USER_SCHED is not set
++# CONFIG_FAIR_CGROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# 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_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_SLOB is not set
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++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 is not set
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++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"
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++CONFIG_ARCH_OXNAS=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Oxford Semiconductor NAS Options
++#
++# CONFIG_ARCH_OXNAS_FPGA is not set
++CONFIG_NOMINAL_PLL400_FREQ=733333333
++CONFIG_NOMINAL_RPSCLK_FREQ=25000000
++# CONFIG_OXNAS_VERSION_0X800 is not set
++CONFIG_OXNAS_VERSION_0X810=y
++# CONFIG_OXNAS_VERSION_0X850 is not set
++# CONFIG_ARCH_OXNAS_UART1 is not set
++CONFIG_ARCH_OXNAS_UART2=y
++# CONFIG_ARCH_OXNAS_UART2_MODEM is not set
++# CONFIG_ARCH_OXNAS_UART3 is not set
++# CONFIG_ARCH_OXNAS_UART4 is not set
++CONFIG_FORCE_MAX_ZONEORDER=10
++CONFIG_SRAM_NUM_PAGES=32
++CONFIG_SUPPORT_LEON=y
++CONFIG_LEON_PAGES=2
++CONFIG_LEON_COPRO=y
++CONFIG_LEON_OFFLOAD_TX=y
++# CONFIG_LEON_RESERVE_DMA_CHANNEL is not set
++CONFIG_LEON_OFFLOAD_TSO=y
++# CONFIG_LEON_START_EARLY is not set
++CONFIG_LEON_POWER_BUTTON_MONITOR=m
++CONFIG_OXNAS_POWER_BUTTON_GPIO=4
++CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
++CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO=28
++# CONFIG_OXNAS_DDR_MON is not set
++# CONFIG_OXNAS_AHB_MON is not set
++# CONFIG_OXNAS_CACHE_LOCKDOWN is not set
++# CONFIG_DO_MEM_TEST is not set
++# CONFIG_CRYPTO_OXAESLRW is not set
++CONFIG_DESCRIPTORS_PAGES=6
++CONFIG_ARCH_OXNAS_NUM_GMAC_DESCRIPTORS=192
++CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES=256
++CONFIG_TACHO_THERM_AND_FAN=m
++# CONFIG_GPIO_TEST is not set
++CONFIG_OXNAS_RTC=m
++# CONFIG_I2S is not set
++# CONFIG_DPE_TEST is not set
++# CONFIG_OXNAS_INSTRUMENT_COPIES is not set
++# CONFIG_OXNAS_DMA_COPIES is not set
++# CONFIG_OXNAS_AHB_MONITOR_MODULE is not set
++# CONFIG_OXNAS_USB_TEST_MODES is not set
++# CONFIG_OXNAS_FRONT_LAMP_CONTROL is not set
++# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
++# CONFIG_OXNAS_LED_TEST is not set
++CONFIG_OXNAS_I2C_SDA=3
++CONFIG_OXNAS_I2C_SCL=2
++CONFIG_OXNAS_USB_PORTA_POWER_CONTROL=y
++# CONFIG_OXNAS_USB_PORTB_POWER_CONTROL is not set
++# CONFIG_OXNAS_USB_PORTC_POWER_CONTROL is not set
++CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE=y
++CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE=y
++# CONFIG_WDC_FAN_OXNAS800 is not set
++# CONFIG_OXNAS_MAP_SRAM is not set
++# CONFIG_OXNAS_SUID_INHERIT is not set
++# CONFIG_OXNAS_USB_HUB_SUPPORT is not set
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++# CONFIG_PCI is not set
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++# CONFIG_TICK_ONESHOT is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_NO_IDLE_HZ is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++# CONFIG_VFP is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_SUSPEND_UP_POSSIBLE=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++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_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++# CONFIG_IP_PNP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE 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=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IP_VS is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETLABEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++
++#
++# Core Netfilter Configuration
++#
++# CONFIG_NETFILTER_NETLINK is not set
++# CONFIG_NF_CONNTRACK_ENABLED is not set
++# CONFIG_NF_CONNTRACK is not set
++# CONFIG_NETFILTER_XTABLES is not set
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE 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_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++CONFIG_WIRELESS_EXT=y
++# CONFIG_MAC80211 is not set
++# CONFIG_IEEE80211 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=y
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++# CONFIG_MTD is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP 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=10240
++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MISC_DEVICES is not set
++# 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=y
++
++#
++# 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 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=y
++# 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=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_DEBUG is not set
++CONFIG_ATA=y
++# CONFIG_ATA_NONSTANDARD is not set
++CONFIG_SATA_OX810=y
++# CONFIG_SATA_OXNAS_SINGLE_SATA is not set
++# CONFIG_SATA_OXNAS_DISK_LIGHT is not set
++CONFIG_MD=y
++CONFIG_BLK_DEV_MD=y
++CONFIG_MD_LINEAR=y
++# CONFIG_MD_RAID0 is not set
++CONFIG_MD_RAID1=y
++# CONFIG_MD_RAID10 is not set
++# CONFIG_MD_RAID456 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_MD_FAULTY is not set
++CONFIG_BLK_DEV_DM=y
++# CONFIG_DM_DEBUG is not set
++CONFIG_DM_CRYPT=y
++# CONFIG_DM_SNAPSHOT is not set
++# CONFIG_DM_MIRROR is not set
++# CONFIG_DM_ZERO is not set
++# CONFIG_DM_MULTIPATH is not set
++# CONFIG_DM_DELAY is not set
++# CONFIG_DM_UEVENT is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# 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_NET_ETHERNET is not set
++CONFIG_MII=y
++CONFIG_NETDEV_1000=y
++CONFIG_SYNOPSYS_GMAC=y
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++
++#
++# 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_SHAPER 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
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# 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 is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_LEGACY_PTYS is not set
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=m
++# CONFIG_NVRAM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=m
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_CHARDEV is not set
++
++#
++# I2C Algorithms
++#
++CONFIG_I2C_ALGOBIT=m
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++# CONFIG_I2C_ALGOOXSEMI is not set
++
++#
++# I2C Hardware Bus support
++#
++CONFIG_I2C_OXNAS_BITBASH=m
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_SENSORS_DS1337 is not set
++# CONFIG_SENSORS_DS1374 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 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
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++CONFIG_DAB=y
++# CONFIG_USB_DABUSB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++CONFIG_VIDEO_OUTPUT_CONTROL=m
++# 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_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++# CONFIG_HID_SUPPORT is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++CONFIG_USB_EHCI_HCD=m
++# CONFIG_USB_EHCI_SPLIT_ISO is not set
++CONFIG_USB_EHCI_ROOT_HUB_TT=y
++# CONFIG_USB_EHCI_TT_NEWSCHED is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_OHCI_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=m
++# 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
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_MON is not set
++
++#
++# USB port drivers
++#
++
++#
++# USB Serial Converter support
++#
++# 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_AUERSWALD 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_PHIDGET 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=m
++
++#
++# USB DSL modem support
++#
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++# CONFIG_MMC is not set
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++
++#
++# LED drivers
++#
++CONFIG_WDC_LEDS_OXNAS800=m
++# CONFIG_OXNAS_WD810_LEDS is not set
++
++#
++# LED Triggers
++#
++CONFIG_LEDS_TRIGGERS=y
++# CONFIG_LEDS_TRIGGER_TIMER is not set
++CONFIG_WDC_LEDS_TRIGGER_SATA_DISK=y
++# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=m
++
++#
++# 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=m
++# 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
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_PL031 is not set
++# CONFIG_DMADEVICES is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_XFS_FS=y
++# CONFIG_XFS_QUOTA is not set
++# CONFIG_XFS_SECURITY is not set
++# CONFIG_XFS_POSIX_ACL is not set
++# CONFIG_XFS_RT is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++CONFIG_DNOTIFY=y
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++CONFIG_FUSE_FS=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=m
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=m
++# CONFIG_NTFS_DEBUG is not set
++# CONFIG_NTFS_RW is not set
++
++#
++# Pseudo filesystems
++#
++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_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++CONFIG_HFSPLUS_FS=m
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++# CONFIG_NFS_FS is not set
++CONFIG_NFSD=m
++CONFIG_NFSD_V2_ACL=y
++CONFIG_NFSD_V3=y
++CONFIG_NFSD_V3_ACL=y
++# CONFIG_NFSD_V4 is not set
++CONFIG_NFSD_TCP=y
++CONFIG_LOCKD=m
++CONFIG_LOCKD_V4=y
++CONFIG_EXPORTFS=m
++CONFIG_NFS_ACL_SUPPORT=m
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=m
++# CONFIG_SUNRPC_BIND34 is not set
++# 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=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++CONFIG_MAC_PARTITION=y
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++CONFIG_LDM_PARTITION=y
++# CONFIG_LDM_DEBUG is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++CONFIG_EFI_PARTITION=y
++# CONFIG_SYSV68_PARTITION is not set
++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 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=y
++# CONFIG_DLM is not set
++# CONFIG_INSTRUMENTATION is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_SAMPLES is not set
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++CONFIG_SECURITY=y
++# CONFIG_SECURITY_NETWORK is not set
++# CONFIG_SECURITY_CAPABILITIES is not set
++CONFIG_SECURITY_TRUSTEES=y
++# CONFIG_SECURITY_TRUSTEES_DEBUG is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=m
++CONFIG_CRYPTO_CBC=y
++CONFIG_CRYPTO_PCBC=m
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++CONFIG_CRYPTO_AES=m
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++CONFIG_CRYPTO_ARC4=m
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++CONFIG_CRYPTO_MICHAEL_MIC=m
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++CONFIG_CRYPTO_HW=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_CRC_CCITT=y
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Nurd linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig
+--- linux-2.6.24/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/configs/oxnas_810_eabi_wd_prod_defconfig 2008-06-11 17:47:52.000000000 +0200
+@@ -0,0 +1,1108 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.24.4
++# Thu Jun 5 16:08:07 2008
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++# CONFIG_GENERIC_GPIO is not set
++# CONFIG_GENERIC_TIME is not set
++# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_ZONE_DMA=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++CONFIG_LOCALVERSION_AUTO=y
++CONFIG_SWAP=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_USER_NS is not set
++# CONFIG_PID_NS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_CGROUPS is not set
++# CONFIG_FAIR_GROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++# CONFIG_RELAY is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
++CONFIG_SYSCTL=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++# 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_ANON_INODES=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLAB=y
++# CONFIG_SLUB is not set
++# CONFIG_SLOB is not set
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++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 is not set
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++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"
++
++#
++# System Type
++#
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_CO285 is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++CONFIG_ARCH_OXNAS=y
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++
++#
++# Oxford Semiconductor NAS Options
++#
++# CONFIG_ARCH_OXNAS_FPGA is not set
++CONFIG_NOMINAL_PLL400_FREQ=733333333
++CONFIG_NOMINAL_RPSCLK_FREQ=25000000
++# CONFIG_OXNAS_VERSION_0X800 is not set
++CONFIG_OXNAS_VERSION_0X810=y
++# CONFIG_OXNAS_VERSION_0X850 is not set
++# CONFIG_ARCH_OXNAS_UART1 is not set
++CONFIG_ARCH_OXNAS_UART2=y
++# CONFIG_ARCH_OXNAS_UART2_MODEM is not set
++# CONFIG_ARCH_OXNAS_UART3 is not set
++# CONFIG_ARCH_OXNAS_UART4 is not set
++CONFIG_OXNAS_SATA_POWER_1=y
++CONFIG_OXNAS_SATA_POWER_GPIO_1=31
++CONFIG_OXNAS_SATA_POWER_2=y
++CONFIG_OXNAS_SATA_POWER_GPIO_2=32
++CONFIG_FORCE_MAX_ZONEORDER=10
++CONFIG_SRAM_NUM_PAGES=32
++CONFIG_SUPPORT_LEON=y
++CONFIG_LEON_PAGES=2
++CONFIG_LEON_COPRO=y
++CONFIG_LEON_OFFLOAD_TX=y
++# CONFIG_LEON_RESERVE_DMA_CHANNEL is not set
++CONFIG_LEON_OFFLOAD_TSO=y
++# CONFIG_LEON_START_EARLY is not set
++CONFIG_LEON_POWER_BUTTON_MONITOR=m
++CONFIG_OXNAS_POWER_BUTTON_GPIO=0
++CONFIG_USER_RECOVERY_BUTTON_MONITOR=y
++CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO=4
++# CONFIG_OXNAS_DDR_MON is not set
++# CONFIG_OXNAS_AHB_MON is not set
++# CONFIG_OXNAS_CACHE_LOCKDOWN is not set
++# CONFIG_DO_MEM_TEST is not set
++# CONFIG_CRYPTO_OXAESLRW is not set
++CONFIG_DESCRIPTORS_PAGES=6
++CONFIG_ARCH_OXNAS_NUM_GMAC_DESCRIPTORS=192
++CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES=256
++CONFIG_TACHO_THERM_AND_FAN=m
++# CONFIG_GPIO_TEST is not set
++CONFIG_OXNAS_RTC=m
++# CONFIG_I2S is not set
++# CONFIG_DPE_TEST is not set
++# CONFIG_OXNAS_INSTRUMENT_COPIES is not set
++# CONFIG_OXNAS_DMA_COPIES is not set
++# CONFIG_OXNAS_AHB_MONITOR_MODULE is not set
++# CONFIG_OXNAS_USB_TEST_MODES is not set
++# CONFIG_OXNAS_FRONT_LAMP_CONTROL is not set
++# CONFIG_LEDS_TRIGGER_SATA_DISK is not set
++# CONFIG_OXNAS_LED_TEST is not set
++CONFIG_OXNAS_I2C_SDA=3
++CONFIG_OXNAS_I2C_SCL=2
++CONFIG_OXNAS_USB_PORTA_POWER_CONTROL=y
++# CONFIG_OXNAS_USB_PORTB_POWER_CONTROL is not set
++# CONFIG_OXNAS_USB_PORTC_POWER_CONTROL is not set
++CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE=y
++CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE=y
++# CONFIG_WDC_FAN_OXNAS800 is not set
++# CONFIG_OXNAS_MAP_SRAM is not set
++# CONFIG_OXNAS_SUID_INHERIT is not set
++CONFIG_OXNAS_USB_HUB_SUPPORT=y
++CONFIG_OXNAS_USB_CKOUT=y
++CONFIG_OXNAS_USB_HUB_RESET_CONTROL=y
++CONFIG_OXNAS_USB_HUB_RESET_GPIO=27
++CONFIG_OXNAS_USB_HUB_RESET_ACTIVE_HIGH=0
++CONFIG_OXNAS_USB_HUB_RESET_TOGGLE=y
++CONFIG_OXNAS_USB_HUB_RESET_PERIOD_MS=100
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++# CONFIG_PCI is not set
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++# CONFIG_TICK_ONESHOT is not set
++# CONFIG_PREEMPT is not set
++# CONFIG_NO_IDLE_HZ is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPARSEMEM_STATIC is not set
++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=1
++CONFIG_BOUNCE=y
++CONFIG_VIRT_TO_BUS=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++# CONFIG_FPE_NWFPE is not set
++# CONFIG_FPE_FASTFPE is not set
++# CONFIG_VFP is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_BINFMT_AOUT is not set
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Power management options
++#
++# CONFIG_PM is not set
++CONFIG_SUSPEND_UP_POSSIBLE=y
++
++#
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++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_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++# CONFIG_IP_PNP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE 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=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IP_VS is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETLABEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++
++#
++# Core Netfilter Configuration
++#
++# CONFIG_NETFILTER_NETLINK is not set
++# CONFIG_NF_CONNTRACK_ENABLED is not set
++# CONFIG_NF_CONNTRACK is not set
++# CONFIG_NETFILTER_XTABLES is not set
++
++#
++# IP: Netfilter Configuration
++#
++# CONFIG_IP_NF_QUEUE is not set
++# CONFIG_IP_NF_IPTABLES is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE 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_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++
++#
++# Wireless
++#
++# CONFIG_CFG80211 is not set
++CONFIG_WIRELESS_EXT=y
++# CONFIG_MAC80211 is not set
++# CONFIG_IEEE80211 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=y
++# CONFIG_SYS_HYPERVISOR is not set
++# CONFIG_CONNECTOR is not set
++# CONFIG_MTD is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP 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=10240
++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++# CONFIG_MISC_DEVICES is not set
++# 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=y
++
++#
++# 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 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=y
++# 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=y
++# CONFIG_ISCSI_TCP is not set
++# CONFIG_SCSI_DEBUG is not set
++CONFIG_ATA=y
++# CONFIG_ATA_NONSTANDARD is not set
++CONFIG_SATA_OX810=y
++# CONFIG_SATA_OXNAS_SINGLE_SATA is not set
++# CONFIG_SATA_OXNAS_DISK_LIGHT is not set
++CONFIG_MD=y
++CONFIG_BLK_DEV_MD=y
++CONFIG_MD_LINEAR=y
++CONFIG_MD_RAID0=y
++CONFIG_MD_RAID1=y
++# CONFIG_MD_RAID10 is not set
++# CONFIG_MD_RAID456 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_MD_FAULTY is not set
++CONFIG_BLK_DEV_DM=y
++# CONFIG_DM_DEBUG is not set
++CONFIG_DM_CRYPT=y
++# CONFIG_DM_SNAPSHOT is not set
++# CONFIG_DM_MIRROR is not set
++# CONFIG_DM_ZERO is not set
++# CONFIG_DM_MULTIPATH is not set
++# CONFIG_DM_DELAY is not set
++# CONFIG_DM_UEVENT is not set
++CONFIG_NETDEVICES=y
++# CONFIG_NETDEVICES_MULTIQUEUE is not set
++# 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_NET_ETHERNET is not set
++CONFIG_MII=y
++CONFIG_NETDEV_1000=y
++CONFIG_SYNOPSYS_GMAC=y
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++
++#
++# 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_SHAPER 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
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# 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 is not set
++
++#
++# Hardware I/O ports
++#
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++# CONFIG_SERIAL_NONSTANDARD is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_HW_RANDOM=m
++# CONFIG_NVRAM is not set
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=m
++CONFIG_I2C_BOARDINFO=y
++# CONFIG_I2C_CHARDEV is not set
++
++#
++# I2C Algorithms
++#
++CONFIG_I2C_ALGOBIT=m
++# CONFIG_I2C_ALGOPCF is not set
++# CONFIG_I2C_ALGOPCA is not set
++# CONFIG_I2C_ALGOOXSEMI is not set
++
++#
++# I2C Hardware Bus support
++#
++CONFIG_I2C_OXNAS_BITBASH=m
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_SIMTEC is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_SENSORS_DS1337 is not set
++# CONFIG_SENSORS_DS1374 is not set
++# CONFIG_DS1682 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 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
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++
++#
++# SPI support
++#
++# CONFIG_SPI is not set
++# CONFIG_SPI_MASTER is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_WATCHDOG is not set
++
++#
++# Sonics Silicon Backplane
++#
++CONFIG_SSB_POSSIBLE=y
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_SM501 is not set
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++CONFIG_DAB=y
++# CONFIG_USB_DABUSB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++CONFIG_VIDEO_OUTPUT_CONTROL=m
++# 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_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++# CONFIG_HID_SUPPORT is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_OTG is not set
++
++#
++# USB Host Controller Drivers
++#
++CONFIG_USB_EHCI_HCD=m
++# CONFIG_USB_EHCI_SPLIT_ISO is not set
++CONFIG_USB_EHCI_ROOT_HUB_TT=y
++# CONFIG_USB_EHCI_TT_NEWSCHED is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_OHCI_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
++#
++
++#
++# may also be needed; see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=m
++# 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
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++# CONFIG_USB_MON is not set
++
++#
++# USB port drivers
++#
++
++#
++# USB Serial Converter support
++#
++# 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_AUERSWALD 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_PHIDGET 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=m
++
++#
++# USB DSL modem support
++#
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++# CONFIG_MMC is not set
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++
++#
++# LED drivers
++#
++# CONFIG_WDC_LEDS_OXNAS800 is not set
++CONFIG_OXNAS_WD810_LEDS=m
++
++#
++# LED Triggers
++#
++CONFIG_LEDS_TRIGGERS=y
++# CONFIG_LEDS_TRIGGER_TIMER is not set
++CONFIG_WDC_LEDS_TRIGGER_SATA_DISK=y
++# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=m
++
++#
++# 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=m
++# 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
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_PL031 is not set
++# CONFIG_DMADEVICES is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++# CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
++CONFIG_EXT3_FS=y
++# CONFIG_EXT3_FS_XATTR is not set
++# CONFIG_EXT4DEV_FS is not set
++CONFIG_JBD=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_XFS_FS=y
++CONFIG_XFS_QUOTA=y
++# CONFIG_XFS_SECURITY is not set
++# CONFIG_XFS_POSIX_ACL is not set
++# CONFIG_XFS_RT is not set
++# CONFIG_GFS2_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS is not set
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++CONFIG_QUOTACTL=y
++CONFIG_DNOTIFY=y
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++CONFIG_FUSE_FS=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=m
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=m
++# CONFIG_NTFS_DEBUG is not set
++# CONFIG_NTFS_RW is not set
++
++#
++# Pseudo filesystems
++#
++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_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++CONFIG_HFSPLUS_FS=m
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++# CONFIG_NFS_FS is not set
++CONFIG_NFSD=m
++CONFIG_NFSD_V2_ACL=y
++CONFIG_NFSD_V3=y
++CONFIG_NFSD_V3_ACL=y
++# CONFIG_NFSD_V4 is not set
++CONFIG_NFSD_TCP=y
++CONFIG_LOCKD=m
++CONFIG_LOCKD_V4=y
++CONFIG_EXPORTFS=m
++CONFIG_NFS_ACL_SUPPORT=m
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=m
++# CONFIG_SUNRPC_BIND34 is not set
++# 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=y
++# CONFIG_ACORN_PARTITION is not set
++# CONFIG_OSF_PARTITION is not set
++# CONFIG_AMIGA_PARTITION is not set
++# CONFIG_ATARI_PARTITION is not set
++CONFIG_MAC_PARTITION=y
++CONFIG_MSDOS_PARTITION=y
++# CONFIG_BSD_DISKLABEL is not set
++# CONFIG_MINIX_SUBPARTITION is not set
++# CONFIG_SOLARIS_X86_PARTITION is not set
++# CONFIG_UNIXWARE_DISKLABEL is not set
++CONFIG_LDM_PARTITION=y
++# CONFIG_LDM_DEBUG is not set
++# CONFIG_SGI_PARTITION is not set
++# CONFIG_ULTRIX_PARTITION is not set
++# CONFIG_SUN_PARTITION is not set
++# CONFIG_KARMA_PARTITION is not set
++CONFIG_EFI_PARTITION=y
++# CONFIG_SYSV68_PARTITION is not set
++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 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=y
++# CONFIG_DLM is not set
++# CONFIG_INSTRUMENTATION is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++CONFIG_ENABLE_WARN_DEPRECATED=y
++CONFIG_ENABLE_MUST_CHECK=y
++# CONFIG_MAGIC_SYSRQ is not set
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_SAMPLES is not set
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++CONFIG_SECURITY=y
++# CONFIG_SECURITY_NETWORK is not set
++# CONFIG_SECURITY_CAPABILITIES is not set
++CONFIG_SECURITY_TRUSTEES=y
++# CONFIG_SECURITY_TRUSTEES_DEBUG is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_MANAGER=y
++# CONFIG_CRYPTO_HMAC is not set
++# CONFIG_CRYPTO_XCBC is not set
++# CONFIG_CRYPTO_NULL is not set
++# CONFIG_CRYPTO_MD4 is not set
++# CONFIG_CRYPTO_MD5 is not set
++# CONFIG_CRYPTO_SHA1 is not set
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_WP512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_ECB=m
++CONFIG_CRYPTO_CBC=y
++CONFIG_CRYPTO_PCBC=m
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_XTS is not set
++# CONFIG_CRYPTO_CRYPTD is not set
++# CONFIG_CRYPTO_DES is not set
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++# CONFIG_CRYPTO_SERPENT is not set
++CONFIG_CRYPTO_AES=m
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++# CONFIG_CRYPTO_TEA is not set
++CONFIG_CRYPTO_ARC4=m
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_DEFLATE is not set
++CONFIG_CRYPTO_MICHAEL_MIC=m
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_TEST is not set
++# CONFIG_CRYPTO_AUTHENC is not set
++CONFIG_CRYPTO_HW=y
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++CONFIG_CRC_CCITT=y
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_ITU_T is not set
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff -Nurd linux-2.6.24/arch/arm/kernel/armksyms.c linux-2.6.24-oxe810/arch/arm/kernel/armksyms.c
+--- linux-2.6.24/arch/arm/kernel/armksyms.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/kernel/armksyms.c 2008-06-11 17:47:43.000000000 +0200
+@@ -114,9 +114,15 @@
+ EXPORT_SYMBOL(__strncpy_from_user);
+
+ #ifdef CONFIG_MMU
++#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
++EXPORT_SYMBOL(__copy_from_user_alt);
++EXPORT_SYMBOL(__copy_to_user_alt);
++EXPORT_SYMBOL(__clear_user_alt);
++#else // CONFIG_OXNAS_INSTRUMENT_COPIES
+ EXPORT_SYMBOL(__copy_from_user);
+ EXPORT_SYMBOL(__copy_to_user);
+ EXPORT_SYMBOL(__clear_user);
++#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
+
+ EXPORT_SYMBOL(__get_user_1);
+ EXPORT_SYMBOL(__get_user_2);
+diff -Nurd linux-2.6.24/arch/arm/kernel/bios32.c linux-2.6.24-oxe810/arch/arm/kernel/bios32.c
+--- linux-2.6.24/arch/arm/kernel/bios32.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/kernel/bios32.c 2008-06-11 17:47:43.000000000 +0200
+@@ -616,7 +616,7 @@
+ }
+ }
+
+-char * __init pcibios_setup(char *str)
++char * __devinit pcibios_setup(char *str)
+ {
+ if (!strcmp(str, "debug")) {
+ debug_pci = 1;
+diff -Nurd linux-2.6.24/arch/arm/kernel/calls.S linux-2.6.24-oxe810/arch/arm/kernel/calls.S
+--- linux-2.6.24/arch/arm/kernel/calls.S 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/kernel/calls.S 2008-06-11 17:47:43.000000000 +0200
+@@ -362,6 +362,7 @@
+ /* 350 */ CALL(sys_timerfd)
+ CALL(sys_eventfd)
+ CALL(sys_fallocate)
++ CALL(sys_samba_reserve)
+ #ifndef syscalls_counted
+ .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
+ #define syscalls_counted
+diff -Nurd linux-2.6.24/arch/arm/kernel/head.S linux-2.6.24-oxe810/arch/arm/kernel/head.S
+--- linux-2.6.24/arch/arm/kernel/head.S 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/kernel/head.S 2008-06-11 17:47:43.000000000 +0200
+@@ -59,6 +59,34 @@
+ #define KERNEL_END _end
+ #endif
+
++#ifdef CONFIG_OXNAS_MAP_SRAM
++ .macro course_pgtbl, rd
++ ldr \rd, =(__virt_to_phys(KERNEL_RAM_ADDR - 0x4400))
++ .endm
++
++ .globl SMALL_AP
++ .equ SMALL_AP, 0xAA
++
++ .globl COURSE_DOMAIN
++ .equ COURSE_DOMAIN, 0x04
++
++ .globl SRAM_CODE_START
++ .globl CODE_COPY_LEN
++
++#ifdef CONFIG_SUPPORT_LEON
++ /*
++ * Allow 2 pages after GMAC/DMA descriptors for ARM/Leon TSO workspace
++ * May have to change if Leon code is built to use more Tx descriptors, but
++ * current 2 pages is easily enough for 54 descriptors
++ */
++ .equ SRAM_CODE_START, SRAM_PA+((CONFIG_DESCRIPTORS_PAGES+2)*4096)
++ .equ CODE_COPY_LEN, ((CONFIG_SRAM_NUM_PAGES-CONFIG_LEON_PAGES-(CONFIG_DESCRIPTORS_PAGES+2))*4096)
++#else // CONFIG_SUPPORT_LEON
++ .equ SRAM_CODE_START, SRAM_PA+(CONFIG_DESCRIPTORS_PAGES*4096)
++ .equ CODE_COPY_LEN, ((CONFIG_SRAM_NUM_PAGES-CONFIG_DESCRIPTORS_PAGES)*4096)
++#endif // CONFIG_SUPPORT_LEON
++#endif // CONFIG_OXNAS_MAP_SRAM
++
+ /*
+ * Kernel startup entry point.
+ * ---------------------------
+@@ -82,6 +110,27 @@
+ ENTRY(stext)
+ msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
+ @ and irqs disabled
++
++#ifdef CONFIG_OXNAS_CACHE_LOCKDOWN
++ /*
++ * Lock down ICache - do not care what ends up in locked down ways -
++ * eventually context switch etc will flush out anything that gets loaded
++ * next
++ */
++ mrc p15,0,r2,c9,c0,1
++ orr r2,r2,#CONFIG_OXNAS_CACHE_I_MASK
++ mcr p15,0,r2,c9,c0,1
++
++ /*
++ * Lock down DCache - do not care what ends up in locked down ways -
++ * eventually context switch etc will flush out anything that gets loaded
++ * next
++ */
++ mrc p15,0,r2,c9,c0,0
++ orr r2,r2,#CONFIG_OXNAS_CACHE_D_MASK
++ mcr p15,0,r2,c9,c0,0
++#endif // CONFIG_OXNAS_CACHE_LOCKDOWN
++
+ mrc p15, 0, r9, c0, c0 @ get processor id
+ bl __lookup_processor_type @ r5=procinfo r9=cpuid
+ movs r10, r5 @ invalid processor (r5=0)?
+@@ -231,7 +280,33 @@
+ teq r0, r6
+ bne 1b
+
+- ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags
++ ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mmuflags
++
++#ifdef CONFIG_OXNAS_MAP_SRAM
++ /*
++ * Create the contents of the first descriptor in the course table which
++ * is to describe the first MB of the kernel with 256 4K small descriptors.
++ * The descriptors' are composed of the top 20 bits of the physical
++ * address plus the appropriate AP, cacheable and bufferable flags
++ */
++ mov r3, #PHYS_OFFSET
++ mov r3, r3, lsr #12
++ mov r3, r3, lsl #12
++ mov r6, #SMALL_AP @ TBC: AP values
++ orr r3, r3, r6, lsl #4
++ orr r3, r3, #0xe @ Cachable, bufferable and small desc
++
++ /*
++ * Fill all 256 entries in the course page table with descriptors for
++ * contiguous pages
++ */
++ course_pgtbl r0
++ add r6, r0, #0x0400
++1: str r3, [r0], #4
++ add r3, r3, #1 << 12
++ teq r0, r6
++ bne 1b
++#endif // CONFIG_OXNAS_MAP_SRAM
+
+ /*
+ * Create identity mapping for first MB of kernel to
+@@ -243,12 +318,26 @@
+ orr r3, r7, r6, lsl #20 @ flags + kernel base
+ str r3, [r4, r6, lsl #2] @ identity mapping
+
++#ifdef CONFIG_OXNAS_MAP_SRAM
++ /*
++ * Write a course descriptor pointing to the small page mapping table
++ * setup to map the first MB of kernel with 4K small pages
++ */
++ course_pgtbl r6
++ mov r0, #COURSE_DOMAIN @ TBC SBZ, Domain etc
++ orr r6, r6, r0, lsl #2
++ orr r6, r6, #1 @ Course descriptor identifier
++
++ add r0, r4, #(KERNEL_START & 0xff000000) >> 18
++ str r6, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
++#else // CONFIG_OXNAS_MAP_SRAM
+ /*
+ * Now setup the pagetables for our kernel direct
+ * mapped region.
+ */
+ add r0, r4, #(KERNEL_START & 0xff000000) >> 18
+ str r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
++#endif // CONFIG_OXNAS_MAP_SRAM
+ ldr r6, =(KERNEL_END - 1)
+ add r0, r0, #4
+ add r6, r4, r6, lsr #18
+@@ -276,6 +365,64 @@
+ bls 1b
+ #endif
+
++#ifdef CONFIG_OXNAS_COPY_CODE_TO_SRAM
++ /*
++ * Copy smallest/most-used kernel code into SRAM
++ */
++
++ /* Get start of kernel code to copy */
++ ldr r0, =(_text)
++ mvn r3, #0xff000000
++ and r0, r0, r3
++ mov r6, #PHYS_OFFSET
++ mov r3, #0xff000000
++ and r6, r6, r3
++ orr r0, r0, r6
++
++ /* Get start of SRAM region to copy into */
++ ldr r3, =(SRAM_CODE_START)
++
++ /* Get amount of code to copy */
++ ldr r6, =(CODE_COPY_LEN)
++
++ /* NB r7 is corrupted here, but opt. debug code below needs it */
++ add r6, r0, r6
++1: ldr r7, [r0], #4
++ str r7, [r3], #4
++ teq r0, r6
++ bne 1b
++
++ /*
++ * Map SRAM resident code into kernel virtual address space by altering
++ * course page table entries covering the smallest/most-used code
++ */
++
++ /* Get the address of the first page table entry to modify */
++ course_pgtbl r3
++ ldr r0, =(_text)
++ sub r0, r0, #PAGE_OFFSET
++ add r3, r3, r0, lsr #10
++
++ /* Get the address after the last entry in the page table to be altered */
++ ldr r6, =(CODE_COPY_LEN)
++ add r6, r3, r6, lsr #10
++
++ /* Form the first small descriptor contents */
++ ldr r0, =(SRAM_CODE_START)
++ mov r0, r0, lsr #12
++ mov r0, r0, lsl #12
++ mov r7, #SMALL_AP
++ orr r0, r0, r7, lsl #4
++ orr r0, r0, #0xe
++
++ /* Modify the page table entries for all SRAM pages filled with code */
++1: str r0, [r3], #4
++ add r0, r0, #1 << 12
++ teq r3, r6
++ bne 1b
++
++#else // CONFIG_OXNAS_COPY_CODE_TO_SRAM
++#ifndef CONFIG_ARCH_OXNAS
+ /*
+ * Then map first 1MB of ram in case it contains our boot params.
+ */
+@@ -285,6 +432,8 @@
+ orr r6, r6, #(PHYS_OFFSET & 0x00f00000)
+ .endif
+ str r6, [r0]
++#endif // !CONFIG_ARCH_OXNAS
++#endif // CONFIG_OXNAS_COPY_CODE_TO_SRAM
+
+ #ifdef CONFIG_DEBUG_LL
+ ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
+diff -Nurd linux-2.6.24/arch/arm/kernel/process.c linux-2.6.24-oxe810/arch/arm/kernel/process.c
+--- linux-2.6.24/arch/arm/kernel/process.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/kernel/process.c 2008-06-11 17:47:43.000000000 +0200
+@@ -117,7 +117,7 @@
+ void (*pm_idle)(void);
+ EXPORT_SYMBOL(pm_idle);
+
+-void (*pm_power_off)(void);
++void (*pm_power_off)(void) = arch_poweroff;
+ EXPORT_SYMBOL(pm_power_off);
+
+ void (*arm_pm_restart)(char str) = arm_machine_restart;
+diff -Nurd linux-2.6.24/arch/arm/kernel/vmlinux.lds.S linux-2.6.24-oxe810/arch/arm/kernel/vmlinux.lds.S
+--- linux-2.6.24/arch/arm/kernel/vmlinux.lds.S 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/kernel/vmlinux.lds.S 2008-06-11 17:47:43.000000000 +0200
+@@ -86,8 +86,659 @@
+ #endif
+ }
+
+- .text : { /* Real text segment */
+- _text = .; /* Text and read-only data */
++ .text : { /* Real text segment */
++ _text = .; /* Text and read-only data */
++ *(.text.arm926_dma_clean_range)
++ *(.text.arm926_dma_inv_range)
++ *(.text.arm926_dma_flush_range)
++ *(.text.__irq_svc)
++ *(.text.__arch_copy_to_user)
++ *(.text.__arch_copy_from_user)
++ *(.text.__kmalloc)
++ *(.text.OXNAS_unmask_irq)
++ *(.text.local_bh_enable)
++ *(.text.do_level_IRQ)
++ *(.text.__memzero)
++ *(.text.irq_exit)
++ *(.text.__do_irq)
++ *(.text.pfifo_fast_dequeue)
++ *(.text.preempt_return)
++ *(.text.cpu_arm926_switch_mm)
++ *(.text.check_irq_lock)
++ *(.text.tcp_init_tso_segs)
++ *(.text.kfree_skbmem)
++ *(.text.consistent_sync)
++ *(.text.__alloc_skb)
++ *(.text.skb_release_data)
++ *(.text.OXNAS_mask_irq)
++ *(.text.Ldiv0)
++ *(.text.__do_softirq)
++ *(.text.kmem_cache_free)
++ *(.text.__kfree_skb)
++ *(.text.kmem_cache_alloc)
++ *(.text.radix_tree_lookup)
++ *(.text.kfree)
++ *(.text.asm_do_IRQ)
++ *(.text.skb_clone)
++ *(.text.qdisc_restart)
++ *(.text.sock_wfree)
++ *(.text.unlock_page)
++ *(.text.tcp_cwnd_validate)
++ *(.text.free_hot_cold_page)
++ *(.text.memcpy)
++ *(.text.velocity_free_tx_buf)
++ *(.text.wake_up_bit)
++ *(.text.cond_resched)
++ *(.text.pfifo_fast_enqueue)
++ *(.text.raise_softirq_irqoff)
++ *(.text.tcp_push_one)
++ *(.text.__modsi3)
++ *(.text.update_send_head)
++ *(.text.tcp_set_skb_tso_segs)
++ *(.text.tcp_snd_test)
++ *(.text.svc_preempt)
++ *(.text.__tcp_select_window)
++ *(.text.dev_queue_xmit)
++ *(.text.oxnas_gettimeoffset)
++ *(.text.__wake_up_bit)
++ *(.text.mod_timer)
++ *(.text.do_simple_IRQ)
++ *(.text.velocity_xmit)
++ *(.text.ip_output)
++ *(.text.net_tx_action)
++ *(.text.ip_queue_xmit)
++ *(.text.tcp_cong_avoid)
++ *(.text.sk_reset_timer)
++ *(.text.velocity_intr)
++ *(.text.pci_dma_sync_single_for_device)
++ *(.text.process_backlog)
++ *(.text.tcp_v4_send_check)
++ *(.text.tcp_transmit_skb)
++ *(.text.file_send_actor)
++ *(.text.tcp_current_mss)
++ *(.text.__netif_rx_schedule)
++ *(.text.__muldi3)
++ *(.text.release_sock)
++ *(.text.do_softirq)
++ *(.text.pfifo_fast_reset)
++ *(.text.netif_rx)
++ *(.text.kernel_sendmsg)
++ *(.text.rt_hash_code)
++ *(.text.mod_page_state_offset)
++ *(.text.preempt_schedule)
++ *(.text.inet_sendmsg)
++ *(.text.page_waitqueue)
++ *(.text.bictcp_acked)
++ *(.text.__sk_dst_check)
++ *(.text.blk_rq_map_sg)
++ *(.text.tcp_mtu_to_mss)
++ *(.text.__delay)
++ *(.text.sock_sendmsg)
++ *(.text.sock_sendpage)
++ *(.text.ip_local_deliver)
++ *(.text.bio_add_page)
++ *(.text.tcp_sendmsg)
++ *(.text.sock_no_sendpage)
++ *(.text.__remove_from_page_cache)
++ *(.text.net_rx_action)
++ *(.text.eth_type_trans)
++ *(.text.find_get_page)
++ *(.text.netif_receive_skb)
++ *(.text.verify_chain)
++ *(.text.radix_tree_delete)
++ *(.text.mpage_readpages)
++ *(.text.velocity_rx_refill)
++ *(.text.mpage_end_io_read)
++ *(.text.radix_tree_insert)
++ *(.text.ip_rcv)
++ *(.text.register_gifconf)
++ *(.text.dma_mmap)
++ *(.text.tcp_rtt_estimator)
++ *(.text.ox800sata_get_bbp_base)
++ *(.text.mark_page_accessed)
++ *(.text.update_process_times)
++ *(.text.__pagevec_free)
++ *(.text.read_page_state_offset)
++ *(.text.__bio_add_page)
++ *(.text.__pagevec_lru_add)
++ *(.text.ox800sata_scr_read)
++ *(.text.bio_add_pc_page)
++ *(.text.__rcu_pending)
++ *(.text.free_sg_entry)
++ *(.text.put_page)
++ *(.text.lock_timer_base)
++ *(.text.radix_tree_tagged)
++ *(.text.__lshrdi3)
++ *(.text.lock_sock)
++ *(.text.__udivsi3)
++ *(.text.zone_watermark_ok)
++ *(.text.klist_children_put)
++ *(.text.sock_aio_dtor)
++ *(.text.ata_qc_prep)
++ *(.text.oxnas_dma_free)
++ *(.text.rcu_pending)
++ *(.text.free_cold_page)
++ *(.text.get_page_from_freelist)
++ *(.text.alloc_sg_entry)
++ *(.text.ret_fast_syscall)
++ *(.text.add_to_page_cache)
++ *(.text.__mod_timer)
++ *(.text.velocity_free_td_ring)
++ *(.text.__do_div64)
++ *(.text.remove_mapping)
++ *(.text.fast_work_pending)
++ *(.text.cond_resched_softirq)
++ *(.text.tcp_v4_rcv)
++ *(.text.kernel_recvmsg)
++ *(.text.isolate_lru_pages)
++ *(.text.klist_children_get)
++ *(.text.sys_getpid)
++ *(.text.mempool_free_slab)
++ *(.text.kobject_get)
++ *(.text.__tcp_push_pending_frames)
++ *(.text.sk_stop_timer)
++ *(.text.bictcp_state)
++ *(.text.tcp_check_space)
++ *(.text.kmem_cache_zalloc)
++ *(.text.get_device)
++ *(.text.work_pending)
++ *(.text.tcp_ack)
++ *(.text.do_edge_IRQ)
++ *(.text.page_referenced)
++ *(.text.profile_tick)
++ *(.text.ox800sata_get_link_base)
++ *(.text.__pagevec_release_nonlru)
++ *(.text.blk_recount_segments)
++ *(.text.__mod_page_state_offset)
++ *(.text.linear_mergeable_bvec)
++ *(.text.recalc_task_prio)
++ *(.text.mempool_kmalloc)
++ *(.text.do_mpage_readpage)
++ *(.text.ksoftirqd)
++ *(.text.__generic_unplug_device)
++ *(.text.rt_cpu_seq_start)
++ *(.text.bio_alloc)
++ *(.text.tasklet_action)
++ *(.text.effective_prio)
++ *(.text.OXNAS_timer_interrupt)
++ *(.text.__wake_up_common)
++ *(.text.free_poll_entry)
++ *(.text.vector_swi)
++ *(.text.do_sock_read)
++ *(.text.alloc_sg_controller)
++ *(.text.tcp_rcv_established)
++ *(.text.oxnas_dma_set_callback)
++ *(.text.run_local_timers)
++ *(.text.sock_rmalloc)
++ *(.text.__rmqueue)
++ *(.text.ox800sata_bmdma_start)
++ *(.text.fget_light)
++ *(.text.queue_work)
++ *(.text.mempool_alloc_slab)
++ *(.text.__wake_up)
++ *(.text.default_idle)
++ *(.text.fput)
++ *(.text.add_wait_queue)
++ *(.text.memcpy_toiovec)
++ *(.text.rw_verify_area)
++ *(.text.internal_add_timer)
++ *(.text.hrtimer_run_queues)
++ *(.text.tcp_v4_do_rcv)
++ *(.text.raise_softirq)
++ *(.text.del_timer)
++ *(.text.try_to_wake_up)
++ *(.text.__do_page_cache_readahead)
++ *(.text.__alloc_pages)
++ *(.text.sock_aio_read)
++ *(.text.timer_tick)
++ *(.text.ox800sata_check_status)
++ *(.text.do_generic_mapping_read)
++ *(.text.__ox800sata_scr_read)
++ *(.text.elv_queue_empty)
++ *(.text.do_select)
++ *(.text.free_pages_bulk)
++ *(.text.remove_wait_queue)
++ *(.text.dma_bh)
++ *(.text.__irq_usr)
++ *(.text.vfs_read)
++ *(.text.run_timer_softirq)
++ *(.text.radix_tree_preload)
++ *(.text.ptrace_getrn)
++ *(.text.tcp_dsack_set)
++ *(.text.__switch_to)
++ *(.text.bio_hw_segments)
++ *(.text.__const_udelay)
++ *(.text.nr_running)
++ *(.text.oxnas_dma_device_set_prd)
++ *(.text.kref_put)
++ *(.text.enqueue_task)
++ *(.text.dequeue_task)
++ *(.text.elv_next_request)
++ *(.text.profile_hit)
++ *(.text.slab_destroy)
++ *(.text.schedule)
++ *(.text.end_that_request_first)
++ *(.text.cfq_find_next_crq)
++ *(.text.__freed_request)
++ *(.text.adjtime_adjustment)
++ *(.text.bictcp_cong_avoid)
++ *(.text.kthread_should_stop)
++ *(.text.__activate_task)
++ *(.text.account_system_time)
++ *(.text.bio_fs_destructor)
++ *(.text.mempool_alloc)
++ *(.text.elv_set_request)
++ *(.text.schedule_work)
++ *(.text.wake_up_state)
++ *(.text.encode_control_status)
++ *(.text.alloc_skb_from_cache)
++ *(.text.qdisc_lock_tree)
++ *(.text.kref_get)
++ *(.text.init_timer)
++ *(.text.oxnas_dma_is_active)
++ *(.text.shrink_slab)
++ *(.text.poll_freewait)
++ *(.text.sys_fstat64)
++ *(.text.__pollwait)
++ *(.text.cfq_queue_empty)
++ *(.text.linear_issue_flush)
++ *(.text.__tasklet_schedule)
++ *(.text.ox800sata_get_io_base)
++ *(.text.deactivate_task)
++ *(.text.cleanup_rbuf)
++ *(.text.nr_free_zone_pages)
++ *(.text.ip_route_input)
++ *(.text.__lock_page)
++ *(.text.sock_poll)
++ *(.text.__pskb_trim_head)
++ *(.text.sys_read)
++ *(.text.__arch_copy_to_user)
++ *(.text.generic_make_request)
++ *(.text.scsi_end_request)
++ *(.text.bio_init)
++ *(.text.pipefs_delete_dentry)
++ *(.text.ox800sata_post_set_mode)
++ *(.text.sock_common_recvmsg)
++ *(.text.put_device)
++ *(.text.tcp_syn_build_options)
++ *(.text.scheduler_tick)
++ *(.text.__sys_trace)
++ *(.text.ox800sata_qc_new)
++ *(.text.elv_latter_request)
++ *(.text.do_sync_read)
++ *(.text.ox800sata_spot_the_end)
++ *(.text.get_dirty_limits)
++ *(.text.bio_phys_segments)
++ *(.text.vfs_fstat)
++ *(.text.scsi_finish_command)
++ *(.text.wake_up_process)
++ *(.text.wdc_ledtrig_sata_activity)
++ *(.text.__elv_add_request)
++ *(.text.sock_common_setsockopt)
++ *(.text.elv_may_queue)
++ *(.text.rb_first)
++ *(.text.dnotify_parent)
++ *(.text.get_writeback_state)
++ *(.text.__blk_put_request)
++ *(.text.sock_mmap)
++ *(.text.throttle_vm_writeout)
++ *(.text.drive_stat_acct)
++ *(.text.dlci_ioctl_set)
++ *(.text.sys_send)
++ *(.text.default_wake_function)
++ *(.text.cfq_resort_rr_list)
++ *(.text.bio_put)
++ *(.text.scsi_done)
++ *(.text.kobject_put)
++ *(.text.release_pages)
++ *(.text.ata_qc_issue)
++ *(.text.cfq_dispatch_insert)
++ *(.text.run_workqueue)
++ *(.text.delayed_work_timer_fn)
++ *(.text.scsi_init_cmd_errh)
++ *(.text.alloc_sock_iocb)
++ *(.text.blk_done_softirq)
++ *(.text.do_timer)
++ *(.text.scsi_10_lba_len)
++ *(.text.scsi_device_unbusy)
++ *(.text.bio_get_nr_vecs)
++ *(.text.cfq_find_cfq_hash)
++ *(.text.ata_dev_select)
++ *(.text.blk_remove_plug)
++ *(.text.end_that_request_last)
++ *(.text.shrink_dcache_memory)
++ *(.text.elv_put_request)
++ *(.text.sys_sendto)
++ *(.text.scsi_put_command)
++ *(.text._clear_bit_le)
++ *(.text.ata_rwcmd_protocol)
++ *(.text.kobject_cleanup)
++ *(.text.do_sendfile)
++ *(.text.worker_thread)
++ *(.text.elv_dispatch_sort)
++ *(.text.tcp_fast_parse_options)
++ *(.text.ox800sata_irq_on)
++ *(.text.scsi_request_fn)
++ *(.text.ox800sata_irq_handler)
++ *(.text.nr_context_switches)
++ *(.text.oxnas_dma_request)
++ *(.text.sys_sendfile64)
++ *(.text.cfq_add_crq_rb)
++ *(.text.ata_scsi_queuecmd)
++ *(.text.sock_def_readable)
++ *(.text.inet_sendpage)
++ *(.text.cfq_set_request)
++ *(.text.init_request_from_bio)
++ *(.text.tcp_v4_conn_request)
++ *(.text.requeue_task)
++ *(.text.cache_alloc_refill)
++ *(.text.scsi_get_command)
++ *(.text.blk_complete_request)
++ *(.text.scsi_add_timer)
++ *(.text.sk_stream_rfree)
++ *(.text.__umodsi3)
++ *(.text.ox800sata_tf_load)
++ *(.text.tcp_recvmsg)
++ *(.text.cfq_insert_request)
++ *(.text.tcp_sendpage)
++ *(.text.bio_alloc_bioset)
++ *(.text.__tcp_ack_snd_check)
++ *(.text.kthread_bind)
++ *(.text.scsi_delete_timer)
++ *(.text.ox800sata_dev_config)
++ *(.text.add_wait_queue_exclusive)
++ *(.text.ox800sata_bmdma_setup)
++ *(.text.ox800sata_exec_command)
++ *(.text.clear_queue_congested)
++ *(.text.generic_file_sendfile)
++ *(.text.get_io_context)
++ *(.text.swap_buf_le16)
++ *(.text._set_bit_be)
++ *(.text.led_trigger_event)
++ *(.text.current_io_context)
++ *(.text.bio_free)
++ *(.text.pipe_poll)
++ *(.text.freed_request)
++ *(.text.cfq_choose_req)
++ *(.text.ox800sata_RAID_faults)
++ *(.text.rb_prev)
++ *(.text.blk_run_queue)
++ *(.text.mpage_alloc)
++ *(.text.__get_zone_counts)
++ *(.text.mpage_bio_submit)
++ *(.text.generic_fillattr)
++ *(.text.kswapd)
++ *(.text.preempt_schedule_irq)
++ *(.text.mempool_free)
++ *(.text.elv_dequeue_request)
++ *(.text.add_interrupt_randomness)
++ *(.text.poll_initwait)
++ *(.text.__put_user_bad)
++ *(.text.vfs_getattr)
++ *(.text.scsi_free_sgtable)
++ *(.text.laptop_sync_completion)
++ *(.text.submit_bio)
++ *(.text.sock_from_file)
++ *(.text.add_disk_randomness)
++ *(.text.scsi_kill_request)
++ *(.text.free_hot_page)
++ *(.text.bio_endio)
++ *(.text.scsi_dispatch_cmd)
++ *(.text.oxnas_dma_start)
++ *(.text.cfq_remove_request)
++ *(.text.do_gettimeofday)
++ *(.text.skb_copy_datagram_iovec)
++ *(.text.ext3_get_blocks_handle)
++ *(.text.__down_read_trylock)
++ *(.text.cfq_activate_request)
++ *(.text.recalc_sigpending)
++ *(.text.ext3_readpage)
++ *(.text.ox800sata_dev_select)
++ *(.text.ret_to_user)
++ *(.text.elv_completed_request)
++ *(.text.read_cache_page)
++ *(.text.touch_atime)
++ *(.text.cfq_update_next_crq)
++ *(.text.no_work_pending)
++ *(.text.recalc_sigpending_tsk)
++ *(.text.end_that_request_chunk)
++ *(.text.cp_new_stat64)
++ *(.text.rb_next)
++ *(.text.__wake_up_sync)
++ *(.text.subsys_create_file)
++ *(.text.rcu_needs_cpu)
++ *(.text.sys_select)
++ *(.text.oxnas_dma_device_set)
++ *(.text.ata_sg_init)
++ *(.text.__put_user_8)
++ *(.text.ox800sata_port_disable)
++ *(.text.scsi_next_command)
++ *(.text.__scsi_done)
++ *(.text.ata_scsi_qc_complete)
++ *(.text.__wake_up_locked)
++ *(.text.lru_add_drain)
++ *(.text.bio_check_pages_dirty)
++ *(.text.cascade)
++ *(.text.tcp_poll)
++ *(.text.oxnas_dma_set_common)
++ *(.text.__pagevec_release)
++ *(.text.ata_scsi_translate)
++ *(.text.oxnas_dma_interrupt)
++ *(.text.sys_newfstat)
++ *(.text.tcp_send_delayed_ack)
++ *(.text.scsi_decide_disposition)
++ *(.text.ox800sata_qc_free)
++ *(.text.scsi_softirq_done)
++ *(.text.netlink_group_mask)
++ *(.text.__brelse)
++ *(.text.do_sock_write)
++ *(.text.mempool_create_node)
++ *(.text.ox800sata_qc_issue)
++ *(.text.__scsi_release_request)
++ *(.text.blockable_page_cache_readahead)
++ *(.text.get_index)
++ *(.text.walk_page_buffers)
++ *(.text.__queue_work)
++ *(.text.ret_from_fork)
++ *(.text.mb_cache_shrink_fn)
++ *(.text.sys_socketcall)
++ *(.text.blk_congestion_wait)
++ *(.text.put_io_context)
++ *(.text.elevator_find)
++ *(.text._set_bit_le)
++ *(.text.generic_write_checks)
++ *(.text.datagram_poll)
++ *(.text.ext3_block_to_path)
++ *(.text.scsi_prep_fn)
++ *(.text.fget)
++ *(.text.blk_plug_device)
++ *(.text.disk_round_stats)
++ *(.text.get_request)
++ *(.text.page_cache_readahead)
++ *(.text.__bread)
++ *(.text.tcp_rcv_space_adjust)
++ *(.text.ox800sata_tf_read)
++ *(.text.add_timer_randomness)
++ *(.text.sockfd_lookup_light)
++ *(.text.__find_get_block)
++ *(.text.split_page)
++ *(.text.cfq_dispatch_requests)
++ *(.text.cfq_kick_queue)
++ *(.text.cfq_may_queue)
++ *(.text.cfq_put_request)
++ *(.text.get_request_wait)
++ *(.text.default_callback)
++ *(.text.cpu_arm926_set_pte)
++ *(.text.tcp_event_data_recv)
++ *(.text.ata_scsi_qc_new)
++ *(.text.SetRoundingMode)
++ *(.text.make_ahead_window)
++ *(.text.inotify_inode_queue_event)
++ *(.text.__make_request)
++ *(.text.finish_wait)
++ *(.text.cfq_completed_request)
++ *(.text.__cfq_slice_expired)
++ *(.text.sd_init_command)
++ *(.text.find_lock_page)
++ *(.text.pipefs_get_sb)
++ *(.text.ata_qc_new_init)
++ *(.text.task_timeslice)
++ *(.text.sk_dst_check)
++ *(.text.set_queue_congested)
++ *(.text.prepare_to_wait)
++ *(.text.sys_write)
++ *(.text.swap_io_context)
++ *(.text.sys_alarm)
++ *(.text.mempool_resize)
++ *(.text.__cond_resched)
++ *(.text.scsi_16_lba_len)
++ *(.text.autoremove_wake_function)
++ *(.text.inotify_dentry_parent_queue_event)
++ *(.text.cfq_init_prio_data)
++ *(.text.group_send_sig_info)
++ *(.text.ata_qc_issue_prot)
++ *(.text.cfq_put_queue)
++ *(.text.__set_irq_handler)
++ *(.text.__generic_file_aio_read)
++ *(.text.ox800sata_eng_timeout)
++ *(.text.rb_erase)
++ *(.text.generic_file_aio_read)
++ *(.text.default_llseek)
++ *(.text.blk_unplug_work)
++ *(.text.linear_make_request)
++ *(.text.elv_insert)
++ *(.text.velocity_init_registers)
++ *(.text.vfs_permission)
++ *(.text.alloc_inode)
++ *(.text.mii_ethtool_sset)
++ *(.text.blk_rq_map_kern)
++ *(.text.tcp_urg)
++ *(.text.__ata_qc_complete)
++ *(.text.io_schedule_timeout)
++ *(.text.run_posix_cpu_timers)
++ *(.text.ox800sata_irq_clear)
++ *(.text.put_tty_driver)
++ *(.text.free_sg_controller)
++ *(.text.__sk_stream_mem_reclaim)
++ *(.text.elv_merge)
++ *(.text.scsi_run_queue)
++ *(.text.elv_former_request)
++ *(.text.blk_requeue_request)
++ *(.text.__end_that_request_first)
++ *(.text.ext3_get_block)
++ *(.text.ox800sata_phy_reset)
++ *(.text.schedule_timeout)
++ *(.text.grab_cache_page_nowait)
++ *(.text.bio_map_kern_endio)
++ *(.text.__up_read)
++ *(.text.tcp_data_queue)
++ *(.text.set_bdev_super)
++ *(.text.ext3_readpages)
++ *(.text.scsi_exit_queue)
++ *(.text.ext3_get_branch)
++ *(.text.cfq_forced_dispatch_cfqqs)
++ *(.text.bioset_free)
++ *(.text.blk_execute_rq_nowait)
++ *(.text.scsi_eh_wakeup)
++ *(.text.tcp_delack_timer)
++ *(.text.shrink_icache_memory)
++ *(.text.mpage_end_io_write)
++ *(.text.scsi_io_completion)
++ *(.text.verify_iovec)
++ *(.text.credit_entropy_store)
++ *(.text.blk_unplug_timeout)
++ *(.text.work_resched)
++ *(.text.sys_sendfile)
++ *(.text.do_bad_IRQ)
++ *(.text.sd_rw_intr)
++ *(.text.set_task_comm)
++ *(.text.blk_do_ordered)
++ *(.text.rb_last)
++ *(.text.drop_buffers)
++ *(.text.ata_scsi_rw_xlat)
++ *(.text.oxnas_dma_shutdown)
++ *(.text.__group_send_sig_info)
++ *(.text.led_trigger_set_default)
++ *(.text.blk_queue_bounce)
++ *(.text.cfq_var_store)
++ *(.text.rb_insert_color)
++ *(.text.__remove_hrtimer)
++ *(.text.sys_sysinfo)
++ *(.text.tcp_simple_retransmit)
++ *(.text.it_real_fn)
++ *(.text.sk_send_sigurg)
++ *(.text.sys_statfs64_wrapper)
++ *(.text.alloc_page_buffers)
++ *(.text.bio_pair_release)
++ *(.text.__dequeue_signal)
++ *(.text.kblockd_schedule_work)
++ *(.text.wakeup_kswapd)
++ *(.text.process_timeout)
++ *(.text.__getblk)
++ *(.text.blk_get_request)
++ *(.text.sync_buffer)
++ *(.text.sk_stream_mem_schedule)
++ *(.text.vfs_stat)
++ *(.text.rb_replace_node)
++ *(.text.signal_wake_up)
++ *(.text.ata_std_ports)
++ *(.text.tcp_send_ack)
++ *(.text.send_signal)
++ *(.text._atomic_dec_and_lock)
++ *(.text.set_bh_page)
++ *(.text.mutex_trylock)
++ *(.text.sys_sigaltstack_wrapper)
++ *(.text.sig_ignored)
++ *(.text.net_family_write_lock)
++ *(.text.radix_tree_node_alloc)
++ *(.text.may_open)
++ *(.text.account_user_time)
++ *(.text.udp_seq_start)
++ *(.text.ll_front_merge_fn)
++ *(.text.laptop_flush)
++ *(.text.__tasklet_hi_schedule)
++ *(.text.__und_usr)
++ *(.text.do_signal)
++ *(.text.wake_bit_function)
++ *(.text.mutex_lock_interruptible)
++ *(.text.cfq_merged_request)
++ *(.text.scsi_init_cmd_from_req)
++ *(.text.elv_requeue_request)
++ *(.text.force_sigsegv)
++ *(.text.elv_merge_requests)
++ *(.text.cp_new_stat)
++ *(.text.prepare_to_wait_exclusive)
++ *(.text.ioc_set_batching)
++ *(.text.check_kill_permission)
++ *(.text.scsi_queue_insert)
++ *(.text.__csum_ipv6_magic)
++ *(.text.wb_kupdate)
++ *(.text.__down_write_trylock)
++ *(.text.elv_register_queue)
++ *(.text.sys_getitimer)
++ *(.text.ox800sata_pio_task)
++ *(.text.hrtimer_try_to_cancel)
++ *(.text.find_pid)
++ *(.text.oxnas_dma_raw_isactive)
++ *(.text.cmp_ex)
++ *(.text.__mpage_writepage)
++ *(.text.sk_stream_wait_memory)
++ *(.text.sys_sched_yield)
++ *(.text.background_writeout)
++ *(.text.rotate_reclaimable_page)
++ *(.text.do_sigaction)
++ *(.text.sock_def_write_space)
++ *(.text.sched_exit)
++ *(.text.inode_change_ok)
++ *(.text.wait_for_completion_interruptible)
++ *(.text.device_initialize)
++ *(.text.journal_set_revoke)
++ *(.text.try_to_free_pages)
++ *(.text.tcp_write_timer)
++ *(.text.dev_ioctl)
++ *(.text.skb_copy_expand)
++ *(.text.invalidate_complete_page)
++ *(.text.*)
+ __exception_text_start = .;
+ *(.exception.text)
+ __exception_text_end = .;
+diff -Nurd linux-2.6.24/arch/arm/lib/Makefile linux-2.6.24-oxe810/arch/arm/lib/Makefile
+--- linux-2.6.24/arch/arm/lib/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/lib/Makefile 2008-06-11 17:47:47.000000000 +0200
+@@ -29,6 +29,10 @@
+ endif
+ endif
+
++ifeq ($(CONFIG_OXNAS_DMA_COPIES),y)
++ lib-y += oxnas_copies.o
++endif
++
+ lib-$(CONFIG_MMU) += $(mmu-y)
+
+ ifeq ($(CONFIG_CPU_32v3),y)
+diff -Nurd linux-2.6.24/arch/arm/lib/clear_user.S linux-2.6.24-oxe810/arch/arm/lib/clear_user.S
+--- linux-2.6.24/arch/arm/lib/clear_user.S 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/lib/clear_user.S 2008-06-11 17:47:47.000000000 +0200
+@@ -18,7 +18,11 @@
+ * : sz - number of bytes to clear
+ * Returns : number of bytes NOT cleared
+ */
++#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
++ENTRY(__clear_user_alt)
++#else // CONFIG_OXNAS_INSTRUMENT_COPIES
+ ENTRY(__clear_user)
++#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
+ stmfd sp!, {r1, lr}
+ mov r2, #0
+ cmp r1, #4
+diff -Nurd linux-2.6.24/arch/arm/lib/copy_from_user.S linux-2.6.24-oxe810/arch/arm/lib/copy_from_user.S
+--- linux-2.6.24/arch/arm/lib/copy_from_user.S 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/lib/copy_from_user.S 2008-06-11 17:47:47.000000000 +0200
+@@ -83,7 +83,12 @@
+
+ .text
+
++#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
++ENTRY(__copy_from_user_alt)
++#else // CONFIG_OXNAS_INSTRUMENT_COPIES
++.section ".text.__copy_from_user"
+ ENTRY(__copy_from_user)
++#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
+
+ #include "copy_template.S"
+
+diff -Nurd linux-2.6.24/arch/arm/lib/copy_to_user.S linux-2.6.24-oxe810/arch/arm/lib/copy_to_user.S
+--- linux-2.6.24/arch/arm/lib/copy_to_user.S 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/lib/copy_to_user.S 2008-06-11 17:47:47.000000000 +0200
+@@ -86,7 +86,12 @@
+
+ .text
+
++#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
++ENTRY(__copy_to_user_alt)
++#else // CONFIG_OXNAS_INSTRUMENT_COPIES
++.section ".text.__copy_to_user"
+ ENTRY(__copy_to_user)
++#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
+
+ #include "copy_template.S"
+
+diff -Nurd linux-2.6.24/arch/arm/lib/memcpy.S linux-2.6.24-oxe810/arch/arm/lib/memcpy.S
+--- linux-2.6.24/arch/arm/lib/memcpy.S 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/lib/memcpy.S 2008-06-11 17:47:47.000000000 +0200
+@@ -53,6 +53,7 @@
+
+ /* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
+
++.section ".text.memcpy"
+ ENTRY(memcpy)
+
+ #include "copy_template.S"
+diff -Nurd linux-2.6.24/arch/arm/lib/memzero.S linux-2.6.24-oxe810/arch/arm/lib/memzero.S
+--- linux-2.6.24/arch/arm/lib/memzero.S 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/lib/memzero.S 2008-06-11 17:47:47.000000000 +0200
+@@ -30,6 +30,7 @@
+ * memzero again.
+ */
+
++.section ".text.__memzero"
+ ENTRY(__memzero)
+ mov r2, #0 @ 1
+ ands r3, r0, #3 @ 1 unaligned?
+diff -Nurd linux-2.6.24/arch/arm/lib/oxnas_copies.c linux-2.6.24-oxe810/arch/arm/lib/oxnas_copies.c
+--- linux-2.6.24/arch/arm/lib/oxnas_copies.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/lib/oxnas_copies.c 2008-06-11 17:47:47.000000000 +0200
+@@ -0,0 +1,261 @@
++/*
++ * linux/arch/arm/lib/nas_copies.c
++ *
++ * Copyright (C) 2006 Oxford Semiconductor Ltd
++ *
++ * 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 <linux/compiler.h>
++#include <linux/dma-mapping.h>
++#include <linux/mm.h>
++#include <linux/pagemap.h>
++#include <asm/scatterlist.h>
++#include <asm/semaphore.h>
++#include <asm/arch/dma.h>
++
++static DECLARE_MUTEX(copy_mutex);
++static __DECLARE_SEMAPHORE_GENERIC(callback_semaphore, 0);
++
++static void dma_callback(
++ oxnas_dma_channel_t *channel,
++ oxnas_callback_arg_t arg,
++ oxnas_dma_callback_status_t error_code,
++ u16 checksum,
++ int interrupt_count)
++{
++ up(&callback_semaphore);
++}
++
++unsigned long oxnas_copy_from_user(void *to, const void __user *from, unsigned long count)
++{
++ int pages_mapped, i;
++ unsigned long transfered = 0;
++ struct page *pages[2];
++ oxnas_dma_channel_t *channel;
++ unsigned long uaddr = (unsigned long)from;
++ unsigned long end_page = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
++ unsigned long start_page = uaddr >> PAGE_SHIFT;
++ int nr_pages = end_page - start_page;
++//printk("F 0x%08lx 0x%08lx %lu -> %lu, %lu, %d\n", (unsigned long)to, (unsigned long)from, count, start_page, end_page, nr_pages);
++
++ might_sleep();
++
++ BUG_ON(nr_pages > 2);
++
++ // Only support a single concurrent copy operation, as only using a single
++ // DMA channel for now
++ while (down_interruptible(©_mutex));
++
++ // Get kernel mappings for the user pages
++ down_read(¤t->mm->mmap_sem);
++ pages_mapped = get_user_pages(current, current->mm, uaddr, nr_pages, 0, 0, pages, NULL);
++ up_read(¤t->mm->mmap_sem);
++
++ if (pages_mapped != nr_pages) {
++ // Didn't get mappings for all pages requested, so release any we did get
++ for (i=0; i < pages_mapped; ++i) {
++ page_cache_release(pages[i]);
++ }
++ pages_mapped = 0;
++ }
++
++ if (pages_mapped) {
++ int i;
++ struct scatterlist sl;
++ struct scatterlist gl[2];
++
++ // Fill gathering DMA descriptors
++ gl[0].page = pages[0];
++ gl[0].offset = uaddr & ~PAGE_MASK;
++ if (pages_mapped > 1) {
++ gl[0].length = PAGE_SIZE - gl[0].offset;
++ gl[1].offset = 0;
++ gl[1].page = pages[1];
++ gl[1].length = count - gl[0].length;
++ } else {
++ gl[0].length = count;
++ }
++
++ // Create DMA mappings for all the user pages
++ for (i=0; i < pages_mapped; ++i) {
++ gl[i].dma_address = dma_map_single(0, page_address(gl[i].page) + gl[i].offset, gl[i].length, DMA_TO_DEVICE);
++ }
++
++ // Create a DMA mapping for the kernel memory range
++ sl.dma_address = dma_map_single(0, to, count, DMA_FROM_DEVICE);
++ sl.length = count;
++
++ // Allocate a DMA channel
++ channel = oxnas_dma_request(1);
++ BUG_ON(channel == OXNAS_DMA_CHANNEL_NUL);
++
++ // Do DMA from user to kernel memory
++ oxnas_dma_set_sg(
++ channel,
++ gl,
++ pages_mapped,
++ &sl,
++ 1,
++ OXNAS_DMA_MODE_INC,
++ OXNAS_DMA_MODE_INC,
++ 0);
++
++ // Using notification callback
++ oxnas_dma_set_callback(channel, dma_callback, OXNAS_DMA_CALLBACK_ARG_NUL);
++ oxnas_dma_start(channel);
++
++ // Sleep until transfer complete
++ while (down_interruptible(&callback_semaphore));
++ oxnas_dma_set_callback(channel, OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
++ transfered += count;
++
++ // Release the DMA channel
++ oxnas_dma_free(channel);
++
++ // Release kernel DMA mapping
++ dma_unmap_single(0, sl.length, count, DMA_FROM_DEVICE);
++ // Release user DMA mappings
++ for (i=0; i < pages_mapped; ++i) {
++ dma_unmap_single(0, gl[i].dma_address, gl[i].length, DMA_TO_DEVICE);
++ }
++
++ // Release user pages
++ for (i=0; i < pages_mapped; ++i) {
++ page_cache_release(pages[i]);
++ }
++ }
++
++ up(©_mutex);
++
++ return count - transfered;
++}
++
++//unsigned long oxnas_copy_to_user(void __user *to, const void *from, unsigned long count)
++//{
++// int pages_mapped, i;
++// unsigned long transfered = 0;
++// struct page *pages[2];
++// oxnas_dma_channel_t *channel;
++// unsigned long uaddr = (unsigned long)to;
++// unsigned long end_page = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
++// unsigned long start_page = uaddr >> PAGE_SHIFT;
++// int nr_pages = end_page - start_page;
++////printk("T 0x%08lx 0x%08lx %lu -> %lu, %lu, %d\n", (unsigned long)to, (unsigned long)from, count, start_page, end_page, nr_pages);
++//
++// might_sleep();
++//
++// BUG_ON(nr_pages > 2);
++//
++// // Only support a single concurrent copy operation, as only using a single
++// // DMA channel for now
++// while (down_interruptible(©_mutex));
++//
++// // Get kernel mappings for the user pages
++// down_read(¤t->mm->mmap_sem);
++// pages_mapped = get_user_pages(current, current->mm, uaddr, nr_pages, 1, 0, pages, NULL);
++// up_read(¤t->mm->mmap_sem);
++//
++// if (pages_mapped != nr_pages) {
++// // Didn't get mapping for all the pages we requested, so release any
++// // user page mappings we did get
++// for (i=0; i < pages_mapped; ++i) {
++// page_cache_release(pages[i]);
++// }
++// pages_mapped = 0;
++// }
++//
++// if (pages_mapped) {
++// int i;
++// struct scatterlist gl;
++// struct scatterlist sl[2];
++//
++// // Fill scattering DMA descriptors for writing to user space
++// sl[0].page = pages[0];
++// sl[0].offset = uaddr & ~PAGE_MASK;
++// if (pages_mapped > 1) {
++// sl[0].length = PAGE_SIZE - sl[0].offset;
++// sl[1].offset = 0;
++// sl[1].page = pages[1];
++// sl[1].length = count - sl[0].length;
++// } else {
++// sl[0].length = count;
++// }
++//
++// // Create DMA mappings for all the user pages
++// for (i=0; i < pages_mapped; ++i) {
++// sl[i].__address = page_address(sl[i].page) + sl[i].offset;
++// sl[i].dma_address = dma_map_single(0, sl[i].__address, sl[i].length, DMA_FROM_DEVICE);
++// }
++//
++// // Create a DMA mapping for the kernel memory range
++// gl.dma_address = dma_map_single(0, (void*)from, count, DMA_TO_DEVICE);
++// gl.length = count;
++//
++//// {
++//////flush_cache_all();
++//// // Do copy with CPU to test
++//// const char* src = from;
++//////printk("T Copying...\n");
++//// for (i=0; i < pages_mapped; ++i) {
++//// void* kadr = kmap(sl[i].page) + sl[i].offset;
++//// memcpy(kadr, src, sl[i].length);
++//// kunmap(sl[i].page);
++//// src += sl[i].length;
++//// transfered += sl[i].length;
++//// }
++//// }
++//
++//flush_cache_all();
++// // Allocate a DMA channel
++// channel = oxnas_dma_request(1);
++// BUG_ON(channel == OXNAS_DMA_CHANNEL_NUL);
++//
++// // Do DMA from kernel to user memory
++// oxnas_dma_set_sg(
++// channel,
++// &gl,
++// 1,
++// sl,
++// pages_mapped,
++// OXNAS_DMA_MODE_INC,
++// OXNAS_DMA_MODE_INC,
++// 0);
++// oxnas_dma_start(channel);
++// while (oxnas_dma_is_active(channel));
++// transfered += count;
++//
++// // Release the DMA channel
++// oxnas_dma_free(channel);
++////flush_cache_all();
++//
++// // Release kernel DMA mapping
++// dma_unmap_single(0, gl.dma_address, count, DMA_TO_DEVICE);
++// // Release user DMA mappings
++// for (i=0; i < pages_mapped; ++i) {
++// dma_unmap_single(0, sl[i].dma_address, sl[i].length, DMA_FROM_DEVICE);
++// }
++//
++// // Release user pages
++// for (i=0; i < pages_mapped; ++i) {
++// SetPageDirty(pages[i]);
++// page_cache_release(pages[i]);
++// }
++// }
++//
++// up(©_mutex);
++//
++// return count - transfered;
++//}
++
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/Kconfig linux-2.6.24-oxe810/arch/arm/mach-oxnas/Kconfig
+--- linux-2.6.24/arch/arm/mach-oxnas/Kconfig 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/Kconfig 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,574 @@
++if ARCH_OXNAS
++
++menu "Oxford Semiconductor NAS Options"
++
++config ARCH_OXNAS_FPGA
++ bool "FPGA platform"
++ default n
++ help
++ This enables support for Oxsemi NAS SoC FPGA development platform
++
++config OXNAS_CORE_CLK
++ int "Integrator core module processor clock frequency in MHz"
++ depends on ARCH_OXNAS_FPGA
++ default 175
++ help
++ Maximum reliable frequency 175MHz
++
++config OXNAS_CORE_BUS_CLK_DIV
++ int "Integrator core module bus clock divider"
++ depends on ARCH_OXNAS_FPGA
++ default 4
++ help
++ Must be greater than 0
++
++config NOMINAL_PLL400_FREQ
++ int "The master clock frequency of the Soc"
++ default 400000000
++ help
++ The PLL400 clock is divided by 2 to drive the ARM clock and by
++ 4 to drive the AHB clock
++
++config NOMINAL_RPSCLK_FREQ
++ int "The input clock frequency to the RPS"
++ default 25000000
++ help
++ The RPS clock feeds into a prescaler and from there feeds the
++ RPS timers
++
++choice
++ prompt "OXNAS system type"
++ default OXNAS_VERSION_0X800
++
++config OXNAS_VERSION_0X800
++ bool "0X800"
++ select ARM_AMBA
++ help
++ Support for the 0X800 SoC
++
++config OXNAS_VERSION_0X810
++ bool "0X810"
++ select ARM_AMBA
++ help
++ Support for the 0X810 SoC
++
++config OXNAS_VERSION_0X850
++ bool "0X850"
++ help
++ Support for the 0X850 SoC
++endchoice
++
++config ARCH_OXNAS_UART1
++ bool "Support UART1"
++ default n
++ help
++ This enables UART1 to be accessible to Linux.
++ UARTs will be mapped to ttySn numbers from UART1 to UART4, only
++ including those UARTs selected to be present
++
++config ARCH_OXNAS_UART1_MODEM
++ bool "Support UART1 modem control lines"
++ depends on ARCH_OXNAS_UART1
++ default n
++ help
++ Multiplex the modem control lines from UART1 onto external pins
++
++config ARCH_OXNAS_UART2
++ bool "Support UART2"
++ default n
++ help
++ This enables UART2 to be accessible to Linux
++ UARTs will be mapped to ttySn numbers from UART1 to UART4, only
++ including those UARTs selected to be present
++
++config ARCH_OXNAS_UART2_MODEM
++ bool "Support UART2 modem control lines"
++ depends on ARCH_OXNAS_UART2
++ default n
++ help
++ Multiplex the modem control lines from UART2 onto external pins
++
++config ARCH_OXNAS_UART3
++ bool "Support UART3"
++ default n
++ help
++ This enables UAR3 to be accessible to Linux
++ UARTs will be mapped to ttySn numbers from UART1 to UART4, only
++ including those UARTs selected to be present
++
++config ARCH_OXNAS_UART3_MODEM
++ bool "Support UART3 modem control lines"
++ depends on ARCH_OXNAS_UART3
++ default n
++ help
++ Multiplex the modem control lines from UART3 onto external pins
++
++config ARCH_OXNAS_UART4
++ bool "Support UART4"
++ depends on !PCI
++ default n
++ help
++ This enables UART4 to be accessible to Linux
++ UARTs will be mapped to ttySn numbers from UART1 to UART4, only
++ including those UARTs selected to be present
++ UART4 always has its modem control lines available on external pins
++ when selected (overlaying PCI functions)
++
++config ARCH_OXNAS_PCI_REQGNT_0
++ bool "Enable req/gnt for PCI device 0"
++ depends on PCI
++ default n
++ help
++
++config ARCH_OXNAS_PCI_REQGNT_1
++ bool "Enable req/gnt for PCI device 1"
++ depends on PCI
++ default n
++ help
++
++config ARCH_OXNAS_PCI_REQGNT_2
++ bool "Enable req/gnt for PCI device 2"
++ depends on PCI
++ default n
++ help
++
++config ARCH_OXNAS_PCI_REQGNT_3
++ bool "Enable req/gnt for PCI device 3"
++ depends on PCI
++ default n
++ help
++
++config ARCH_OXNAS_PCI_CLKOUT_0
++ bool "Enable PCI clock output 0"
++ depends on PCI
++ default n
++ help
++
++config ARCH_OXNAS_PCI_CLKOUT_1
++ bool "Enable PCI clock output 1"
++ depends on PCI
++ default n
++ help
++
++config ARCH_OXNAS_PCI_CLKOUT_2
++ bool "Enable PCI clock output 2"
++ depends on PCI
++ default n
++ help
++
++config ARCH_OXNAS_PCI_CLKOUT_3
++ bool "Enable PCI clock output 3"
++ depends on PCI
++ default n
++ help
++
++config OXNAS_PCI_RESET
++ bool "Allow PCI reset to be toggled after power up"
++ depends on PCI
++ default n
++ help
++ The SoC requires that the PCI bus reset be toggled after the
++ rest of the SoC has emerged from reset
++
++config OXNAS_PCI_RESET_GPIO
++ int "GPIO line connected to PCI reset"
++ depends on OXNAS_PCI_RESET
++ default 12
++ help
++ The PCI bus requires a separate reset to be asserted after the
++ reset of the SoC has emerged from reset. This defines the GPIO
++ line which is connected to the PCI reset
++
++config OXNAS_SATA_POWER_1
++ bool "Allow control of SATA 1 disk power via GPIO"
++ default n
++ help
++ Allow SATA disk 1 power to be turned off via GPIO lines
++
++config OXNAS_SATA_POWER_GPIO_1
++ int "GPIO line connected to SATA power control for disk 1"
++ depends on OXNAS_SATA_POWER_1
++ default 15
++ help
++ The GPIO line that controls SATA disk 1 power
++
++config OXNAS_SATA_POWER_2
++ bool "Allow control of SATA disk 2 power via GPIO"
++ default n
++ help
++ Allow SATA disk 2 power to be turned off via GPIO lines
++
++config OXNAS_SATA_POWER_GPIO_2
++ int "GPIO line connected to SATA power control for disk 2"
++ depends on OXNAS_SATA_POWER_2
++ default 18
++ help
++ The GPIO line that controls SATA disk 2 power
++
++config FORCE_MAX_ZONEORDER
++ int "Max order of zoned buddy allocator"
++ default 11
++ help
++ The value to be assigned to MAX_ORDER
++
++config SRAM_NUM_PAGES
++ int "The number of SRAM memory pages present in the system"
++ default 8
++ help
++ Determines the number of pages of SRAM that are assumed to exist in the
++ system memory map
++
++config SUPPORT_LEON
++ bool "Include support for Leon"
++ default n
++
++config LEON_PAGES
++ int "The number of 4K pages of SRAM to reserve for the LEON program"
++ depends on SUPPORT_LEON
++ default 2
++ help
++ Determines the number of 4K pages of SRAM that are reserved for the
++ LEON program
++
++config LEON_COPRO
++ bool "Load LEON networking acceleration program"
++ depends on SUPPORT_LEON && OXNAS_VERSION_0X810
++ default n
++
++config LEON_OFFLOAD_TX
++ bool "Whether network Tx operations should be offloaded to the LEON"
++ depends on LEON_COPRO
++ default n
++
++config LEON_RESERVE_DMA_CHANNEL
++ bool "Whether to reserve the last DMA channel for the CoPro's use"
++ depends on LEON_OFFLOAD_TX
++ default n
++
++config LEON_OFFLOAD_TSO
++ bool "Whether network TSO operations should be offloaded to the LEON"
++ depends on LEON_OFFLOAD_TX
++ default n
++
++config LEON_START_EARLY
++ bool "Load LEON early startup program"
++ depends on SUPPORT_LEON
++ default n
++ help
++ For situations where the LEON is to run some code unrelated to
++ its normal network acceleration functions, this options causes
++ the LEON code to be loaded and the LEON started early in the
++ boot process
++
++config LEON_POWER_BUTTON_MONITOR
++ tristate "Load LEON power button monitoring program"
++ depends on SUPPORT_LEON
++ default n
++ help
++ Support powering down the system via a GPIO button and when the
++ system is powered down load a LEON program that will monitor the
++ button for attempts to power the system back on
++
++config OXNAS_POWER_BUTTON_GPIO
++ int "GPIO line connected to power button"
++ depends on LEON_POWER_BUTTON_MONITOR
++ default 33
++ help
++ Specifies the GPIO line to which the power button is connected
++
++config USER_RECOVERY_BUTTON_MONITOR
++ tristate "Load user recovery button monitoring program"
++ default n
++ help
++ Support User recovery of the system via a GPIO button. When the
++ system is power cycled after the use of this button, the admin
++ password and network settings are set to factory values.
++
++config OXNAS_USER_RECOVERY_BUTTON_GPIO
++ int "GPIO line connected to user recovery button"
++ depends on USER_RECOVERY_BUTTON_MONITOR
++ default 32
++ help
++ Specifies the GPIO line to which the user recovery button is
++ connected.
++
++config OXNAS_DDR_MON
++ bool "Poll the DDR core bus monitors from timer tick interrupt"
++ default n
++
++config OXNAS_AHB_MON
++ bool "Include support for AHB monitors"
++ default n
++
++config OXNAS_MONITOR_SUBSAMPLE
++ int "Jiffy subsample factor for AHB monitor sampling"
++ depends on OXNAS_AHB_MON || OXNAS_DDR_MON
++ default 10
++ help
++ The factor by which to subsample the jiffy count to produce AHB monitor
++ sampling events
++
++config OXNAS_CACHE_LOCKDOWN
++ bool "Allow locking down part of the caches"
++ default n
++
++config OXNAS_CACHE_I_MASK
++ int "Bit mask for I cache lockdown"
++ depends on OXNAS_CACHE_LOCKDOWN
++ default 0
++ help
++ Allowable values are:
++ 0 - No ways locked down
++ 1 - One way locked down
++ 3 - Two ways locked down
++ 7 - Three ways locked down
++
++config OXNAS_CACHE_D_MASK
++ int "Bit mask for D cache lockdown"
++ depends on OXNAS_CACHE_LOCKDOWN
++ default 0
++ help
++ Allowable values are:
++ 0 - No ways locked down
++ 1 - One way locked down
++ 3 - Two ways locked down
++ 7 - Three ways locked down
++
++config DO_MEM_TEST
++ bool "Perform memory copy throughput test during boot"
++ default 0
++
++config CRYPTO_OXAESLRW
++ tristate "LRW-AES hardware support"
++ help
++ Driver for controlling the Ox-Semi OX800 cipher core for LRW-AES
++ encryption
++
++config DESCRIPTORS_PAGES
++ int "The number of SRAM memory pages to reserve for DMA descriptors"
++ default 1
++ help
++ Determines the number of pages of SRAM that are reserved for DMA
++ descriptors
++
++config ARCH_OXNAS_NUM_GMAC_DESCRIPTORS
++ int "The number of GMAC descriptors to allocate"
++ default 112
++
++config ARCH_OXNAS_MAX_SATA_SG_ENTRIES
++ int "The max. number of SG DMA descriptors to use in the single transfer"
++ default 64
++
++config TACHO_THERM_AND_FAN
++ tristate "Include support for the temperature sensing, and automatic fan control"
++ default n
++
++config GPIO_TEST
++ tristate "Device driver for exercising GPIO block."
++ default n
++ help
++ Connect the I2C serial lines (SCLK, SCS, and SDT) together to run test
++
++config OXNAS_RTC
++ tristate "Probe for m41t00 RTC"
++ select I2C
++ select I2C_ALGOBIT
++ select I2C_OXNAS_BITBASH
++ select RTC_CLASS
++ select RTC_DRV_DS1307
++ default n
++ help
++ The M41T00 RTC provides basic time save and restore.
++ The device is probed for on the OXNAS bit-bash I2C bus.
++
++config I2S
++ tristate "I2S test interface"
++ default n
++ help
++ Say Y here to use i2s
++ This support is also available as a module. If so, the module will be
++ called i2s.
++
++config PCI_OXNAS_CARDBUS
++ bool "Switches from a PCI/Mini-PCI bus to a Cardbus bus."
++ depends on PCI && ARCH_OXNAS_FPGA
++ ---help---
++ This option limits scanning of the bus to omit the Via SATA interface.
++ This makes the bus compatible with cardbus cards that expect to be the
++ only PCI device on the bus.
++
++config DPE_TEST
++ tristate "Test the DPE core"
++ default n
++
++config OXNAS_EARLY_PRINTK
++ bool "Whether to output to printascii from printk"
++ depends on DEBUG_LL
++ help
++ If both CONFIG_DEBUG_LL and this option are selected, then each printk
++ call will duplicate the message in a call to printascii to get very
++ early console output
++
++config OXNAS_INSTRUMENT_COPIES
++ bool "Instrument copy_to_user and copy_from_user"
++ default n
++
++config OXNAS_INSTRUMENT_COPIES_THRESHOLD
++ int "The threshold above which copies will be instrumented"
++ depends on OXNAS_INSTRUMENT_COPIES
++ default 0
++
++config OXNAS_INSTRUMENT_COPIES_TIME
++ bool "Whether to print copy timing to console"
++ depends on OXNAS_INSTRUMENT_COPIES
++ default n
++
++config OXNAS_INSTRUMENT_COPIES_GPIO
++ bool "Whether to toggle a GPIO around copies"
++ depends on OXNAS_INSTRUMENT_COPIES
++ default n
++
++config OXNAS_DMA_COPIES
++ bool "Whether to use DMA for larger user-kernel copies"
++ default n
++
++config OXNAS_DMA_COPY_THRESHOLD
++ int "The threshold above which DMA will be used for copies"
++ depends on OXNAS_DMA_COPIES
++ default 1024
++
++config OXNAS_AHB_MONITOR_MODULE
++ tristate "Creates a loadable module to control the AHB monitors"
++ default n
++ help
++ This module publishes the current values of the AHB
++ monitors in the /proc filing system.
++ The monitors can be controlled by writing into this
++ filing system
++
++config OXNAS_USB_TEST_MODES
++ tristate "Create a loadable module to control the USB port test modes"
++ default n
++ help
++ This module reports the port status and allows setting
++ of the test mode in the port register via the /proc
++ filing system.
++
++config OXNAS_FRONT_LAMP_CONTROL
++ tristate "Front Panel LED control system"
++ depends on LEDS_CLASS
++ default n
++ help
++ This module reports drives a number of GPIOs as PWM signals to drive
++ front panel LEDs. The pattern displayed is dependent on system state.
++
++config LEDS_TRIGGER_SATA_DISK
++ tristate "Front Panel SATA disk activity lamp control system"
++ default n
++ help
++ This module reports drives the SATA disk activity lamp.
++
++config OXNAS_LED_TEST
++ bool "Exercise the WD LEDs"
++ default n
++
++config OXNAS_I2C_SDA
++ int "I2C bit-bash data line"
++ default 2
++
++config OXNAS_I2C_SCL
++ int "I2C bit-bash clock line"
++ default 3
++
++config OXNAS_USB_PORTA_POWER_CONTROL
++ bool "Support USB port A power control lines"
++ default n
++ help
++ Whether to support power switch out and monitor in via GPIOs
++ for USB port A
++
++config OXNAS_USB_PORTB_POWER_CONTROL
++ bool "Support USB port B power control lines"
++ default n
++ help
++ Whether to support power switch out and monitor in via GPIOs
++ for USB port B
++
++config OXNAS_USB_PORTC_POWER_CONTROL
++ bool "Support USB port C power control lines"
++ default n
++ help
++ Whether to support power switch out and monitor in via GPIOs
++ for USB port C
++
++config OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE
++ bool "Set USB power monitor input polarity to negative"
++ default n
++ help
++ n - Positive polarity
++ y - Negative polarity
++
++config OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE
++ bool "Set USB power switch output polarity to negative"
++ default n
++ help
++ n - Positive polarity
++ y - Negative polarity
++
++config WDC_FAN_OXNAS800
++ tristate "WD NetCenter/2NC Fan control driver"
++ default n
++ help
++ This driver allows user-mode applications to control the cooling
++ fan on Western Digital's NetCenter/2NC platform.
++
++config OXNAS_MAP_SRAM
++ bool "Allow part of kernel to be mapped into SRAM"
++ default n
++
++config OXNAS_COPY_CODE_TO_SRAM
++ bool "Copy part of kernel to SRAM"
++ depends on OXNAS_MAP_SRAM
++ default n
++
++config OXNAS_SUID_INHERIT
++ bool "Make SUID be inherited by subdirectories"
++ default n
++
++config OXNAS_USB_HUB_SUPPORT
++ bool "Enable support for on-board USB hub"
++ default n
++
++config OXNAS_USB_CKOUT
++ bool "Enable output of 12MHz USB clock on GPIO 10"
++ depends on OXNAS_USB_HUB_SUPPORT
++ default n
++
++config OXNAS_USB_HUB_RESET_CONTROL
++ bool "Control the USB hub reset line"
++ depends on OXNAS_USB_HUB_SUPPORT
++ default n
++
++config OXNAS_USB_HUB_RESET_GPIO
++ int "The GPIO connected to the USB hub reset"
++ depends on OXNAS_USB_HUB_RESET_CONTROL
++ default 27
++
++config OXNAS_USB_HUB_RESET_ACTIVE_HIGH
++ int "Set to 1 for active high, 0 for active low reset"
++ depends on OXNAS_USB_HUB_RESET_CONTROL
++ default 1
++
++config OXNAS_USB_HUB_RESET_TOGGLE
++ bool "Select to toggle reset, do not select to just deassert reset"
++ depends on OXNAS_USB_HUB_RESET_CONTROL
++ default y
++
++config OXNAS_USB_HUB_RESET_PERIOD_MS
++ int "The period for which the USB hub reset should be asserted in milliseconds"
++ depends on OXNAS_USB_HUB_RESET_TOGGLE
++ default 100
++
++endmenu
++
++endif
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/Makefile linux-2.6.24-oxe810/arch/arm/mach-oxnas/Makefile
+--- linux-2.6.24/arch/arm/mach-oxnas/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/Makefile 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,43 @@
++#
++# Makefile for the linux kernel.
++#
++
++# Object file lists.
++
++obj-y := oxnas.o irq.o time.o dma.o pci.o ahb_mon.o leon.o samba_reserve.o
++
++obj-$(CONFIG_SYNOPSYS_GMAC) += gmac.o
++
++gmac-objs := gmac-napi.o gmac_ethtool.o gmac_phy.o gmac_desc.o gmac_offload.o
++
++obj-$(CONFIG_OXNAS_IBW) += ibw.o
++
++obj-$(CONFIG_TACHO_THERM_AND_FAN) += thermAndFan.o
++
++obj-$(CONFIG_I2S) += i2s.o
++
++obj-$(CONFIG_CRYPTO_OXAESLRW) += cipher.o
++
++obj-$(CONFIG_GPIO_TEST) += gpioTest.o
++
++obj-$(CONFIG_I2S) += i2s.o
++
++obj-$(CONFIG_DPE_TEST) += dpe_test.o
++
++obj-$(CONFIG_OXNAS_AHB_MONITOR_MODULE) += oxnas-ahb-monitor.o
++
++obj-$(CONFIG_OXNAS_USB_TEST_MODES) += usb-test-mode.o
++
++obj-$(CONFIG_LEON_POWER_BUTTON_MONITOR) += power_button.o
++
++obj-$(CONFIG_USER_RECOVERY_BUTTON_MONITOR) += user_recovery_button.o
++
++obj-$(CONFIG_OXNAS_FRONT_LAMP_CONTROL) += leds.o
++
++obj-$(CONFIG_WDC_FAN_OXNAS800) += wdc-fan.o
++
++obj-$(CONFIG_WDC_LEDS_OXNAS800) += wdc-leds.o
++
++obj-$(CONFIG_OXNAS_WD810_LEDS) += oxnas-wd810-leds.o
++
++obj-$(CONFIG_WDC_LEDS_TRIGGER_SATA_DISK) += wdc-ledtrig-sata.o
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/Makefile.boot linux-2.6.24-oxe810/arch/arm/mach-oxnas/Makefile.boot
+--- linux-2.6.24/arch/arm/mach-oxnas/Makefile.boot 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/Makefile.boot 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,3 @@
++initrd_phys-$(CONFIG_ARCH_OXNAS) := 0x48200000
++params_phys-$(CONFIG_ARCH_OXNAS) := 0x48000100
++zreladdr-$(CONFIG_ARCH_OXNAS) := 0x48008000
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/README linux-2.6.24-oxe810/arch/arm/mach-oxnas/README
+--- linux-2.6.24/arch/arm/mach-oxnas/README 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/README 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,85 @@
++
++usb-test-modes
++
++This is best built as a module which may be inserted into a running
++Linux system only when needed.
++The module can be built as part of the standard kernel module build
++if the correct options are chosen in the config.
++
++
++How to use:
++
++copy the usb-test-mode.ko file somewhere convenient on the NAS and
++insert the module into the system using
++'modprobe usb-test-mode.ko'
++
++It should report successfull loading or an error message. Assuming it is
++successful /proc will have an 'usb_test_mode' entry (verify with ls).
++
++Actions:
++read the current port status:
++cat /proc/usb_test_mode/read
++
++set port 1 into test mode 4:
++echo 4 > /proc/usb_test_mode/write1
++
++
++When testing is completed the module can be removed from the linux
++system using:
++rmmod usb_test_mode
++
++ahb_mon
++
++This should be built as a module.
++
++How to use:
++
++insert the module into a working system by typing
++'modprobe oxnas-ahb-monitor'
++
++When successfully installed a directory entry will appear in /proc for
++oxnas-ahb-monitor. In the directory will be a writeable file for each
++AHB monitor and a control file. There will also be a readable file for
++obtaining the counts stored in all the ahb monitors.
++
++
++Actions:
++set a monitor to a limited range, burst mode etc using
++low addres, high address, mode, burst mode, burst mask, hprot, hprot mask
++
++Use the echo command to set data into the /proc/oxnas-ahb-monitor an example is
++the following script to observe the activities of the ARM processor on the GMAC
++core when pinging a remote machine:
++---------------------------
++#!/bin/sh -x
++#
++
++# start montoring of ARM data bus to MAC
++# format is "low high mode burst mask hprot mask"
++# mode - 1 write 2 read 3 read write.
++
++echo 2 > /proc/oxnas-test/control
++
++echo 0 > /proc/oxnas-test/control
++
++
++echo "0x40400000,0x405fffff,3,0,0,0,0" > /proc/oxnas-test/ARM_Data
++echo "0x40400000,0x405fffff,3,0,0,0,0" > /proc/oxnas-test/Arm_Inst
++echo "0,4,3,0,0,0,0" > /proc/oxnas-test/CoPro
++echo "0,4,3,0,0,0,0" > /proc/oxnas-test/DMA_A
++echo "0,4,3,0,0,0,0" > /proc/oxnas-test/DMA_B
++echo "0,4,3,0,0,0,0" > /proc/oxnas-test/GMAC
++echo "0,4,3,0,0,0,0" > /proc/oxnas-test/PCI
++echo "0,4,3,0,0,0,0" > /proc/oxnas-test/USBHS
++
++echo 1 > /proc/oxnas-test/control
++
++ping -c 1 172.31.0.102
++
++echo 0 > /proc/oxnas-test/control
++--------------------------------------
++
++When testing is commplete the module can be removed using
++rmmod oxnas-ahb-monitor
++
++
+Files linux-2.6.24/arch/arm/mach-oxnas/ThermCalc.xls and linux-2.6.24-oxe810/arch/arm/mach-oxnas/ThermCalc.xls differ
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/ahb_mon.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/ahb_mon.c
+--- linux-2.6.24/arch/arm/mach-oxnas/ahb_mon.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/ahb_mon.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,177 @@
++/*
++ * linux/arch/arm/mach-oxnas/ahb_mon.c
++ *
++ * 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 <linux/kernel.h>
++#include <asm/io.h>
++#include <asm/arch/hardware.h>
++
++#ifdef CONFIG_OXNAS_AHB_MON
++static void start_ahb_monitors(void)
++{
++ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_D + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_I + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_A + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_B + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_LEON + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_USB + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_MAC + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_ACTIVE << AHB_MON_MODE_MODE_BIT, AHB_MON_PCI + AHB_MON_MODE_REG_OFFSET);
++}
++
++void init_ahb_monitors(
++ AHB_MON_HWRITE_T ahb_mon_hwrite,
++ unsigned hburst_mask,
++ unsigned hburst_match,
++ unsigned hprot_mask,
++ unsigned hprot_match)
++{
++ u32 hburst_mask_value = (hburst_mask & ((1 << AHB_MON_HBURST_MASK_NUM_BITS) - 1));
++ u32 hburst_match_value = (hburst_match & ((1 << AHB_MON_HBURST_MATCH_NUM_BITS) - 1));
++ u32 hprot_mask_value = (hprot_mask & ((1 << AHB_MON_HPROT_MASK_NUM_BITS) - 1));
++ u32 hprot_match_value = (hprot_match & ((1 << AHB_MON_HPROT_MATCH_NUM_BITS) - 1));
++
++ u32 hburst_reg_value = (hburst_mask_value << AHB_MON_HBURST_MASK_BIT) | (hburst_match_value << AHB_MON_HBURST_MATCH_BIT);
++ u32 hprot_reg_value = (hprot_mask_value << AHB_MON_HPROT_MASK_BIT) | (hprot_match_value << AHB_MON_HPROT_MATCH_BIT);
++
++printk("$Ghburst reg value = 0x%08x\n", hburst_reg_value);
++printk("$Ghprot reg value = 0x%08x\n", hprot_reg_value);
++
++ // Reset all the counters and set their operating mode
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_D + AHB_MON_MODE_REG_OFFSET);
++ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_ARM_D + AHB_MON_HWRITE_REG_OFFSET);
++ writel(0UL, AHB_MON_ARM_D + AHB_MON_HADDR_LOW_REG_OFFSET);
++ writel(~0UL, AHB_MON_ARM_D + AHB_MON_HADDR_HIGH_REG_OFFSET);
++ writel(hburst_reg_value, AHB_MON_ARM_D + AHB_MON_HBURST_REG_OFFSET);
++ writel(hprot_reg_value, AHB_MON_ARM_D + AHB_MON_HPROT_REG_OFFSET);
++
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_I + AHB_MON_MODE_REG_OFFSET);
++ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_ARM_I + AHB_MON_HWRITE_REG_OFFSET);
++ writel(0UL, AHB_MON_ARM_I + AHB_MON_HADDR_LOW_REG_OFFSET);
++ writel(~0UL, AHB_MON_ARM_I + AHB_MON_HADDR_HIGH_REG_OFFSET);
++ writel(hburst_reg_value, AHB_MON_ARM_I + AHB_MON_HBURST_REG_OFFSET);
++ writel(hprot_reg_value, AHB_MON_ARM_I + AHB_MON_HPROT_REG_OFFSET);
++
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_A + AHB_MON_MODE_REG_OFFSET);
++ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_DMA_A + AHB_MON_HWRITE_REG_OFFSET);
++ writel(0UL, AHB_MON_DMA_A + AHB_MON_HADDR_LOW_REG_OFFSET);
++ writel(~0UL, AHB_MON_DMA_A + AHB_MON_HADDR_HIGH_REG_OFFSET);
++ writel(hburst_reg_value, AHB_MON_DMA_A + AHB_MON_HBURST_REG_OFFSET);
++ writel(hprot_reg_value, AHB_MON_DMA_A + AHB_MON_HPROT_REG_OFFSET);
++
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_B + AHB_MON_MODE_REG_OFFSET);
++ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_DMA_B + AHB_MON_HWRITE_REG_OFFSET);
++ writel(0UL, AHB_MON_DMA_B + AHB_MON_HADDR_LOW_REG_OFFSET);
++ writel(~0UL, AHB_MON_DMA_B + AHB_MON_HADDR_HIGH_REG_OFFSET);
++ writel(hburst_reg_value, AHB_MON_DMA_B + AHB_MON_HBURST_REG_OFFSET);
++ writel(hprot_reg_value, AHB_MON_DMA_B + AHB_MON_HPROT_REG_OFFSET);
++
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_LEON + AHB_MON_MODE_REG_OFFSET);
++ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_LEON + AHB_MON_HWRITE_REG_OFFSET);
++ writel(0UL, AHB_MON_LEON + AHB_MON_HADDR_LOW_REG_OFFSET);
++ writel(~0UL, AHB_MON_LEON + AHB_MON_HADDR_HIGH_REG_OFFSET);
++ writel(hburst_reg_value, AHB_MON_LEON + AHB_MON_HBURST_REG_OFFSET);
++ writel(hprot_reg_value, AHB_MON_LEON + AHB_MON_HPROT_REG_OFFSET);
++
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_USB + AHB_MON_MODE_REG_OFFSET);
++ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_USB + AHB_MON_HWRITE_REG_OFFSET);
++ writel(0UL, AHB_MON_USB + AHB_MON_HADDR_LOW_REG_OFFSET);
++ writel(~0UL, AHB_MON_USB + AHB_MON_HADDR_HIGH_REG_OFFSET);
++ writel(hburst_reg_value, AHB_MON_USB + AHB_MON_HBURST_REG_OFFSET);
++ writel(hprot_reg_value, AHB_MON_USB + AHB_MON_HPROT_REG_OFFSET);
++
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_MAC + AHB_MON_MODE_REG_OFFSET);
++ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_MAC + AHB_MON_HWRITE_REG_OFFSET);
++ writel(0UL, AHB_MON_MAC + AHB_MON_HADDR_LOW_REG_OFFSET);
++ writel(~0UL, AHB_MON_MAC + AHB_MON_HADDR_HIGH_REG_OFFSET);
++ writel(hburst_reg_value, AHB_MON_MAC + AHB_MON_HBURST_REG_OFFSET);
++ writel(hprot_reg_value, AHB_MON_MAC + AHB_MON_HPROT_REG_OFFSET);
++
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_PCI + AHB_MON_MODE_REG_OFFSET);
++ writel(ahb_mon_hwrite << AHB_MON_HWRITE_COUNT_BIT, AHB_MON_PCI + AHB_MON_HWRITE_REG_OFFSET);
++ writel(0UL, AHB_MON_PCI + AHB_MON_HADDR_LOW_REG_OFFSET);
++ writel(~0UL, AHB_MON_PCI + AHB_MON_HADDR_HIGH_REG_OFFSET);
++ writel(hburst_reg_value, AHB_MON_PCI + AHB_MON_HBURST_REG_OFFSET);
++ writel(hprot_reg_value, AHB_MON_PCI + AHB_MON_HPROT_REG_OFFSET);
++
++ // Start all the counters
++ start_ahb_monitors();
++}
++
++void restart_ahb_monitors(void)
++{
++ // Reset the counters
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_D + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_I + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_A + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_B + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_LEON + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_USB + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_MAC + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_RESET << AHB_MON_MODE_MODE_BIT, AHB_MON_PCI + AHB_MON_MODE_REG_OFFSET);
++
++ // Start the counters
++ start_ahb_monitors();
++}
++
++void read_ahb_monitors(void)
++{
++ // Prepare the counters for reading
++ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_D + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_ARM_I + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_A + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_DMA_B + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_LEON + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_USB + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_MAC + AHB_MON_MODE_REG_OFFSET);
++ writel(AHB_MON_MODE_IDLE << AHB_MON_MODE_MODE_BIT, AHB_MON_PCI + AHB_MON_MODE_REG_OFFSET);
++
++ // Read the counters
++ printk("ARM-D: B=%u, T=%u, W=%u\n", readl(AHB_MON_ARM_D + AHB_MON_CYCLES_REG_OFFSET),
++ readl(AHB_MON_ARM_D + AHB_MON_TRANSFERS_REG_OFFSET),
++ readl(AHB_MON_ARM_D + AHB_MON_WAITS_REG_OFFSET));
++
++ printk("ARM-I: B=%u, T=%u, W=%u\n", readl(AHB_MON_ARM_I + AHB_MON_CYCLES_REG_OFFSET),
++ readl(AHB_MON_ARM_I + AHB_MON_TRANSFERS_REG_OFFSET),
++ readl(AHB_MON_ARM_I + AHB_MON_WAITS_REG_OFFSET));
++
++ printk("DMA-A: B=%u, T=%u, W=%u\n", readl(AHB_MON_DMA_A + AHB_MON_CYCLES_REG_OFFSET),
++ readl(AHB_MON_DMA_A + AHB_MON_TRANSFERS_REG_OFFSET),
++ readl(AHB_MON_DMA_A + AHB_MON_WAITS_REG_OFFSET));
++
++ printk("DMA-B: B=%u, T=%u, W=%u\n", readl(AHB_MON_DMA_B + AHB_MON_CYCLES_REG_OFFSET),
++ readl(AHB_MON_DMA_B + AHB_MON_TRANSFERS_REG_OFFSET),
++ readl(AHB_MON_DMA_B + AHB_MON_WAITS_REG_OFFSET));
++
++ printk("LEON: B=%u, T=%u, W=%u\n", readl(AHB_MON_LEON + AHB_MON_CYCLES_REG_OFFSET),
++ readl(AHB_MON_LEON + AHB_MON_TRANSFERS_REG_OFFSET),
++ readl(AHB_MON_LEON + AHB_MON_WAITS_REG_OFFSET));
++
++ printk("USB: B=%u, T=%u, W=%u\n", readl(AHB_MON_USB + AHB_MON_CYCLES_REG_OFFSET),
++ readl(AHB_MON_USB + AHB_MON_TRANSFERS_REG_OFFSET),
++ readl(AHB_MON_USB + AHB_MON_WAITS_REG_OFFSET));
++
++ printk("MAC: B=%u, T=%u, W=%u\n", readl(AHB_MON_MAC + AHB_MON_CYCLES_REG_OFFSET),
++ readl(AHB_MON_MAC + AHB_MON_TRANSFERS_REG_OFFSET),
++ readl(AHB_MON_MAC + AHB_MON_WAITS_REG_OFFSET));
++
++ printk("PCI: B=%u, T=%u, W=%u\n", readl(AHB_MON_PCI + AHB_MON_CYCLES_REG_OFFSET),
++ readl(AHB_MON_PCI + AHB_MON_TRANSFERS_REG_OFFSET),
++ readl(AHB_MON_PCI + AHB_MON_WAITS_REG_OFFSET));
++}
++#endif // CONFIG_OXNAS_AHB_MON
++
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/cipher.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/cipher.c
+--- linux-2.6.24/arch/arm/mach-oxnas/cipher.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/cipher.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,362 @@
++/* linux/arch/arm/mach-oxnas/cipher.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 <linux/types.h>
++#include <linux/sched.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/device.h>
++#include <linux/string.h>
++#include <linux/sysdev.h>
++#include <linux/highmem.h>
++#include <asm/semaphore.h>
++#include <asm/arch/cipher.h>
++#include <asm/io.h>
++#include <asm/arch/hardware.h>
++#include <linux/dma-mapping.h>
++#include <asm/arch/dma.h>
++#include <asm-arm/page.h>
++
++
++#if 0
++#define DPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
++#define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
++#else
++#define DPRINTK(fmt, args...)
++#define VPRINTK(fmt, args...)
++#endif
++
++//#define CIPHER_USE_SG_DMA
++
++/*****************************************************************************/
++
++typedef struct ox800_aeslrw_driver ox800_aeslrw_driver_t;
++
++struct ox800_aeslrw_driver {
++ struct device dev;
++ struct semaphore core;
++ int result;
++ u8 cipher_key[OX800DPE_KEYSIZE];
++ u8 tweak_key[OX800DPE_KEYSIZE];
++};
++
++static ox800_aeslrw_driver_t ox800_aeslrw_driver;
++
++
++/*****************************************************************************/
++
++/**
++ * Sets the keys only if they have changed.
++ * @param cipher_key 16 byte array that is the cipher key
++ * @param tweak_key 16 byte array that is the I-Value tweak key
++ */
++static void ox800_aeslrw_setkeys(u8* cipher_key, u8* tweak_key)
++{
++ VPRINTK(KERN_INFO"\n");
++
++ /*
++ * changing the keys can take a long time as the core will
++ * compute internal values based on the keys
++ */
++ if (memcmp(&(ox800_aeslrw_driver.cipher_key[0]), cipher_key, OX800DPE_KEYSIZE) ||
++ memcmp(&(ox800_aeslrw_driver.tweak_key[0]), tweak_key, OX800DPE_KEYSIZE) )
++ {
++ u32* key;
++ unsigned int i;
++
++ DPRINTK(KERN_INFO"cipher key =");
++ for (i = 0; i < OX800DPE_KEYSIZE; ++i)
++ DPRINTK("%02x", cipher_key[i]);
++ DPRINTK("\n");
++ DPRINTK(KERN_INFO"tweak key =");
++ for (i = 0; i < OX800DPE_KEYSIZE; ++i)
++ DPRINTK("%02x", tweak_key[i]);
++ DPRINTK("\n");
++
++ /* update stored values */
++ memcpy(&(ox800_aeslrw_driver.cipher_key[0]), cipher_key, OX800DPE_KEYSIZE);
++ memcpy(&(ox800_aeslrw_driver.tweak_key[0]), tweak_key, OX800DPE_KEYSIZE);
++
++ /* update hardware values */
++ key = (u32* )cipher_key;
++ writel(key[0], OX800DPE_KEY00 );
++ writel(key[1], OX800DPE_KEY01 );
++ writel(key[2], OX800DPE_KEY02 );
++ writel(key[3], OX800DPE_KEY03 );
++
++ key = (u32* )tweak_key;
++ writel(key[0], OX800DPE_KEY10 );
++ writel(key[1], OX800DPE_KEY11 );
++ writel(key[2], OX800DPE_KEY12 );
++ writel(key[3], OX800DPE_KEY13 );
++ }
++}
++
++/**
++ * Generic LRW-AES en/decryption
++ * @param encrypt non-zero to encrypt, zero to decrypt
++ * @param in Source of data
++ * @param out Location to place en/decrypted data
++ * @param nents Number of entries in scatter list, in and out must have the same
++ * number of entries
++ * @param iv 8 byte array containing the I-Value
++ * @return error code or 0 for success
++ */
++static int ox800_aeslrw_gencrypt( u8 encrypt,
++ struct scatterlist* in,
++ struct scatterlist* out,
++ unsigned int nents,
++ u8 iv[])
++{
++ oxnas_dma_channel_t* dma_in;
++ oxnas_dma_channel_t* dma_out;
++ struct scatterlist* out_;
++ char same_buffer;
++ int status = 0;
++
++ /* get dma resources (non blocking) */
++ dma_in = oxnas_dma_request(0);
++ dma_out = oxnas_dma_request(0);
++
++ VPRINTK("dma in %d out %d \n",
++ dma_in->channel_number_,
++ dma_out->channel_number_);
++
++ if ((dma_in) && (dma_out)) {
++ u32 reg;
++
++ // shouldn't be busy or full
++ reg = readl( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ printk("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ printk("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ printk("rx not empty after abort toggle");
++
++ /* check to see if the destination buffer is the same as the source */
++ same_buffer = (in->page == out->page);
++
++ /* map transfers */
++ if (same_buffer) {
++ dma_map_sg(NULL, in, nents, DMA_BIDIRECTIONAL);
++ out_ = in;
++ } else {
++ /* map transfers */
++ dma_map_sg(NULL, in, nents, DMA_TO_DEVICE);
++ dma_map_sg(NULL, out, nents, DMA_FROM_DEVICE);
++ out_ = out;
++ }
++#ifdef CIPHER_USE_SG_DMA
++ /* setup DMA transfers */
++ oxnas_dma_device_set_sg(
++ dma_in,
++ OXNAS_DMA_TO_DEVICE,
++ in,
++ nents,
++ &oxnas_dpe_rx_dma_settings,
++ OXNAS_DMA_MODE_INC);
++
++ oxnas_dma_device_set_sg(
++ dma_out,
++ OXNAS_DMA_FROM_DEVICE,
++ out_,
++ nents,
++ &oxnas_dpe_tx_dma_settings,
++ OXNAS_DMA_MODE_INC);
++
++#else
++ oxnas_dma_device_set(
++ dma_in,
++ OXNAS_DMA_TO_DEVICE,
++ (unsigned char* )sg_dma_address(in),
++ sg_dma_len(in),
++ &oxnas_dpe_rx_dma_settings,
++ OXNAS_DMA_MODE_INC,
++ 1 /*paused */ );
++
++ oxnas_dma_device_set(
++ dma_out,
++ OXNAS_DMA_FROM_DEVICE,
++ (unsigned char* )sg_dma_address(out_),
++ sg_dma_len(out_),
++ &oxnas_dpe_tx_dma_settings,
++ OXNAS_DMA_MODE_INC,
++ 1 /*paused */ );
++#endif
++
++ /* set dma callbacks */
++ oxnas_dma_set_callback(
++ dma_in,
++ OXNAS_DMA_CALLBACK_ARG_NUL,
++ OXNAS_DMA_CALLBACK_ARG_NUL);
++
++ oxnas_dma_set_callback(
++ dma_out,
++ OXNAS_DMA_CALLBACK_ARG_NUL,
++ OXNAS_DMA_CALLBACK_ARG_NUL);
++
++
++ /* set for AES LRW encryption or decryption */
++ writel( (encrypt ? OX800DPE_CTL_DIRECTION_ENC : 0 ) |
++ OX800DPE_CTL_MODE_LRW_AES,
++ OX800DPE_CONTROL);
++ wmb();
++
++ /* write in I-value */
++ writel(*((u32* )&(iv[0])), OX800DPE_DATA_LRW0 );
++ writel(*((u32* )&(iv[4])), OX800DPE_DATA_LRW1 );
++
++ wmb();
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & readl( OX800DPE_STATUS )) );
++
++ /* start dma */
++ oxnas_dma_start(dma_out);
++ oxnas_dma_start(dma_in);
++
++ /* wait (once for each channel) */
++ while ( oxnas_dma_is_active( dma_out ) ||
++ oxnas_dma_is_active( dma_in ) )
++ {
++ schedule();
++ }
++
++ /* free any allocated dma channels */
++ oxnas_dma_free( dma_in );
++ oxnas_dma_free( dma_out );
++
++ /* unmap transfers */
++ if (same_buffer) {
++ dma_unmap_sg(NULL, in, nents, DMA_BIDIRECTIONAL);
++ } else {
++ dma_unmap_sg(NULL, in, nents, DMA_TO_DEVICE);
++ dma_unmap_sg(NULL, out, nents, DMA_FROM_DEVICE);
++ }
++
++ status = ox800_aeslrw_driver.result;
++ } else {
++ /* free any allocated dma channels */
++ if (dma_in)
++ oxnas_dma_free( dma_in );
++ if (dma_out)
++ oxnas_dma_free( dma_out );
++ status = -EBUSY;
++ }
++ /* return an indication of success */
++ return status;
++}
++
++/**
++ * Performs LRW-AES encryption.
++ * @param in Source of data
++ * @param out Location to place encrypted data
++ * @param nents Number of entries in scatter list, in and out must have the same
++ * number of entries
++ * @param iv I-Value
++ * @param cipher_key 16 byte array that is the cipher key
++ * @param tweak_key 16 byte array that is the I-Value tweak key
++ * @return error code or 0 for success
++ */
++int ox800_aeslrw_encrypt( struct scatterlist* in,
++ struct scatterlist* out,
++ unsigned int nents,
++ u8* iv,
++ u8* cipher_key,
++ u8* tweak_key)
++{
++ int localresult;
++
++ VPRINTK(KERN_INFO"in %p, out %p, nents %d, iv %08x%08x, ckey %p, tkey %p\n",
++ in, out, nents, *((u32* )(&iv[4])), *((u32* )(&iv[0])), cipher_key, tweak_key );
++
++ /* get cipher core */
++ while( down_interruptible(&ox800_aeslrw_driver.core) ) ;
++
++ VPRINTK(KERN_INFO"got core\n");
++
++ ox800_aeslrw_setkeys(cipher_key, tweak_key);
++ localresult = ox800_aeslrw_gencrypt( 1, in, out, nents, iv);
++
++ up(&ox800_aeslrw_driver.core);
++ VPRINTK(KERN_INFO"released\n");
++
++ return localresult;
++}
++
++/**
++ * Performs LRW-AES decryption.
++ * @param in Source of data
++ * @param out Location to place decrypted data
++ * @param nents Number of entries in scatter list, in and out must have the same
++ * number of entries
++ * @param iv I-Value
++ * @param cipher_key 16 byte array that is the cipher key
++ * @param tweak_key 16 byte array that is the I-Value tweak key
++ * @return error code or 0 for success
++ */
++int ox800_aeslrw_decrypt( struct scatterlist* in,
++ struct scatterlist* out,
++ unsigned int nents,
++ u8* iv,
++ u8* cipher_key,
++ u8* tweak_key)
++{
++ int localresult;
++
++ VPRINTK(KERN_INFO"in %p, out %p, nents %d, iv %08x%08x, ckey %p, tkey%p\n",
++ in, out, nents, *((u32* )(&iv[4])), *((u32* )(&iv[0])), cipher_key, tweak_key );
++
++ /* get cipher core */
++ while( down_interruptible(&ox800_aeslrw_driver.core) ) ;
++
++ VPRINTK(KERN_INFO"got core\n");
++
++ ox800_aeslrw_setkeys(cipher_key, tweak_key);
++ localresult = ox800_aeslrw_gencrypt( 0, in, out, nents, iv);
++
++ up(&ox800_aeslrw_driver.core);
++ VPRINTK(KERN_INFO"released core \n");
++
++ return localresult;
++}
++
++/**
++ * module initialisation
++ * @return success is 0
++ */
++static int __init ox800_aeslrw_init( void )
++{
++ VPRINTK(KERN_INFO"\n");
++
++ /* Enable the clock to the DPE block */
++ writel(1UL << SYS_CTRL_CKEN_DPE_BIT, SYS_CTRL_CKEN_SET_CTRL);
++
++ /* Bring out of reset */
++ writel(1UL << SYS_CTRL_RSTEN_DPE_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
++
++ /* initialise in unlocked state */
++ init_MUTEX(&ox800_aeslrw_driver.core);
++
++ return 0;
++}
++
++/**
++ * module cleanup
++ */
++static void __exit ox800_aeslrw_exit( void )
++{
++}
++
++/**
++ * macros to register intiialisation and exit functions with kernal
++ */
++module_init(ox800_aeslrw_init);
++module_exit(ox800_aeslrw_exit);
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/dma.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/dma.c
+--- linux-2.6.24/arch/arm/mach-oxnas/dma.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/dma.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,2849 @@
++/*
++ * linux/arch/arm/mach-oxnas/dma.c
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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 <asm/dma.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/arch/hardware.h>
++#include <linux/bitops.h>
++#include <linux/dma-mapping.h>
++#include <linux/dmapool.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++#include <asm/arch/desc_alloc.h>
++
++#ifdef CONFIG_OXNAS_VERSION_0X800
++#include <asm/checksum.h>
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++//#define DMA_DEBUG
++
++#ifdef OXNAS_DMA_TEST
++#define DMA_DEBUG
++static void dma_test(unsigned long length);
++#endif // OXNAS_DMA_TEST
++
++#ifdef OXNAS_DMA_SG_TEST
++#define DMA_DEBUG
++static void dma_sg_test(void);
++#endif // OXNAS_DMA_SG_TEST
++
++#ifdef OXNAS_DMA_SG_TEST_2
++#define DMA_DEBUG
++static void dma_sg_test2(void);
++#endif // OXNAS_DMA_SG_TEST_2
++
++#ifdef DMA_DEBUG
++#define DBG(args...) printk(args)
++#else
++#define DBG(args...) do { } while(0)
++#endif
++
++// Normal (non-SG) registers
++#define DMA_REGS_PER_CHANNEL 8
++
++#define DMA_CTRL_STATUS 0x0
++#define DMA_BASE_SRC_ADR 0x4
++#define DMA_BASE_DST_ADR 0x8
++#define DMA_BYTE_CNT 0xC
++#define DMA_CURRENT_SRC_ADR 0x10
++#define DMA_CURRENT_DST_ADR 0x14
++#define DMA_CURRENT_BYTE_CNT 0x18
++#define DMA_INTR_ID 0x1C
++#define DMA_INTR_CLEAR_REG (DMA_CURRENT_SRC_ADR)
++
++// 8 quad-sized registers per channel arranged contiguously
++#define DMA_CALC_REG_ADR(channel, register) (DMA_BASE + ((channel) << 5) + (register))
++
++#define DMA_CTRL_STATUS_FAIR_SHARE_ARB (1 << 0)
++#define DMA_CTRL_STATUS_IN_PROGRESS (1 << 1)
++#define DMA_CTRL_STATUS_SRC_DREQ_MASK (0x0000003C)
++#define DMA_CTRL_STATUS_SRC_DREQ_SHIFT 2
++#define DMA_CTRL_STATUS_DEST_DREQ_MASK (0x000003C0)
++#define DMA_CTRL_STATUS_DEST_DREQ_SHIFT 6
++#define DMA_CTRL_STATUS_INTR (1 << 10)
++#define DMA_CTRL_STATUS_NXT_FREE (1 << 11)
++#define DMA_CTRL_STATUS_RESET (1 << 12)
++#define DMA_CTRL_STATUS_DIR_MASK (0x00006000)
++#define DMA_CTRL_STATUS_DIR_SHIFT 13
++#define DMA_CTRL_STATUS_SRC_ADR_MODE (1 << 15)
++#define DMA_CTRL_STATUS_DEST_ADR_MODE (1 << 16)
++#define DMA_CTRL_STATUS_TRANSFER_MODE_A (1 << 17)
++#define DMA_CTRL_STATUS_TRANSFER_MODE_B (1 << 18)
++#define DMA_CTRL_STATUS_SRC_WIDTH_MASK (0x00380000)
++#define DMA_CTRL_STATUS_SRC_WIDTH_SHIFT 19
++#define DMA_CTRL_STATUS_DEST_WIDTH_MASK (0x01C00000)
++#define DMA_CTRL_STATUS_DEST_WIDTH_SHIFT 22
++#define DMA_CTRL_STATUS_PAUSE (1 << 25)
++#define DMA_CTRL_STATUS_INTERRUPT_ENABLE (1 << 26)
++#define DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED (1 << 27)
++#define DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED (1 << 28)
++#define DMA_CTRL_STATUS_STARVE_LOW_PRIORITY (1 << 29)
++#define DMA_CTRL_STATUS_INTR_CLEAR_ENABLE (1 << 30)
++
++#define DMA_BYTE_CNT_MASK ((1 << 21) - 1)
++#define DMA_BYTE_CNT_INC4_SET_MASK (1 << 28)
++#define DMA_BYTE_CNT_HPROT_MASK (1 << 29)
++#define DMA_BYTE_CNT_WR_EOT_MASK (1 << 30)
++#define DMA_BYTE_CNT_RD_EOT_MASK (1 << 31)
++
++#define DMA_INTR_ID_GET_NUM_CHANNELS(reg_contents) (((reg_contents) >> 16) & 0xFF)
++#define DMA_INTR_ID_GET_VERSION(reg_contents) (((reg_contents) >> 24) & 0xFF)
++#define DMA_INTR_ID_INT_BIT 0
++#define DMA_INTR_ID_INT_NUM_BITS (MAX_OXNAS_DMA_CHANNELS)
++#define DMA_INTR_ID_INT_MASK (((1 << DMA_INTR_ID_INT_NUM_BITS) - 1) << DMA_INTR_ID_INT_BIT)
++
++#define DMA_HAS_V4_INTR_CLEAR(version) ((version) > 3)
++
++// H/W scatter gather controller registers
++#define OXNAS_DMA_NUM_SG_REGS 4
++
++#define DMA_SG_CONTROL 0x0
++#define DMA_SG_STATUS 0x04
++#define DMA_SG_REQ_PTR 0x08
++#define DMA_SG_RESETS 0x0C
++
++#define DMA_SG_CALC_REG_ADR(channel, register) ((DMA_SG_BASE) + ((channel) << 4) + (register))
++
++// SG DMA controller control register field definitions
++#define DMA_SG_CONTROL_START_BIT 0
++#define DMA_SG_CONTROL_QUEUING_ENABLE_BIT 1
++#define DMA_SG_CONTROL_HBURST_ENABLE_BIT 2
++
++// SG DMA controller status register field definitions
++#define DMA_SG_STATUS_ERROR_CODE_BIT 0
++#define DMA_SG_STATUS_ERROR_CODE_NUM_BITS 6
++#define DMA_SG_STATUS_BUSY_BIT 7
++
++// SG DMA controller sub-block resets register field definitions
++#define DMA_SG_RESETS_CONTROL_BIT 0
++#define DMA_SG_RESETS_ARBITER_BIT 1
++#define DMA_SG_RESETS_AHB_BIT 2
++
++// oxnas_dma_sg_info_t qualifier field definitions
++#define OXNAS_DMA_SG_QUALIFIER_BIT 0
++#define OXNAS_DMA_SG_QUALIFIER_NUM_BITS 16
++#define OXNAS_DMA_SG_DST_EOT_BIT 16
++#define OXNAS_DMA_SG_DST_EOT_NUM_BITS 2
++#define OXNAS_DMA_SG_SRC_EOT_BIT 20
++#define OXNAS_DMA_SG_SRC_EOT_NUM_BITS 2
++#define OXNAS_DMA_SG_CHANNEL_BIT 24
++#define OXNAS_DMA_SG_CHANNEL_NUM_BITS 8
++
++// Valid address bits mask
++#define OXNAS_DMA_ADR_MASK ((1UL << (MEM_MAP_ALIAS_SHIFT)) - 1)
++
++#ifdef CONFIG_OXNAS_VERSION_0X800
++#define OXNAS_DMA_CSUM_ADR_MASK ((OXNAS_DMA_ADR_MASK) | (1UL << (OXNAS_DMA_CSUM_ENABLE_ADR_BIT)))
++#else
++#define OXNAS_DMA_CSUM_ADR_MASK (OXNAS_DMA_ADR_MASK)
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++/* The available buses to which the DMA controller is attached */
++typedef enum oxnas_dma_transfer_bus
++{
++ OXNAS_DMA_SIDE_A,
++ OXNAS_DMA_SIDE_B
++} oxnas_dma_transfer_bus_t;
++
++/* Direction of data flow between the DMA controller's pair of interfaces */
++typedef enum oxnas_dma_transfer_direction
++{
++ OXNAS_DMA_A_TO_A,
++ OXNAS_DMA_B_TO_A,
++ OXNAS_DMA_A_TO_B,
++ OXNAS_DMA_B_TO_B
++} oxnas_dma_transfer_direction_t;
++
++/* The available data widths */
++typedef enum oxnas_dma_transfer_width
++{
++ OXNAS_DMA_TRANSFER_WIDTH_8BITS,
++ OXNAS_DMA_TRANSFER_WIDTH_16BITS,
++ OXNAS_DMA_TRANSFER_WIDTH_32BITS
++} oxnas_dma_transfer_width_t;
++
++/* The mode of the DMA transfer */
++typedef enum oxnas_dma_transfer_mode
++{
++ OXNAS_DMA_TRANSFER_MODE_SINGLE,
++ OXNAS_DMA_TRANSFER_MODE_BURST
++} oxnas_dma_transfer_mode_t;
++
++/* The available transfer targets */
++typedef enum oxnas_dma_dreq
++{
++ OXNAS_DMA_DREQ_PATA = 0,
++ OXNAS_DMA_DREQ_SATA = 0,
++ OXNAS_DMA_DREQ_DPE_RX = 1,
++ OXNAS_DMA_DREQ_DPE_TX = 2,
++ OXNAS_DMA_DREQ_AUDIO_TX = 5,
++ OXNAS_DMA_DREQ_AUDIO_RX = 6,
++ OXNAS_DMA_DREQ_MEMORY = 15
++} oxnas_dma_dreq_t;
++
++/* Pre-defined settings for known DMA devices */
++oxnas_dma_device_settings_t oxnas_pata_dma_settings = {
++ .address_ = 0,
++ .fifo_size_ = 16,
++ .dreq_ = OXNAS_DMA_DREQ_PATA,
++ .read_eot_policy_ = OXNAS_DMA_EOT_FINAL,
++ .write_eot_policy_ = OXNAS_DMA_EOT_FINAL,
++ .bus_ = OXNAS_DMA_SIDE_A,
++ .width_ = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
++ .transfer_mode_ = OXNAS_DMA_TRANSFER_MODE_BURST,
++ .address_mode_ = OXNAS_DMA_MODE_FIXED,
++ .address_really_fixed_ = 0
++};
++
++oxnas_dma_device_settings_t oxnas_sata_dma_settings = {
++ .address_ = SATA_DATA_BASE_PA,
++ .fifo_size_ = 16,
++ .dreq_ = OXNAS_DMA_DREQ_SATA,
++ .read_eot_policy_ = OXNAS_DMA_EOT_FINAL,
++ .write_eot_policy_ = OXNAS_DMA_EOT_FINAL,
++ .bus_ = OXNAS_DMA_SIDE_A,
++ .width_ = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
++ .transfer_mode_ = OXNAS_DMA_TRANSFER_MODE_BURST,
++ .address_mode_ = OXNAS_DMA_MODE_FIXED,
++ .address_really_fixed_ = 0
++};
++
++oxnas_dma_device_settings_t oxnas_dpe_rx_dma_settings = {
++ .address_ = DPE_BASE_PA,
++ .fifo_size_ = 16,
++ .dreq_ = OXNAS_DMA_DREQ_DPE_RX,
++ .read_eot_policy_ = OXNAS_DMA_EOT_FINAL,
++ .write_eot_policy_ = OXNAS_DMA_EOT_FINAL,
++ .bus_ = OXNAS_DMA_SIDE_A,
++ .width_ = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
++ .transfer_mode_ = OXNAS_DMA_TRANSFER_MODE_BURST,
++ .address_mode_ = OXNAS_DMA_MODE_FIXED,
++ .address_really_fixed_ = 0
++};
++
++oxnas_dma_device_settings_t oxnas_dpe_tx_dma_settings = {
++ .address_ = DPE_BASE_PA,
++ .fifo_size_ = 16,
++ .dreq_ = OXNAS_DMA_DREQ_DPE_TX,
++ .read_eot_policy_ = OXNAS_DMA_EOT_FINAL,
++ .write_eot_policy_ = OXNAS_DMA_EOT_FINAL,
++ .bus_ = OXNAS_DMA_SIDE_A,
++ .width_ = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
++ .transfer_mode_ = OXNAS_DMA_TRANSFER_MODE_BURST,
++ .address_mode_ = OXNAS_DMA_MODE_FIXED,
++ .address_really_fixed_ = 0
++};
++
++/* For use with normal memory to memory transfers as the settings for the source
++ * of the transfer */
++oxnas_dma_device_settings_t oxnas_ram_only_src_dma_settings = {
++ .address_ = 0,
++ .fifo_size_ = 0,
++ .dreq_ = OXNAS_DMA_DREQ_MEMORY,
++ .read_eot_policy_ = OXNAS_DMA_EOT_FINAL, // Won't interfere with checksumming transfers, as csum only latched if high order address bit set
++ .write_eot_policy_ = OXNAS_DMA_EOT_NONE,
++ .bus_ = OXNAS_DMA_SIDE_A, // Maximise performance with src on side A while dst in on side B
++ .width_ = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
++ .transfer_mode_ = OXNAS_DMA_TRANSFER_MODE_BURST,
++ .address_mode_ = OXNAS_DMA_MODE_FIXED,
++ .address_really_fixed_ = 1
++};
++
++#ifdef CONFIG_OXNAS_VERSION_0X800
++/* For use with checksumming transfers as the settings for the source of the
++ * transfer */
++oxnas_dma_device_settings_t oxnas_ram_csum_src_dma_settings = {
++ .address_ = 0,
++ .fifo_size_ = 0,
++ .dreq_ = OXNAS_DMA_DREQ_MEMORY,
++ .read_eot_policy_ = OXNAS_DMA_EOT_FINAL, // To enable checksum accumulation
++ .write_eot_policy_ = OXNAS_DMA_EOT_NONE,
++ .bus_ = OXNAS_DMA_SIDE_A, // Checksumming happens on read from side A only
++ .width_ = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
++ .transfer_mode_ = OXNAS_DMA_TRANSFER_MODE_BURST,
++ .address_mode_ = OXNAS_DMA_MODE_FIXED,
++ .address_really_fixed_ = 1
++};
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++/* For use in all occasions not covered by oxnas_ram_only_src_dma_settings and
++ * oxnas_ram_csum_src_dma_settings */
++oxnas_dma_device_settings_t oxnas_ram_generic_dma_settings = {
++ .address_ = 0,
++ .fifo_size_ = 0,
++ .dreq_ = OXNAS_DMA_DREQ_MEMORY,
++ .read_eot_policy_ = OXNAS_DMA_EOT_NONE, // Don't interfere with any checksumming transfers
++ .write_eot_policy_ = OXNAS_DMA_EOT_NONE,
++ .bus_ = OXNAS_DMA_SIDE_B,
++ .width_ = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
++ .transfer_mode_ = OXNAS_DMA_TRANSFER_MODE_BURST,
++ .address_mode_ = OXNAS_DMA_MODE_FIXED,
++ .address_really_fixed_ = 1
++};
++
++static oxnas_dma_controller_t dma_controller;
++
++/**
++ * Acquisition of a SG DMA descriptor list entry
++ * If called from non-atomic context the call could block.
++ */
++static oxnas_dma_sg_entry_t* alloc_sg_entry(int in_atomic)
++{
++ oxnas_dma_sg_entry_t* entry = 0;
++ if (in_atomic) {
++ if (down_trylock(&dma_controller.sg_entry_sem_)) {
++ return (oxnas_dma_sg_entry_t*)0;
++ }
++ } else {
++ // Wait for an entry to be available
++ while (down_interruptible(&dma_controller.sg_entry_sem_));
++ }
++
++ // Serialise while manipulating free list
++ spin_lock_bh(&dma_controller.alloc_spinlock_);
++
++ // It's an error if there isn't a buffer available at this point
++ BUG_ON(!dma_controller.sg_entry_head_);
++
++ // Unlink the head entry on the free list and return it to caller
++ entry = dma_controller.sg_entry_head_;
++ dma_controller.sg_entry_head_ = dma_controller.sg_entry_head_->next_;
++ --dma_controller.sg_entry_available_;
++
++ // Finished manipulating free list
++ spin_unlock_bh(&dma_controller.alloc_spinlock_);
++
++ return entry;
++}
++
++static void free_sg_entry(oxnas_dma_sg_entry_t* entry)
++{
++ // Serialise while manipulating free list
++ spin_lock(&dma_controller.alloc_spinlock_);
++
++ // Insert the freed buffer at the head of the free list
++ entry->next_ = dma_controller.sg_entry_head_;
++ dma_controller.sg_entry_head_ = entry;
++ ++dma_controller.sg_entry_available_;
++
++ // Finished manipulating free list
++ spin_unlock(&dma_controller.alloc_spinlock_);
++
++ // Make freed buffer available for allocation
++ up(&dma_controller.sg_entry_sem_);
++}
++
++void oxnas_dma_free_sg_entries(oxnas_dma_sg_entry_t* entries)
++{
++ while (entries) {
++ oxnas_dma_sg_entry_t* next = entries->next_;
++ free_sg_entry(entries);
++ entries = next;
++ }
++}
++
++/**
++ * This implementation is not the most efficient, as it could result in alot
++ * of alloc's only to decide to free them all as not sufficient available, but
++ * in practice we would hope there will not be much contention for entries
++ */
++int oxnas_dma_alloc_sg_entries(
++ oxnas_dma_sg_entry_t **entries,
++ unsigned required,
++ int in_atomic)
++{
++ if (likely(required)) {
++ oxnas_dma_sg_entry_t* prev;
++ oxnas_dma_sg_entry_t* entry;
++ unsigned acquired = 0;
++
++ *entries = alloc_sg_entry(in_atomic);
++ if (!*entries) {
++ return 1;
++ }
++
++ (*entries)->next_ = 0;
++ prev = *entries;
++
++ while (++acquired < required) {
++ entry = alloc_sg_entry(in_atomic);
++ if (!entry) {
++ // Did not acquire the entry
++ oxnas_dma_free_sg_entries(*entries);
++ return 1;
++ }
++ entry->next_ = 0;
++ prev->next_ = entry;
++ prev = entry;
++ }
++ }
++
++ return 0;
++}
++
++#ifdef CONFIG_OXNAS_VERSION_0X800
++/**
++ * Blocking acquisition of the checksum engine
++ */
++static inline int alloc_csum_engine(int in_atomic)
++{
++#ifdef CONFIG_LEON_RESERVE_DMA_CHANNEL
++ // Checksum engine is allocated exclusively to the CoPro
++ return 1;
++#else
++ if (in_atomic) {
++ return down_trylock(&dma_controller.csum_engine_sem_);
++ } else {
++ while (1) {
++ if (!down_interruptible(&dma_controller.csum_engine_sem_)) {
++ return 0;
++ }
++ }
++ }
++#endif // CONFIG_LEON_RESERVE_DMA_CHANNEL
++}
++
++static inline void free_csum_engine(void)
++{
++ up(&dma_controller.csum_engine_sem_);
++}
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++/**
++ * Optionally blocking acquisition of a DMA channel
++ * May be invoked either at task or softirq level
++ */
++oxnas_dma_channel_t* oxnas_dma_request(int block)
++{
++ oxnas_dma_channel_t* channel = OXNAS_DMA_CHANNEL_NUL;
++ while (channel == OXNAS_DMA_CHANNEL_NUL) {
++ if (block) {
++ // Wait for a channel to be available
++ if (down_interruptible(&dma_controller.channel_sem_)) {
++ // Awoken by signal
++ continue;
++ }
++ } else {
++ // Non-blocking test of whether a channel is available
++ if (down_trylock(&dma_controller.channel_sem_)) {
++ // No channel available so return to user immediately
++ break;
++ }
++ }
++
++ // Serialise while manipulating free list
++ spin_lock_bh(&dma_controller.channel_alloc_spinlock_);
++
++ // It's an error if there isn't a channel available at this point
++ BUG_ON(!dma_controller.channel_head_);
++
++ // Unlink the head entry on the free list and return it to caller
++ channel = dma_controller.channel_head_;
++ dma_controller.channel_head_ = dma_controller.channel_head_->next_;
++
++ // Finished manipulating free list
++ spin_unlock_bh(&dma_controller.channel_alloc_spinlock_);
++ }
++ return channel;
++}
++
++/**
++ * May be invoked either at task or softirq level
++ */
++void oxnas_dma_free(oxnas_dma_channel_t* channel)
++{
++ if (oxnas_dma_is_active(channel)) {
++ printk(KERN_WARNING "oxnas_dma_free() Freeing channel %u while active\n", channel->channel_number_);
++ }
++
++ // Serialise while manipulating free list
++ spin_lock_bh(&dma_controller.channel_alloc_spinlock_);
++
++ // Insert the freed buffer at the head of the free list
++ channel->next_ = dma_controller.channel_head_;
++ dma_controller.channel_head_ = channel;
++
++ // Finished manipulating free list
++ spin_unlock_bh(&dma_controller.channel_alloc_spinlock_);
++
++ // Make freed buffer available for allocation
++ up(&dma_controller.channel_sem_);
++}
++
++/** Shared between all DMA interrupts and run with interrupts enabled, thus any
++ * access to shared data structures must be sync'ed
++ */
++static irqreturn_t oxnas_dma_interrupt(int irq, void *dev_id)
++{
++ oxnas_dma_channel_t *channel = 0;
++ unsigned channel_number = 0;
++ int need_bh = 0;
++
++DBG("oxnas_dma_interrupt() from interrupt line %u\n", irq);
++
++ // Only acknowledge interrupts from the channel directly responsible for the
++ // RPS interrupt line which caused the ISR to be entered, to get around the
++ // problem that the SG-DMA controller can only filter DMA interrupts exter-
++ // nally to the DMA controller, i.e. the DMA controller interrupt status
++ // register always shows all active interrupts for all channels, regardless
++ // of whether the SG-DMA controller is filtering them
++
++ // Find the DMA channel that can generate interrupts on the RPS interrupt
++ // line which caused the ISR to be invoked.
++ if (likely(irq == DMA_INTERRUPT_4)) {
++ channel = &dma_controller.channels_[4];
++ } else {
++ channel = &dma_controller.channels_[irq - DMA_INTERRUPT_0];
++ }
++ channel_number = channel->channel_number_;
++DBG("RPS interrupt %u from channel %u\n", irq, channel_number);
++
++ // Non-SG transfers have no completion status, so initialise
++ // channel's error code to no-error. If transfer turns out to
++ // have been SG, this status will be overwritten
++ channel->error_code_ = OXNAS_DMA_ERROR_CODE_NONE;
++
++ // Must finish in bottom half if checksumming or need to invoke callback
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ need_bh = channel->checksumming_ ||
++#else // CONFIG_OXNAS_VERSION_0X800
++ need_bh =
++#endif // CONFIG_OXNAS_VERSION_0X800
++ (channel->notification_callback_ != OXNAS_DMA_CALLBACK_NUL);
++
++ // Cope with the DMA controller's ability to have a pair of chained
++ // transfers which have both completed, which causes the interrupt request
++ // to stay active until both have been acknowledged, which is causing the SG
++ // controller problems
++ while (readl(DMA_CALC_REG_ADR(0, DMA_INTR_ID)) & (1 << channel_number)) {
++DBG("Ack'ing interrupt for channel %u\n", channel_number);
++ // Write to the interrupt clear register to clear interrupt
++ writel(0, DMA_CALC_REG_ADR(channel_number, DMA_INTR_CLEAR_REG));
++
++ // Record how many interrupts are awaiting service
++ atomic_inc(&channel->interrupt_count_);
++ }
++DBG("Left int ack'ing loop\n");
++
++ // If was a SG transfer, record the completion status
++ if (channel->v_sg_info_->v_srcEntries_) {
++ // Record the SG transfer completion status
++ u32 error_code = readl(DMA_SG_CALC_REG_ADR(channel_number, DMA_SG_STATUS));
++ channel->error_code_ =
++ ((error_code >> DMA_SG_STATUS_ERROR_CODE_BIT) &
++ ((1UL << DMA_SG_STATUS_ERROR_CODE_NUM_BITS) - 1));
++
++ if (channel->auto_sg_entries_) {
++ // Must finish in bottom half if we are to manage the SG entries
++DBG("ISR channel %d is auto SG\n", channel->channel_number_);
++ need_bh = 1;
++ } else {
++DBG("ISR channel %d not auto SG\n", channel->channel_number_);
++ // Zeroise SG DMA descriptor info
++ channel->v_sg_info_->p_srcEntries_ = 0;
++ channel->v_sg_info_->v_srcEntries_ = 0;
++ channel->v_sg_info_->p_dstEntries_ = 0;
++ channel->v_sg_info_->v_dstEntries_ = 0;
++ }
++
++DBG("Return SG controller to idle, error_code = 0x%08x\n", error_code);
++ // Return the SG DMA controller to the IDLE state and clear any SG
++ // controller error interrupt
++ writel(1, DMA_SG_CALC_REG_ADR(channel_number, DMA_SG_STATUS));
++ }
++
++ // Can we finish w/o invoking bottom half?
++ if (likely(!need_bh)) {
++DBG("ISR channel %d do not call bh\n", channel->channel_number_);
++ atomic_set(&channel->interrupt_count_, 0);
++ atomic_set(&channel->active_count_, 0);
++ } else {
++DBG("Marking channel %d as requiring its bottom half to run\n", channel_number);
++ // Set a flag for the channel to cause its bottom half to be run
++ set_bit(channel_number, (void*)&dma_controller.run_bh_);
++
++DBG("Scheduling tasklet\n");
++ // Signal the bottom half to perform the notifications
++ tasklet_schedule(&dma_controller.tasklet_);
++ }
++
++DBG("Returning\n");
++ return IRQ_HANDLED;
++}
++
++static void fake_interrupt(int channel)
++{
++ // Set a flag to cause the bottom half handler to be run for the channel
++ set_bit(channel, (void*)&dma_controller.run_bh_);
++
++ // Signal the bottom half to perform the notifications
++ tasklet_schedule(&dma_controller.tasklet_);
++}
++
++static void dma_bh(unsigned long data)
++{
++ // Check for any bottom halves having become ready to run
++ u32 run_bh = atomic_read(&dma_controller.run_bh_);
++ while (run_bh) {
++ unsigned i;
++
++ // Free any checksumming or SG resources
++ u32 temp_run_bh = run_bh;
++ for (i = 0; i < dma_controller.numberOfChannels_; i++, temp_run_bh >>= 1) {
++ if (temp_run_bh & 1) {
++ oxnas_dma_channel_t* channel = &dma_controller.channels_[i];
++DBG("Bottom halve for channel %u\n", channel->channel_number_);
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ // If this channel computed a checksum
++ if (unlikely(channel->checksumming_)) {
++ // Read the result of the checksum calculation, clearing the
++ // result in the process
++ channel->checksum_ = readl(DMA_CHECKSUM_BASE);
++ channel->checksumming_ = 0;
++
++ // Relinquish ownership of the checksum engine
++ free_csum_engine();
++ }
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++ if (channel->auto_sg_entries_) {
++ // Free SG DMA source descriptor resources
++ oxnas_dma_sg_entry_t* sg_entry = channel->v_sg_info_->v_srcEntries_;
++DBG("Freeing SG resources for channel %d\n", channel->channel_number_);
++ while (sg_entry) {
++ oxnas_dma_sg_entry_t* next = sg_entry->v_next_;
++ free_sg_entry(sg_entry);
++ sg_entry = next;
++ }
++
++ // Free SG DMA destination descriptor resources
++ sg_entry = channel->v_sg_info_->v_dstEntries_;
++ while (sg_entry) {
++ oxnas_dma_sg_entry_t* next = sg_entry->v_next_;
++ free_sg_entry(sg_entry);
++ sg_entry = next;
++ }
++
++ // Zeroise SG DMA source descriptor info
++ channel->v_sg_info_->p_srcEntries_ = 0;
++ channel->v_sg_info_->v_srcEntries_ = 0;
++ channel->v_sg_info_->p_dstEntries_ = 0;
++ channel->v_sg_info_->v_dstEntries_ = 0;
++ }
++ }
++ }
++
++ // Mark that we have serviced the bottom halves. None of the channels
++ // we have just serviced can interrupt again until their active flags
++ // are cleared below
++ atomic_sub(run_bh, &dma_controller.run_bh_);
++
++ // Notify all listeners of transfer completion
++ for (i = 0; i < dma_controller.numberOfChannels_; i++, run_bh >>= 1) {
++ if (run_bh & 1) {
++ int interrupt_count;
++ oxnas_dma_channel_t* channel = &dma_controller.channels_[i];
++
++ // Clear the count of received interrupts for the channel now
++ // that we have serviced them all
++ interrupt_count = atomic_read(&channel->interrupt_count_);
++ atomic_sub(interrupt_count, &channel->interrupt_count_);
++
++ // Decrement the count of active transfers, by the number of
++ // interrupts we've seen. This must occur before we inform any
++ // listeners who are awaiting completion notification. Should
++ // only decrement if greater than zero, in case we see spurious
++ // interrupt events - we can't be fully safe against this sort
++ // of broken h/w, but we can at least stop the count underflowing
++ // active_count_ is only shared with thread level code, so read
++ // and decrement don't need to be atomic
++ if (atomic_read(&channel->active_count_)) {
++ atomic_dec(&channel->active_count_);
++ }
++
++ // If there is a callback registered, notify the user that the
++ // transfer is complete
++ if (channel->notification_callback_ != OXNAS_DMA_CALLBACK_NUL) {
++DBG("Notifying channel %u, %d outstanding interrupts\n", channel->channel_number_, interrupt_count);
++ (*channel->notification_callback_)(
++ &dma_controller.channels_[i],
++ channel->notification_arg_,
++ channel->error_code_,
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ channel->checksum_,
++#else // CONFIG_OXNAS_VERSION_0X800
++ 0,
++#endif // CONFIG_OXNAS_VERSION_0X800
++ interrupt_count);
++ }
++ }
++ }
++
++ // Check for any more bottom halves having become ready to run
++ run_bh = atomic_read(&dma_controller.run_bh_);
++ }
++}
++
++void __init oxnas_dma_init()
++{
++ unsigned i;
++ unsigned long intId;
++ oxnas_dma_sg_info_t *v_info;
++ dma_addr_t p_info;
++
++ // Ensure the DMA block is properly reset
++ writel(1UL << SYS_CTRL_RSTEN_DMA_BIT, SYS_CTRL_RSTEN_SET_CTRL);
++ writel(1UL << SYS_CTRL_RSTEN_DMA_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
++
++ // Ensure the SG-DMA block is properly reset
++ writel(1UL << SYS_CTRL_RSTEN_SGDMA_BIT, SYS_CTRL_RSTEN_SET_CTRL);
++ writel(1UL << SYS_CTRL_RSTEN_SGDMA_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
++
++ // Enable the clock to the DMA block
++ writel(1UL << SYS_CTRL_CKEN_DMA_BIT, SYS_CTRL_CKEN_SET_CTRL);
++
++ // Initialise the DMA controller
++ atomic_set(&dma_controller.run_bh_, 0);
++ spin_lock_init(&dma_controller.spinlock_);
++ spin_lock_init(&dma_controller.alloc_spinlock_);
++ spin_lock_init(&dma_controller.channel_alloc_spinlock_);
++ sema_init(&dma_controller.csum_engine_sem_, 1);
++
++ // Initialise channel allocation management
++ dma_controller.channel_head_ = 0;
++ sema_init(&dma_controller.channel_sem_, 0);
++ // Initialise SRAM buffer management
++ dma_controller.sg_entry_head_ = 0;
++ sema_init(&dma_controller.sg_entry_sem_, 0);
++ dma_controller.sg_entry_available_ = 0;
++
++ tasklet_init(&dma_controller.tasklet_, dma_bh, 0);
++
++ // Discover the number of channels available
++ intId = readl(DMA_CALC_REG_ADR(0, DMA_INTR_ID));
++ dma_controller.numberOfChannels_ = DMA_INTR_ID_GET_NUM_CHANNELS(intId);
++ if (dma_controller.numberOfChannels_ > MAX_OXNAS_DMA_CHANNELS) {
++ printk(KERN_WARNING "DMA: Too many DMA channels");
++ dma_controller.numberOfChannels_ = MAX_OXNAS_DMA_CHANNELS;
++ }
++
++ dma_controller.version_ = DMA_INTR_ID_GET_VERSION(intId);
++ printk(KERN_INFO "Number of DMA channels = %u, version = %u\n",
++ dma_controller.numberOfChannels_, dma_controller.version_);
++
++ if (!DMA_HAS_V4_INTR_CLEAR(dma_controller.version_)) {
++ panic("DMA: Trying to use v4+ interrupt clearing on DMAC version without support\n");
++ }
++
++#ifdef CONFIG_LEON_RESERVE_DMA_CHANNEL
++ // Reserve the last DMA channel for the CoPro's use
++ --dma_controller.numberOfChannels_;
++#endif // CONFIG_LEON_RESERVE_DMA_CHANNEL
++
++ // Allocate coherent memory for array sg_info structs
++ dma_controller.v_sg_infos_ = (oxnas_dma_sg_info_t*)DMA_DESC_ALLOC_START;
++ dma_controller.p_sg_infos_ = DMA_DESC_ALLOC_START_PA;
++
++ if (!dma_controller.v_sg_infos_) {
++ panic("DMA: Coherent alloc of SG info struct array");
++ }
++
++ {
++ // Initialise list of DMA descriptors
++ unsigned long sg_info_alloc_size = (dma_controller.numberOfChannels_ * sizeof(oxnas_dma_sg_info_t));
++ unsigned num_sg_entries = (DMA_DESC_ALLOC_SIZE - sg_info_alloc_size) / sizeof(oxnas_dma_sg_entry_t);
++ oxnas_dma_sg_entry_t* entry_v = (oxnas_dma_sg_entry_t*)(DMA_DESC_ALLOC_START + sg_info_alloc_size);
++ oxnas_dma_sg_entry_t* entry_p = (oxnas_dma_sg_entry_t*)(DMA_DESC_ALLOC_START_PA + sg_info_alloc_size);
++printk("Allocating %u SRAM generic DMA descriptors\n", num_sg_entries);
++ for (i=0; i < num_sg_entries; ++i, ++entry_v, ++entry_p) {
++ entry_v->paddr_ = (dma_addr_t)entry_p;
++ free_sg_entry(entry_v);
++ }
++ }
++
++ // Initialise all available DMA channels
++ v_info = dma_controller.v_sg_infos_;
++ p_info = dma_controller.p_sg_infos_;
++ for (i=0; i < dma_controller.numberOfChannels_; i++) {
++ oxnas_dma_channel_t *channel = &dma_controller.channels_[i];
++
++ channel->channel_number_ = i;
++ channel->notification_callback_ = OXNAS_DMA_CALLBACK_NUL;
++ channel->notification_arg_ = OXNAS_DMA_CALLBACK_ARG_NUL;
++
++ // Setup physical and virtual addresses of the SG info struct for this
++ // channel
++ channel->v_sg_info_ = v_info++;
++ channel->p_sg_info_ = p_info;
++ p_info += sizeof(oxnas_dma_sg_info_t);
++
++ // Initialise heads of src and dst SG lists to null
++ channel->v_sg_info_->p_srcEntries_ = 0;
++ channel->v_sg_info_->p_dstEntries_ = 0;
++ channel->v_sg_info_->v_srcEntries_ = 0;
++ channel->v_sg_info_->v_dstEntries_ = 0;
++
++ channel->error_code_ = 0;
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ channel->checksumming_ = 0;
++ channel->checksum_ = 0;
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++ // Initialise the atomic variable that records the number of interrupts
++ // for the channel that are awaiting service
++ atomic_set(&channel->interrupt_count_, 0);
++
++ // Initialise the atomic variable maintaining the count of in-progress
++ // transfers for the channel. Currently can be a maximum of two, as
++ // the hardware can only queue details for a pair of transfers
++ atomic_set(&channel->active_count_, 0);
++
++ // The binary semaphore for the default callback used when abort
++ // requested without a user-registered callback being available
++ sema_init(&channel->default_semaphore_, 0);
++
++ // Add channel to free list
++ oxnas_dma_free(channel);
++ }
++
++ // Connect the dma interrupt handler
++ dma_controller.channels_[0].rps_interrupt_ = DMA_INTERRUPT_0;
++ if (request_irq(DMA_INTERRUPT_0, &oxnas_dma_interrupt, 0, "DMA 0", 0)) {
++ panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_0);
++ }
++ dma_controller.channels_[1].rps_interrupt_ = DMA_INTERRUPT_1;
++ if (request_irq(DMA_INTERRUPT_1, &oxnas_dma_interrupt, 0, "DMA 1", 0)) {
++ panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_1);
++ }
++ dma_controller.channels_[2].rps_interrupt_ = DMA_INTERRUPT_2;
++ if (request_irq(DMA_INTERRUPT_2, &oxnas_dma_interrupt, 0, "DMA 2", 0)) {
++ panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_2);
++ }
++ dma_controller.channels_[3].rps_interrupt_ = DMA_INTERRUPT_3;
++ if (request_irq(DMA_INTERRUPT_3, &oxnas_dma_interrupt, 0, "DMA 3", 0)) {
++ panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_3);
++ }
++#ifndef CONFIG_LEON_RESERVE_DMA_CHANNEL
++ dma_controller.channels_[4].rps_interrupt_ = DMA_INTERRUPT_4;
++ if (request_irq(DMA_INTERRUPT_4, &oxnas_dma_interrupt, 0, "DMA 4", 0)) {
++ panic("DMA: Failed to allocate interrupt %u\n", DMA_INTERRUPT_4);
++ }
++#endif // CONFIG_LEON_RESERVE_DMA_CHANNEL
++
++#ifdef OXNAS_DMA_OVERALL_TEST_LOOPS
++ {
++ int j;
++ for (j=0; j < OXNAS_DMA_OVERALL_TEST_LOOPS; ++j) {
++#ifdef OXNAS_DMA_TEST
++ {
++ int i;
++ for (i=0; i < OXNAS_DMA_TEST_ITERATIONS; ++i) {
++ dma_test(512);
++ }
++ }
++#endif // OXNAS_DMA_TEST
++#ifdef OXNAS_DMA_SG_TEST
++ {
++ int i;
++ for (i=0; i < OXNAS_DMA_SG_TEST_ITERATIONS; ++i) {
++ dma_sg_test();
++ }
++ }
++#endif // OXNAS_DMA_SG_TEST
++#ifdef OXNAS_DMA_SG_TEST_2
++ {
++ int i;
++ for (i=0; i < OXNAS_DMA_SG_TEST_ITERATIONS; ++i) {
++ dma_sg_test2();
++ }
++ }
++#endif // OXNAS_DMA_SG_TEST_2
++#ifdef OXNAS_DMA_TEST
++ {
++ int i;
++ for (i=0; i < OXNAS_DMA_TEST_AFTER_SG_ITERATIONS; ++i) {
++ dma_test(512);
++ }
++ }
++#endif // OXNAS_DMA_TEST
++ }
++ }
++#endif // OXNAS_DMA_OVERALL_TEST_LOOPS
++}
++
++void oxnas_dma_shutdown()
++{
++ dma_controller.sg_entry_head_ = 0;
++}
++
++int oxnas_dma_is_active(oxnas_dma_channel_t* channel)
++{
++ return atomic_read(&channel->active_count_);
++}
++
++/**
++ * Get the transfer status directly from the hardware, so for instance the
++ * end of a transfer can be polled for within interrupt context.
++ *
++ * NB If this function indicates the channel is inactive, it does NOT imply that
++ * it can be reused. Reuse is only possible when oxnas_dma_is_active() returns
++ * the inactive state
++ */
++int oxnas_dma_raw_isactive(oxnas_dma_channel_t* channel)
++{
++ unsigned long ctrl_status = readl(DMA_CALC_REG_ADR(channel->channel_number_, DMA_CTRL_STATUS));
++ return ctrl_status & DMA_CTRL_STATUS_IN_PROGRESS;
++}
++
++/**
++ * Get the SG transfer status directly from the hardware, so for instance the
++ * end of a SG transfer can be polled for within interrupt context.
++ *
++ * NB If this function indicates the channel is inactive, it does NOT imply that
++ * it can be reused. Reuse is only possible when oxnas_dma_is_active() returns
++ * the inactive state
++ */
++int oxnas_dma_raw_sg_isactive(oxnas_dma_channel_t* channel)
++{
++ // Record the SG channel status
++ u32 status = readl(DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_STATUS));
++ return status & (1UL << DMA_SG_STATUS_BUSY_BIT);
++}
++
++int oxnas_dma_get_raw_direction(oxnas_dma_channel_t* channel)
++{
++ unsigned long ctrl_status = readl(DMA_CALC_REG_ADR(channel->channel_number_, DMA_CTRL_STATUS));
++ return (ctrl_status & DMA_CTRL_STATUS_DIR_MASK) >> DMA_CTRL_STATUS_DIR_SHIFT;
++}
++
++static unsigned long encode_control_status(
++ oxnas_dma_device_settings_t *src_settings,
++ oxnas_dma_device_settings_t *dst_settings,
++ int paused)
++{
++ unsigned long ctrl_status;
++ oxnas_dma_transfer_direction_t direction;
++
++ ctrl_status = paused ? DMA_CTRL_STATUS_PAUSE : 0; // Paused if requested
++ ctrl_status |= (DMA_CTRL_STATUS_INTERRUPT_ENABLE | // Interrupts enabled
++ DMA_CTRL_STATUS_FAIR_SHARE_ARB | // High priority
++ DMA_CTRL_STATUS_INTR_CLEAR_ENABLE); // Use new interrupt clearing register
++ ctrl_status |= (src_settings->dreq_ << DMA_CTRL_STATUS_SRC_DREQ_SHIFT); // Source dreq
++ ctrl_status |= (dst_settings->dreq_ << DMA_CTRL_STATUS_DEST_DREQ_SHIFT); // Destination dreq
++
++ // Setup the transfer direction and burst/single mode for the two DMA busses
++ if (src_settings->bus_ == OXNAS_DMA_SIDE_A) {
++ // Set the burst/single mode for bus A based on src device's settings
++ if (src_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
++ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_A;
++ } else {
++ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_A;
++ }
++
++ if (dst_settings->bus_ == OXNAS_DMA_SIDE_A) {
++ direction = OXNAS_DMA_A_TO_A;
++ } else {
++ direction = OXNAS_DMA_A_TO_B;
++
++ // Set the burst/single mode for bus B based on dst device's settings
++ if (dst_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
++ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_B;
++ } else {
++ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_B;
++ }
++ }
++ } else {
++ // Set the burst/single mode for bus B based on src device's settings
++ if (src_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
++ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_B;
++ } else {
++ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_B;
++ }
++
++ if (dst_settings->bus_ == OXNAS_DMA_SIDE_A) {
++ direction = OXNAS_DMA_B_TO_A;
++
++ // Set the burst/single mode for bus A based on dst device's settings
++ if (dst_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
++ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_A;
++ } else {
++ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_A;
++ }
++ } else {
++ direction = OXNAS_DMA_B_TO_B;
++ }
++ }
++ ctrl_status |= (direction << DMA_CTRL_STATUS_DIR_SHIFT);
++
++ // Setup source address mode fixed or increment
++ if (src_settings->address_mode_ == OXNAS_DMA_MODE_FIXED) {
++ // Fixed address
++ ctrl_status &= ~(DMA_CTRL_STATUS_SRC_ADR_MODE);
++
++ // Set up whether fixed address is _really_ fixed
++ if (src_settings->address_really_fixed_) {
++ ctrl_status |= DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
++ } else {
++ ctrl_status &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
++ }
++ } else {
++ // Incrementing address
++ ctrl_status |= DMA_CTRL_STATUS_SRC_ADR_MODE;
++ ctrl_status &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
++ }
++
++ // Setup destination address mode fixed or increment
++ if (dst_settings->address_mode_ == OXNAS_DMA_MODE_FIXED) {
++ // Fixed address
++ ctrl_status &= ~(DMA_CTRL_STATUS_DEST_ADR_MODE);
++
++ // Set up whether fixed address is _really_ fixed
++ if (dst_settings->address_really_fixed_) {
++ ctrl_status |= DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
++ } else {
++ ctrl_status &= ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
++ }
++ } else {
++ // Incrementing address
++ ctrl_status |= DMA_CTRL_STATUS_DEST_ADR_MODE;
++ ctrl_status &= ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
++ }
++
++ // Set up the width of the transfers on the DMA buses
++ ctrl_status |= (src_settings->width_ << DMA_CTRL_STATUS_SRC_WIDTH_SHIFT);
++ ctrl_status |= (dst_settings->width_ << DMA_CTRL_STATUS_DEST_WIDTH_SHIFT);
++
++ // Setup the priority arbitration scheme
++ ctrl_status &= ~DMA_CTRL_STATUS_STARVE_LOW_PRIORITY; // !Starve low priority
++
++ return ctrl_status;
++}
++
++static unsigned long encode_eot(
++ oxnas_dma_device_settings_t* src_settings,
++ oxnas_dma_device_settings_t* dst_settings,
++ unsigned long length,
++ int isFinalTransfer)
++{
++ // Write the length, with EOT configuration and enable INC4 tranfers and
++ // HPROT. HPROT will delay data reaching memory for a few clock cycles, but
++ // most unlikely to cause a problem for the CPU.
++ unsigned long encoded = length |
++ DMA_BYTE_CNT_INC4_SET_MASK | // Always enable INC4 transfers
++ DMA_BYTE_CNT_HPROT_MASK; // Always enable HPROT assertion
++
++ // Encode the EOT setting for the src device based on its policy
++ encoded &= ~DMA_BYTE_CNT_RD_EOT_MASK;
++ switch (src_settings->read_eot_policy_) {
++ case OXNAS_DMA_EOT_FINAL:
++ if (!isFinalTransfer) {
++ break;
++ }
++ // Fall through in case of final transfer and EOT required for final
++ // transfer
++ case OXNAS_DMA_EOT_ALL:
++ encoded |= DMA_BYTE_CNT_RD_EOT_MASK;
++ break;
++ default:
++ break;
++ }
++
++ // Encode the EOT setting for the dst device based on its policy
++ encoded &= ~DMA_BYTE_CNT_WR_EOT_MASK;
++ switch (dst_settings->write_eot_policy_) {
++ case OXNAS_DMA_EOT_FINAL:
++ if (!isFinalTransfer) {
++ break;
++ }
++ // Fall through in case of final transfer and EOT required for final
++ // transfer
++ case OXNAS_DMA_EOT_ALL:
++ encoded |= DMA_BYTE_CNT_WR_EOT_MASK;
++ break;
++ default:
++ break;
++ }
++
++ return encoded;
++}
++
++static unsigned long encode_start(unsigned long ctrl_status)
++{
++ ctrl_status &= ~DMA_CTRL_STATUS_PAUSE;
++ return ctrl_status;
++}
++
++static void oxnas_dma_set_common_lowlevel(
++ oxnas_dma_channel_t *channel,
++ unsigned long ctrl_status,
++ dma_addr_t src_address,
++ dma_addr_t dst_address,
++ unsigned long lengthAndEOT)
++{
++ unsigned channel_number = channel->channel_number_;
++
++ spin_lock(&dma_controller.spinlock_);
++
++ // Write the control/status value to the DMAC
++ writel(ctrl_status, DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
++
++ // Ensure control/status word makes it to the DMAC before we write address/length info
++ wmb();
++
++ // Write the source addresses to the DMAC
++ writel(src_address, DMA_CALC_REG_ADR(channel_number, DMA_BASE_SRC_ADR));
++
++ // Write the destination addresses to the DMAC
++ writel(dst_address, DMA_CALC_REG_ADR(channel_number, DMA_BASE_DST_ADR));
++
++ // Write the length, with EOT configuration for the single transfer
++ writel(lengthAndEOT, DMA_CALC_REG_ADR(channel_number, DMA_BYTE_CNT));
++
++ // Ensure adr/len info makes it to DMAC before later modifications to
++ // control/status register due to starting the transfer, which happens in
++ // oxnas_dma_start()
++ wmb();
++
++ spin_unlock(&dma_controller.spinlock_);
++
++ // Increase count of in-progress transfers on this channel
++ atomic_inc(&channel->active_count_);
++}
++
++static int oxnas_dma_set_common(
++ oxnas_dma_channel_t* channel,
++ unsigned long length,
++ oxnas_dma_device_settings_t *src_settings,
++ oxnas_dma_device_settings_t *dst_settings,
++ int isFinalTransfer,
++ int paused)
++{
++ int status = 0;
++
++ if (length > MAX_OXNAS_DMA_TRANSFER_LENGTH) {
++ printk(KERN_WARNING "oxnas_dma_set_common() length exceeds hardware allowed maximum\n");
++ status = 1;
++ } else {
++ oxnas_dma_set_common_lowlevel(
++ channel,
++ encode_control_status(src_settings, dst_settings, paused),
++ (dma_addr_t)src_settings->address_,
++ (dma_addr_t)dst_settings->address_,
++ encode_eot(src_settings, dst_settings, length, isFinalTransfer));
++ }
++ return status;
++}
++
++int oxnas_dma_set(
++ oxnas_dma_channel_t *channel,
++ unsigned char *src_adr, // Physical address
++ unsigned long length,
++ unsigned char *dst_adr, // Physical address
++ oxnas_dma_mode_t src_mode,
++ oxnas_dma_mode_t dst_mode,
++ int do_checksum,
++ int paused)
++{
++ if (oxnas_dma_is_active(channel)) {
++ printk(KERN_WARNING "oxnas_dma_set() Trying to use channel %u while active\n", channel->channel_number_);
++ }
++
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ if (do_checksum) {
++ // Arbitrate for ownership of the checksum engine
++ if (alloc_csum_engine()) {
++ // Did not obtain the csum engine, so return will failure status
++ return 1;
++ }
++ }
++#else // CONFIG_OXNAS_VERSION_0X800
++ BUG_ON(do_checksum);
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++ {
++ // Assemble complete memory settings, accounting for csum generation if
++ // required
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ oxnas_dma_device_settings_t src_settings =
++ do_checksum ? oxnas_ram_csum_src_dma_settings :
++ oxnas_ram_only_src_dma_settings;
++#else // CONFIG_OXNAS_VERSION_0X800
++ oxnas_dma_device_settings_t src_settings = oxnas_ram_only_src_dma_settings;
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++ oxnas_dma_device_settings_t dst_settings = oxnas_ram_generic_dma_settings;
++
++ // Assemble the source address
++ src_settings.address_ = (unsigned long)src_adr;
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ if (do_checksum) {
++ // Record that we are checksumming, so that the result is read on
++ // completion
++ channel->checksumming_ = 1;
++
++ // To checksum set the high order address bit to enable the engine
++ src_settings.address_ |= (1UL << OXNAS_DMA_CSUM_ENABLE_ADR_BIT);
++ }
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++ // Ensure only use the valid src address bits are used
++ src_settings.address_ &= OXNAS_DMA_CSUM_ADR_MASK;
++ src_settings.address_mode_ = src_mode;
++
++ // Ensure only use the valid dst address bits are used
++ dst_settings.address_ = ((unsigned long)dst_adr) & OXNAS_DMA_ADR_MASK;
++ dst_settings.address_mode_ = dst_mode;
++
++ return oxnas_dma_set_common(channel, length, &src_settings, &dst_settings, 1, paused);
++ }
++}
++
++int oxnas_dma_device_set(
++ oxnas_dma_channel_t *channel,
++ oxnas_dma_direction_t direction,
++ unsigned char *mem_adr, // Physical address
++ unsigned long length,
++ oxnas_dma_device_settings_t *device_settings,
++ oxnas_dma_mode_t mem_mode,
++ int paused)
++{
++ oxnas_dma_device_settings_t mem_settings;
++
++ if (oxnas_dma_is_active(channel)) {
++ printk(KERN_WARNING "oxnas_dma_device_set() Trying to use channel %u while active\n", channel->channel_number_);
++ }
++
++ // Assemble complete memory settings, ensuring addresses do not affect the
++ // checksum enabling high order adr bit
++ mem_settings = oxnas_ram_generic_dma_settings;
++ mem_settings.address_ = ((unsigned long)mem_adr) & OXNAS_DMA_ADR_MASK;
++ mem_settings.address_mode_ = mem_mode;
++
++ device_settings->address_ &= OXNAS_DMA_ADR_MASK;
++
++ return oxnas_dma_set_common(
++ channel,
++ length,
++ (direction == OXNAS_DMA_TO_DEVICE) ? &mem_settings : device_settings,
++ (direction == OXNAS_DMA_FROM_DEVICE) ? &mem_settings : device_settings,
++ 1,
++ paused);
++}
++
++int oxnas_dma_device_pair_set(
++ oxnas_dma_channel_t* channel,
++ unsigned long length,
++ oxnas_dma_device_settings_t *src_device_settings,
++ oxnas_dma_device_settings_t *dst_device_settings,
++ int paused)
++{
++ if (oxnas_dma_is_active(channel)) {
++ printk(KERN_WARNING "oxnas_dma_device_pair_set() Trying to use channel %u while active\n", channel->channel_number_);
++ }
++
++ // Ensure addresses do not affect the checksum enabling high order adr bit
++ src_device_settings->address_ &= OXNAS_DMA_ADR_MASK;
++ dst_device_settings->address_ &= OXNAS_DMA_ADR_MASK;
++ return oxnas_dma_set_common(channel, length, src_device_settings, dst_device_settings, 1, paused);
++}
++
++static int oxnas_dma_set_sg_common(
++ oxnas_dma_channel_t* channel,
++ struct scatterlist* src_sg,
++ unsigned src_sg_count,
++ struct scatterlist* dst_sg,
++ unsigned dst_sg_count,
++ oxnas_dma_device_settings_t* src_settings,
++ oxnas_dma_device_settings_t* dst_settings,
++ int in_atomic)
++{
++ int i;
++ int failed = 0;
++ oxnas_dma_sg_entry_t *sg_entry;
++ oxnas_dma_sg_entry_t *previous_entry;
++
++ // Get reference to this channel's top level SG DMA descriptor structure
++ oxnas_dma_sg_info_t *sg_info = channel->v_sg_info_;
++
++ // SG entries have not been provided
++ channel->auto_sg_entries_ = 1;
++
++ // Initialise list pointers to zero
++ sg_info->v_srcEntries_ = 0;
++ sg_info->p_srcEntries_ = 0;
++ sg_info->v_dstEntries_ = 0;
++ sg_info->p_dstEntries_ = 0;
++
++ sg_entry = 0;
++ previous_entry = 0;
++ for (i=0; i < src_sg_count; i++) {
++ // Is this entry contiguous with the previous one and would the combined
++ // lengths not exceed the maximum that the hardware is capable of
++#if 0
++ if (previous_entry &&
++ ((previous_entry->addr_ + previous_entry->length_) == (src_sg[i].dma_address & OXNAS_DMA_CSUM_ADR_MASK)) &&
++ ((previous_entry->length_ + src_sg[i].length) <= MAX_OXNAS_DMA_TRANSFER_LENGTH)) {
++ // Yes, so coalesce the pair
++ previous_entry->length_ += src_sg[i].length;
++ } else
++#endif
++ {
++ // Allocate space for SG list entry from coherent DMA pool
++ oxnas_dma_sg_entry_t *new_sg_entry = alloc_sg_entry(in_atomic);
++ if (!new_sg_entry) {
++ failed = 1;
++ break;
++ }
++ sg_entry = new_sg_entry;
++
++ if (previous_entry) {
++ // Link the previous SG list entry forward to this one
++ previous_entry->v_next_ = sg_entry;
++ previous_entry->p_next_ = sg_entry->paddr_;
++ } else {
++ // Create a link from the SG info structure to the first SG list entry
++ sg_info->v_srcEntries_ = sg_entry;
++ sg_info->p_srcEntries_ = sg_entry->paddr_;
++ }
++ previous_entry = sg_entry;
++
++ // Fill in the SG list entry with start address, ensuring only valid
++ // address bits are used, preserving the checksum enabling flag
++ sg_entry->addr_ = src_sg[i].dma_address & OXNAS_DMA_CSUM_ADR_MASK;
++
++ // Fill in the length, checking that it does not exceed the hardware
++ // allowed maximum
++ sg_entry->length_ = (src_sg[i].length <= MAX_OXNAS_DMA_TRANSFER_LENGTH) ? src_sg[i].length : 0;
++ if (!sg_entry->length_) {
++ printk(KERN_WARNING "oxnas_dma_set_sg_common() Source entry too long, zeroing\n");
++ }
++ }
++ }
++ if (sg_entry) {
++ // Mark the end of the source SG list with nulls
++ sg_entry->p_next_ = 0;
++ sg_entry->v_next_ = 0;
++ }
++
++ if (failed) {
++ // Failed to allocate all SG src entries, so free those we did get
++ oxnas_dma_sg_entry_t* sg_entry = sg_info->v_srcEntries_;
++ while (sg_entry) {
++ oxnas_dma_sg_entry_t* next = sg_entry->v_next_;
++ free_sg_entry(sg_entry);
++ sg_entry = next;
++ }
++ channel->v_sg_info_->p_srcEntries_ = 0;
++ channel->v_sg_info_->v_srcEntries_ = 0;
++ return 1;
++ }
++
++ // Assemble destination descriptors
++ sg_entry = 0;
++ previous_entry = 0;
++ for (i=0; i < dst_sg_count; i++) {
++ // Is this entry contiguous with the previous one?
++#if 0
++ if (previous_entry &&
++ ((previous_entry->addr_ + previous_entry->length_) == (dst_sg[i].dma_address & OXNAS_DMA_CSUM_ADR_MASK)) &&
++ ((previous_entry->length_ + dst_sg[i].length) <= MAX_OXNAS_DMA_TRANSFER_LENGTH)) {
++ // Yes, so coalesce the pair
++ previous_entry->length_ += dst_sg[i].length;
++ } else
++#endif
++ {
++ // Allocate space for SG list entry from coherent DMA pool
++ oxnas_dma_sg_entry_t *new_sg_entry = alloc_sg_entry(in_atomic);
++ if (!new_sg_entry) {
++ failed = 1;
++ break;
++ }
++ sg_entry = new_sg_entry;
++
++ if (previous_entry) {
++ // Link the previous SG list entry forward to this one
++ previous_entry->v_next_ = sg_entry;
++ previous_entry->p_next_ = sg_entry->paddr_;
++ } else {
++ // Create a link from the SG info structure to the first SG list entry
++ sg_info->v_dstEntries_ = sg_entry;
++ sg_info->p_dstEntries_ = sg_entry->paddr_;
++ }
++ previous_entry = sg_entry;
++
++ // Fill in the SG list entry with start address, ensuring address
++ // does not affect the checksum enabling high order adr bit
++ sg_entry->addr_ = dst_sg[i].dma_address & OXNAS_DMA_ADR_MASK;
++
++ // Fill in the length, checking that it does not exceed the hardware
++ // allowed maximum
++ sg_entry->length_ = (dst_sg[i].length <= MAX_OXNAS_DMA_TRANSFER_LENGTH) ? dst_sg[i].length : 0;
++ if (!sg_entry->length_) {
++ printk(KERN_WARNING "oxnas_dma_set_sg_common() Destination entry too long, zeroing\n");
++ }
++ }
++ }
++ if (sg_entry) {
++ // Mark the end of the destination SG list with nulls
++ sg_entry->p_next_ = 0;
++ sg_entry->v_next_ = 0;
++ }
++
++ if (failed) {
++ // Failed to allocate all SG dst entries, so free those we did obtain
++ oxnas_dma_sg_entry_t* sg_entry = sg_info->v_dstEntries_;
++ while (sg_entry) {
++ oxnas_dma_sg_entry_t* next = sg_entry->v_next_;
++ free_sg_entry(sg_entry);
++ sg_entry = next;
++ }
++ sg_info->p_dstEntries_ = 0;
++ sg_info->v_dstEntries_ = 0;
++
++ // Free all the SG src entries which we did sucessfully obtain
++ sg_entry = sg_info->v_srcEntries_;
++ while (sg_entry) {
++ oxnas_dma_sg_entry_t* next = sg_entry->v_next_;
++ free_sg_entry(sg_entry);
++ sg_entry = next;
++ }
++ sg_info->p_srcEntries_ = 0;
++ sg_info->v_srcEntries_ = 0;
++ return 1;
++ }
++
++ sg_info->qualifer_ = ((channel->channel_number_ << OXNAS_DMA_SG_CHANNEL_BIT) |
++ (src_settings->read_eot_policy_ << OXNAS_DMA_SG_SRC_EOT_BIT) |
++ (dst_settings->write_eot_policy_ << OXNAS_DMA_SG_DST_EOT_BIT) |
++ (1 << OXNAS_DMA_SG_QUALIFIER_BIT));
++
++ // Flags are the same for source and destination for each SG transfer component
++ sg_info->control_ = encode_control_status(src_settings, dst_settings, 0);
++
++ // Increase count of in-progress transfers on this channel
++ atomic_inc(&channel->active_count_);
++
++ return 0;
++}
++
++int oxnas_dma_set_sg(
++ oxnas_dma_channel_t* channel,
++ struct scatterlist* src_sg,
++ unsigned src_sg_count,
++ struct scatterlist* dst_sg,
++ unsigned dst_sg_count,
++ oxnas_dma_mode_t src_mode,
++ oxnas_dma_mode_t dst_mode,
++ int do_checksum,
++ int in_atomic)
++{
++ if (oxnas_dma_is_active(channel)) {
++ printk(KERN_WARNING "oxnas_dma_set_sg() Trying to use channel %u while active\n", channel->channel_number_);
++ }
++
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ if (do_checksum) {
++ // Arbitrate for ownership of the checksum engine
++ if (alloc_csum_engine()) {
++ // Failed to obtain csum engine, so return with failure status
++ return 1;
++ }
++ }
++#else // CONFIG_OXNAS_VERSION_0X800
++ BUG_ON(do_checksum);
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++ {
++ // Assemble complete memory settings, accounting for csum generation if
++ // required
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ oxnas_dma_device_settings_t src_settings =
++ do_checksum ? oxnas_ram_csum_src_dma_settings :
++ oxnas_ram_only_src_dma_settings;
++#else // CONFIG_OXNAS_VERSION_0X800
++ oxnas_dma_device_settings_t src_settings = oxnas_ram_only_src_dma_settings;
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++ oxnas_dma_device_settings_t dst_settings = oxnas_ram_generic_dma_settings;
++
++ // Normal adr bits not used for SG transfers
++ src_settings.address_ = 0;
++ src_settings.address_mode_ = src_mode;
++
++ // Normal adr bits not used for SG transfers
++ dst_settings.address_ = 0;
++ dst_settings.address_mode_ = dst_mode;
++
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ if (do_checksum) {
++ // Record that we are checksumming, so that the result is read on
++ // completion
++ channel->checksumming_ = 1;
++
++ // The high order address bit enabling the checksum engine will be
++ // set by the caller in the passed scatterlist entries, for those
++ // entries which are required to contribute to the checksum
++ // calculation
++ }
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++ return oxnas_dma_set_sg_common(
++ channel,
++ src_sg,
++ src_sg_count,
++ dst_sg,
++ dst_sg_count,
++ &src_settings,
++ &dst_settings,
++ in_atomic);
++ }
++}
++
++int oxnas_dma_device_set_sg(
++ oxnas_dma_channel_t* channel,
++ oxnas_dma_direction_t direction,
++ struct scatterlist* mem_sg,
++ unsigned mem_sg_count,
++ oxnas_dma_device_settings_t* device_settings,
++ oxnas_dma_mode_t mem_mode,
++ int in_atomic)
++{
++ int i;
++ struct scatterlist *sg;
++ struct scatterlist dev_sg;
++
++ oxnas_dma_device_settings_t mem_settings;
++
++ if (oxnas_dma_is_active(channel)) {
++ printk(KERN_WARNING "oxnas_dma_device_set_sg() Trying to use channel %u while active\n", channel->channel_number_);
++ }
++
++ // Assemble complete memory settings
++ mem_settings = oxnas_ram_generic_dma_settings;
++ mem_settings.address_ = 0; // Not used for SG transfers
++ mem_settings.address_mode_ = mem_mode;
++
++ // Need to total all memory transfer lengths and assign as device single transfer length
++ dev_sg.dma_address = device_settings->address_;
++ for (i=0, sg=mem_sg, dev_sg.length = 0; i < mem_sg_count; i++, sg++) {
++ dev_sg.length += sg->length;
++ }
++
++ return oxnas_dma_set_sg_common(
++ channel,
++ (direction == OXNAS_DMA_TO_DEVICE) ? mem_sg : &dev_sg,
++ (direction == OXNAS_DMA_TO_DEVICE) ? mem_sg_count : 1,
++ (direction == OXNAS_DMA_FROM_DEVICE) ? mem_sg : &dev_sg,
++ (direction == OXNAS_DMA_FROM_DEVICE) ? mem_sg_count : 1,
++ (direction == OXNAS_DMA_TO_DEVICE) ? &mem_settings : device_settings,
++ (direction == OXNAS_DMA_FROM_DEVICE) ? &mem_settings : device_settings,
++ in_atomic);
++}
++
++static int oxnas_dma_set_prd_common(
++ oxnas_dma_channel_t *channel,
++ struct ata_prd *src_prd,
++ struct ata_prd *dst_prd,
++ oxnas_dma_device_settings_t *src_settings,
++ oxnas_dma_device_settings_t *dst_settings,
++ oxnas_dma_sg_entry_t *sg_entries)
++{
++ int i;
++ int failed = 0;
++ oxnas_dma_sg_entry_t *sg_entry, *previous_entry, *next_entry;
++ u32 eot;
++ u32 tot_src_len = 0, tot_dst_len = 0;
++
++ // Get reference to this channel's top level SG DMA descriptor structure
++ oxnas_dma_sg_info_t *sg_info = channel->v_sg_info_;
++
++ // SG entries have been provided
++ channel->auto_sg_entries_ = 0;
++
++ // Initialise list pointers to zero
++ sg_info->v_srcEntries_ = 0;
++ sg_info->p_srcEntries_ = 0;
++ sg_info->v_dstEntries_ = 0;
++ sg_info->p_dstEntries_ = 0;
++
++ // Get pointer to first available SG entry
++ sg_entry = previous_entry = 0;
++ next_entry = sg_entries;
++ i=0;
++ do {
++ u32 addr;
++ u32 length;
++ u32 flags_len;
++
++ addr = src_prd[i].addr;
++ flags_len = le32_to_cpu(src_prd[i++].flags_len);
++ length = flags_len & ~ATA_PRD_EOT;
++ eot = flags_len & ATA_PRD_EOT;
++
++ // Zero length field means 64KB
++ if (!length) length = 0x10000;
++
++ // Accumulate the total length of all source elements
++ tot_src_len += length;
++
++ // Is this entry contiguous with the previous one and would the combined
++ // lengths not exceed the maximum that the hardware is capable of
++#if 0
++ if (previous_entry &&
++ ((previous_entry->addr_ + previous_entry->length_) == (addr & OXNAS_DMA_CSUM_ADR_MASK)) &&
++ ((previous_entry->length_ + length) <= MAX_OXNAS_DMA_TRANSFER_LENGTH)) {
++ // Yes, so coalesce the pair
++ previous_entry->length_ += length;
++ } else
++#endif
++ {
++ // Get the next available SG entry
++ if (!next_entry) {
++ failed = 1;
++ break;
++ }
++ sg_entry = next_entry;
++
++ if (previous_entry) {
++ // Link the previous SG list entry forward to this one
++ previous_entry->v_next_ = sg_entry;
++ previous_entry->p_next_ = sg_entry->paddr_;
++ } else {
++ // Create a link from the SG info structure to the first SG list entry
++ sg_info->v_srcEntries_ = sg_entry;
++ sg_info->p_srcEntries_ = sg_entry->paddr_;
++ }
++ previous_entry = sg_entry;
++
++ // Fill in the SG list entry with start address, ensuring only valid
++ // address bits are used, preserving the checksum enabling flag
++ sg_entry->addr_ = addr & OXNAS_DMA_CSUM_ADR_MASK;
++
++ // Fill in the length, checking that it does not exceed the hardware
++ // allowed maximum
++ if (length > MAX_OXNAS_DMA_TRANSFER_LENGTH) {
++ printk(KERN_WARNING "oxnas_dma_set_prd_common() Source entry too long (0x%x), zeroing\n", length);
++ sg_entry->length_ = 0;
++ } else {
++ sg_entry->length_ = length;
++ }
++
++ // Get pointer to next available SG entry
++ next_entry = sg_entry->next_;
++ }
++ } while (!eot);
++ if (sg_entry) {
++ // Mark the end of the source SG list with nulls
++ sg_entry->p_next_ = 0;
++ sg_entry->v_next_ = 0;
++ }
++
++ if (failed) {
++ // Failed to allocate all SG src entries
++ channel->v_sg_info_->p_srcEntries_ = 0;
++ channel->v_sg_info_->v_srcEntries_ = 0;
++ printk(KERN_WARNING "Too few SG entries to satisfy source requirements\n");
++ return 1;
++ }
++
++ // Assemble destination descriptors
++ sg_entry = previous_entry = 0;
++ i=0;
++ do {
++ u32 addr;
++ u32 length;
++ u32 flags_len;
++
++ addr = dst_prd[i].addr;
++ flags_len = le32_to_cpu(dst_prd[i++].flags_len);
++ length = flags_len & ~ATA_PRD_EOT;
++ eot = flags_len & ATA_PRD_EOT;
++
++ // Zero length field means 64KB
++ if (!length) length = 0x10000;
++
++ // Accumulate the total length of all destination elements
++ tot_dst_len += length;
++
++ // Is this entry contiguous with the previous one?
++#if 0
++ if (previous_entry &&
++ ((previous_entry->addr_ + previous_entry->length_) == (addr & OXNAS_DMA_CSUM_ADR_MASK)) &&
++ ((previous_entry->length_ + length) <= MAX_OXNAS_DMA_TRANSFER_LENGTH)) {
++ // Yes, so coalesce the pair
++ previous_entry->length_ += length;
++ } else
++#endif
++ {
++ // Get the next available SG entry
++ if (!next_entry) {
++ failed = 1;
++ break;
++ }
++ sg_entry = next_entry;
++
++ if (previous_entry) {
++ // Link the previous SG list entry forward to this one
++ previous_entry->v_next_ = sg_entry;
++ previous_entry->p_next_ = sg_entry->paddr_;
++ } else {
++ // Create a link from the SG info structure to the first SG list entry
++ sg_info->v_dstEntries_ = sg_entry;
++ sg_info->p_dstEntries_ = sg_entry->paddr_;
++ }
++ previous_entry = sg_entry;
++
++ // Fill in the SG list entry with start address, ensuring address
++ // does not affect the checksum enabling high order adr bit
++ sg_entry->addr_ = addr & OXNAS_DMA_ADR_MASK;
++
++ // Fill in the length, checking that it does not exceed the hardware
++ // allowed maximum
++ if (length > MAX_OXNAS_DMA_TRANSFER_LENGTH) {
++ printk(KERN_WARNING "oxnas_dma_set_prd_common() Destination entry too long (0x%x), zeroing\n", length);
++ sg_entry->length_ = 0;
++ } else {
++ sg_entry->length_ = length;
++ }
++
++ // Get pointer to next available SG entry
++ next_entry = sg_entry->next_;
++ }
++ } while (!eot);
++ if (sg_entry) {
++ // Mark the end of the destination SG list with nulls
++ sg_entry->p_next_ = 0;
++ sg_entry->v_next_ = 0;
++ }
++
++ if (failed) {
++ // Failed to allocate all SG dst entries
++ sg_info->p_dstEntries_ = 0;
++ sg_info->v_dstEntries_ = 0;
++ sg_info->p_srcEntries_ = 0;
++ sg_info->v_srcEntries_ = 0;
++ printk(KERN_WARNING "Too few SG entries to satisfy destination requirements\n");
++ return 1;
++ }
++
++ // Fill in length of single device SG entry from the total length of all the
++ // memory SG entries
++ if ((sg_entry = sg_info->v_srcEntries_) && !sg_entry->v_next_) {
++ sg_entry->length_ = tot_dst_len;
++ } else if ((sg_entry = sg_info->v_dstEntries_) && !sg_entry->v_next_) {
++ sg_entry->length_ = tot_src_len;
++ }
++
++ sg_info->qualifer_ = ((channel->channel_number_ << OXNAS_DMA_SG_CHANNEL_BIT) |
++ (src_settings->read_eot_policy_ << OXNAS_DMA_SG_SRC_EOT_BIT) |
++ (dst_settings->write_eot_policy_ << OXNAS_DMA_SG_DST_EOT_BIT) |
++ (1 << OXNAS_DMA_SG_QUALIFIER_BIT));
++
++ // Flags are the same for source and destination for each SG transfer component
++ sg_info->control_ = encode_control_status(src_settings, dst_settings, 0);
++
++ // Increase count of in-progress transfers on this channel
++ atomic_inc(&channel->active_count_);
++
++ return 0;
++}
++
++int oxnas_dma_device_set_prd(
++ oxnas_dma_channel_t *channel,
++ oxnas_dma_direction_t direction,
++ struct ata_prd *mem_prd,
++ oxnas_dma_device_settings_t *device_settings,
++ oxnas_dma_mode_t mem_mode,
++ oxnas_dma_sg_entry_t *sg_entries)
++{
++ struct ata_prd dev_prd;
++ oxnas_dma_device_settings_t mem_settings;
++
++ if (unlikely(oxnas_dma_is_active(channel))) {
++ printk(KERN_WARNING "oxnas_dma_device_set_prd() Trying to use channel %u while active\n", channel->channel_number_);
++ }
++
++ // Assemble complete memory settings
++ mem_settings = oxnas_ram_generic_dma_settings;
++ mem_settings.address_ = 0; // Not used for SG transfers
++ mem_settings.address_mode_ = mem_mode;
++
++ // Device has only a single SG entry whose length will be assigned once
++ // all the memory transfer lengths have been accumulated
++ dev_prd.addr = device_settings->address_;
++ dev_prd.flags_len = ATA_PRD_EOT;
++
++ return oxnas_dma_set_prd_common(
++ channel,
++ (direction == OXNAS_DMA_TO_DEVICE) ? mem_prd : &dev_prd,
++ (direction == OXNAS_DMA_FROM_DEVICE) ? mem_prd : &dev_prd,
++ (direction == OXNAS_DMA_TO_DEVICE) ? &mem_settings : device_settings,
++ (direction == OXNAS_DMA_FROM_DEVICE) ? &mem_settings : device_settings,
++ sg_entries);
++}
++
++void oxnas_dma_set_callback(oxnas_dma_channel_t* channel, oxnas_dma_callback_t callback, oxnas_callback_arg_t arg)
++{
++#if defined(OXNAS_DMA_TEST) || defined(OXNAS_DMA_SG_TEST)
++printk("Registering callback 0x%08x for channel %u\n", (unsigned)callback, channel->channel_number_);
++#endif // defined(OXNAS_DMA_TEST) || defined(OXNAS_DMA_SG_TEST)
++ channel->notification_callback_ = callback;
++ channel->notification_arg_ = arg;
++}
++
++static void default_callback(
++ oxnas_dma_channel_t* channel,
++ oxnas_callback_arg_t arg,
++ oxnas_dma_callback_status_t status,
++ u16 checksum,
++ int interrupt_count)
++{
++ up(&channel->default_semaphore_);
++}
++
++void oxnas_dma_abort(
++ oxnas_dma_channel_t *channel,
++ int in_atomic)
++{
++ u32 ctrl_status;
++ unsigned channel_number = channel->channel_number_;
++ int must_wait = 0;
++ int callback_registered = 0;
++
++ // Assert reset for the channel
++ spin_lock(&dma_controller.spinlock_);
++ ctrl_status = readl(DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
++ ctrl_status |= DMA_CTRL_STATUS_RESET;
++ writel(ctrl_status, DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
++ spin_unlock(&dma_controller.spinlock_);
++
++ // Wait for the channel to become idle - should be quick as should finish
++ // after the next AHB single or burst transfer
++ while (readl(DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS)) & DMA_CTRL_STATUS_IN_PROGRESS);
++
++ // Deassert reset for the channel
++ spin_lock(&dma_controller.spinlock_);
++ ctrl_status = readl(DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
++ ctrl_status &= ~DMA_CTRL_STATUS_RESET;
++ writel(ctrl_status, DMA_CALC_REG_ADR(channel_number, DMA_CTRL_STATUS));
++ spin_unlock(&dma_controller.spinlock_);
++
++ // If no user callback is registered, we need to wait here for the DMA
++ // channel to become inactive, i.e. for the ISR to be called and the
++ // channel software returned to the idle state
++ if (channel->notification_callback_ == OXNAS_DMA_CALLBACK_NUL) {
++ must_wait = 1;
++ if (!in_atomic) {
++ // If the callers is not calling us from atomic context we can
++ // register our own callback and sleep until it is invoked
++ oxnas_dma_set_callback(channel, default_callback, OXNAS_DMA_CALLBACK_ARG_NUL);
++ callback_registered = 1;
++ }
++ }
++
++ // Fake an interrupt to cause the channel to be cleaned up by running the
++ // DMA bottom half tasklet
++ fake_interrupt(channel_number);
++
++ if (must_wait) {
++ if (callback_registered) {
++ // Sleep until the channel becomes inactive
++ down_interruptible(&channel->default_semaphore_);
++
++ // Deregister the callback
++ oxnas_dma_set_callback(channel, OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
++ } else {
++ // If we reach here we are in an atomic context and thus must not do
++ // anything that might cause us to sleep
++ // NB. Possible problem here if we're atomic because someone has
++ // called spin_lock_bh(); I'm concerned that calling do_softirq()
++ // under these circumstances might cause issues, althought the net-
++ // working code calls do_softirq() and doesn't appear to worry
++ if (local_softirq_pending()) {
++ // If an interrupt has not arrived and caused the tasklet to
++ // have been run already, cause it to run now.
++ do_softirq();
++ }
++
++ // The tasklet should have run by this point and cleaned up the channel
++ BUG_ON(oxnas_dma_is_active(channel));
++ }
++ }
++}
++
++void oxnas_dma_start(oxnas_dma_channel_t* channel)
++{
++ // Are there SG lists setup for this channel?
++ if (channel->v_sg_info_->v_srcEntries_) {
++#ifdef OXNAS_DMA_SG_TEST_DUMP_DESCRIPTORS
++ // Print the desciptor contents for debugging
++ oxnas_dma_sg_entry_t* d = channel->v_sg_info_->v_srcEntries_;
++ printk("qualifer_ = 0x%08lx, control_ = 0x%lx\n", channel->v_sg_info_->qualifer_, channel->v_sg_info_->control_);
++ printk("Source Descriptors:\n");
++ while (d) {
++ printk("v_addr=0x%08x, p_addr=0x%08x, addr_=0x%08x, length_=0x%08lx, next=0x%08x\n", (u32)d, (u32)d->paddr_, d->addr_, d->length_, d->p_next_);
++ d = d->v_next_;
++ }
++ printk("Destination Descriptors:\n");
++ d = channel->v_sg_info_->v_dstEntries_;
++ while (d) {
++ printk("v_addr=0x%08x, p_addr=0x%08x, addr_=0x%08x, length_=0x%08lx, next=0x%08x\n", (u32)d, (u32)d->paddr_, d->addr_, d->length_, d->p_next_);
++ d = d->v_next_;
++ }
++#endif // OXNAS_DMA_SG_TEST_DUMP_DESCRIPTORS
++
++ // Write to the SG-DMA channel's reset register to reset the control
++ // in case the previous SG-DMA transfer failed in some way, thus
++ // leaving the SG-DMA controller hung up part way through processing
++ // its SG list. The reset bits are self-clearing
++ writel(1UL << DMA_SG_RESETS_CONTROL_BIT, DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_RESETS));
++
++ // Write the pointer to the SG info struct into the Request Pointer reg.
++ writel(channel->p_sg_info_, DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_REQ_PTR));
++
++#ifdef OXNAS_DMA_SG_TEST
++printk("p_sg_info_ = 0x%08x written to 0x%08x\n", (u32)channel->p_sg_info_, DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_REQ_PTR));
++printk("*(DMA_SG_CONTROL) = 0x%08x\n", readl(DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_CONTROL)));
++printk("*(DMA_SG_STATUS) = 0x%08x\n", readl(DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_STATUS)));
++printk("*(DMA_SG_REQ_PTR) = 0x%08x\n", readl(DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_REQ_PTR)));
++#endif // OXNAS_DMA_SG_TEST
++
++ // Start the transfer
++ writel((1UL << DMA_SG_CONTROL_START_BIT) |
++ (1UL << DMA_SG_CONTROL_QUEUING_ENABLE_BIT) |
++ (1UL << DMA_SG_CONTROL_HBURST_ENABLE_BIT),
++ DMA_SG_CALC_REG_ADR(channel->channel_number_, DMA_SG_CONTROL));
++ } else {
++ // Single transfer mode, so unpause the DMA controller channel
++ spin_lock(&dma_controller.spinlock_);
++ writel(encode_start(readl(DMA_CALC_REG_ADR(channel->channel_number_, DMA_CTRL_STATUS))),
++ DMA_CALC_REG_ADR(channel->channel_number_, DMA_CTRL_STATUS));
++ spin_unlock(&dma_controller.spinlock_);
++ }
++}
++
++void oxnas_dma_dump_registers()
++{
++ unsigned long* adr = (unsigned long*)DMA_CALC_REG_ADR(0, 0);
++ unsigned long* end = (adr + DMA_REGS_PER_CHANNEL);
++ int i;
++
++ printk("oxnas_dma_dump_registers(), adr= 0x%08lx, end=0x%08lx\n", (unsigned long)adr, (unsigned long)(adr + (DMA_REGS_PER_CHANNEL * dma_controller.numberOfChannels_)));
++
++ for (i=0; i < dma_controller.numberOfChannels_; i++) {
++ for (; adr < end; adr++) {
++ printk("0x%08lx\n", *adr);
++ }
++ printk("SG-Debug: 0x%08x\n", readl(DMA_SG_CALC_REG_ADR(i, DMA_SG_RESETS)));
++ printk("-----------------------\n");
++ end += DMA_REGS_PER_CHANNEL;
++ }
++ printk("oxnas_dma_dump_registers() - end\n");
++}
++
++void oxnas_dma_dump_registers_single(int channel_number)
++{
++ unsigned long* adr = (unsigned long*)DMA_CALC_REG_ADR(channel_number, 0);
++ unsigned long* end = (adr + DMA_REGS_PER_CHANNEL);
++
++ printk("DMA channel %d regs:\n", channel_number);
++ for (; adr < end; adr++) {
++ printk("0x%08lx\n", *adr);
++ }
++}
++
++#if defined(OXNAS_DMA_TEST) || defined(OXNAS_DMA_SG_TEST)
++static __DECLARE_SEMAPHORE_GENERIC(callback_semaphore, 0); // Binary semaphore for testing
++
++static void dma_callback(
++ oxnas_dma_channel_t *channel,
++ oxnas_callback_arg_t arg,
++ oxnas_dma_callback_status_t error_code,
++ u16 checksum,
++ int interrupt_count)
++{
++ printk("dma_callback() for channel %u, arg = 0x%lx, status = 0x%04x, checksum = 0x%04hx, interrupt_count = %d\n", channel->channel_number_, (unsigned long)arg, error_code, checksum, interrupt_count);
++ up(&callback_semaphore);
++}
++
++#include <linux/dma-mapping.h>
++#include <linux/slab.h>
++
++#ifdef OXNAS_DMA_TEST
++static void dma_test(unsigned long length)
++{
++ void* memory1;
++ void* memory2;
++ unsigned long* ptr;
++ unsigned long quads;
++ int i;
++ unsigned long* end;
++ dma_addr_t dma_address1;
++ dma_addr_t dma_address2;
++ oxnas_dma_channel_t* channels[MAX_OXNAS_DMA_CHANNELS];
++
++ printk("*************************************************************\n");
++ printk(" \n");
++ printk("Simple DMA Test, length = %lu, number of channel = %u\n", length, MAX_OXNAS_DMA_CHANNELS);
++ printk(" \n");
++ printk("*************************************************************\n");
++
++ for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
++ channels[i] = oxnas_dma_request(0);
++ if (channels[i] == OXNAS_DMA_CHANNEL_NUL) {
++ printk("No DMA channels[%d] obtained\n", i);
++ } else {
++ printk("Obtained DMA channels[%d] %u, isActive=%d\n", i, channels[i]->channel_number_, oxnas_dma_is_active(channels[i]));
++ }
++ }
++
++ // Allocate some DMA coherent memory
++ printk("Calling kmalloc()\n");
++ memory1 = kmalloc(length, GFP_KERNEL | GFP_DMA);
++ memory2 = kmalloc(length, GFP_KERNEL | GFP_DMA);
++
++ // Test each available DMA channel
++ for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
++ int j;
++
++ // Fill each memory area with a different pattern
++ ptr = (unsigned long*)memory1;
++ quads = length/sizeof(unsigned long);
++ for (j=0; j < quads; j++) {
++ *ptr++ = 0xdeadbeef;
++ }
++ ptr = (unsigned long*)memory2;
++ for (j=0; j < quads; j++) {
++ *ptr++ = 0xc001babe;
++ }
++
++ printk("Before:\n");
++ ptr = (unsigned long*)memory1;
++ end = (unsigned long*)(memory1 + length);
++ while (ptr < end) {
++ for (j=0; j < 8; j++) {
++ printk("0x%08lx ", *ptr++);
++ }
++ printk("\n");
++ }
++ printk("---------------------------------------------------------\n");
++ ptr = (unsigned long*)memory2;
++ end = (unsigned long*)(memory2 + length);
++ while (ptr < end) {
++ for (j=0; j < 8; j++) {
++ printk("0x%08lx ", *ptr++);
++ }
++ printk("\n");
++ }
++
++ // Get a consistent DMA mapping for the memory to be DMAed from - causing a
++ // flush from the CPU's cache to the memory
++ dma_address1 = dma_map_single(0, memory1, length, DMA_TO_DEVICE);
++ if (dma_mapping_error(dma_address1)) {
++ printk("Consistent DMA mapping 1 failed\n");
++ }
++
++ // Get a consistent DMA mapping for the memory to be DMAed to - causing a
++ // flush and invalidation of any entries in the CPU's cache covering the
++ // memory region
++ dma_address2 = dma_map_single(0, memory2, length, DMA_BIDIRECTIONAL);
++ if (dma_mapping_error(dma_address2)) {
++ printk("Consistent DMA mapping 2 failed\n");
++ }
++
++ // Setup up DMA from first half to second half on memory, using physical addresses
++ printk("Calling oxnas_dma_set(), memory1 = 0x%08lx, memory2 = 0x%08lx\n", (unsigned long)memory1, (unsigned long)memory2);
++ oxnas_dma_set(
++ channels[i],
++ (unsigned char*)dma_address1,
++ length,
++ (unsigned char*)dma_address2,
++ OXNAS_DMA_MODE_INC,
++ OXNAS_DMA_MODE_INC,
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ 1, // Calculate checksum over source data
++#else // CONFIG_OXNAS_VERSION_0X800
++ 0,
++#endif // CONFIG_OXNAS_VERSION_0X800
++ 1); // Paused
++
++ // Using notification callback
++ oxnas_dma_set_callback(channels[i], dma_callback, OXNAS_DMA_CALLBACK_ARG_NUL);
++
++//printk("Before starting status = 0x%08x, intId = 0x%08x\n", readl(DMA_CALC_REG_ADR(channels[i]->channel_number_, DMA_CTRL_STATUS)), readl(DMA_CALC_REG_ADR(0, DMA_INTR_ID)));
++ // Start the transfer
++ printk("oxnas_dma_start() for channel %u\n", channels[i]->channel_number_);
++ oxnas_dma_start(channels[i]);
++
++// Poll for transfer completion
++//while (oxnas_dma_raw_isactive(channels[i])) {
++// printk(".");
++//}
++//printk("Found channel inactive, status = 0x%08x, intId = 0x%08x\n", readl(DMA_CALC_REG_ADR(channels[i]->channel_number_, DMA_CTRL_STATUS)), readl(DMA_CALC_REG_ADR(0, DMA_INTR_ID)));
++
++ printk("Waiting for channel to be inactive\n");
++
++ // Sleep until transfer completed
++ while (down_interruptible(&callback_semaphore));
++ oxnas_dma_set_callback(channels[i], OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
++
++ // Release the consistent DMA mappings
++ dma_unmap_single(0, dma_address1, length, DMA_TO_DEVICE);
++ dma_unmap_single(0, dma_address2, length, DMA_BIDIRECTIONAL);
++
++ printk("After:\n");
++ ptr = (unsigned long*)memory1;
++ end = (unsigned long*)(memory1 + length);
++ while (ptr < end) {
++ for (j=0; j < 8; j++) {
++ printk("0x%08lx ", *ptr++);
++ }
++ printk("\n");
++ }
++ printk("---------------------------------------------------------\n");
++ ptr = (unsigned long*)memory2;
++ end = (unsigned long*)(memory2 + length);
++ while (ptr < end) {
++ for (j=0; j < 8; j++) {
++ printk("0x%08lx ", *ptr++);
++ }
++ printk("\n");
++ }
++ }
++
++ // Deallocate the memory
++ printk("Calling kfree()\n");
++ kfree(memory1);
++ kfree(memory2);
++ printk("Returned from kfree()\n");
++
++ for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
++ oxnas_dma_free(channels[i]);
++ }
++
++ for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
++ channels[i] = oxnas_dma_request(0);
++ if (channels[i] == OXNAS_DMA_CHANNEL_NUL) {
++ printk("No DMA channels[%d] obtained\n", i);
++ } else {
++ printk("Obtained DMA channels[%d] %u, isActive=%d\n", i, channels[i]->channel_number_, oxnas_dma_is_active(channels[i]));
++ }
++ }
++
++ for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
++ oxnas_dma_free(channels[i]);
++ }
++}
++#endif // OXNAS_DMA_TEST
++
++#ifdef OXNAS_DMA_SG_TEST
++static void dma_sg_test(void)
++{
++ int i;
++ struct scatterlist* src_scatterlist = 0;
++ struct scatterlist* dst_scatterlist = 0;
++ const int num_src_buffers = 8;
++ const int num_dst_buffers = 3;
++ unsigned long src_fill_value = 0;
++ unsigned long total_src_len = 0;
++ int channel_number;
++ oxnas_dma_channel_t* channels[MAX_OXNAS_DMA_CHANNELS];
++
++ printk("*************************************************************\n");
++ printk(" \n");
++ printk("Scatter-Gather DMA Test\n");
++ printk(" \n");
++ printk("*************************************************************\n");
++
++ for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
++ channels[i] = oxnas_dma_request(0);
++ if (channels[i] == OXNAS_DMA_CHANNEL_NUL) {
++ printk("No DMA channels[%d] obtained\n", i);
++ } else {
++ printk("Obtained DMA channels[%d] %u, isActive=%d\n", i, channels[i]->channel_number_, oxnas_dma_is_active(channels[i]));
++ }
++ }
++
++ for (channel_number=0; channel_number < MAX_OXNAS_DMA_CHANNELS; ++channel_number) {
++ if (num_src_buffers) {
++ printk("Allocating source SG list and entry buffers\n");
++ // Allocate scatterlist and memory for source buffers - store virtual buffer
++ // addresses in scatterlist.offset for convenience. Include some contiguous
++ // entries to test coalescing
++ src_scatterlist = (struct scatterlist*)kmalloc(sizeof(struct scatterlist) * num_src_buffers, GFP_KERNEL);
++ src_scatterlist[0].offset = (unsigned int)kmalloc(8*1024, GFP_KERNEL | GFP_DMA);
++ src_scatterlist[0].__address = (char*)(8*1024); // Real allocation length
++ src_scatterlist[0].length = 8*1024;
++ src_scatterlist[0].page = (struct page*)0xdeadbeef; // Fill value
++ src_scatterlist[1].offset = (unsigned int)kmalloc(8, GFP_KERNEL | GFP_DMA);
++ src_scatterlist[1].__address = (char*)8; // Real allocation length
++ src_scatterlist[1].length = 8;
++ src_scatterlist[1].page = (struct page*)0xc001babe; // Fill value
++ src_scatterlist[2].offset = (unsigned int)kmalloc(48*1024, GFP_KERNEL | GFP_DMA);
++ src_scatterlist[2].__address = (char*)(48*1024); // Real allocation length
++ src_scatterlist[2].length = 16*1024;
++ src_scatterlist[2].page = (struct page*)0x22222222; // Fill value
++ src_scatterlist[3].offset = src_scatterlist[2].offset + src_scatterlist[2].length;
++ src_scatterlist[3].__address = (char*)0; // No allocation
++ src_scatterlist[3].length = 16*1024;
++ src_scatterlist[3].page = (struct page*)0x33333333; // Fill value
++ src_scatterlist[4].offset = src_scatterlist[3].offset + src_scatterlist[3].length;
++ src_scatterlist[4].__address = (char*)0; // No allocation
++ src_scatterlist[4].length = 16*1024;
++ src_scatterlist[4].page = (struct page*)0x44444444; // Fill value
++ src_scatterlist[5].offset = (unsigned int)kmalloc(64, GFP_KERNEL | GFP_DMA);
++ src_scatterlist[5].__address = (char*)64; // Real allocation length
++ src_scatterlist[5].length = 64;
++ src_scatterlist[5].page = (struct page*)0x55555555; // Fill value
++ src_scatterlist[6].offset = (unsigned int)kmalloc(256, GFP_KERNEL | GFP_DMA);
++ src_scatterlist[6].__address = (char*)256; // Real allocation length
++ src_scatterlist[6].length = 128;
++ src_scatterlist[6].page = (struct page*)0x66666666; // Fill value
++ src_scatterlist[7].offset = src_scatterlist[6].offset + src_scatterlist[6].length;
++ src_scatterlist[7].__address = (char*)0; // No allocation
++ src_scatterlist[7].length = 128;
++ src_scatterlist[7].page = (struct page*)0x77777777; // Fill value
++ }
++
++ // Fill source memory buffers with stuff
++ for (i=0; i < num_src_buffers; i++) {
++ unsigned long* ptr = (unsigned long*)src_scatterlist[i].offset;
++ int quads = src_scatterlist[i].length/sizeof(unsigned long);
++ int j=0;
++ printk("Filling source buffer %u\n", i);
++ src_fill_value = (unsigned long)(src_scatterlist[i].page);
++ for (; j < quads; j++) {
++ *ptr++ = src_fill_value;
++ }
++ }
++
++ #ifdef OXNAS_DMA_SG_TEST_DUMP_BUFFERS
++ // Print before contents of source buffers
++ printk("Source Before:\n");
++ for (i=0; i < num_src_buffers; i++) {
++ unsigned long* ptr = (unsigned long*)src_scatterlist[i].offset;
++ unsigned long* end = (unsigned long*)(src_scatterlist[i].offset + src_scatterlist[i].length);
++ printk("Buffer %d\n", i);
++ while (ptr < end) {
++ int j=0;
++ for (; j < 8; j++) {
++ printk("0x%08lx ", *ptr++);
++ }
++ printk("\n");
++ }
++ }
++ #endif // OXNAS_DMA_SG_TEST_DUMP_BUFFERS
++
++ // Get a consistent DMA mapping for the memory to be DMAed from - causing a
++ // flush from the CPU's cache to the memory
++ for (i=0; i < num_src_buffers; i++) {
++ printk("Creating DMA mappings for source entry buffer %u\n", i);
++ src_scatterlist[i].dma_address = dma_map_single(0, (void*)src_scatterlist[i].offset, src_scatterlist[i].length, DMA_TO_DEVICE);
++ if (dma_mapping_error(src_scatterlist[i].dma_address)) {
++ printk("Consistent source DMA mapping %d failed\n", i);
++ }
++
++ // Set the checksum enabling high order address bit
++ src_scatterlist[i].dma_address |= (1UL << OXNAS_DMA_CSUM_ENABLE_ADR_BIT);
++ }
++
++ // Allocate scatterlist and memory for destination buffers - store virtual
++ // buffer addresses in scatterlist.offset for convenience
++ if (num_dst_buffers) {
++ unsigned long dst_length;
++ unsigned long offset;
++
++ printk("Allocating destination SG list and entry buffers\n");
++ total_src_len = 0;
++ for (i=0; i < num_src_buffers; i++) {
++ total_src_len += src_scatterlist[i].length;
++ }
++
++ // Following will only work if no remainder due to divide
++ dst_length = total_src_len / num_dst_buffers;
++ dst_scatterlist = (struct scatterlist*)kmalloc(sizeof(struct scatterlist) * num_dst_buffers, GFP_KERNEL);
++
++ // First destination segment owns the buffer
++ dst_scatterlist[0].offset = (unsigned int)kmalloc(total_src_len, GFP_KERNEL | GFP_DMA);
++ dst_scatterlist[0].__address = (char*)total_src_len; // Real allocation length
++ dst_scatterlist[0].length = dst_length;
++
++ offset = dst_length;
++ for (i=1; i < num_dst_buffers; i++) {
++ dst_scatterlist[i].offset = dst_scatterlist[0].offset + offset;
++ dst_scatterlist[i].__address = 0; // No allocation
++ dst_scatterlist[i].length = dst_length;
++
++ offset += dst_length;
++ }
++ }
++
++ // Fill destination memory buffers with zero
++ for (i=0; i < num_dst_buffers; i++) {
++ unsigned long* ptr = (unsigned long*)dst_scatterlist[i].offset;
++ int quads = dst_scatterlist[i].length/sizeof(unsigned long);
++ int j=0;
++ printk("Filling destination buffer %u\n", i);
++ for (; j < quads; j++) {
++ *ptr++ = 0x000000;
++ }
++ }
++
++ //#ifdef OXNAS_DMA_SG_TEST_DUMP_BUFFERS
++ // // Print before contents of destination buffers
++ // printk("Destination Before:\n");
++ // for (i=0; i < num_dst_buffers; i++) {
++ // unsigned long* ptr = (unsigned long*)dst_scatterlist[i].offset;
++ // unsigned long* end = (unsigned long*)(dst_scatterlist[i].offset + dst_scatterlist[i].length);
++ // printk("Buffer %d\n", i);
++ // while (ptr < end) {
++ // int j=0;
++ // for (; j < 8; j++) {
++ // printk("0x%08lx ", *ptr++);
++ // }
++ // printk("\n");
++ // }
++ // }
++ //#endif // OXNAS_DMA_SG_TEST_DUMP_BUFFERS
++
++ // Get a consistent DMA mapping for the memory to be DMAed to - causing an
++ // invalidate to the CPU's cache
++ for (i=0; i < num_dst_buffers; i++) {
++ printk("Creating DMA mappings for destination entry buffer %u\n", i);
++ dst_scatterlist[i].dma_address = dma_map_single(0, (void*)dst_scatterlist[i].offset, dst_scatterlist[i].length, DMA_BIDIRECTIONAL);
++ if (dma_mapping_error(dst_scatterlist[i].dma_address)) {
++ printk("Consistent destination DMA mapping %d failed\n", i);
++ }
++ }
++
++ // Setup up SG DMA transfer
++ printk("Setting up transfer\n");
++ oxnas_dma_set_sg(
++ channels[channel_number],
++ src_scatterlist,
++ num_src_buffers,
++ dst_scatterlist,
++ num_dst_buffers,
++ OXNAS_DMA_MODE_INC,
++ OXNAS_DMA_MODE_INC,
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ 1); // Compute checksum
++#else // CONFIG_OXNAS_VERSION_0X800
++ 0);
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++ // Using second DMA channel requested
++ oxnas_dma_set_callback(channels[channel_number], dma_callback, OXNAS_DMA_CALLBACK_ARG_NUL);
++
++ // Start the transfer
++ printk("Starting the transfer\n");
++ oxnas_dma_start(channels[channel_number]);
++
++ // Sleep until transfer completed
++ printk("Waiting for transfer to complete...\n");
++
++ while (down_interruptible(&callback_semaphore));
++ oxnas_dma_set_callback(channels[channel_number], OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
++
++ // Release the consistent DMA mappings for the source buffers
++ for (i=0; i < num_src_buffers; i++) {
++ printk("Releasing DMA mappings for source entry buffer %u\n", i);
++ // Ensure the checksum enabling high order address bit is not set, as
++ // this would confuse the DMA mapping release function
++ src_scatterlist[i].dma_address &= ~(1UL << OXNAS_DMA_CSUM_ENABLE_ADR_BIT);
++ dma_unmap_single(0, src_scatterlist[i].dma_address, src_scatterlist[i].length, DMA_TO_DEVICE);
++ }
++
++ // Release the consistent DMA mappings for the destination buffers
++ for (i=0; i < num_dst_buffers; i++) {
++ printk("Releasing DMA mappings for destination entry buffer %u\n", i);
++ dma_unmap_single(0, dst_scatterlist[i].dma_address, dst_scatterlist[i].length, DMA_BIDIRECTIONAL);
++ }
++
++ {
++ u32 sw_csum = 0;
++ for (i=0; i < num_src_buffers; i++) {
++ sw_csum = csum_partial((u8*)src_scatterlist[i].offset, src_scatterlist[i].length, sw_csum);
++ }
++ printk("S/W generated src csum = 0x%04hx\n", csum_fold(sw_csum));
++
++ sw_csum = 0;
++ for (i=0; i < num_dst_buffers; i++) {
++ sw_csum = csum_partial((u8*)dst_scatterlist[i].offset, dst_scatterlist[i].length, sw_csum);
++ }
++ printk("S/W generated dst csum = 0x%04hx\n", csum_fold(sw_csum));
++ }
++
++ #ifdef OXNAS_DMA_SG_TEST_DUMP_BUFFERS
++ // // Print after contents of source buffers
++ // printk("Source After:\n");
++ // for (i=0; i < num_src_buffers; i++) {
++ // unsigned long* ptr = (unsigned long*)src_scatterlist[i].offset;
++ // unsigned long* end = (unsigned long*)(src_scatterlist[i].offset + src_scatterlist[i].length);
++ // printk("Buffer %d\n", i);
++ // while (ptr < end) {
++ // int j=0;
++ // for (; j < 8; j++) {
++ // printk("0x%08lx ", *ptr++);
++ // }
++ // printk("\n");
++ // }
++ // }
++
++ // Print after contents of destination buffers
++ printk("Destination After:\n");
++ for (i=0; i < num_dst_buffers; i++) {
++ unsigned long* ptr = (unsigned long*)dst_scatterlist[i].offset;
++ unsigned long* end = (unsigned long*)(dst_scatterlist[i].offset + dst_scatterlist[i].length);
++ printk("Buffer %d\n", i);
++ while (ptr < end) {
++ int j=0;
++ for (; j < 8; j++) {
++ printk("0x%08lx ", *ptr++);
++ }
++ printk("\n");
++ }
++ }
++ #endif // OXNAS_DMA_SG_TEST_DUMP_BUFFERS
++
++ // Free the memory for the source buffers
++ for (i=0; i < num_src_buffers; i++) {
++ // Check that unique allocation made for this entry
++ if (src_scatterlist[i].__address) {
++ printk("Freeing source SG entry buffer, adr = 0x%08x, len = 0x%08x\n", src_scatterlist[i].offset, (u32)src_scatterlist[i].__address);
++ kfree((void*)src_scatterlist[i].offset);
++ }
++ }
++
++ // Free the memory for the source scatterlist
++ if (src_scatterlist) {
++ printk("Freeing source SG scatter list structure\n");
++ kfree(src_scatterlist);
++ }
++
++ // Free the memory for the destination buffers
++ for (i=0; i < num_dst_buffers; i++) {
++ if (dst_scatterlist[i].__address) {
++ printk("Freeing destination SG entry, adr = 0x%08x, len = 0x%08x\n", dst_scatterlist[i].offset, (u32)dst_scatterlist[i].__address);
++ kfree((void*)dst_scatterlist[i].offset);
++ }
++ }
++
++ // Free the memory for the destination scatterlist
++ if (dst_scatterlist) {
++ printk("Freeing source SG scatter list structure\n");
++ kfree(dst_scatterlist);
++ }
++ }
++
++ for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
++ oxnas_dma_free(channels[i]);
++ }
++}
++#endif // OXNAS_DMA_SG_TEST
++
++#ifdef OXNAS_DMA_SG_TEST_2
++static void dma_sg_test2()
++{
++ /** Include initial 2 bytes of pad that real network buffers would contain
++ in order to ensure that IP header and TCP/UDP header are quad aligned */
++ static const unsigned char bad_src_data0[] = {
++ 0xff, 0xff, 0x00, 0xa0, 0xd2, 0x05, 0x06, 0xec, 0x00, 0xcf, 0x52, 0x49, 0xc3, 0x03, 0x08, 0x00,
++ 0x45, 0x00, 0x05, 0xb4, 0x99, 0x45, 0x40, 0x00, 0x40, 0x06, 0x42, 0xf5, 0xac, 0x1f, 0x00, 0x65,
++ 0xac, 0x1f, 0x00, 0x66
++ };
++
++ static const unsigned char bad_src_data1[] = {
++ 0x04, 0x00, 0x13, 0x89, 0x02, 0x8a, 0x5c, 0x83, 0x52, 0xde, 0xc7, 0x0c, 0x80, 0x19, 0x0b, 0x68,
++ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0xff, 0xff, 0xb3, 0x9d, 0x3f, 0x82, 0xf0, 0xff,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
++ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
++ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
++ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31
++ };
++
++ /** Include initial 2 bytes of pad that real network buffers would contain
++ in order to ensure that IP header and TCP/UDP header are quad aligned */
++ static const unsigned char good_src_data0[] = {
++ 0xff, 0xff, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5
++ };
++
++ static const unsigned char good_src_data1[] = {
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
++ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5
++ };
++
++ static const int src_offset = 2; // To jump IP quad align padding
++ static const int dst_buffer_size = 512;
++
++ const unsigned char *src_data0 = bad_src_data0;
++ const unsigned char *src_data1 = bad_src_data1;
++ unsigned long src_data0_len = sizeof(bad_src_data0);
++ unsigned long src_data1_len = sizeof(bad_src_data1);
++ int channel_number;
++ oxnas_dma_channel_t* channels[MAX_OXNAS_DMA_CHANNELS];
++ int i;
++
++// const unsigned char *src_data0 = good_src_data0;
++// const unsigned char *src_data1 = good_src_data1;
++// unsigned long src_data0_len = sizeof(good_src_data0);
++// unsigned long src_data1_len = sizeof(good_src_data1);
++
++ printk("*************************************************************\n");
++ printk(" \n");
++ printk("Scatter-Gather DMA Test 2\n");
++ printk(" \n");
++ printk("*************************************************************\n");
++
++ printk("seg0 0x%08x, %lu\n", (u32)src_data0, src_data0_len);
++ printk("seg1 0x%08x, %lu\n", (u32)src_data1, src_data1_len);
++
++ for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
++ channels[i] = oxnas_dma_request(0);
++ if (channels[i] == OXNAS_DMA_CHANNEL_NUL) {
++ printk("No DMA channels[%d] obtained\n", i);
++ } else {
++ printk("Obtained DMA channels[%d] %u, isActive=%d\n", i, channels[i]->channel_number_, oxnas_dma_is_active(channels[i]));
++ }
++ }
++
++ // Test each available DMA channel
++ for (channel_number=0; channel_number < MAX_OXNAS_DMA_CHANNELS; ++channel_number) {
++
++ struct scatterlist* src_scatterlist = (struct scatterlist*)kmalloc(sizeof(struct scatterlist) * 2, GFP_KERNEL);
++
++ unsigned long total_src_length = src_data0_len + src_data1_len;
++ src_scatterlist[0].offset = (unsigned int)kmalloc(total_src_length, GFP_KERNEL | GFP_DMA) + src_offset;
++ src_scatterlist[0].length = src_data0_len - src_offset;
++ memcpy((u8*)src_scatterlist[0].offset, src_data0, src_scatterlist[0].length);
++
++ src_scatterlist[1].offset = src_scatterlist[0].offset + src_scatterlist[0].length;
++ src_scatterlist[1].length = src_data1_len;
++ memcpy((u8*)src_scatterlist[1].offset, src_data1, src_scatterlist[1].length);
++
++ unsigned long total_dst_length = total_src_length - src_offset; // Excludes initial IP quad alignment pad
++ unsigned num_dst_buffers = total_dst_length / dst_buffer_size;
++ if ((num_dst_buffers * dst_buffer_size) < total_dst_length) {
++ ++num_dst_buffers;
++ }
++ printk("total_src_length = %lu, src_offset = %u, total_dst_length = %lu, dst_buffer_size = %u, num_dst_buffers = %u\n", total_src_length, src_offset, total_dst_length, dst_buffer_size, num_dst_buffers);
++ struct scatterlist* dst_scatterlist = (struct scatterlist*)kmalloc(sizeof(struct scatterlist) * num_dst_buffers, GFP_KERNEL);
++
++ int i;
++ unsigned long remainder = total_dst_length;
++ for (i=0; i < num_dst_buffers; ++i) {
++ dst_scatterlist[i].offset = (unsigned int)kmalloc(dst_buffer_size, GFP_KERNEL | GFP_DMA);
++ dst_scatterlist[i].length = (remainder < dst_buffer_size) ? remainder : dst_buffer_size;
++ remainder -= dst_scatterlist[i].length;
++ }
++
++ int j;
++ for (j=0; j < OXNAS_DMA_SG_TEST2_ITERATIONS; ++j) {
++ src_scatterlist[0].dma_address = dma_map_single(0, (void*)src_scatterlist[0].offset, src_scatterlist[0].length, DMA_TO_DEVICE);
++ if (dma_mapping_error(src_scatterlist[0].dma_address)) {
++ printk("Consistent source DMA mapping 0 failed\n");
++ }
++ // Set the checksum enabling high order address bit
++ //src_scatterlist[0].dma_address |= (1UL << OXNAS_DMA_CSUM_ENABLE_ADR_BIT);
++
++ src_scatterlist[1].dma_address = dma_map_single(0, (void*)src_scatterlist[1].offset, src_scatterlist[1].length, DMA_TO_DEVICE);
++ if (dma_mapping_error(src_scatterlist[1].dma_address)) {
++ printk("Consistent source DMA mapping 1 failed\n");
++ }
++ // Set the checksum enabling high order address bit
++ src_scatterlist[1].dma_address |= (1UL << OXNAS_DMA_CSUM_ENABLE_ADR_BIT);
++
++ printk("num_dst_buffers = %u\n", num_dst_buffers);
++ for (i=0; i < num_dst_buffers; i++) {
++ memset((void*)dst_scatterlist[i].offset, 0, dst_scatterlist[i].length);
++
++ dst_scatterlist[i].dma_address = dma_map_single(0, (void*)dst_scatterlist[i].offset, dst_scatterlist[i].length, DMA_BIDIRECTIONAL);
++ if (dma_mapping_error(dst_scatterlist[i].dma_address)) {
++ printk("Consistent destination DMA mapping %d failed\n", i);
++ }
++ }
++
++ // Setup up SG DMA transfer
++ printk("Setting up transfer\n");
++ oxnas_dma_set_sg(
++ channels[channel_number],
++ src_scatterlist,
++ 2,
++ dst_scatterlist,
++ num_dst_buffers,
++ OXNAS_DMA_MODE_INC,
++ OXNAS_DMA_MODE_INC,
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ 1); // Compute checksum
++#else // CONFIG_OXNAS_VERSION_0X800
++ 0);
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++ // Using second DMA channel requested
++ oxnas_dma_set_callback(channels[channel_number], dma_callback, OXNAS_DMA_CALLBACK_ARG_NUL);
++
++ // Start the transfer
++ printk("Starting the transfer\n");
++ oxnas_dma_start(channels[channel_number]);
++
++ // Sleep until transfer completed
++ printk("Waiting for transfer to complete...\n");
++ while (down_interruptible(&callback_semaphore));
++ oxnas_dma_set_callback(channels[channel_number], OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
++
++ printk("Error code = %u\n", channels[channel_number]->error_code_);
++
++ // Release the consistent DMA mappings for the source buffers
++ for (i=0; i < 2; i++) {
++ // Ensure the checksum enabling high order address bit is not set, as
++ // this would confuse the DMA mapping release function
++ src_scatterlist[i].dma_address &= ~(1UL << OXNAS_DMA_CSUM_ENABLE_ADR_BIT);
++ dma_unmap_single(0, src_scatterlist[i].dma_address, src_scatterlist[i].length, DMA_TO_DEVICE);
++ }
++
++ // Release the consistent DMA mappings for the destination buffers
++ for (i=0; i < num_dst_buffers; i++) {
++ printk("Releasing DMA mappings for destination entry buffer %u\n", i);
++ dma_unmap_single(0, dst_scatterlist[i].dma_address, dst_scatterlist[i].length, DMA_BIDIRECTIONAL);
++ }
++
++ u32 sw_csum = 0;
++ //sw_csum = csum_partial((u8*)src_scatterlist[0].offset, src_scatterlist[0].length, 0);
++ sw_csum = csum_partial((u8*)src_scatterlist[1].offset, src_scatterlist[1].length, sw_csum);
++ printk("S/W generated src csum = 0x%04hx\n", csum_fold(sw_csum));
++
++ sw_csum = 0;
++ unsigned offset = src_scatterlist[0].length;
++ //unsigned offset = 0;
++ for (i=0; i < num_dst_buffers; i++) {
++ sw_csum = csum_partial((u8*)dst_scatterlist[i].offset + offset, dst_scatterlist[i].length - offset, sw_csum);
++ offset = 0;
++ }
++ printk("S/W generated dst csum = 0x%04hx\n", csum_fold(sw_csum));
++ }
++
++ for (i=0; i < num_dst_buffers; ++i) {
++ kfree((void*)dst_scatterlist[i].offset);
++ }
++ kfree(dst_scatterlist);
++
++ kfree((void*)(src_scatterlist[0].offset - src_offset));
++ kfree(src_scatterlist);
++ }
++
++ for (i=0; i < MAX_OXNAS_DMA_CHANNELS; ++i) {
++ oxnas_dma_free(channels[i]);
++ }
++}
++#endif // OXNAS_DMA_SG_TEST_2
++#endif // defined(OXNAS_DMA_TEST) || defined(OXNAS_DMA_SG_TEST)
++
++EXPORT_SYMBOL(oxnas_dma_request);
++EXPORT_SYMBOL(oxnas_dma_free);
++EXPORT_SYMBOL(oxnas_dma_set_callback);
++EXPORT_SYMBOL(oxnas_dma_set_common);
++EXPORT_SYMBOL(oxnas_dma_is_active);
++EXPORT_SYMBOL(oxnas_dma_raw_isactive);
++EXPORT_SYMBOL(oxnas_dma_set);
++EXPORT_SYMBOL(oxnas_dma_device_set);
++EXPORT_SYMBOL(oxnas_dma_abort);
++EXPORT_SYMBOL(oxnas_dma_dump_registers);
++EXPORT_SYMBOL(oxnas_dma_dump_registers_single);
++EXPORT_SYMBOL(oxnas_dma_start);
++
++EXPORT_SYMBOL(oxnas_pata_dma_settings);
++EXPORT_SYMBOL(oxnas_sata_dma_settings);
++EXPORT_SYMBOL(oxnas_dpe_rx_dma_settings);
++EXPORT_SYMBOL(oxnas_dpe_tx_dma_settings);
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/dpe_test.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/dpe_test.c
+--- linux-2.6.24/arch/arm/mach-oxnas/dpe_test.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/dpe_test.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,3051 @@
++/*
++ * /arch/=arm/mach-oxnas/dpe-test.c
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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
++ */
++
++/**
++ * Test driver for the cipher core
++ *
++ */
++
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/interrupt.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/device.h>
++#include <linux/string.h>
++#include <linux/sysdev.h>
++#include <linux/fs.h>
++#include <asm/arch/cipher.h>
++#include <asm/io.h>
++#include <asm/arch/hardware.h>
++#include <linux/dma-mapping.h>
++#include <asm/arch/dma.h>
++
++/***************************************************************************
++* CONSTANTS
++***************************************************************************/
++#define DRIVER_AUTHOR "Oxford Semiconductor Inc."
++#define DRIVER_DESC "Cipher block testing"
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
++
++// uses /dev/dv940led
++#define DEVICE_NAME "ox800dpetst"
++MODULE_SUPPORTED_DEVICE(DEVICE_NAME);
++
++#define FAILED(reason) {printk(KERN_ERR"%s failed %s\n",__FUNCTION__,reason);++failed;}
++/**************************************************************************
++* PROTOTYPES
++**************************************************************************/
++#if 0
++static u32 READL(int a) {u32 v = readl(a);printk("0x%08x <- [0x%08x]\n",v,a);return v;}
++static void WRITEL(int v,int a){printk("0x%08x -> [0x%08x]\n",v,a);writel(v,a);}
++#else
++static u32 READL(int a) {u32 v = readl(a);return v;}
++static void WRITEL(int v,int a){writel(v,a);}
++#endif
++/**************************************************************************
++* STRUCTURES
++**************************************************************************/
++typedef int (ox800dpe_test_t)(void) ;
++
++/**************************************************************************
++* FUCTIONS
++* prefix all with "ox800dpe"
++**************************************************************************/
++
++/*************************************************************************/
++static int test1(void) {
++ int failed = 0;
++ u32 reg;
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC | OX800DPE_CTL_MODE_ECB_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // 1st data set
++ WRITEL(be32_to_cpu( 0x00112233), OX800DPE_DATA_IN0 );
++
++ /* in fifo no longer empty */
++ reg = READL( OX800DPE_STATUS );
++ if ( (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo still empty after data input")
++
++ WRITEL(be32_to_cpu( 0x44556677), OX800DPE_DATA_IN1 );
++ WRITEL(be32_to_cpu( 0x8899aabb), OX800DPE_DATA_IN2 );
++
++ // shouldn't be busy as not enough data
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("core lept into action before putting in all the data");
++
++ WRITEL(be32_to_cpu( 0xccddeeff), OX800DPE_DATA_IN3 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be full */
++ if ( !(reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still empty after encrypting data ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ /* check output */
++ {
++ u32 data[4];
++
++ data[0] = READL( OX800DPE_DATA_OUT0 );
++ data[1] = READL( OX800DPE_DATA_OUT1 );
++ data[2] = READL( OX800DPE_DATA_OUT2 );
++ data[3] = READL( OX800DPE_DATA_OUT3 );
++
++ if ((data[0] != cpu_to_be32(0x69c4e0d8)) ||
++ (data[1] != cpu_to_be32(0x6a7b0430)) ||
++ (data[2] != cpu_to_be32(0xd8cdb780)) ||
++ (data[3] != cpu_to_be32(0x70b4c55a)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data[0],data[1],data[2],data[3]);
++ }
++ }
++
++ /* output should be empty again */
++ reg = READL( OX800DPE_STATUS );
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after data read");
++
++ return failed;
++
++}
++
++/*************************************************************************/
++static int test2(void) {
++ int failed = 0;
++ u32 reg;
++ oxnas_dma_channel_t* dma_in;
++ oxnas_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = oxnas_dma_request(1);
++ dma_out = oxnas_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x00112233);
++ data_in[1] = be32_to_cpu( 0x44556677);
++ data_in[2] = be32_to_cpu( 0x8899aabb);
++ data_in[3] = be32_to_cpu( 0xccddeeff);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ oxnas_dma_device_set(
++ dma_in,
++ OXNAS_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_rx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ oxnas_dma_device_set(
++ dma_out,
++ OXNAS_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_tx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC | OX800DPE_CTL_MODE_ECB_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ oxnas_dma_start(dma_out);
++ oxnas_dma_start(dma_in);
++
++ /* wait until done */
++ while( oxnas_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[0] != cpu_to_be32(0x69c4e0d8)) ||
++ (data_out[1] != cpu_to_be32(0x6a7b0430)) ||
++ (data_out[2] != cpu_to_be32(0xd8cdb780)) ||
++ (data_out[3] != cpu_to_be32(0x70b4c55a)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ oxnas_dma_free( dma_in );
++ oxnas_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/*************************************************************************/
++static int test3(void) {
++ int failed = 0;
++ u32 reg;
++ oxnas_dma_channel_t* dma_in;
++ oxnas_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = oxnas_dma_request(1);
++ dma_out = oxnas_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x69c4e0d8);
++ data_in[1] = be32_to_cpu( 0x6a7b0430);
++ data_in[2] = be32_to_cpu( 0xd8cdb780);
++ data_in[3] = be32_to_cpu( 0x70b4c55a);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ oxnas_dma_device_set(
++ dma_in,
++ OXNAS_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_rx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ oxnas_dma_device_set(
++ dma_out,
++ OXNAS_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_tx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for decryption
++ reg = OX800DPE_CTL_MODE_ECB_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ oxnas_dma_start(dma_out);
++ oxnas_dma_start(dma_in);
++
++ /* wait until dma done */
++ while( oxnas_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[0] != cpu_to_be32(0x00112233)) ||
++ (data_out[1] != cpu_to_be32(0x44556677)) ||
++ (data_out[2] != cpu_to_be32(0x8899aabb)) ||
++ (data_out[3] != cpu_to_be32(0xccddeeff)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ oxnas_dma_free( dma_in );
++ oxnas_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++/*************************************************************************/
++static int test4(void) {
++ int failed = 0;
++ u32 reg;
++ oxnas_dma_channel_t* dma_out;
++ dma_addr_t out_address;
++
++ u32* data_out;
++
++ // setup dmas
++ dma_out = oxnas_dma_request(1);
++
++ // get some dma accessable memory
++ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with non expected output
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ oxnas_dma_device_set(
++ dma_out,
++ OXNAS_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_tx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for decryption
++ reg = OX800DPE_CTL_PRIMARY_IS_KEY3 | OX800DPE_CTL_MODE_ECB_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY20 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY21 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY22 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY23 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ oxnas_dma_start(dma_out);
++
++ // 1st data set
++ WRITEL(be32_to_cpu( 0x69c4e0d8), OX800DPE_DATA_IN0 );
++ WRITEL(be32_to_cpu( 0x6a7b0430), OX800DPE_DATA_IN1 );
++ WRITEL(be32_to_cpu( 0xd8cdb780), OX800DPE_DATA_IN2 );
++ WRITEL(be32_to_cpu( 0x70b4c55a), OX800DPE_DATA_IN3 );
++
++ /* wait until done */
++ while( oxnas_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[0] != cpu_to_be32(0x00112233)) ||
++ (data_out[1] != cpu_to_be32(0x44556677)) ||
++ (data_out[2] != cpu_to_be32(0x8899aabb)) ||
++ (data_out[3] != cpu_to_be32(0xccddeeff)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ oxnas_dma_free( dma_out );
++ kfree(data_out);
++
++ return failed;
++
++}
++
++/*************************************************************************/
++static int test5(void) {
++ int failed = 0;
++ u32 reg;
++ oxnas_dma_channel_t* dma_in;
++ dma_addr_t in_address;
++
++ u32* data_in;
++
++ // setup dmas
++ dma_in = oxnas_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x00112233);
++ data_in[1] = be32_to_cpu( 0x44556677);
++ data_in[2] = be32_to_cpu( 0x8899aabb);
++ data_in[3] = be32_to_cpu( 0xccddeeff);
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // setup the transfers
++ oxnas_dma_device_set(
++ dma_in,
++ OXNAS_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_rx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_MODE_ECB_AES |
++ OX800DPE_CTL_PRIMARY_IS_KEY3 ;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY20 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY21 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY22 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY23 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ oxnas_dma_start(dma_in);
++
++ /* wait until done */
++ while( oxnas_dma_is_active( dma_in ) );
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be full */
++ if ( !(reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still empty after encrypting data ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++
++ /* check output */
++ {
++ u32 data[4];
++
++ data[0] = READL( OX800DPE_DATA_OUT0 );
++ data[1] = READL( OX800DPE_DATA_OUT1 );
++ data[2] = READL( OX800DPE_DATA_OUT2 );
++ data[3] = READL( OX800DPE_DATA_OUT3 );
++
++ if ((data[0] != cpu_to_be32(0x69c4e0d8)) ||
++ (data[1] != cpu_to_be32(0x6a7b0430)) ||
++ (data[2] != cpu_to_be32(0xd8cdb780)) ||
++ (data[3] != cpu_to_be32(0x70b4c55a)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data[0],data[1],data[2],data[3]);
++ }
++ }
++
++ /* output should be empty again */
++ reg = READL( OX800DPE_STATUS );
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after data read");
++
++ // free dmas
++ kfree(data_in);
++
++ oxnas_dma_free( dma_in );
++
++ return failed;
++
++}
++
++/*************************************************************************/
++static int test6(void) {
++ int failed = 0;
++ u32 reg;
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for key encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_ENCRYPT_KEY |
++ OX800DPE_CTL_MODE_ECB_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++ // data to be encrypted to form a key
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_DATA_IN0 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_DATA_IN1 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_DATA_IN2 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_DATA_IN3 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ /* output should be empty */
++ reg = READL( OX800DPE_STATUS );
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ {
++ u32 data[4];
++
++ data[0] = READL( OX800DPE_KEY00 );
++ data[1] = READL( OX800DPE_KEY01 );
++ data[2] = READL( OX800DPE_KEY02 );
++ data[3] = READL( OX800DPE_KEY03 );
++
++ if ((data[0] != cpu_to_be32(0x4791b833)) ||
++ (data[1] != cpu_to_be32(0x7e2d8a69)) ||
++ (data[2] != cpu_to_be32(0x290233f1)) ||
++ (data[3] != cpu_to_be32(0xf3dff5a9)))
++ {
++ FAILED("encrypted key incorrect");
++ printk("%08x%08x%08x%08x\n",data[0],data[1],data[2],data[3]);
++ }
++ }
++
++ return failed;
++
++}
++
++
++/*************************************************************************/
++static int test7(void) {
++ int failed = 0;
++ u32 reg;
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // setup for key encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_ENCRYPT_KEY |
++ OX800DPE_CTL_MODE_ECB_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++ // data to be encrypted to form a key
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_DATA_IN0 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_DATA_IN1 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_DATA_IN2 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_DATA_IN3 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ /* output should be empty */
++ reg = READL( OX800DPE_STATUS );
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ {
++ u32 data[4];
++
++ data[0] = READL( OX800DPE_KEY00 );
++ data[1] = READL( OX800DPE_KEY01 );
++ data[2] = READL( OX800DPE_KEY02 );
++ data[3] = READL( OX800DPE_KEY03 );
++
++ if ((data[0] != cpu_to_be32(0x4791b833)) ||
++ (data[1] != cpu_to_be32(0x7e2d8a69)) ||
++ (data[2] != cpu_to_be32(0x290233f1)) ||
++ (data[3] != cpu_to_be32(0xf3dff5a9)))
++ {
++ FAILED("encrypted key incorrect");
++ printk("%08x%08x%08x%08x\n",data[0],data[1],data[2],data[3]);
++ }
++ }
++
++ return failed;
++
++}
++
++
++
++/**********************************************************************/
++/* CBC tests */
++/**********************************************************************/
++
++static int test8(void) {
++ int failed = 0;
++ u32 reg;
++ oxnas_dma_channel_t* dma_in;
++ oxnas_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = oxnas_dma_request(1);
++ dma_out = oxnas_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x00112233);
++ data_in[1] = be32_to_cpu( 0x44556677);
++ data_in[2] = be32_to_cpu( 0x8899aabb);
++ data_in[3] = be32_to_cpu( 0xccddeeff);
++ data_in[4] = be32_to_cpu( 0x00112233);
++ data_in[5] = be32_to_cpu( 0x44556677);
++ data_in[6] = be32_to_cpu( 0x8899aabb);
++ data_in[7] = be32_to_cpu( 0xccddeeff);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++ data_out[4] = ~0;
++ data_out[5] = ~0;
++ data_out[6] = ~0;
++ data_out[7] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 8 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 8 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ oxnas_dma_device_set(
++ dma_in,
++ OXNAS_DMA_TO_DEVICE,
++ (char*)in_address,
++ 8 * sizeof(u32),
++ &oxnas_dpe_rx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ oxnas_dma_device_set(
++ dma_out,
++ OXNAS_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 8 * sizeof(u32),
++ &oxnas_dpe_tx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_MODE_CBC_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // setup initialisation vector
++ WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC0 );
++ WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC1 );
++
++ // start dma transfers
++ oxnas_dma_start(dma_out);
++ oxnas_dma_start(dma_in);
++
++ /* wait until dma done */
++ while( oxnas_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 8 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 8 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[0] != cpu_to_be32(0x69c4e0d8)) ||
++ (data_out[1] != cpu_to_be32(0x6a7b0430)) ||
++ (data_out[2] != cpu_to_be32(0xd8cdb780)) ||
++ (data_out[3] != cpu_to_be32(0x70b4c55a)) ||
++
++ (data_out[4] != cpu_to_be32(0x7d7786be)) ||
++ (data_out[5] != cpu_to_be32(0x32d059a6)) ||
++ (data_out[6] != cpu_to_be32(0x0ca8021a)) ||
++ (data_out[7] != cpu_to_be32(0x65dd9f09)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ printk("%08x%08x%08x%08x\n",data_out[4],data_out[5],data_out[6],data_out[7]);
++ }
++
++ // free dmas
++ oxnas_dma_free( dma_in );
++ oxnas_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/*************************************************************************/
++static int test9(void) {
++ int failed = 0;
++ u32 reg;
++ oxnas_dma_channel_t* dma_in;
++ oxnas_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = oxnas_dma_request(1);
++ dma_out = oxnas_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x69c4e0d8);
++ data_in[1] = be32_to_cpu( 0x6a7b0430);
++ data_in[2] = be32_to_cpu( 0xd8cdb780);
++ data_in[3] = be32_to_cpu( 0x70b4c55a);
++ data_in[4] = be32_to_cpu( 0x7d7786be);
++ data_in[5] = be32_to_cpu( 0x32d059a6);
++ data_in[6] = be32_to_cpu( 0x0ca8021a);
++ data_in[7] = be32_to_cpu( 0x65dd9f09);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++ data_out[4] = ~0;
++ data_out[5] = ~0;
++ data_out[6] = ~0;
++ data_out[7] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 8 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 8 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ oxnas_dma_device_set(
++ dma_in,
++ OXNAS_DMA_TO_DEVICE,
++ (char*)in_address,
++ 8 * sizeof(u32),
++ &oxnas_dpe_rx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ oxnas_dma_device_set(
++ dma_out,
++ OXNAS_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 8 * sizeof(u32),
++ &oxnas_dpe_tx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for decryption
++ reg = OX800DPE_CTL_MODE_CBC_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // setup initialisation vector
++ WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC0 );
++ WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC1 );
++
++ // start dma transfers
++ oxnas_dma_start(dma_out);
++ oxnas_dma_start(dma_in);
++
++ /* wait until done */
++ while( oxnas_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 8 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 8 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[0] != cpu_to_be32(0x00112233)) ||
++ (data_out[1] != cpu_to_be32(0x44556677)) ||
++ (data_out[2] != cpu_to_be32(0x8899aabb)) ||
++ (data_out[3] != cpu_to_be32(0xccddeeff)) ||
++ (data_out[4] != cpu_to_be32(0x00112233)) ||
++ (data_out[5] != cpu_to_be32(0x44556677)) ||
++ (data_out[6] != cpu_to_be32(0x8899aabb)) ||
++ (data_out[7] != cpu_to_be32(0xccddeeff)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ printk("%08x%08x%08x%08x\n",data_out[4],data_out[5],data_out[6],data_out[7]);
++ }
++
++ // free dmas
++ oxnas_dma_free( dma_in );
++ oxnas_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++/*************************************************************************/
++static int test10(void) {
++ int failed = 0;
++ u32 reg;
++ oxnas_dma_channel_t* dma_in;
++ oxnas_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = oxnas_dma_request(1);
++ dma_out = oxnas_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x00112233);
++ data_in[1] = be32_to_cpu( 0x44556677);
++ data_in[2] = be32_to_cpu( 0x8899aabb);
++ data_in[3] = be32_to_cpu( 0xccddeeff);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ oxnas_dma_device_set(
++ dma_in,
++ OXNAS_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_rx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ oxnas_dma_device_set(
++ dma_out,
++ OXNAS_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_tx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_MODE_CBC_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // setup initialisation vector
++ WRITEL(be32_to_cpu(~0), OX800DPE_DATA_CBC0 );
++ WRITEL(be32_to_cpu(~0), OX800DPE_DATA_CBC1 );
++
++ // start dma transfers
++ oxnas_dma_start(dma_out);
++ oxnas_dma_start(dma_in);
++
++ /* wait until done */
++ while( oxnas_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[0] != cpu_to_be32(0x0bde5b88)) ||
++ (data_out[1] != cpu_to_be32(0x114ac430)) ||
++ (data_out[2] != cpu_to_be32(0x134e99ee)) ||
++ (data_out[3] != cpu_to_be32(0xd3557046)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ oxnas_dma_free( dma_in );
++ oxnas_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/*************************************************************************/
++static int test11(void) {
++ int failed = 0;
++ u32 reg;
++ oxnas_dma_channel_t* dma_in;
++ oxnas_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = oxnas_dma_request(1);
++ dma_out = oxnas_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x69c4e0d8);
++ data_in[1] = be32_to_cpu( 0x6a7b0430);
++ data_in[2] = be32_to_cpu( 0xd8cdb780);
++ data_in[3] = be32_to_cpu( 0x70b4c55a);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ oxnas_dma_device_set(
++ dma_in,
++ OXNAS_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_rx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ oxnas_dma_device_set(
++ dma_out,
++ OXNAS_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_tx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for decryption
++ reg = OX800DPE_CTL_MODE_CBC_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // setup initialisation vector
++ WRITEL(be32_to_cpu(~0), OX800DPE_DATA_CBC0 );
++ WRITEL(be32_to_cpu(~0), OX800DPE_DATA_CBC1 );
++
++ // start dma transfers
++ oxnas_dma_start(dma_out);
++ oxnas_dma_start(dma_in);
++
++ /* wait until done */
++ while( oxnas_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[0] != cpu_to_be32(0x00112233)) ||
++ (data_out[1] != cpu_to_be32(0x44556677)) ||
++ (data_out[2] != cpu_to_be32(0x8899aab4)) ||
++ (data_out[3] != cpu_to_be32(0x33221100)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ oxnas_dma_free( dma_in );
++ oxnas_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++/*************************************************************************/
++static int test12(void) {
++ int failed = 0;
++ u32 reg;
++ oxnas_dma_channel_t* dma_in;
++ oxnas_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = oxnas_dma_request(1);
++ dma_out = oxnas_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x00112233);
++ data_in[1] = be32_to_cpu( 0x44556677);
++ data_in[2] = be32_to_cpu( 0x8899aabb);
++ data_in[3] = be32_to_cpu( 0xccddeeff);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ oxnas_dma_device_set(
++ dma_in,
++ OXNAS_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_rx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ oxnas_dma_device_set(
++ dma_out,
++ OXNAS_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_tx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_MODE_CBC_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // setup initialisation vector
++ WRITEL(be32_to_cpu(1), OX800DPE_DATA_CBC0 );
++ WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC1 );
++
++ // start dma transfers
++ oxnas_dma_start(dma_out);
++ oxnas_dma_start(dma_in);
++
++ /* wait until done */
++ while( oxnas_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++
++
++
++
++ /* check output */
++ if ((data_out[0] != 0x850d2506) ||
++ (data_out[1] != 0xd71056c7) ||
++ (data_out[2] != 0xe62c220f) ||
++ (data_out[3] != 0xc3dedaf9))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ oxnas_dma_free( dma_in );
++ oxnas_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/*************************************************************************/
++static int test13(void) {
++ int failed = 0;
++ u32 reg;
++ oxnas_dma_channel_t* dma_in;
++ oxnas_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = oxnas_dma_request(1);
++ dma_out = oxnas_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = 0x850d2506;
++ data_in[1] = 0xd71056c7;
++ data_in[2] = 0xe62c220f;
++ data_in[3] = 0xc3dedaf9;
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ oxnas_dma_device_set(
++ dma_in,
++ OXNAS_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_rx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ oxnas_dma_device_set(
++ dma_out,
++ OXNAS_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_tx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for decryption
++ reg = OX800DPE_CTL_MODE_CBC_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ reg = READL( OX800DPE_STATUS );
++ // shouldn't be busy
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle even with incomplete data");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx not empty before data input ");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx fifo filling without data");
++
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x00010203), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0x04050607), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x08090a0b), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x0c0d0e0f), OX800DPE_KEY03 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // setup initialisation vector
++ WRITEL(be32_to_cpu(1), OX800DPE_DATA_CBC0 );
++ WRITEL(be32_to_cpu(0), OX800DPE_DATA_CBC1 );
++
++ // start dma transfers
++ oxnas_dma_start(dma_out);
++ oxnas_dma_start(dma_in);
++
++ /* wait until done */
++ while( oxnas_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[0] != cpu_to_be32(0x00112233)) ||
++ (data_out[1] != cpu_to_be32(0x44556677)) ||
++ (data_out[2] != cpu_to_be32(0x8899aabb)) ||
++ (data_out[3] != cpu_to_be32(0xccddeeff)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ oxnas_dma_free( dma_in );
++ oxnas_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/**********************************************************************/
++/* LRW tests */
++/**********************************************************************/
++
++static int test14(void) {
++ int failed = 0;
++ u32 reg;
++ oxnas_dma_channel_t* dma_in;
++ oxnas_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = oxnas_dma_request(1);
++ dma_out = oxnas_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x30313233);
++ data_in[1] = be32_to_cpu( 0x34353637);
++ data_in[2] = be32_to_cpu( 0x38394142);
++ data_in[3] = be32_to_cpu( 0x43444546);
++ data_in[4] = be32_to_cpu( 0x30313233);
++ data_in[5] = be32_to_cpu( 0x34353637);
++ data_in[6] = be32_to_cpu( 0x38394142);
++ data_in[7] = be32_to_cpu( 0x43444546);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++ data_out[4] = ~0;
++ data_out[5] = ~0;
++ data_out[6] = ~0;
++ data_out[7] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 8 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 8 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ oxnas_dma_device_set(
++ dma_in,
++ OXNAS_DMA_TO_DEVICE,
++ (char*)in_address,
++ 8 * sizeof(u32),
++ &oxnas_dpe_rx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ oxnas_dma_device_set(
++ dma_out,
++ OXNAS_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 8 * sizeof(u32),
++ &oxnas_dpe_tx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_MODE_LRW_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x4562ac25), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0xf828176d), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x4c268414), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0xb5680185), OX800DPE_KEY03 );
++
++ // key no 2
++ WRITEL(be32_to_cpu( 0x258e2a05), OX800DPE_KEY10 );
++ WRITEL(be32_to_cpu( 0xe73e9d03), OX800DPE_KEY11 );
++ WRITEL(be32_to_cpu( 0xee5a830c), OX800DPE_KEY12 );
++ WRITEL(be32_to_cpu( 0xcc094c87), OX800DPE_KEY13 );
++
++ // setup index
++ WRITEL(0, OX800DPE_DATA_LRW0 );
++ WRITEL(0, OX800DPE_DATA_LRW1 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ oxnas_dma_start(dma_out);
++ oxnas_dma_start(dma_in);
++
++ /* wait until dma done */
++ while( oxnas_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 8 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 8 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /*
++ check output.
++ note: first 4 quads contain unwanted data used to set
++ tweek location to 1, they are not checked.
++ */
++ if ((data_out[4] != cpu_to_be32(0xf1b273cd)) ||
++ (data_out[5] != cpu_to_be32(0x65a3df5f)) ||
++ (data_out[6] != cpu_to_be32(0xe95d4892)) ||
++ (data_out[7] != cpu_to_be32(0x54634eb8)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ printk("%08x%08x%08x%08x\n",data_out[4],data_out[5],data_out[6],data_out[7]);
++ }
++
++ // free dmas
++ oxnas_dma_free( dma_in );
++ oxnas_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/*************************************************************************/
++static int test15(void) {
++ int failed = 0;
++ u32 reg;
++ oxnas_dma_channel_t* dma_in;
++ oxnas_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = oxnas_dma_request(1);
++ dma_out = oxnas_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0xf1b273cd);
++ data_in[1] = be32_to_cpu( 0x65a3df5f);
++ data_in[2] = be32_to_cpu( 0xe95d4892);
++ data_in[3] = be32_to_cpu( 0x54634eb8);
++ data_in[4] = be32_to_cpu( 0xf1b273cd);
++ data_in[5] = be32_to_cpu( 0x65a3df5f);
++ data_in[6] = be32_to_cpu( 0xe95d4892);
++ data_in[7] = be32_to_cpu( 0x54634eb8);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++ data_out[4] = ~0;
++ data_out[5] = ~0;
++ data_out[6] = ~0;
++ data_out[7] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 8 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 8 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ oxnas_dma_device_set(
++ dma_in,
++ OXNAS_DMA_TO_DEVICE,
++ (char*)in_address,
++ 8 * sizeof(u32),
++ &oxnas_dpe_rx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ oxnas_dma_device_set(
++ dma_out,
++ OXNAS_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 8 * sizeof(u32),
++ &oxnas_dpe_tx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for decryption
++ reg = OX800DPE_CTL_MODE_LRW_AES |
++ OX800DPE_CTL_PRIMARY_IS_KEY3;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x4562ac25), OX800DPE_KEY20 );
++ WRITEL(be32_to_cpu( 0xf828176d), OX800DPE_KEY21 );
++ WRITEL(be32_to_cpu( 0x4c268414), OX800DPE_KEY22 );
++ WRITEL(be32_to_cpu( 0xb5680185), OX800DPE_KEY23 );
++
++ // key no 2
++ WRITEL(be32_to_cpu( 0x258e2a05), OX800DPE_KEY10 );
++ WRITEL(be32_to_cpu( 0xe73e9d03), OX800DPE_KEY11 );
++ WRITEL(be32_to_cpu( 0xee5a830c), OX800DPE_KEY12 );
++ WRITEL(be32_to_cpu( 0xcc094c87), OX800DPE_KEY13 );
++
++ // setup index
++ WRITEL(0, OX800DPE_DATA_LRW0 );
++ WRITEL(0, OX800DPE_DATA_LRW1 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ oxnas_dma_start(dma_out);
++ oxnas_dma_start(dma_in);
++
++ /* wait until done */
++ while( oxnas_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 8 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 8 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[4] != cpu_to_be32(0x30313233)) ||
++ (data_out[5] != cpu_to_be32(0x34353637)) ||
++ (data_out[6] != cpu_to_be32(0x38394142)) ||
++ (data_out[7] != cpu_to_be32(0x43444546)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ printk("%08x%08x%08x%08x\n",data_out[4],data_out[5],data_out[6],data_out[7]);
++ }
++
++ // free dmas
++ oxnas_dma_free( dma_in );
++ oxnas_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++/*************************************************************************/
++static int test16(void) {
++ int failed = 0;
++ u32 reg;
++ oxnas_dma_channel_t* dma_in;
++ oxnas_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = oxnas_dma_request(1);
++ dma_out = oxnas_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 12 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 12 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[8 ] = be32_to_cpu( 0x30313233);
++ data_in[9 ] = be32_to_cpu( 0x34353637);
++ data_in[10] = be32_to_cpu( 0x38394142);
++ data_in[11] = be32_to_cpu( 0x43444546);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++ data_out[4] = ~0;
++ data_out[5] = ~0;
++ data_out[6] = ~0;
++ data_out[7] = ~0;
++ data_out[8] = ~0;
++ data_out[9] = ~0;
++ data_out[10] = ~0;
++ data_out[11] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 12 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 12 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ oxnas_dma_device_set(
++ dma_in,
++ OXNAS_DMA_TO_DEVICE,
++ (char*)in_address,
++ 12 * sizeof(u32),
++ &oxnas_dpe_rx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ oxnas_dma_device_set(
++ dma_out,
++ OXNAS_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 12 * sizeof(u32),
++ &oxnas_dpe_tx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_PRIMARY_IS_KEY3 |
++ OX800DPE_CTL_MODE_LRW_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x59704714), OX800DPE_KEY20 );
++ WRITEL(be32_to_cpu( 0xf557478c), OX800DPE_KEY21 );
++ WRITEL(be32_to_cpu( 0xd779e80f), OX800DPE_KEY22 );
++ WRITEL(be32_to_cpu( 0x54887944), OX800DPE_KEY23 );
++
++ // key no 2
++ WRITEL(be32_to_cpu( 0x0d48f0b7), OX800DPE_KEY10 );
++ WRITEL(be32_to_cpu( 0xb15a53ea), OX800DPE_KEY11 );
++ WRITEL(be32_to_cpu( 0x1caa6b29), OX800DPE_KEY12 );
++ WRITEL(be32_to_cpu( 0xc2cafbaf), OX800DPE_KEY13 );
++
++ // setup index
++ WRITEL(0, OX800DPE_DATA_LRW0 );
++ WRITEL(0, OX800DPE_DATA_LRW1 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ oxnas_dma_start(dma_out);
++ oxnas_dma_start(dma_in);
++
++ /* wait until dma done */
++ while( oxnas_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 12 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 12 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /*
++ check output.
++ note: first 4 quads contain unwanted data used to set
++ tweek location to 1, they are not checked.
++ */
++ if ((data_out[ 8] != cpu_to_be32(0x00c82bae)) ||
++ (data_out[ 9] != cpu_to_be32(0x95bbcde5)) ||
++ (data_out[10] != cpu_to_be32(0x274f0769)) ||
++ (data_out[11] != cpu_to_be32(0xb260e136)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[8],data_out[9],data_out[10],data_out[11]);
++ }
++
++ // free dmas
++ oxnas_dma_free( dma_in );
++ oxnas_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/*************************************************************************/
++static int test17(void) {
++ int failed = 0;
++ u32 reg;
++ oxnas_dma_channel_t* dma_in;
++ oxnas_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = oxnas_dma_request(1);
++ dma_out = oxnas_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 12 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 12 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[ 8] = be32_to_cpu( 0x00c82bae);
++ data_in[ 9] = be32_to_cpu( 0x95bbcde5);
++ data_in[10] = be32_to_cpu( 0x274f0769);
++ data_in[11] = be32_to_cpu( 0xb260e136);
++ data_out[ 0] = ~0;
++ data_out[ 1] = ~0;
++ data_out[ 2] = ~0;
++ data_out[ 3] = ~0;
++ data_out[ 4] = ~0;
++ data_out[ 5] = ~0;
++ data_out[ 6] = ~0;
++ data_out[ 7] = ~0;
++ data_out[ 8] = ~0;
++ data_out[ 9] = ~0;
++ data_out[10] = ~0;
++ data_out[11] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 12 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 12 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ oxnas_dma_device_set(
++ dma_in,
++ OXNAS_DMA_TO_DEVICE,
++ (char*)in_address,
++ 12 * sizeof(u32),
++ &oxnas_dpe_rx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ oxnas_dma_device_set(
++ dma_out,
++ OXNAS_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 12 * sizeof(u32),
++ &oxnas_dpe_tx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for decryption
++ reg = OX800DPE_CTL_MODE_LRW_AES ;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x59704714), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0xf557478c), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0xd779e80f), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x54887944), OX800DPE_KEY03 );
++
++ // key no 2
++ WRITEL(be32_to_cpu( 0x0d48f0b7), OX800DPE_KEY10 );
++ WRITEL(be32_to_cpu( 0xb15a53ea), OX800DPE_KEY11 );
++ WRITEL(be32_to_cpu( 0x1caa6b29), OX800DPE_KEY12 );
++ WRITEL(be32_to_cpu( 0xc2cafbaf), OX800DPE_KEY13 );
++
++ // setup index
++ WRITEL(0, OX800DPE_DATA_LRW0 );
++ WRITEL(0, OX800DPE_DATA_LRW1 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ oxnas_dma_start(dma_out);
++ oxnas_dma_start(dma_in);
++
++ /* wait until done */
++ while( oxnas_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 12 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 12 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[ 8] != cpu_to_be32(0x30313233)) ||
++ (data_out[ 9] != cpu_to_be32(0x34353637)) ||
++ (data_out[10] != cpu_to_be32(0x38394142)) ||
++ (data_out[11] != cpu_to_be32(0x43444546)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[8],data_out[9],data_out[10],data_out[11]);
++ }
++
++ // free dmas
++ oxnas_dma_free( dma_in );
++ oxnas_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++/*************************************************************************/
++static int test18(void) {
++ int failed = 0;
++ u32 reg;
++ oxnas_dma_channel_t* dma_in;
++ oxnas_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = oxnas_dma_request(1);
++ dma_out = oxnas_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x30313233);
++ data_in[1] = be32_to_cpu( 0x34353637);
++ data_in[2] = be32_to_cpu( 0x38394142);
++ data_in[3] = be32_to_cpu( 0x43444546);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ oxnas_dma_device_set(
++ dma_in,
++ OXNAS_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_rx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ oxnas_dma_device_set(
++ dma_out,
++ OXNAS_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_tx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_MODE_LRW_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0xd82a9134), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0xb26a5650), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x30fe69e2), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x377f9847), OX800DPE_KEY03 );
++
++ // key no 2
++ WRITEL(be32_to_cpu( 0xcdf90b16), OX800DPE_KEY10 );
++ WRITEL(be32_to_cpu( 0x0c648fb6), OX800DPE_KEY11 );
++ WRITEL(be32_to_cpu( 0xb00d0d1b), OX800DPE_KEY12 );
++ WRITEL(be32_to_cpu( 0xae85871f), OX800DPE_KEY13 );
++
++ // setup index
++ WRITEL(0x10000000, OX800DPE_DATA_LRW0 );
++ WRITEL(0, OX800DPE_DATA_LRW1 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ oxnas_dma_start(dma_out);
++ oxnas_dma_start(dma_in);
++
++ /* wait until dma done */
++ while( oxnas_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /*
++ check output.
++ */
++ if ((data_out[0] != cpu_to_be32(0x76322183)) ||
++ (data_out[1] != cpu_to_be32(0xed8ff182)) ||
++ (data_out[2] != cpu_to_be32(0xf9596203)) ||
++ (data_out[3] != cpu_to_be32(0x690e5e01)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ oxnas_dma_free( dma_in );
++ oxnas_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/*************************************************************************/
++static int test19(void) {
++ int failed = 0;
++ u32 reg;
++ oxnas_dma_channel_t* dma_in;
++ oxnas_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = oxnas_dma_request(1);
++ dma_out = oxnas_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 8 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x76322183);
++ data_in[1] = be32_to_cpu( 0xed8ff182);
++ data_in[2] = be32_to_cpu( 0xf9596203);
++ data_in[3] = be32_to_cpu( 0x690e5e01);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ oxnas_dma_device_set(
++ dma_in,
++ OXNAS_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_rx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ oxnas_dma_device_set(
++ dma_out,
++ OXNAS_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_tx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for decryption
++ reg = OX800DPE_CTL_MODE_LRW_AES |
++ OX800DPE_CTL_PRIMARY_IS_KEY3;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0xd82a9134), OX800DPE_KEY20 );
++ WRITEL(be32_to_cpu( 0xb26a5650), OX800DPE_KEY21 );
++ WRITEL(be32_to_cpu( 0x30fe69e2), OX800DPE_KEY22 );
++ WRITEL(be32_to_cpu( 0x377f9847), OX800DPE_KEY23 );
++
++ // key no 2
++ WRITEL(be32_to_cpu( 0xcdf90b16), OX800DPE_KEY10 );
++ WRITEL(be32_to_cpu( 0x0c648fb6), OX800DPE_KEY11 );
++ WRITEL(be32_to_cpu( 0xb00d0d1b), OX800DPE_KEY12 );
++ WRITEL(be32_to_cpu( 0xae85871f), OX800DPE_KEY13 );
++
++ // setup index
++ WRITEL(0x10000000, OX800DPE_DATA_LRW0 );
++ WRITEL(0, OX800DPE_DATA_LRW1 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ oxnas_dma_start(dma_out);
++ oxnas_dma_start(dma_in);
++
++ /* wait until done */
++ while( oxnas_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[0] != cpu_to_be32(0x30313233)) ||
++ (data_out[1] != cpu_to_be32(0x34353637)) ||
++ (data_out[2] != cpu_to_be32(0x38394142)) ||
++ (data_out[3] != cpu_to_be32(0x43444546)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ oxnas_dma_free( dma_in );
++ oxnas_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++/*************************************************************************/
++static int test20(void) {
++ int failed = 0;
++ u32 reg;
++ oxnas_dma_channel_t* dma_in;
++ oxnas_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = oxnas_dma_request(1);
++ dma_out = oxnas_dma_request(1);
++
++ // get some dma accessable memory
++ data_in = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 4 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[0] = be32_to_cpu( 0x30313233);
++ data_in[1] = be32_to_cpu( 0x34353637);
++ data_in[2] = be32_to_cpu( 0x38394142);
++ data_in[3] = be32_to_cpu( 0x43444546);
++ data_out[0] = ~0;
++ data_out[1] = ~0;
++ data_out[2] = ~0;
++ data_out[3] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 4 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 4 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ oxnas_dma_device_set(
++ dma_in,
++ OXNAS_DMA_TO_DEVICE,
++ (char*)in_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_rx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ oxnas_dma_device_set(
++ dma_out,
++ OXNAS_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 4 * sizeof(u32),
++ &oxnas_dpe_tx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ // don't authenticate
++ WRITEL(0 ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for encryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_MODE_LRW_AES;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0x4562ac25), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0xf828176d), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x4c268414), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0xb5680185), OX800DPE_KEY03 );
++
++ // key no 2
++ WRITEL(be32_to_cpu( 0x258e2a05), OX800DPE_KEY10 );
++ WRITEL(be32_to_cpu( 0xe73e9d03), OX800DPE_KEY11 );
++ WRITEL(be32_to_cpu( 0xee5a830c), OX800DPE_KEY12 );
++ WRITEL(be32_to_cpu( 0xcc094c87), OX800DPE_KEY13 );
++
++ // setup index
++ WRITEL(0x00000000, OX800DPE_DATA_LRW0 );
++ WRITEL(0x00000008, OX800DPE_DATA_LRW1 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ oxnas_dma_start(dma_out);
++ oxnas_dma_start(dma_in);
++
++ /* wait until dma done */
++ while( oxnas_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 4 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 4 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /*
++ check output.
++ */
++ if ((data_out[0] == 0xc0a37fda) )
++ {
++ FAILED("encryption output indicates most significant bit is ignored.");
++ printk("%08x%08x%08x%08x\n",data_out[0],data_out[1],data_out[2],data_out[3]);
++ }
++
++ // free dmas
++ oxnas_dma_free( dma_in );
++ oxnas_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/*************************************************************************/
++static int test21(void) {
++ int failed = 0;
++ u32 reg;
++ oxnas_dma_channel_t* dma_in;
++ oxnas_dma_channel_t* dma_out;
++ dma_addr_t in_address;
++ dma_addr_t out_address;
++
++ u32* data_in;
++ u32* data_out;
++
++ // setup dmas
++ dma_in = oxnas_dma_request(1);
++ dma_out = oxnas_dma_request(1);
++
++ // get some dma accessable memory (512B + 16B
++ data_in = (u32*)kmalloc( 132 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++ data_out = (u32*)kmalloc( 132 * sizeof(u32), GFP_KERNEL|GFP_DMA);
++
++ // fill with input and non expected output
++ data_in[128] = be32_to_cpu( 0x30313233);
++ data_in[129] = be32_to_cpu( 0x34353637);
++ data_in[130] = be32_to_cpu( 0x38394142);
++ data_in[131] = be32_to_cpu( 0x43444546);
++ data_out[128] = ~0;
++ data_out[129] = ~0;
++ data_out[130] = ~0;
++ data_out[131] = ~0;
++
++ // map the dma regons
++ in_address = dma_map_single(
++ 0,
++ data_in,
++ 132 * sizeof(u32),
++ DMA_TO_DEVICE);
++
++ // map the dma regons
++ out_address = dma_map_single(
++ 0,
++ data_out,
++ 132 * sizeof(u32),
++ DMA_FROM_DEVICE);
++
++ // setup the transfers
++ oxnas_dma_device_set(
++ dma_in,
++ OXNAS_DMA_TO_DEVICE,
++ (char*)in_address,
++ 132 * sizeof(u32),
++ &oxnas_dpe_rx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ oxnas_dma_device_set(
++ dma_out,
++ OXNAS_DMA_FROM_DEVICE,
++ (char*)out_address,
++ 132 * sizeof(u32),
++ &oxnas_dpe_tx_dma_settings,
++ OXNAS_DMA_MODE_INC, 1);
++
++ // authenticate
++ WRITEL(OX800IBW_STAT_AUTHENTICATED ,OX800IBW_STATUS);
++
++ // toggle cleardown bit to start
++ WRITEL(OX800DPE_CTL_ABORT ,OX800DPE_CONTROL);
++ WRITEL(0 ,OX800DPE_CONTROL);
++
++ // shouldn't be busy or full
++ reg = READL( OX800DPE_STATUS );
++ if (! (reg & OX800DPE_STAT_IDLE) )
++ FAILED("not idle after abort toggle");
++ if (reg & OX800DPE_STAT_TX_NOTEMPTY)
++ FAILED("tx fifo not empty after abort toggle");
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx not empty after abort toggle");
++
++ // setup for decryption
++ reg = OX800DPE_CTL_DIRECTION_ENC |
++ OX800DPE_CTL_MODE_LRW_AES ;
++ WRITEL(reg ,OX800DPE_CONTROL);
++
++ // key no 1
++ WRITEL(be32_to_cpu( 0xd82a9134), OX800DPE_KEY00 );
++ WRITEL(be32_to_cpu( 0xb26a5650), OX800DPE_KEY01 );
++ WRITEL(be32_to_cpu( 0x30fe69e2), OX800DPE_KEY02 );
++ WRITEL(be32_to_cpu( 0x377f9847), OX800DPE_KEY03 );
++
++ // key no 2
++ WRITEL(be32_to_cpu( 0xcdf90b16), OX800DPE_KEY10 );
++ WRITEL(be32_to_cpu( 0x0c648fb6), OX800DPE_KEY11 );
++ WRITEL(be32_to_cpu( 0xb00d0d1b), OX800DPE_KEY12 );
++ WRITEL(be32_to_cpu( 0xae85871f), OX800DPE_KEY13 );
++
++ // setup index
++ WRITEL(0x0fffffff, OX800DPE_DATA_LRW0 );
++ WRITEL(0x00000000, OX800DPE_DATA_LRW1 );
++
++ /* wait until done */
++ while( !(OX800DPE_STAT_IDLE & READL( OX800DPE_STATUS )) );
++
++ // start dma transfers
++ oxnas_dma_start(dma_out);
++ oxnas_dma_start(dma_in);
++
++ /* wait until done */
++ while( oxnas_dma_is_active( dma_out ) );
++
++ reg = READL( OX800DPE_STATUS );
++
++ /* output should be empty */
++ if ( (reg & OX800DPE_STAT_TX_NOTEMPTY) )
++ FAILED("tx still full after fetching ");
++
++ /* in empty */
++ if (! (reg & OX800DPE_STAT_RX_SPACE) )
++ FAILED("rx still full after encrypting data ");
++
++ dma_unmap_single(0, in_address, 132 * sizeof(u32), DMA_TO_DEVICE);
++ dma_unmap_single(0, out_address, 132 * sizeof(u32), DMA_FROM_DEVICE);
++
++ /* check output */
++ if ((data_out[128] != cpu_to_be32(0x76322183)) ||
++ (data_out[129] != cpu_to_be32(0xed8ff182)) ||
++ (data_out[130] != cpu_to_be32(0xf9596203)) ||
++ (data_out[131] != cpu_to_be32(0x690e5e01)))
++ {
++ FAILED("encryption output incorrect");
++ printk("%08x%08x%08x%08x\n",data_out[128],data_out[129],data_out[130],data_out[131]);
++ }
++
++ // free dmas
++ oxnas_dma_free( dma_in );
++ oxnas_dma_free( dma_out );
++
++ kfree(data_in);
++ kfree(data_out);
++
++ return failed;
++
++}
++
++
++/*****************************************************************************/
++#define NOCIPHERTESTS 21
++static ox800dpe_test_t* tests[NOCIPHERTESTS] = {
++ /* ordinary AES tests */
++ test1,
++ test2,
++ test3,
++ test4,
++ test5,
++ test6,
++ test7,
++
++ /* CBC AES tests */
++ test8,
++ test9,
++ test10,
++ test11,
++ test12,
++ test13,
++
++ /* LRW AES tests */
++ test14,
++ test15,
++ test16,
++ test17,
++ test18,
++ test19,
++ test20,
++ test21
++
++} ;
++
++
++static int __init ox800dpe_init(void)
++{
++ int i;
++ int result;
++ printk("*******************************************************************\n");
++ printk("* CIPHER CORE TESTING START *\n");
++ printk("*******************************************************************\n");
++
++ /* Enable the clock to the DPE block */
++ writel(1UL << SYS_CTRL_CKEN_DPE_BIT, SYS_CTRL_CKEN_SET_CTRL);
++
++ /* Bring out of reset */
++ writel(1UL << SYS_CTRL_RSTEN_DPE_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
++
++
++
++
++ for (i = 0; i < NOCIPHERTESTS; ++i)
++ {
++ printk("\nTest %d start\n",i+1);
++ result = (tests[i])();
++ if (result)
++ printk("Test %d failed with %d faults.\n",i+1,result);
++ else
++ printk("Test %d passed\n",i+1);
++
++ }
++
++ printk("*******************************************************************\n");
++ printk("* CIPHER CORE TESTING END *\n");
++ printk("*******************************************************************\n");
++
++ return 0;
++}
++
++
++
++/***************************************************************************/
++module_init(ox800dpe_init);
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac-napi.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac-napi.c
+--- linux-2.6.24/arch/arm/mach-oxnas/gmac-napi.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac-napi.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,3637 @@
++/*
++ * linux/arch/arm/mach-oxnas/gmac.c
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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 <linux/crc32.h>
++#include <linux/version.h>
++#include <linux/init.h>
++#include <linux/errno.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/dma-mapping.h>
++#include <linux/delay.h>
++#include <linux/in.h>
++#include <net/ip.h>
++#include <linux/tcp.h>
++#include <linux/udp.h>
++#include <asm/io.h>
++#include <asm/arch/hardware.h>
++#include <asm/arch/irqs.h>
++
++#ifdef CONFIG_LEON_COPRO
++#include <asm/arch/leon-program.h>
++#endif // CONFIG_LEON_COPRO
++
++//#define GMAC_DEBUG
++#undef GMAC_DEBUG
++
++#include "gmac.h"
++#include "gmac_ethtool.h"
++#include "gmac_phy.h"
++#include "gmac_desc.h"
++#include "gmac_reg.h"
++
++//#define DUMP_REGS_ON_GMAC_UP
++
++#define MAX_GMAC_UNITS 1
++
++#define ALLOW_AUTONEG
++
++//#define ALLOW_OX800_1000M
++
++//#define SUPPORT_IPV6
++
++#ifdef CONFIG_LEON_COPRO
++//#define TEST_COPRO
++#define COPRO_RX_MITIGATION 0 /* No Rx mitigation in CoPro */
++#define COPRO_RX_MITIGATION_FRAMES 5
++#define COPRO_RX_MITIGATION_USECS 500
++
++#define COPRO_TX_QUEUE_NUM_ENTRIES 4
++#define COPRO_CMD_QUEUE_NUM_ENTRIES 6
++#define COPRO_MAX_QUEUED_TX_SKBS 16
++#endif // CONFIG_LEON_COPRO
++
++#ifdef CONFIG_LEON_OFFLOAD_TX
++#define NUM_RX_DMA_DESCRIPTORS NUM_GMAC_DMA_DESCRIPTORS
++#define NUM_TX_DMA_DESCRIPTORS 0
++#else
++#define NUM_RX_DMA_DESCRIPTORS (NUM_GMAC_DMA_DESCRIPTORS / 2)
++#define NUM_TX_DMA_DESCRIPTORS (NUM_GMAC_DMA_DESCRIPTORS - NUM_RX_DMA_DESCRIPTORS)
++#endif // CONFIG_LEON_OFFLOAD_TX
++
++#if (((NUM_RX_DMA_DESCRIPTORS) + (NUM_TX_DMA_DESCRIPTORS)) > (NUM_GMAC_DMA_DESCRIPTORS))
++#error "GMAC TX+RX descriptors exceed allocation"
++#endif
++
++#define DESC_SINCE_REFILL_LIMIT ((NUM_RX_DMA_DESCRIPTORS) / 4)
++
++static const u32 MAC_BASE_OFFSET = 0x0000;
++static const u32 DMA_BASE_OFFSET = 0x1000;
++
++static const int MIN_PACKET_SIZE = 68;
++static const int NORMAL_PACKET_SIZE = 1500;
++static const int MAX_JUMBO = 9000;
++
++#define RX_BUFFER_SIZE 796 // Must be multiple of 4, If not defined will size buffer to hold a single MTU-sized packet
++
++#ifdef CONFIG_OXNAS_VERSION_0X800
++static const int EXTRA_RX_SKB_SPACE = 24; // Has extra 2 bytes of Rx payload csum
++#else // CONFIG_OXNAS_VERSION_0X800
++static const int EXTRA_RX_SKB_SPACE = 22; // Ethernet header 14, VLAN 4, CRC 4
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++// The amount of header to copy from a receive packet into the skb buffer
++static const int GMAC_HLEN = 66;
++
++#define GMAC_ALLOC_ORDER 0
++static const int GMAC_ALLOC_SIZE = ((1 << GMAC_ALLOC_ORDER) * PAGE_SIZE);
++
++static const u32 AUTO_NEGOTIATION_WAIT_TIMEOUT_MS = 5000;
++
++static const u32 NAPI_POLL_WEIGHT = 64;
++static const u32 NAPI_OOM_POLL_INTERVAL_MS = 50;
++
++static const int WATCHDOG_TIMER_INTERVAL = 500*HZ/1000;
++
++#define AUTO_NEG_MS_WAIT 500
++static const int AUTO_NEG_INTERVAL = (AUTO_NEG_MS_WAIT)*HZ/1000;
++static const int START_RESET_INTERVAL = 50*HZ/1000;
++static const int RESET_INTERVAL = 10*HZ/1000;
++
++static const int GMAC_RESET_TIMEOUT_MS = 10000;
++
++static int debug = 0;
++
++MODULE_AUTHOR("Brian Clarke (Oxford Semiconductor Ltd)");
++MODULE_DESCRIPTION("GMAC Network Driver");
++MODULE_LICENSE("GPL");
++MODULE_VERSION("v2.0");
++
++/* Ethernet MAC adr to assign to interface */
++static int mac_adr[] = { 0x00, 0x30, 0xe0, 0x00, 0x00, 0x00 };
++module_param_array(mac_adr, int, NULL, S_IRUGO);
++
++/* PHY type kernel cmdline options */
++static int phy_is_rgmii = 0;
++module_param(phy_is_rgmii, int, S_IRUGO);
++
++/* Parse netdev kernel cmdline options */
++static int __init do_setup(char *str)
++{
++ int i;
++ int ints[5]; // Hold arg count and four args
++ u32 mac_hi = 0;
++ u32 mac_lo = 0;
++
++ /* Get the netdev bootargs parameters */
++ get_options(str, sizeof(ints)/sizeof(int), ints);
++ for (i=1; i<=ints[0]; i++) {
++ switch (i) {
++ case 3:
++ mac_hi = ints[i];
++ break;
++ case 4:
++ mac_lo = ints[i];
++ break;
++ }
++ }
++
++ /* Break down the mac adr into its components */
++ for (i=0; i < sizeof(mac_adr)/sizeof(int); i++) {
++ if (i < sizeof(u32)) {
++ mac_adr[i] = ((mac_hi >> (((sizeof(u32)-1)-i)*8)) & 0xff);
++ } else {
++ mac_adr[i] = ((mac_lo >> (((sizeof(u32)+1)-i)*8)) & 0xff);
++ }
++ }
++
++ return 0;
++}
++__setup("netdev=",do_setup);
++
++#ifdef DUMP_REGS_ON_GMAC_UP
++static void dump_mac_regs(u32 macBase, u32 dmaBase)
++{
++ int n = 0;
++
++ for (n=0; n<0x60; n+=4) {
++ printk(KERN_INFO "MAC Register %08x (%08x) = %08x\n", n, macBase+n, readl(macBase+n));
++ }
++
++ for (n=0; n<0x60; n+=4) {
++ printk(KERN_INFO "DMA Register %08x (%08x) = %08x\n", n, dmaBase+n, readl(dmaBase+n));
++ }
++}
++#endif // DUMP_REGS_ON_GMAC_UP
++
++#ifdef CONFIG_LEON_COPRO
++static struct semaphore copro_update_semaphore;
++
++static void copro_update_callback(volatile gmac_cmd_que_ent_t* entry)
++{
++ up(&copro_update_semaphore);
++}
++
++static struct semaphore copro_start_semaphore;
++
++static void copro_start_callback(volatile gmac_cmd_que_ent_t* entry)
++{
++ up(&copro_start_semaphore);
++}
++
++static struct semaphore copro_rx_enable_semaphore;
++
++static void copro_rx_enable_callback(volatile gmac_cmd_que_ent_t* entry)
++{
++ up(&copro_rx_enable_semaphore);
++}
++#endif // CONFIG_LEON_COPRO
++
++static void gmac_int_en_set(
++ gmac_priv_t *priv,
++ u32 mask)
++{
++ unsigned long irq_flags = 0;
++
++#ifdef CONFIG_LEON_COPRO
++ int cmd_queue_result = -1;
++ while (cmd_queue_result) {
++ if (in_irq())
++ spin_lock(&priv->cmd_que_lock_);
++ else
++ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
++
++ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_INT_EN_SET, mask, 0);
++
++ if (in_irq())
++ spin_unlock(&priv->cmd_que_lock_);
++ else
++ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
++ }
++
++ // Interrupt the CoPro so it sees the new command
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++#else
++ if (in_irq())
++ spin_lock(&priv->cmd_que_lock_);
++ else
++ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
++
++ dma_reg_set_mask(priv, DMA_INT_ENABLE_REG, mask);
++
++ if (in_irq())
++ spin_unlock(&priv->cmd_que_lock_);
++ else
++ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
++#endif // CONFIG_LEON_COPRO
++}
++
++#ifdef CONFIG_LEON_COPRO
++static struct semaphore copro_int_clr_semaphore;
++static unsigned long copro_int_clr_return;
++
++static void copro_int_clr_callback(volatile gmac_cmd_que_ent_t* entry)
++{
++ copro_int_clr_return = entry->operand_;
++ up(&copro_int_clr_semaphore);
++}
++#endif // CONFIG_LEON_COPRO
++
++static void gmac_int_en_clr(
++ gmac_priv_t *priv,
++ u32 mask,
++ u32 *new_value,
++ int in_atomic)
++{
++#ifdef CONFIG_LEON_COPRO
++ unsigned long irq_flags = 0;
++
++ int cmd_queue_result = -1;
++ while (cmd_queue_result) {
++ if (in_irq())
++ spin_lock(&priv->cmd_que_lock_);
++ else
++ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
++
++ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_INT_EN_CLR, mask, copro_int_clr_callback);
++
++ if (in_irq())
++ spin_unlock(&priv->cmd_que_lock_);
++ else
++ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
++ }
++
++ // Interrupt the CoPro so it sees the new command
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++
++ if (new_value) {
++ // Wait until the CoPro acknowledges that it has stopped
++ if (in_atomic) {
++ while (down_trylock(&copro_int_clr_semaphore)) {
++ udelay(100);
++ }
++ } else {
++ down_interruptible(&copro_int_clr_semaphore);
++ }
++ *new_value = copro_int_clr_return;
++ }
++#else
++ unsigned long temp;
++ unsigned long irq_flags = 0;
++
++ if (in_irq())
++ spin_lock(&priv->cmd_que_lock_);
++ else
++ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
++
++ temp = dma_reg_clear_mask(priv, DMA_INT_ENABLE_REG, mask);
++
++ if (in_irq())
++ spin_unlock(&priv->cmd_que_lock_);
++ else
++ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
++
++ if (new_value) {
++ *new_value = temp;
++ }
++#endif
++}
++
++/**
++ * May be invoked from either ISR or process context, so locking must be
++ * invoked appropriate to the return from in_irq()
++ */
++static void change_rx_enable(
++ gmac_priv_t *priv,
++ u32 start,
++ int waitForAck,
++ int in_atomic)
++{
++#ifdef CONFIG_LEON_COPRO
++ unsigned long irq_flags = 0;
++ int cmd_queue_result = -1;
++
++ while (cmd_queue_result) {
++ if (in_irq())
++ spin_lock(&priv->cmd_que_lock_);
++ else
++ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
++
++ // Request the CoPro to start/stop GMAC receiver
++ cmd_queue_result =
++ cmd_que_queue_cmd(&priv->cmd_queue_,
++ GMAC_CMD_CHANGE_RX_ENABLE,
++ start,
++ waitForAck ? copro_rx_enable_callback : 0);
++
++ if (in_irq())
++ spin_unlock(&priv->cmd_que_lock_);
++ else
++ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
++ }
++
++ // Interrupt the CoPro so it sees the new command
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++
++ if (waitForAck) {
++ // Wait until the CoPro acknowledges that the receiver has been stopped
++ if (in_atomic) {
++ while (down_trylock(&copro_rx_enable_semaphore)) {
++ udelay(100);
++ }
++ } else {
++ down_interruptible(&copro_rx_enable_semaphore);
++ }
++ }
++#else // CONFIG_LEON_COPRO
++ start ? dma_reg_set_mask(priv, DMA_OP_MODE_REG, 1UL << DMA_OP_MODE_SR_BIT) :
++ dma_reg_clear_mask(priv, DMA_OP_MODE_REG, 1UL << DMA_OP_MODE_SR_BIT);
++#endif // CONFIG_LEON_COPRO
++}
++
++/**
++ * Invoked from the watchdog timer action routine which runs as softirq, so
++ * must disable interrupts when obtaining locks
++ */
++static void change_gig_mode(gmac_priv_t *priv)
++{
++ unsigned int is_gig = priv->mii.using_1000;
++
++#ifdef CONFIG_LEON_COPRO
++ unsigned long irq_flags = 0;
++ int cmd_queue_result = -1;
++
++ while (cmd_queue_result) {
++ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
++ // Request the CoPro to change gigabit mode
++ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_CHANGE_GIG_MODE, is_gig, 0);
++ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
++ }
++
++ // Interrupt the CoPro so it sees the new command
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++#else // CONFIG_LEON_COPRO
++ static const int MAX_TRIES = 1000;
++ int tries = 0;
++
++ // Mask to extract the transmit status field from the status register
++ u32 ts_mask = ((1UL << DMA_STATUS_TS_NUM_BITS) - 1) << DMA_STATUS_TS_BIT;
++
++ // Must stop transmission in order to change store&forward mode
++ dma_reg_clear_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
++
++ // Transmission only stops after current Tx frame has completed trans-
++ // mission, so wait for the Tx state machine to enter the stopped state
++ while ((dma_reg_read(priv, DMA_STATUS_REG) & ts_mask) != (DMA_STATUS_TS_STOPPED << DMA_STATUS_TS_BIT)) {
++ mdelay(1);
++ if (unlikely(++tries == MAX_TRIES)) {
++ break;
++ }
++ }
++
++ if (unlikely(tries == MAX_TRIES)) {
++ printk(KERN_WARNING "Timed out of wait for Tx to stop\n");
++ }
++
++ if (is_gig) {
++ mac_reg_clear_mask(priv, MAC_CONFIG_REG, (1UL << MAC_CONFIG_PS_BIT));
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ // In gigabit mode the OX800 cannot support the required data rate to
++ // the GMAC, so must use store&forward and OX800 doesn't support Tx
++ // checksumming in the GMAC
++ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
++#endif // CONFIG_OXNAS_VERSION_0X800
++ } else {
++ mac_reg_set_mask(priv, MAC_CONFIG_REG, (1UL << MAC_CONFIG_PS_BIT));
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ dma_reg_clear_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
++#endif // CONFIG_OXNAS_VERSION_0X800
++ }
++
++ // Re-start transmission after store&forward change applied
++ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
++#endif // CONFIG_LEON_COPRO
++}
++
++/**
++ * Invoked from the watchdog timer action routine which runs as softirq, so
++ * must disable interrupts when obtaining locks
++ */
++static void change_pause_mode(gmac_priv_t *priv)
++{
++#ifdef CONFIG_LEON_COPRO
++ unsigned int enable_pause = priv->mii.using_pause;
++ unsigned long irq_flags = 0;
++ int cmd_queue_result = -1;
++
++ while (cmd_queue_result) {
++ spin_lock_irqsave(&priv->cmd_que_lock_, irq_flags);
++ // Request the CoPro to change pause mode
++ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_CHANGE_PAUSE_MODE, enable_pause, 0);
++ spin_unlock_irqrestore(&priv->cmd_que_lock_, irq_flags);
++ }
++
++ // Interrupt the CoPro so it sees the new command
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++#else // CONFIG_LEON_COPRO
++#ifndef CONFIG_OXNAS_VERSION_0X800
++ unsigned int enable_pause = priv->mii.using_pause;
++
++ if (enable_pause) {
++ mac_reg_set_mask(priv, MAC_FLOW_CNTL_REG, (1UL << MAC_FLOW_CNTL_TFE_BIT));
++ } else {
++ mac_reg_clear_mask(priv, MAC_FLOW_CNTL_REG, (1UL << MAC_FLOW_CNTL_TFE_BIT));
++ }
++#endif // !CONFIG_OXNAS_VERSION_0X800
++#endif // CONFIG_LEON_COPRO
++}
++
++static void refill_rx_ring(struct net_device *dev)
++{
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ int filled = 0;
++
++ if (unlikely(priv->rx_buffers_per_page)) {
++ // Receive into pages
++ struct page *page = 0;
++ int offset = 0;
++ dma_addr_t phys_adr = 0;
++
++ // While there are empty RX descriptor ring slots
++ while (1) {
++ int available;
++ int desc;
++ rx_frag_info_t frag_info;
++
++ // Have we run out of space in the current page?
++ if (offset + NET_IP_ALIGN + priv->rx_buffer_size_ > GMAC_ALLOC_SIZE) {
++ page = 0;
++ offset = 0;
++ }
++
++ if (!page) {
++ // Start a new page
++ available = available_for_write(&priv->rx_gmac_desc_list_info);
++ if (available < priv->rx_buffers_per_page) {
++ break;
++ }
++
++ // Allocate a page to hold a received packet
++ page = alloc_pages(GFP_ATOMIC, GMAC_ALLOC_ORDER);
++ if (unlikely(page == NULL)) {
++ printk(KERN_WARNING "refill_rx_ring() Could not alloc page\n");
++ break;
++ }
++
++ // Get a consistent DMA mapping for the entire page that will be
++ // DMAed to - causing an invalidation of any entries in the CPU's
++ // cache covering the memory region
++ phys_adr = dma_map_page(0, page, 0, GMAC_ALLOC_SIZE, DMA_FROM_DEVICE);
++ BUG_ON(dma_mapping_error(phys_adr));
++ } else {
++ // Using the current page again
++ get_page(page);
++ }
++
++ // Ensure IP header is quad aligned
++ offset += NET_IP_ALIGN;
++ frag_info.page = page;
++ frag_info.length = priv->rx_buffer_size_;
++ frag_info.phys_adr = phys_adr + offset;
++
++ // Try to associate a descriptor with the fragment info
++ desc = set_rx_descriptor(priv, &frag_info);
++ if (desc >= 0) {
++ filled = 1;
++ } else {
++ // Failed to associate the descriptor, so release the DMA mapping
++ // for the socket buffer
++ dma_unmap_page(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
++
++ // No more RX descriptor ring entries to refill
++ break;
++ }
++
++ // Account for the space used in the current page
++ offset += frag_info.length;
++
++ // Start next packet on a cacheline boundary
++ offset = SKB_DATA_ALIGN(offset);
++ }
++ } else {
++ // Preallocate MTU-sized SKBs
++ while (1) {
++ struct sk_buff *skb;
++ rx_frag_info_t frag_info;
++ int desc;
++
++ if (!available_for_write(&priv->rx_gmac_desc_list_info)) {
++ break;
++ }
++
++ // Allocate a new skb for the descriptor ring which is large enough
++ // for any packet received from the link
++ skb = dev_alloc_skb(priv->rx_buffer_size_ + NET_IP_ALIGN);
++ if (!skb) {
++ // Can't refill any more RX descriptor ring entries
++ break;
++ } else {
++ // Despite what the comments in the original code from Synopsys
++ // claimed, the GMAC DMA can cope with non-quad aligned buffers
++ // - it will always perform quad transfers but zero/ignore the
++ // unwanted bytes.
++ skb_reserve(skb, NET_IP_ALIGN);
++ }
++
++ // Get a consistent DMA mapping for the memory to be DMAed to
++ // causing invalidation of any entries in the CPU's cache covering
++ // the memory region
++ frag_info.page = (struct page*)skb;
++ frag_info.length = skb_tailroom(skb);
++ frag_info.phys_adr = dma_map_single(0, skb->tail, frag_info.length, DMA_FROM_DEVICE);
++ BUG_ON(dma_mapping_error(frag_info.phys_adr));
++
++ // Associate the skb with the descriptor
++ desc = set_rx_descriptor(priv, &frag_info);
++ if (desc >= 0) {
++ filled = 1;
++ } else {
++ // No, so release the DMA mapping for the socket buffer
++ dma_unmap_single(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
++
++ // Free the socket buffer
++ dev_kfree_skb(skb);
++
++ // No more RX descriptor ring entries to refill
++ break;
++ }
++ }
++ }
++
++#ifndef CONFIG_OXNAS_VERSION_0X800
++ if (likely(filled)) {
++ // Issue a RX poll demand to restart RX descriptor processing and DFF
++ // mode does not automatically restart descriptor processing after a
++ // descriptor unavailable event
++ dma_reg_write(priv, DMA_RX_POLL_REG, 0);
++ }
++#endif // !CONFIG_OXNAS_VERSION_0X800
++}
++
++static inline void set_phy_type_rgmii(void)
++{
++#ifndef CONFIG_OXNAS_VERSION_0X800
++ // Use sysctrl to switch MAC link lines into either (G)MII or RGMII mode
++ u32 reg_contents = readl(SYS_CTRL_GMAC_CTRL);
++ reg_contents |= (1UL << SYS_CTRL_GMAC_RGMII);
++ writel(reg_contents, SYS_CTRL_RSTEN_SET_CTRL);
++#endif // !CONFIG_OXNAS_VERSION_0X800
++}
++
++static void initialise_phy(gmac_priv_t* priv)
++{
++ switch (priv->phy_type) {
++ case PHY_TYPE_VITESSE_VSC8201XVZ:
++ {
++ // Allow s/w to override mode/duplex pin settings
++ u32 acsr = priv->mii.mdio_read(priv->netdev, priv->mii.phy_id, VSC8201_MII_ACSR);
++
++ printk(KERN_INFO "%s: PHY is Vitesse VSC8201XVZ\n", priv->netdev->name);
++ acsr |= (1UL << VSC8201_MII_ACSR_MDPPS_BIT);
++ priv->mii.mdio_write(priv->netdev, priv->mii.phy_id, VSC8201_MII_ACSR, acsr);
++ }
++ break;
++ case PHY_TYPE_REALTEK_RTL8211BGR:
++ printk(KERN_INFO "%s: PHY is Realtek RTL8211BGR\n", priv->netdev->name);
++ set_phy_type_rgmii();
++ break;
++ case PHY_TYPE_LSI_ET1011C:
++ case PHY_TYPE_LSI_ET1011C2:
++ {
++ u32 phy_reg;
++
++ printk(KERN_INFO "%s: PHY is LSI ET1011C\n", priv->netdev->name);
++
++ // Configure clocks
++ phy_reg = priv->mii.mdio_read(priv->netdev, priv->mii.phy_id, ET1011C_MII_CONFIG);
++ phy_reg &= ~(((1UL << ET1011C_MII_CONFIG_IFMODESEL_NUM_BITS) - 1) << ET1011C_MII_CONFIG_IFMODESEL);
++ phy_reg |= (ET1011C_MII_CONFIG_IFMODESEL_GMII_MII << ET1011C_MII_CONFIG_IFMODESEL);
++ phy_reg |= ((1UL << ET1011C_MII_CONFIG_SYSCLKEN) |
++ (1UL << ET1011C_MII_CONFIG_TXCLKEN) |
++ (1UL << ET1011C_MII_CONFIG_TBI_RATESEL) |
++ (1UL << ET1011C_MII_CONFIG_CRS_TX_EN));
++ priv->mii.mdio_write(priv->netdev, priv->mii.phy_id, ET1011C_MII_CONFIG, phy_reg);
++
++ // Enable Tx/Rx LED
++ phy_reg = priv->mii.mdio_read(priv->netdev, priv->mii.phy_id, ET1011C_MII_LED2);
++ phy_reg &= ~(((1UL << ET1011C_MII_LED2_LED_NUM_BITS) - 1) << ET1011C_MII_LED2_LED_TXRX);
++ phy_reg |= (ET1011C_MII_LED2_LED_TXRX_ACTIVITY << ET1011C_MII_LED2_LED_TXRX);
++ priv->mii.mdio_write(priv->netdev, priv->mii.phy_id, ET1011C_MII_LED2, phy_reg);
++ }
++ break;
++ case PHY_TYPE_ICPLUS_IP1001:
++ printk(KERN_INFO "%s: PHY is ICPlus 1001\n", priv->netdev->name);
++ break;
++ }
++}
++
++static struct kobj_type ktype_gmac_link_state = {
++ .release = 0,
++ .sysfs_ops = 0,
++ .default_attrs = 0,
++};
++
++static int gmac_link_state_hotplug_filter(struct kset* kset, struct kobject* kobj) {
++ return get_ktype(kobj) == &ktype_gmac_link_state;
++}
++
++static const char* gmac_link_state_hotplug_name(struct kset* kset, struct kobject* kobj) {
++ return "gmac_link_state";
++}
++
++static struct kset_uevent_ops gmac_link_state_uevent_ops = {
++ .filter = gmac_link_state_hotplug_filter,
++ .name = gmac_link_state_hotplug_name,
++ .uevent = NULL,
++};
++
++static int gmac_link_state_init_sysfs(gmac_priv_t* priv)
++{
++ int err = 0;
++
++ /* Prepare the sysfs interface for use */
++ kobject_set_name(&priv->link_state_kset.kobj, "gmac_link_state");
++ priv->link_state_kset.ktype = &ktype_gmac_link_state;
++
++ err = subsystem_register(&priv->link_state_kset);
++ if (err)
++ return err;
++
++ /* Setup hotplugging */
++ priv->link_state_kset.uevent_ops = &gmac_link_state_uevent_ops;
++
++ /* Setup the heirarchy, the name will be set on detection */
++ kobject_init(&priv->link_state_kobject);
++ priv->link_state_kobject.kset = kset_get(&priv->link_state_kset);
++ priv->link_state_kobject.parent = &priv->link_state_kset.kobj;
++
++ /* Build the sysfs entry */
++ kobject_set_name(&priv->link_state_kobject, "gmac_link_state-1");
++ return kobject_add(&priv->link_state_kobject);
++}
++
++static void work_handler(struct work_struct *ws) {
++ gmac_priv_t *priv = container_of(ws, gmac_priv_t, link_state_change_work);
++
++ kobject_uevent(&priv->link_state_kobject, priv->link_state ? KOBJ_ONLINE : KOBJ_OFFLINE);
++}
++
++static void link_state_change_callback(
++ int link_state,
++ void *arg)
++{
++ gmac_priv_t* priv = (gmac_priv_t*)arg;
++
++ priv->link_state = link_state;
++ schedule_work(&priv->link_state_change_work);
++}
++
++static void start_watchdog_timer(gmac_priv_t* priv)
++{
++ priv->watchdog_timer.expires = jiffies + WATCHDOG_TIMER_INTERVAL;
++ priv->watchdog_timer_shutdown = 0;
++ mod_timer(&priv->watchdog_timer, priv->watchdog_timer.expires);
++}
++
++static void delete_watchdog_timer(gmac_priv_t* priv)
++{
++ // Ensure link/PHY state watchdog timer won't be invoked again
++ priv->watchdog_timer_shutdown = 1;
++ del_timer_sync(&priv->watchdog_timer);
++}
++
++static inline int is_auto_negotiation_in_progress(gmac_priv_t* priv)
++{
++ return !(phy_read(priv->netdev, priv->phy_addr, MII_BMSR) & BMSR_ANEGCOMPLETE);
++}
++
++static void watchdog_timer_action(unsigned long arg)
++{
++ typedef enum watchdog_state {
++ WDS_IDLE,
++ WDS_RESETTING,
++ WDS_NEGOTIATING
++ } watchdog_state_t;
++
++ static int state = WDS_IDLE;
++
++ gmac_priv_t* priv = (gmac_priv_t*)arg;
++ unsigned long new_timeout = jiffies + WATCHDOG_TIMER_INTERVAL;
++#ifndef ARMULATING
++ int ready;
++ int duplex_changed;
++ int gigabit_changed;
++ int pause_changed;
++
++ // Interpret the PHY/link state.
++ if (priv->phy_force_negotiation || (state == WDS_RESETTING)) {
++ mii_check_link(&priv->mii);
++ ready = 0;
++ } else {
++ duplex_changed = mii_check_media_ex(&priv->mii, 1, priv->mii_init_media, &gigabit_changed, &pause_changed, link_state_change_callback, priv);
++ priv->mii_init_media = 0;
++ ready = netif_carrier_ok(priv->netdev);
++ }
++
++ if (!ready) {
++ if (priv->phy_force_negotiation) {
++ if (netif_carrier_ok(priv->netdev)) {
++ state = WDS_RESETTING;
++ } else {
++ state = WDS_IDLE;
++ }
++
++ priv->phy_force_negotiation = 0;
++ }
++
++ // May be a good idea to restart everything here, in an attempt to clear
++ // out any fault conditions
++ if ((state == WDS_NEGOTIATING) && is_auto_negotiation_in_progress(priv)) {
++ new_timeout = jiffies + AUTO_NEG_INTERVAL;
++ } else {
++ switch (state) {
++ case WDS_IDLE:
++ // Reset the PHY to get it into a known state
++ start_phy_reset(priv);
++ new_timeout = jiffies + START_RESET_INTERVAL;
++ state = WDS_RESETTING;
++ break;
++ case WDS_RESETTING:
++ if (!is_phy_reset_complete(priv)) {
++ new_timeout = jiffies + RESET_INTERVAL;
++ } else {
++ // Force or auto-negotiate PHY mode
++ set_phy_negotiate_mode(priv->netdev);
++
++ // Set PHY specfic features
++ initialise_phy(priv);
++
++ state = WDS_NEGOTIATING;
++ new_timeout = jiffies + AUTO_NEG_INTERVAL;
++ }
++ break;
++ default:
++ DBG(1, KERN_ERR "watchdog_timer_action() %s: Unexpected state\n", priv->netdev->name);
++ state = WDS_IDLE;
++ break;
++ }
++ }
++ } else {
++ state = WDS_IDLE;
++ if (duplex_changed) {
++ priv->mii.full_duplex ? mac_reg_set_mask(priv, MAC_CONFIG_REG, (1UL << MAC_CONFIG_DM_BIT)) :
++ mac_reg_clear_mask(priv, MAC_CONFIG_REG, (1UL << MAC_CONFIG_DM_BIT));
++ }
++
++ if (gigabit_changed) {
++ change_gig_mode(priv);
++ }
++
++ if (pause_changed) {
++ change_pause_mode(priv);
++ }
++ }
++#endif // !ARMULATING
++
++ // Re-trigger the timer, unless some other thread has requested it be stopped
++ if (!priv->watchdog_timer_shutdown) {
++ // Restart the timer
++ mod_timer(&priv->watchdog_timer, new_timeout);
++ }
++}
++
++static int inline is_ip_packet(unsigned short eth_protocol)
++{
++ return (eth_protocol == ETH_P_IP)
++#ifdef SUPPORT_IPV6
++ || (eth_protocol == ETH_P_IPV6)
++#endif // SUPPORT_IPV6
++ ;
++}
++
++static int inline is_ipv4_packet(unsigned short eth_protocol)
++{
++ return eth_protocol == ETH_P_IP;
++}
++
++#ifdef SUPPORT_IPV6
++static int inline is_ipv6_packet(unsigned short eth_protocol)
++{
++ return eth_protocol == ETH_P_IPV6;
++}
++#endif // SUPPORT_IPV6
++
++static int inline is_hw_checksummable(unsigned short protocol)
++{
++ return (protocol == IPPROTO_TCP) || (protocol == IPPROTO_UDP)
++#ifndef CONFIG_OXNAS_VERSION_0X800
++ || (protocol == IPPROTO_ICMP)
++#endif // !CONFIG_OXNAS_VERSION_0X800
++ ;
++}
++
++static u32 unmap_rx_page(
++ gmac_priv_t *priv,
++ dma_addr_t phys_adr)
++{
++ u32 offset = phys_adr & ~PAGE_MASK;
++ u32 next_offset = offset + priv->rx_buffer_size_;
++ next_offset = SKB_DATA_ALIGN(next_offset);
++ next_offset += NET_IP_ALIGN;
++
++ // If this is the last packet in a page
++ if (next_offset > GMAC_ALLOC_SIZE) {
++ // Release the DMA mapping for the page
++ dma_unmap_page(0, phys_adr & PAGE_MASK, GMAC_ALLOC_SIZE, DMA_FROM_DEVICE);
++ }
++
++ return offset;
++}
++
++#define FCS_LEN 4 // Ethernet CRC length
++#ifdef CONFIG_OXNAS_VERSION_0X800
++#define HW_CSUM_LEN 2 // The OX800 H/W appending partial csum length
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++static inline int get_desc_len(
++ u32 desc_status,
++ int last)
++{
++ int length = get_rx_length(desc_status);
++
++ if (last) {
++ length -= FCS_LEN;
++#if defined(CONFIG_OXNAS_VERSION_0X800) && defined(USE_RX_CSUM)
++ length -= HW_CSUM_LEN;
++#endif // CONFIG_OXNAS_VERSION_0X800 && USE_RX_CSUM
++ }
++
++ return length;
++}
++
++static int process_rx_packet_skb(gmac_priv_t *priv)
++{
++ int desc;
++ int last;
++ u32 desc_status = 0;
++ rx_frag_info_t frag_info;
++ int packet_len;
++ struct sk_buff *skb;
++ int valid;
++ int ip_summed;
++
++ desc = get_rx_descriptor(priv, &last, &desc_status, &frag_info);
++ if (desc < 0) {
++ return 0;
++ }
++
++ // Release the DMA mapping for the received data
++ dma_unmap_single(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
++
++ // Get the packet data length
++ packet_len = get_desc_len(desc_status, last);
++
++ // Get pointer to the SKB
++ skb = (struct sk_buff*)frag_info.page;
++
++ // Is the packet entirely contained within the descriptors and without errors?
++ valid = !(desc_status & (1UL << RDES0_ES_BIT));
++
++ if (unlikely(!valid)) {
++ goto not_valid_skb;
++ }
++
++ ip_summed = CHECKSUM_NONE;
++
++#ifdef USE_RX_CSUM
++ // Has the h/w flagged an IP header checksum failure?
++ valid = !(desc_status & (1UL << RDES0_IPC_BIT));
++
++ if (likely(valid)) {
++ // Determine whether Ethernet frame contains an IP packet -
++ // only bother with Ethernet II frames, but do cope with
++ // 802.1Q VLAN tag presence
++ int vlan_offset = 0;
++ unsigned short eth_protocol = ntohs(((struct ethhdr*)skb->data)->h_proto);
++ int is_ip = is_ip_packet(eth_protocol);
++
++ if (!is_ip) {
++ // Check for VLAN tag
++ if (eth_protocol == ETH_P_8021Q) {
++ // Extract the contained protocol type from after
++ // the VLAN tag
++ eth_protocol = ntohs(*(unsigned short*)(skb->data + ETH_HLEN));
++ is_ip = is_ip_packet(eth_protocol);
++
++ // Adjustment required to skip the VLAN stuff and
++ // get to the IP header
++ vlan_offset = 4;
++ }
++ }
++
++ // Only offload checksum calculation for IP packets
++ if (is_ip) {
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ u16 payload_length = 0;
++#endif // CONFIG_OXNAS_VERSION_0X800
++ struct iphdr* ipv4_header = 0;
++
++#ifndef CONFIG_OXNAS_VERSION_0X800
++ if (unlikely(desc_status & (1UL << RDES0_PCE_BIT))) {
++ valid = 0;
++ } else
++#endif // !CONFIG_OXNAS_VERSION_0X800
++ if (is_ipv4_packet(eth_protocol)) {
++ ipv4_header = (struct iphdr*)(skb->data + ETH_HLEN + vlan_offset);
++
++ // H/W can only checksum non-fragmented IP packets
++ if (!(ipv4_header->frag_off & htons(IP_MF | IP_OFFSET))) {
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ switch (ipv4_header->protocol) {
++ case IPPROTO_TCP:
++ // Compute TCP pseudo-header checksum
++ payload_length = ntohs(ipv4_header->tot_len) - (ipv4_header->ihl*4);
++ break;
++ case IPPROTO_UDP:
++ {
++ struct udphdr* udp_header = (struct udphdr*)((u8*)ipv4_header + (ipv4_header->ihl*4));
++ payload_length = ntohs(udp_header->len);
++ }
++ break;
++ default:
++ // Not supporting any other than TCP/UDP
++ break;
++ }
++#else // CONFIG_OXNAS_VERSION_0X800
++ if (is_hw_checksummable(ipv4_header->protocol)) {
++ ip_summed = CHECKSUM_UNNECESSARY;
++ }
++#endif // CONFIG_OXNAS_VERSION_0X800
++ }
++ }
++#ifndef CONFIG_OXNAS_VERSION_0X800
++ else {
++#ifdef SUPPORT_IPV6
++ struct ipv6hdr* ipv6_header = (struct ipv6hdr*)(skb->data + ETH_HLEN + vlan_offset);
++
++ if (is_hw_checksummable(ipv6_header->nexthdr)) {
++ ip_summed = CHECKSUM_UNNECESSARY;
++ }
++#endif // SUPPORT_IPV6
++ }
++#endif // !CONFIG_OXNAS_VERSION_0X800
++
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ if (payload_length) {
++ // Get the hardware generated payload checksum from
++ // the end of the received packet, reverse the 1's
++ // complement operation that the h/w applies and add
++ // to the pseudo-header checksum, in network order
++ u16 hw_csum = ~(*(u16*)(skb->data + packet_len + FCS_LEN));
++
++ // Calculate checksum of pseudo header and payload
++ if (csum_tcpudp_magic(
++ ipv4_header->saddr,
++ ipv4_header->daddr,
++ payload_length,
++ ipv4_header->protocol,
++ hw_csum)) {
++ // Bad checksum, so indicate in descriptor status
++ desc_status |= (1UL << RDES0_IPC_BIT);
++ valid = 0;
++ } else {
++ ip_summed = CHECKSUM_UNNECESSARY;
++ }
++ }
++#endif // CONFIG_OXNAS_VERSION_0X800
++ }
++ }
++
++ if (unlikely(!valid)) {
++ goto not_valid_skb;
++ }
++#endif // USE_RX_CSUM
++
++ // Increase the skb's data pointer to account for the RX packet that has
++ // been DMAed into it
++ skb_put(skb, packet_len);
++
++ // Set the device for the skb
++ skb->dev = priv->netdev;
++
++ // Set packet protocol
++ skb->protocol = eth_type_trans(skb, priv->netdev);
++
++ // Record whether h/w checksumed the packet
++ skb->ip_summed = ip_summed;
++
++ // Send the packet up the network stack
++ netif_receive_skb(skb);
++
++ // Update receive statistics
++ priv->netdev->last_rx = jiffies;
++ ++priv->stats.rx_packets;
++ priv->stats.rx_bytes += packet_len;
++
++ return 1;
++
++not_valid_skb:
++ dev_kfree_skb(skb);
++
++ DBG(2, KERN_WARNING "process_rx_packet() %s: Received packet has bad desc_status = 0x%08x\n", priv->netdev->name, desc_status);
++
++ // Update receive statistics from the descriptor status
++ if (is_rx_collision_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: Collision (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.collisions;
++ }
++ if (is_rx_crc_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: CRC error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.rx_crc_errors;
++ ++priv->stats.rx_errors;
++ }
++ if (is_rx_frame_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: frame error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.rx_frame_errors;
++ ++priv->stats.rx_errors;
++ }
++ if (is_rx_length_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: Length error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.rx_length_errors;
++ ++priv->stats.rx_errors;
++ }
++ if (is_rx_csum_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: Checksum error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.rx_frame_errors;
++ ++priv->stats.rx_errors;
++ }
++
++ return 0;
++}
++
++static int process_rx_packet(gmac_priv_t *priv)
++{
++ struct sk_buff *skb = NULL;
++ int last;
++ u32 desc_status;
++ rx_frag_info_t frag_info;
++ int desc;
++ u32 offset;
++ int desc_len;
++ unsigned char *packet;
++ int valid;
++ int desc_used = 0;
++ int hlen = 0;
++ int partial_len = 0;
++ int first = 1;
++
++ // Check that there is at least one Rx descriptor available. Cache the
++ // descriptor information so we don't have to touch the uncached/unbuffered
++ // descriptor memory more than necessary when we come to use that descriptor
++ if (!rx_available_for_read(&priv->rx_gmac_desc_list_info, &desc_status)) {
++ return 0;
++ }
++
++ // Attempt to allocate an skb before we change anything on the Rx descriptor ring
++ skb = dev_alloc_skb(GMAC_HLEN + NET_IP_ALIGN);
++ if (unlikely(skb == NULL)) {
++ return 0;
++ }
++
++ // Align IP header start in header storage
++ skb_reserve(skb, NET_IP_ALIGN);
++
++ // Process all descriptors associated with the packet
++ while (1) {
++ int prev_len;
++
++ // First call to get_rx_descriptor() will use the status read from the
++ // first descriptor by the call to rx_available_for_read() above
++ while ((desc = get_rx_descriptor(priv, &last, &desc_status, &frag_info)) < 0) {
++ // We are part way through processing a multi-descriptor packet
++ // and the GMAC hasn't finished with the next descriptor for the
++ // packet yet, so have to poll until it becomes available
++ desc_status = 0;
++ udelay(1);
++ }
++
++ // We've consumed a descriptor
++ ++desc_used;
++
++ if (!frag_info.page) {
++ panic("process_rx_packet() %s: Found RX descriptor without attached page\n", priv->netdev->name);
++ }
++
++ // If this is the last packet in the page, release the DMA mapping
++ offset = unmap_rx_page(priv, frag_info.phys_adr);
++ if (!first) {
++ // The buffer adr of descriptors associate with middle or last
++ // parts of a packet have ls 2 bits of buffer adr ignored by GMAC DMA
++ offset &= ~0x3;
++ }
++
++ // Get the length of the packet excluding CRC, h/w csum etc.
++ prev_len = partial_len;
++ partial_len = get_desc_len(desc_status, last);
++ desc_len = partial_len - prev_len;
++
++ // Get a pointer to the start of the packet data received into page
++ packet = page_address(frag_info.page) + offset;
++
++ // Is the packet entirely contained within the desciptors and without errors?
++ valid = !(desc_status & (1UL << RDES0_ES_BIT));
++
++ if (unlikely(!valid)) {
++ goto not_valid;
++ }
++
++ if (first) {
++ // Store headers in skb buffer
++ hlen = min(GMAC_HLEN, desc_len);
++
++ // Copy header into skb buffer
++ memcpy(skb->data, packet, hlen);
++ skb->tail += hlen;
++
++ if (desc_len > hlen) {
++ // Point skb frags array at remaining packet data in pages
++ skb_shinfo(skb)->nr_frags = 1;
++ skb_shinfo(skb)->frags[0].page = frag_info.page;
++ skb_shinfo(skb)->frags[0].page_offset = offset + hlen;
++ skb_shinfo(skb)->frags[0].size = desc_len - hlen;
++ } else {
++ // Entire packet now in skb buffer so don't require page anymore
++ put_page(frag_info.page);
++ }
++
++ first = 0;
++ } else {
++ // Store intermediate descriptor data into packet
++ int frag_index = skb_shinfo(skb)->nr_frags;
++ skb_shinfo(skb)->frags[frag_index].page = frag_info.page;
++ skb_shinfo(skb)->frags[frag_index].page_offset = offset;
++ skb_shinfo(skb)->frags[frag_index].size = desc_len;
++ ++skb_shinfo(skb)->nr_frags;
++ }
++
++ if (last) {
++ int ip_summed = CHECKSUM_NONE;
++
++ // Update total packet length skb metadata
++ skb->len = partial_len;
++ skb->data_len = skb->len - hlen;
++ skb->truesize = skb->len + sizeof(struct sk_buff);
++
++#ifdef USE_RX_CSUM
++ // Has the h/w flagged an IP header checksum failure?
++ valid = !(desc_status & (1UL << RDES0_IPC_BIT));
++
++ // Are we offloading RX checksuming?
++ if (likely(valid)) {
++ // Determine whether Ethernet frame contains an IP packet -
++ // only bother with Ethernet II frames, but do cope with
++ // 802.1Q VLAN tag presence
++ int vlan_offset = 0;
++ unsigned short eth_protocol = ntohs(((struct ethhdr*)skb->data)->h_proto);
++ int is_ip = is_ip_packet(eth_protocol);
++
++ if (!is_ip) {
++ // Check for VLAN tag
++ if (eth_protocol == ETH_P_8021Q) {
++ // Extract the contained protocol type from after
++ // the VLAN tag
++ eth_protocol = ntohs(*(unsigned short*)(skb->data + ETH_HLEN));
++ is_ip = is_ip_packet(eth_protocol);
++
++ // Adjustment required to skip the VLAN stuff and
++ // get to the IP header
++ vlan_offset = 4;
++ }
++ }
++
++ // Only offload checksum calculation for IP packets
++ if (is_ip) {
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ u16 payload_length = 0;
++#endif // CONFIG_OXNAS_VERSION_0X800
++ struct iphdr* ipv4_header = 0;
++
++#ifndef CONFIG_OXNAS_VERSION_0X800
++ if (unlikely(desc_status & (1UL << RDES0_PCE_BIT))) {
++ valid = 0;
++ } else
++#endif // !CONFIG_OXNAS_VERSION_0X800
++ if (is_ipv4_packet(eth_protocol)) {
++ ipv4_header = (struct iphdr*)(skb->data + ETH_HLEN + vlan_offset);
++
++ // H/W can only checksum non-fragmented IP packets
++ if (!(ipv4_header->frag_off & htons(IP_MF | IP_OFFSET))) {
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ switch (ipv4_header->protocol) {
++ case IPPROTO_TCP:
++ // Compute TCP pseudo-header checksum
++ payload_length = ntohs(ipv4_header->tot_len) - (ipv4_header->ihl*4);
++ break;
++ case IPPROTO_UDP:
++ {
++ struct udphdr* udp_header = (struct udphdr*)((u8*)ipv4_header + (ipv4_header->ihl*4));
++ payload_length = ntohs(udp_header->len);
++ }
++ break;
++ default:
++ // Not supporting any other than TCP/UDP
++ break;
++ }
++#else // CONFIG_OXNAS_VERSION_0X800
++ if (is_hw_checksummable(ipv4_header->protocol)) {
++ ip_summed = CHECKSUM_UNNECESSARY;
++ }
++#endif // CONFIG_OXNAS_VERSION_0X800
++ }
++ }
++#ifndef CONFIG_OXNAS_VERSION_0X800
++ else {
++#ifdef SUPPORT_IPV6
++ struct ipv6hdr* ipv6_header = (struct ipv6hdr*)(skb->data + ETH_HLEN + vlan_offset);
++
++ if (is_hw_checksummable(ipv6_header->nexthdr)) {
++ ip_summed = CHECKSUM_UNNECESSARY;
++ }
++#endif // SUPPORT_IPV6
++ }
++#endif // !CONFIG_OXNAS_VERSION_0X800
++
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ if (payload_length) {
++ // Get the hardware generated payload checksum from
++ // the end of the received packet, reverse the 1's
++ // complement operation that the h/w applies and add
++ // to the pseudo-header checksum, in network order
++ u16 hw_csum = ~(*(u16*)(packet + desc_len + FCS_LEN));
++
++ // Calculate checksum of pseudo header and payload
++ if (csum_tcpudp_magic(
++ ipv4_header->saddr,
++ ipv4_header->daddr,
++ payload_length,
++ ipv4_header->protocol,
++ hw_csum)) {
++ // Bad checksum, so indicate in descriptor status
++ desc_status |= (1UL << RDES0_IPC_BIT);
++ valid = 0;
++ } else {
++ ip_summed = CHECKSUM_UNNECESSARY;
++ }
++ }
++#endif // CONFIG_OXNAS_VERSION_0X800
++ }
++ }
++
++ if (unlikely(!valid)) {
++ goto not_valid;
++ }
++#endif // USE_RX_CSUM
++
++ // Initialise other required skb header fields
++ skb->dev = priv->netdev;
++ skb->protocol = eth_type_trans(skb, priv->netdev);
++
++ // Record whether h/w checksumed the packet
++ skb->ip_summed = ip_summed;
++
++ // Send the skb up the network stack
++ netif_receive_skb(skb);
++
++ // Update receive statistics
++ priv->netdev->last_rx = jiffies;
++ ++priv->stats.rx_packets;
++ priv->stats.rx_bytes += partial_len;
++
++ break;
++ }
++
++ // Want next call to get_rx_descriptor() to read status from descriptor
++ desc_status = 0;
++ }
++ return desc_used;
++
++not_valid:
++ if (!skb_shinfo(skb)->nr_frags) {
++ // Free the page as it wasn't attached to the skb
++ put_page(frag_info.page);
++ }
++
++ dev_kfree_skb(skb);
++
++ DBG(2, KERN_WARNING "process_rx_packet() %s: Received packet has bad desc_status = 0x%08x\n", priv->netdev->name, desc_status);
++
++ // Update receive statistics from the descriptor status
++ if (is_rx_collision_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: Collision (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.collisions;
++ }
++ if (is_rx_crc_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: CRC error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.rx_crc_errors;
++ ++priv->stats.rx_errors;
++ }
++ if (is_rx_frame_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: frame error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.rx_frame_errors;
++ ++priv->stats.rx_errors;
++ }
++ if (is_rx_length_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: Length error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.rx_length_errors;
++ ++priv->stats.rx_errors;
++ }
++ if (is_rx_csum_error(desc_status)) {
++ DBG(20, KERN_INFO "process_rx_packet() %s: Checksum error (0x%08x:%u bytes)\n", priv->netdev->name, desc_status, desc_len);
++ ++priv->stats.rx_frame_errors;
++ ++priv->stats.rx_errors;
++ }
++
++ return desc_used;
++}
++
++/*
++ * NAPI receive polling method
++ */
++static int poll(
++ struct napi_struct *napi,
++ int budget)
++{
++ gmac_priv_t *priv = container_of(napi, gmac_priv_t, napi_struct);
++ struct net_device *dev = priv->netdev;
++ int rx_work_limit = budget;
++ int work_done = 0;
++ int continue_polling;
++ int finished;
++ int available;
++ int desc_since_refill = 0;
++
++ finished = 0;
++ do {
++ u32 status;
++
++ // While there are receive polling jobs to be done
++ while (rx_work_limit) {
++ int desc_used;
++
++ if (unlikely(priv->rx_buffers_per_page)) {
++ desc_used = process_rx_packet(priv);
++ } else {
++ desc_used = process_rx_packet_skb(priv);
++ }
++
++ if (!desc_used) {
++ break;
++ }
++
++ // Increment count of processed packets
++ ++work_done;
++
++ // Decrement our remaining budget
++ if (rx_work_limit > 0) {
++ --rx_work_limit;
++ }
++
++ // Rx overflows seem to upset the GMAC, so try to ensure we never see them
++ desc_since_refill += desc_used;
++ if (desc_since_refill >= DESC_SINCE_REFILL_LIMIT) {
++ desc_since_refill = 0;
++ refill_rx_ring(dev);
++ }
++ }
++
++ if (rx_work_limit) {
++ // We have unused budget remaining, but apparently no Rx packets to
++ // process
++ available = 0;
++
++ // Clear any RI status so we don't immediately get reinterrupted
++ // when we leave polling, due to either a new RI event, or a left
++ // over interrupt from one of the RX descriptors we've already
++ // processed
++ status = dma_reg_read(priv, DMA_STATUS_REG);
++ if (status & (1UL << DMA_STATUS_RI_BIT)) {
++ // Ack the RI, including the normal summary sticky bit
++ dma_reg_write(priv, DMA_STATUS_REG, ((1UL << DMA_STATUS_RI_BIT) |
++ (1UL << DMA_STATUS_NIS_BIT)));
++
++ // Must check again for available RX descriptors, in case the RI
++ // status came from a new RX descriptor
++ available = rx_available_for_read(&priv->rx_gmac_desc_list_info, 0);
++ }
++
++ if (!available) {
++ // We have budget left but no Rx packets to process so stop
++ // polling
++ continue_polling = 0;
++ finished = 1;
++ }
++ } else {
++ // If we have consumed all our budget, don't cancel the
++ // poll, the NAPI instructure assumes we won't
++ continue_polling = 1;
++
++ // Must leave poll() routine as no budget left
++ finished = 1;
++ }
++ } while (!finished);
++
++ // Attempt to fill any empty slots in the RX ring
++ refill_rx_ring(dev);
++
++ // Decrement the budget even if we didn't process any packets
++ if (!work_done) {
++ work_done = 1;
++ }
++
++ if (!continue_polling) {
++ // No more received packets to process so return to interrupt mode
++ netif_rx_complete(dev, napi);
++
++ // Enable interrupts caused by received packets that may have been
++ // disabled in the ISR before entering polled mode
++ gmac_int_en_set(priv, (1UL << DMA_INT_ENABLE_RI_BIT) |
++ (1UL << DMA_INT_ENABLE_RU_BIT) |
++ (1UL << DMA_INT_ENABLE_OV_BIT));
++ }
++
++ return work_done;
++}
++
++#if defined(CONFIG_LEON_COPRO) && defined(CONFIG_LEON_OFFLOAD_TX)
++static void copro_fill_tx_job(
++ volatile gmac_tx_que_ent_t *job,
++ struct sk_buff *skb)
++{
++ int i;
++ int nr_frags = skb_shinfo(skb)->nr_frags;
++ unsigned short flags = 0;
++ dma_addr_t hdr_dma_address;
++
++ // if too many fragments call sbk_linearize()
++ // and take the CPU memory copies hit
++ if (nr_frags > COPRO_NUM_TX_FRAGS_DIRECT) {
++ int err;
++ printk(KERN_WARNING "Fill: linearizing socket buffer as required %d frags and have only %d\n", nr_frags, COPRO_NUM_TX_FRAGS_DIRECT);
++ err = skb_linearize(skb);
++ if (err) {
++ panic("Fill: No free memory");
++ }
++
++ // update nr_frags
++ nr_frags = skb_shinfo(skb)->nr_frags;
++ }
++
++ // Get a DMA mapping of the packet's data
++ hdr_dma_address = dma_map_single(0, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
++ BUG_ON(dma_mapping_error(hdr_dma_address));
++
++ // Allocate storage for remainder of fragments and create DMA mappings
++ // Get a DMA mapping for as many fragments as will fit into the first level
++ // fragment info. storage within the job structure
++ for (i=0; i < nr_frags; ++i) {
++ struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
++ job->frag_ptr_[i] = dma_map_page(0, frag->page, frag->page_offset, frag->size, DMA_TO_DEVICE);
++ job->frag_len_[i] = frag->size;
++ }
++
++ // Is h/w checksumming and possibly TSO required
++ if (likely((skb->ip_summed == CHECKSUM_PARTIAL) &&
++ (ntohs(skb->protocol) == ETH_P_IP))) {
++ flags |= (1UL << TX_JOB_FLAGS_ACCELERATE_BIT);
++ }
++
++ // Fill the job description with information about the packet
++ job->skb_ = (u32)skb;
++ job->len_ = skb->len;
++ job->data_len_ = skb->data_len;
++ job->ethhdr_ = hdr_dma_address;
++ job->iphdr_ = hdr_dma_address + (skb_network_header(skb) - skb->data);
++ job->iphdr_csum_ = ((struct iphdr*)skb_network_header(skb))->check;
++ job->tso_segs_ = skb_shinfo(skb)->gso_segs;
++ job->tso_size_ = skb_shinfo(skb)->gso_size;
++ job->flags_ = flags;
++ job->statistics_ = 0;
++}
++
++static void copro_free_tx_resources(volatile gmac_tx_que_ent_t* job)
++{
++ int i;
++ struct sk_buff* skb = (struct sk_buff*)job->skb_;
++ int nr_frags = skb_shinfo(skb)->nr_frags;
++
++ // This should never happen, since we check space when we filled
++ // the job in copro_fill_tx_job
++ if (nr_frags > COPRO_NUM_TX_FRAGS_DIRECT) {
++ panic("Free: Insufficient fragment storage, required %d, have only %d", nr_frags, COPRO_NUM_TX_FRAGS_DIRECT);
++ }
++
++ // Release the DMA mapping for the data directly referenced by the SKB
++ dma_unmap_single(0, job->ethhdr_, skb_headlen(skb), DMA_TO_DEVICE);
++
++ // Release the DMA mapping for any fragments in the first level fragment
++ // info. storage within the job structure
++ for (i=0; (i < nr_frags) && (i < COPRO_NUM_TX_FRAGS_DIRECT); ++i) {
++ dma_unmap_page(0, job->frag_ptr_[i], job->frag_len_[i], DMA_TO_DEVICE);
++ }
++
++ // Inform the network stack that we've finished with the packet
++ dev_kfree_skb_irq(skb);
++}
++
++static void copro_process_pending_tx_skbs(
++ struct net_device *dev,
++ volatile gmac_tx_que_ent_t *job)
++{
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++
++ // Process pending SKBs, oldest first
++ do {
++ // Get the oldest pending SKB
++ struct sk_buff *skb;
++ struct list_head *entry = priv->copro_tx_skb_list_.next;
++ BUG_ON(!entry);
++ list_del(entry);
++
++ skb = list_entry(entry, struct sk_buff, cb);
++ BUG_ON(!skb);
++
++ // Keep track of how many entries are in the pending SKB list
++ --priv->copro_tx_skb_list_count_;
++
++ // Fill the Tx offload job with the network packet's details
++ copro_fill_tx_job(job, skb);
++
++ // Enqueue the new Tx offload job with the CoPro
++ tx_que_new_job(dev, job);
++
++ if (list_empty(&priv->copro_tx_skb_list_)) {
++ // No more pending SKBs
++ break;
++ }
++ } while ((job = tx_que_get_idle_job(dev)));
++}
++
++static void finish_xmit(struct net_device *dev)
++{
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ volatile gmac_tx_que_ent_t *job;
++
++ // Process all available completed jobs
++ while ((job = tx_que_get_finished_job(dev))) {
++ int aborted;
++ int carrier;
++ int collisions;
++ u32 statistics = job->statistics_;
++
++ copro_free_tx_resources(job);
++
++ // Accumulate TX statistics returned by CoPro in the job structure
++ priv->stats.tx_bytes += (statistics & TX_JOB_STATS_BYTES_MASK) >> TX_JOB_STATS_BYTES_BIT;
++ priv->stats.tx_packets += (statistics & TX_JOB_STATS_PACKETS_MASK) >> TX_JOB_STATS_PACKETS_BIT;
++ aborted = (statistics & TX_JOB_STATS_ABORT_MASK) >> TX_JOB_STATS_ABORT_BIT;
++ carrier = (statistics & TX_JOB_STATS_CARRIER_MASK) >> TX_JOB_STATS_CARRIER_BIT;
++ collisions = (statistics & TX_JOB_STATS_COLLISION_MASK) >> TX_JOB_STATS_COLLISION_BIT;
++ priv->stats.tx_aborted_errors += aborted;
++ priv->stats.tx_carrier_errors += carrier;
++ priv->stats.collisions += collisions;
++ priv->stats.tx_errors += (aborted + carrier);
++ }
++
++ // Process any queued pending SKBs for which resources are available
++ if (priv->copro_tx_skb_list_count_ && (job = tx_que_get_idle_job(dev))) {
++ copro_process_pending_tx_skbs(dev, job);
++
++ // Record start of transmission, so timeouts will work once they're
++ // implemented
++ dev->trans_start = jiffies;
++
++ // Interrupt the CoPro to cause it to examine the Tx offload queue
++ wmb();
++ writel(1UL << COPRO_SEM_INT_TX, SYS_CTRL_SEMA_SET_CTRL);
++ }
++
++ // If the network stack's Tx queue was stopped and we now have resources
++ // to process more Tx offload jobs
++ if (netif_queue_stopped(dev) &&
++ !tx_que_is_full(&priv->tx_queue_) &&
++ !priv->copro_tx_skb_list_count_) {
++ // Restart the network stack's TX queue
++ netif_wake_queue(dev);
++ }
++}
++#else
++static void finish_xmit(struct net_device *dev)
++{
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ unsigned descriptors_freed = 0;
++ u32 desc_status = 0;
++
++ // Handle transmit descriptors for the completed packet transmission
++ while (1) {
++ struct sk_buff *skb;
++ tx_frag_info_t fragment;
++ int buffer_owned;
++ int desc_index;
++
++ // Get tx descriptor content, accumulating status for all buffers
++ // contributing to each packet
++ desc_index = get_tx_descriptor(priv, &skb, &desc_status, &fragment, &buffer_owned);
++
++ if (desc_index < 0) {
++ // No more completed Tx packets
++ break;
++ }
++
++ // Only unmap DMA buffer if descriptor owned the buffer
++ if (buffer_owned) {
++ // Release the DMA mapping for the buffer
++ dma_unmap_single(0, fragment.phys_adr, fragment.length, DMA_TO_DEVICE);
++ }
++
++ // When all buffers contributing to a packet have been processed
++ if (skb) {
++ // Check the status of the transmission
++ if (likely(is_tx_valid(desc_status))) {
++ priv->stats.tx_bytes += skb->len;
++ priv->stats.tx_packets++;
++ } else {
++ priv->stats.tx_errors++;
++ if (is_tx_aborted(desc_status)) {
++ ++priv->stats.tx_aborted_errors;
++ }
++ if (is_tx_carrier_error(desc_status)) {
++ ++priv->stats.tx_carrier_errors;
++ }
++ }
++
++ if (unlikely(is_tx_collision_error(desc_status))) {
++ ++priv->stats.collisions;
++ }
++
++ // Inform the network stack that packet transmission has finished
++ dev_kfree_skb_irq(skb);
++
++ // Start accumulating status for the next packet
++ desc_status = 0;
++ }
++
++ // Track how many descriptors we make available, so we know
++ // if we need to re-start of network stack's TX queue processing
++ ++descriptors_freed;
++ }
++
++ // If the TX queue is stopped, there may be a pending TX packet waiting to
++ // be transmitted
++ if (unlikely(netif_queue_stopped(dev))) {
++ // No locking with hard_start_xmit() required, as queue is already
++ // stopped so hard_start_xmit() won't touch the h/w
++
++ // If any TX descriptors have been freed and there is an outstanding TX
++ // packet waiting to be queued due to there not having been a TX
++ // descriptor available when hard_start_xmit() was presented with an skb
++ // by the network stack
++ if (priv->tx_pending_skb) {
++ // Construct the GMAC specific DMA descriptor
++ if (set_tx_descriptor(priv,
++ priv->tx_pending_skb,
++ priv->tx_pending_fragments,
++ priv->tx_pending_fragment_count,
++ priv->tx_pending_skb->ip_summed == CHECKSUM_PARTIAL) >= 0) {
++ // No TX packets now outstanding
++ priv->tx_pending_skb = 0;
++ priv->tx_pending_fragment_count = 0;
++
++ // We have used one of the TX descriptors freed by transmission
++ // completion processing having occured above
++ --descriptors_freed;
++
++ // Issue a TX poll demand to restart TX descriptor processing, as we
++ // have just added one, in case it had found there were no more
++ // pending transmission
++ dma_reg_write(priv, DMA_TX_POLL_REG, 0);
++ }
++ }
++
++ // If there are TX descriptors available we should restart the TX queue
++ if (descriptors_freed) {
++ // The TX queue had been stopped by hard_start_xmit() due to lack of
++ // TX descriptors, so restart it now that we've freed at least one
++ netif_wake_queue(dev);
++ }
++ }
++}
++#endif // CONFIG_LEON_COPRO && CONFIG_LEON_OFFLOAD_TX
++
++#ifndef CONFIG_LEON_COPRO
++static void process_non_dma_ints(u32 raw_status)
++{
++ printk(KERN_ERR "Found GPI/GMI/GLI interrupt\n");
++}
++#endif // !CONFIG_LEON_COPRO
++
++#ifdef CONFIG_LEON_COPRO
++static void copro_fwd_intrs_handler(
++ void *dev_id,
++ u32 status)
++{
++ struct net_device *dev = (struct net_device *)dev_id;
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ int restart_watchdog = 0;
++ int restart_tx = 0;
++ int poll_tx = 0;
++
++ // Test for normal receive interrupt
++ if (status & (1UL << DMA_STATUS_RI_BIT)) {
++ if (netif_rx_schedule_prep(dev, &priv->napi_struct)) {
++ // Tell system we have work to be done
++ __netif_rx_schedule(dev, &priv->napi_struct);
++ } else {
++ printk(KERN_ERR "copro_fwd_intrs_handler() %s: RX interrupt while in poll\n", dev->name);
++ }
++ }
++
++ // Test for unavailable RX buffers - CoPro should have disabled
++ if (unlikely(status & (1UL << DMA_STATUS_RU_BIT))) {
++ DBG(30, KERN_INFO "int_handler() %s: RX buffer unavailable\n", dev->name);
++ // Accumulate receive statistics
++ ++priv->stats.rx_over_errors;
++ ++priv->stats.rx_errors;
++ }
++
++ // Test for Rx overflow - CoPro should have disabled
++ if (unlikely(status & (1UL << DMA_STATUS_OVF_BIT))) {
++ DBG(30, KERN_INFO "int_handler() %s: Rx overflow\n", dev->name);
++ // Accumulate receive statistics
++ ++priv->stats.rx_fifo_errors;
++ ++priv->stats.rx_errors;
++ }
++
++ // Test for normal TX interrupt
++ if (status & ((1UL << DMA_STATUS_TI_BIT) |
++ (1UL << DMA_STATUS_ETI_BIT))) {
++#ifndef CONFIG_LEON_OFFLOAD_TX
++ // Finish packet transmision started by start_xmit
++ finish_xmit(dev);
++#endif // !CONFIG_LEON_OFFLOAD_TX
++ }
++
++ // Test for abnormal transmitter interrupt where there may be completed
++ // packets waiting to be processed
++ if (unlikely(status & ((1UL << DMA_STATUS_TJT_BIT) |
++ (1UL << DMA_STATUS_UNF_BIT)))) {
++#ifndef CONFIG_LEON_OFFLOAD_TX
++ // Complete processing of any TX packets closed by the DMA
++ finish_xmit(dev);
++#endif // !CONFIG_LEON_OFFLOAD_TX
++
++ if (status & (1UL << DMA_STATUS_TJT_BIT)) {
++ // A transmit jabber timeout causes the transmitter to enter the
++ // stopped state
++ DBG(50, KERN_INFO "int_handler() %s: TX jabber timeout\n", dev->name);
++ restart_tx = 1;
++ } else {
++ DBG(51, KERN_INFO "int_handler() %s: TX underflow\n", dev->name);
++ }
++
++ // Issue a TX poll demand in an attempt to restart TX descriptor
++ // processing
++ poll_tx = 1;
++ }
++
++ // Test for any of the error states which we deal with directly within
++ // this interrupt service routine.
++ if (unlikely(status & ((1UL << DMA_STATUS_ERI_BIT) |
++ (1UL << DMA_STATUS_RWT_BIT) |
++ (1UL << DMA_STATUS_RPS_BIT) |
++ (1UL << DMA_STATUS_TPS_BIT) |
++ (1UL << DMA_STATUS_FBE_BIT)))) {
++ // Test for early RX interrupt
++ if (status & (1UL << DMA_STATUS_ERI_BIT)) {
++ // Don't expect to see this, as never enable it
++ DBG(30, KERN_WARNING "int_handler() %s: Early RX \n", dev->name);
++ }
++
++ if (status & (1UL << DMA_STATUS_RWT_BIT)) {
++ DBG(30, KERN_INFO "int_handler() %s: RX watchdog timeout\n", dev->name);
++ // Accumulate receive statistics
++ ++priv->stats.rx_frame_errors;
++ ++priv->stats.rx_errors;
++ restart_watchdog = 1;
++ }
++
++ if (status & (1UL << DMA_STATUS_RPS_BIT)) {
++ // Mask to extract the receive status field from the status register
++// u32 rs_mask = ((1UL << DMA_STATUS_RS_NUM_BITS) - 1) << DMA_STATUS_RS_BIT;
++// u32 rs = (status & rs_mask) >> DMA_STATUS_RS_BIT;
++// printk("int_handler() %s: RX process stopped 0x%x\n", dev->name, rs);
++ ++priv->stats.rx_errors;
++ restart_watchdog = 1;
++
++ // Restart the receiver
++ DBG(35, KERN_INFO "int_handler() %s: Restarting receiver\n", dev->name);
++ change_rx_enable(priv, 1, 0, 1);
++ }
++
++ if (status & (1UL << DMA_STATUS_TPS_BIT)) {
++ // Mask to extract the transmit status field from the status register
++// u32 ts_mask = ((1UL << DMA_STATUS_TS_NUM_BITS) - 1) << DMA_STATUS_TS_BIT;
++// u32 ts = (status & ts_mask) >> DMA_STATUS_TS_BIT;
++// printk("int_handler() %s: TX process stopped 0x%x\n", dev->name, ts);
++ ++priv->stats.tx_errors;
++ restart_watchdog = 1;
++ restart_tx = 1;
++ }
++
++ // Test for pure error interrupts
++ if (status & (1UL << DMA_STATUS_FBE_BIT)) {
++ // Mask to extract the bus error status field from the status register
++// u32 eb_mask = ((1UL << DMA_STATUS_EB_NUM_BITS) - 1) << DMA_STATUS_EB_BIT;
++// u32 eb = (status & eb_mask) >> DMA_STATUS_EB_BIT;
++// printk("int_handler() %s: Bus error 0x%x\n", dev->name, eb);
++ restart_watchdog = 1;
++ }
++
++ if (restart_watchdog) {
++ // Restart the link/PHY state watchdog immediately, which will
++ // attempt to restart the system
++ mod_timer(&priv->watchdog_timer, jiffies);
++ restart_watchdog = 0;
++ }
++ }
++
++ if (unlikely(restart_tx)) {
++ // Restart the transmitter, causes am implicit Tx descriptor list poll
++ DBG(35, KERN_INFO "int_handler() %s: Restarting transmitter\n", dev->name);
++#ifndef CONFIG_LEON_OFFLOAD_TX
++ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
++#endif // !CONFIG_LEON_OFFLOAD_TX
++ poll_tx = 0;
++ }
++
++ if (unlikely(poll_tx)) {
++ // Issue a TX poll demand in an attempt to restart TX descriptor
++ // processing
++ DBG(33, KERN_INFO "int_handler() %s: Issuing Tx poll demand\n", dev->name);
++#ifndef CONFIG_LEON_OFFLOAD_TX
++ dma_reg_write(priv, DMA_TX_POLL_REG, 0);
++#endif // !CONFIG_LEON_OFFLOAD_TX
++ }
++}
++#else // CONFIG_LEON_COPRO
++static irqreturn_t int_handler(int int_num, void* dev_id)
++{
++ struct net_device *dev = (struct net_device *)dev_id;
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++ u32 int_enable;
++ int rx_polling;
++ u32 raw_status;
++ u32 status;
++
++ /** Read the interrupt enable register to determine if we're in rx poll mode
++ * Id like to get rid of this read, if a more efficient way of determining
++ * whether we are polling is available */
++ spin_lock(&priv->cmd_que_lock_);
++ int_enable = dma_reg_read(priv, DMA_INT_ENABLE_REG);
++ spin_unlock(&priv->cmd_que_lock_);
++
++ rx_polling = !(int_enable & (1UL << DMA_INT_ENABLE_RI_BIT));
++
++ // Get interrupt status
++ raw_status = dma_reg_read(priv, DMA_STATUS_REG);
++
++ // MMC, PMT and GLI interrupts are not masked by the interrupt enable
++ // register, so must deal with them on the raw status
++ if (unlikely(raw_status & ((1UL << DMA_STATUS_GPI_BIT) |
++ (1UL << DMA_STATUS_GMI_BIT) |
++ (1UL << DMA_STATUS_GLI_BIT)))) {
++ process_non_dma_ints(raw_status);
++ }
++
++ // Get status of enabled interrupt sources
++ status = raw_status & int_enable;
++
++ while (status) {
++ // Whether the link/PHY watchdog timer should be restarted
++ int restart_watchdog = 0;
++ int restart_tx = 0;
++ int poll_tx = 0;
++ u32 int_disable_mask = 0;
++
++ // Test for RX interrupt resulting from sucessful reception of a packet-
++ // must do this before ack'ing, else otherwise can get into trouble with
++ // the sticky summary bits when we try to disable further RI interrupts
++ if (status & (1UL << DMA_STATUS_RI_BIT)) {
++//printk("RI ");
++ // Disable interrupts caused by received packets as henceforth
++ // we shall poll for packet reception
++ int_disable_mask |= (1UL << DMA_INT_ENABLE_RI_BIT);
++
++ // Do NAPI compatible receive processing for RI interrupts
++ if (likely(netif_rx_schedule_prep(dev, &priv->napi_struct))) {
++ // Remember that we are polling, so we ignore RX events for the
++ // remainder of the ISR
++ rx_polling = 1;
++
++ // Tell system we have work to be done
++ __netif_rx_schedule(dev, &priv->napi_struct);
++ } else {
++ printk(KERN_ERR "int_handler() %s: RX interrupt while in poll\n", dev->name);
++ }
++ }
++
++ // Test for unavailable RX buffers - must do this before ack'ing, else
++ // otherwise can get into trouble with the sticky summary bits
++ if (unlikely(status & (1UL << DMA_STATUS_RU_BIT))) {
++ printk(/*DBG(30, KERN_INFO */"int_handler() %s: RX buffer unavailable\n", dev->name);
++ // Accumulate receive statistics
++ ++priv->stats.rx_over_errors;
++ ++priv->stats.rx_errors;
++
++ // Disable RX buffer unavailable reporting, so we don't get swamped
++ int_disable_mask |= (1UL << DMA_INT_ENABLE_RU_BIT);
++ }
++
++ if (unlikely(status & (1UL << DMA_STATUS_OVF_BIT))) {
++ printk(/*DBG(30, KERN_INFO */"int_handler() %s: RX overflow\n", dev->name);
++ // Accumulate receive statistics
++ ++priv->stats.rx_fifo_errors;
++ ++priv->stats.rx_errors;
++
++ // Disable RX overflow reporting, so we don't get swamped
++ int_disable_mask |= (1UL << DMA_INT_ENABLE_OV_BIT);
++ }
++
++ // Do any interrupt disabling with a single register write
++ if (int_disable_mask) {
++ gmac_int_en_clr(priv, int_disable_mask, 0);
++
++ // Update our record of the current interrupt enable status
++ int_enable &= ~int_disable_mask;
++ }
++
++ // The broken GMAC interrupt mechanism with its sticky summary bits
++ // means that we have to ack all asserted interrupts here; we can't not
++ // ack the RI interrupt source as we might like to (in order that the
++ // poll() routine could examine the status) because if it was asserted
++ // prior to being masked above, then the summary bit(s) would remain
++ // asserted and cause an immediate re-interrupt.
++ dma_reg_write(priv, DMA_STATUS_REG, status | ((1UL << DMA_STATUS_NIS_BIT) |
++ (1UL << DMA_STATUS_AIS_BIT)));
++
++ // Test for normal TX interrupt
++ if (status & ((1UL << DMA_STATUS_TI_BIT) |
++ (1UL << DMA_STATUS_ETI_BIT))) {
++ // Finish packet transmision started by start_xmit
++ finish_xmit(dev);
++ }
++
++ // Test for abnormal transmitter interrupt where there may be completed
++ // packets waiting to be processed
++ if (unlikely(status & ((1UL << DMA_STATUS_TJT_BIT) |
++ (1UL << DMA_STATUS_UNF_BIT)))) {
++ // Complete processing of any TX packets closed by the DMA
++ finish_xmit(dev);
++
++ if (status & (1UL << DMA_STATUS_TJT_BIT)) {
++ // A transmit jabber timeout causes the transmitter to enter the
++ // stopped state
++ DBG(50, KERN_INFO "int_handler() %s: TX jabber timeout\n", dev->name);
++ restart_tx = 1;
++ } else {
++ DBG(51, KERN_INFO "int_handler() %s: TX underflow\n", dev->name);
++ }
++
++ // Issue a TX poll demand in an attempt to restart TX descriptor
++ // processing
++ poll_tx = 1;
++ }
++
++ // Test for any of the error states which we deal with directly within
++ // this interrupt service routine.
++ if (unlikely(status & ((1UL << DMA_STATUS_ERI_BIT) |
++ (1UL << DMA_STATUS_RWT_BIT) |
++ (1UL << DMA_STATUS_RPS_BIT) |
++ (1UL << DMA_STATUS_TPS_BIT) |
++ (1UL << DMA_STATUS_FBE_BIT)))) {
++ // Test for early RX interrupt
++ if (status & (1UL << DMA_STATUS_ERI_BIT)) {
++ // Don't expect to see this, as never enable it
++ DBG(30, KERN_WARNING "int_handler() %s: Early RX \n", dev->name);
++ }
++
++ if (status & (1UL << DMA_STATUS_RWT_BIT)) {
++ DBG(30, KERN_INFO "int_handler() %s: RX watchdog timeout\n", dev->name);
++ // Accumulate receive statistics
++ ++priv->stats.rx_frame_errors;
++ ++priv->stats.rx_errors;
++ restart_watchdog = 1;
++ }
++
++ if (status & (1UL << DMA_STATUS_RPS_BIT)) {
++ // Mask to extract the receive status field from the status register
++ u32 rs_mask = ((1UL << DMA_STATUS_RS_NUM_BITS) - 1) << DMA_STATUS_RS_BIT;
++ u32 rs = (status & rs_mask) >> DMA_STATUS_RS_BIT;
++ printk(/*DBG(30, KERN_INFO */"int_handler() %s: RX process stopped 0x%x\n", dev->name, rs);
++ ++priv->stats.rx_errors;
++ restart_watchdog = 1;
++
++ // Restart the receiver
++ printk(/*DBG(35, KERN_INFO */"int_handler() %s: Restarting receiver\n", dev->name);
++ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SR_BIT));
++ }
++
++ if (status & (1UL << DMA_STATUS_TPS_BIT)) {
++ // Mask to extract the transmit status field from the status register
++// u32 ts_mask = ((1UL << DMA_STATUS_TS_NUM_BITS) - 1) << DMA_STATUS_TS_BIT;
++// u32 ts = (status & ts_mask) >> DMA_STATUS_TS_BIT;
++// DBG(30, KERN_INFO "int_handler() %s: TX process stopped 0x%x\n", dev->name, ts);
++ ++priv->stats.tx_errors;
++ restart_watchdog = 1;
++ restart_tx = 1;
++ }
++
++ // Test for pure error interrupts
++ if (status & (1UL << DMA_STATUS_FBE_BIT)) {
++ // Mask to extract the bus error status field from the status register
++// u32 eb_mask = ((1UL << DMA_STATUS_EB_NUM_BITS) - 1) << DMA_STATUS_EB_BIT;
++// u32 eb = (status & eb_mask) >> DMA_STATUS_EB_BIT;
++// DBG(30, KERN_INFO "int_handler() %s: Bus error 0x%x\n", dev->name, eb);
++ restart_watchdog = 1;
++ }
++
++ if (restart_watchdog) {
++ // Restart the link/PHY state watchdog immediately, which will
++ // attempt to restart the system
++ mod_timer(&priv->watchdog_timer, jiffies);
++ restart_watchdog = 0;
++ }
++ }
++
++ if (unlikely(restart_tx)) {
++ // Restart the transmitter
++ DBG(35, KERN_INFO "int_handler() %s: Restarting transmitter\n", dev->name);
++ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
++ }
++
++ if (unlikely(poll_tx)) {
++ // Issue a TX poll demand in an attempt to restart TX descriptor
++ // processing
++ DBG(33, KERN_INFO "int_handler() %s: Issuing Tx poll demand\n", dev->name);
++ dma_reg_write(priv, DMA_TX_POLL_REG, 0);
++ }
++
++ // Read the record of current interrupt requests again, in case some
++ // more arrived while we were processing
++ raw_status = dma_reg_read(priv, DMA_STATUS_REG);
++
++ // MMC, PMT and GLI interrupts are not masked by the interrupt enable
++ // register, so must deal with them on the raw status
++ if (unlikely(raw_status & ((1UL << DMA_STATUS_GPI_BIT) |
++ (1UL << DMA_STATUS_GMI_BIT) |
++ (1UL << DMA_STATUS_GLI_BIT)))) {
++ process_non_dma_ints(raw_status);
++ }
++
++ // Get status of enabled interrupt sources.
++ status = raw_status & int_enable;
++ }
++
++ return IRQ_HANDLED;
++}
++#endif // CONFIG_LEON_COPRO
++
++#ifdef CONFIG_LEON_COPRO
++static struct semaphore copro_stop_semaphore;
++
++static void copro_stop_callback(volatile gmac_cmd_que_ent_t* entry)
++{
++ up(&copro_stop_semaphore);
++}
++#endif // CONFIG_LEON_COPRO
++
++static void gmac_down(struct net_device *dev)
++{
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++ int desc;
++ u32 int_enable;
++#ifdef CONFIG_LEON_COPRO
++ tx_que_t *tx_queue = &priv->tx_queue_;
++ int cmd_queue_result;
++#endif // CONFIG_LEON_COPRO
++
++ // Stop NAPI
++ napi_disable(&priv->napi_struct);
++
++ // Stop further TX packets being delivered to hard_start_xmit();
++ netif_stop_queue(dev);
++ netif_carrier_off(dev);
++
++ // Disable all GMAC interrupts and wait for change to be acknowledged
++ gmac_int_en_clr(priv, ~0UL, &int_enable, 0);
++
++#ifdef CONFIG_LEON_COPRO
++ // Tell the CoPro to stop network offload operations
++ cmd_queue_result = -1;
++ while (cmd_queue_result) {
++ spin_lock(&priv->cmd_que_lock_);
++ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_STOP, 0, copro_stop_callback);
++ spin_unlock(&priv->cmd_que_lock_);
++ }
++
++ // Interrupt the CoPro so it sees the new command
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++
++ // Wait until the CoPro acknowledges the STOP command
++ down_interruptible(&copro_stop_semaphore);
++
++ // Wait until the CoPro acknowledges that it has completed stopping
++ down_interruptible(&priv->copro_stop_complete_semaphore_);
++
++ // Clear out the Tx offload job queue, deallocating associated resources
++ while (tx_que_not_empty(tx_queue)) {
++ // Free any dynamic fragment ptr/len storage
++ /** @todo */
++ tx_que_inc_r_ptr(tx_queue);
++ }
++
++ // Reinitialise the Tx offload queue metadata
++ tx_que_init(
++ &priv->tx_queue_,
++ (gmac_tx_que_ent_t*)descriptors_phys_to_virt(priv->copro_params_.tx_que_head_),
++ priv->copro_tx_que_num_entries_);
++
++ // Empty the pending SKB queue
++ while (!list_empty(&priv->copro_tx_skb_list_)) {
++ struct sk_buff *skb;
++
++ // Remove the first entry on the list
++ struct list_head *entry = priv->copro_tx_skb_list_.next;
++ BUG_ON(!entry);
++ list_del(entry);
++
++ // Get pointer to SKB from it's list_head member
++ skb = list_entry(entry, struct sk_buff, cb);
++ BUG_ON(!skb);
++
++ // Inform the network stack that we've finished with the packet
++ dev_kfree_skb(skb);
++ }
++ priv->copro_tx_skb_list_count_ = 0;
++#endif // CONFIG_LEON_COPRO
++
++#ifndef CONFIG_LEON_OFFLOAD_TX
++ // Stop transmitter, take ownership of all tx descriptors
++ dma_reg_clear_mask(priv, DMA_OP_MODE_REG, 1UL << DMA_OP_MODE_ST_BIT);
++ if (priv->desc_vaddr) {
++ tx_take_ownership(&priv->tx_gmac_desc_list_info);
++ }
++#endif // !CONFIG_LEON_OFFLOAD_TX
++
++ // Stop receiver, waiting until it's really stopped and then take ownership
++ // of all rx descriptors
++ change_rx_enable(priv, 0, 1, 0);
++
++ if (priv->desc_vaddr) {
++ rx_take_ownership(&priv->rx_gmac_desc_list_info);
++ }
++
++ // Stop all timers
++ delete_watchdog_timer(priv);
++
++ if (priv->desc_vaddr) {
++ // Free receive descriptors
++ do {
++ int first_last = 0;
++ rx_frag_info_t frag_info;
++
++ desc = get_rx_descriptor(priv, &first_last, 0, &frag_info);
++ if (desc >= 0) {
++ if (unlikely(priv->rx_buffers_per_page)) {
++ // If this is the last packet in the page, release the DMA mapping
++ unmap_rx_page(priv, frag_info.phys_adr);
++ put_page(frag_info.page);
++ } else {
++ // Release the DMA mapping for the packet buffer
++ dma_unmap_single(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
++
++ // Free the skb
++ dev_kfree_skb((struct sk_buff *)frag_info.page);
++ }
++ }
++ } while (desc >= 0);
++
++ // Free transmit descriptors
++ do {
++ struct sk_buff *skb;
++ tx_frag_info_t frag_info;
++ int buffer_owned;
++
++ desc = get_tx_descriptor(priv, &skb, 0, &frag_info, &buffer_owned);
++ if (desc >= 0) {
++ if (buffer_owned) {
++ // Release the DMA mapping for the packet buffer
++ dma_unmap_single(0, frag_info.phys_adr, frag_info.length, DMA_FROM_DEVICE);
++ }
++
++ if (skb) {
++ // Free the skb
++ dev_kfree_skb(skb);
++ }
++ }
++ } while (desc >= 0);
++
++ // Free any resources associated with the buffers of a pending packet
++ if (priv->tx_pending_fragment_count) {
++ tx_frag_info_t *frag_info = priv->tx_pending_fragments;
++
++ while (priv->tx_pending_fragment_count--) {
++ dma_unmap_single(0, frag_info->phys_adr, frag_info->length, DMA_FROM_DEVICE);
++ ++frag_info;
++ }
++ }
++
++ // Free the socket buffer of a pending packet
++ if (priv->tx_pending_skb) {
++ dev_kfree_skb(priv->tx_pending_skb);
++ priv->tx_pending_skb = 0;
++ }
++ }
++
++ // Power down the PHY
++ phy_powerdown(dev);
++}
++
++static int stop(struct net_device *dev)
++{
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++
++ gmac_down(dev);
++
++#ifdef CONFIG_LEON_COPRO
++ shutdown_copro();
++
++ if (priv->shared_copro_params_) {
++ // Free the DMA coherent parameter space
++ dma_free_coherent(0, sizeof(copro_params_t), priv->shared_copro_params_, priv->shared_copro_params_pa_);
++ priv->shared_copro_params_ = 0;
++ }
++
++ // Disable semaphore register from causing ARM interrupts
++ *((volatile unsigned long*)SYS_CTRL_SEMA_MASKA_CTRL) = 0;
++ *((volatile unsigned long*)SYS_CTRL_SEMA_MASKB_CTRL) = 0;
++
++ // Release interrupts lines used by semaphore register interrupts
++ if (priv->copro_a_irq_alloced_) {
++ free_irq(priv->copro_a_irq_, dev);
++ priv->copro_a_irq_alloced_ = 0;
++ }
++ if (priv->copro_b_irq_alloced_) {
++ free_irq(priv->copro_b_irq_, dev);
++ priv->copro_b_irq_alloced_ = 0;
++ }
++#endif // CONFIG_LEON_COPRO
++
++ // Free the shadow descriptor memory
++ kfree(priv->tx_desc_shadow_);
++ priv->tx_desc_shadow_ = 0;
++
++ kfree(priv->rx_desc_shadow_);
++ priv->rx_desc_shadow_ = 0;
++
++ // Release the IRQ
++ if (priv->have_irq) {
++ free_irq(dev->irq, dev);
++ priv->have_irq = 0;
++ }
++
++ // Disable the clock to the MAC block
++ writel(1UL << SYS_CTRL_CKEN_MAC_BIT, SYS_CTRL_CKEN_CLR_CTRL);
++
++ // Free the sysfs resources
++ kobject_del(&priv->link_state_kobject);
++ subsystem_unregister(&priv->link_state_kset);
++
++ return 0;
++}
++
++static void hw_set_mac_address(struct net_device *dev, unsigned char* addr)
++{
++ u32 mac_lo;
++ u32 mac_hi;
++
++ mac_lo = (u32)addr[0];
++ mac_lo |= ((u32)addr[1] << 8);
++ mac_lo |= ((u32)addr[2] << 16);
++ mac_lo |= ((u32)addr[3] << 24);
++
++ mac_hi = (u32)addr[4];
++ mac_hi |= ((u32)addr[5] << 8);
++
++ mac_reg_write(netdev_priv(dev), MAC_ADR0_LOW_REG, mac_lo);
++ mac_reg_write(netdev_priv(dev), MAC_ADR0_HIGH_REG, mac_hi);
++}
++
++static int set_mac_address(struct net_device *dev, void *p)
++{
++ struct sockaddr *addr = p;
++
++ if (!is_valid_ether_addr(addr->sa_data)) {
++ return -EADDRNOTAVAIL;
++ }
++
++ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
++ hw_set_mac_address(dev, addr->sa_data);
++
++ return 0;
++}
++
++static void multicast_hash(struct dev_mc_list *dmi, u32 *hash_lo, u32 *hash_hi)
++{
++ u32 crc = ether_crc_le(dmi->dmi_addrlen, dmi->dmi_addr);
++ u32 mask = 1 << ((crc >> 26) & 0x1F);
++
++ if (crc >> 31) {
++ *hash_hi |= mask;
++ } else {
++ *hash_lo |= mask;
++ }
++}
++
++static void set_multicast_list(struct net_device *dev)
++{
++ gmac_priv_t* priv = netdev_priv(dev);
++ u32 hash_lo=0;
++ u32 hash_hi=0;
++ u32 mode = 0;
++ int i;
++
++ // Disable promiscuous mode and uni/multi-cast matching
++ mac_reg_write(priv, MAC_FRAME_FILTER_REG, mode);
++
++ // Disable all perfect match registers
++ for (i=0; i < NUM_PERFECT_MATCH_REGISTERS; ++i) {
++ mac_adrhi_reg_write(priv, i, 0);
++ }
++
++ // Promiscuous mode overrides all-multi which overrides other filtering
++ if (dev->flags & IFF_PROMISC) {
++ mode |= (1 << MAC_FRAME_FILTER_PR_BIT);
++ } else if (dev->flags & IFF_ALLMULTI) {
++ mode |= (1 << MAC_FRAME_FILTER_PM_BIT);
++ } else {
++ struct dev_mc_list *dmi;
++
++ if (dev->mc_count <= NUM_PERFECT_MATCH_REGISTERS) {
++ // Use perfect matching registers
++ for (i=0, dmi = dev->mc_list; dmi; dmi = dmi->next, ++i) {
++ u32 addr;
++
++ addr = dmi->dmi_addr[0];
++ addr |= (u32)dmi->dmi_addr[1] << 8;
++ addr |= (u32)dmi->dmi_addr[2] << 16;
++ addr |= (u32)dmi->dmi_addr[3] << 24;
++ mac_adrlo_reg_write(priv, i, addr);
++
++ addr = dmi->dmi_addr[4];
++ addr |= (u32)dmi->dmi_addr[5] << 8;
++ addr |= (1 << MAC_ADR1_HIGH_AE_BIT);
++ mac_adrhi_reg_write(priv, i, addr);
++ }
++ } else {
++ // Use hashing
++ mode |= (1 << MAC_FRAME_FILTER_HUC_BIT);
++ mode |= (1 << MAC_FRAME_FILTER_HMC_BIT);
++
++ for (dmi = dev->mc_list; dmi; dmi = dmi->next) {
++ multicast_hash(dmi, &hash_lo, &hash_hi);
++ }
++ }
++ }
++
++ // Update the filtering rules
++ mac_reg_write(priv, MAC_FRAME_FILTER_REG, mode);
++
++ // Update the filtering hash table
++ mac_reg_write(priv, MAC_HASH_LOW_REG, hash_lo);
++ mac_reg_write(priv, MAC_HASH_HIGH_REG, hash_hi);
++}
++
++static int gmac_up(struct net_device *dev)
++{
++ int status = 0;
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ u32 reg_contents;
++#ifdef CONFIG_LEON_COPRO
++ int cmd_queue_result;
++#endif // CONFIG_LEON_COPRO
++
++ // Reset the entire GMAC
++ dma_reg_write(priv, DMA_BUS_MODE_REG, 1UL << DMA_BUS_MODE_SWR_BIT);
++
++ // Ensure reset is performed before testing for completion
++ wmb();
++
++ // Wait for the reset operation to complete
++ status = -EIO;
++ printk(KERN_INFO "Resetting GMAC\n");
++ for (;;) {
++ if (!(dma_reg_read(priv, DMA_BUS_MODE_REG) & (1UL << DMA_BUS_MODE_SWR_BIT))) {
++ status = 0;
++ break;
++ }
++ }
++
++ // Did the GMAC reset operation fail?
++ if (status) {
++ printk(KERN_ERR "open() %s: GMAC reset failed\n", dev->name);
++ goto gmac_up_err_out;
++ }
++ printk(KERN_INFO "GMAC reset complete\n");
++
++ /* Initialise MAC config register contents
++ */
++ reg_contents = 0;
++ if (!priv->mii.using_1000) {
++ DBG(1, KERN_INFO "open() %s: PHY in 10/100Mb mode\n", dev->name);
++ reg_contents |= (1UL << MAC_CONFIG_PS_BIT);
++ } else {
++ DBG(1, KERN_INFO "open() %s: PHY in 1000Mb mode\n", dev->name);
++ }
++ if (priv->mii.full_duplex) {
++ reg_contents |= (1UL << MAC_CONFIG_DM_BIT);
++ }
++
++#ifdef USE_RX_CSUM
++ reg_contents |= (1UL << MAC_CONFIG_IPC_BIT);
++#endif // USE_RX_CSUM
++
++ if (priv->jumbo_) {
++ // Allow passage of jumbo frames through both transmitter and receiver
++ reg_contents |= ((1UL << MAC_CONFIG_JE_BIT) |
++ (1UL << MAC_CONFIG_JD_BIT) |
++ (1UL << MAC_CONFIG_WD_BIT));
++ }
++
++ // Enable transmitter and receiver
++ reg_contents |= ((1UL << MAC_CONFIG_TE_BIT) |
++ (1UL << MAC_CONFIG_RE_BIT));
++
++ // Select the minimum IFG - I found that 80 bit times caused very poor
++ // IOZone performance, so stcik with the 96 bit times default
++ reg_contents |= (0UL << MAC_CONFIG_IFG_BIT);
++
++ // Write MAC config setup to the GMAC
++ mac_reg_write(priv, MAC_CONFIG_REG, reg_contents);
++
++ /* Initialise MAC VLAN register contents
++ */
++ reg_contents = 0;
++ mac_reg_write(priv, MAC_VLAN_TAG_REG, reg_contents);
++
++ // Initialise the hardware's record of our primary MAC address
++ hw_set_mac_address(dev, dev->dev_addr);
++
++ // Initialise multicast and promiscuous modes
++ set_multicast_list(dev);
++
++ // Disable all MMC interrupt sources
++ mac_reg_write(priv, MMC_RX_MASK_REG, ~0UL);
++ mac_reg_write(priv, MMC_TX_MASK_REG, ~0UL);
++
++ // Remember how large the unified descriptor array is to be
++ priv->total_num_descriptors = NUM_TX_DMA_DESCRIPTORS + NUM_RX_DMA_DESCRIPTORS;
++
++ // Initialise the structures managing the TX descriptor list
++ init_tx_desc_list(&priv->tx_gmac_desc_list_info,
++ priv->desc_vaddr,
++ priv->tx_desc_shadow_,
++ NUM_TX_DMA_DESCRIPTORS);
++
++ // Initialise the structures managing the RX descriptor list
++ init_rx_desc_list(&priv->rx_gmac_desc_list_info,
++ priv->desc_vaddr + NUM_TX_DMA_DESCRIPTORS,
++ priv->rx_desc_shadow_,
++ NUM_RX_DMA_DESCRIPTORS,
++ priv->rx_buffer_size_);
++
++ // Reset record of pending Tx packet
++ priv->tx_pending_skb = 0;
++ priv->tx_pending_fragment_count = 0;
++
++#ifndef CONFIG_LEON_OFFLOAD_TX
++ // Write the physical DMA consistent address of the start of the tx descriptor array
++ dma_reg_write(priv, DMA_TX_DESC_ADR_REG, priv->desc_dma_addr);
++#endif // !CONFIG_LEON_OFFLOAD_TX
++
++ // Write the physical DMA consistent address of the start of the rx descriptor array
++ dma_reg_write(priv, DMA_RX_DESC_ADR_REG, priv->desc_dma_addr +
++ (priv->tx_gmac_desc_list_info.num_descriptors * sizeof(gmac_dma_desc_t)));
++
++ // Initialise the GMAC DMA bus mode register
++ dma_reg_write(priv, DMA_BUS_MODE_REG, ((1UL << DMA_BUS_MODE_FB_BIT) | // Force bursts
++ (8UL << DMA_BUS_MODE_PBL_BIT) | // AHB burst size
++ (1UL << DMA_BUS_MODE_DA_BIT))); // Round robin Rx/Tx
++
++ // Prepare receive descriptors
++ refill_rx_ring(dev);
++
++ // Clear any pending interrupt requests
++ dma_reg_write(priv, DMA_STATUS_REG, dma_reg_read(priv, DMA_STATUS_REG));
++
++ /* Initialise flow control register contents
++ */
++ // Enable Rx flow control
++ reg_contents = (1UL << MAC_FLOW_CNTL_RFE_BIT);
++
++#ifndef CONFIG_OXNAS_VERSION_0X800
++ if (priv->mii.using_pause) {
++ // Enable Tx flow control
++ reg_contents |= (1UL << MAC_FLOW_CNTL_TFE_BIT);
++ }
++
++ // Set the duration of the pause frames generated by the transmitter when
++ // the Rx fifo fill threshold is exceeded
++ reg_contents |= ((0x100UL << MAC_FLOW_CNTL_PT_BIT) | // Pause for 256 slots
++ (0x1UL << MAC_FLOW_CNTL_PLT_BIT));
++#endif // !CONFIG_OXNAS_VERSION_0X800
++
++ // Write flow control setup to the GMAC
++ mac_reg_write(priv, MAC_FLOW_CNTL_REG, reg_contents);
++
++ /* Initialise operation mode register contents
++ */
++ // Initialise the GMAC DMA operation mode register. Set Tx/Rx FIFO thresholds
++ // to make best use of our limited SDRAM bandwidth when operating in gigabit
++ reg_contents = ((DMA_OP_MODE_TTC_256 << DMA_OP_MODE_TTC_BIT) | // Tx threshold
++ (1UL << DMA_OP_MODE_FUF_BIT) | // Forward Undersized good Frames
++ (DMA_OP_MODE_RTC_128 << DMA_OP_MODE_RTC_BIT) | // Rx threshold 128 bytes
++ (1UL << DMA_OP_MODE_OSF_BIT)); // Operate on 2nd frame
++
++#ifndef CONFIG_OXNAS_VERSION_0X800
++ // Enable hardware flow control
++ reg_contents |= (1UL << DMA_OP_MODE_EFC_BIT);
++
++ // Set threshold for enabling hardware flow control at (full-4KB) to give
++ // space for upto two in-flight std MTU packets to arrive after pause frame
++ // has been sent.
++ reg_contents |= ((0UL << DMA_OP_MODE_RFA2_BIT) |
++ (3UL << DMA_OP_MODE_RFA_BIT));
++
++ // Set threshold for disabling hardware flow control (-7KB)
++ reg_contents |= ((1UL << DMA_OP_MODE_RFD2_BIT) |
++ (2UL << DMA_OP_MODE_RFD_BIT));
++
++ // Don't flush Rx frames from FIFO just because there's no descriptor available
++ reg_contents |= (1UL << DMA_OP_MODE_DFF_BIT);
++#endif // !CONFIG_OXNAS_VERSION_0X800
++
++ // Write settings to operation mode register
++ dma_reg_write(priv, DMA_OP_MODE_REG, reg_contents);
++
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ // Use store&forward when operating in gigabit mode, as OX800 does not have
++ // sufficient SDRAM bandwidth to support gigabit Tx without it and OX800
++ // does not support Tx checksumming in the GMAC
++ if (priv->mii.using_1000) {
++ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
++ } else {
++ dma_reg_clear_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
++ }
++#else // CONFIG_OXNAS_VERSION_0X800
++ // GMAC requires store&forward in order to compute Tx checksums
++ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_SF_BIT));
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++ // Ensure setup is complete, before enabling TX and RX
++ wmb();
++
++#ifdef CONFIG_LEON_COPRO
++ // Update the CoPro's parameters with the current MTU
++ priv->copro_params_.mtu_ = dev->mtu;
++
++ // Only attempt to write to uncached/unbuffered shared parameter storage if
++ // CoPro is started and thus storage has been allocated
++ if (priv->shared_copro_params_) {
++ // Fill the CoPro parameter block
++ memcpy(priv->shared_copro_params_, &priv->copro_params_, sizeof(copro_params_t));
++ }
++
++ // Make sure the CoPro parameter block updates have made it to memory (which
++ // is uncached/unbuffered, so just compiler issues to overcome)
++ wmb();
++
++ // Tell the CoPro to re-read parameters
++ cmd_queue_result = -1;
++ while (cmd_queue_result) {
++ spin_lock(&priv->cmd_que_lock_);
++ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_UPDATE_PARAMS, 0, copro_update_callback);
++ spin_unlock(&priv->cmd_que_lock_);
++ }
++
++ // Interrupt the CoPro so it sees the new command
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++
++ // Wait until the CoPro acknowledges that the update of parameters is complete
++ down_interruptible(&copro_update_semaphore);
++
++ // Tell the CoPro to begin network offload operations
++ cmd_queue_result = -1;
++ while (cmd_queue_result) {
++ spin_lock(&priv->cmd_que_lock_);
++ cmd_queue_result = cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_START, 0, copro_start_callback);
++ spin_unlock(&priv->cmd_que_lock_);
++ }
++
++ // Interrupt the CoPro so it sees the new command
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++
++ // Wait until the CoPro acknowledges that it has started
++ down_interruptible(&copro_start_semaphore);
++#endif // CONFIG_LEON_COPRO
++
++ // Start NAPI
++ napi_enable(&priv->napi_struct);
++
++ // Start the transmitter and receiver
++#ifndef CONFIG_LEON_OFFLOAD_TX
++ dma_reg_set_mask(priv, DMA_OP_MODE_REG, (1UL << DMA_OP_MODE_ST_BIT));
++#endif // !LEON_OFFLOAD_TX
++ change_rx_enable(priv, 1, 0, 0);
++
++ // Enable interesting GMAC interrupts
++ gmac_int_en_set(priv, ((1UL << DMA_INT_ENABLE_NI_BIT) |
++ (1UL << DMA_INT_ENABLE_AI_BIT) |
++ (1UL << DMA_INT_ENABLE_FBE_BIT) |
++ (1UL << DMA_INT_ENABLE_RI_BIT) |
++ (1UL << DMA_INT_ENABLE_RU_BIT) |
++ (1UL << DMA_INT_ENABLE_OV_BIT) |
++ (1UL << DMA_INT_ENABLE_RW_BIT) |
++ (1UL << DMA_INT_ENABLE_RS_BIT) |
++ (1UL << DMA_INT_ENABLE_TI_BIT) |
++ (1UL << DMA_INT_ENABLE_UN_BIT) |
++ (1UL << DMA_INT_ENABLE_TJ_BIT) |
++ (1UL << DMA_INT_ENABLE_TS_BIT)));
++
++ // (Re)start the link/PHY state monitoring timer
++ start_watchdog_timer(priv);
++
++ // Allow the network stack to call hard_start_xmit()
++ netif_start_queue(dev);
++
++#ifdef DUMP_REGS_ON_GMAC_UP
++ dump_mac_regs(priv->macBase, priv->dmaBase);
++#endif // DUMP_REGS_ON_GMAC_UP
++
++ return status;
++
++gmac_up_err_out:
++ stop(dev);
++
++ return status;
++}
++
++static void set_rx_packet_info(struct net_device *dev)
++{
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ int max_packet_buffer_size = dev->mtu + EXTRA_RX_SKB_SPACE;
++
++ if (max_packet_buffer_size > max_descriptor_length()) {
++#ifndef RX_BUFFER_SIZE
++ priv->rx_buffer_size_ = max_packet_buffer_size;
++#else // !RX_BUFFER_SIZE
++ priv->rx_buffer_size_ = RX_BUFFER_SIZE;
++#endif // ! RX_BUFFER_SIZE
++ priv->rx_buffers_per_page = GMAC_ALLOC_SIZE / (priv->rx_buffer_size_ + NET_IP_ALIGN);
++ } else {
++ priv->rx_buffer_size_ = max_packet_buffer_size;
++ priv->rx_buffers_per_page = 0;
++ }
++}
++
++static int change_mtu(struct net_device *dev, int new_mtu)
++{
++ int status = 0;
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ int original_mtu = dev->mtu;
++
++ // Check that new MTU is within supported range
++ if ((new_mtu < MIN_PACKET_SIZE) || (new_mtu > MAX_JUMBO)) {
++ DBG(1, KERN_WARNING "change_mtu() %s: Invalid MTU %d\n", dev->name, new_mtu);
++ status = -EINVAL;
++ } else {
++ // Put MAC/PHY into quiesent state, causing all current buffers to be
++ // deallocated and the PHY to powerdown
++ gmac_down(dev);
++
++ // Record the new MTU, so bringing the MAC back up will allocate
++ // resources to suit the new MTU
++ dev->mtu = new_mtu;
++
++ // Set length etc. of rx packets
++ set_rx_packet_info(dev);
++
++ // Reset the PHY to get it into a known state and ensure we have TX/RX
++ // clocks to allow the GMAC reset to complete
++ if (phy_reset(priv->netdev)) {
++ DBG(1, KERN_ERR "change_mtu() %s: Failed to reset PHY\n", dev->name);
++ status = -EIO;
++ } else {
++ // Set PHY specfic features
++ initialise_phy(priv);
++
++ // Record whether jumbo frames should be enabled
++ priv->jumbo_ = (dev->mtu > NORMAL_PACKET_SIZE);
++
++ // Force or auto-negotiate PHY mode
++ priv->phy_force_negotiation = 1;
++
++ // Reallocate buffers with new MTU
++ gmac_up(dev);
++ }
++ }
++
++ // If there was a failure
++ if (status) {
++ // Return the MTU to its original value
++ DBG(1, KERN_INFO "change_mtu() Failed, returning MTU to original value\n");
++ dev->mtu = original_mtu;
++ }
++
++ return status;
++}
++
++#ifdef TEST_COPRO
++DECLARE_MUTEX_LOCKED(start_sem);
++DECLARE_MUTEX_LOCKED(heartbeat_sem);
++
++void start_callback(volatile gmac_cmd_que_ent_t* entry)
++{
++ printk("START callback, operand = 0x%08x\n", entry->operand_);
++ up(&start_sem);
++}
++
++void heartbeat_callback(volatile gmac_cmd_que_ent_t* entry)
++{
++ printk("Heartbeat callback, operand = 0x%08x\n", entry->operand_);
++ up(&heartbeat_sem);
++}
++
++static void test_copro(gmac_priv_t* priv)
++{
++ unsigned long irq_flags;
++
++ spin_lock(&priv->cmd_que_lock_);
++ cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_STOP, 0, 0);
++ spin_unlock(&priv->cmd_que_lock_);
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++ mdelay(500);
++
++ spin_lock(&priv->cmd_que_lock_);
++ cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_START, 0, start_callback);
++ spin_unlock(&priv->cmd_que_lock_);
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++ mdelay(500);
++
++ spin_lock(&priv->cmd_que_lock_);
++ cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_HEARTBEAT, 0, heartbeat_callback);
++ spin_unlock(&priv->cmd_que_lock_);
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++ mdelay(500);
++
++ printk("Waiting for start ack...\n");
++ down_interruptible(&start_sem);
++ printk("Start ack received\n");
++
++ printk("Waiting for heartbeat ack...\n");
++ down_interruptible(&heartbeat_sem);
++ printk("Heartbeat ack received\n");
++}
++#endif // TEST_COPRO
++
++#ifdef CONFIG_LEON_COPRO
++#define SEM_INT_FWD 8
++#define SEM_INT_ACK 16
++#define SEM_INT_TX 17
++#define SEM_INT_STOP_ACK 18
++
++#define SEM_INTA_MASK (1UL << SEM_INT_FWD)
++#define SEM_INTB_MASK ((1UL << SEM_INT_ACK) | (1UL << SEM_INT_TX) | (1UL << SEM_INT_STOP_ACK))
++
++static irqreturn_t copro_sema_intr(int irq, void *dev_id)
++{
++ struct net_device *dev = (struct net_device *)dev_id;
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ u32 asserted;
++ u32 fwd_intrs_status = 0;
++ int is_fwd_intr;
++
++ // Read the contents of semaphore A register
++ asserted = (*((volatile unsigned long*)SYS_CTRL_SEMA_STAT) & SEM_INTA_MASK);
++
++ while (asserted) {
++ // Extract any forwarded interrupts info
++ is_fwd_intr = asserted & (1UL << SEM_INT_FWD);
++ if (is_fwd_intr) {
++ fwd_intrs_status = ((volatile gmac_fwd_intrs_t*)descriptors_phys_to_virt(priv->copro_params_.fwd_intrs_mailbox_))->status_;
++ }
++
++ // Clear any interrupts directed at the ARM
++ *((volatile unsigned long*)SYS_CTRL_SEMA_CLR_CTRL) = asserted;
++
++ if (is_fwd_intr) {
++ // Process any forwarded GMAC interrupts
++ copro_fwd_intrs_handler(dev_id, fwd_intrs_status);
++ }
++
++ // Stay in interrupt routine if interrupt has been re-asserted
++ asserted = (*((volatile unsigned long*)SYS_CTRL_SEMA_STAT) & SEM_INTA_MASK);
++ }
++
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t copro_semb_intr(int irq, void *dev_id)
++{
++ struct net_device *dev = (struct net_device *)dev_id;
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ u32 asserted;
++
++ // Read the contents of semaphore B register
++ asserted = (*((volatile unsigned long*)SYS_CTRL_SEMA_STAT) & SEM_INTB_MASK);
++
++ while (asserted) {
++ // Clear any interrupts directed at the ARM
++ *((volatile unsigned long*)SYS_CTRL_SEMA_CLR_CTRL) = asserted;
++
++ // Process any outstanding command acknowledgements
++ if (asserted & (1UL << SEM_INT_ACK)) {
++ while (!cmd_que_dequeue_ack(&priv->cmd_queue_));
++ }
++
++ // Process STOP completion signal
++ if (asserted & (1UL << SEM_INT_STOP_ACK)) {
++ up(&priv->copro_stop_complete_semaphore_);
++ }
++
++#ifdef CONFIG_LEON_OFFLOAD_TX
++ // Process any completed TX offload jobs
++ if (asserted & (1UL << SEM_INT_TX)) {
++ finish_xmit(dev);
++ }
++#endif // CONFIG_LEON_OFFLOAD_TX
++
++ // Stay in interrupt routine if interrupt has been re-asserted
++ asserted = (*((volatile unsigned long*)SYS_CTRL_SEMA_STAT) & SEM_INTB_MASK);
++ }
++
++ return IRQ_HANDLED;
++}
++#endif // CONFIG_LEON_COPRO
++
++static int open(struct net_device *dev)
++{
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++ int status;
++
++ // Ensure the MAC block is properly reset
++ writel(1UL << SYS_CTRL_RSTEN_MAC_BIT, SYS_CTRL_RSTEN_SET_CTRL);
++ writel(1UL << SYS_CTRL_RSTEN_MAC_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
++
++ // Enable the clock to the MAC block
++ writel(1UL << SYS_CTRL_CKEN_MAC_BIT, SYS_CTRL_CKEN_SET_CTRL);
++
++ // Ensure reset and clock operations are complete
++ wmb();
++
++ // Reset the PHY to get it into a known state and ensure we have TX/RX clocks
++ // to allow the GMAC reset to complete
++ if (phy_reset(priv->netdev)) {
++ DBG(1, KERN_ERR "open() %s: Failed to reset PHY\n", dev->name);
++ status = -EIO;
++ goto open_err_out;
++ }
++
++ // Set PHY specfic features
++ initialise_phy(priv);
++
++ // Check that the MAC address is valid. If it's not, refuse to bring the
++ // device up
++ if (!is_valid_ether_addr(dev->dev_addr)) {
++ DBG(1, KERN_ERR "open() %s: MAC address invalid\n", dev->name);
++ status = -EINVAL;
++ goto open_err_out;
++ }
++
++#ifdef CONFIG_LEON_COPRO
++ // Register ISRs for the semaphore register interrupt sources, which will
++ // originate from the CoPro
++ if (request_irq(priv->copro_a_irq_, &copro_sema_intr, 0, "SEMA", dev)) {
++ panic("open: Failed to allocate semaphore A %u\n", priv->copro_a_irq_);
++ status = -ENODEV;
++ goto open_err_out;
++ }
++ priv->copro_a_irq_alloced_ = 1;
++
++ if (request_irq(priv->copro_b_irq_, &copro_semb_intr, 0, "SEMB", dev)) {
++ panic("open: Failed to allocate semaphore B %u\n", priv->copro_b_irq_);
++ status = -ENODEV;
++ goto open_err_out;
++ }
++ priv->copro_b_irq_alloced_ = 1;
++#else // CONFIG_LEON_COPRO
++ // Allocate the IRQ
++ if (request_irq(dev->irq, &int_handler, 0, dev->name, dev)) {
++ DBG(1, KERN_ERR "open() %s: Failed to allocate irq %d\n", dev->name, dev->irq);
++ status = -ENODEV;
++ goto open_err_out;
++ }
++ priv->have_irq = 1;
++#endif // CONFIG_LEON_COPRO
++
++ // Need a consistent DMA mapping covering all the memory occupied by DMA
++ // unified descriptor array, as both CPU and DMA engine will be reading and
++ // writing descriptor fields.
++ priv->desc_vaddr = (gmac_dma_desc_t*)GMAC_DESC_ALLOC_START;
++ priv->desc_dma_addr = GMAC_DESC_ALLOC_START_PA;
++
++ if (!priv->desc_vaddr) {
++ DBG(1, KERN_ERR "open() %s: Failed to allocate consistent memory for DMA descriptors\n", dev->name);
++ status = -ENOMEM;
++ goto open_err_out;
++ }
++
++ // Allocate memory to hold shadow of GMAC descriptors
++ if (!(priv->tx_desc_shadow_ = kmalloc(NUM_TX_DMA_DESCRIPTORS * sizeof(gmac_dma_desc_t), GFP_KERNEL))) {
++ DBG(1, KERN_ERR "open() %s: Failed to allocate memory for Tx descriptor shadows\n", dev->name);
++ status = -ENOMEM;
++ goto open_err_out;
++ }
++ if (!(priv->rx_desc_shadow_ = kmalloc(NUM_RX_DMA_DESCRIPTORS * sizeof(gmac_dma_desc_t), GFP_KERNEL))) {
++ DBG(1, KERN_ERR "open() %s: Failed to allocate memory for Rx descriptor shadows\n", dev->name);
++ status = -ENOMEM;
++ goto open_err_out;
++ }
++
++ // Record whether jumbo frames should be enabled
++ priv->jumbo_ = (dev->mtu > NORMAL_PACKET_SIZE);
++
++ set_rx_packet_info(dev);
++
++#ifdef CONFIG_LEON_COPRO
++ // Allocate SRAM for the command queue entries
++ priv->copro_params_.cmd_que_head_ = DESCRIPTORS_BASE_PA + DESCRIPTORS_SIZE;
++
++ priv->copro_params_.cmd_que_tail_ =
++ (u32)((gmac_cmd_que_ent_t*)(priv->copro_params_.cmd_que_head_) + priv->copro_cmd_que_num_entries_);
++ priv->copro_params_.fwd_intrs_mailbox_ = priv->copro_params_.cmd_que_tail_;
++ priv->copro_params_.tx_que_head_ = priv->copro_params_.fwd_intrs_mailbox_ + sizeof(gmac_fwd_intrs_t);
++ priv->copro_params_.tx_que_tail_ =
++ (u32)((gmac_tx_que_ent_t*)(priv->copro_params_.tx_que_head_) + priv->copro_tx_que_num_entries_);
++ priv->copro_params_.free_start_ = priv->copro_params_.tx_que_tail_;
++
++ // Set RX interrupt mitigation behaviour
++ priv->copro_params_.rx_mitigation_ = COPRO_RX_MITIGATION;
++ priv->copro_params_.rx_mitigation_frames_ = COPRO_RX_MITIGATION_FRAMES;
++ priv->copro_params_.rx_mitigation_usec_ = COPRO_RX_MITIGATION_USECS;
++
++ // Initialise command queue metadata
++ cmd_que_init(
++ &priv->cmd_queue_,
++ (gmac_cmd_que_ent_t*)descriptors_phys_to_virt(priv->copro_params_.cmd_que_head_),
++ priv->copro_cmd_que_num_entries_);
++
++ // Initialise tx offload queue metadata
++ tx_que_init(
++ &priv->tx_queue_,
++ (gmac_tx_que_ent_t*)descriptors_phys_to_virt(priv->copro_params_.tx_que_head_),
++ priv->copro_tx_que_num_entries_);
++
++ // Allocate DMA coherent space for the parameter block shared with the CoPro
++ priv->shared_copro_params_ = dma_alloc_coherent(0, sizeof(copro_params_t), &priv->shared_copro_params_pa_, GFP_KERNEL);
++ if (!priv->shared_copro_params_) {
++ DBG(1, KERN_ERR "open() %s: Failed to allocate DMA coherent space for parameters\n");
++ status = -ENOMEM;
++ goto open_err_out;
++ }
++
++ // Update the CoPro's parameters with the current MTU
++ priv->copro_params_.mtu_ = dev->mtu;
++
++ // Fill the shared CoPro parameter block from the ARM's local copy
++ memcpy(priv->shared_copro_params_, &priv->copro_params_, sizeof(copro_params_t));
++
++ // Load CoPro program and start it running
++ init_copro(leon_srec, priv->shared_copro_params_pa_);
++
++ // Enable selected semaphore register bits to cause ARM interrupts
++ *((volatile unsigned long*)SYS_CTRL_SEMA_MASKA_CTRL) = SEM_INTA_MASK;
++ *((volatile unsigned long*)SYS_CTRL_SEMA_MASKB_CTRL) = SEM_INTB_MASK;
++
++#ifdef TEST_COPRO
++ // Send test commands to the CoPro
++ test_copro(priv);
++#endif // TEST_COPRO
++#endif // CONFIG_LEON_COPRO
++
++ // Do startup operations that are in common with gmac_down()/_up() processing
++ priv->mii_init_media = 1;
++ priv->phy_force_negotiation = 1;
++ status = gmac_up(dev);
++ if (status) {
++ goto open_err_out;
++ }
++
++ return 0;
++
++open_err_out:
++ stop(dev);
++
++ return status;
++}
++
++#if defined(CONFIG_LEON_COPRO) && defined(CONFIG_LEON_OFFLOAD_TX)
++static int hard_start_xmit(
++ struct sk_buff *skb,
++ struct net_device *dev)
++{
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ volatile gmac_tx_que_ent_t *job;
++ unsigned long irq_flags;
++
++ if (skb_shinfo(skb)->frag_list) {
++ panic("Frag list - can't handle this!\n");
++ }
++
++ // Protection against concurrent operations in ISR and hard_start_xmit()
++ if (!spin_trylock_irqsave(&priv->tx_spinlock_, irq_flags)) {
++ return NETDEV_TX_LOCKED;
++ }
++
++ // NETIF_F_LLTX apparently introduces a potential for hard_start_xmit() to
++ // be called when the queue has been stopped (although I think only in SMP)
++ // so do a check here to make sure we should proceed
++ if (netif_queue_stopped(dev)) {
++ spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
++ return NETDEV_TX_BUSY;
++ }
++
++ job = tx_que_get_idle_job(dev);
++ if (!job) {
++ // Tx offload queue is full, so add skb to pending skb list
++ list_add_tail((struct list_head*)&skb->cb, &priv->copro_tx_skb_list_);
++
++ // Keep track of how many entries are in the pending SKB list
++ ++priv->copro_tx_skb_list_count_;
++
++ // Have we queued the max allowed number of SKBs?
++ if (priv->copro_tx_skb_list_count_ >= COPRO_MAX_QUEUED_TX_SKBS) {
++ // Stop further calls to hard_start_xmit() until some descriptors
++ // are freed up by already queued TX packets being completed
++ netif_stop_queue(dev);
++ }
++ } else {
++ if (priv->copro_tx_skb_list_count_) {
++ // Have queued pending SKBs, so add new SKB to tail of pending list
++ list_add_tail((struct list_head*)&skb->cb, &priv->copro_tx_skb_list_);
++
++ // Keep track of how many entries are in the pending SKB list
++ ++priv->copro_tx_skb_list_count_;
++
++ // Process pending SKBs, oldest first
++ copro_process_pending_tx_skbs(dev, job);
++ } else {
++ // Fill the Tx offload job with the network packet's details
++ copro_fill_tx_job(job, skb);
++
++ // Enqueue the new Tx offload job with the CoPro
++ tx_que_new_job(dev, job);
++ }
++
++ // Record start of transmission, so timeouts will work once they're
++ // implemented
++ dev->trans_start = jiffies;
++
++ // Interrupt the CoPro to cause it to examine the Tx offload queue
++ wmb();
++ writel(1UL << COPRO_SEM_INT_TX, SYS_CTRL_SEMA_SET_CTRL);
++
++ // If the network stack's Tx queue was stopped and we now have resources
++ // to process more Tx offload jobs
++ if (netif_queue_stopped(dev) &&
++ !tx_que_is_full(&priv->tx_queue_) &&
++ !priv->copro_tx_skb_list_count_) {
++ // Restart the network stack's TX queue
++ netif_wake_queue(dev);
++ }
++ }
++
++ spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
++
++ return NETDEV_TX_OK;
++}
++#else
++static inline void unmap_fragments(
++ tx_frag_info_t *frags,
++ int count)
++{
++ while (count--) {
++ dma_unmap_single(0, frags->phys_adr, frags->length, DMA_TO_DEVICE);
++ ++frags;
++ }
++}
++
++static int hard_start_xmit(
++ struct sk_buff *skb,
++ struct net_device *dev)
++{
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ unsigned long irq_flags;
++ struct skb_shared_info *shinfo = skb_shinfo(skb);
++ int fragment_count = shinfo->nr_frags + 1;
++ tx_frag_info_t fragments[fragment_count];
++ int frag_index;
++
++ // Get consistent DMA mappings for the SDRAM to be DMAed from by the GMAC,
++ // causing a flush from the CPU's cache to the memory.
++
++ // Do the DMA mappings before acquiring the tx lock, even though it complicates
++ // the later code, as this can be a long operation involving cache flushing
++
++ // Map the main buffer
++ fragments[0].length = skb_headlen(skb);
++ fragments[0].phys_adr = dma_map_single(0, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
++ BUG_ON(dma_mapping_error(fragments[0].phys_adr));
++
++ // Map any SG fragments
++ for (frag_index = 0; frag_index < shinfo->nr_frags; ++frag_index) {
++ skb_frag_t *frag = &shinfo->frags[frag_index];
++
++ fragments[frag_index + 1].length = frag->size;
++ fragments[frag_index + 1].phys_adr = dma_map_page(0, frag->page, frag->page_offset, frag->size, DMA_TO_DEVICE);
++ BUG_ON(dma_mapping_error(fragments[frag_index + 1].phys_adr));
++ }
++
++ // Protection against concurrent operations in ISR and hard_start_xmit()
++ if (unlikely(!spin_trylock_irqsave(&priv->tx_spinlock_, irq_flags))) {
++ unmap_fragments(fragments, fragment_count);
++ return NETDEV_TX_LOCKED;
++ }
++
++ // NETIF_F_LLTX apparently introduces a potential for hard_start_xmit() to
++ // be called when the queue has been stopped (although I think only in SMP)
++ // so do a check here to make sure we should proceed
++ if (unlikely(netif_queue_stopped(dev))) {
++ unmap_fragments(fragments, fragment_count);
++ spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
++ return NETDEV_TX_BUSY;
++ }
++
++ // Construct the GMAC DMA descriptor
++ if (unlikely(set_tx_descriptor(priv,
++ skb,
++ fragments,
++ fragment_count,
++ skb->ip_summed == CHECKSUM_PARTIAL) < 0)) {
++ // Shouldn't see a full ring without the queue having already been
++ // stopped, and the queue should already have been stopped if we have
++ // already queued a single pending packet
++ if (priv->tx_pending_skb) {
++ printk(KERN_WARNING "hard_start_xmit() Ring full and pending packet already queued\n");
++ unmap_fragments(fragments, fragment_count);
++ spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
++ return NETDEV_TX_BUSY;
++ }
++
++ // Should keep a record of the skb that we haven't been able to queue
++ // for transmission and queue it as soon as a descriptor becomes free
++ priv->tx_pending_skb = skb;
++ priv->tx_pending_fragment_count = fragment_count;
++
++ // Copy the fragment info to the allocated storage
++ memcpy(priv->tx_pending_fragments, fragments, sizeof(tx_frag_info_t) * fragment_count);
++
++ // Stop further calls to hard_start_xmit() until some descriptors are
++ // freed up by already queued TX packets being completed
++ netif_stop_queue(dev);
++ } else {
++ // Record start of transmission, so timeouts will work once they're
++ // implemented
++ dev->trans_start = jiffies;
++
++ // Poke the transmitter to look for available TX descriptors, as we have
++ // just added one, in case it had previously found there were no more
++ // pending transmission
++ dma_reg_write(priv, DMA_TX_POLL_REG, 0);
++ }
++
++ spin_unlock_irqrestore(&priv->tx_spinlock_, irq_flags);
++
++ return NETDEV_TX_OK;
++}
++#endif // CONFIG_LEON_COPRO && CONFIG_LEON_OFFLOAD_TX
++
++static struct net_device_stats *get_stats(struct net_device *dev)
++{
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++ return &priv->stats;
++}
++
++#ifdef CONFIG_NET_POLL_CONTROLLER
++/**
++ * Polling 'interrupt' - used by things like netconsole to send skbs without
++ * having to re-enable interrupts. It's not called while the interrupt routine
++ * is executing.
++ */
++static void netpoll(struct net_device *netdev)
++{
++ disable_irq(netdev->irq);
++ int_handler(netdev->irq, netdev, NULL);
++ enable_irq(netdev->irq);
++}
++#endif // CONFIG_NET_POLL_CONTROLLER
++
++static int probe(
++ struct net_device *netdev,
++ u32 vaddr,
++ u32 irq,
++ int copro_a_irq,
++ int copro_b_irq)
++{
++ int err = 0;
++ u32 version;
++ int i;
++ unsigned synopsis_version;
++ unsigned vendor_version;
++ gmac_priv_t* priv = netdev_priv(netdev);
++ u32 reg_contents;
++
++ // Ensure the MAC block is properly reset
++ writel(1UL << SYS_CTRL_RSTEN_MAC_BIT, SYS_CTRL_RSTEN_SET_CTRL);
++ writel(1UL << SYS_CTRL_RSTEN_MAC_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
++
++ // Enable the clock to the MAC block
++ writel(1UL << SYS_CTRL_CKEN_MAC_BIT, SYS_CTRL_CKEN_SET_CTRL);
++
++ // Ensure reset and clock operations are complete
++ wmb();
++
++ // Ensure all of the device private data are zero, so we can clean up in
++ // the event of a later failure to initialise all fields
++ priv = (gmac_priv_t*)netdev_priv(netdev);
++ memset(priv, 0, sizeof(gmac_priv_t));
++
++ // No debug messages allowed
++ priv->msg_level = 0UL;
++
++ // Initialise the ISR/hard_start_xmit() lock
++ spin_lock_init(&priv->tx_spinlock_);
++
++ // Initialise the PHY access lock
++ spin_lock_init(&priv->phy_lock);
++
++ // Set hardware device base addresses
++ priv->macBase = vaddr + MAC_BASE_OFFSET;
++ priv->dmaBase = vaddr + DMA_BASE_OFFSET;
++
++ // Initialise IRQ ownership to not owned
++ priv->have_irq = 0;
++
++ // Lock protecting access to CoPro command queue functions or direct access
++ // to the GMAC interrupt enable register if CoPro is not in use
++ spin_lock_init(&priv->cmd_que_lock_);
++
++#ifdef CONFIG_LEON_COPRO
++ sema_init(&copro_stop_semaphore, 0);
++ sema_init(&copro_start_semaphore, 0);
++ sema_init(&copro_int_clr_semaphore, 0);
++ sema_init(&copro_update_semaphore, 0);
++ sema_init(&copro_rx_enable_semaphore, 0);
++ priv->copro_a_irq_alloced_ = 0;
++ priv->copro_b_irq_alloced_ = 0;
++ sema_init(&priv->copro_stop_complete_semaphore_, 0);
++ INIT_LIST_HEAD(&priv->copro_tx_skb_list_);
++ priv->copro_tx_skb_list_count_ = 0;
++#endif // CONFIG_LEON_COPRO
++
++ init_timer(&priv->watchdog_timer);
++ priv->watchdog_timer.function = &watchdog_timer_action;
++ priv->watchdog_timer.data = (unsigned long)priv;
++
++ // Set pointer to device in private data
++ priv->netdev = netdev;
++
++ /** Do something here to detect the present or otherwise of the MAC
++ * Read the version register as a first test */
++ version = mac_reg_read(priv, MAC_VERSION_REG);
++ synopsis_version = version & 0xff;
++ vendor_version = (version >> 8) & 0xff;
++
++ /** Assume device is at the adr and irq specified until have probing working */
++ netdev->base_addr = vaddr;
++ netdev->irq = irq;
++#ifdef CONFIG_LEON_COPRO
++ priv->copro_a_irq_ = copro_a_irq;
++ priv->copro_b_irq_ = copro_b_irq;
++#endif // CONFIG_LEON_COPRO
++
++#ifdef CONFIG_LEON_COPRO
++ // Allocate the CoPro A IRQ
++ err = request_irq(priv->copro_a_irq_, &copro_sema_intr, 0, "SEMA", netdev);
++ if (err) {
++ DBG(1, KERN_ERR "probe() %s: Failed to allocate CoPro irq A (%d)\n", netdev->name, priv->copro_a_irq_);
++ goto probe_err_out;
++ }
++ // Release the CoPro A IRQ again, as open()/stop() should manage IRQ ownership
++ free_irq(priv->copro_a_irq_, netdev);
++
++ // Allocate the CoPro B IRQ
++ err = request_irq(priv->copro_b_irq_, &copro_semb_intr, 0, "SEMB", netdev);
++ if (err) {
++ DBG(1, KERN_ERR "probe() %s: Failed to allocate CoPro irq B (%d)\n", netdev->name, priv->copro_b_irq_);
++ goto probe_err_out;
++ }
++ // Release the CoPro B IRQ again, as open()/stop() should manage IRQ ownership
++ free_irq(priv->copro_b_irq_, netdev);
++#else // CONFIG_LEON_COPRO
++ // Allocate the IRQ
++ err = request_irq(netdev->irq, &int_handler, 0, netdev->name, netdev);
++ if (err) {
++ DBG(1, KERN_ERR "probe() %s: Failed to allocate irq %d\n", netdev->name, netdev->irq);
++ goto probe_err_out;
++ }
++
++ // Release the IRQ again, as open()/stop() should manage IRQ ownership
++ free_irq(netdev->irq, netdev);
++#endif // CONFIG_LEON_COPRO
++
++ // Initialise the ethernet device with std. contents
++ ether_setup(netdev);
++
++ // Tell the kernel of our MAC address
++ for (i = 0; i < netdev->addr_len; i++) {
++ netdev->dev_addr[i] = (unsigned char)mac_adr[i];
++ }
++
++ // Setup operations pointers
++ netdev->open = &open;
++ netdev->hard_start_xmit = &hard_start_xmit;
++ netdev->stop = &stop;
++ netdev->get_stats = &get_stats;
++ netdev->change_mtu = &change_mtu;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++ netdev->poll_controller = &netpoll;
++#endif // CONFIG_NET_POLL_CONTROLLER
++ netdev->set_mac_address = &set_mac_address;
++ netdev->set_multicast_list = &set_multicast_list;
++
++ // Initialise NAPI support
++ netif_napi_add(netdev, &priv->napi_struct, &poll, NAPI_POLL_WEIGHT);
++
++ set_ethtool_ops(netdev);
++
++ if (debug) {
++ netdev->flags |= IFF_DEBUG;
++ }
++
++#if defined(CONFIG_LEON_COPRO) && defined(CONFIG_LEON_OFFLOAD_TSO)
++ // Do TX H/W checksum and SG list processing
++ netdev->features |= NETIF_F_HW_CSUM;
++ netdev->features |= NETIF_F_SG;
++
++ // Do hardware TCP/IP Segmentation Offload
++ netdev->features |= NETIF_F_TSO;
++#elif !defined(CONFIG_LEON_COPRO) && !defined(CONFIG_OXNAS_VERSION_0X800)
++ // Do TX H/W checksum and SG list processing
++ netdev->features |= NETIF_F_HW_CSUM;
++ netdev->features |= NETIF_F_SG;
++#endif // USE_TX_CSUM
++
++ // We take care of our own TX locking
++ netdev->features |= NETIF_F_LLTX;
++
++ // Initialise PHY support
++ priv->mii.phy_id_mask = 0x1f;
++ priv->mii.reg_num_mask = 0x1f;
++ priv->mii.force_media = 0;
++ priv->mii.full_duplex = 1;
++ priv->mii.using_100 = 0;
++ priv->mii.using_1000 = 1;
++ priv->mii.using_pause = 1;
++ priv->mii.dev = netdev;
++ priv->mii.mdio_read = phy_read;
++ priv->mii.mdio_write = phy_write;
++
++ priv->gmii_csr_clk_range = 5; // Slowest for now
++
++ // Use simple mux for 25/125 Mhz clock switching and
++ // enable GMII_GTXCLK to follow GMII_REFCLK - required for gigabit PHY
++ reg_contents = readl(SYS_CTRL_GMAC_CTRL);
++ reg_contents |= ((1UL << SYS_CTRL_GMAC_SIMPLE_MAX) |
++ (1UL << SYS_CTRL_GMAC_CKEN_GTX));
++ writel(reg_contents, SYS_CTRL_GMAC_CTRL);
++
++ // Remember whether auto-negotiation is allowed
++#ifdef ALLOW_AUTONEG
++ priv->ethtool_cmd.autoneg = 1;
++ priv->ethtool_pauseparam.autoneg = 1;
++#else // ALLOW_AUTONEG
++ priv->ethtool_cmd.autoneg = 0;
++ priv->ethtool_pauseparam.autoneg = 0;
++#endif // ALLOW_AUTONEG
++
++ // Set up PHY mode for when auto-negotiation is not allowed
++ priv->ethtool_cmd.speed = SPEED_1000;
++ priv->ethtool_cmd.duplex = DUPLEX_FULL;
++ priv->ethtool_cmd.port = PORT_MII;
++ priv->ethtool_cmd.transceiver = XCVR_INTERNAL;
++
++#ifndef CONFIG_OXNAS_VERSION_0X800
++ // We can support both reception and generation of pause frames
++ priv->ethtool_pauseparam.rx_pause = 1;
++ priv->ethtool_pauseparam.tx_pause = 1;
++#endif // !CONFIG_OXNAS_VERSION_0X800
++
++ // Initialise the set of features we would like to advertise as being
++ // available for negotiation
++ priv->ethtool_cmd.advertising = (ADVERTISED_10baseT_Half |
++ ADVERTISED_10baseT_Full |
++ ADVERTISED_100baseT_Half |
++ ADVERTISED_100baseT_Full |
++#if !defined(CONFIG_OXNAS_VERSION_0X800) || defined(ALLOW_OX800_1000M)
++ ADVERTISED_1000baseT_Half |
++ ADVERTISED_1000baseT_Full |
++ ADVERTISED_Pause |
++ ADVERTISED_Asym_Pause |
++#endif
++ ADVERTISED_Autoneg |
++ ADVERTISED_MII);
++
++ // Attempt to locate the PHY
++ phy_detect(netdev);
++ priv->ethtool_cmd.phy_address = priv->mii.phy_id;
++
++ // Did we find a PHY?
++ if (priv->phy_type == PHY_TYPE_NONE) {
++ printk(KERN_WARNING "%s: No PHY found\n", netdev->name);
++ err = ENXIO;
++ goto probe_err_out;
++ }
++
++ // Setup the PHY
++ initialise_phy(priv);
++
++ // Find out what modes the PHY supports
++ priv->ethtool_cmd.supported = get_phy_capabilies(priv);
++#if defined(CONFIG_OXNAS_VERSION_0X800) && !defined(ALLOW_OX800_1000M)
++ // OX800 has broken 1000M support in the MAC
++ priv->ethtool_cmd.supported &= ~(SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half);
++#endif
++
++ // Register the device with the network intrastructure
++ err = register_netdev(netdev);
++ if (err) {
++ DBG(1, KERN_ERR "probe() %s: Failed to register device\n", netdev->name);
++ goto probe_err_out;
++ }
++
++ // Record details about the hardware we found
++ printk(KERN_NOTICE "%s: GMAC ver = %u, vendor ver = %u at 0x%lx, IRQ %d\n", netdev->name, synopsis_version, vendor_version, netdev->base_addr, netdev->irq);
++#ifndef ARMULATING
++ printk(KERN_NOTICE "%s: Found PHY at address %u, type 0x%08x -> %s\n", priv->netdev->name, priv->phy_addr, priv->phy_type, (priv->ethtool_cmd.supported & SUPPORTED_1000baseT_Full) ? "10/100/1000" : "10/100");
++#endif // !ARMULATING
++ printk(KERN_NOTICE "%s: Ethernet addr: ", priv->netdev->name);
++ for (i = 0; i < 5; i++) {
++ printk("%02x:", netdev->dev_addr[i]);
++ }
++ printk("%02x\n", netdev->dev_addr[5]);
++
++#ifdef CONFIG_LEON_COPRO
++ // Define sizes of queues for communicating with the CoPro
++ priv->copro_cmd_que_num_entries_ = COPRO_CMD_QUEUE_NUM_ENTRIES;
++ priv->copro_tx_que_num_entries_ = COPRO_TX_QUEUE_NUM_ENTRIES;
++#endif // CONFIG_LEON_COPRO
++
++ // Initialise sysfs for link state reporting
++ err = gmac_link_state_init_sysfs(priv);
++ if (err) {
++ DBG(1, KERN_ERR "probe() %s: Failed to initialise sysfs support\n", netdev->name);
++ goto probe_err_out;
++ }
++
++ // Initialise the work queue entry to be used to issue hotplug events to userspace
++ INIT_WORK(&priv->link_state_change_work, work_handler);
++
++ return 0;
++
++probe_err_out:
++#ifdef CONFIG_LEON_COPRO
++ shutdown_copro();
++
++ if (priv->shared_copro_params_) {
++ // Free the DMA coherent parameter space
++ dma_free_coherent(0, sizeof(copro_params_t), priv->shared_copro_params_, priv->shared_copro_params_pa_);
++ priv->shared_copro_params_ = 0;
++ }
++#endif // CONFIG_LEON_COPRO
++
++ // Disable the clock to the MAC block
++ writel(1UL << SYS_CTRL_CKEN_MAC_BIT, SYS_CTRL_CKEN_CLR_CTRL);
++
++ return err;
++}
++
++static int gmac_found_count = 0;
++static struct net_device* gmac_netdev[MAX_GMAC_UNITS];
++
++/**
++ * External entry point to the driver, called from Space.c to detect a card
++ */
++struct net_device* __init synopsys_gmac_probe(int unit)
++{
++ int err = 0;
++ struct net_device *netdev = alloc_etherdev(sizeof(gmac_priv_t));
++
++ printk(KERN_NOTICE "Probing for Synopsis GMAC, unit %d\n", unit);
++
++ // Will allocate private data later, as may want descriptors etc in special memory
++ if (!netdev) {
++ printk(KERN_WARNING "synopsys_gmac_probe() failed to alloc device\n");
++ err = -ENODEV;
++ } else {
++ if (unit >= 0) {
++ sprintf(netdev->name, "eth%d", unit);
++
++ netdev_boot_setup_check(netdev);
++
++ if (gmac_found_count >= MAX_GMAC_UNITS) {
++ err = -ENODEV;
++ } else {
++ err = probe(netdev, MAC_BASE, MAC_INTERRUPT, SEM_A_INTERRUPT, SEM_B_INTERRUPT);
++ if (err) {
++ printk(KERN_WARNING "synopsys_gmac_probe() Probing failed for %s\n", netdev->name);
++ } else {
++ ++gmac_found_count;
++ }
++ }
++ }
++
++ if (err) {
++ netdev->reg_state = NETREG_UNREGISTERED;
++ free_netdev(netdev);
++ } else {
++ gmac_netdev[unit] = netdev;
++ }
++ }
++
++ return ERR_PTR(err);
++}
++
++static int __init gmac_module_init(void)
++{
++ return (int)synopsys_gmac_probe(0);
++}
++module_init(gmac_module_init);
++
++static void __exit gmac_module_cleanup(void)
++{
++ int i;
++ for (i=0; i < gmac_found_count; i++) {
++ stop(gmac_netdev[i]);
++ gmac_netdev[i]->reg_state = NETREG_UNREGISTERED;
++ free_netdev(gmac_netdev[i]);
++ }
++}
++module_exit(gmac_module_cleanup);
++
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac.h
+--- linux-2.6.24/arch/arm/mach-oxnas/gmac.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac.h 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,194 @@
++/*
++ * linux/arch/arm/mach-oxnas/gmac.h
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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
++ */
++#if !defined(__GMAC_H__)
++#define __GMAC_H__
++
++#include <asm/semaphore.h>
++#include <asm/types.h>
++#include <linux/mii.h>
++#include <linux/netdevice.h>
++#include <linux/spinlock.h>
++#include <linux/workqueue.h>
++#include <linux/list.h>
++#include <linux/ethtool.h>
++#include <linux/kobject.h>
++#include <asm/arch/desc_alloc.h>
++#include <asm/arch/dma.h>
++#ifdef CONFIG_LEON_COPRO
++#include <asm/arch/leon.h>
++#include "gmac_offload.h"
++#endif // CONFIG_LEON_COPRO
++
++#ifdef GMAC_DEBUG
++#define DBG(n, args...)\
++ do {\
++ if ((n) <= priv->msg_level)\
++ printk(args);\
++ } while (0)
++#else
++#define DBG(n, args...) do { } while(0)
++#endif
++
++#define MS_TO_JIFFIES(x) (((x) < (1000/(HZ))) ? 1 : (x) * (HZ) / 1000)
++
++#define USE_RX_CSUM
++//#define ARMULATING
++
++typedef struct gmac_desc_list_info {
++ volatile gmac_dma_desc_t *base_ptr;
++ gmac_dma_desc_t *shadow_ptr;
++ int num_descriptors;
++ int empty_count;
++ int full_count;
++ int r_index;
++ int w_index;
++} gmac_desc_list_info_t;
++
++#ifdef CONFIG_LEON_COPRO
++typedef struct copro_params {
++ u32 cmd_que_head_;
++ u32 cmd_que_tail_;
++ u32 fwd_intrs_mailbox_;
++ u32 tx_que_head_;
++ u32 tx_que_tail_;
++ u32 free_start_;
++ u32 mtu_;
++ u32 rx_mitigation_;
++ u32 rx_mitigation_frames_;
++ u32 rx_mitigation_usec_;
++} __attribute ((aligned(4),packed)) copro_params_t;
++#endif // CONFIG_LEON_COPRO
++
++typedef struct tx_frag_info {
++ dma_addr_t phys_adr;
++ u16 length;
++} tx_frag_info_t;
++
++// Private data structure for the GMAC driver
++typedef struct gmac_priv {
++ /** Base address of GMAC MAC registers */
++ u32 macBase;
++ /** Base address of GMAC DMA registers */
++ u32 dmaBase;
++
++ struct net_device* netdev;
++
++ struct net_device_stats stats;
++
++ u32 msg_level;
++
++ /** Whether we own an IRQ */
++ int have_irq;
++
++ /** Pointer to outstanding tx packet that has not yet been queued due to
++ * lack of descriptors */
++ struct sk_buff *tx_pending_skb;
++ tx_frag_info_t tx_pending_fragments[18];
++ int tx_pending_fragment_count;
++
++ /** DMA consistent physical address of outstanding tx packet */
++ dma_addr_t tx_pending_dma_addr;
++ unsigned long tx_pending_length;
++
++ /** To synchronise ISR and thread TX activities' access to private data */
++ spinlock_t tx_spinlock_;
++
++ /** To synchronise access to the PHY */
++ spinlock_t phy_lock;
++
++ /** The timer for NAPI polling when out of memory when trying to fill RX
++ * descriptor ring */
++
++ /** PHY related info */
++ struct mii_if_info mii;
++ struct ethtool_cmd ethtool_cmd;
++ struct ethtool_pauseparam ethtool_pauseparam;
++ u32 phy_addr;
++ u32 phy_type;
++ int gmii_csr_clk_range;
++
++ /** Periodic timer to check link status etc */
++ struct timer_list watchdog_timer;
++ volatile int watchdog_timer_shutdown;
++
++ /** The number of descriptors in the gmac_dma_desc_t array holding both the TX and
++ * RX descriptors. The TX descriptors reside at the start of the array */
++ unsigned total_num_descriptors;
++ /** The CPU accessible virtual address of the start of the descriptor array */
++ gmac_dma_desc_t* desc_vaddr;
++ /** The hardware accessible physical address of the start of the descriptor array */
++ dma_addr_t desc_dma_addr;
++
++ /** Descriptor list management */
++ gmac_desc_list_info_t tx_gmac_desc_list_info;
++ gmac_desc_list_info_t rx_gmac_desc_list_info;
++
++ /** Record of disabling RX overflow interrupts */
++ unsigned rx_overflow_ints_disabled;
++
++ /** The result of the last H/W DMA generated checksum operation */
++ u16 tx_csum_result_;
++
++ /** Whether we deal in jumbo frames */
++ int jumbo_;
++
++ volatile int mii_init_media;
++ volatile int phy_force_negotiation;
++
++#ifdef CONFIG_LEON_COPRO
++ /** DMA coherent memory for CoPro's parameter storage */
++ copro_params_t *shared_copro_params_;
++ dma_addr_t shared_copro_params_pa_;
++
++ /** ARM's local CoPro parameter storage */
++ copro_params_t copro_params_;
++
++ /** Queue for commands/acks to/from CoPro */
++ int copro_a_irq_;
++ int copro_a_irq_alloced_;
++ int copro_b_irq_;
++ int copro_b_irq_alloced_;
++ cmd_que_t cmd_queue_;
++ tx_que_t tx_queue_;
++ int copro_cmd_que_num_entries_;
++ int copro_tx_que_num_entries_;
++ struct semaphore copro_stop_complete_semaphore_;
++ struct list_head copro_tx_skb_list_;
++ int copro_tx_skb_list_count_;
++#endif // CONFIG_LEON_COPRO
++
++ spinlock_t cmd_que_lock_;
++ u32 rx_buffer_size_;
++ int rx_buffers_per_page;
++
++ gmac_dma_desc_t *tx_desc_shadow_;
++ gmac_dma_desc_t *rx_desc_shadow_;
++
++ struct napi_struct napi_struct;
++
++ /** sysfs dir tree root for recovery button driver */
++ struct kset link_state_kset;
++ struct kobject link_state_kobject;
++ struct work_struct link_state_change_work;
++ int link_state;
++} gmac_priv_t;
++
++#endif // #if !defined(__GMAC_H__)
++
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_desc.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_desc.c
+--- linux-2.6.24/arch/arm/mach-oxnas/gmac_desc.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_desc.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,452 @@
++/*
++ * linux/arch/arm/mach-oxnas/gmac_desc.c
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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 <linux/delay.h>
++
++//#define GMAC_DEBUG
++#undef GMAC_DEBUG
++
++#include "gmac.h"
++#include "gmac_desc.h"
++
++void init_rx_desc_list(
++ gmac_desc_list_info_t *desc_list,
++ volatile gmac_dma_desc_t *base_ptr,
++ gmac_dma_desc_t *shadow_ptr,
++ int num_descriptors,
++ u16 rx_buffer_length)
++{
++ int i;
++
++ desc_list->base_ptr = base_ptr;
++ desc_list->shadow_ptr = shadow_ptr;
++ desc_list->num_descriptors = num_descriptors;
++ desc_list->empty_count = num_descriptors;
++ desc_list->full_count = 0;
++ desc_list->r_index = 0;
++ desc_list->w_index = 0;
++
++ for (i=0; i < num_descriptors; ++i) {
++ gmac_dma_desc_t *shadow = shadow_ptr + i;
++ volatile gmac_dma_desc_t *desc = base_ptr + i;
++
++ // Initialise the shadow descriptor
++ shadow->status = 0;
++ shadow->length = (rx_buffer_length << RDES1_RBS1_BIT);
++ if (i == (num_descriptors - 1)) {
++ shadow->length |= (1UL << RDES1_RER_BIT);
++ }
++ shadow->buffer1 = 0;
++ shadow->buffer2 = 0;
++
++ // Copy the shadow descriptor into the real descriptor
++ desc->status = shadow->status;
++ desc->length = shadow->length;
++ desc->buffer1 = shadow->buffer1;
++ desc->buffer2 = shadow->buffer2;
++ }
++}
++
++void init_tx_desc_list(
++ gmac_desc_list_info_t *desc_list,
++ volatile gmac_dma_desc_t *base_ptr,
++ gmac_dma_desc_t *shadow_ptr,
++ int num_descriptors)
++{
++ int i;
++
++ desc_list->base_ptr = base_ptr;
++ desc_list->shadow_ptr = shadow_ptr;
++ desc_list->num_descriptors = num_descriptors;
++ desc_list->empty_count = num_descriptors;
++ desc_list->full_count = 0;
++ desc_list->r_index = 0;
++ desc_list->w_index = 0;
++
++ for (i=0; i < num_descriptors; ++i) {
++ gmac_dma_desc_t *shadow = shadow_ptr + i;
++ volatile gmac_dma_desc_t *desc = base_ptr + i;
++
++ // Initialise the shadow descriptor
++ shadow->status = 0;
++ shadow->length = (1UL << TDES1_IC_BIT);
++ if (i == (num_descriptors - 1)) {
++ shadow->length |= (1UL << TDES1_TER_BIT);
++ }
++ shadow->buffer1 = 0;
++ shadow->buffer2 = 0;
++
++ // Copy the shadow descriptor into the real descriptor
++ desc->status = shadow->status;
++ desc->length = shadow->length;
++ desc->buffer1 = shadow->buffer1;
++ desc->buffer2 = shadow->buffer2;
++ }
++}
++
++void rx_take_ownership(gmac_desc_list_info_t* desc_list)
++{
++ int i;
++ for (i=0; i < desc_list->num_descriptors; ++i) {
++ (desc_list->base_ptr + i)->status &= ~(1UL << RDES0_OWN_BIT);
++ }
++
++ // Ensure all write to the descriptor shared with MAC have completed
++ wmb();
++}
++
++void tx_take_ownership(gmac_desc_list_info_t* desc_list)
++{
++ int i;
++ for (i=0; i < desc_list->num_descriptors; ++i) {
++ (desc_list->base_ptr + i)->status &= ~(1UL << TDES0_OWN_BIT);
++ }
++
++ // Ensure all write to the descriptor shared with MAC have completed
++ wmb();
++}
++
++int set_rx_descriptor(
++ gmac_priv_t *priv,
++ rx_frag_info_t *frag_info)
++{
++ int index = -1;
++
++ // Is there a Rx descriptor available for writing by the CPU?
++ if (available_for_write(&priv->rx_gmac_desc_list_info)) {
++ // Setup the descriptor required to describe the RX packet
++ volatile gmac_dma_desc_t *descriptor;
++ gmac_dma_desc_t *shadow;
++
++ // Get the index of the next RX descriptor available for writing by the CPU
++ index = priv->rx_gmac_desc_list_info.w_index;
++
++ // Get a pointer to the next RX descriptor available for writing by the CPU
++ descriptor = priv->rx_gmac_desc_list_info.base_ptr + index;
++ shadow = priv->rx_gmac_desc_list_info.shadow_ptr + index;
++
++ // Set first buffer pointer to buffer from skb
++ descriptor->buffer1 = shadow->buffer1 = frag_info->phys_adr;
++
++ // Remember the skb associated with the buffer
++ shadow->buffer2 = (u32)frag_info->page;
++
++ // Ensure all prior writes to the descriptor shared with MAC have
++ // completed before setting the descriptor ownership flag to transfer
++ // ownership to the GMAC
++ wmb();
++
++ // Set RX descriptor status to transfer ownership to the GMAC
++ descriptor->status = (1UL << RDES0_OWN_BIT);
++
++ // Update the index of the next descriptor available for writing by the CPU
++ priv->rx_gmac_desc_list_info.w_index = (shadow->length & (1UL << RDES1_RER_BIT)) ? 0 : index + 1;
++
++ // Account for the descriptor used to hold the new packet
++ --priv->rx_gmac_desc_list_info.empty_count;
++ ++priv->rx_gmac_desc_list_info.full_count;
++ }
++
++ return index;
++}
++
++int get_rx_descriptor(
++ gmac_priv_t *priv,
++ int *last,
++ u32 *status,
++ rx_frag_info_t *frag_info)
++{
++ int index;
++ volatile gmac_dma_desc_t *descriptor;
++ gmac_dma_desc_t *shadow;
++ u32 desc_status;
++
++ if (!priv->rx_gmac_desc_list_info.full_count) {
++ return -2;
++ }
++
++ // Get the index of the descriptor released the longest time ago by the GMAC DMA
++ index = priv->rx_gmac_desc_list_info.r_index;
++ descriptor = priv->rx_gmac_desc_list_info.base_ptr + index;
++ shadow = priv->rx_gmac_desc_list_info.shadow_ptr + index;
++
++ if (status && *status) {
++ desc_status = *status;
++ } else {
++ desc_status = descriptor->status;
++ }
++
++ if (desc_status & (1UL << RDES0_OWN_BIT)) {
++ return -1;
++ }
++
++ // Update the index of the next descriptor with which the GMAC DMA may have finished
++ priv->rx_gmac_desc_list_info.r_index = (shadow->length & (1UL << RDES1_RER_BIT)) ? 0 : index + 1;
++
++ // Account for the descriptor which is now no longer waiting to be processed by the CPU
++ ++priv->rx_gmac_desc_list_info.empty_count;
++ --priv->rx_gmac_desc_list_info.full_count;
++
++ // Get packet details from the descriptor
++ frag_info->page = (struct page*)(shadow->buffer2);
++ frag_info->phys_adr = shadow->buffer1;
++ frag_info->length = get_rx_length(desc_status);
++
++ // Is this descriptor the last contributing to a packet
++ *last = desc_status & (1UL << RDES0_LS_BIT);
++
++ // Accumulate the status
++ if (status && !*status) {
++ *status = desc_status;
++ }
++
++ return index;
++}
++
++static inline int num_descriptors_needed(u16 length)
++{
++ static const int GMAC_MAX_DESC_ORDER = 11;
++ static const u16 GMAC_MAX_DESC_MASK = ((1 << (GMAC_MAX_DESC_ORDER)) - 1);
++
++ int count = length >> GMAC_MAX_DESC_ORDER;
++ if (length & GMAC_MAX_DESC_MASK) {
++ ++count;
++ }
++ if ((count * max_descriptor_length()) < length) {
++ ++count;
++ }
++
++ return count;
++}
++
++int set_tx_descriptor(
++ gmac_priv_t *priv,
++ struct sk_buff *skb,
++ tx_frag_info_t *frag_info,
++ int frag_count,
++ int use_hw_csum)
++{
++ int first_descriptor_index = -1;
++ int num_descriptors = frag_count;
++ int frag_index = 0;
++ int check_oversized_frags = priv->netdev->mtu >= (max_descriptor_length() - ETH_HLEN);
++
++ if (unlikely(check_oversized_frags)) {
++ // Calculate the number of extra descriptors required due to fragments
++ // being longer than the maximum buffer size that can be described by a
++ // single descriptor
++ num_descriptors = 0;
++ do {
++ // How many descriptors are required to describe the fragment?
++ num_descriptors += num_descriptors_needed(frag_info[frag_index].length);
++ } while (++frag_index < frag_count);
++ }
++
++ // Are sufficicent descriptors available for writing by the CPU?
++ if (available_for_write(&priv->tx_gmac_desc_list_info) < num_descriptors) {
++ return -1;
++ }
++
++ {
++ volatile gmac_dma_desc_t *previous_descriptor = 0;
++ gmac_dma_desc_t *previous_shadow = 0;
++ volatile gmac_dma_desc_t *descriptors[num_descriptors];
++ int desc_index = 0;
++
++ frag_index = 0;
++ do {
++ int last_frag = (frag_index == (frag_count - 1));
++ u16 part_length = frag_info[frag_index].length;
++ dma_addr_t phys_adr = frag_info[frag_index].phys_adr;
++ int part = 0;
++ int parts = 1;
++
++ if (unlikely(check_oversized_frags)) {
++ // How many descriptors are required to describe the fragment?
++ parts = num_descriptors_needed(part_length);
++ }
++
++ // Setup a descriptor for each part of the fragment that can be
++ // described by a single descriptor
++ do {
++ int last_part = (part == (parts - 1));
++ int index = priv->tx_gmac_desc_list_info.w_index;
++ volatile gmac_dma_desc_t *descriptor = priv->tx_gmac_desc_list_info.base_ptr + index;
++ gmac_dma_desc_t *shadow = priv->tx_gmac_desc_list_info.shadow_ptr + index;
++ u32 length = shadow->length;
++ u32 buffer2 = 0;
++
++ // Remember descriptor pointer for final passing of ownership to GMAC
++ descriptors[desc_index++] = descriptor;
++
++ // May have a second chained descriptor, but never a second buffer,
++ // so clear the flag indicating whether there is a chained descriptor
++ length &= ~(1UL << TDES1_TCH_BIT);
++
++ // Clear the first/last descriptor flags
++ length &= ~((1UL << TDES1_LS_BIT) | (1UL << TDES1_FS_BIT));
++
++ // Set the Tx checksum mode
++ length &= ~(((1UL << TDES1_CIC_NUM_BITS) - 1) << TDES1_CIC_BIT);
++ if (use_hw_csum) {
++ // Don't want full mode as network stack will have already
++ // computed the TCP/UCP pseudo header and placed in into the
++ // TCP/UCP checksum field
++ length |= (TDES1_CIC_PAYLOAD << TDES1_CIC_BIT);
++ }
++ // Set fragment buffer length
++ length &= ~(((1UL << TDES1_TBS1_NUM_BITS) - 1) << TDES1_TBS1_BIT);
++ length |= ((part_length > max_descriptor_length() ? max_descriptor_length() : part_length) << TDES1_TBS1_BIT);
++
++ // Set fragment buffer address
++ descriptor->buffer1 = shadow->buffer1 = phys_adr;
++
++ if (previous_shadow) {
++ // Make the previous descriptor chain to the current one
++ previous_shadow->length |= (1UL << TDES1_TCH_BIT);
++ previous_descriptor->length = previous_shadow->length;
++
++ previous_shadow->buffer2 |= descriptors_virt_to_phys((u32)descriptor);
++ previous_descriptor->buffer2 = previous_shadow->buffer2;
++ }
++
++ // Is this the first desciptor for the packet?
++ if (!frag_index && !part) {
++ // Need to return index of first descriptor used for packet
++ first_descriptor_index = index;
++
++ // Set flag indicating is first descriptor for packet
++ length |= (1UL << TDES1_FS_BIT);
++ }
++
++ // Is this the last descriptor for the packet?
++ if (last_frag && last_part) {
++ // Store the skb pointer with the last descriptor for packet, in
++ // which the second buffer address will be unused as we do not use
++ // second buffers and only intermedate buffers may use the chained
++ // descriptor address
++ buffer2 = (u32)skb;
++
++ // Set flag indicating is last descriptor for packet
++ length |= (1UL << TDES1_LS_BIT);
++ } else {
++ // For descriptor chaining need to remember previous descriptor
++ previous_descriptor = descriptor;
++ previous_shadow = shadow;
++
++ // Is this descriptor not the last describing a single fragment
++ // buffer?
++ if (!last_part) {
++ // This descriptor does not own the fragment buffer, so use
++ // the (h/w ignored) lsb of buffer2 to encode this info.
++ buffer2 = 1;
++
++ // Update the fragment buffer part details
++ part_length -= max_descriptor_length();
++ phys_adr += max_descriptor_length();
++ }
++ }
++
++ // Write the assembled length descriptor entry to the descriptor
++ descriptor->length = shadow->length = length;
++
++ // Write the assembled buffer2 descriptor entry to the descriptor
++ shadow->buffer2 = buffer2;
++
++ // Update the index of the next descriptor available for writing by the CPU
++ priv->tx_gmac_desc_list_info.w_index = (length & (1UL << TDES1_TER_BIT)) ? 0 : index + 1;
++ } while (++part < parts);
++ } while (++frag_index < frag_count);
++
++ // Ensure all prior writes to the descriptors shared with MAC have
++ // completed before setting the descriptor ownership flags to transfer
++ // ownership to the GMAC
++ wmb();
++
++ // Transfer descriptors to GMAC's ownership in reverse order, so when
++ // GMAC begins processing the first descriptor all others are already
++ // owned by the GMAC
++ for (desc_index = (num_descriptors - 1); desc_index >= 0; --desc_index) {
++ descriptors[desc_index]->status = (1UL << TDES0_OWN_BIT);
++ }
++ }
++
++ // Account for the number of descriptors used to hold the new packet
++ priv->tx_gmac_desc_list_info.empty_count -= (num_descriptors);
++ priv->tx_gmac_desc_list_info.full_count += (num_descriptors);
++
++ return first_descriptor_index;
++}
++
++int get_tx_descriptor(
++ gmac_priv_t *priv,
++ struct sk_buff **skb,
++ u32 *status,
++ tx_frag_info_t *frag_info,
++ int *buffer_owned)
++{
++ int index = -1;
++ u32 local_status;
++
++ // Find the first available Tx descriptor
++ if (tx_available_for_read(&priv->tx_gmac_desc_list_info, &local_status)) {
++ gmac_dma_desc_t *shadow;
++ u32 length;
++ u32 buffer2;
++
++ // Get the descriptor released the longest time ago by the GMAC DMA
++ index = priv->tx_gmac_desc_list_info.r_index;
++ shadow = priv->tx_gmac_desc_list_info.shadow_ptr + index;
++
++ // Get the length of the buffer
++ length = shadow->length;
++ frag_info->length = ((length >> TDES1_TBS1_BIT) & ((1UL << TDES1_TBS1_NUM_BITS) - 1));
++
++ // Get a pointer to the buffer
++ frag_info->phys_adr = shadow->buffer1;
++
++ // Get buffer ownership or skb info
++ buffer2 = shadow->buffer2;
++
++ // Check that chained buffer not is use before setting skb from buffer2
++ if (!(length & (1UL << TDES1_TCH_BIT))) {
++ *skb = (struct sk_buff*)buffer2;
++ *buffer_owned = 1;
++ } else {
++ // The lsb (h/w ignored) is used to encode buffer ownership
++ *buffer_owned = !(buffer2 & 1);
++ *skb = 0;
++ }
++
++ // Accumulate status
++ if (status) {
++ *status |= local_status;
++ }
++
++ // Update the index of the next descriptor with which the GMAC DMA may have finished
++ priv->tx_gmac_desc_list_info.r_index = (length & (1UL << TDES1_TER_BIT)) ? 0 : index + 1;
++
++ // Account for the descriptor which is now no longer waiting to be processed by the CPU
++ ++priv->tx_gmac_desc_list_info.empty_count;
++ --priv->tx_gmac_desc_list_info.full_count;
++ }
++
++ return index;
++}
++
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_desc.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_desc.h
+--- linux-2.6.24/arch/arm/mach-oxnas/gmac_desc.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_desc.h 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,315 @@
++/*
++ * linux/arch/arm/mach-oxnas/gmac_desc.h
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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
++ */
++#if !defined(__GMAC_DESC_H__)
++#define __GMAC_DESC_H__
++
++#include <asm/types.h>
++#include "gmac.h"
++
++typedef enum rdes0 {
++ RDES0_OWN_BIT = 31,
++ RDES0_AFM_BIT = 30,
++ RDES0_FL_BIT = 16,
++ RDES0_ES_BIT = 15,
++ RDES0_DE_BIT = 14,
++ RDES0_SAF_BIT = 13,
++ RDES0_LE_BIT = 12,
++ RDES0_OE_BIT = 11,
++ RDES0_IPC_BIT = 10,
++ RDES0_FS_BIT = 9,
++ RDES0_LS_BIT = 8,
++ RDES0_VLAN_BIT = 7,
++ RDES0_LC_BIT = 6,
++ RDES0_FT_BIT = 5,
++ RDES0_RWT_BIT = 4,
++ RDES0_RE_BIT = 3,
++ RDES0_DRE_BIT = 2,
++ RDES0_CE_BIT = 1,
++ RDES0_PCE_BIT = 0
++} rdes0_t;
++
++#define RX_DESC_STATUS_FL_NUM_BITS 14
++
++typedef enum rdes1 {
++ RDES1_DIC_BIT = 31,
++ RDES1_RER_BIT = 25,
++ RDES1_RCH_BIT = 24,
++ RDES1_RBS2_BIT = 11,
++ RDES1_RBS1_BIT = 0,
++} rdes1_t;
++
++#define RX_DESC_LENGTH_RBS2_NUM_BITS 11
++#define RX_DESC_LENGTH_RBS1_NUM_BITS 11
++
++typedef enum tdes0 {
++ TDES0_OWN_BIT = 31,
++ TDES0_IHE_BIT = 16,
++ TDES0_ES_BIT = 15,
++ TDES0_JT_BIT = 14,
++ TDES0_FF_BIT = 13,
++ TDES0_PCE_BIT = 12,
++ TDES0_LOC_BIT = 11,
++ TDES0_NC_BIT = 10,
++ TDES0_LC_BIT = 9,
++ TDES0_EC_BIT = 8,
++ TDES0_VF_BIT = 7,
++ TDES0_CC_BIT = 3,
++ TDES0_ED_BIT = 2,
++ TDES0_UF_BIT = 1,
++ TDES0_DB_BIT = 0
++} tdes0_t;
++
++#define TDES0_CC_NUM_BITS 4
++
++typedef enum tdes1 {
++ TDES1_IC_BIT = 31,
++ TDES1_LS_BIT = 30,
++ TDES1_FS_BIT = 29,
++ TDES1_CIC_BIT = 27,
++ TDES1_DC_BIT = 26,
++ TDES1_TER_BIT = 25,
++ TDES1_TCH_BIT = 24,
++ TDES1_DP_BIT = 23,
++ TDES1_TBS2_BIT = 11,
++ TDES1_TBS1_BIT = 0
++} tdes1_t;
++
++#define TDES1_CIC_NUM_BITS 2
++#define TDES1_TBS2_NUM_BITS 11
++#define TDES1_TBS1_NUM_BITS 11
++
++#define TDES1_CIC_NONE 0
++#define TDES1_CIC_HDR 1
++#define TDES1_CIC_PAYLOAD 2
++#define TDES1_CIC_FULL 3
++
++extern void init_rx_desc_list(
++ gmac_desc_list_info_t *desc_list,
++ volatile gmac_dma_desc_t *base_ptr,
++ gmac_dma_desc_t *shadow_ptr,
++ int num_descriptors,
++ u16 rx_buffer_length);
++
++extern void init_tx_desc_list(
++ gmac_desc_list_info_t *desc_list,
++ volatile gmac_dma_desc_t *base_ptr,
++ gmac_dma_desc_t *shadow_ptr,
++ int num_descriptors);
++
++/** Force ownership of all descriptors in the specified list to being owned by
++ * the CPU
++ */
++extern void rx_take_ownership(gmac_desc_list_info_t* desc_list);
++
++/** Force ownership of all descriptors in the specified list to being owned by
++ * the CPU
++ */
++extern void tx_take_ownership(gmac_desc_list_info_t* desc_list);
++
++/** Return the number of descriptors available for the CPU to fill with new
++ * packet info */
++static inline int available_for_write(gmac_desc_list_info_t* desc_list)
++{
++ return desc_list->empty_count;
++}
++
++/** Return non-zero if there is a descriptor available with a packet with which
++ * the GMAC DMA has finished */
++static inline int tx_available_for_read(
++ volatile gmac_desc_list_info_t *desc_list,
++ u32 *status)
++{
++ if (!desc_list->full_count) {
++ return 0;
++ }
++
++ *status = (desc_list->base_ptr + desc_list->r_index)->status;
++
++ if (*status & (1UL << TDES0_OWN_BIT)) {
++ return 0;
++ }
++
++ return 1;
++}
++
++/**
++ * Return non-zero if there is a descriptor available with a packet with which
++ * the GMAC DMA has finished.
++ */
++static inline int rx_available_for_read(
++ volatile gmac_desc_list_info_t *desc_list,
++ u32 *status)
++{
++ u32 local_status;
++
++ if (!desc_list->full_count) {
++ return 0;
++ }
++
++ local_status = (desc_list->base_ptr + desc_list->r_index)->status;
++
++ if (local_status & (1UL << RDES0_OWN_BIT)) {
++ return 0;
++ }
++
++ if (status) {
++ *status = local_status;
++ }
++
++ return 1;
++}
++
++typedef struct rx_frag_info {
++ struct page *page;
++ dma_addr_t phys_adr;
++ u16 length;
++} rx_frag_info_t;
++
++/**
++ * Fill a RX descriptor and pass ownership to DMA engine
++ */
++extern int set_rx_descriptor(
++ gmac_priv_t *priv,
++ rx_frag_info_t *frag_info);
++
++/**
++ * Extract data from the next available descriptor with which the GMAC DMA
++ * controller has finished.
++ * The caller indicates via the 'first_last' argument whether the first
++ * descriptor contributing to a packet is expected. The 'first_last' argument
++ * will be returned set to indicate whether the descriptor was the last
++ * contributing to a packet.
++ * If the 'status' argument is non-null it will have the status from the
++ * descriptor or'ed into it, thus enabling the compound status for all
++ * descriptors contributing to a packet to be built up
++ */
++extern int get_rx_descriptor(
++ gmac_priv_t *priv,
++ int *last,
++ u32 *status,
++ rx_frag_info_t *frag_info);
++
++/**
++ * Fill in descriptors describing all fragments in a single Tx packet and pass
++ * ownership to the GMAC. The 'frag_info' argument points to an array describing
++ * each buffer that is to contribute to the transmitted packet. The 'frag_count'
++ * argument gives the number of elements in that array
++ */
++extern int set_tx_descriptor(
++ gmac_priv_t *priv,
++ struct sk_buff *skb,
++ tx_frag_info_t *frag_info,
++ int frag_count,
++ int use_hw_csum);
++
++/**
++ * Extract information about the TX packet transmitted the longest time ago.
++ * If the 'status' argument is non-null it will have the status from the
++ * descriptor or'ed into it.
++ */
++extern int get_tx_descriptor(
++ gmac_priv_t *priv,
++ struct sk_buff **skb,
++ u32 *status,
++ tx_frag_info_t *frag_info,
++ int *buffer_owned);
++
++/**
++ * @param A u32 containing the status from a received frame's DMA descriptor
++ * @return An int which is non-zero if a valid received frame has no error
++ * condititions flagged
++ */
++static inline int is_rx_valid(u32 status)
++{
++ return !(status & (1UL << RDES0_ES_BIT)) &&
++ !(status & (1UL << RDES0_IPC_BIT));
++}
++
++static inline int is_rx_dribbling(u32 status)
++{
++ return status & (1UL << RDES0_DRE_BIT);
++}
++
++static inline u32 get_rx_length(u32 status)
++{
++ return (status >> RDES0_FL_BIT) & ((1UL << RX_DESC_STATUS_FL_NUM_BITS) - 1);
++}
++
++static inline int is_rx_collision_error(u32 status)
++{
++ return status & ((1UL << RDES0_OE_BIT) | (1UL << RDES0_LC_BIT));
++}
++
++static inline int is_rx_crc_error(u32 status)
++{
++ return status & (1UL << RDES0_CE_BIT);
++}
++
++static inline int is_rx_frame_error(u32 status)
++{
++ return status & (1UL << RDES0_DE_BIT);
++}
++
++static inline int is_rx_length_error(u32 status)
++{
++ return status & (1UL << RDES0_LE_BIT);
++}
++
++static inline int is_rx_csum_error(u32 status)
++{
++ return (status & (1UL << RDES0_IPC_BIT))
++#ifndef CONFIG_OXNAS_VERSION_0X800
++ || (status & (1UL << RDES0_PCE_BIT))
++#endif // !CONFIG_OXNAS_VERSION_0X800
++ ;
++}
++
++static inline int is_rx_long_frame(u32 status)
++{
++ return status & (1UL << RDES0_VLAN_BIT);
++}
++
++static inline int is_tx_valid(u32 status)
++{
++ return !(status & (1UL << TDES0_ES_BIT));
++}
++
++static inline int is_tx_collision_error(u32 status)
++{
++ return (status & (((1UL << TDES0_CC_NUM_BITS) - 1) << TDES0_CC_BIT)) >> TDES0_CC_BIT;
++}
++
++static inline int is_tx_aborted(u32 status)
++{
++ return status & ((1UL << TDES0_LC_BIT) | (1UL << TDES0_EC_BIT));
++}
++
++static inline int is_tx_carrier_error(u32 status)
++{
++ return status & ((1UL << TDES0_LOC_BIT) | (1UL << TDES0_NC_BIT));
++}
++
++static inline u16 max_descriptor_length(void) {
++ static const int GMAC_MAX_DESC_LEN = 2047;
++
++ return GMAC_MAX_DESC_LEN;
++}
++#endif // #if !defined(__GMAC_DESC_H__)
++
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_ethtool.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_ethtool.c
+--- linux-2.6.24/arch/arm/mach-oxnas/gmac_ethtool.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_ethtool.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,275 @@
++/*
++ * linux/arch/arm/mach-oxnas/gmac_ethtool.c
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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 <asm/types.h>
++#include <linux/errno.h>
++#include <linux/ethtool.h>
++#include <linux/netdevice.h>
++#include <asm/io.h>
++#include <asm/arch/leon.h>
++
++//#define GMAC_DEBUG
++#undef GMAC_DEBUG
++
++#include "gmac.h"
++#include "gmac_desc.h"
++
++static int get_settings(struct net_device* dev, struct ethtool_cmd* cmd)
++{
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++ unsigned long irq_flags;
++ int status;
++
++ spin_lock_irqsave(&priv->phy_lock, irq_flags);
++ status = mii_ethtool_gset(&priv->mii, cmd);
++ spin_unlock_irqrestore(&priv->phy_lock, irq_flags);
++
++ return status;
++}
++
++static int set_settings(struct net_device* dev, struct ethtool_cmd* cmd)
++{
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++ unsigned long irq_flags;
++ int status;
++
++ spin_lock_irqsave(&priv->phy_lock, irq_flags);
++ status = mii_ethtool_sset(&priv->mii, cmd);
++ spin_unlock_irqrestore(&priv->phy_lock, irq_flags);
++
++ return status;
++}
++
++static void get_drvinfo(struct net_device* dev, struct ethtool_drvinfo* drvinfo)
++{
++ strncpy(drvinfo->driver, "GMAC", 32);
++ strncpy(drvinfo->version, "1.0", 32);
++ strncpy(drvinfo->fw_version, "1.0", 32); // Version of CoPro s/w
++ strncpy(drvinfo->bus_info, "AMBA", 32);
++}
++
++static int nway_reset(struct net_device* dev)
++{
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++ unsigned long irq_flags;
++ int status;
++
++ spin_lock_irqsave(&priv->phy_lock, irq_flags);
++ status = mii_nway_restart(&priv->mii);
++ spin_unlock_irqrestore(&priv->phy_lock, irq_flags);
++
++ return status;
++}
++
++static u32 get_msglevel(struct net_device* dev)
++{
++ return ((gmac_priv_t*)netdev_priv(dev))->msg_level;
++}
++
++static void set_msglevel(struct net_device* dev, u32 data)
++{
++ ((gmac_priv_t*)netdev_priv(dev))->msg_level = data;
++}
++
++static u32 get_rx_csum(struct net_device* dev)
++{
++#ifdef USE_RX_CSUM
++ return 1;
++#else
++ return 0;
++#endif
++}
++
++static int set_rx_csum(struct net_device* dev, u32 data)
++{
++ return 0;
++}
++
++static int get_regs_len(struct net_device* dev)
++{
++ return 0;
++}
++
++static void get_regs(struct net_device* dev, struct ethtool_regs* regs, void *p)
++{
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ unsigned long irq_state;
++ u32 status;
++
++ printk("RX ring info:\n");
++ printk(" num_descriptors = %d\n", priv->rx_gmac_desc_list_info.num_descriptors);
++ printk(" empty_count = %d\n", priv->rx_gmac_desc_list_info.empty_count);
++ printk(" full_count = %d\n", priv->rx_gmac_desc_list_info.full_count);
++ printk(" r_index = %d\n", priv->rx_gmac_desc_list_info.r_index);
++ printk(" w_index = %d\n", priv->rx_gmac_desc_list_info.w_index);
++ printk(" available_for_write = %d\n", available_for_write(&priv->rx_gmac_desc_list_info));
++ printk(" available_for_read %s\n", rx_available_for_read(&priv->rx_gmac_desc_list_info, 0) ? "yes" :"no");
++
++ spin_lock_irqsave(&priv->tx_spinlock_, irq_state);
++ printk("TX ring info:\n");
++ printk(" num_descriptors = %d\n", priv->tx_gmac_desc_list_info.num_descriptors);
++ printk(" empty_count = %d\n", priv->tx_gmac_desc_list_info.empty_count);
++ printk(" full_count = %d\n", priv->tx_gmac_desc_list_info.full_count);
++ printk(" r_index = %d\n", priv->tx_gmac_desc_list_info.r_index);
++ printk(" w_index = %d\n", priv->tx_gmac_desc_list_info.w_index);
++ printk(" available_for_write = %d\n", available_for_write(&priv->tx_gmac_desc_list_info));
++ printk(" available_for_read %s\n", tx_available_for_read(&priv->tx_gmac_desc_list_info, &status) ? "yes" : "no");
++ spin_unlock_irqrestore(&priv->tx_spinlock_, irq_state);
++}
++
++static void get_wol(struct net_device* dev, struct ethtool_wolinfo* wol_info)
++{
++}
++
++static int set_wol(struct net_device* dev, struct ethtool_wolinfo* wol_info)
++{
++ return -EINVAL;
++}
++
++static int get_coalesce(struct net_device* dev, struct ethtool_coalesce *ethtool_coalesce)
++{
++#ifdef CONFIG_LEON_COPRO
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++
++ if (priv->copro_params_.rx_mitigation_) {
++ ethtool_coalesce->rx_max_coalesced_frames = priv->copro_params_.rx_mitigation_frames_;
++ ethtool_coalesce->rx_coalesce_usecs = priv->copro_params_.rx_mitigation_usec_;
++printk("get_coalesce() %u packets, %u usec\n", ethtool_coalesce->rx_max_coalesced_frames, ethtool_coalesce->rx_coalesce_usecs);
++ }
++#endif // CONFIG_LEON_COPRO
++ return 0;
++}
++
++static int set_coalesce(struct net_device* dev, struct ethtool_coalesce *ethtool_coalesce)
++{
++#ifdef CONFIG_LEON_COPRO
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++
++ if (priv->copro_params_.rx_mitigation_) {
++printk("set_coalesce() %u packets, %u usec\n", ethtool_coalesce->rx_max_coalesced_frames, ethtool_coalesce->rx_coalesce_usecs);
++ priv->copro_params_.rx_mitigation_frames_ = ethtool_coalesce->rx_max_coalesced_frames;
++ priv->copro_params_.rx_mitigation_usec_ = ethtool_coalesce->rx_coalesce_usecs;
++
++ // Only attempt to write to uncached/unbuffered shared parameter storage
++ // if CoPro is started and thus storage has been allocated
++ if (priv->shared_copro_params_) {
++ // Fill the CoPro parameter block
++ memcpy(priv->shared_copro_params_, &priv->copro_params_, sizeof(copro_params_t));
++ }
++
++ // Make sure the CoPro parameter block updates have made it to memory (which
++ // is uncached/unbuffered, so just compiler issues to overcome)
++ wmb();
++
++ spin_lock(&priv->cmd_que_lock_);
++ cmd_que_queue_cmd(&priv->cmd_queue_, GMAC_CMD_UPDATE_PARAMS, 0, 0);
++ spin_unlock(&priv->cmd_que_lock_);
++
++ // Interrupt the CoPro so it sees the new command
++ writel(1UL << COPRO_SEM_INT_CMD, SYS_CTRL_SEMA_SET_CTRL);
++ }
++#endif // CONFIG_LEON_COPRO
++
++ return 0;
++}
++
++static void get_ringparam(struct net_device* dev, struct ethtool_ringparam *ethtool_ringparam)
++{
++}
++
++static int set_ringparam(struct net_device* dev, struct ethtool_ringparam *ethtool_ringparam)
++{
++ return -EINVAL;
++}
++
++static void get_pauseparam(struct net_device* dev, struct ethtool_pauseparam* ethtool_pauseparam)
++{
++}
++
++static int set_pauseparam(struct net_device* dev, struct ethtool_pauseparam* ethtool_pauseparam)
++{
++ return -EINVAL;
++}
++
++static int self_test_count(struct net_device* dev)
++{
++ return -EINVAL;
++}
++
++static void self_test(struct net_device* dev, struct ethtool_test* ethtool_test, u64 *data)
++{
++}
++
++static void get_strings(struct net_device* dev, u32 stringset, u8 *data)
++{
++}
++
++static int phys_id(struct net_device* dev, u32 data)
++{
++ return -EINVAL;
++}
++
++static int get_stats_count(struct net_device* dev)
++{
++ return -EINVAL;
++}
++
++static void get_ethtool_stats(struct net_device* dev, struct ethtool_stats* ethtool_stats, u64 *data)
++{
++}
++
++static struct ethtool_ops ethtool_ops = {
++ .get_settings = get_settings,
++ .set_settings = set_settings,
++ .get_drvinfo = get_drvinfo,
++ .get_regs_len = get_regs_len,
++ .get_regs = get_regs,
++ .get_wol = get_wol,
++ .set_wol = set_wol,
++ .get_msglevel = get_msglevel,
++ .set_msglevel = set_msglevel,
++ .nway_reset = nway_reset,
++ .get_link = ethtool_op_get_link,
++ .get_coalesce = get_coalesce,
++ .set_coalesce = set_coalesce,
++ .get_ringparam = get_ringparam,
++ .set_ringparam = set_ringparam,
++ .get_pauseparam = get_pauseparam,
++ .set_pauseparam = set_pauseparam,
++ .get_rx_csum = get_rx_csum,
++ .set_rx_csum = set_rx_csum,
++ .get_tx_csum = ethtool_op_get_tx_csum,
++ .set_tx_csum = ethtool_op_set_tx_csum,
++ .get_sg = ethtool_op_get_sg,
++ .set_sg = ethtool_op_set_sg,
++ .get_tso = ethtool_op_get_tso,
++ .set_tso = ethtool_op_set_tso,
++ .self_test_count = self_test_count,
++ .self_test = self_test,
++ .get_strings = get_strings,
++ .phys_id = phys_id,
++ .get_stats_count = get_stats_count,
++ .get_ethtool_stats = get_ethtool_stats
++};
++
++void set_ethtool_ops(struct net_device *netdev)
++{
++ SET_ETHTOOL_OPS(netdev, ðtool_ops);
++}
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_ethtool.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_ethtool.h
+--- linux-2.6.24/arch/arm/mach-oxnas/gmac_ethtool.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_ethtool.h 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,26 @@
++/*
++ * linux/arch/arm/mach-oxnas/gmac_ethtool.h
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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
++ */
++#if !defined(__GMAC_ETHTOOL_H__)
++#define __GMAC_ETHTOOL_H__
++
++extern void set_ethtool_ops(struct net_device *netdev);
++
++#endif // #if !defined(__GMAC_ETHTOOL_H__)
++
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_offload.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_offload.c
+--- linux-2.6.24/arch/arm/mach-oxnas/gmac_offload.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_offload.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,223 @@
++/*
++ * linux/arch/arm/mach-oxnas/gmac-offload.c
++ *
++ * Copyright (C) 2006 Oxford Semiconductor Ltd
++ *
++ * 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
++ */
++#ifdef CONFIG_LEON_COPRO
++
++#include <linux/slab.h>
++#include "gmac.h"
++
++void cmd_que_init(
++ cmd_que_t *queue,
++ gmac_cmd_que_ent_t *start,
++ int num_entries)
++{
++ // Initialise queue management metadata
++ INIT_LIST_HEAD(&queue->ack_list_);
++ queue->head_ = start;
++ queue->tail_ = start + num_entries;
++ queue->w_ptr_ = queue->head_;
++
++ // Zeroise all entries in the queue
++ memset(start, 0, num_entries * sizeof(gmac_cmd_que_ent_t));
++}
++
++int cmd_que_dequeue_ack(cmd_que_t *queue)
++{
++ struct list_head *list_entry;
++ cmd_que_ack_t *ack;
++
++ if (list_empty(&queue->ack_list_)) {
++ return -1;
++ }
++
++ // Remove the first entry on the acknowledgement list
++ list_entry = queue->ack_list_.next;
++ BUG_ON(!list_entry);
++
++ // Get pointer to ack entry from it's list_head member
++ ack = list_entry(list_entry, cmd_que_ack_t, list_);
++ BUG_ON(!ack);
++ BUG_ON(!ack->entry_);
++ BUG_ON(!ack->callback_);
++
++ // Has the CoPro acknowledged the command yet?
++ if (!(ack->entry_->opcode_ & (1UL << GMAC_CMD_QUE_SKP_BIT))) {
++ // No, so no further acknowledgements can be pending as CoPro executes
++ // commands/acks in order
++ return -1;
++ }
++
++ // Going to process the acknowledgement, so remove it from the pending list
++ list_del(list_entry);
++
++//printk("ak=0x%08x:0x%08x\n", ack->entry_->opcode_, ack->entry_->operand_);
++ // Invoke the acknowledgement handler routine
++ ack->callback_(ack->entry_);
++
++ // Reset ACK flag in command queue entry
++ ack->entry_->opcode_ &= ~(1UL << GMAC_CMD_QUE_ACK_BIT);
++
++ kfree(ack);
++ return 0;
++}
++
++#define OPCODE_FLAGS_MASK ((1UL << (GMAC_CMD_QUE_OWN_BIT)) |\
++ (1UL << (GMAC_CMD_QUE_ACK_BIT)) |\
++ (1UL << (GMAC_CMD_QUE_SKP_BIT)))
++
++int cmd_que_queue_cmd(
++ cmd_que_t *queue,
++ u32 opcode,
++ u32 operand,
++ cmd_que_ack_callback callback)
++{
++ int result = -1;
++
++ do {
++ volatile gmac_cmd_que_ent_t* entry = queue->w_ptr_;
++ u32 old_opcode = entry->opcode_;
++
++ if (old_opcode & (1UL << GMAC_CMD_QUE_OWN_BIT)) {
++ // Queue is full as we've run into an entry still owned by the CoPro
++ break;
++ }
++
++ if (!(old_opcode & (1UL << GMAC_CMD_QUE_ACK_BIT))) {
++ // We've found an entry we own that isn't waiting for the contained
++ // ack to be processed, so we can use it for the new command
++ opcode &= ~(OPCODE_FLAGS_MASK);
++ opcode |= (1UL << GMAC_CMD_QUE_OWN_BIT);
++
++ if (callback) {
++ // Register ack. handler before releasing entry to CoPro
++ cmd_que_ack_t *ack = kmalloc(sizeof(cmd_que_ack_t), GFP_ATOMIC);
++ BUG_ON(!ack);
++
++ ack->entry_ = queue->w_ptr_;
++ ack->callback_ = callback;
++ INIT_LIST_HEAD(&ack->list_);
++ list_add_tail(&ack->list_, &queue->ack_list_);
++
++ // Mark the entry as requiring an ack.
++ opcode |= (1UL << GMAC_CMD_QUE_ACK_BIT);
++ }
++
++ // Copy the command into the queue entry and pass ownership to the
++ // CoPro, being sure to set the OWN flag last
++//printk("op=0x%08x:0x%08x\n", opcode, operand);
++ queue->w_ptr_->operand_ = operand;
++ wmb();
++ queue->w_ptr_->opcode_ = opcode;
++ // Ensure the OWN flag gets to memory before any following interrupt
++ // to the CoPro is issued
++ wmb();
++
++ result = 0;
++ }
++
++ // Make the write pointer point to the next potentially available entry
++ if (++queue->w_ptr_ == queue->tail_) {
++ queue->w_ptr_ = queue->head_;
++ }
++ } while (result);
++
++ return result;
++}
++
++void tx_que_init(
++ tx_que_t *queue,
++ gmac_tx_que_ent_t *start,
++ int num_entries)
++{
++ // Initialise queue management metadata
++ queue->head_ = start;
++ queue->tail_ = start + num_entries;
++ queue->w_ptr_ = queue->head_;
++ queue->r_ptr_ = queue->head_;
++ queue->full_ = 0;
++
++ // Zeroise all entries in the queue
++ memset(start, 0, num_entries * sizeof(gmac_tx_que_ent_t));
++}
++
++static inline void tx_que_inc_w_ptr(tx_que_t *queue)
++{
++ if (++queue->w_ptr_ == queue->tail_) {
++ queue->w_ptr_ = queue->head_;
++ }
++ queue->full_ = (queue->w_ptr_ == queue->r_ptr_);
++}
++
++volatile gmac_tx_que_ent_t* tx_que_get_finished_job(struct net_device *dev)
++{
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++ tx_que_t *queue = &priv->tx_queue_;
++ volatile gmac_tx_que_ent_t *entry = 0;
++
++ if (tx_que_not_empty(queue)) {
++ entry = queue->r_ptr_;
++ if (entry->flags_ & (1UL << TX_JOB_FLAGS_OWN_BIT)) {
++ entry = (volatile gmac_tx_que_ent_t*)0;
++ } else {
++ tx_que_inc_r_ptr(queue);
++ }
++ }
++
++ return entry;
++}
++
++/**
++ * A call to tx_que_get_idle_job() must be followed by a call to tx_que_new_job()
++ * before any subsequent call to tx_que_get_idle_job()
++ */
++volatile gmac_tx_que_ent_t* tx_que_get_idle_job(struct net_device *dev)
++{
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++ tx_que_t *queue = &priv->tx_queue_;
++ volatile gmac_tx_que_ent_t *entry = 0;
++
++ // Must not reuse completed Tx packets returned by CoPro until the queue
++ // reader has had a chance to process them
++ if (!tx_que_is_full(queue)) {
++ entry = queue->w_ptr_;
++ }
++
++ return entry;
++}
++
++/**
++ * A call to tx_que_get_idle_job() must be followed by a call to tx_que_new_job()
++ * before any subsequent call to tx_que_get_idle_job()
++ */
++void tx_que_new_job(
++ struct net_device *dev,
++ volatile gmac_tx_que_ent_t *entry)
++{
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++
++ // Make sure any modifications to Tx job structures make it to memory before
++ // setting the OWN flag to pass ownership to the CoPro
++ wmb();
++
++ entry->flags_ |= (1UL << TX_JOB_FLAGS_OWN_BIT);
++
++ tx_que_inc_w_ptr(&priv->tx_queue_);
++}
++#endif // #ifdef CONFIG_LEON_COPRO
++
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_offload.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_offload.h
+--- linux-2.6.24/arch/arm/mach-oxnas/gmac_offload.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_offload.h 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,163 @@
++/*
++ * linux/arch/arm/mach-oxnas/gmac-offload.h
++ *
++ * Copyright (C) 2006 Oxford Semiconductor Ltd
++ *
++ * 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
++ */
++#ifdef CONFIG_LEON_COPRO
++
++#if !defined(__GMAC_OFFLOAD_H__)
++#define __GMAC_OFFLOAD_H__
++
++#include <linux/kernel.h>
++#include <linux/list.h>
++
++#define GMAC_CMD_QUE_OWN_BIT 31 // 0-Owned by ARM, 1-Owned by CoPro
++#define GMAC_CMD_QUE_ACK_BIT 30
++#define GMAC_CMD_QUE_SKP_BIT 29
++
++typedef struct gmac_cmd_que_ent {
++ u32 opcode_;
++ u32 operand_;
++} __attribute ((aligned(4),packed)) gmac_cmd_que_ent_t;
++
++#define GMAC_CMD_STOP 0
++#define GMAC_CMD_START 1
++#define GMAC_CMD_INT_EN_SET 2
++#define GMAC_CMD_INT_EN_CLR 3
++#define GMAC_CMD_HEARTBEAT 4
++#define GMAC_CMD_UPDATE_PARAMS 5
++#define GMAC_CMD_CHANGE_GIG_MODE 6
++#define GMAC_CMD_CHANGE_RX_ENABLE 7
++#define GMAC_CMD_CLEAR_RX_INTS 8
++#define GMAC_CMD_CHANGE_PAUSE_MODE 9
++
++typedef void (*cmd_que_ack_callback)(volatile gmac_cmd_que_ent_t* entry);
++
++typedef struct cmd_que_ack {
++ struct list_head list_;
++ volatile gmac_cmd_que_ent_t *entry_;
++ cmd_que_ack_callback callback_;
++} cmd_que_ack_t;
++
++typedef struct cmd_que {
++ gmac_cmd_que_ent_t *head_;
++ gmac_cmd_que_ent_t *tail_;
++ volatile gmac_cmd_que_ent_t *w_ptr_;
++ struct list_head ack_list_;
++} cmd_que_t;
++
++extern void cmd_que_init(
++ cmd_que_t *queue,
++ gmac_cmd_que_ent_t *start,
++ int num_entries);
++
++extern int cmd_que_dequeue_ack(cmd_que_t *queue);
++
++extern int cmd_que_queue_cmd(
++ cmd_que_t *queue,
++ u32 opcode,
++ u32 operand,
++ cmd_que_ack_callback callback); // non-zero if ack. required
++
++#define COPRO_SEM_INT_CMD 0
++#define COPRO_SEM_INT_TX 1
++
++typedef struct gmac_fwd_intrs {
++ u32 status_;
++} __attribute ((aligned(4),packed)) gmac_fwd_intrs_t;
++
++#define TX_JOB_FLAGS_OWN_BIT 0
++#define TX_JOB_FLAGS_COPRO_RESERVED_1_BIT 1
++#define TX_JOB_FLAGS_ACCELERATE_BIT 2
++
++#define TX_JOB_STATS_BYTES_BIT 0
++#define TX_JOB_STATS_BYTES_NUM_BITS 16
++#define TX_JOB_STATS_BYTES_MASK (((1UL << TX_JOB_STATS_BYTES_NUM_BITS) - 1) << TX_JOB_STATS_BYTES_BIT)
++#define TX_JOB_STATS_PACKETS_BIT 16
++#define TX_JOB_STATS_PACKETS_NUM_BITS 6
++#define TX_JOB_STATS_PACKETS_MASK (((1UL << TX_JOB_STATS_PACKETS_NUM_BITS) - 1) << TX_JOB_STATS_PACKETS_BIT)
++#define TX_JOB_STATS_ABORT_BIT 22
++#define TX_JOB_STATS_ABORT_NUM_BITS 3
++#define TX_JOB_STATS_ABORT_MASK (((1UL << TX_JOB_STATS_ABORT_NUM_BITS) - 1) << TX_JOB_STATS_ABORT_BIT)
++#define TX_JOB_STATS_CARRIER_BIT 25
++#define TX_JOB_STATS_CARRIER_NUM_BITS 3
++#define TX_JOB_STATS_CARRIER_MASK (((1UL << TX_JOB_STATS_CARRIER_NUM_BITS) - 1) << TX_JOB_STATS_CARRIER_BIT)
++#define TX_JOB_STATS_COLLISION_BIT 28
++#define TX_JOB_STATS_COLLISION_NUM_BITS 4
++#define TX_JOB_STATS_COLLISION_MASK (((1UL << TX_JOB_STATS_COLLISION_NUM_BITS) - 1) << TX_JOB_STATS_COLLISION_BIT)
++
++/* Make even number else gmac_tx_que_ent_t struct below alignment will be wrong */
++#define COPRO_NUM_TX_FRAGS_DIRECT 18
++
++typedef struct gmac_tx_que_ent {
++ u32 skb_;
++ u32 len_;
++ u32 data_len_;
++ u32 ethhdr_;
++ u32 iphdr_;
++ u16 iphdr_csum_;
++ u16 tso_segs_;
++ u16 tso_size_;
++ u16 flags_;
++ u32 frag_ptr_[COPRO_NUM_TX_FRAGS_DIRECT];
++ u16 frag_len_[COPRO_NUM_TX_FRAGS_DIRECT];
++ u32 statistics_;
++} __attribute ((aligned(4),packed)) gmac_tx_que_ent_t;
++
++typedef struct tx_que {
++ gmac_tx_que_ent_t *head_;
++ gmac_tx_que_ent_t *tail_;
++ volatile gmac_tx_que_ent_t *w_ptr_;
++ volatile gmac_tx_que_ent_t *r_ptr_;
++ int full_;
++} tx_que_t;
++
++extern void tx_que_init(
++ tx_que_t *queue,
++ gmac_tx_que_ent_t *start,
++ int num_entries);
++
++static inline int tx_que_not_empty(tx_que_t *queue)
++{
++ return (queue->r_ptr_ != queue->w_ptr_) || queue->full_;
++}
++
++static inline int tx_que_is_full(tx_que_t *queue)
++{
++ return queue->full_;
++}
++
++static inline void tx_que_inc_r_ptr(tx_que_t *queue)
++{
++ if (++queue->r_ptr_ == queue->tail_) {
++ queue->r_ptr_ = queue->head_;
++ }
++ if (queue->full_) {
++ queue->full_ = 0;
++ }
++}
++
++extern volatile gmac_tx_que_ent_t* tx_que_get_finished_job(struct net_device *dev);
++
++extern volatile gmac_tx_que_ent_t* tx_que_get_idle_job(struct net_device *dev);
++
++extern void tx_que_new_job(
++ struct net_device *dev,
++ volatile gmac_tx_que_ent_t *entry);
++
++#endif // #if !defined(__GMAC_OFFLOAD_H__)
++#endif // CONFIG_LEON_COPRO
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_phy.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_phy.c
+--- linux-2.6.24/arch/arm/mach-oxnas/gmac_phy.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_phy.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,318 @@
++/*
++ * linux/arch/arm/mach-oxnas/gmac_phy.c
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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 <linux/delay.h>
++
++//#define GMAC_DEBUG
++#undef GMAC_DEBUG
++
++#include "gmac.h"
++#include "gmac_phy.h"
++#include "gmac_reg.h"
++
++static const int PHY_TRANSFER_TIMEOUT_MS = 100;
++
++/*
++ * Reads a register from the MII Management serial interface
++ */
++int phy_read(struct net_device *dev, int phyaddr, int phyreg)
++{
++ int data = 0;
++#ifndef ARMULATING
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++ unsigned long end;
++
++ u32 addr = (phyaddr << MAC_GMII_ADR_PA_BIT) |
++ (phyreg << MAC_GMII_ADR_GR_BIT) |
++ (priv->gmii_csr_clk_range << MAC_GMII_ADR_CR_BIT) |
++ (1UL << MAC_GMII_ADR_GB_BIT);
++
++ mac_reg_write(priv, MAC_GMII_ADR_REG, addr);
++
++ end = jiffies + MS_TO_JIFFIES(PHY_TRANSFER_TIMEOUT_MS);
++ while (time_before(jiffies, end)) {
++ if (!(mac_reg_read(priv, MAC_GMII_ADR_REG) & (1UL << MAC_GMII_ADR_GB_BIT))) {
++ // Successfully read from PHY
++ data = mac_reg_read(priv, MAC_GMII_DATA_REG) & 0xFFFF;
++ break;
++ }
++ }
++
++ DBG(1, KERN_INFO "phy_read() %s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", dev->name, phyaddr, phyreg, data);
++#endif // ARMULATING
++
++ return data;
++}
++
++/*
++ * Writes a register to the MII Management serial interface
++ */
++void phy_write(struct net_device *dev, int phyaddr, int phyreg, int phydata)
++{
++#ifndef ARMULATING
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++ unsigned long end;
++
++ u32 addr = (phyaddr << MAC_GMII_ADR_PA_BIT) |
++ (phyreg << MAC_GMII_ADR_GR_BIT) |
++ (priv->gmii_csr_clk_range << MAC_GMII_ADR_CR_BIT) |
++ (1UL << MAC_GMII_ADR_GW_BIT) |
++ (1UL << MAC_GMII_ADR_GB_BIT);
++
++ mac_reg_write(priv, MAC_GMII_DATA_REG, phydata);
++ mac_reg_write(priv, MAC_GMII_ADR_REG, addr);
++
++ end = jiffies + MS_TO_JIFFIES(PHY_TRANSFER_TIMEOUT_MS);
++ while (time_before(jiffies, end)) {
++ if (!(mac_reg_read(priv, MAC_GMII_ADR_REG) & (1UL << MAC_GMII_ADR_GB_BIT))) {
++ break;
++ }
++ }
++
++ DBG(1, KERN_INFO "phy_write() %s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", dev->name, phyaddr, phyreg, phydata);
++#endif // ARMULATING
++}
++
++/*
++ * Finds and reports the PHY address
++ */
++void phy_detect(struct net_device *dev)
++{
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++#ifdef ARMULATING
++ priv->mii.phy_id = 0;
++ priv->phy_type = 0x22 << 16 | 0x1619;
++ priv->phy_addr = 0;
++#else // ARMULATING
++ int phyaddr;
++
++ DBG(2, KERN_INFO "phy_detect() %s: Entered\n", priv->netdev->name);
++
++ // Scan all 32 PHY addresses if necessary
++ priv->phy_type = 0;
++ for (phyaddr = 1; phyaddr < 33; ++phyaddr) {
++ unsigned int id1, id2;
++
++ // Read the PHY identifiers
++ id1 = phy_read(priv->netdev, phyaddr & 31, MII_PHYSID1);
++ id2 = phy_read(priv->netdev, phyaddr & 31, MII_PHYSID2);
++
++ DBG(2, KERN_INFO "phy_detect() %s: PHY adr = %u -> phy_id1=0x%x, phy_id2=0x%x\n", priv->netdev->name, phyaddr, id1, id2);
++
++ // Make sure it is a valid identifier
++ if (id1 != 0x0000 && id1 != 0xffff && id1 != 0x8000 &&
++ id2 != 0x0000 && id2 != 0xffff && id2 != 0x8000) {
++ DBG(2, KERN_NOTICE "phy_detect() %s: Found PHY at address = %u\n", priv->netdev->name, phyaddr);
++ priv->mii.phy_id = phyaddr & 31;
++ priv->phy_type = id1 << 16 | id2;
++ priv->phy_addr = phyaddr;
++ break;
++ }
++ }
++#endif // ARMULATING
++}
++
++void start_phy_reset(gmac_priv_t* priv)
++{
++ // Ask the PHY to reset
++ phy_write(priv->netdev, priv->phy_addr, MII_BMCR, BMCR_RESET);
++}
++
++int is_phy_reset_complete(gmac_priv_t* priv)
++{
++#ifdef ARMULATING
++ return 1;
++#else // ARMULATING
++ int complete = 0;
++ int bmcr;
++
++ // Read back the status until it indicates reset, or we timeout
++ bmcr = phy_read(priv->netdev, priv->phy_addr, MII_BMCR);
++ if (!(bmcr & BMCR_RESET)) {
++ complete = 1;
++ }
++
++ return complete;
++#endif // ARMULATING
++}
++
++int phy_reset(struct net_device *dev)
++{
++#ifdef ARMULATING
++ return 0;
++#else // ARMULATING
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++ int complete = 0;
++ unsigned long end;
++
++ // Start the reset operation
++ start_phy_reset(priv);
++
++ // Total time to wait for reset to complete
++ end = jiffies + MS_TO_JIFFIES(PHY_TRANSFER_TIMEOUT_MS);
++
++ // Should apparently wait at least 50mS before reading back from PHY; this
++ // could just be a nasty feature of the SMC91x MAC/PHY and not apply to us
++ msleep(50);
++
++ // Read back the status until it indicates reset, or we timeout
++ while (!(complete = is_phy_reset_complete(priv)) && time_before(jiffies, end)) {
++ msleep(1);
++ }
++
++ return !complete;
++#endif // ARMULATING
++}
++
++void phy_powerdown(struct net_device *dev)
++{
++ gmac_priv_t* priv = (gmac_priv_t*)netdev_priv(dev);
++
++ unsigned int bmcr = phy_read(dev, priv->phy_addr, MII_BMCR);
++ phy_write(dev, priv->phy_addr, MII_BMCR, bmcr | BMCR_PDOWN);
++}
++
++void set_phy_negotiate_mode(struct net_device *dev)
++{
++ gmac_priv_t *priv = (gmac_priv_t*)netdev_priv(dev);
++ struct mii_if_info *mii = &priv->mii;
++ struct ethtool_cmd *ecmd = &priv->ethtool_cmd;
++ u32 bmcr;
++
++ bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
++
++ if (ecmd->autoneg == AUTONEG_ENABLE) {
++ u32 advert, tmp;
++ u32 advert2 = 0, tmp2 = 0;
++
++//printk("set_phy_negotiate_mode() Auto negotiating link mode\n");
++ // Advertise only what has been requested
++ advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE);
++ tmp = advert & ~(ADVERTISE_ALL | ADVERTISE_100BASE4 |
++ ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
++
++ if (ecmd->supported & (SUPPORTED_1000baseT_Full | ADVERTISE_1000HALF)) {
++ advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
++ tmp2 = advert2 & ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
++ }
++
++ if (ecmd->advertising & ADVERTISED_10baseT_Half) {
++ tmp |= ADVERTISE_10HALF;
++ }
++ if (ecmd->advertising & ADVERTISED_10baseT_Full) {
++ tmp |= ADVERTISE_10FULL;
++ }
++ if (ecmd->advertising & ADVERTISED_100baseT_Half) {
++ tmp |= ADVERTISE_100HALF;
++ }
++ if (ecmd->advertising & ADVERTISED_100baseT_Full) {
++ tmp |= ADVERTISE_100FULL;
++ }
++ if ((ecmd->supported & SUPPORTED_1000baseT_Half) &&
++ (ecmd->advertising & ADVERTISED_1000baseT_Half)) {
++ tmp2 |= ADVERTISE_1000HALF;
++ }
++ if ((ecmd->supported & SUPPORTED_1000baseT_Full) &&
++ (ecmd->advertising & ADVERTISED_1000baseT_Full)) {
++ tmp2 |= ADVERTISE_1000FULL;
++ }
++
++ if (ecmd->advertising & ADVERTISED_Pause) {
++ tmp |= ADVERTISE_PAUSE_CAP;
++ }
++ if (ecmd->advertising & ADVERTISED_Asym_Pause) {
++ tmp |= ADVERTISE_PAUSE_ASYM;
++ }
++
++ if (advert != tmp) {
++//printk("set_phy_negotiate_mode() Setting MII_ADVERTISE to 0x%08x\n", tmp);
++ mii->mdio_write(dev, mii->phy_id, MII_ADVERTISE, tmp);
++ mii->advertising = tmp;
++ }
++ if (advert2 != tmp2) {
++//printk("set_phy_negotiate_mode() Setting MII_CTRL1000 to 0x%08x\n", tmp2);
++ mii->mdio_write(dev, mii->phy_id, MII_CTRL1000, tmp2);
++ }
++
++ // Auto-negotiate the link state
++ bmcr |= (BMCR_ANRESTART | BMCR_ANENABLE);
++ mii->mdio_write(dev, mii->phy_id, MII_BMCR, bmcr);
++ } else {
++ u32 tmp;
++//printk("set_phy_negotiate_mode() Unilaterally setting link mode\n");
++
++ // Turn off auto negotiation, set speed and duplicitly unilaterally
++ tmp = bmcr & ~(BMCR_ANENABLE | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_FULLDPLX);
++ if (ecmd->speed == SPEED_1000) {
++ tmp |= BMCR_SPEED1000;
++ } else if (ecmd->speed == SPEED_100) {
++ tmp |= BMCR_SPEED100;
++ }
++
++ if (ecmd->duplex == DUPLEX_FULL) {
++ tmp |= BMCR_FULLDPLX;
++ mii->full_duplex = 1;
++ } else {
++ mii->full_duplex = 0;
++ }
++
++ if (bmcr != tmp) {
++ mii->mdio_write(dev, mii->phy_id, MII_BMCR, tmp);
++ }
++ }
++}
++
++u32 get_phy_capabilies(gmac_priv_t* priv)
++{
++ struct mii_if_info *mii = &priv->mii;
++
++ // Ask the PHY for it's capabilities
++ u32 reg = mii->mdio_read(priv->netdev, mii->phy_id, MII_BMSR);
++
++ // Assume PHY has MII interface
++ u32 features = SUPPORTED_MII;
++
++ if (reg & BMSR_ANEGCAPABLE) {
++ features |= SUPPORTED_Autoneg;
++ }
++ if (reg & BMSR_100FULL) {
++ features |= SUPPORTED_100baseT_Full;
++ }
++ if (reg & BMSR_100HALF) {
++ features |= SUPPORTED_100baseT_Half;
++ }
++ if (reg & BMSR_10FULL) {
++ features |= SUPPORTED_10baseT_Full;
++ }
++ if (reg & BMSR_10HALF) {
++ features |= SUPPORTED_10baseT_Half;
++ }
++
++ // Does the PHY have the extended status register?
++ if (reg & BMSR_ESTATEN) {
++ reg = mii->mdio_read(priv->netdev, mii->phy_id, MII_ESTATUS);
++
++ if (reg & ESTATUS_1000_TFULL)
++ features |= SUPPORTED_1000baseT_Full;
++ if (reg & ESTATUS_1000_THALF)
++ features |= SUPPORTED_1000baseT_Half;
++ }
++
++ return features;
++}
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_phy.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_phy.h
+--- linux-2.6.24/arch/arm/mach-oxnas/gmac_phy.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_phy.h 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,78 @@
++/*
++ * linux/arch/arm/mach-oxnas/gmac_phy.h
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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
++ */
++#if !defined(__GMAC_PHY_H__)
++#define __GMAC_PHY_H__
++
++#include <asm/types.h>
++#include <linux/netdevice.h>
++#include <linux/mii.h>
++#include "gmac.h"
++
++#define PHY_TYPE_NONE 0
++#define PHY_TYPE_MICREL_KS8721BL 0x00221619
++#define PHY_TYPE_VITESSE_VSC8201XVZ 0x000fc413
++#define PHY_TYPE_REALTEK_RTL8211BGR 0x001cc912
++#define PHY_TYPE_LSI_ET1011C 0x0282f013
++#define PHY_TYPE_LSI_ET1011C2 0x0282f014
++#define PHY_TYPE_ICPLUS_IP1001 0x02430d90
++
++#define VSC8201_MII_ACSR 0x1c // Vitesse VCS8201 gigabit PHY Auxillary Control and Status register
++#define VSC8201_MII_ACSR_MDPPS_BIT 2 // Mode/Duplex Pin Priority Select
++
++#define ET1011C_MII_CONFIG 0x16
++#define ET1011C_MII_CONFIG_IFMODESEL 0
++#define ET1011C_MII_CONFIG_IFMODESEL_NUM_BITS 3
++#define ET1011C_MII_CONFIG_SYSCLKEN 4
++#define ET1011C_MII_CONFIG_TXCLKEN 5
++#define ET1011C_MII_CONFIG_TBI_RATESEL 8
++#define ET1011C_MII_CONFIG_CRS_TX_EN 15
++
++#define ET1011C_MII_CONFIG_IFMODESEL_GMII_MII 0
++#define ET1011C_MII_CONFIG_IFMODESEL_TBI 1
++#define ET1011C_MII_CONFIG_IFMODESEL_GMII_MII_GTX 2
++
++#define ET1011C_MII_LED2 0x1c
++#define ET1011C_MII_LED2_LED_TXRX 12
++#define ET1011C_MII_LED2_LED_NUM_BITS 4
++
++#define ET1011C_MII_LED2_LED_TXRX_ON 0xe
++#define ET1011C_MII_LED2_LED_TXRX_ACTIVITY 0x7
++
++extern int phy_read(struct net_device *dev, int phyaddr, int phyreg);
++
++extern void phy_write(struct net_device *dev, int phyaddr, int phyreg, int phydata);
++
++extern void phy_detect(struct net_device *dev);
++
++extern int phy_reset(struct net_device *dev);
++
++extern void phy_powerdown(struct net_device *dev);
++
++extern void start_phy_reset(gmac_priv_t* priv);
++
++extern int is_phy_reset_complete(gmac_priv_t* priv);
++
++extern void set_phy_negotiate_mode(struct net_device *dev);
++
++extern u32 get_phy_capabilies(gmac_priv_t* priv);
++
++extern u32 get_phy_capabilies(gmac_priv_t* priv);
++#endif // #if !defined(__GMAC_PHY_H__)
++
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gmac_reg.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_reg.h
+--- linux-2.6.24/arch/arm/mach-oxnas/gmac_reg.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gmac_reg.h 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,508 @@
++/*
++ * linux/arch/arm/mach-oxnas/gmac_reg.h
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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
++ */
++#if !defined(__GMAC_REG_H__)
++#define __GMAC_REG_H__
++
++#include <asm/io.h>
++#include "gmac.h"
++
++/**
++ * MAC register access functions
++ */
++
++/**
++ * @param priv A gmac_priv_t* pointing to private device data
++ * @param reg_num An int specifying the index of the MAC register to access
++ */
++static inline u32 mac_reg_read(gmac_priv_t* priv, int reg_num)
++{
++//printk("$WReading MAC register %u at byte adr 0x%08x\n", reg_num, priv->macBase + (reg_num << 2));
++ return readl(priv->macBase + (reg_num << 2));
++}
++
++/**
++ * @param priv A gmac_priv_t* pointing to private device data
++ * @param reg_num An int specifying the index of the MAC register to access
++ */
++static inline void mac_reg_write(gmac_priv_t* priv, int reg_num, u32 value)
++{
++//printk("$WWriting MAC register %u at byte adr 0x%08x with 0x%08x\n", reg_num, priv->macBase + (reg_num << 2), value);
++ writel(value, priv->macBase + (reg_num << 2));
++}
++
++/**
++ * @param priv A gmac_priv_t* pointing to private device data
++ * @param reg_num An int specifying the index of the MAC register to access
++ * @param bits_to_clear A u32 specifying which bits of the specified register to
++ * clear. A set bit in this parameter will cause the matching bit in the
++ * register to be cleared
++ */
++static inline void mac_reg_clear_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_clear)
++{
++ mac_reg_write(priv, reg_num, mac_reg_read(priv, reg_num) & ~bits_to_clear);
++}
++
++/**
++ * @param priv A gmac_priv_t* pointing to private device data
++ * @param reg_num An int specifying the index of the MAC register to access
++ * @param bits_to_set A u32 specifying which bits of the specified register to
++ * set. A set bit in this parameter will cause the matching bit in the register
++ * to be set
++ */
++static inline void mac_reg_set_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_set)
++{
++ mac_reg_write(priv, reg_num, mac_reg_read(priv, reg_num) | bits_to_set);
++}
++
++/**
++ * DMA register access functions
++ */
++
++/**
++ * @param priv A gmac_priv_t* pointing to private device data
++ * @param reg_num An int specifying the index of the DMA register to access
++ */
++static inline u32 dma_reg_read(gmac_priv_t* priv, int reg_num)
++{
++//printk("$WReading DMA register %u at byte adr 0x%08x\n", reg_num, priv->dmaBase + (reg_num << 2));
++ return readl(priv->dmaBase + (reg_num << 2));
++}
++
++/**
++ * @param priv A gmac_priv_t* pointing to private device data
++ * @param reg_num An int specifying the index of the DMA register to access
++ */
++static inline void dma_reg_write(gmac_priv_t* priv, int reg_num, u32 value)
++{
++//printk("$WWriting DMA register %u at byte adr 0x%08x with 0x%08x\n", reg_num, priv->dmaBase + (reg_num << 2), value);
++ writel(value, priv->dmaBase + (reg_num << 2));
++}
++
++/**
++ * @param priv A gmac_priv_t* pointing to private device data
++ * @param reg_num An int specifying the index of the DMA register to access
++ * @param bits_to_clear A u32 specifying which bits of the specified register to
++ * clear. A set bit in this parameter will cause the matching bit in the
++ * register to be cleared
++ * @return An u32 containing the new value written to the register
++ */
++static inline u32 dma_reg_clear_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_clear)
++{
++ u32 new_value = dma_reg_read(priv, reg_num) & ~bits_to_clear;
++ dma_reg_write(priv, reg_num, new_value);
++ return new_value;
++}
++
++/**
++ * @param priv A gmac_priv_t* pointing to private device data
++ * @param reg_num An int specifying the index of the DMA register to access
++ * @param bits_to_set A u32 specifying which bits of the specified register to
++ * set. A set bit in this parameter will cause the matching bit in the register
++ * to be set
++ * @return An u32 containing the new value written to the register
++ */
++static inline u32 dma_reg_set_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_set)
++{
++ u32 new_value = dma_reg_read(priv, reg_num) | bits_to_set;
++ dma_reg_write(priv, reg_num, new_value);
++ return new_value;
++}
++
++#define NUM_PERFECT_MATCH_REGISTERS 15
++
++/**
++ * MAC register indices
++ */
++typedef enum gmac_mac_regs {
++ MAC_CONFIG_REG = 0,
++ MAC_FRAME_FILTER_REG = 1,
++ MAC_HASH_HIGH_REG = 2,
++ MAC_HASH_LOW_REG = 3,
++ MAC_GMII_ADR_REG = 4,
++ MAC_GMII_DATA_REG = 5,
++ MAC_FLOW_CNTL_REG = 6,
++ MAC_VLAN_TAG_REG = 7,
++ MAC_VERSION_REG = 8,
++ MAC_ADR0_HIGH_REG = 16,
++ MAC_ADR0_LOW_REG = 17,
++ MAC_ADR1_HIGH_REG = 18,
++ MAC_ADR1_LOW_REG = 19,
++ MAC_ADR2_HIGH_REG = 20,
++ MAC_ADR2_LOW_REG = 21,
++ MAC_ADR3_HIGH_REG = 22,
++ MAC_ADR3_LOW_REG = 23,
++ MAC_ADR4_HIGH_REG = 24,
++ MAC_ADR4_LOW_REG = 25,
++ MAC_ADR5_HIGH_REG = 26,
++ MAC_ADR5_LOW_REG = 27,
++ MAC_ADR6_HIGH_REG = 28,
++ MAC_ADR6_LOW_REG = 29,
++ MAC_ADR7_HIGH_REG = 30,
++ MAC_ADR7_LOW_REG = 31,
++ MAC_ADR8_HIGH_REG = 32,
++ MAC_ADR8_LOW_REG = 33,
++ MAC_ADR9_HIGH_REG = 34,
++ MAC_ADR9_LOW_REG = 35,
++ MAC_ADR10_HIGH_REG = 36,
++ MAC_ADR10_LOW_REG = 37,
++ MAC_ADR11_HIGH_REG = 38,
++ MAC_ADR11_LOW_REG = 39,
++ MAC_ADR12_HIGH_REG = 40,
++ MAC_ADR12_LOW_REG = 41,
++ MAC_ADR13_HIGH_REG = 42,
++ MAC_ADR13_LOW_REG = 43,
++ MAC_ADR14_HIGH_REG = 44,
++ MAC_ADR14_LOW_REG = 45,
++ MAC_ADR15_HIGH_REG = 46,
++ MAC_ADR15_LOW_REG = 47
++} gmac_mac_regs_t;
++
++/**
++ * @param priv A gmac_priv_t* pointing to private device data
++ * @param reg_num An int specifying the index of the perfect matching low register
++ * @param value A u32 specifying the value to write to the register
++ */
++static inline void mac_adrlo_reg_write(gmac_priv_t* priv, int reg_num, u32 value)
++{
++ mac_reg_write(priv, MAC_ADR1_LOW_REG + (2*reg_num), value);
++}
++
++/**
++ * @param priv A gmac_priv_t* pointing to private device data
++ * @param reg_num An int specifying the index of the perfect matching high register
++ * @param value A u32 specifying the value to write to the register
++ */
++static inline void mac_adrhi_reg_write(gmac_priv_t* priv, int reg_num, u32 value)
++{
++ mac_reg_write(priv, MAC_ADR1_HIGH_REG + (2*reg_num), value);
++}
++
++/**
++ * MAC register field definitions
++ */
++typedef enum gmac_config_reg {
++ MAC_CONFIG_WD_BIT = 23,
++ MAC_CONFIG_JD_BIT = 22,
++ MAC_CONFIG_BE_BIT = 21,
++ MAC_CONFIG_JE_BIT = 20,
++ MAC_CONFIG_IFG_BIT = 17,
++ MAC_CONFIG_PS_BIT = 15,
++ MAC_CONFIG_DO_BIT = 13,
++ MAC_CONFIG_LM_BIT = 12,
++ MAC_CONFIG_DM_BIT = 11,
++ MAC_CONFIG_IPC_BIT = 10,
++ MAC_CONFIG_DR_BIT = 9,
++ MAC_CONFIG_ACS_BIT = 7,
++ MAC_CONFIG_BL_BIT = 5,
++ MAC_CONFIG_DC_BIT = 4,
++ MAC_CONFIG_TE_BIT = 3,
++ MAC_CONFIG_RE_BIT = 2
++} gmac_config_reg_t;
++
++#define MAC_CONFIG_IFG_NUM_BITS 3
++#define MAC_CONFIG_BL_NUM_BITS 2
++
++typedef enum gmac_frame_filter_reg {
++ MAC_FRAME_FILTER_RA_BIT = 31,
++ MAC_FRAME_FILTER_SAF_BIT = 9,
++ MAC_FRAME_FILTER_SAIF_BIT = 8,
++ MAC_FRAME_FILTER_PCF_BIT = 6,
++ MAC_FRAME_FILTER_DBF_BIT = 5,
++ MAC_FRAME_FILTER_PM_BIT = 4,
++ MAC_FRAME_FILTER_DAIF_BIT = 3,
++ MAC_FRAME_FILTER_HMC_BIT = 2,
++ MAC_FRAME_FILTER_HUC_BIT = 1,
++ MAC_FRAME_FILTER_PR_BIT = 0
++} gmac_frame_filter_reg_t;
++
++#define MAC_FRAME_FILTER_PCF_NUM_BITS 2
++
++typedef enum gmac_hash_table_high_reg {
++ MAC_HASH_HIGH_HTH_BIT = 0
++} gmac_hash_table_high_reg_t;
++
++typedef enum gmac_hash_table_low_reg {
++ MAC_HASH_LOW_HTL_BIT = 0
++} gmac_hash_table_low_reg_t;
++
++typedef enum gmac_gmii_address_reg {
++ MAC_GMII_ADR_PA_BIT = 11,
++ MAC_GMII_ADR_GR_BIT = 6,
++ MAC_GMII_ADR_CR_BIT = 2,
++ MAC_GMII_ADR_GW_BIT = 1,
++ MAC_GMII_ADR_GB_BIT = 0
++} gmac_gmii_address_reg_t;
++
++#define MAC_GMII_ADR_PA_NUM_BITS 5
++#define MAC_GMII_ADR_GR_NUM_BITS 5
++#define MAC_GMII_ADR_CR_NUM_BITS 3
++
++typedef enum gmac_gmii_data_reg {
++ MAC_GMII_DATA_GD_BIT = 0
++} gmac_gmii_data_reg_t;
++
++#define MAC_GMII_DATA_GD_NUM_BITS 16
++
++typedef enum gmac_flow_control_reg {
++ MAC_FLOW_CNTL_PT_BIT = 16,
++ MAC_FLOW_CNTL_PLT_BIT = 4,
++ MAC_FLOW_CNTL_UP_BIT = 3,
++ MAC_FLOW_CNTL_RFE_BIT = 2,
++ MAC_FLOW_CNTL_TFE_BIT = 1,
++ MAC_FLOW_CNTL_FCB_BPA_BIT = 0
++} gmac_flow_control_reg_t;
++
++#define MAC_FLOW_CNTL_PT_NUM_BITS 16
++#define MAC_FLOW_CNTL_PLT_NUM_BITS 2
++
++typedef enum gmac_vlan_tag_reg {
++ MAC_VLAN_TAG_LV_BIT = 0
++} gmac_vlan_tag_reg_t;
++
++#define MAC_VLAN_TAG_LV_NUM_BITS 16
++
++typedef enum gmac_version_reg {
++ MAC_VERSION_UD_BIT = 8,
++ MAC_VERSION_SD_BIT = 0
++} gmac_version_reg_t;
++
++#define MAC_VERSION_UD_NUM_BITS 8
++#define MAC_VERSION_SD_NUM_BITS 8
++
++typedef enum gmac_mac_adr_0_high_reg {
++ MAC_ADR0_HIGH_MO_BIT = 31,
++ MAC_ADR0_HIGH_A_BIT = 0
++} gmac_mac_adr_0_high_reg_t;
++
++#define MAC_ADR0_HIGH_A_NUM_BITS 16
++
++typedef enum gmac_mac_adr_0_low_reg {
++ MAC_ADR0_LOW_A_BIT = 0
++} gmac_mac_adr_0_low_reg_t;
++
++typedef enum gmac_mac_adr_1_high_reg {
++ MAC_ADR1_HIGH_AE_BIT = 31,
++ MAC_ADR1_HIGH_SA_BIT = 30,
++ MAC_ADR1_HIGH_MBC_BIT = 24,
++ MAC_ADR1_HIGH_A_BIT = 0
++} gmac_mac_adr_1_high_reg_t;
++
++#define MAC_ADR1_HIGH_MBC_NUM_BITS 6
++#define MAC_ADR1_HIGH_A_NUM_BITS 16
++
++typedef enum gmac_mac_adr_1_low_reg {
++ MAC_ADR1_LOW_A_BIT = 0
++} gmac_mac_adr_1_low_reg_t;
++
++
++/**
++ * MMC register indices - registers accessed via the MAC accessor functions
++ */
++typedef enum gmac_mmc_regs {
++ MMC_CONTROL_REG = 64,
++ MMC_RX_INT_REG = 65,
++ MMC_TX_INT_REG = 66,
++ MMC_RX_MASK_REG = 67,
++ MMC_TX_MASK_REG = 68
++} gmac_mmc_regs_t;
++
++
++/**
++ * DMA register indices
++ */
++typedef enum gmac_dma_regs {
++ DMA_BUS_MODE_REG = 0,
++ DMA_TX_POLL_REG = 1,
++ DMA_RX_POLL_REG = 2,
++ DMA_RX_DESC_ADR_REG = 3,
++ DMA_TX_DESC_ADR_REG = 4,
++ DMA_STATUS_REG = 5,
++ DMA_OP_MODE_REG = 6,
++ DMA_INT_ENABLE_REG = 7,
++ DMA_MISSED_OVERFLOW_REG = 8,
++ DMA_CUR_TX_DESC_REG = 18,
++ DMA_CUR_RX_DESC_REG = 19,
++ DMA_CUR_TX_ADR_REG = 20,
++ DMA_CUR_RX_ADR_REG = 21
++} gmac_dma_regs_t;
++
++
++/**
++ * DMA register field definitions
++ */
++
++typedef enum gmac_dma_bus_mode_reg {
++ DMA_BUS_MODE_FB_BIT = 16,
++ DMA_BUS_MODE_PR_BIT = 14,
++ DMA_BUS_MODE_PBL_BIT = 8,
++ DMA_BUS_MODE_DSL_BIT = 2,
++ DMA_BUS_MODE_DA_BIT = 1,
++ DMA_BUS_MODE_SWR_BIT = 0
++} gmac_dma_bus_mode_reg_t;
++
++#define DMA_BUS_MODE_PR_NUM_BITS 2
++#define DMA_BUS_MODE_PBL_NUM_BITS 6
++#define DMA_BUS_MODE_DSL_NUM_BITS 5
++
++typedef enum gmac_dma_tx_poll_demand_reg {
++ DMA_TX_POLL_TPD_BIT = 0
++} gmac_dma_tx_poll_demand_reg_t;
++
++typedef enum gmac_dma_rx_poll_demand_reg {
++ DMA_RX_POLL_RPD_BIT = 0
++} gmac_dma_rx_poll_demand_reg_t;
++
++typedef enum gmac_dma_rx_desc_list_adr_reg {
++ DMA_RX_DESC_ADR_SRL_BIT = 0
++} gmac_dma_rx_desc_list_adr_reg_t;
++
++typedef enum gmac_dma_tx_desc_list_adr_reg {
++ DMA_TX_DESC_ADR_STL_BIT = 0
++} gmac_dma_tx_desc_list_adr_reg_t;
++
++typedef enum gmac_dma_status_reg {
++ DMA_STATUS_GPI_BIT = 28,
++ DMA_STATUS_GMI_BIT = 27,
++ DMA_STATUS_GLI_BIT = 26,
++ DMA_STATUS_EB_BIT = 23,
++ DMA_STATUS_TS_BIT = 20,
++ DMA_STATUS_RS_BIT = 17,
++ DMA_STATUS_NIS_BIT = 16,
++ DMA_STATUS_AIS_BIT = 15,
++ DMA_STATUS_ERI_BIT = 14,
++ DMA_STATUS_FBE_BIT = 13,
++ DMA_STATUS_ETI_BIT = 10,
++ DMA_STATUS_RWT_BIT = 9,
++ DMA_STATUS_RPS_BIT = 8,
++ DMA_STATUS_RU_BIT = 7,
++ DMA_STATUS_RI_BIT = 6,
++ DMA_STATUS_UNF_BIT = 5,
++ DMA_STATUS_OVF_BIT = 4,
++ DMA_STATUS_TJT_BIT = 3,
++ DMA_STATUS_TU_BIT = 2,
++ DMA_STATUS_TPS_BIT = 1,
++ DMA_STATUS_TI_BIT = 0
++} gmac_dma_status_reg_t;
++
++#define DMA_STATUS_EB_NUM_BITS 3
++#define DMA_STATUS_TS_NUM_BITS 3
++#define DMA_STATUS_RS_NUM_BITS 3
++
++typedef enum gmac_dma_status_ts_val {
++ DMA_STATUS_TS_CLOSING = 7,
++ DMA_STATUS_TS_SUSPENDED = 6,
++ DMA_STATUS_TS_RESERVED = 5,
++ DMA_STATUS_TS_FLUSHING = 4,
++ DMA_STATUS_TS_READING = 3,
++ DMA_STATUS_TS_WAITING = 2,
++ DMA_STATUS_TS_FETCHING = 1,
++ DMA_STATUS_TS_STOPPED = 0
++} gmac_dma_status_ts_val_t;
++
++typedef enum gmac_dma_op_mode_reg {
++ DMA_OP_MODE_DT_BIT = 26,
++ DMA_OP_MODE_RSF_BIT = 25,
++ DMA_OP_MODE_DFF_BIT = 24,
++ DMA_OP_MODE_RFA2_BIT = 23,
++ DMA_OP_MODE_RFD2_BIT = 22,
++ DMA_OP_MODE_SF_BIT = 21,
++ DMA_OP_MODE_FTF_BIT = 20,
++ DMA_OP_MODE_TTC_BIT = 14,
++ DMA_OP_MODE_ST_BIT = 13,
++ DMA_OP_MODE_RFD_BIT = 11,
++ DMA_OP_MODE_RFA_BIT = 9,
++ DMA_OP_MODE_EFC_BIT = 8,
++ DMA_OP_MODE_FEF_BIT = 7,
++ DMA_OP_MODE_FUF_BIT = 6,
++ DMA_OP_MODE_RTC_BIT = 3,
++ DMA_OP_MODE_OSF_BIT = 2,
++ DMA_OP_MODE_SR_BIT = 1
++} gmac_dma_op_mode_reg_t;
++
++#define DMA_OP_MODE_TTC_NUM_BITS 3
++
++typedef enum gmac_dma_op_mode_ttc_val {
++ DMA_OP_MODE_TTC_16 = 7,
++ DMA_OP_MODE_TTC_24 = 6,
++ DMA_OP_MODE_TTC_32 = 5,
++ DMA_OP_MODE_TTC_40 = 4,
++ DMA_OP_MODE_TTC_256 = 3,
++ DMA_OP_MODE_TTC_192 = 2,
++ DMA_OP_MODE_TTC_128 = 1,
++ DMA_OP_MODE_TTC_64 = 0
++} gmac_dma_op_mode_ttc_val_t;
++
++#define DMA_OP_MODE_RFD_NUM_BITS 2
++#define DMA_OP_MODE_RFA_NUM_BITS 2
++#define DMA_OP_MODE_RTC_NUM_BITS 2
++
++typedef enum gmac_dma_op_mode_rtc_val {
++ DMA_OP_MODE_RTC_128 = 3,
++ DMA_OP_MODE_RTC_96 = 2,
++ DMA_OP_MODE_RTC_32 = 1,
++ DMA_OP_MODE_RTC_64 = 0
++} gmac_dma_op_mode_rtc_val_t;
++
++typedef enum gmac_dma_intr_enable_reg {
++ DMA_INT_ENABLE_NI_BIT = 16,
++ DMA_INT_ENABLE_AI_BIT = 15,
++ DMA_INT_ENABLE_ERE_BIT = 14,
++ DMA_INT_ENABLE_FBE_BIT = 13,
++ DMA_INT_ENABLE_ETE_BIT = 10,
++ DMA_INT_ENABLE_RW_BIT = 9,
++ DMA_INT_ENABLE_RS_BIT = 8,
++ DMA_INT_ENABLE_RU_BIT = 7,
++ DMA_INT_ENABLE_RI_BIT = 6,
++ DMA_INT_ENABLE_UN_BIT = 5,
++ DMA_INT_ENABLE_OV_BIT = 4,
++ DMA_INT_ENABLE_TJ_BIT = 3,
++ DMA_INT_ENABLE_TU_BIT = 2,
++ DMA_INT_ENABLE_TS_BIT = 1,
++ DMA_INT_ENABLE_TI_BIT = 0
++} gmac_dma_intr_enable_reg_t;
++
++typedef enum gmac_dma_missed_overflow_reg {
++ DMA_MISSED_OVERFLOW_OFOC_BIT = 28, // Overflow bit for FIFO Overflow Counter
++ DMA_MISSED_OVERFLOW_AMFC_BIT = 17, // Application Missed Frames Count
++ DMA_MISSED_OVERFLOW_OAMFO_BIT = 16, // Overflow bit for Application Missed Frames Count
++ DMA_MISSED_OVERFLOW_CMFC_BIT = 0 // Controller Missed Frames Count
++} gmac_dma_missed_overflow_reg_t;
++
++#define DMA_MISSED_OVERFLOW_OAMFO_NUM_BITS 11
++#define DMA_MISSED_OVERFLOW_CMFC_NUM_BITS 16
++
++typedef enum gmac_dma_current_tx_desc_reg {
++ DMA_CUR_TX_DESC_A_BIT = 0
++} gmac_dma_current_tx_desc_reg_t;
++
++typedef enum gmac_dma_current_rx_desc_reg {
++ DMA_CUR_RX_DESC_A_BIT = 0
++} gmac_dma_current_rx_desc_reg_t;
++
++typedef enum gmac_dma_current_tx_adr_reg {
++ DMA_CUR_TX_ADR_A_BIT = 0
++} gmac_dma_current_tx_adr_reg_t;
++
++typedef enum gmac_dma_current_rx_adr_reg {
++ DMA_CUR_RX_ADR_A_BIT = 0
++} gmac_dma_current_rx_adr_reg_t;
++
++#endif // #if !defined(__GMAC_REG_H__)
++
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/gpioTest.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/gpioTest.c
+--- linux-2.6.24/arch/arm/mach-oxnas/gpioTest.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/gpioTest.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,657 @@
++#include <asm/io.h>
++#include <asm/bitops.h>
++#include <asm/uaccess.h> // copy_to_user and copy_from_user
++#include <linux/init.h> // modules
++#include <linux/module.h> // module
++#include <linux/types.h> // dev_t type
++#include <linux/fs.h> // chrdev allocation
++#include <linux/slab.h> // kmalloc and kfree
++#include <linux/cdev.h> // struct cdev
++#include <linux/errno.h> // error codes
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++#include <asm/arch/hardware.h>
++
++MODULE_LICENSE("GPL v2");
++
++MODULE_AUTHOR("C Ford");
++MODULE_DESCRIPTION("gpioTest first version");
++
++struct gpioTest_dev {
++ struct semaphore sem; // Mutual exclusion semaphore
++ struct cdev cdev; // Char device structure
++ int found;
++};
++
++struct gpioTest_dev * gpioTest_device; // Contains the gpioTest devices
++
++dev_t dev; // Contains major and first minor number
++static wait_queue_head_t ir_block;
++
++////////////////////////////
++// LINKED LIST OPERATIONS //
++////////////////////////////
++
++
++///////////////
++// CALLBACKS //
++///////////////
++
++#define GPIO_TEST_SCL (1UL << CONFIG_OXNAS_I2C_SCL)
++#define GPIO_TEST_SDA (1UL << CONFIG_OXNAS_I2C_SDA)
++
++void DumpGPIO( void )
++{
++ printk( KERN_INFO "================= GPIO Dump\n"
++ " GPIO_A_DATA 0x%08x\n"
++ " GPIO_A_OUTPUT_ENABLE 0x%08x\n"
++ " GPIO_A_INTERRUPT_ENABLE 0x%08x\n"
++ " GPIO_A_INTERRUPT_EVENT 0x%08x\n"
++ " GPIO_A_OUTPUT_VALUE 0x%08x\n"
++ " GPIO_A_OUTPUT_SET 0x%08x\n"
++ " GPIO_A_OUTPUT_CLEAR 0x%08x\n"
++ " GPIO_A_OUTPUT_ENABLE_SET 0x%08x\n"
++ " GPIO_A_OUTPUT_ENABLE_CLEAR 0x%08x\n"
++ " GPIO_A_INPUT_DEBOUNCE_ENABLE 0x%08x\n"
++ " GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE 0x%08x\n"
++ " GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE 0x%08x\n"
++ " GPIO_A_RISING_EDGE_DETECT 0x%08x\n"
++ " GPIO_A_FALLING_EDGE_DETECT 0x%08x\n"
++ " GPIO_A_LEVEL_INTERRUPT_ENABLE 0x%08x\n"
++ " GPIO_A_INTERRUPT_STATUS_REGISTER 0x%08x\n",
++ readl( GPIO_A_DATA ),
++ readl( GPIO_A_OUTPUT_ENABLE ),
++ readl( GPIO_A_INTERRUPT_ENABLE ),
++ readl( GPIO_A_INTERRUPT_EVENT ),
++ readl( GPIO_A_OUTPUT_VALUE ),
++ readl( GPIO_A_OUTPUT_SET ),
++ readl( GPIO_A_OUTPUT_CLEAR ),
++ readl( GPIO_A_OUTPUT_ENABLE_SET ),
++ readl( GPIO_A_OUTPUT_ENABLE_CLEAR ),
++ readl( GPIO_A_INPUT_DEBOUNCE_ENABLE ),
++ readl( GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ),
++ readl( GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ),
++ readl( GPIO_A_RISING_EDGE_DETECT ),
++ readl( GPIO_A_FALLING_EDGE_DETECT ),
++ readl( GPIO_A_LEVEL_INTERRUPT_ENABLE ),
++ readl( GPIO_A_INTERRUPT_STATUS_REGISTER ) );
++
++}
++
++irqreturn_t irqHandler( int irq, void* dev_id)
++{
++ // is this interrupt fors us??
++ struct gpioTest_dev* pGPIO = (struct gpioTest_dev*) dev_id;
++ unsigned int temp = readl( (volatile unsigned long *) GPIO_A_INTERRUPT_STATUS_REGISTER );
++
++ if ( !(temp & (GPIO_TEST_SCL | GPIO_TEST_SDA) ) )
++ {
++ printk("Not for us...\n");
++ return IRQ_NONE;
++ }
++
++ // apparantly it is, for simplicity, we will stop the intterupting pin,
++ // and clear its source, then signal the bottmo half to continue
++ if ( test_bit( CONFIG_OXNAS_I2C_SCL, (volatile unsigned long *) &temp ) )
++ {
++ printk("Int Found CONFIG_OXNAS_I2C_SCL\n");
++ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) &= ~(1UL << CONFIG_OXNAS_I2C_SCL);
++ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) &= ~(1UL << CONFIG_OXNAS_I2C_SCL);
++ *( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE ) &= ~(1UL << CONFIG_OXNAS_I2C_SCL);
++ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_DETECT ) &= ~(1UL << CONFIG_OXNAS_I2C_SCL);
++ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_DETECT ) &= ~(1UL << CONFIG_OXNAS_I2C_SCL);
++ pGPIO->found |= GPIO_TEST_SCL;
++ }
++
++ if ( test_bit( CONFIG_OXNAS_I2C_SDA, (volatile unsigned long *) &temp ) )
++ {
++ printk("Int Found CONFIG_OXNAS_I2C_SDA\n");
++ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) &= ~(1UL << CONFIG_OXNAS_I2C_SDA);
++ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) &= ~(1UL << CONFIG_OXNAS_I2C_SDA);
++ *( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE ) &= ~(1UL << CONFIG_OXNAS_I2C_SDA);
++ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_DETECT ) &= ~(1UL << CONFIG_OXNAS_I2C_SDA);
++ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_DETECT ) &= ~(1UL << CONFIG_OXNAS_I2C_SDA);
++ pGPIO->found |= GPIO_TEST_SDA;
++ }
++
++ if ( pGPIO->found )
++ {
++ printk("Int cleared\n");
++ wake_up_interruptible(&ir_block);
++ }
++
++ return IRQ_HANDLED;
++}
++
++int gpioTest_go(void)
++{
++ unsigned long flags;
++ unsigned int temp;
++ unsigned int i;
++
++ //assert( CONFIG_OXNAS_I2C_SDA < CONFIG_OXNAS_I2C_SCL );
++
++ printk( KERN_ERR "****************************************************************\n");
++ printk( KERN_ERR "************************************************** gpioTest_go:\n");
++ printk( KERN_ERR "Please connect I2c SDA to I2C SCLK, and optionally attach scope:\n\n");
++
++ printk( KERN_ERR "Test 1: setup all inputs (and check for pull up res)\n");
++
++ // Setting lines to GPIO
++ *( (volatile unsigned long *) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) &= ~(1UL << (CONFIG_OXNAS_I2C_SDA & 0x0000001F) );
++ *( (volatile unsigned long *) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) &= ~(1UL << (CONFIG_OXNAS_I2C_SCL & 0x0000001F) );
++
++ *( (volatile unsigned long *) SYS_CTRL_GPIO_SECSEL_CTRL_0 ) &= ~(1UL << (CONFIG_OXNAS_I2C_SDA & 0x0000001F) );
++ *( (volatile unsigned long *) SYS_CTRL_GPIO_SECSEL_CTRL_0 ) &= ~(1UL << (CONFIG_OXNAS_I2C_SCL & 0x0000001F) );
++
++// Setting lines to Input
++/*
++temp = readl( GPIO_A_OUTPUT_ENABLE );
++temp |= (GPIO_TEST_SCL | GPIO_TEST_SDA | GPIO_TEST_SCS);
++writel( temp, GPIO_A_OUTPUT_ENABLE );
++for (i=0; i<65000; ++i)
++{
++ temp = (i & 0x00000007) << CONFIG_OXNAS_I2C_SCL;
++ flags = readl( GPIO_A_OUTPUT_VALUE );
++ flags &= ~(GPIO_TEST_SCL | GPIO_TEST_SDA | GPIO_TEST_SCS);
++ flags |= temp;
++ writel( flags, GPIO_A_OUTPUT_VALUE );
++ printk( "reads 0x%08x ",readl( GPIO_A_DATA ) );
++ udelay(100);
++ printk( " 0x%08x\n",readl( GPIO_A_DATA ) );
++
++}
++*/
++DumpGPIO();
++ // Setting lines to Input
++ temp = readl( GPIO_A_OUTPUT_ENABLE );
++ temp &= ~(GPIO_TEST_SCL | GPIO_TEST_SDA);
++ writel( temp, GPIO_A_OUTPUT_ENABLE );
++ udelay(1);
++ if ( *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE) & (1UL << CONFIG_OXNAS_I2C_SDA) ||
++ *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE) & (1UL << CONFIG_OXNAS_I2C_SCL))
++ {
++ printk( KERN_ERR "Test 1: Failed to clear GPIO Output Enable register)\n");
++ return -1;
++ }
++
++ udelay(1);
++ // read the input value: it should be one due to the pull up
++ if ( !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
++ !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) ))
++ {
++ printk( KERN_ERR "Test 1: Failed to read 1 on the input(check for pull up res.))\n");
++ return -1;
++ }
++
++ printk( KERN_ERR "===== Passed Test 1 ======= Created GPIO inputs, and read correct values\n");
++
++ // Test 2: set output using direct setting, first set the output latches to zero on all lines
++ printk( KERN_ERR "Test 2: output testing and OE testing\n");
++ *( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR ) |= (1UL << (CONFIG_OXNAS_I2C_SDA & 0x0000001F) );
++ *( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR ) |= (1UL << (CONFIG_OXNAS_I2C_SCL & 0x0000001F) );
++ for (i=CONFIG_OXNAS_I2C_SCL; i<=CONFIG_OXNAS_I2C_SDA; ++i)
++ {
++ // from all input, set output using direct write. Assume all input at start.
++ temp = readl( GPIO_A_OUTPUT_ENABLE );
++ temp |= ((0x00000001) << i);
++ writel( temp, GPIO_A_OUTPUT_ENABLE );
++
++ udelay(1);
++ if ( ( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
++ ( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) ))
++ {
++ printk( KERN_ERR "Test 2: Failed to read 0 on the %d input (output enabled with direct write.))\n", i);
++ return -1;
++ }
++
++ // Setting lines to Input
++ temp = readl( GPIO_A_OUTPUT_ENABLE );
++ temp &= ~(GPIO_TEST_SCL | GPIO_TEST_SDA);
++ writel( temp, GPIO_A_OUTPUT_ENABLE );
++
++ udelay(1);
++ if ( ( *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
++ ( *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE) & (1UL << CONFIG_OXNAS_I2C_SCL) ) ||
++ !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
++ !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) ) )
++ {
++ printk( KERN_ERR "Test 2: Failed to reset to clean state 1)\n");
++ return -1;
++ }
++
++ // from all inputs, set an output enable usign output enable set
++ *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_SET ) |= (1UL << i);
++
++ udelay(1);
++ if ( ( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
++ ( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) ) )
++ {
++ printk( KERN_ERR "Test 2: Failed to read 0 on the input %d (output enabled with direct write.))\n", i);
++ return -1;
++ }
++
++ // now exercise the setting and clearing of the output value
++ *( (volatile unsigned long *) GPIO_A_OUTPUT_SET ) |= (1UL << i);
++
++ udelay(1);
++ if ( !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
++ !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) ) )
++ {
++ printk( KERN_ERR "Test 2: Failed to read 1 on the input after settin %d ahs high)\n", i);
++ return -1;
++ }
++
++ // now exercise the setting and clearing of the output value
++ *( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR ) |= (1UL << i);
++
++ udelay(1);
++ if ( ( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
++ ( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) ) )
++ {
++ printk( KERN_ERR "Test 2: Failed to read 1 on the input after settin %d ahs high)\n", i);
++ return -1;
++ }
++
++ // from i as output, set all inputs , set an output enable usign output enable set
++ *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_CLEAR ) |= (1UL << i);
++
++ udelay(1);
++ if ( temp != readl( GPIO_A_OUTPUT_ENABLE ) ||
++ ( *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
++ ( *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE) & (1UL << CONFIG_OXNAS_I2C_SCL) ) ||
++ !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SDA) ) ||
++ !( *( (volatile unsigned long *) GPIO_A_DATA) & (1UL << CONFIG_OXNAS_I2C_SCL) ) )
++ {
++ printk( KERN_ERR "Test 2: Failed to reset to clean state 2)\n");
++ return -1;
++ }
++ }
++
++ printk( KERN_ERR "===== Passed Test 2 ======= Used all Set and clear methods for both OE and OV\n");
++
++ // Test 3, now exercise the interrupt.
++ printk( KERN_ERR "Test 3: Interrupt testing\n");
++ init_waitqueue_head(&ir_block);
++
++ request_irq(
++ (int) GPIO_1_INTERRUPT, // unsigned int irq,
++ &irqHandler, // irqreturn_t (*handler)(int, void *, struct pt_regs *),
++ IRQF_SHARED, // unsigned long irq_flags,
++ "GPIO Test Module", // const char * devname,
++ (void*) gpioTest_device ); // void * dev_id)
++
++
++ // set int condiiton....
++ for (i=CONFIG_OXNAS_I2C_SCL; i<=CONFIG_OXNAS_I2C_SDA; ++i)
++ {
++ int tmo;
++ int drv = i+1 > CONFIG_OXNAS_I2C_SDA ? CONFIG_OXNAS_I2C_SCL : i+1; // BHC - This is rubbish, there's no contract saying SDA has to be on a higher numbered GPIO than SCL
++
++
++ // ================================================= level detect
++ // set an interrupt on i being high-level
++ printk( KERN_INFO "Test %d level int High against OP %d\n", i, drv);
++ local_irq_save(flags);
++ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) |= (1UL << i);
++ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) &= ~(1UL << i);
++ *( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE ) |= (1UL << i);
++ *( (volatile unsigned long *) GPIO_A_INTERRUPT_EVENT ) |= (1UL << i);
++ gpioTest_device->found = 0;
++ local_irq_restore(flags);
++
++ tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
++printk("tmo1 == 0x%08x / 0x%08x\n", tmo, 1*HZ );
++ if ( !(gpioTest_device->found & ((0x00000001 << i))) )
++ {
++
++ printk( KERN_ERR "$R FAILED Test 3 timed out 1 sec with no interrupt "
++ "While waiting for level high int....\n");
++ return -1;
++ }
++
++ // Next try setting the lines low, and ensure that the devices times out
++ local_irq_save(flags);
++ *( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR ) |= (1UL << drv);
++ *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_SET ) |= (1UL << drv);
++ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) |= (1UL << i);
++ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) &= ~(1UL << i);
++ *( (volatile unsigned long *) GPIO_A_INTERRUPT_EVENT ) |= (1UL << i);
++ *( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE ) |= (1UL << i);
++ gpioTest_device->found = 0;
++
++ local_irq_restore(flags);
++ tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
++printk("tmo2 == 0x%08x\n", tmo );
++ if ( gpioTest_device->found )
++ {
++
++ printk( KERN_ERR "$R FAILED Test 3 did not timed out "
++ "While waiting for level high int with 0 input....\n");
++ return -1;
++ }
++
++ // set the int acive low level now.
++ printk( KERN_INFO "Test %d level int Low against OP %d\n", i, drv);
++ local_irq_save(flags);
++ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) &= ~(1UL << i);
++ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) |= (1UL << i);
++ *( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE ) |= (1UL << i);
++ *( (volatile unsigned long *) GPIO_A_INTERRUPT_EVENT ) |= (1UL << i);
++ gpioTest_device->found = 0;
++
++ local_irq_restore(flags);
++ tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
++printk("tmo3 == 0x%08x / 0x%08x\n", tmo, 1*HZ );
++ if ( !(gpioTest_device->found & ((0x00000001 << i))) )
++ {
++
++ printk( KERN_ERR "$R FAILED Test 3 timed out 1 sec with no interrupt "
++ "While waiting for level low int....\n");
++ return -1;
++ }
++
++ // Next try setting the lines high, and ensure that the devices times out
++ *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_CLEAR ) |= ~(1UL << drv);
++ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) &= ~(1UL << i);
++ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) |= (1UL << i);
++ *( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE ) |= (1UL << i);
++ *( (volatile unsigned long *) GPIO_A_INTERRUPT_EVENT ) |= (1UL << i);
++ gpioTest_device->found = 0;
++
++ local_irq_restore(flags);
++ tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
++printk("tmo4 == 0x%08x\n", tmo );
++ if ( gpioTest_device->found )
++ {
++
++ printk( KERN_ERR "$R FAILED Test 3 did not timed out "
++ "While waiting for level low int with 1 input....\n");
++ return -1;
++ }
++
++ // Setting lines to Input --------------------------------------
++ temp = readl( GPIO_A_OUTPUT_ENABLE );
++ temp &= ~(GPIO_TEST_SCL | GPIO_TEST_SDA);
++ writel( temp, GPIO_A_OUTPUT_ENABLE );
++ // ================================================= Edge detect
++
++ // set an interrupt on i being high-level
++ local_irq_save(flags);
++ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) |= (1UL << i);
++ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) &= ~(1UL << i);
++ *( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE ) &= ~(1UL << i);
++ *( (volatile unsigned long *) GPIO_A_INTERRUPT_EVENT ) |= (1UL << i);
++ gpioTest_device->found = 0;
++
++ printk( KERN_INFO "Test %d rising edge int High against falling edge on OP %d\n", i, drv);
++ local_irq_restore(flags);
++
++ *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_SET ) |= (1UL << drv);
++ *( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR ) |= (1UL << drv);
++ tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
++ if ( gpioTest_device->found || tmo )
++ {
++
++ printk( KERN_ERR "$R FAILED Test 3 found int on %d falling edge, when set to rising...\n", i);
++ return -1;
++ }
++
++ // now do th rising edge...
++ *( (volatile unsigned long *) GPIO_A_OUTPUT_SET ) |= (1UL << drv);
++
++ tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
++ if ( !(gpioTest_device->found & (0x00000001 << i)) || (tmo == 0) )
++ {
++
++ printk( KERN_ERR "$R FAILED Test 3 did not find int on %d rising edge, when set to rising...\n", i);
++ return -1;
++ }
++
++ // set the int acive low level now.
++ local_irq_save(flags);
++
++ *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_SET ) |= (1UL << drv);
++ *( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR ) |= (1UL << drv);
++
++ *( (volatile unsigned long *) GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE ) &= ~(1UL << i);
++ *( (volatile unsigned long *) GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE ) |= (1UL << i);
++ *( (volatile unsigned long *) GPIO_A_LEVEL_INTERRUPT_ENABLE ) &= ~(1UL << i);
++ *( (volatile unsigned long *) GPIO_A_INTERRUPT_EVENT ) |= (1UL << i);
++ gpioTest_device->found = 0;
++
++ printk( KERN_INFO "Test %d falling edge int against rising edge on OP %d\n", i, drv);
++ local_irq_restore(flags);
++
++ *( (volatile unsigned long *) GPIO_A_OUTPUT_ENABLE_SET ) |= (1UL << drv);
++ *( (volatile unsigned long *) GPIO_A_OUTPUT_SET ) |= (1UL << drv);
++ tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
++ if ( gpioTest_device->found || tmo )
++ {
++
++ printk( KERN_ERR "$R FAILED Test 3 found int on %d falling edge, when set to rising...\n", i);
++ return -1;
++ }
++
++ // now do th rising edge...
++ *( (volatile unsigned long *) GPIO_A_OUTPUT_CLEAR) |= (1UL << drv);
++
++ tmo = wait_event_interruptible_timeout(ir_block, gpioTest_device->found, 1*HZ);
++ if ( !(gpioTest_device->found & (0x00000001 << i)) || (tmo == 0) )
++ {
++
++ printk( KERN_ERR "$R FAILED Test 3 did not find int on %d rising edge, when set to rising...\n", i);
++ return -1;
++ }
++
++
++
++ // Setting lines to Input --------------------------------------
++ temp = readl( GPIO_A_OUTPUT_ENABLE );
++ temp &= ~(GPIO_TEST_SCL | GPIO_TEST_SDA);
++ writel( temp, GPIO_A_OUTPUT_ENABLE );
++ }
++
++
++ printk("$G All gpiuo tests passed.\n");
++
++ return 0;
++}
++
++
++/*
++Read callback:
++-> filp, contains the device in its private data
++-> buf, the buffer in userspace
++-> count, amount of that to be read
++-> f_pos, the starting point of the data
++-> return:number of bytes read
++*/
++ssize_t gpioTest_read(struct file *filp, char __user *buf, size_t count,loff_t *f_pos){
++// dev was stored in filp during the open call.
++// struct gpioTest_dev *dev = filp->private_data;
++
++ printk( KERN_ERR "gpioTest_read:\n");
++
++// Copy this quantum (from the offset, to the end of this quantum)
++// to userspace
++// if(copy_to_user(buf, dptr->data[s_pos] + q_pos, count)){
++// retval = -EFAULT;
++// goto out;
++// }
++
++// Update the file offset
++// *f_pos += count;
++// retval = count;
++// out:
++// up(&dev->sem);
++ return 0;
++}
++
++/*
++Write callback
++-> filp, contains the device in its private data
++-> buf, the buffer in userspace
++-> count, amount of that to be written
++-> f_pos, the starting point of the data
++-> return:number of bytes written
++*/
++ssize_t gpioTest_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos){
++
++// struct gpioTest_dev *dev = filp->private_data;
++
++ printk( KERN_ERR "gpioTest_write:\n");
++
++
++ // Copy the data to be written from userspace
++ // if(copy_from_user(dptr->data[s_pos]+q_pos, buf, count)){
++ // retval = -EFAULT;
++ // }
++ //
++ // *f_pos+=count;
++ // retval = count;
++
++ // Update the size
++ // if(dev->size < *f_pos){
++ // dev->size = *f_pos;
++ // }
++
++// out:
++ // up(&dev->sem);
++ return 0;
++}
++
++
++
++/*
++Release callback
++*/
++int gpioTest_release(struct inode *inode, struct file *filp)
++{
++ printk( KERN_ERR "gpioTest_release:\n");
++ return 0;
++}
++
++/*
++Open callback
++*/
++int gpioTest_open(struct inode *inode, struct file *filp){
++// struct gpioTest_dev *dev;
++
++ printk( KERN_ERR "gpioTest_open:\n");
++ // This macro takes a pointer to a field of type 'container_field', within
++ // a strcture of type 'container_type' and returns a pointer to the containing
++ // structure.
++ // dev = container_of(inode->i_cdev, struct gpioTest_dev, cdev);
++ // Store the pointer for future access
++ // filp->private_data = dev;
++
++ return 0;
++}
++
++
++
++
++//////////////////
++// MODULE STUFF //
++//////////////////
++
++// File operations for this charater device
++struct file_operations gpioTest_fops = {
++ .owner = THIS_MODULE,
++ //.llseek = gpioTest_llseek,
++ .read = gpioTest_read,
++ .write = gpioTest_write,
++ // .ioctl = gpioTest_ioctl,
++ .open = gpioTest_open,
++ .release = gpioTest_release,
++};
++
++
++/*
++ Module loading
++*/
++static int gpioTest_init(void){
++
++ // alloc_chrdev_region return 0 on success
++ int res = alloc_chrdev_region(
++ &dev,
++ 0,
++ 1,
++ "GPIOTest");
++
++ printk( KERN_ERR "gpioTest_init:\n");
++
++ if(res){
++ printk(KERN_WARNING "gpioTest: could not allocate device\n");
++ return res;
++ }else{
++ printk(KERN_WARNING "gpioTest: registered with major number:%i\n", MAJOR(dev));
++ }
++
++
++ // Allocate memory for gpioTest_COUNT gpioTest_devices
++ gpioTest_device = kmalloc(sizeof(struct gpioTest_dev), GFP_KERNEL);
++ if(gpioTest_device == NULL){
++ res = -ENOMEM;
++ goto fail;
++ }
++
++ // Fill the gpioTest_devices region with zeros
++ memset(gpioTest_device, 0, sizeof(struct gpioTest_dev));
++
++ // Initialise the devices
++
++ // Register the cdev, gpioTest_fops contains all the defined callbacks
++ cdev_init(&gpioTest_device->cdev,&gpioTest_fops);
++ gpioTest_device->cdev.owner = THIS_MODULE;
++ gpioTest_device->cdev.ops = &gpioTest_fops;
++ res = cdev_add(&gpioTest_device->cdev,MKDEV(MAJOR(dev), MINOR(dev)) ,1);
++ if(res){
++ printk(KERN_NOTICE "Error %d adding gpioTest\n", res);
++ }else{
++ printk(KERN_NOTICE "gpioTest added\n");
++ }
++
++ // perform a test
++ res = readl( GPIO_A_INPUT_DEBOUNCE_ENABLE );
++ res &= ~(GPIO_TEST_SCL | GPIO_TEST_SDA);
++ writel( res, GPIO_A_INPUT_DEBOUNCE_ENABLE );
++ if ( gpioTest_go() )
++ {
++ DumpGPIO();
++ }
++
++ // perform a test again with debounce.
++ res = readl( GPIO_A_INPUT_DEBOUNCE_ENABLE );
++ res |= (GPIO_TEST_SCL | GPIO_TEST_SDA);
++ writel( res, GPIO_A_INPUT_DEBOUNCE_ENABLE );
++ if ( gpioTest_go() )
++ {
++ DumpGPIO();
++ }
++
++
++
++ return 0;
++
++fail:
++ // do cleanup;
++ return res;
++}
++
++
++/*
++ Module unloading
++*/
++static void gpioTest_exit(void){
++ // Free the devices
++ printk( KERN_ERR "gpioTest_exit:\n");
++ cdev_del(&gpioTest_device->cdev);
++ kfree(gpioTest_device);
++ gpioTest_device = NULL;
++ unregister_chrdev_region(dev,1);
++}
++
++module_init(gpioTest_init);
++module_exit(gpioTest_exit);
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/i2s.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/i2s.c
+--- linux-2.6.24/arch/arm/mach-oxnas/i2s.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/i2s.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,352 @@
++/*
++ * procfs3.c - create a "file" in /proc, use the file_operation way
++ * to manage the file.
++ */
++
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/kernel.h> /* We're doing kernel work */
++#include <linux/module.h> /* Specifically, a module */
++#include <linux/proc_fs.h> /* Necessary because we use proc fs */
++#include <asm/uaccess.h> /* for copy_*_user */
++#include "asm/arch-oxnas/i2s.h"
++#include "asm/io.h"
++
++#define DRV_NAME "i2s"
++#define DRV_VERSION "0.1"
++#define PROC_ENTRY_FILENAME "i2s"
++#define PROCFS_MAX_SIZE 2048
++
++
++
++MODULE_AUTHOR("Chris Ford");
++MODULE_DESCRIPTION("I2S Test module");
++MODULE_LICENSE("GPL");
++MODULE_VERSION(DRV_VERSION);
++
++/**
++ * The buffer (2k) for this module
++ *
++ */
++static char procfs_buffer[PROCFS_MAX_SIZE];
++
++/**
++ * The size of the data hold in the buffer
++ *
++ */
++static unsigned long procfs_buffer_size = 0;
++
++/**
++ * The structure keeping information about the /proc file
++ *
++ */
++static struct proc_dir_entry *Our_Proc_File;
++
++
++void RefreshI2SRegisters(void)
++{
++ int iLen = sprintf( procfs_buffer,
++ "DumpI2SRegisters----------------------------------\n"
++ " \n"
++ " TX_CONTROL = 0x%08x\n"
++ " TX_SETUP = 0x%08x\n"
++ " TX_SETUP1 = 0x%08x\n"
++ " TX_STATUS = 0x%08x\n"
++ " RX_CONTROL = 0x%08x\n"
++ " RX_SETUP = 0x%08x\n"
++ " RX_SETUP1 = 0x%08x\n"
++ " RX_STATUS = 0x%08x\n"
++ " TX_DEBUG = 0x%08x\n"
++ " TX_DEBUG2 = 0x%08x\n"
++ " TX_DEBUG3 = 0x%08x\n"
++ " RX_DEBUG_ = 0x%08x\n"
++ " RX_DEBUG2 = 0x%08x\n"
++ " RX_DEBUG3 = 0x%08x\n"
++ " TX_BUFFER_LEVEL = 0x%08x\n"
++ " TX_BUFFER_INTERRUPT_LEVEL = 0x%08x\n"
++ " RX_BUFFER_LEVEL = 0x%08x\n"
++ " RX_BUFFER_INTERRUPT_LEVEL = 0x%08x\n"
++ " RX_SPDIF_DEBUG = 0x%08x\n"
++ " RX_SPDIF_DEBUG2 = 0x%08x\n",
++ (u32) __raw_readl( TX_CONTROL ),
++ (u32) __raw_readl( TX_SETUP ),
++ (u32) __raw_readl( TX_SETUP1 ),
++ (u32) __raw_readl( TX_STATUS ),
++ (u32) __raw_readl( RX_CONTROL ),
++ (u32) __raw_readl( RX_SETUP ),
++ (u32) __raw_readl( RX_SETUP1 ),
++ (u32) __raw_readl( RX_STATUS ),
++ (u32) __raw_readl( TX_DEBUG ),
++ (u32) __raw_readl( TX_DEBUG2 ),
++ (u32) __raw_readl( TX_DEBUG3 ),
++ (u32) __raw_readl( RX_DEBUG_ ),
++ (u32) __raw_readl( RX_DEBUG2 ),
++ (u32) __raw_readl( RX_DEBUG3 ),
++ (u32) __raw_readl( TX_BUFFER_LEVEL ),
++ (u32) __raw_readl( TX_BUFFER_INTERRUPT_LEVEL ),
++ (u32) __raw_readl( RX_BUFFER_LEVEL ),
++ (u32) __raw_readl( RX_BUFFER_INTERRUPT_LEVEL ),
++ (u32) __raw_readl( RX_SPDIF_DEBUG ),
++ (u32) __raw_readl( RX_SPDIF_DEBUG2 ) );
++
++ procfs_buffer_size = iLen + sprintf( procfs_buffer + iLen,
++ " INTERRUPT_CONTROL_STATUS = 0x%08x\n"
++ " INTERRUPT_MASK = 0x%08x\n"
++ " VERSION = 0x%08x\n"
++ " TX_DATA_IN_FORMAT = 0x%08x\n"
++ " TX_CHANNELS_ENABLE = 0x%08x\n"
++ " TX_WRITES_TO = 0x%08x\n"
++ " RX_DATA_OUT_FORMAT = 0x%08x\n"
++ " RX_CHANNELS_ENABLE = 0x%08x\n"
++ " RX_READS_FROM = 0x%08x\n"
++ " TX_CPU_DATA_WRITES_ALT = 0x%08x\n"
++ " RX_CPU_DATA_READS_ALT = 0x%08x\n"
++ " TX_CPU_DATA_WRITES = 0x%08x\n"
++ " RX_CPU_DATA_READS = 0x%08x\n"
++ "\n"
++ "--------------------------------------------------\n",
++ (u32) __raw_readl( INTERRUPT_CONTROL_STATUS ),
++ (u32) __raw_readl( INTERRUPT_MASK ),
++ (u32) __raw_readl( VERSION ),
++ (u32) __raw_readl( TX_DATA_IN_FORMAT ),
++ (u32) __raw_readl( TX_CHANNELS_ENABLE ),
++ (u32) __raw_readl( TX_WRITES_TO ),
++ (u32) __raw_readl( RX_DATA_OUT_FORMAT ),
++ (u32) __raw_readl( RX_CHANNELS_ENABLE ),
++ (u32) __raw_readl( RX_READS_FROM ),
++ (u32) __raw_readl( TX_CPU_DATA_WRITES_ALT ),
++ (u32) __raw_readl( RX_CPU_DATA_READS_ALT ),
++ (u32) __raw_readl( TX_CPU_DATA_WRITES ),
++ (u32) __raw_readl( RX_CPU_DATA_READS ) );
++}
++
++
++void DumpI2SRegisters(void)
++{
++ RefreshI2SRegisters();
++ printk( KERN_INFO "%s", procfs_buffer );
++ return;
++}
++
++
++/**
++ * This funtion is called when the /proc file is read
++ *
++ */
++static ssize_t procfs_read(
++ struct file *filp, /* see include/linux/fs.h */
++ char *buffer, /* buffer to fill with data */
++ size_t length, /* length of the buffer */
++ loff_t * offset)
++{
++ static int finished = 0;
++
++ /*
++ * We return 0 to indicate end of file, that we have
++ * no more information. Otherwise, processes will
++ * continue to read from us in an endless loop.
++ */
++ if ( finished ) {
++ printk(KERN_INFO "procfs_read: END\n");
++ finished = 0;
++ return 0;
++ }
++
++ finished = 1;
++
++ /*
++ * We use put_to_user to copy the string from the kernel's
++ * memory segment to the memory segment of the process
++ * that called us. get_from_user, BTW, is
++ * used for the reverse.
++ */
++ if ( copy_to_user(buffer, procfs_buffer, procfs_buffer_size) ) {
++ return -EFAULT;
++ }
++
++ printk(KERN_INFO "procfs_read: read %lu bytes\n", procfs_buffer_size);
++
++ return procfs_buffer_size; /* Return the number of bytes "read" */
++}
++
++/*
++ * This function is called when /proc is written
++ */
++static ssize_t
++procfs_write(struct file *file, const char *buffer, size_t len, loff_t * off)
++{
++ if ( len > PROCFS_MAX_SIZE ) {
++ procfs_buffer_size = PROCFS_MAX_SIZE;
++ }
++ else {
++ procfs_buffer_size = len;
++ }
++
++ if ( copy_from_user(procfs_buffer, buffer, procfs_buffer_size) ) {
++ return -EFAULT;
++ }
++
++ printk(KERN_INFO "procfs_write: write %s\n",buffer);
++ printk(KERN_INFO "procfs_write: write %lu bytes\n", procfs_buffer_size);
++
++ return procfs_buffer_size;
++}
++
++/*
++ * This function decides whether to allow an operation
++ * (return zero) or not allow it (return a non-zero
++ * which indicates why it is not allowed).
++ *
++ * The operation can be one of the following values:
++ * 0 - Execute (run the "file" - meaningless in our case)
++ * 2 - Write (input to the kernel module)
++ * 4 - Read (output from the kernel module)
++ *
++ * This is the real function that checks file
++ * permissions. The permissions returned by ls -l are
++ * for referece only, and can be overridden here.
++ */
++
++static int module_permission(struct inode *inode, int op, struct nameidata *foo)
++{
++ /*
++ * We allow everybody to read from our module, but
++ * only root (uid 0) may write to it
++ */
++ if (op == 4 || (op == 2 && current->euid == 0)) {
++ printk( KERN_INFO "Insufficient permissions\n");
++ return 0;
++ }
++
++ /*
++ * If it's anything else, access is denied
++ */
++ return -EACCES;
++}
++
++/*
++ * The file is opened - we don't really care about
++ * that, but it does mean we need to increment the
++ * module's reference count.
++ */
++int procfs_open(struct inode *inode, struct file *file)
++{
++ u32 temp = 0;
++
++ /* Open an entry on the proc filesystem */
++ printk(KERN_INFO "I2S::procfs_open\n");
++ try_module_get(THIS_MODULE);
++
++ // printk(KERN_INFO "I2S::pre-reg set..\n");
++ // RefreshI2SRegisters();
++
++ /* Setup the I2S TX Core... */
++ temp = 1 << TX_CONTROL_ENABLE |
++ 1 << TX_CONTROL_FLUSH |
++ 0 << TX_CONTROL_MUTE |
++ 0 << TX_CONTROL_TRICK |
++ 0 << TX_CONTROL_SPEED |
++ 1 << TX_CONTROL_ABORT_DMA |
++ 0 << TX_CONTROL_AHB_ENABLE |
++ 1 << TX_CONTROL_QUAD_BURSTS;
++ __raw_writel( temp, TX_CONTROL );
++
++ temp = TRUE_I2S << TX_SETUP_FORMAT |
++ I2S_SLAVE << TX_SETUP_MODE |
++ 0 << TX_SETUP_FLOW_INVERT |
++ 0 << TX_SETUP_POS_EDGE |
++ 0 << TX_SETUP_CLOCK_STOP |
++ 0 << TX_SETUP_SPLIT_QUAD |
++ 0 << TX_SETUP_SPDIF_EN;
++ __raw_writel( temp, TX_SETUP );
++
++ temp = TWOS_COMPLIMENT << TX_SETUP1_INPUT |
++ 0 << TX_SETUP1_REVERSE |
++ 0 << TX_SETUP1_INVERT |
++ 0 << TX_SETUP1_BIG_ENDIAN |
++ 0 << TX_SETUP1_QUAD_ENDIAN |
++ 0 << TX_SETUP1_QUAD_SAMPLES |
++ 0 << TX_SETUP1_FLOW_CONTROL;
++ __raw_writel( temp, TX_SETUP1 );
++
++ /* Setup the I2S RX Core... */
++
++ printk(KERN_INFO "\n\nI2S::post-reg set..\n");
++ RefreshI2SRegisters();
++ return 0;
++}
++
++/*
++ * The file is closed - again, interesting only because
++ * of the reference count.
++ */
++int procfs_close(struct inode *inode, struct file *file)
++{
++ printk(KERN_INFO "I2S::procfs_close\n");
++ module_put(THIS_MODULE);
++ return 0; /* success */
++}
++
++static struct file_operations File_Ops_4_Our_Proc_File = {
++ .read = procfs_read,
++ .write = procfs_write,
++ .open = procfs_open,
++ .release = procfs_close,
++};
++
++/*
++ * Inode operations for our proc file. We need it so
++ * we'll have some place to specify the file operations
++ * structure we want to use, and the function we use for
++ * permissions. It's also possible to specify functions
++ * to be called for anything else which could be done to
++ * an inode (although we don't bother, we just put
++ * NULL).
++ */
++
++static struct inode_operations Inode_Ops_4_Our_Proc_File = {
++ .permission = module_permission, /* check for permissions */
++};
++
++/*
++ * Module initialization and cleanup
++ */
++static int __init oxnas_i2s_init_module(void)
++{
++ printk(KERN_INFO "I2S::init_module\n");
++
++ /* create the /proc file */
++ Our_Proc_File = create_proc_entry(PROC_ENTRY_FILENAME, 0644, NULL);
++
++ /* check if the /proc file was created successfuly */
++ if (Our_Proc_File == NULL){
++ printk(KERN_ALERT "Error: Could not initialize /proc/%s\n",
++ PROC_ENTRY_FILENAME);
++ return -ENOMEM;
++ }
++
++ Our_Proc_File->owner = THIS_MODULE;
++ Our_Proc_File->proc_iops = &Inode_Ops_4_Our_Proc_File;
++ Our_Proc_File->proc_fops = &File_Ops_4_Our_Proc_File;
++ Our_Proc_File->mode = S_IFREG | S_IRUGO | S_IWUSR;
++ Our_Proc_File->uid = 0;
++ Our_Proc_File->gid = 0;
++ Our_Proc_File->size = 80;
++
++ printk(KERN_INFO "/proc/%s created\n", PROC_ENTRY_FILENAME);
++
++ return 0; /* success */
++}
++
++static void __exit oxnas_i2s_cleanup_module(void)
++{
++ printk(KERN_INFO "I2S::cleanup_module\n");
++ remove_proc_entry(PROC_ENTRY_FILENAME, &proc_root);
++ printk(KERN_INFO "/proc/%s removed\n", PROC_ENTRY_FILENAME);
++}
++
++module_init(oxnas_i2s_init_module);
++module_exit(oxnas_i2s_cleanup_module);
++
++
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/irq.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/irq.c
+--- linux-2.6.24/arch/arm/mach-oxnas/irq.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/irq.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,59 @@
++/*
++ * linux/arch/arm/mach-oxnas/irq.c
++ *
++ * 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 <linux/init.h>
++#include <linux/list.h>
++#include <asm/hardware.h>
++#include <asm/irq.h>
++#include <asm/mach/irq.h>
++
++static void OXNAS_mask_irq(unsigned int irq)
++{
++ *((volatile unsigned long*)(RPS_IRQ_DISABLE)) = (1UL << irq);
++}
++
++static void OXNAS_unmask_irq(unsigned int irq)
++{
++ *((volatile unsigned long*)RPS_IRQ_ENABLE) = (1UL << irq);
++}
++
++static struct irq_chip OXNAS_chip = {
++ .name = "OXNAS",
++ .ack = OXNAS_mask_irq,
++ .mask = OXNAS_mask_irq,
++ .unmask = OXNAS_unmask_irq,
++};
++
++void __init oxnas_init_irq(void)
++{
++ unsigned irq;
++
++ // Disable all IRQs
++ *((volatile unsigned long*)(RPS_IRQ_DISABLE)) = ~0UL;
++
++ // Disable FIQ
++ *((volatile unsigned long*)(RPS_FIQ_DISABLE)) = ~0UL;
++
++ // Initialise IRQ tracking structures
++ for (irq=0; irq < NR_IRQS; irq++)
++ {
++ set_irq_chip(irq, &OXNAS_chip);
++ set_irq_handler(irq, handle_level_irq);
++ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
++ }
++}
++
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/leds.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/leds.c
+--- linux-2.6.24/arch/arm/mach-oxnas/leds.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/leds.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,212 @@
++/*
++ * linux/arch/arm/mach-oxnas/leds.c
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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
++ */
++#define DEBUG
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/timer.h>
++#include <linux/interrupt.h>
++
++#include <linux/platform_device.h>
++
++
++#include <linux/leds.h>
++
++#include <asm/hardware.h>
++
++#define DEBUG_PRINT(A) printk(KERN_NOTICE A)
++
++#define writel(data,address) (*(volatile u32 *) address = data)
++#define readl(address) (*(volatile u32 *) address)
++
++/* run pwm refresh at approximately 100Hz to avoid flicker */
++/* resolution is 8bits, sys clock 200MHz divider is therefore 7812 less 1 cycle */
++#define PWM_PERIOD (7811)
++
++#define MAX_PWMS 16
++
++static void ramp_power_on_leds(unsigned long data);
++
++DEFINE_TIMER (power_ramp_timer, ramp_power_on_leds, 0, 0);
++
++enum { POWER_ON,
++ NUMBER_LEDS};
++
++static struct platform_device *oxnas_leds;
++static u16 offset[NUMBER_LEDS] = {25};
++
++static u16 led [NUMBER_LEDS];
++
++#define MAX_BRIGHTNESS 255
++
++static void set_led(u16 led, u16 value)
++{
++ u16 led_index = offset[led] % MAX_PWMS;
++
++ writel(value, (PWM_DATA_REGISTER_BASE+4*led_index));
++
++}
++
++static void ramp_power_on_leds(unsigned long data)
++{
++ if (led[POWER_ON] < MAX_BRIGHTNESS) {
++ set_led(POWER_ON, ++led[POWER_ON]);
++ mod_timer(&power_ramp_timer, (power_ramp_timer.expires + msecs_to_jiffies(64)) );
++ }
++ else del_timer(&power_ramp_timer);
++}
++
++static void oxnasled_power_on_set(struct led_classdev *led_cdev, enum led_brightness value)
++{
++ if (value == 0) {
++ current_bright = 0;
++ led[POWER_ON]=0;
++ set_led(POWER_ON, 0);
++
++ }
++ else
++ {
++ power_ramp_timer.expires = jiffies + msecs_to_jiffies(64);
++ add_timer(&power_ramp_timer);
++ }
++}
++
++static struct led_classdev oxnas_power_on_led = {
++ .name = "oxnas:power_on",
++ .brightness_set = oxnasled_power_on_set,
++};
++
++
++#ifdef CONFIG_PM
++
++// TODO implement led suspend operation on NAS
++static int oxnasled_suspend(struct platform_device *dev, pm_message_t state)
++{
++#ifdef CONFIG_LEDS_TRIGGERS
++ if (oxnas_amber_led.trigger && strcmp(oxnas_amber_led.trigger->name, "sharpsl-charge"))
++#endif
++ led_classdev_suspend(&oxnas_amber_led);
++ led_classdev_suspend(&oxnas_green_led);
++ return 0;
++}
++// TODO implement led resume operation on NAS
++static int oxnasled_resume(struct platform_device *dev)
++{
++ led_classdev_resume(&oxnas_amber_led);
++ led_classdev_resume(&oxnas_green_led);
++ return 0;
++}
++#endif
++
++static int oxnasled_probe(struct platform_device *pdev)
++{
++ int ret;
++ int i;
++
++ writel(PWM_PERIOD, PWM_CLOCK_REGISTER);
++
++
++ /* enable PWM drives outputs */
++ for (i=0; i < NUMBER_LEDS ; ++i)
++ {
++ if (offset[i] < 32) {
++ writel(readl(SYS_CTRL_GPIO_PWMSEL_CTRL_0) | (1 << offset[i]), SYS_CTRL_GPIO_PWMSEL_CTRL_0);
++ }
++ else {
++ writel(readl(SYS_CTRL_GPIO_PWMSEL_CTRL_1) | (1 << (offset[i]% 32)), SYS_CTRL_GPIO_PWMSEL_CTRL_1);
++ }
++ }
++
++ ret = led_classdev_register(&pdev->dev, &oxnas_power_on_led);
++
++ if (ret < 0) goto error_1;
++
++ return ret;
++
++error_1:
++ return ret;
++}
++
++static int oxnasled_remove(struct platform_device *pdev)
++{
++ int i;
++
++ led_classdev_unregister(&oxnas_power_on_led);
++
++ /* disable PWM drives outputs */
++ for (i=0; i < NUMBER_LEDS ; ++i)
++ {
++ if (offset[i] < 32) {
++ writel(readl(SYS_CTRL_GPIO_PWMSEL_CTRL_0) & ~((u32)1 << offset[i]), SYS_CTRL_GPIO_PWMSEL_CTRL_0);
++ }
++ else {
++ writel(readl(SYS_CTRL_GPIO_PWMSEL_CTRL_1) & ~((u32)1 << (offset[i]% 32)), SYS_CTRL_GPIO_PWMSEL_CTRL_1);
++ }
++ }
++
++ writel(PWM_CLOCK_REGISTER, 0);
++
++ return 0;
++}
++
++
++static struct platform_driver oxnasled_driver = {
++ .probe = oxnasled_probe,
++ .remove = oxnasled_remove,
++#ifdef CONFIG_PM
++ .suspend = oxnasled_suspend,
++ .resume = oxnasled_resume,
++#endif
++ .driver = {
++ .name = "oxnas-leds",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init oxnasled_init(void)
++{
++ int ret;
++
++ ret = platform_driver_register(&oxnasled_driver);
++
++
++
++ /* now register the devices on the bus so they can be associated with the driver */
++ if (!ret)
++ oxnas_leds=platform_device_register_simple("oxnas-leds", -1, NULL, 0);
++ return ret;
++}
++
++static void __exit oxnasled_exit(void)
++{
++ if (oxnas_leds) {
++ platform_device_unregister(oxnas_leds);
++ }
++
++ platform_driver_unregister(&oxnasled_driver);
++}
++
++module_init(oxnasled_init);
++module_exit(oxnasled_exit);
++
++MODULE_AUTHOR("John Larkworthy <john.larkworthy@oxsem.com");
++MODULE_DESCRIPTION("OXNAS front panel LED driver");
++MODULE_LICENSE("GPL");
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/ledtrig_sata.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/ledtrig_sata.c
+--- linux-2.6.24/arch/arm/mach-oxnas/ledtrig_sata.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/ledtrig_sata.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,69 @@
++/*
++ * linux/arch/arm/mach-oxnas/leds.c
++ *
++ * Copyright (C) 2006 Oxford Semiconductor Ltd
++ *
++ * 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 <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/timer.h>
++#include <linux/leds.h>
++
++static void ledtrig_ide_timerfunc(unsigned long data);
++
++DEFINE_LED_TRIGGER(ledtrig_ide);
++static DEFINE_TIMER(ledtrig_ide_timer, ledtrig_ide_timerfunc, 0, 0);
++static int ide_activity;
++static int ide_lastactivity;
++
++void ledtrig_sata_activity(void)
++{
++ ide_activity++;
++ if (!timer_pending(&ledtrig_ide_timer))
++ mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
++}
++EXPORT_SYMBOL(ledtrig_sata_activity);
++
++static void ledtrig_ide_timerfunc(unsigned long data)
++{
++ if (ide_lastactivity != ide_activity) {
++ ide_lastactivity = ide_activity;
++ led_trigger_event(ledtrig_ide, LED_FULL);
++ mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
++ } else {
++ led_trigger_event(ledtrig_ide, LED_OFF);
++ }
++}
++
++static int __init ledtrig_ide_init(void)
++{
++ led_trigger_register_simple("sata-disk", &ledtrig_ide);
++ return 0;
++}
++
++static void __exit ledtrig_ide_exit(void)
++{
++ led_trigger_unregister_simple(ledtrig_ide);
++}
++
++module_init(ledtrig_ide_init);
++module_exit(ledtrig_ide_exit);
++
++MODULE_AUTHOR("John Larkworthy <john.larkworthy@oxnas.com>");
++MODULE_DESCRIPTION("LED SATA Disk Activity Trigger");
++MODULE_LICENSE("GPL");
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/leon.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/leon.c
+--- linux-2.6.24/arch/arm/mach-oxnas/leon.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/leon.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,244 @@
++/*
++ * linux/arch/arm/mach-oxnas/leon.c
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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
++ */
++#ifdef CONFIG_SUPPORT_LEON
++
++#include <asm/io.h>
++#include <asm/types.h>
++#include <asm/arch/hardware.h>
++#include <linux/ctype.h>
++#include <linux/delay.h>
++#include <linux/dma-mapping.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <asm/arch/leon.h>
++
++static u8 asciihex_to_decimal(u8 ascii)
++{
++ return isdigit(ascii) ? (ascii - '0') : (isalpha(ascii) ? ((toupper(ascii) - 'A') + 10) : 0);
++}
++
++static u8 srec_read_u8(const s8** srec)
++{
++ u8 first_ascii = **srec;
++ u8 second_ascii = *++*srec;
++ ++*srec;
++ return ((asciihex_to_decimal(first_ascii) << 4) | asciihex_to_decimal(second_ascii));
++}
++
++static u32 srec_read_u32(const s8** srec)
++{
++ u32 word = ((u32)srec_read_u8(srec) << 24);
++ word |= ((u32)srec_read_u8(srec) << 16);
++ word |= ((u16)srec_read_u8(srec) << 8);
++ word |= srec_read_u8(srec);
++ return word;
++}
++
++static void skip_to_next_record(const s8** srec)
++{
++ while (*++*srec != '\n');
++ ++*srec;
++}
++
++/**
++ * @param srec An const s8** pointing to the position in the input s-record
++ * array at which to begin parsing
++ * @param buf An u8* into which any extracted record in to be placed
++ * @param adr An u8** into which either the extracted record's load address is
++ * to be written, or the execution start address
++ * @param len An u8* into which the length in bytes of the extracted record is
++ * to be written
++ * @return An int which is zero if another record is available, else if non-zero
++ * indicated that the execution start address is available in the
++ * adr argument
++ */
++static void read_record(u8 len, const s8** srec, u8* buf)
++{
++ int quads = len/sizeof(u32);
++ int spare = len - (quads*sizeof(u32));
++
++ int i=0;
++ while (i < quads) {
++ ((u32*)buf)[i++] = srec_read_u32(srec);
++ }
++ i = len-spare;
++ while (i < len) {
++ buf[i++] = srec_read_u8(srec);
++ }
++}
++
++static int get_next_record(const s8** srec, u8* buf, u8** adr, u8* len)
++{
++ int again;
++ int last = 1;
++
++ *adr = 0;
++ do {
++ again = 0;
++ if (**srec == 'S') {
++ switch (*++*srec) {
++ case '0':
++ skip_to_next_record(srec);
++ again = 1;
++ break;
++ case '3':
++ ++*srec;
++ *len = srec_read_u8(srec) - sizeof(u32) - 1;
++ *adr = (u8*)srec_read_u32(srec);
++ read_record(*len, srec, buf);
++ skip_to_next_record(srec);
++ last = 0;
++ break;
++ case '7':
++ ++*srec;
++ *len = srec_read_u8(srec) - 1;
++ if (*len >= sizeof(u32)) {
++ *adr = (u8*)srec_read_u32(srec);
++ }
++ break;
++ default:
++ break;
++ }
++ }
++ } while (again);
++
++ return last;
++}
++
++static const u32 ENDIAN_LITTLE_READ_BIT = 30;
++static const u32 ENDIAN_BIG_WRITE_BIT = 31;
++
++static u8* convert_adr_to_virt(u8* adr)
++{
++ static const u32 ARM_HIGH_ORDER_ADR_BIT = 30;
++
++ u32 virt = (u32)adr;
++
++ // Zero the Leon endian control bits
++ virt &= ~((1UL << ENDIAN_BIG_WRITE_BIT) | (1UL << ENDIAN_LITTLE_READ_BIT));
++
++ // Convert to an ARM physical address
++ virt |= (1UL << ARM_HIGH_ORDER_ADR_BIT);
++
++ // Is address sane?
++ if (virt < LEON_IMAGE_BASE_PA) {
++ panic("CoPro SRAM load address 0x%08x below mapped region beginning at 0x%08lx\n", (u32)adr, LEON_IMAGE_BASE_PA);
++ } else {
++ virt -= LEON_IMAGE_BASE_PA;
++ virt += LEON_IMAGE_BASE;
++ }
++
++ return (u8*)virt;
++}
++
++static void leon_load_image(const s8 *srec)
++{
++ u8 *buf;
++ u8 *adr;
++ u8 len;
++ u32 code_base;
++
++ // Copy each record to the specified address
++ // Convert the LEON physical address to an ARM virtual address before
++ // attempting to get the ARM to access it
++ // NB must endian-swap any trailing non-quad multiple bytes, as LEON will
++ // expect its instruction data in big endian format, whereas the ARM is
++ // little endian
++ buf = kmalloc(512, GFP_KERNEL);
++ while (!get_next_record(&srec, buf, &adr, &len)) {
++ int i=0;
++ int quads = len/sizeof(u32);
++ int spare = len - (quads*sizeof(u32));
++ int padded_len = len+(sizeof(u32)-spare);
++ u32* quad_ptr;
++
++ adr = convert_adr_to_virt(adr);
++
++ quad_ptr = (u32*)adr;
++ while (i < quads) {
++ *quad_ptr++ = ((u32*)buf)[i++];
++ }
++ adr = (u8*)quad_ptr;
++ for (i=len; i < padded_len; i++) {
++ buf[i] = 0;
++ }
++ i = padded_len-1;
++ while (i >= (len-spare)) {
++ *adr++ = buf[i--];
++ }
++ }
++ kfree(buf);
++
++ // Start LEON execution at the address specified by the S-records, with
++ // correct endianess. Use the address unchanged, as the LEON required
++ // physical addresses and may make use of alternative upper nibble values
++ code_base = (((u32)adr & ~((1UL << ENDIAN_BIG_WRITE_BIT) | (1UL << ENDIAN_LITTLE_READ_BIT))) | (1UL << ENDIAN_BIG_WRITE_BIT));
++
++ // Set the LEON's start address
++ printk(KERN_NOTICE "CoPro: Programming start address as 0x%08x (basic adr = 0x%08x)\n", code_base, (u32)adr);
++ writel(code_base, SYS_CTRL_COPRO_CTRL);
++
++ // Ensure start address has been loaded before release the LEON from reset
++ wmb();
++}
++
++void init_copro(const s8 *srec, unsigned long arg)
++{
++ // Ensure the LEON is in reset
++ writel(1UL << SYS_CTRL_RSTEN_COPRO_BIT, SYS_CTRL_RSTEN_SET_CTRL);
++
++ // Enable the clock to the LEON
++ writel(1UL << SYS_CTRL_CKEN_COPRO_BIT, SYS_CTRL_CKEN_SET_CTRL);
++
++ // Ensure reset and clock operations are complete
++ wmb();
++
++ // Place LEON context argument in top quad of SRAM
++ *((u32*)(LEON_IMAGE_BASE+LEON_IMAGE_SIZE-sizeof(u32))) = arg;
++
++ // Load LEON's program and data and execution start address
++ leon_load_image(srec);
++
++ // Release the LEON from reset so it begins execution of the loaded code
++ writel(1UL << SYS_CTRL_RSTEN_COPRO_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
++
++ // Give the LEON a chance to stabilise before giving it any commands
++ mdelay(100);
++ return;
++}
++EXPORT_SYMBOL_GPL(init_copro);
++
++void shutdown_copro(void)
++{
++ // Ensure the LEON is in reset
++ writel(1UL << SYS_CTRL_RSTEN_COPRO_BIT, SYS_CTRL_RSTEN_SET_CTRL);
++
++ // Disable the clock to the LEON
++ writel(1UL << SYS_CTRL_CKEN_COPRO_BIT, SYS_CTRL_CKEN_CLR_CTRL);
++
++ // Ensure reset and clock operations are complete
++ wmb();
++}
++EXPORT_SYMBOL_GPL(shutdown_copro);
++
++#endif // CONFIG_SUPPORT_LEON
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/oxnas-ahb-monitor.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/oxnas-ahb-monitor.c
+--- linux-2.6.24/arch/arm/mach-oxnas/oxnas-ahb-monitor.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/oxnas-ahb-monitor.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,374 @@
++/*
++ * arch/arm/mach-oxnas/oxnas-ahb-monitor.c
++ *
++ * Copyright (C) 2006 Oxford Semiconductor Ltd
++ *
++ * 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 <linux/types.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/miscdevice.h>
++#include <linux/smp_lock.h>
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/sched.h>
++#include <linux/i2c.h>
++#include <linux/proc_fs.h>
++#include <linux/capability.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/spinlock.h>
++#include <linux/smp_lock.h>
++#include <linux/wait.h>
++#include <linux/suspend.h>
++#include <linux/kthread.h>
++#include <linux/moduleparam.h>
++
++#include <asm/io.h>
++#include <asm/system.h>
++#include <asm/sections.h>
++#include <asm/uaccess.h>
++#include <asm/bitops.h>
++
++#include <asm/hardware.h>
++
++
++/* usb test masks and offsets */
++#define TEST_MASK 0xF
++#define TEST_OFFSET 16
++
++#define MODULE_VERS "0.1"
++#define MODULE_NAME "oxnas-test"
++MODULE_AUTHOR( "John Larkworthy" );
++MODULE_DESCRIPTION( "Driver to access the test hardware in oxnas units" );
++MODULE_LICENSE( "GPL" );
++
++
++static struct proc_dir_entry *proc_dir_usb_test_read, *oxnas_test_dir;
++
++
++static struct {
++ void * address;
++ char * name;
++ long unsigned low_add;
++ long unsigned high_add;
++ unsigned burst;
++ unsigned burst_mask;
++ unsigned hprot;
++ unsigned hprot_mask;
++ unsigned mode;
++} monitor[] =
++{
++ { (void *) 0x00000, "ARM_Data", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
++ { (void *) 0x10000, "Arm_Inst", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
++ { (void *) 0x20000, "DMA_A", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
++ { (void *) 0x30000, "DMA_B", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
++ { (void *) 0x40000, "CoPro", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
++ { (void *) 0x50000, "USBHS", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
++ { (void *) 0x60000, "GMAC", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 },
++ { (void *) 0x70000, "PCI", 0, 0xFFFFFFFFl, 0, 0, 0, 0, 0 }
++};
++#define NO_MONITORS (sizeof(monitor)/sizeof(monitor[0]))
++
++/* create proc filing system entries to accept configuration data */
++static int usb_test_write_entries(const char *name, write_proc_t *w, read_proc_t *r, int data)
++{
++ struct proc_dir_entry * entry = create_proc_entry(name, 0222, oxnas_test_dir);
++ if (entry) {
++ entry->write_proc = w;
++ entry->read_proc =r;
++ entry->data = (void *)data;
++ entry->owner = THIS_MODULE;
++ return 0;
++ }
++ else
++ {
++ return -ENOMEM;
++ }
++}
++
++static int
++oxnas_test_read(char *buf, char **start, off_t offset,
++ int count, int *eof, void *unused)
++{
++
++ int i;
++ int len = 0;
++ long unsigned *rd_monitor;
++
++
++ for (i=0; i < NO_MONITORS; i++)
++ {
++ rd_monitor = (long unsigned *) (AHB_MON_BASE + monitor[i].address);
++ len += sprintf(buf+len, "%s CL:%ld EV:%ld hld:%ld slw:%lx tm:%ld\n",
++ monitor[i].name,
++ *rd_monitor,
++ *(rd_monitor+1),
++ *(rd_monitor+2),
++ *(rd_monitor+3),
++ (*(rd_monitor+4) & 0xFFFF));
++ }
++ *eof=1;
++ return len;
++}
++/*
++ * function to clear and start all the timers mainly together.
++ */
++#define MAX_CMD 5
++static int
++oxnas_test_control(struct file *file, const char *buf, unsigned long count, void * data)
++{
++ int len;
++ int i;
++ long unsigned *rd_monitor;
++ unsigned cmd = 0;
++
++ char local[MAX_CMD];
++ int result;
++
++ if (count > MAX_CMD-1)
++ len= MAX_CMD-1;
++ else
++ len=count;
++
++ if (copy_from_user(&local, buf, len))
++ return -EFAULT;
++
++ result=sscanf(local, "%d", &cmd);
++
++ switch (cmd)
++ {
++ case 0:
++ printk(KERN_INFO "oxnas-test: stop command\n");
++ break;
++ case 1:
++ printk(KERN_INFO "oxnas-test: run command\n");
++ break;
++ case 2:
++ printk(KERN_INFO "oxnas-test: reset command\n");
++ break;
++ default:
++ printk(KERN_INFO "oxnas-test: ignored command\n");
++ return len;
++ break;
++ }
++
++ for (i=0; i < NO_MONITORS; i++)
++ {
++ rd_monitor = (long unsigned *) (AHB_MON_BASE + monitor[i].address);
++ *rd_monitor = (long unsigned) cmd;
++ }
++ return len;
++}
++
++
++/*
++ * The write function accepts a line as below:
++ * start_addr, end_addr, mode, burst, burst_mask, hprot, hprot_mask
++ * expected string length is 10 + 10 + 3 + 3 + 4 + 3 + 4 < 40char.
++ * This is decoded by the scanf function into the separate items. - missing items are defaulted.
++ */
++
++#define MAX_STRING 40
++static int
++oxnas_test_config_write(struct file *file, const char *buf, unsigned long count, void * data)
++{
++
++ int len;
++ int i = (int) data;
++ char local[MAX_STRING];
++ int result;
++ unsigned long * mon_ptr;
++
++ if (count > MAX_STRING-1)
++ len= MAX_STRING-1;
++ else
++ len=count;
++
++ if (copy_from_user(&local, buf, len))
++ return -EFAULT;
++
++ /* extract value from buffer and store */
++
++ result = sscanf(local, "%li,%li,%i,%i,%i,%i,%i",
++ &monitor[i].low_add,
++ &monitor[i].high_add,
++ &monitor[i].mode,
++ &monitor[i].burst,
++ &monitor[i].burst_mask,
++ &monitor[i].hprot,
++ &monitor[i].hprot_mask
++ );
++ if (result != 7)
++ return -EINVAL;
++
++ /* load values on hardware */
++
++ mon_ptr=(unsigned long *) (AHB_MON_BASE + monitor[i].address);
++
++ *(mon_ptr + 1) = monitor[i].mode & 0x3;
++ *(mon_ptr + 2) = monitor[i].low_add;
++ *(mon_ptr + 3) = monitor[i].high_add;
++ *(mon_ptr + 4) = ((monitor[i].burst & 0x7) << 4 | (monitor[i].burst_mask & 0x7));
++ *(mon_ptr + 5) = ((monitor[i].hprot & 0xf) << 4 | (monitor[i].hprot_mask &0xf));
++
++ return len;
++}
++
++static int
++oxnas_test_config_read(char *buf, char **start, off_t offset,
++ int count, int *eof, void *data)
++{
++
++ int len = 0;
++ int i = (int) data;
++
++ len += sprintf(buf+len, "name low high mode burst/mask hprot/mask\n");
++
++ len += sprintf(buf+len, "%s 0x%08lx 0x%08lx %d 0x%x/0x%x 0x%x/0x%x\n",
++ monitor[i].name,
++ monitor[i].low_add,
++ monitor[i].high_add,
++ monitor[i].mode,
++ monitor[i].burst,
++ monitor[i].burst_mask,
++ monitor[i].hprot,
++ monitor[i].hprot_mask);
++
++
++ *eof=1;
++ return len;
++}
++
++static int __init oxnas_test_init(void)
++{
++ int rv=0;
++ int i;
++
++ oxnas_test_dir = proc_mkdir(MODULE_NAME, NULL);
++ if (oxnas_test_dir == NULL) {
++ printk(KERN_ERR "oxnas-test: unable to register /proc/usb-test\n");
++ rv= -ENOMEM;
++ goto out;
++ }
++
++ oxnas_test_dir->owner= THIS_MODULE;
++
++ proc_dir_usb_test_read = create_proc_entry("read", 0444, oxnas_test_dir);
++ if (proc_dir_usb_test_read) {
++ proc_dir_usb_test_read->read_proc = oxnas_test_read;
++ } else {
++ printk(KERN_ERR "oxnas-test: unable to register /proc/usb-test/read\n");
++ rv = -ENOMEM;
++ goto no_read;
++ }
++
++ /* create port write file entries */
++ for (i=0;i<NO_MONITORS;i++)
++ {
++ rv = usb_test_write_entries(monitor[i].name, &oxnas_test_config_write, &oxnas_test_config_read, i);
++ if (rv < 0)
++ {
++ while (i != 0)
++ {
++ i--;
++ /* remove any allocated entries */
++ remove_proc_entry (monitor[i].name, oxnas_test_dir);
++ }
++ goto no_write;
++ }
++ }
++
++ {
++ struct proc_dir_entry * entry = create_proc_entry("control", 0666, oxnas_test_dir);
++ if (entry) {
++ entry->write_proc = oxnas_test_control;
++ entry->owner = THIS_MODULE;
++ return 0;
++ }
++ else
++ {
++ goto no_control;
++ }
++ }
++
++
++ printk(KERN_INFO "%s %s initialised\n", MODULE_NAME, MODULE_VERS);
++
++ return 0;
++
++ no_control:
++ for (i = NO_MONITORS; i != 0; )
++ {
++ i--;
++ /* remove any allocated entries */
++ remove_proc_entry (monitor[i].name, oxnas_test_dir);
++ }
++
++ no_write:
++ remove_proc_entry("read", oxnas_test_dir);
++ no_read:
++ remove_proc_entry(MODULE_NAME, NULL);
++ out:
++ return rv;
++}
++
++
++static void __exit oxnas_test_exit(void)
++{
++ int i;
++
++ remove_proc_entry("control", oxnas_test_dir);
++
++ for (i = 0; i < NO_MONITORS; i++)
++ {
++ remove_proc_entry(monitor[i].name, oxnas_test_dir);
++ }
++
++ remove_proc_entry("read", oxnas_test_dir);
++ remove_proc_entry(MODULE_NAME, NULL);
++
++ printk(KERN_INFO "%s %s removed\n", MODULE_NAME, MODULE_VERS);
++
++}
++
++
++module_init(oxnas_test_init);
++module_exit(oxnas_test_exit);
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/oxnas-wd810-leds.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/oxnas-wd810-leds.c
+--- linux-2.6.24/arch/arm/mach-oxnas/oxnas-wd810-leds.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/oxnas-wd810-leds.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,1021 @@
++/*
++ * linux/arch/arm/mach-oxnas/oxnas-wd810-leds.c
++ *
++ * Copyright (c) 2008 Oxford Semiconductor Ltd.
++ *
++ * 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 <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/timer.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/leds.h>
++#include <asm/hardware.h>
++#include <asm/io.h>
++
++
++/* Timer Values and Pulse Width Modulation */
++#define PWM_RESOLUTION 255
++#define TIMER_LED_MODE TIMER_MODE_PERIODIC
++
++#define LED100 (PWM_RESOLUTION) /* 100% duty cycle */
++#define LED50 (PWM_RESOLUTION / 2) /* 50% duty cycle */
++#define LED25 (PWM_RESOLUTION / 4) /* 25% duty cycle */
++
++#define STEP_RESOLUTION (16) /* change intensity in 16 steps */
++
++
++/* Setup Timer2 prescaler, operation mode, and start it */
++#define PERIODIC_INTERRUPT \
++ ( \
++ (TIMER_PRESCALE_256 << TIMER_PRESCALE_BIT) | \
++ (TIMER_LED_MODE << TIMER_MODE_BIT) | \
++ (TIMER_ENABLE_ENABLE << TIMER_ENABLE_BIT) \
++ )
++
++/*
++ * Target frame rate is 60Hz. Slower frame rates flicker badly.
++ * Since each frame has 16 divisions to perform the pulse width
++ * modulation that means we need the timer set to 960Hz (i.e. 60 * 16)
++ *
++ * With a system clock of 25Mhz and a load register value of (1627) prescaled 256
++ * to achieve 2Hz:
++ * 25Mhz / 256 / 24414 =~4Hz //1627 = ~60
++ *
++ * PWM clock = 183MHz/256/814=~877kHz
++ */
++#define FAST_TIMER_INT 24414 //48828//(1627) /* Timer2 count down */
++#define SYS_CLOCK CONFIG_NOMINAL_RPSCLK_FREQ /* System clock frequency */
++#define PRESCALE_VALUE (256) /* Value set in prescaler */
++#define PWM_PRESCALE 814 /* Value loaded on PWM clock register */
++#define MAX_PWM 255
++#define SLOW_TPS ((SYS_CLOCK/PRESCALE_VALUE) / FAST_TIMER_INT) //=~4Hz, 250ms
++
++
++ /**** if GPIO31~GPIO16 is used, sift left 16 bits ****//* GPIO bits dedicated to LEDs *///Need to modify if different GPIO used
++#define LED_MASK_CG5 (1 << GPIO_34) /* Capacity Gauge TOP LED */
++#define LED_MASK_CG4 (1 << GPIO_7) /* Capacity Gauge 4th LED */
++#define LED_MASK_CG3 (1 << GPIO_6) /* Capacity Gauge 3rd LED */
++#define LED_MASK_CG2 (1 << GPIO_5) /* Capacity Gauge 2nd LED */
++#define LED_MASK_CG1 ((1 << GPIO_26)>>16) //sift left 16 bits for PWM10 /* Capacity Gauge 1st LED */
++#define LED_MASK_CG0 ((1 << GPIO_25)>>16) //sift left 16 bits for PWM9 /* Capacity Gauge BOTTOM LED */
++
++/* Mask for all the LEDs in the Fuel Gauge.*/
++/* Mask for all the LEDs on GPIO_A */
++
++#define LED_MASK_GPIO_A \
++ ( \
++ (LED_MASK_CG0<<16) | \
++ (LED_MASK_CG1<<16) | \
++ LED_MASK_CG2 | \
++ LED_MASK_CG3 | \
++ LED_MASK_CG4 \
++ )
++
++/* Mask for all the LEDs on GPIO_B */
++#define LED_MASK_GPIO_B \
++ ( \
++ LED_MASK_CG5 \
++ )
++
++#define LED_MASK_GAUGE \
++ ( \
++ LED_MASK_CG0 | \
++ LED_MASK_CG1 | \
++ LED_MASK_CG2 | \
++ LED_MASK_CG3 | \
++ LED_MASK_CG4 | \
++ LED_MASK_CG5 \
++ )
++
++#define LED_MASK_GAUGE_ODD \
++ ( \
++ LED_MASK_CG0 | \
++ LED_MASK_CG2 | \
++ LED_MASK_CG4 \
++ )
++
++#define LED_MASK_GAUGE_EVEN \
++ ( \
++ LED_MASK_CG1 | \
++ LED_MASK_CG3 | \
++ LED_MASK_CG5 \
++ )
++
++#define LED_MASK_GAUGE_CENTER \
++ ( \
++ LED_MASK_CG2 | \
++ LED_MASK_CG3 \
++ )
++
++#define LED_MASK_GAUGE_MID \
++ ( \
++ LED_MASK_CG1 | \
++ LED_MASK_CG4 \
++ )
++
++#define LED_MASK_GAUGE_OUTER \
++ ( \
++ LED_MASK_CG0 | \
++ LED_MASK_CG5 \
++ )
++
++#define CLEAR(addr, mask) writel(readl(addr) & ~mask, addr)
++
++
++/* Variables to hold the number of LED classes created */
++static int leds_created;
++
++/* Variables to save/restore timer register values */
++static u32 timer_load;
++static u32 timer_control;
++
++/* LED polarity */
++static int negative_led_logic = 0;
++module_param(negative_led_logic, bool, 0);
++
++/*
++ * States for the main LED behavior state machine.
++ */
++enum {
++ STATE_NOP,
++ STANDBY,
++ SHOW_CAPACITY,
++ ACTIVITY,
++ POWER_OFF,
++ RESET,
++ ATTENTION,
++ FAILURE,
++ BOOT_OK,
++ BOOT_stage1,
++ BOOT_stage2,
++ BOOT_stage3,
++ BOOT_stage4,
++ BOOT_stage5,
++ BOOT_stage6,
++};
++
++/*Various LED state timing*/
++#define BOOTOK_RAMP_DIV 11
++#define STANBY_RAMP_DIV 9
++#define STANBY_ALT_STEP (SLOW_TPS*4) //16//8//250 //~4sec
++#define POWEROFF_RAMP_DIV 6
++#define POWEROFF_ALT_STEP ((SLOW_TPS/2)*7) //14//7//200 //~3.5sec
++#define ATTENTION_ALT_STEP (SLOW_TPS/2) // 2 //~2Hz, 0.5sec
++#define FAILURE_RAMP_DIV 6
++#define FAILURE_ALT_STEP (SLOW_TPS/2) // 2 //~2Hz, 0.5sec
++#define ACTIVITY_RAMP_DIV 1 // 2
++#define ACTIVITY_ALT_STEP (SLOW_TPS/4) // 2 //~2Hz, 0.5sec
++#define RESET_ALT_STEP (SLOW_TPS/2) // 2 //~2Hz, 0.5sec
++
++
++/* Variables for main LED behavior state machine */
++static int state;
++static u8 start;
++static u8 act;
++static u8 mark;
++static u16 act_led[6] = {
++ LED_MASK_CG0,
++ LED_MASK_CG1,
++ LED_MASK_CG2,
++ LED_MASK_CG3,
++ LED_MASK_CG4,
++ LED_MASK_CG5,
++};
++static u32 alt = 0;
++static int count;
++static u16 capacity_gauge_bits; /* see LED frame buffer design assumption */
++static u8 leds_switch;
++static u8 activity_block = 1;
++
++
++/*
++ * Declare tasklet for the LED behavior state machine.
++ */
++void oxnas_wd810_leds_behavior(unsigned long);
++DECLARE_TASKLET(oxnas_wd810_leds_behavior_tasklet,
++ oxnas_wd810_leds_behavior, 0);
++
++
++/***************************************************************************/
++/* FUNCTION: oxnas_wd810_leds_interrupt */
++/* */
++/* PURPOSE: */
++/* Interrupt handler for the oxnas-wd810-leds pulse width modulation */
++/***************************************************************************/
++static irqreturn_t oxnas_wd810_leds_interrupt(int irq, void *dev_id)
++{
++ writel(0, TIMER2_CLEAR);
++
++ tasklet_schedule(&oxnas_wd810_leds_behavior_tasklet);
++
++ return IRQ_HANDLED;
++}
++
++
++/***************************************************************************/
++/* FUNCTION: get_vbar_bits */
++/* */
++/* PURPOSE: */
++/* Convert the bit map of V-bar LEDs into the GPIO bit map */
++/***************************************************************************/
++static u16 get_vbar_bits(u16 value)
++{
++ u16 pattern = 0;
++
++ // Convert the bit map to the GPIO bit pattern
++ if (value & (1 << 0))
++ pattern |= LED_MASK_CG0;
++ if (value & (1 << 1))
++ pattern |= LED_MASK_CG1;
++ if (value & (1 << 2))
++ pattern |= LED_MASK_CG2;
++ if (value & (1 << 3))
++ pattern |= LED_MASK_CG3;
++ if (value & (1 << 4))
++ pattern |= LED_MASK_CG4;
++ if (value & (1 << 5))
++ pattern |= LED_MASK_CG5;
++
++ return pattern;
++}
++
++
++/***************************************************************************/
++/* FUNCTION: get_percentage_pattern */
++/* */
++/* PURPOSE: */
++/* Convert a percentage to a V-bar bit map. Note, we never display */
++/* less than 1 LED for a percentage so that something is alway visible. */
++/***************************************************************************/
++static u16 get_percentage_pattern(u16 percentage)
++{
++ if (percentage >= 50) {
++ if (percentage >= 67) {
++ if (percentage >= 83) {
++ if (percentage >= 97) {
++ return 0x3F; // 6 LEDs is >= 97%
++ } else {
++ return 0x1F; // 5 LEDs is >= 83%
++ }
++ } else {
++ return 0x0F; // 4 LEDs is >= 67%
++ }
++ } else {
++ return 0x07; // 3 LEDs is >= 50%
++ }
++ } else {
++ if (percentage >= 33) {
++ return 0x03; // 2 LEDs is >= 33%
++ } else {
++ return 0x01; // 1 LED is >= 0%
++ }
++ }
++}
++
++
++/***************************************************************************/
++/* FUNCTION: set_led */
++/* */
++/* PURPOSE: */
++/* Set requested brightness on the requested LED(s) */
++/***************************************************************************/
++static void set_led(u16 led_bits, u8 value, u16 ramp, u16 ramp_div)
++{
++ u16 bit;
++ s8 count = 0;
++ u32 reg;
++
++ if (negative_led_logic) {
++ value = MAX_PWM - value;
++ if (ramp & 0x100) {
++ ramp = ((MAX_PWM - (ramp & 0xFF)) | 0x100);
++ } else
++ ramp = ((MAX_PWM - (ramp & 0xFF)));
++ }
++
++ reg = ((ramp << 16) | value);
++//printk(KERN_INFO "set_led: reg=%x\n", reg);
++ if (ramp & 0x100) {
++ writel(ramp_div, (PWM_DATA_REGISTER_BASE + 0x404));
++ }
++ for (bit = 1; bit > 0; bit <<= 1, ++count) {
++ if (bit & led_bits) {
++ writel(reg, ((u32 *) PWM_DATA_REGISTER_BASE + count));
++ }
++ }
++}
++
++
++/***************************************************************************/
++/* FUNCTION: display_vbar */
++/* */
++/* PURPOSE: */
++/* Set bits for the requested V-bar map */
++/***************************************************************************/
++static void display_vbar(u16 vbar_bits)
++{
++ //printk(KERN_INFO "display_vbar: vbar_bits=%x\n", vbar_bits);
++
++ //set_led(~vbar_bits & LED_MASK_GAUGE, 0, 0, 0);
++ set_led(LED_MASK_GAUGE, 0, 0, 0);
++ set_led(vbar_bits, LED100, 0, 0);
++}
++
++
++/***************************************************************************/
++/* FUNCTION: oxnas_wd810_leds_behavior_init */
++/* */
++/* PURPOSE: */
++/* Initialization for LED behavior main state machine */
++/***************************************************************************/
++void oxnas_wd810_leds_behavior_init(void)
++{
++ /* State machine variables */
++ state = BOOT_OK;
++ count = 0;
++ capacity_gauge_bits = 0;
++ leds_switch = 0xFF;
++}
++
++
++
++/***************************************************************************/
++/* FUNCTION: oxnas_wd810_leds_behavior */
++/* */
++/* PURPOSE: */
++/* LED behavior main state machine */
++/***************************************************************************/
++void oxnas_wd810_leds_behavior(unsigned long unused)
++{
++//printk(KERN_INFO "oxnas_wd810_leds_behavior state=%d count=%d\n", state, count);
++ switch (state) {
++ case STANDBY:
++ //All LEDs dim-up and dim-down every 4sec.
++ if (leds_switch & (1 << 0)) { //LEDS display turn on
++ if (count-- != 0)
++ break;
++ alt++;
++ if ((alt % 2) == 1) {
++ set_led(LED_MASK_GAUGE, 0, 0x1FF, STANBY_RAMP_DIV);
++ } else {
++ set_led(LED_MASK_GAUGE, 255, 0x100, STANBY_RAMP_DIV);
++ }
++ count = STANBY_ALT_STEP;
++ } else {
++ printk(KERN_INFO " state STANDBY LED display off \n");
++ state = STATE_NOP;
++ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
++ }
++ break;
++
++ case SHOW_CAPACITY:
++ //Each LED represents 1/6 of the total available capacity.
++ if (leds_switch & (1 << 1)) { //LEDS display turn on
++ display_vbar(capacity_gauge_bits);
++ } else {
++ printk(KERN_INFO " state SHOW_CAPACITY LED display off \n");
++ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
++ }
++ state = STATE_NOP;
++ break;
++
++
++ case ACTIVITY:
++ //LEDs illuminate in a up and down "cylon" motion.
++ if (leds_switch & (1 << 2)) { //LEDS display turn on
++ if (count-- != 0)
++ break;
++
++ if (start == 0) {
++ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
++ set_led(act_led[act], 0, 0x1FF, ACTIVITY_RAMP_DIV);
++ start = 1;
++ } else {
++ if ((mark == 0) && (++act < 6)) {
++ set_led(act_led[act], 0, 0x1FF, ACTIVITY_RAMP_DIV);
++ set_led(act_led[act - 1], 255, 0x100,
++ ACTIVITY_RAMP_DIV);
++ goto NEXT;
++ }
++ mark = 1;
++ if ((mark == 1) && (act-- > 1)) {
++ set_led(act_led[act], 255, 0x100, ACTIVITY_RAMP_DIV);
++ set_led(act_led[act - 1], 0, 0x1FF, ACTIVITY_RAMP_DIV);
++ goto NEXT;
++ }
++ mark = 0;
++ state = SHOW_CAPACITY; //Michael TBD
++ }
++ NEXT:
++ count = ACTIVITY_ALT_STEP;
++ } else {
++ printk(KERN_INFO " state ACTIVITY LED display off \n");
++ state = STATE_NOP;
++ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
++ }
++ break;
++
++ case POWER_OFF:
++ //LEDs in the array dim-up/dim-down in an odd/even alternating pattern.
++ if (leds_switch & (1 << 3)) { //LEDS display turn on
++ if (count-- != 0)
++ break;
++ alt++;
++ if ((alt % 2) == 1) {
++ set_led(LED_MASK_GAUGE_ODD, 0, 0x1FF, POWEROFF_RAMP_DIV);
++ set_led(LED_MASK_GAUGE_EVEN, 255, 0x100,
++ POWEROFF_RAMP_DIV);
++ } else {
++ set_led(LED_MASK_GAUGE_ODD, 255, 0x100, POWEROFF_RAMP_DIV);
++ set_led(LED_MASK_GAUGE_EVEN, 0, 0x1FF, POWEROFF_RAMP_DIV);
++ }
++ count = POWEROFF_ALT_STEP;
++ } else {
++ printk(KERN_INFO " state POWER_OFF LED display off \n");
++ state = STATE_NOP;
++ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
++ }
++
++ break;
++
++ case RESET:
++ //Alternately blink the upper LED and lower LED at 1/2 sec rate.
++ if (leds_switch & (1 << 4)) { //LEDS display turn on
++ if (count-- != 0)
++ break;
++ alt++;
++ if ((alt % 2) == 1) {
++ set_led(act_led[0], 255, 0x000, 0);
++ set_led(act_led[5], 0, 0x000, 0);
++ } else {
++ set_led(act_led[0], 0, 0x000, 0);
++ set_led(act_led[5], 255, 0x000, 0);
++ }
++ count = RESET_ALT_STEP;
++ } else {
++ printk(KERN_INFO " state RESET LED display off \n");
++ state = STATE_NOP;
++ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
++ }
++
++ break;
++
++ case ATTENTION:
++ //All LEDs flash simultaneously at a 1/2 sec. rate
++ if (count-- != 0)
++ break;
++ alt++;
++ if ((alt % 2) == 1) {
++ set_led(LED_MASK_GAUGE, 255, 0x000, 0);
++
++ } else {
++ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
++ }
++ count = ATTENTION_ALT_STEP;
++
++ break;
++
++ case FAILURE:
++ //LEDs illuminate in a continous "center out" sweep pattern.
++ if (count-- != 0)
++ break;
++
++ switch ((alt % 4)) {
++ case 0:
++ set_led(LED_MASK_GAUGE_CENTER, 0, 0x1FF, FAILURE_RAMP_DIV);
++ break;
++ case 1:
++ set_led(LED_MASK_GAUGE_MID, 0, 0x1FF, FAILURE_RAMP_DIV);
++ break;
++ case 2:
++ set_led(LED_MASK_GAUGE_OUTER, 0, 0x1FF, FAILURE_RAMP_DIV);
++ break;
++ case 3:
++ set_led(LED_MASK_GAUGE, 0, 0, 0);
++ break;
++ }
++ alt++;
++ count = FAILURE_ALT_STEP;
++
++ break;
++
++ case BOOT_OK:
++ //All 6 LEDs ramp up smoothly to full intensity.
++ if (leds_switch & (1 << 5)) { //LEDS display turn on
++ set_led(LED_MASK_GAUGE, 0, 0x1FF, BOOTOK_RAMP_DIV);
++ } else {
++ printk(KERN_INFO " state BOOT_OK LED display off \n");
++ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
++ }
++ state = STATE_NOP;
++ break;
++
++ case BOOT_stage1:
++ //Bottom LED ramp up smoothly to full intensity.
++ if (leds_switch & (1 << 6)) { //LEDS display turn on
++ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
++ set_led(LED_MASK_CG0, 0, 0x1FF, BOOTOK_RAMP_DIV);
++ } else {
++ printk(KERN_INFO " state BOOT_stage1~3 LED display off \n");
++ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
++ }
++ state = STATE_NOP;
++ break;
++
++ case BOOT_stage2:
++ // 2nd LED ramp up smoothly to full intensity.
++ if (leds_switch & (1 << 6)) { //LEDS display turn on
++ set_led(LED_MASK_CG1, 0, 0x1FF, BOOTOK_RAMP_DIV);
++ } else {
++ printk(KERN_INFO " state BOOT_stage1~3 LED display off \n");
++ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
++ }
++ state = STATE_NOP;
++ break;
++
++ case BOOT_stage3:
++ // 3rd LED ramp up smoothly to full intensity.
++ if (leds_switch & (1 << 6)) { //LEDS display turn on
++ set_led(LED_MASK_CG2, 0, 0x1FF, BOOTOK_RAMP_DIV);
++ } else {
++ printk(KERN_INFO " state BOOT_stage1~3 LED display off \n");
++ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
++ }
++ state = STATE_NOP;
++ break;
++
++ case BOOT_stage4:
++ // 4th LED ramp up smoothly to full intensity.
++ if (leds_switch & (1 << 7)) { //LEDS display turn on
++ set_led(LED_MASK_CG3, 0, 0x1FF, BOOTOK_RAMP_DIV);
++ } else {
++ printk(KERN_INFO " state BOOT_stage4~6 LED display off \n");
++ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
++ }
++ state = STATE_NOP;
++ break;
++
++ case BOOT_stage5:
++ //5th LED ramp up smoothly to full intensity.
++ if (leds_switch & (1 << 7)) { //LEDS display turn on
++ set_led(LED_MASK_CG4, 0, 0x1FF, BOOTOK_RAMP_DIV);
++ } else {
++ printk(KERN_INFO " state BOOT_stage4~6 LED display off \n");
++ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
++ }
++ state = STATE_NOP;
++ break;
++
++ case BOOT_stage6:
++ //Top LED ramp up smoothly to full intensity.
++ if (leds_switch & (1 << 7)) { //LEDS display turn on
++ set_led(LED_MASK_CG5, 0, 0x1FF, BOOTOK_RAMP_DIV);
++ } else {
++ printk(KERN_INFO " state BOOT_stage4~6 LED display off \n");
++ set_led(LED_MASK_GAUGE, 0, 0x000, 0);
++ }
++ state = STATE_NOP;
++ break;
++
++ case STATE_NOP:
++ default:
++ return;
++ }
++}
++
++
++/***************************************************************************/
++/* FUNCTION: oxnas_wd810_leds_set_switch */
++/* */
++/* PURPOSE: */
++/* Set the LED display "on/off" of each state by Web GUI */
++/***************************************************************************/
++static void oxnas_wd810_leds_set_switch
++ (struct led_classdev *led_cdev, enum led_brightness value) {
++ leds_switch = value;
++}
++
++/***************************************************************************/
++/* FUNCTION: oxnas_wd810_leds_set_state */
++/* */
++/* PURPOSE: */
++/* Set the "state" LED to the requested behavior */
++/***************************************************************************/
++static void oxnas_wd810_leds_set_state
++ (struct led_classdev *led_cdev, enum led_brightness value) {
++ count = 0;
++ alt = 0;
++ state = value;
++ start = 0;
++ act = 0;
++ mark = 0;
++ printk(KERN_INFO "oxnas_wd810_leds_state state=%d\n", state);
++
++ if (state > 3)
++ activity_block = 1;
++ else
++ activity_block = 0;
++}
++
++
++/***************************************************************************/
++/* FUNCTION: oxnas_wd810_leds_set_activity */
++/* */
++/* PURPOSE: */
++/* Trigger activity display behavior */
++/***************************************************************************/
++//TBD Michael
++static void oxnas_wd810_leds_set_activity
++ (struct led_classdev *led_cdev, enum led_brightness value) {
++ if (activity_block == 0) {
++//printk("<1> oxnas_wd810_leds_set_activity value=%x\n", value);
++ state = ACTIVITY;
++ }
++}
++
++/***************************************************************************/
++/* FUNCTION: oxnas_wd810_leds_set_capacity_gauge */
++/* */
++/* PURPOSE: */
++/* Set the fuel gauge to the requested value (treated as a percentage) */
++/***************************************************************************/
++static void oxnas_wd810_leds_set_capacity_gauge
++ (struct led_classdev *led_cdev, enum led_brightness value) {
++ capacity_gauge_bits = get_vbar_bits(get_percentage_pattern(value));
++//printk("<1> oxnas_wd810_leds_set_capacity_gauge capacity_gauge_bits=%x\n", capacity_gauge_bits);
++ state = SHOW_CAPACITY;
++ activity_block = 0;
++}
++
++/***************************************************************************/
++/* DATA STRUCTURE: oxnas_wd810_leds_switch */
++/* */
++/* PURPOSE: */
++/* Describe the oxnas-wd810-leds "switch" on/off */
++/***************************************************************************/
++static struct led_classdev oxnas_wd810_leds_switch = {
++ .name = "oxnas-wd810-leds:switch",.brightness_set =
++ oxnas_wd810_leds_set_switch,
++};
++
++/***************************************************************************/
++/* DATA STRUCTURE: oxnas_wd810_leds_state */
++/* */
++/* PURPOSE: */
++/* Describe the oxnas-wd810-leds "power" pseudo-LED */
++/***************************************************************************/
++static struct led_classdev oxnas_wd810_leds_state = {
++ .name = "oxnas-wd810-leds:state",
++ .brightness_set = oxnas_wd810_leds_set_state,
++};
++
++/***************************************************************************/
++/* DATA STRUCTURE: oxnas_wd810_leds_activity */
++/* */
++/* PURPOSE: */
++/* Describe the oxnas-wd810-leds "activity" pseudo-LED */
++/***************************************************************************/
++//TBD Michael
++static struct led_classdev oxnas_wd810_leds_activity = {
++ .name = "oxnas-wd810-leds:activity",
++ .brightness_set = oxnas_wd810_leds_set_activity,
++ .default_trigger = "sata-disk"
++};
++
++/***************************************************************************/
++/* DATA STRUCTURE: oxnas_wd810_leds_capacity_gauge */
++/* */
++/* PURPOSE: */
++/* Describe the oxnas-wd810-leds "capacity-gauge" LEDs (brightness = % full) */
++/***************************************************************************/
++static struct led_classdev oxnas_wd810_leds_capacity_gauge = {
++ .name = "oxnas-wd810-leds:capacity",
++ .brightness_set = oxnas_wd810_leds_set_capacity_gauge,
++};
++
++/***************************************************************************/
++/* DATA STRUCTURE: oxnas_wd810_leds_classes[] */
++/* */
++/* PURPOSE: */
++/* Array of LED classes to create/destroy */
++/***************************************************************************/
++static struct led_classdev *oxnas_led_classes[] = {
++ &oxnas_wd810_leds_switch,
++ &oxnas_wd810_leds_state,
++ &oxnas_wd810_leds_activity, //TBD
++ &oxnas_wd810_leds_capacity_gauge,
++};
++
++#ifdef DEBUG
++static ssize_t
++show_registers(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ char *out = buf;
++ u32 clock_data = readl(PWM_CLOCK_REGISTER);
++ u32 data_ptr = PWM_CLOCK_REGISTER;
++ u8 no_pwms = (clock_data >> 16);
++ u8 i;
++ /* report hardware status here */
++ out += sprintf(buf, "PWM drive registers\n");
++ out +=
++ sprintf(out, "clock register:0x%08x @ 0x%08x\n", clock_data,
++ data_ptr);
++
++ for (i = 0; i < no_pwms; ++i) {
++ data_ptr = (u32) ((u32 *) PWM_BASE + i);
++ out +=
++ sprintf(out, "%d:%d @ 0x%08x\n", i, (u8) readl(data_ptr),
++ data_ptr);
++ }
++
++ return out - buf;
++}
++
++/* create a register 'file' to enbale reading back the pwm drive register status */
++static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
++
++static void create_debug_files(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ device_create_file(dev, &dev_attr_registers);
++}
++
++static void remove_debug_files(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ device_remove_file(dev, &dev_attr_registers);
++}
++#endif
++
++
++#ifdef CONFIG_PM
++/***************************************************************************/
++/* FUNCTION: oxnas_wd810_leds_suspend */
++/* */
++/* PURPOSE: */
++/* Suspend all LED class devices created by this driver */
++/***************************************************************************/
++static int
++oxnas_wd810_leds_suspend(struct platform_device *pdev, pm_message_t state)
++{
++ int n = leds_created;
++ while (n > 0) {
++ if (--n < ARRAY_SIZE(oxnas_led_classes)) {
++ led_classdev_suspend(oxnas_led_classes[n]);
++ }
++ }
++
++ return 0;
++}
++
++/***************************************************************************/
++/* FUNCTION: oxnas_wd810_leds_resume */
++/* */
++/* PURPOSE: */
++/* Wake up all LED class devices created by this driver */
++/***************************************************************************/
++static int
++oxnas_wd810_leds_resume(struct platform_device *pdev, pm_message_t state)
++{
++ int n = leds_created;
++ while (n > 0) {
++ if (--n < ARRAY_SIZE(oxnas_led_classes)) {
++ led_classdev_resume(oxnas_led_classes[n]);
++ }
++ }
++
++ return 0;
++}
++#endif /* CONFIG_PM */
++
++/***************************************************************************/
++/* FUNCTION: oxnas_wd810_leds_probe */
++/* */
++/* PURPOSE: */
++/* Perform any necessary probing and initial setup for oxnas-wd810-leds device */
++/***************************************************************************/
++static int oxnas_wd810_leds_probe(struct platform_device *pdev)
++{
++ int rc;
++ int timer_changed = 0;
++ int interrupt_allocated = 0;
++ leds_created = 0;
++
++ /* Turn off all the LEDs */
++ if (negative_led_logic) {
++ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_SET);
++ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_SET);
++ } else {
++ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_CLEAR);
++ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_CLEAR);
++ }
++ /* put PWM module back into reset and disable clock */
++ writel((1 << SYS_CTRL_RSTEN_MISC_BIT), SYS_CTRL_RSTEN_SET_CTRL);
++ // writel(PWM_CLOCK, SYS_CTRL_CKEN_CLR_CTRL);
++
++ do {
++ /* Enable LED output drivers and disable other uses */
++ CLEAR(SYS_CTRL_GPIO_PRIMSEL_CTRL_0, LED_MASK_GPIO_A);
++ CLEAR(SYS_CTRL_GPIO_SECSEL_CTRL_0, LED_MASK_GPIO_A);
++ CLEAR(SYS_CTRL_GPIO_TERTSEL_CTRL_0, LED_MASK_GPIO_A);
++
++ CLEAR(SYS_CTRL_GPIO_PRIMSEL_CTRL_1, LED_MASK_GPIO_B);
++ CLEAR(SYS_CTRL_GPIO_SECSEL_CTRL_1, LED_MASK_GPIO_B);
++ CLEAR(SYS_CTRL_GPIO_TERTSEL_CTRL_1, LED_MASK_GPIO_B);
++ /* Turn off all the LEDs */
++ if (negative_led_logic) {
++ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_SET);
++ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_SET);
++ } else {
++ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_CLEAR);
++ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_CLEAR);
++ }
++
++ /* bring PWM module out of reset and enable clock */
++ writel((1 << SYS_CTRL_RSTEN_MISC_BIT), SYS_CTRL_RSTEN_CLR_CTRL);
++ //writel(PWM_CLOCK, SYS_CTRL_CKEN_SET_CTRL);
++
++ /* enable PWM clock */
++ writel(PWM_PRESCALE, PWM_CLOCK_REGISTER);
++
++ /* Initialize frame buffer to everything off */
++//printk(KERN_INFO "oxnas_wd810_leds_probe: LED_MASK_GAUGE=%x\n",LED_MASK_GAUGE);
++ set_led(LED_MASK_GAUGE, 0, 0, 0);
++ /* Enable output to the LEDs */
++ writel(LED_MASK_GPIO_A, SYS_CTRL_GPIO_PWMSEL_CTRL_0);
++ writel(LED_MASK_GPIO_B, SYS_CTRL_GPIO_PWMSEL_CTRL_1);
++
++ /* Initialize the LED behavior state machine */
++ oxnas_wd810_leds_behavior_init();
++ /* Save Timer2 state for restoring later */
++ timer_load = readl(TIMER2_LOAD);
++ timer_control = readl(TIMER2_CONTROL);
++ writel(0, TIMER2_CONTROL);
++ timer_changed = 1;
++ /* Setup Timer2 for LED control */
++ rc = request_irq(TIMER_2_INTERRUPT, oxnas_wd810_leds_interrupt, 0,
++ "led_pwm", 0);
++
++ // rc = request_irq(TIMER_2_INTERRUPT, wdc_leds_interrupt, 0, "led_pwm", 0);
++ if (rc < 0) {
++ printk(KERN_ERR "failed to get IRQ\n");
++ break;
++ }
++
++ interrupt_allocated = 1;
++ writel(FAST_TIMER_INT, TIMER2_LOAD);
++ writel(PERIODIC_INTERRUPT, TIMER2_CONTROL);
++
++ /* Register each LED class device */
++ while (leds_created < ARRAY_SIZE(oxnas_led_classes)) {
++ rc = led_classdev_register(&pdev->dev,
++ oxnas_led_classes[leds_created]);
++ if (rc < 0) {
++ printk(KERN_ERR "failed to register led class \"%s\"\n",
++ oxnas_led_classes[leds_created]->name);
++ break;
++ }
++
++ ++leds_created;
++ }
++ }
++ while (0);
++ /* If we failed then perform any needed clean up */
++ if (rc < 0) {
++ /* Unregister any classes we registered */
++ while (leds_created > 0) {
++ if (--leds_created < ARRAY_SIZE(oxnas_led_classes)) {
++ led_classdev_unregister(oxnas_led_classes[leds_created]);
++ }
++ }
++
++ /* Free the interrupt if we allocated one */
++ if (interrupt_allocated) {
++ free_irq(TIMER_2_INTERRUPT, 0);
++ }
++
++ /* Restore Timer2 if we changed it */
++ if (timer_changed) {
++ writel(timer_load, TIMER2_LOAD);
++ writel(timer_control, TIMER2_CONTROL);
++ }
++ }
++#ifdef DEBUG
++ create_debug_files(pdev);
++#endif
++ return rc;
++}
++
++
++/***************************************************************************/
++/* FUNCTION: oxnas_wd810_leds_remove */
++/* */
++/* PURPOSE: */
++/* Perform steps to remove the oxnas-wd810-leds device */
++/***************************************************************************/
++static int oxnas_wd810_leds_remove(struct platform_device *pdev)
++{
++ while (leds_created > 0) {
++ if (--leds_created < ARRAY_SIZE(oxnas_led_classes)) {
++ led_classdev_unregister(oxnas_led_classes[leds_created]);
++ }
++ }
++
++ writel(0, TIMER2_CONTROL);
++ free_irq(TIMER_2_INTERRUPT, 0);
++ writel(timer_load, TIMER2_LOAD);
++ writel(timer_control, TIMER2_CONTROL);
++ /* Turn off all the LEDs */
++ if (negative_led_logic) {
++ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_SET);
++ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_SET);
++ } else {
++ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_CLEAR);
++ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_CLEAR);
++ }
++ /* put PWM module back into reset and disable clock */
++ writel((1 << SYS_CTRL_RSTEN_MISC_BIT), SYS_CTRL_RSTEN_SET_CTRL);
++ // writel(PWM_CLOCK, SYS_CTRL_CKEN_CLR_CTRL);
++#ifdef DEBUG
++ remove_debug_files(pdev);
++#endif
++ return 0;
++}
++
++
++/***************************************************************************/
++/* DATA STRUCTURE: oxnas_wd810_leds_driver */
++/* */
++/* PURPOSE: */
++/* Describe the oxnas-wd810-leds platform device driver */
++/***************************************************************************/
++static struct platform_driver oxnas_wd810_leds_driver = {
++ .probe = oxnas_wd810_leds_probe,
++ .remove = oxnas_wd810_leds_remove,
++#ifdef CONFIG_PM
++ .suspend = oxnas_wd810_leds_suspend,.resume = oxnas_wd810_leds_resume,
++#endif /* CONFIG_PM */
++ .driver = {.name = "oxnas-wd810-leds",},
++};
++
++/* Pointer to device returned by platform_device_register_simple */
++static struct platform_device *oxnas_wd810_leds;
++/***************************************************************************/
++/* FUNCTION: oxnas_wd810_leds_init */
++/* */
++/* PURPOSE: */
++/* Perform module initialization */
++/***************************************************************************/
++static int __init oxnas_wd810_leds_init(void)
++{
++ int ret;
++ printk(KERN_INFO "oxnas-wd810-leds: SLOW_TPS=%d\n", SLOW_TPS);
++ ret = platform_driver_register(&oxnas_wd810_leds_driver);
++ if (!ret) {
++ oxnas_wd810_leds =
++ platform_device_register_simple("oxnas-wd810-leds", -1, NULL,
++ 0);
++ }
++
++ return ret;
++}
++
++
++/***************************************************************************/
++/* FUNCTION: oxnas_wd810_leds_exit */
++/* */
++/* PURPOSE: */
++/* Perform module unloading and cleanup */
++/***************************************************************************/
++static void __exit oxnas_wd810_leds_exit(void)
++{
++ if (oxnas_wd810_leds) {
++ platform_device_unregister(oxnas_wd810_leds);
++ }
++ platform_driver_unregister(&oxnas_wd810_leds_driver);
++}
++
++
++module_init(oxnas_wd810_leds_init);
++module_exit(oxnas_wd810_leds_exit);
++MODULE_DESCRIPTION("oxnas wd810 1NC/2NC LEDs");
++MODULE_AUTHOR("Oxford Semiconductor Ltd");
++MODULE_LICENSE("GPL");
++/******************************* End of File *********************************/
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/oxnas.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/oxnas.c
+--- linux-2.6.24/arch/arm/mach-oxnas/oxnas.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/oxnas.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,1104 @@
++/*
++ * linux/arch/arm/mach-oxnas/oxnas.c
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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 <linux/delay.h>
++#include <linux/platform_device.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/completion.h>
++#include <linux/serial.h>
++#include <linux/serial_core.h>
++#include <linux/serial_8250.h>
++
++#include <asm/sizes.h>
++#include <asm/setup.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++#include <asm/mach/map.h>
++#include <asm/arch/hardware.h>
++#include <asm/arch/dma.h>
++
++#ifdef CONFIG_DO_MEM_TEST
++#include <linux/dma-mapping.h>
++#include <asm/io.h>
++#include <asm/arch/ahb_mon.h>
++#endif // CONFIG_DO_MEM_TEST
++
++#include <asm/io.h>
++
++#ifdef CONFIG_LEON_START_EARLY
++#include <asm/arch/leon.h>
++#include <asm/arch/leon-early-prog.h>
++#endif // CONFIG_LEON_START_EARLY
++
++#ifdef CONFIG_OXNAS_PCI_RESET_GPIO
++#if (CONFIG_OXNAS_PCI_RESET_GPIO < 32)
++#define PCI_RESET_NUM CONFIG_OXNAS_PCI_RESET_GPIO
++#define PCI_RESET_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_0
++#define PCI_RESET_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_0
++#define PCI_RESET_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_0
++#define PCI_RESET_SET_OE_REG GPIO_A_OUTPUT_ENABLE_SET
++#define PCI_RESET_OUTPUT_SET_REG GPIO_A_OUTPUT_SET
++#define PCI_RESET_OUTPUT_CLR_REG GPIO_A_OUTPUT_CLEAR
++#else
++#define PCI_RESET_NUM ((CONFIG_OXNAS_PCI_RESET_GPIO) - 32)
++#define PCI_RESET_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_1
++#define PCI_RESET_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_1
++#define PCI_RESET_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_1
++#define PCI_RESET_SET_OE_REG GPIO_B_OUTPUT_ENABLE_SET
++#define PCI_RESET_OUTPUT_SET_REG GPIO_B_OUTPUT_SET
++#define PCI_RESET_OUTPUT_CLR_REG GPIO_B_OUTPUT_CLEAR
++#endif
++
++#define PCI_RESET_MASK (1UL << (PCI_RESET_NUM))
++#endif // CONFIG_OXNAS_PCI_RESET_GPIO
++
++#define PCI_CLOCK_NUM 10
++#define PCI_CLOCK_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_0
++#define PCI_CLOCK_SET_OE_REG GPIO_A_OUTPUT_ENABLE_SET
++#define PCI_CLOCK_MASK (1UL << (PCI_CLOCK_NUM))
++
++#ifdef CONFIG_OXNAS_SATA_POWER_GPIO_1
++#if (CONFIG_OXNAS_SATA_POWER_GPIO_1 < 32)
++#define SATA_POWER_1_NUM CONFIG_OXNAS_SATA_POWER_GPIO_1
++#define SATA_POWER_1_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_0
++#define SATA_POWER_1_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_0
++#define SATA_POWER_1_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_0
++#define SATA_POWER_1_SET_OE_REG GPIO_A_OUTPUT_ENABLE_SET
++#define SATA_POWER_1_OUTPUT_SET_REG GPIO_A_OUTPUT_SET
++#define SATA_POWER_1_OUTPUT_CLR_REG GPIO_A_OUTPUT_CLEAR
++#else
++#define SATA_POWER_1_NUM ((CONFIG_OXNAS_SATA_POWER_GPIO_1) - 32)
++#define SATA_POWER_1_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_1
++#define SATA_POWER_1_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_1
++#define SATA_POWER_1_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_1
++#define SATA_POWER_1_SET_OE_REG GPIO_B_OUTPUT_ENABLE_SET
++#define SATA_POWER_1_OUTPUT_SET_REG GPIO_B_OUTPUT_SET
++#define SATA_POWER_1_OUTPUT_CLR_REG GPIO_B_OUTPUT_CLEAR
++#endif
++
++#define SATA_POWER_1_MASK (1UL << (SATA_POWER_1_NUM))
++#endif // CONFIG_OXNAS_SATA_POWER_GPIO_1
++
++#ifdef CONFIG_OXNAS_SATA_POWER_GPIO_2
++#if (CONFIG_OXNAS_SATA_POWER_GPIO_2 < 32)
++#define SATA_POWER_2_NUM CONFIG_OXNAS_SATA_POWER_GPIO_2
++#define SATA_POWER_2_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_0
++#define SATA_POWER_2_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_0
++#define SATA_POWER_2_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_0
++#define SATA_POWER_2_SET_OE_REG GPIO_A_OUTPUT_ENABLE_SET
++#define SATA_POWER_2_OUTPUT_SET_REG GPIO_A_OUTPUT_SET
++#define SATA_POWER_2_OUTPUT_CLR_REG GPIO_A_OUTPUT_CLEAR
++#else
++#define SATA_POWER_2_NUM ((CONFIG_OXNAS_SATA_POWER_GPIO_2) - 32)
++#define SATA_POWER_2_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_1
++#define SATA_POWER_2_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_1
++#define SATA_POWER_2_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_1
++#define SATA_POWER_2_SET_OE_REG GPIO_B_OUTPUT_ENABLE_SET
++#define SATA_POWER_2_OUTPUT_SET_REG GPIO_B_OUTPUT_SET
++#define SATA_POWER_2_OUTPUT_CLR_REG GPIO_B_OUTPUT_CLEAR
++#endif
++
++#define SATA_POWER_2_MASK (1UL << (SATA_POWER_2_NUM))
++#endif // CONFIG_OXNAS_SATA_POWER_GPIO_2
++
++#ifdef CONFIG_OXNAS_USB_HUB_RESET_GPIO
++#if (CONFIG_OXNAS_USB_HUB_RESET_GPIO < 32)
++#define USB_HUB_RESET_NUM CONFIG_OXNAS_USB_HUB_RESET_GPIO
++#define USB_HUB_RESET_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_0
++#define USB_HUB_RESET_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_0
++#define USB_HUB_RESET_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_0
++#define USB_HUB_RESET_SET_OE_REG GPIO_A_OUTPUT_ENABLE_SET
++#define USB_HUB_RESET_OUTPUT_SET_REG GPIO_A_OUTPUT_SET
++#define USB_HUB_RESET_OUTPUT_CLR_REG GPIO_A_OUTPUT_CLEAR
++#else
++#define USB_HUB_RESET_NUM ((CONFIG_OXNAS_USB_HUB_RESET_GPIO) - 32)
++#define USB_HUB_RESET_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_1
++#define USB_HUB_RESET_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_1
++#define USB_HUB_RESET_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_1
++#define USB_HUB_RESET_SET_OE_REG GPIO_B_OUTPUT_ENABLE_SET
++#define USB_HUB_RESET_OUTPUT_SET_REG GPIO_B_OUTPUT_SET
++#define USB_HUB_RESET_OUTPUT_CLR_REG GPIO_B_OUTPUT_CLEAR
++#endif
++
++#define USB_HUB_RESET_MASK (1UL << (USB_HUB_RESET_NUM))
++#endif // CONFIG_OXNAS_USB_HUB_RESET_GPIO
++
++extern void oxnas_init_irq(void);
++extern struct sys_timer oxnas_timer;
++
++// The spinlock exported to allow atomic use of GPIO register set
++spinlock_t oxnas_gpio_spinlock;
++
++// To hold LED inversion state
++int oxnas_global_invert_leds = 0;
++#include <linux/module.h>
++EXPORT_SYMBOL(oxnas_global_invert_leds);
++
++static struct map_desc oxnas_io_desc[] __initdata = {
++ { CORE_MODULE_BASE, __phys_to_pfn(CORE_MODULE_BASE_PA), SZ_4K, MT_DEVICE },
++ { APB_BRIDGE_A_BASE, __phys_to_pfn(APB_BRIDGE_A_BASE_PA), SZ_16M, MT_DEVICE },
++ { STATIC_CONTROL_BASE, __phys_to_pfn(STATIC_CONTROL_BASE_PA), SZ_4K, MT_DEVICE },
++ { STATIC_CS0_BASE, __phys_to_pfn(STATIC_CS0_BASE_PA), SZ_4K, MT_DEVICE },
++ { STATIC_CS1_BASE, __phys_to_pfn(STATIC_CS1_BASE_PA), SZ_4K, MT_DEVICE },
++ { STATIC_CS2_BASE, __phys_to_pfn(STATIC_CS2_BASE_PA), SZ_4K, MT_DEVICE },
++ { APB_BRIDGE_B_BASE, __phys_to_pfn(APB_BRIDGE_B_BASE_PA), SZ_16M, MT_DEVICE },
++ { USB_BASE, __phys_to_pfn(USB_BASE_PA), SZ_4M, MT_DEVICE },
++ { MAC_BASE, __phys_to_pfn(MAC_BASE_PA), SZ_4M, MT_DEVICE },
++ { ROM_BASE, __phys_to_pfn(ROM_BASE_PA), SZ_16K, MT_DEVICE },
++ { PCI_CSRS_BASE, __phys_to_pfn(PCI_CSRS_BASE_PA), SZ_4K, MT_DEVICE }
++#ifdef CONFIG_SUPPORT_LEON
++#if (CONFIG_LEON_PAGES == 1)
++ ,{ LEON_IMAGE_BASE, __phys_to_pfn(LEON_IMAGE_BASE_PA), SZ_4K, MT_DEVICE }
++#elif (CONFIG_LEON_PAGES == 2)
++ ,{ LEON_IMAGE_BASE, __phys_to_pfn(LEON_IMAGE_BASE_PA), SZ_8K, MT_DEVICE }
++#elif (CONFIG_LEON_PAGES == 3)
++ ,{ LEON_IMAGE_BASE, __phys_to_pfn(LEON_IMAGE_BASE_PA), SZ_8K, MT_DEVICE }
++ ,{ LEON_IMAGE_BASE+0x2000, __phys_to_pfn(LEON_IMAGE_BASE_PA+0x2000), SZ_4K, MT_DEVICE }
++#elif (CONFIG_LEON_PAGES == 4)
++ ,{ LEON_IMAGE_BASE, __phys_to_pfn(LEON_IMAGE_BASE_PA), SZ_8K, MT_DEVICE }
++ ,{ LEON_IMAGE_BASE+0x2000, __phys_to_pfn(LEON_IMAGE_BASE_PA+0x2000), SZ_8K, MT_DEVICE }
++#else
++#error "Unsupported number of Leon code pages"
++#endif // CONFIG_LEON_PAGES
++#endif // CONFIG_SUPPORT_LEON
++ /*
++ * Upto 8 pages for GMAC/DMA descriptors plus ARM/Leon TSO workspace if
++ * Leon TSO is in use
++ */
++ ,{ SRAM_BASE, __phys_to_pfn(SRAM_PA), SZ_16K, MT_DEVICE }
++ ,{ SRAM_BASE+0x4000, __phys_to_pfn(SRAM_PA+0x4000), SZ_16K, MT_DEVICE }
++};
++
++static struct resource usb_resources[] = {
++ [0] = {
++ .start = USB_BASE_PA,
++ .end = USB_BASE_PA + 0x10000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = USB_FS_INTERRUPT,
++ .end = USB_FS_INTERRUPT,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static u64 usb_dmamask = ~(u32)0;
++
++static struct platform_device usb_device = {
++ .name = "oxnas-ehci",
++ .id = 0,
++ .dev = {
++ .dma_mask = &usb_dmamask,
++ .coherent_dma_mask = 0xffffffff,
++ },
++ .num_resources = ARRAY_SIZE(usb_resources),
++ .resource = usb_resources,
++};
++
++static struct platform_device *platform_devices[] __initdata = {
++ &usb_device,
++};
++
++#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
++
++#define INT_UART_BASE_BAUD (NOMINAL_SYSCLK)
++
++#ifdef CONFIG_ARCH_OXNAS_UART1
++static struct uart_port internal_serial_port_1 = {
++ .membase = (char *)(UART_1_BASE),
++ .mapbase = UART_1_BASE_PA,
++ .irq = UART_1_INTERRUPT,
++ .flags = STD_COM_FLAGS,
++ .iotype = UPIO_MEM,
++ .regshift = 0,
++ .uartclk = INT_UART_BASE_BAUD,
++ .line = 0,
++ .type = PORT_16550A,
++ .fifosize = 16
++};
++#endif // CONFIG_ARCH_OXNAS_UART1
++
++#ifdef CONFIG_ARCH_OXNAS_UART2
++static struct uart_port internal_serial_port_2 = {
++ .membase = (char *)(UART_2_BASE),
++ .mapbase = UART_2_BASE_PA,
++ .irq = UART_2_INTERRUPT,
++ .flags = STD_COM_FLAGS,
++ .iotype = UPIO_MEM,
++ .regshift = 0,
++ .uartclk = INT_UART_BASE_BAUD,
++ .line = 0,
++ .type = PORT_16550A,
++ .fifosize = 16
++};
++#endif // CONFIG_ARCH_OXNAS_UART2
++
++#ifdef CONFIG_ARCH_OXNAS_UART3
++static struct uart_port internal_serial_port_3 = {
++ .membase = (char *)(UART_3_BASE),
++ .mapbase = UART_3_BASE_PA,
++ .irq = UART_3_INTERRUPT,
++ .flags = STD_COM_FLAGS,
++ .iotype = UPIO_MEM,
++ .regshift = 0,
++ .uartclk = INT_UART_BASE_BAUD,
++ .line = 0,
++ .type = PORT_16550A,
++ .fifosize = 16
++};
++#endif // CONFIG_ARCH_OXNAS_UART3
++
++#ifdef CONFIG_ARCH_OXNAS_UART4
++static struct uart_port internal_serial_port_4 = {
++ .membase = (char *)(UART_4_BASE),
++ .mapbase = UART_4_BASE_PA,
++ .irq = UART_4_INTERRUPT,
++ .flags = STD_COM_FLAGS,
++ .iotype = UPIO_MEM,
++ .regshift = 0,
++ .uartclk = INT_UART_BASE_BAUD,
++ .line = 0,
++ .type = PORT_16550A,
++ .fifosize = 16
++};
++#endif // CONFIG_ARCH_OXNAS_UART4
++
++static void __init oxnas_mapio(void)
++{
++ unsigned int uart_line=0;
++
++//printk("oxnas_mapio()\n");
++
++ // Setup kernel mappings for hardware cores
++ iotable_init(oxnas_io_desc, ARRAY_SIZE(oxnas_io_desc));
++
++#ifdef CONFIG_ARCH_OXNAS_FPGA
++ // Setup the ARM926-EJ-S integrator module clock and bus clock divider
++ asm volatile(
++ "mov r3,%2,LSL #4;" /* Bus clock divider = ((n+1) << 4) */
++ "sub r3,r3,#16;"
++ "mov r0,%1;" /* Processor clock frequency */
++ "sub r0,r0,#8;" /* correction for MHz */
++ "and r0,r0,#0xFF;" /* ensure byte value */
++ "mov r2,%0;" /* read CM base value */
++ "ldr r1,[r2,#8];" /* read CM_OSC */
++ "bic r1,r1,#0x0FF;" /* clear bottom byte r1 */
++ "orr r1,r1,r0;" /* write in new clock values */
++ "ldr r4,[r2,#0x24];" /* read CM_INIT */
++ "bic r4,r4,#0x070;" /* clear bits [6:4] */
++ "orr r4,r4,r3;" /* write in new clock values */
++ "mov r0,#0xA000;"
++ "orr r0,r0,#0x5F;" /* build 0xA05F in r0 */
++ "str r0,[r2,#0x14];" /* write to unlock CM_LOCK */
++ "str r1,[r2,#8];" /* write value back */
++ "str r4,[r2,#0x24];" /* write HCLK value back */
++ "str r1,[r2,#0x14];" /* write in any value to relock CM_LOCK */
++ :
++ : "r" (CORE_MODULE_BASE), "r" (CONFIG_OXNAS_CORE_CLK), "r" (CONFIG_OXNAS_CORE_BUS_CLK_DIV)
++ : "r0","r1","r2","r3","r4");
++#endif // CONFIG_ARCH_OXNAS_FPGA
++
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ // Configure the DDR controller arbitration scheme
++ *(volatile u32*)DDR_ARB_REG = ((1UL << DDR_ARB_DATDIR_NCH_BIT) |
++ (1UL << DDR_ARB_DATDIR_EN_BIT) |
++ (1UL << DDR_ARB_REQAGE_EN_BIT) |
++ (1UL << DDR_ARB_LRUBANK_EN_BIT) |
++ (1UL << DDR_ARB_MIDBUF_BIT));
++
++ // Setup the DDR client read buffers
++ // NB 0X800 ASIC bug means DMA read buffers should never be enabled
++ *(volatile u32*)DDR_AHB_REG = ((1UL << DDR_AHB_NO_RCACHE_ARMD_BIT) |
++ /*(1UL << DDR_AHB_NO_RCACHE_ARMI_BIT) |*/
++ (1UL << DDR_AHB_NO_RCACHE_COPRO_BIT) |
++ (1UL << DDR_AHB_NO_RCACHE_DMAA_BIT) |
++ (1UL << DDR_AHB_NO_RCACHE_DMAB_BIT) |
++ /* (1UL << DDR_AHB_NO_RCACHE_PCI_BIT) |
++ (1UL << DDR_AHB_NO_RCACHE_GMAC_BIT) |*/
++ (1UL << DDR_AHB_NO_RCACHE_USB_BIT));
++
++ // Ignore HPROT for all clients except ARM data, as ARM Linux interrupt
++ // latency will mask any slight delay in data written by cores getting to
++ // memory after the core raises an interrupt
++ *(volatile u32*)DDR_AHB2_REG = ((1UL << DDR_AHB2_IGNORE_HPROT_ARMI_BIT) |
++ (1UL << DDR_AHB2_IGNORE_HPROT_COPRO_BIT) |
++ (1UL << DDR_AHB2_IGNORE_HPROT_DMAA_BIT) |
++ (1UL << DDR_AHB2_IGNORE_HPROT_DMAB_BIT) |
++ (1UL << DDR_AHB2_IGNORE_HPROT_PCI_BIT) |
++ (1UL << DDR_AHB2_IGNORE_HPROT_GMAC_BIT) |
++ (1UL << DDR_AHB2_IGNORE_HPROT_USB_BIT));
++#elif CONFIG_OXNAS_VERSION_0X810
++ // Configure the DDR controller arbitration scheme
++ *(volatile u32*)DDR_ARB_REG = ((1UL << DDR_ARB_DATDIR_NCH_BIT) |
++ (1UL << DDR_ARB_DATDIR_EN_BIT) |
++ (1UL << DDR_ARB_REQAGE_EN_BIT) |
++ (1UL << DDR_ARB_LRUBANK_EN_BIT) |
++ (1UL << DDR_ARB_MIDBUF_BIT));
++
++ // Configure read buffers - Do not disable any read buffers
++ *(volatile u32*)DDR_AHB_REG = 0UL;
++
++ // Configure wrapping - Ignore wrap
++ // Configure HPROT - Ignore all HPROT except ARM data
++ *(volatile u32*)DDR_AHB2_REG = ((1UL << DDR_AHB2_IGNORE_WRAP_ARMD_BIT) |
++ (1UL << DDR_AHB2_IGNORE_WRAP_ARMI_BIT) |
++ (1UL << DDR_AHB2_IGNORE_WRAP_COPRO_BIT) |
++ (1UL << DDR_AHB2_IGNORE_WRAP_DMAA_BIT) |
++ (1UL << DDR_AHB2_IGNORE_WRAP_DMAB_BIT) |
++ (1UL << DDR_AHB2_IGNORE_WRAP_PCI_BIT) |
++ (1UL << DDR_AHB2_IGNORE_WRAP_GMAC_BIT) |
++ (1UL << DDR_AHB2_IGNORE_WRAP_US_BIT) |
++ (1UL << DDR_AHB2_IGNORE_HPROT_ARMI_BIT) |
++ (1UL << DDR_AHB2_IGNORE_HPROT_COPRO_BIT) |
++ (1UL << DDR_AHB2_IGNORE_HPROT_DMAA_BIT) |
++ (1UL << DDR_AHB2_IGNORE_HPROT_DMAB_BIT) |
++ (1UL << DDR_AHB2_IGNORE_HPROT_PCI_BIT) |
++ (1UL << DDR_AHB2_IGNORE_HPROT_GMAC_BIT) |
++ (1UL << DDR_AHB2_IGNORE_HPROT_USB_BIT));
++
++ // Configure burst ordering - Do not disable burst ordering
++ // Configure non-cachable - Do not prevent non-cachable accesses from using read buffers
++ *(volatile u32*)DDR_AHB3_REG = 0UL;
++
++ // Configure read buffer timeout - Do not enable read buffer invalidate after timeout
++ // Configure write behind - Enable write behind coherency
++ *(volatile u32*)DDR_AHB4_REG = ((1UL << DDR_AHB4_EN_WRBEHIND_ARMD_BIT) |
++ (1UL << DDR_AHB4_EN_WRBEHIND_ARMI_BIT) |
++ (1UL << DDR_AHB4_EN_WRBEHIND_COPRO_BIT) |
++ (1UL << DDR_AHB4_EN_WRBEHIND_DMAA_BIT) |
++ (1UL << DDR_AHB4_EN_WRBEHIND_DMAB_BIT) |
++ (1UL << DDR_AHB4_EN_WRBEHIND_PCI_BIT) |
++ (1UL << DDR_AHB4_EN_WRBEHIND_GMAC_BIT) |
++ (1UL << DDR_AHB4_EN_WRBEHIND_USB_BIT));
++
++#endif // CONFIG_OXNAS_VERSION_0X8xx
++
++ // Enable all DDR client interfaces
++ *(volatile u32*)DDR_BLKEN_REG |= (((1UL << DDR_BLKEN_CLIENTS_NUM_BITS) - 1) << DDR_BLKEN_CLIENTS_BIT);
++
++#ifdef CONFIG_ARCH_OXNAS_UART1
++ // Block reset UART1
++ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART1_BIT);
++ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART1_BIT);
++
++ // Route UART1 SOUT onto external pin
++ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x80000000;
++ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 &= ~0x80000000;
++ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |= 0x80000000;
++
++ // Route UART1 SIN onto external pin
++ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_1 &= ~0x00000001;
++ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_1 &= ~0x00000001;
++ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_1 |= 0x00000001;
++
++ // Setup GPIO line direction for UART1 SOUT
++ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_SET |= 0x80000000;
++
++ // Setup GPIO line direction for UART1 SIN
++ *(volatile u32*)GPIO_B_OUTPUT_ENABLE_CLEAR |= 0x00000001;
++
++#ifdef CONFIG_ARCH_OXNAS_UART1_MODEM
++ // Route UART1 modem control lines onto external pins
++ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x78000000;
++ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 &= ~0x78000000;
++ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |= 0x78000000;
++
++ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_1 &= ~0x00000006;
++ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_1 &= ~0x00000006;
++ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_1 |= 0x00000006;
++
++ // Setup GPIO line directions for UART1 modem control lines
++ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_SET |= 0x08000000;
++ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_CLEAR |= 0x70000000;
++
++ *(volatile u32*)GPIO_B_OUTPUT_ENABLE_SET |= 0x00000004;
++ *(volatile u32*)GPIO_B_OUTPUT_ENABLE_CLEAR |= 0x00000002;
++#endif // CONFIG_ARCH_OXNAS_UART1_MODEM
++
++ // Give Linux a contiguous numbering scheme for available UARTs
++ internal_serial_port_1.line = uart_line++;
++ early_serial_setup(&internal_serial_port_1);
++#endif // CONFIG_ARCH_OXNAS_UART1
++
++#ifdef CONFIG_ARCH_OXNAS_UART2
++ // Block reset UART2
++ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART2_BIT);
++ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART2_BIT);
++
++ // Route UART2 SIN/SOUT onto external pin
++ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x00500000;
++ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 &= ~0x00500000;
++ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |= 0x00500000;
++
++ // Setup GPIO line directions for UART2 SIN/SOUT
++ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_SET |= 0x00100000;
++ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_CLEAR |= 0x00400000;
++
++#ifdef CONFIG_ARCH_OXNAS_UART2_MODEM
++ // Route UART2 modem control lines onto external pins
++ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x07800300;
++ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 &= ~0x07800300;
++ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |= 0x07800300;
++
++ // Setup GPIO line directions for UART2 modem control lines
++ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_SET |= 0x02000200;
++ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_CLEAR |= 0x05800100;
++#endif // CONFIG_ARCH_OXNAS_UART2_MODEM
++
++ // Give Linux a contiguous numbering scheme for available UARTs
++ internal_serial_port_2.line = uart_line++;
++ early_serial_setup(&internal_serial_port_2);
++#endif // CONFIG_ARCH_OXNAS_UART2
++
++#ifdef CONFIG_ARCH_OXNAS_UART3
++ // Block reset UART3
++ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART3_BIT);
++ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART3_BIT);
++
++ // Route UART3 SIN/SOUT onto external pin
++ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x000000C0;
++ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 &= ~0x000000C0;
++ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |= 0x000000C0;
++
++ // Setup GPIO line directions for UART3 SIN/SOUT
++ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_SET |= 0x00000080;
++ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_CLEAR |= 0x00000040;
++
++ // Enable UART3 interrupt
++ *(volatile u32*)SYS_CTRL_UART_CTRL |= (1UL << SYS_CTRL_UART3_IQ_EN);
++
++#ifdef CONFIG_ARCH_OXNAS_UART3_MODEM
++ // Route UART3 modem control lines onto external pins
++ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x0000003f;
++ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 &= ~0x0000003f;
++ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |= 0x0000003f;
++
++ // Setup GPIO line directions for UART3 modem control lines
++ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_SET |= 0x00000030;
++ *(volatile u32*)GPIO_A_OUTPUT_ENABLE_CLEAR |= 0x0000000f;
++#endif // CONFIG_ARCH_OXNAS_UART3_MODEM
++
++ // Give Linux a contiguous numbering scheme for available UARTs
++ internal_serial_port_3.line = uart_line++;
++ early_serial_setup(&internal_serial_port_3);
++#endif // CONFIG_ARCH_OXNAS_UART3
++
++#ifdef CONFIG_ARCH_OXNAS_UART4
++ // Block reset UART4
++ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART4_BIT);
++ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART4_BIT);
++
++ // Enable UART4 interrupt
++ *(volatile u32*)SYS_CTRL_UART_CTRL |= (1UL << SYS_CTRL_UART4_IQ_EN);
++
++ // Enable UART4 to override PCI functions onto GPIOs
++ *(volatile u32*)SYS_CTRL_UART_CTRL |= (1UL << SYS_CTRL_UART4_NOT_PCI_MODE);
++
++ internal_serial_port_4.line = uart_line++;
++ early_serial_setup(&internal_serial_port_4);
++#endif // CONFIG_ARCH_OXNAS_UART4
++
++#ifdef CONFIG_PCI
++ // Block reset PCI core
++ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_PCI_BIT);
++ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_PCI_BIT);
++
++ // Setup the PCI clock divider
++ {
++ static const u32 PCIDIV_MASK = (((1UL << SYS_CTRL_CKCTRL_CTRL_PCIDIV_NUM_BITS) - 1) << SYS_CTRL_CKCTRL_CTRL_PCIDIV_BIT);
++ *(volatile u32*)SYS_CTRL_CKCTRL_CTRL &= ~PCIDIV_MASK;
++ *(volatile u32*)SYS_CTRL_CKCTRL_CTRL |= (PCI_CLOCK_DIVIDER << SYS_CTRL_CKCTRL_CTRL_PCIDIV_BIT);
++ }
++
++ // Enable clock to PCI core
++ *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_PCI_BIT);
++
++ // Enable auto-arbitration between static and PCI
++ *(u32*)SYS_CTRL_PCI_CTRL1 &= ~(1UL << SYSCTL_PCI_CTRL1_SYSPCI_STATIC_REQ);
++
++ // Enable primary function on PCI clock line to be looped back
++ writel(readl(PCI_CLOCK_PRISEL_REG) | PCI_CLOCK_MASK, PCI_CLOCK_PRISEL_REG);
++
++ // Enable GPIO output on PCI clock line to be looped back
++ writel(PCI_CLOCK_MASK, PCI_CLOCK_SET_OE_REG);
++
++#ifdef CONFIG_OXNAS_PCI_RESET
++ // Disable primary, secondary and teriary GPIO functions on PCI reset line
++ writel(readl(PCI_RESET_PRISEL_REG) & ~PCI_RESET_MASK, PCI_RESET_PRISEL_REG);
++ writel(readl(PCI_RESET_SECSEL_REG) & ~PCI_RESET_MASK, PCI_RESET_SECSEL_REG);
++ writel(readl(PCI_RESET_TERSEL_REG) & ~PCI_RESET_MASK, PCI_RESET_TERSEL_REG);
++
++ // Assert PCI reset from GPIO line
++ writel(PCI_RESET_MASK, PCI_RESET_OUTPUT_CLR_REG);
++
++ // Enable GPIO output on PCI reset line
++ writel(PCI_RESET_MASK, PCI_RESET_SET_OE_REG);
++
++ // Wait awhile for PCI reset to take effect
++ mdelay(100);
++
++ // Deassert PCI reset from GPIO line
++ writel(PCI_RESET_MASK, PCI_RESET_OUTPUT_SET_REG);
++#endif // CONFIG_OXNAS_PCI_RESET
++#endif // CONFIG_PCI
++
++#ifdef CONFIG_OXNAS_SATA_POWER_1
++ // Disable primary, secondary and teriary GPIO functions on SATA 1 power line
++ writel(readl(SATA_POWER_1_PRISEL_REG) & ~SATA_POWER_1_MASK, SATA_POWER_1_PRISEL_REG);
++ writel(readl(SATA_POWER_1_SECSEL_REG) & ~SATA_POWER_1_MASK, SATA_POWER_1_SECSEL_REG);
++ writel(readl(SATA_POWER_1_TERSEL_REG) & ~SATA_POWER_1_MASK, SATA_POWER_1_TERSEL_REG);
++
++ // Enable power to SATA 1
++ writel(SATA_POWER_1_MASK, SATA_POWER_1_OUTPUT_SET_REG);
++
++ // Enable GPIO output on SATA 1 power line
++ writel(SATA_POWER_1_MASK, SATA_POWER_1_SET_OE_REG);
++#endif // CONFIG_OXNAS_SATA_POWER_1
++
++#ifdef CONFIG_OXNAS_SATA_POWER_2
++ // Disable primary, secondary and teriary GPIO functions on SATA 2 power line
++ writel(readl(SATA_POWER_2_PRISEL_REG) & ~SATA_POWER_2_MASK, SATA_POWER_2_PRISEL_REG);
++ writel(readl(SATA_POWER_2_SECSEL_REG) & ~SATA_POWER_2_MASK, SATA_POWER_2_SECSEL_REG);
++ writel(readl(SATA_POWER_2_TERSEL_REG) & ~SATA_POWER_2_MASK, SATA_POWER_2_TERSEL_REG);
++
++ // Enable power to SATA 2
++ writel(SATA_POWER_2_MASK, SATA_POWER_2_OUTPUT_SET_REG);
++
++ // Enable GPIO output on SATA 2 power line
++ writel(SATA_POWER_2_MASK, SATA_POWER_2_SET_OE_REG);
++#endif // CONFIG_OXNAS_SATA_POWER_2
++
++#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES_GPIO
++ // Use GPIO 6 (normally PCI Req 6) for copies instrumentation
++ #define INSTRUMENT_COPIES_GPIO_MASK ((1UL << 6) | (1UL << 7))
++
++ // Enable normal GPIO on line
++ writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) & ~INSTRUMENT_COPIES_GPIO_MASK, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
++ writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0) & ~INSTRUMENT_COPIES_GPIO_MASK, SYS_CTRL_GPIO_SECSEL_CTRL_0);
++ writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0) & ~INSTRUMENT_COPIES_GPIO_MASK, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
++
++ // Set line inactive to begin with
++ writel(INSTRUMENT_COPIES_GPIO_MASK, GPIO_A_OUTPUT_CLEAR);
++
++ // Enable line as an output
++ writel(INSTRUMENT_COPIES_GPIO_MASK, GPIO_A_OUTPUT_ENABLE_SET);
++#endif // CONFIG_OXNAS_INSTRUMENT_COPIES_GPIO
++
++#ifdef CONFIG_OXNAS_USB_CKOUT
++ // Enable secondary function (USB clock out) on GPIO 10
++ writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) & ~(1UL << 10), SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
++ writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0) | (1UL << 10), SYS_CTRL_GPIO_SECSEL_CTRL_0);
++#endif // CONFIG_OXNAS_USB_CKOUT
++
++#ifdef CONFIG_OXNAS_USB_HUB_RESET_CONTROL
++ // Disable primary, secondary and teriary GPIO functions on USB hub reset control line
++ writel(readl(USB_HUB_RESET_PRISEL_REG) & ~USB_HUB_RESET_MASK, USB_HUB_RESET_PRISEL_REG);
++ writel(readl(USB_HUB_RESET_SECSEL_REG) & ~USB_HUB_RESET_MASK, USB_HUB_RESET_SECSEL_REG);
++ writel(readl(USB_HUB_RESET_TERSEL_REG) & ~USB_HUB_RESET_MASK, USB_HUB_RESET_TERSEL_REG);
++
++#ifdef CONFIG_OXNAS_USB_HUB_RESET_TOGGLE
++ // Assert USB hub reset
++ writel(USB_HUB_RESET_MASK, CONFIG_OXNAS_USB_HUB_RESET_ACTIVE_HIGH ? USB_HUB_RESET_OUTPUT_SET_REG : USB_HUB_RESET_OUTPUT_CLR_REG);
++#else
++ // Deassert USB hub reset
++ writel(USB_HUB_RESET_MASK, CONFIG_OXNAS_USB_HUB_RESET_ACTIVE_HIGH ? USB_HUB_RESET_OUTPUT_CLR_REG : USB_HUB_RESET_OUTPUT_SET_REG);
++#endif // CONFIG_OXNAS_USB_HUB_RESET_TOGGLE
++
++ // Enable GPIO output on USB hub reset line
++ writel(USB_HUB_RESET_MASK, USB_HUB_RESET_SET_OE_REG);
++
++#ifdef CONFIG_OXNAS_USB_HUB_RESET_TOGGLE
++ if (CONFIG_OXNAS_USB_HUB_RESET_PERIOD_MS > 0) {
++ // Wait for USB hub reset toggle assertion time
++ mdelay(CONFIG_OXNAS_USB_HUB_RESET_PERIOD_MS);
++ }
++
++ // Deassert USB hub reset
++ writel(USB_HUB_RESET_MASK, CONFIG_OXNAS_USB_HUB_RESET_ACTIVE_HIGH ? USB_HUB_RESET_OUTPUT_CLR_REG : USB_HUB_RESET_OUTPUT_SET_REG);
++#endif // CONFIG_OXNAS_USB_HUB_RESET_TOGGLE
++
++#endif // CONFIG_OXNAS_USB_HUB_RESET_CONTROL
++}
++
++static void __init oxnas_fixup(
++ struct machine_desc *desc,
++ struct tag *tags,
++ char **cmdline,
++ struct meminfo *mi)
++{
++
++ mi->nr_banks = 0;
++ mi->bank[mi->nr_banks].start = SDRAM_PA;
++ mi->bank[mi->nr_banks].size = SDRAM_SIZE;
++ mi->bank[mi->nr_banks].node = mi->nr_banks;
++ ++mi->nr_banks;
++#ifdef CONFIG_DISCONTIGMEM
++ mi->bank[mi->nr_banks].start = SRAM_PA;
++ mi->bank[mi->nr_banks].size = SRAM_SIZE;
++#ifdef LEON_IMAGE_IN_SRAM
++ mi->bank[mi->nr_banks].size -= LEON_IMAGE_SIZE;
++#endif
++ mi->bank[mi->nr_banks].node = mi->nr_banks;
++ ++mi->nr_banks;
++#endif
++
++//printk(KERN_NOTICE "%d memory %s\n", mi->nr_banks, (mi->nr_banks > 1) ? "regions" : "region");
++}
++
++#ifdef CONFIG_DO_MEM_TEST
++static void __init oxnas_asm_copy(void* dst, void* src, u32 length)
++{
++ // Assume the length is consistent with transfering 8 quads per load/store
++ asm volatile(
++ "1:ldmia %0!, {r3, r4, r5, r6, r7, r8, r9, r12};"
++ "subs %2, %2, #32;"
++ "stmia %1!, {r3, r4, r5, r6, r7, r8, r9, r12};"
++ "bne 1b;"
++ :
++ : "r" (src), "r" (dst), "r" (length)
++ : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r12");
++}
++
++static void __init oxnas_mem_test(void)
++{
++ static const unsigned BUFFER_SIZE_CHARS = 16*1024;
++ static const unsigned BUFFER_ELEMENTS = (BUFFER_SIZE_CHARS / sizeof(unsigned long));
++
++ dma_addr_t dma_address;
++ unsigned long* buffer;
++
++ buffer = dma_alloc_coherent(0, BUFFER_SIZE_CHARS, &dma_address, GFP_KERNEL | GFP_DMA);
++ if (!buffer) {
++ printk(KERN_ERR "$RFailed to allocate ucached/unbuffered memory test buffer\n");
++ } else {
++ static const int ITERATIONS = 10;
++
++ unsigned long* buf1 = buffer;
++ unsigned long* buf2 = buffer + (BUFFER_ELEMENTS/2);
++ int j;
++ u32* time1 = (u32*)kmalloc(ITERATIONS *sizeof(u32), GFP_KERNEL);
++ u32* time2 = (u32*)kmalloc(ITERATIONS *sizeof(u32), GFP_KERNEL);
++
++ BUG_ON(!time1 || !time2);
++
++ printk("Uncached/unbuffered: src = 0x%08x, dst = 0x%08x, length = %u, elements = %u, dma_address = 0x%08x\n", (u32)buf1, (u32)buf2, BUFFER_SIZE_CHARS/2, BUFFER_ELEMENTS/2, dma_address);
++
++ printk("\nAll accesses:\n");
++ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, 0, 0, 0, 0);
++
++ for (j=0; j < ITERATIONS; j++) {
++ unsigned long* src = buf1;
++ unsigned long* dst = buf2;
++// int i;
++
++ time1[j] = readl(TIMER2_VALUE);
++// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
++ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
++// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
++// *dst++ = *src++;
++// }
++ time2[j] = readl(TIMER2_VALUE);
++ }
++ read_ahb_monitors();
++ for (j=0; j < ITERATIONS; j++) {
++ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
++ }
++
++ printk("\nNon-burst accesses:\n");
++ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_SINGLE, 0, 0);
++ for (j=0; j < ITERATIONS; j++) {
++ unsigned long* src = buf1;
++ unsigned long* dst = buf2;
++// int i;
++
++ time1[j] = readl(TIMER2_VALUE);
++// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
++ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
++// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
++// *dst++ = *src++;
++// }
++ time2[j] = readl(TIMER2_VALUE);
++ }
++ read_ahb_monitors();
++ for (j=0; j < ITERATIONS; j++) {
++ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
++ }
++
++ printk("\nINCR accesses:\n");
++ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_INCR, 0, 0);
++ for (j=0; j < ITERATIONS; j++) {
++ unsigned long* src = buf1;
++ unsigned long* dst = buf2;
++// int i;
++
++ time1[j] = readl(TIMER2_VALUE);
++// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
++ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
++// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
++// *dst++ = *src++;
++// }
++ time2[j] = readl(TIMER2_VALUE);
++ }
++ read_ahb_monitors();
++ for (j=0; j < ITERATIONS; j++) {
++ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
++ }
++
++ printk("\nWRAP4 accesses:\n");
++ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_WRAP4, 0, 0);
++ for (j=0; j < ITERATIONS; j++) {
++ unsigned long* src = buf1;
++ unsigned long* dst = buf2;
++// int i;
++
++ time1[j] = readl(TIMER2_VALUE);
++// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
++ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
++// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
++// *dst++ = *src++;
++// }
++ time2[j] = readl(TIMER2_VALUE);
++ }
++ read_ahb_monitors();
++ for (j=0; j < ITERATIONS; j++) {
++ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
++ }
++
++ printk("\nINCR4 accesses:\n");
++ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_INCR4, 0, 0);
++ for (j=0; j < ITERATIONS; j++) {
++ unsigned long* src = buf1;
++ unsigned long* dst = buf2;
++// int i;
++
++ time1[j] = readl(TIMER2_VALUE);
++// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
++ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
++// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
++// *dst++ = *src++;
++// }
++ time2[j] = readl(TIMER2_VALUE);
++ }
++ read_ahb_monitors();
++ for (j=0; j < ITERATIONS; j++) {
++ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
++ }
++
++ printk("\nWRAP8 accesses:\n");
++ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_WRAP8, 0, 0);
++ for (j=0; j < ITERATIONS; j++) {
++ unsigned long* src = buf1;
++ unsigned long* dst = buf2;
++// int i;
++
++ time1[j] = readl(TIMER2_VALUE);
++// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
++ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
++// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
++// *dst++ = *src++;
++// }
++ time2[j] = readl(TIMER2_VALUE);
++ }
++ read_ahb_monitors();
++ for (j=0; j < ITERATIONS; j++) {
++ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
++ }
++
++ printk("\nINCR8 accesses:\n");
++ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_INCR8, 0, 0);
++ for (j=0; j < ITERATIONS; j++) {
++ unsigned long* src = buf1;
++ unsigned long* dst = buf2;
++// int i;
++
++ time1[j] = readl(TIMER2_VALUE);
++// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
++ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
++// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
++// *dst++ = *src++;
++// }
++ time2[j] = readl(TIMER2_VALUE);
++ }
++ read_ahb_monitors();
++ for (j=0; j < ITERATIONS; j++) {
++ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
++ }
++
++ printk("\nWRAP16 accesses:\n");
++ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_WRAP16, 0, 0);
++ for (j=0; j < ITERATIONS; j++) {
++ unsigned long* src = buf1;
++ unsigned long* dst = buf2;
++// int i;
++
++ time1[j] = readl(TIMER2_VALUE);
++// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
++ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
++// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
++// *dst++ = *src++;
++// }
++ time2[j] = readl(TIMER2_VALUE);
++ }
++ read_ahb_monitors();
++ for (j=0; j < ITERATIONS; j++) {
++ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
++ }
++
++ printk("\nINCR16 accesses:\n");
++ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, ~0, AHB_MON_HBURST_INCR16, 0, 0);
++ for (j=0; j < ITERATIONS; j++) {
++ unsigned long* src = buf1;
++ unsigned long* dst = buf2;
++// int i;
++
++ time1[j] = readl(TIMER2_VALUE);
++// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
++ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
++// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
++// *dst++ = *src++;
++// }
++ time2[j] = readl(TIMER2_VALUE);
++ }
++ read_ahb_monitors();
++ for (j=0; j < ITERATIONS; j++) {
++ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
++ }
++
++ dma_free_coherent(0, BUFFER_SIZE_CHARS, buffer, dma_address);
++
++ kfree(time1);
++ kfree(time2);
++ }
++
++ buffer = kmalloc(BUFFER_SIZE_CHARS, GFP_KERNEL | GFP_DMA);
++ if (!buffer) {
++ printk(KERN_ERR "$RFailed to allocate cached memory test buffer\n");
++ } else {
++ static const int ITERATIONS = 100;
++
++ unsigned long* buf1 = buffer;
++ unsigned long* buf2 = buffer + (BUFFER_ELEMENTS/2);
++ unsigned long* src = buf1;
++ unsigned long* dst = buf2;
++ int j;
++ u32* time1 = (u32*)kmalloc(ITERATIONS *sizeof(u32), GFP_KERNEL);
++ u32* time2 = (u32*)kmalloc(ITERATIONS *sizeof(u32), GFP_KERNEL);
++
++ BUG_ON(!time1 || !time2);
++
++ printk("Cached/: src = 0x%08x, dst = 0x%08x, length = %u, elements = %u\n", (u32)buf1, (u32)buf2, BUFFER_SIZE_CHARS/2, BUFFER_ELEMENTS/2);
++
++ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, 0, 0, 0, 0);
++
++ // Measure the first cached iteration separately
++ printk("1st iteration:\n");
++ restart_ahb_monitors();
++ time1[0] = readl(TIMER2_VALUE);
++// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
++ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
++// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
++// *dst++ = *src++;
++// }
++ time2[0] = readl(TIMER2_VALUE);
++ read_ahb_monitors();
++ printk("%u->%lu Bytes/s\n", time1[0]-time2[0], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[0]-time2[0]));
++
++ printk("Subsequent iterations:\n");
++ restart_ahb_monitors();
++ for (j=1; j < ITERATIONS; j++) {
++ src = buf1;
++ dst = buf2;
++// int i;
++
++ time1[j] = readl(TIMER2_VALUE);
++// memcpy(dst, src, BUFFER_SIZE_CHARS/2);
++ oxnas_asm_copy(dst, src, BUFFER_SIZE_CHARS/2);
++// for (i=0; i<BUFFER_ELEMENTS/2; i++) {
++// *dst++ = *src++;
++// }
++ time2[j] = readl(TIMER2_VALUE);
++ }
++ read_ahb_monitors();
++
++ for (j=1; j < ITERATIONS; j++) {
++ printk("%u->%lu Bytes/s\n", time1[j]-time2[j], 100000UL * (BUFFER_SIZE_CHARS/2) / (time1[j]-time2[j]));
++ }
++
++ kfree(time1);
++ kfree(time2);
++
++ kfree(buffer);
++ }
++}
++#endif // CONFIG_DO_MEM_TEST
++
++#ifdef CONFIG_OXNAS_LED_TEST
++
++#define LED_D1 (1UL << 6)
++#define LED_D2 (1UL << 7)
++#define LED_D3 (1UL << 13)
++#define LED_D4 (1UL << 14)
++#define LED_D5 (1UL << 19)
++#define LED_D6 (1UL << 21)
++#define LED_D7 (1UL << 25)
++#define LED_D8 (1UL << 26)
++#define LED_D9 (1UL << 27)
++#define FIRST_LEDS_MASK (LED_D1 | LED_D2 | LED_D3 | LED_D4 | LED_D5 | LED_D6 | LED_D7 | LED_D8 | LED_D9)
++
++#define LED_D10 (1UL << 1)
++#define SECOND_LEDS_MASK (LED_D10)
++
++#define PWM_MASK (1UL << 8)
++
++static void test_leds_and_pwm(void)
++{
++ // Disable primary, secondary and teriary GPIO functions for first nine LEDS
++ writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) & ~FIRST_LEDS_MASK, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
++ writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0) & ~FIRST_LEDS_MASK, SYS_CTRL_GPIO_SECSEL_CTRL_0);
++ writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0) & ~FIRST_LEDS_MASK, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
++
++ // Disable primary, secondary and teriary GPIO functions for last LED
++ writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_1) & ~SECOND_LEDS_MASK, SYS_CTRL_GPIO_PRIMSEL_CTRL_1);
++ writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_1) & ~SECOND_LEDS_MASK, SYS_CTRL_GPIO_SECSEL_CTRL_1);
++ writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_1) & ~SECOND_LEDS_MASK, SYS_CTRL_GPIO_TERTSEL_CTRL_1);
++
++ // Turn off first nine LEDs
++ writel(FIRST_LEDS_MASK, GPIO_A_OUTPUT_SET);
++
++ // Turn off tenth LED
++ writel(SECOND_LEDS_MASK, GPIO_B_OUTPUT_SET);
++
++ // Enable first nine LEDs as outputs
++ writel(FIRST_LEDS_MASK, GPIO_A_OUTPUT_ENABLE_SET);
++
++ // Enable tenth LED as output
++ writel(SECOND_LEDS_MASK, GPIO_B_OUTPUT_ENABLE_SET);
++
++ // Turn on first nine LEDs sequentially
++ mdelay(1000);
++ writel(LED_D1, GPIO_A_OUTPUT_CLEAR);
++ mdelay(1000);
++ writel(LED_D2, GPIO_A_OUTPUT_CLEAR);
++ mdelay(1000);
++ writel(LED_D3, GPIO_A_OUTPUT_CLEAR);
++ mdelay(1000);
++ writel(LED_D4, GPIO_A_OUTPUT_CLEAR);
++ mdelay(1000);
++ writel(LED_D5, GPIO_A_OUTPUT_CLEAR);
++ mdelay(1000);
++ writel(LED_D6, GPIO_A_OUTPUT_CLEAR);
++ mdelay(1000);
++ writel(LED_D7, GPIO_A_OUTPUT_CLEAR);
++ mdelay(1000);
++ writel(LED_D8, GPIO_A_OUTPUT_CLEAR);
++ mdelay(1000);
++ writel(LED_D9, GPIO_A_OUTPUT_CLEAR);
++
++ // Turn on tenth LED
++ mdelay(1000);
++ writel(LED_D10, GPIO_B_OUTPUT_CLEAR);
++
++ // Disable primary, secondary and teriary GPIO functions for PWN line
++ writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) & ~PWM_MASK, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
++ writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0) & ~PWM_MASK, SYS_CTRL_GPIO_SECSEL_CTRL_0);
++ writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0) & ~PWM_MASK, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
++
++ // Turn off PWM line
++ writel(PWM_MASK, GPIO_A_OUTPUT_SET);
++
++ // Enable PWM line as output
++ writel(PWM_MASK, GPIO_A_OUTPUT_ENABLE_SET);
++
++ // Turn on PWM line
++ mdelay(1000);
++ writel(PWM_MASK, GPIO_A_OUTPUT_CLEAR);
++}
++#endif // CONFIG_OXNAS_LED_TEST
++
++static void __init oxnas_init_machine(void)
++{
++//printk("oxnas_init_machine()\n");
++ /* Initialise the spinlock used to make GPIO register set access atomic */
++ spin_lock_init(&oxnas_gpio_spinlock);
++
++ /*
++ * Initialise the support for our multi-channel memory-to-memory DMAC
++ * The interrupt subsystem needs to be available before we can initialise
++ * the DMAC support
++ */
++ oxnas_dma_init();
++
++#ifdef CONFIG_DO_MEM_TEST
++ /*
++ * Do memory performance test
++ */
++ oxnas_mem_test();
++#endif // CONFIG_DO_MEM_TEST
++
++#ifdef CONFIG_LEON_START_EARLY
++ init_copro(leon_early_srec, 0);
++#endif // CONFIG_LEON_START_EARLY
++
++#ifdef CONFIG_OXNAS_LED_TEST
++ test_leds_and_pwm();
++#endif // CONFIG_OXNAS_LED_TEST
++
++ // Add any platform bus devices
++ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
++}
++
++void sata_power_off(void)
++{
++#ifdef CONFIG_OXNAS_SATA_POWER_1
++ // Disable power to SATA 1
++ printk(KERN_INFO "Turning off disk 1\n");
++ writel(SATA_POWER_1_MASK, SATA_POWER_1_OUTPUT_CLR_REG);
++#endif // CONFIG_OXNAS_SATA_POWER_1
++
++#ifdef CONFIG_OXNAS_SATA_POWER_2
++ // Disable power to SATA 2
++ printk(KERN_INFO "Turning off disk 2\n");
++ writel(SATA_POWER_2_MASK, SATA_POWER_2_OUTPUT_CLR_REG);
++#endif // CONFIG_OXNAS_SATA_POWER_2
++}
++
++MACHINE_START(OXNAS, "Oxsemi NAS")
++ /* Maintainer: Oxford Semiconductor Ltd */
++#ifdef CONFIG_ARCH_OXNAS_UART1
++ .phys_io = UART_1_BASE_PA,
++ .io_pg_offst = (((u32)UART_1_BASE) >> 18) & 0xfffc,
++#elif defined(CONFIG_ARCH_OXNAS_UART2)
++ .phys_io = UART_2_BASE_PA,
++ .io_pg_offst = (((u32)UART_2_BASE) >> 18) & 0xfffc,
++#elif defined(CONFIG_ARCH_OXNAS_UART3)
++ .phys_io = UART_3_BASE_PA,
++ .io_pg_offst = (((u32)UART_3_BASE) >> 18) & 0xfffc,
++#elif defined(CONFIG_ARCH_OXNAS_UART4)
++ .phys_io = UART_4_BASE_PA,
++ .io_pg_offst = (((u32)UART_4_BASE) >> 18) & 0xfffc,
++#endif
++ .boot_params = SDRAM_PA + 0x100,
++ .fixup = oxnas_fixup,
++ .map_io = oxnas_mapio,
++ .init_irq = oxnas_init_irq,
++ .timer = &oxnas_timer,
++ .init_machine = oxnas_init_machine,
++MACHINE_END
++
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/pci.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/pci.c
+--- linux-2.6.24/arch/arm/mach-oxnas/pci.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/pci.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,678 @@
++/*
++ * arch/arm/mach-oxnas/pci.c
++ *
++ * Copyright (C) 2006 Oxford Semiconductor Ltd
++ *
++ * 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 <linux/kernel.h>
++
++#include <linux/pci.h>
++#include <linux/ptrace.h>
++#include <linux/interrupt.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++
++#include <asm/io.h>
++#include <asm/hardware.h>
++#include <asm/irq.h>
++#include <asm/system.h>
++#include <asm/mach/pci.h>
++#include <asm/mach-types.h>
++
++#ifndef CONFIG_PCI
++
++inline void outb(unsigned char v, u32 p) { *((volatile u8*)(__io(p))) = (v); }
++inline void outw(unsigned short v, u32 p) { *((volatile u16*)(__io(p))) = cpu_to_le16(v); }
++inline void outl(unsigned long v, u32 p) { *((volatile u32*)(__io(p))) = cpu_to_le32(v); }
++
++inline unsigned char inb(u32 p) { return (*((volatile u8*)(__io(p)))); }
++inline unsigned short inw(u32 p) { return le16_to_cpu(*((volatile u16*)(__io(p)))); }
++inline unsigned long inl(u32 p) { return le32_to_cpu(*((volatile u32*)(__io(p)))); }
++
++inline void outsb(u32 p, unsigned char * from, u32 len) { while (len--) { outb((*from++),(p) ); } }
++inline void outsw(u32 p, unsigned short * from, u32 len) { while (len--) { outw((*from++),(p) ); } }
++inline void outsl(u32 p, unsigned long * from, u32 len) { while (len--) { outl((*from++),(p) ); } }
++
++inline void insb(u32 p, unsigned char * to, u32 len) { while (len--) { *to++ = inb(p); } }
++inline void insw(u32 p, unsigned short * to, u32 len) { while (len--) { *to++ = inw(p); } }
++inline void insl(u32 p, unsigned long * to, u32 len) { while (len--) { *to++ = inl(p); } }
++
++EXPORT_SYMBOL( inb );
++EXPORT_SYMBOL( inw );
++EXPORT_SYMBOL( inl );
++
++EXPORT_SYMBOL( outb );
++EXPORT_SYMBOL( outw );
++EXPORT_SYMBOL( outl );
++
++EXPORT_SYMBOL( insb );
++EXPORT_SYMBOL( insw );
++EXPORT_SYMBOL( insl );
++
++EXPORT_SYMBOL( outsb );
++EXPORT_SYMBOL( outsw );
++EXPORT_SYMBOL( outsl );
++
++#else // #ifdef CONFIG_PCI
++
++extern spinlock_t oxnas_gpio_spinlock;
++
++#define PCI_BUS_NONMEM_START 0x00000000
++#define PCI_BUS_NONMEM_SIZE 0x00080000
++
++
++#define PCI_BUS_PREMEM_START PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE
++#define PCI_BUS_PREMEM_SIZE 0x00080000
++
++#define SYNOPSYS_PCI_MEMORY_BASE_ADDRESS PCI_BASE_ADDRESS_0
++#define SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS PCI_BASE_ADDRESS_2
++#define SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS PCI_BASE_ADDRESS_1 // PLEASE NOTE - THESE ARE INCORRECT IN THE DOCUMENT!!
++
++
++inline void outb(unsigned char v, u32 p) { pciio_write(v,(u32)__io(p), sizeof(char ) ); }
++inline void outw(unsigned short v, u32 p) { pciio_write(cpu_to_le16(v),(u32)__io(p),sizeof(short) ); }
++inline void outl(unsigned long v, u32 p) { pciio_write(cpu_to_le32(v),(u32)__io(p),sizeof(long ) ); }
++
++inline unsigned char inb(u32 p) { unsigned int __v = (pciio_read((u32)__io(p),sizeof(char ))); return __v; }
++inline unsigned short inw(u32 p) { unsigned int __v = le16_to_cpu(pciio_read((u32)__io(p),sizeof(short))); return __v; }
++inline unsigned long inl(u32 p) { unsigned int __v = le32_to_cpu(pciio_read((u32)__io(p),sizeof(long ))); return __v; }
++
++inline void outsb(volatile u32 p, unsigned char * from, u32 len) { while (len--) { pciio_write( (*from++),(u32)__io(p),sizeof(char ) ); } }
++inline void outsw(volatile u32 p, unsigned short * from, u32 len) { while (len--) { pciio_write(cpu_to_le16(*from++),(u32)__io(p),sizeof(short) ); } }
++inline void outsl(volatile u32 p, unsigned long * from, u32 len) { while (len--) { pciio_write(cpu_to_le32(*from++),(u32)__io(p),sizeof(long ) ); } }
++
++inline void insb(volatile u32 p, unsigned char * to, u32 len) { while (len--) { *to++ = (pciio_read((u32)__io(p),sizeof(char ))); } }
++inline void insw(volatile u32 p, unsigned short * to, u32 len) { while (len--) { *to++ = le16_to_cpu(pciio_read((u32)__io(p),sizeof(short))); } }
++inline void insl(volatile u32 p, unsigned long * to, u32 len) { while (len--) { *to++ = le32_to_cpu(pciio_read((u32)__io(p),sizeof(long ))); } }
++
++EXPORT_SYMBOL( inb );
++EXPORT_SYMBOL( inw );
++EXPORT_SYMBOL( inl );
++
++EXPORT_SYMBOL( outb );
++EXPORT_SYMBOL( outw );
++EXPORT_SYMBOL( outl );
++
++EXPORT_SYMBOL( insb );
++EXPORT_SYMBOL( insw );
++EXPORT_SYMBOL( insl );
++
++EXPORT_SYMBOL( outsb );
++EXPORT_SYMBOL( outsw );
++EXPORT_SYMBOL( outsl );
++
++EXPORT_SYMBOL( pciio_read );
++EXPORT_SYMBOL( pciio_write );
++
++static spinlock_t oxnas_lock = SPIN_LOCK_UNLOCKED;
++
++//static int oxnas_pci_read_core_config( unsigned int config_register )
++//{
++// unsigned long val, flags;
++// //printk(KERN_DEBUG "PCI: oxnas_pci_read_core_config( 0x%x )\n", config_register );
++// spin_lock_irqsave(&oxnas_lock, flags);
++// writel(
++// 0x00 << PCI_CRP_BYTE_ENABLES_START |
++// PCI_BUS_CMD_CONFIGURATION_READ << PCI_CRP_CMD_START |
++// config_register << PCI_CRP_ADDRESS_START,
++// PCI_CRP_CMD_AND_ADDR );
++// wmb();
++// val = readl( PCI_CRP_READ_DATA );
++// spin_unlock_irqrestore(&oxnas_lock, flags);
++// return val;
++//}
++
++
++static void oxnas_pci_write_core_config( unsigned int value, unsigned int config_register )
++{
++ unsigned long flags;
++
++ //printk(KERN_DEBUG "PCI: oxnas_pci_write_core_config( 0x%x, 0x%x )\n", config_register , value);
++ /* printk(KERN_DEBUG "PCI: writel( 0x%lx, 0x%lx )\n",
++ 0x00 << PCI_CRP_BYTE_ENABLES_START |
++ PCI_BUS_CMD_CONFIGURATION_WRITE << PCI_CRP_CMD_START |
++ config_register << PCI_CRP_ADDRESS_START,
++ PCI_CRP_CMD_AND_ADDR ); */
++
++ spin_lock_irqsave(&oxnas_lock, flags);
++ writel(
++ 0x00 << PCI_CRP_BYTE_ENABLES_START |
++ PCI_BUS_CMD_CONFIGURATION_WRITE << PCI_CRP_CMD_START |
++ config_register << PCI_CRP_ADDRESS_START,
++ PCI_CRP_CMD_AND_ADDR );
++ wmb();
++
++ // printk(KERN_DEBUG "PCI: writel( 0x%lx, 0x%lx )\n", value, PCI_CRP_WRITE_DATA );
++ writel( value, PCI_CRP_WRITE_DATA );
++ spin_unlock_irqrestore(&oxnas_lock, flags);
++}
++
++
++
++inline unsigned int CheckAndClearBusError(void)
++{
++ unsigned int value = readl( PCI_ERROR_MSG ) & 0x00000003;
++ if ( value )
++ {
++// printk(KERN_DEBUG "PCI: %s ERROR ON PCI BUS Clearing error\n", value & 0x00000001 ? "FATAL" : "PARITY" );
++ writel( ( value ), PCI_ERROR_MSG );
++ }
++
++ return value;
++}
++
++
++void pciio_write(unsigned int data, u32 addr, unsigned int size)
++{
++ // setup byte enables
++ unsigned long flags;
++ unsigned int be = 0x0000000f >> (4-size);
++ unsigned int trunc = (addr & 0x00000003);
++ be <<= trunc;
++ be = (~be) & 0x00000000f;
++
++
++ data &= (0xffffffff >> ((4-size)*8));
++ data <<= (trunc*8);
++
++ //printk(KERN_DEBUG "$YPCI: pciio_write( 0x%08x = 0x%08x (%x:%x) )\n", addr, data, size, be);
++
++ /* Setup the io read address (rounded down to word boundry) */
++ spin_lock_irqsave(&oxnas_lock, flags);
++ writel( addr , PCI_CONFIG_IO_CYCLE_ADDR );
++ wmb();
++
++ /* issue the config io read command to the config io cmd reg */
++ writel( ( be << PCI_CONFIG_IO_BYTE_ENABLES_START) |
++ ( PCI_BUS_CMD_IO_WRITE << PCI_CONFIG_IO_CMD_START ),
++ PCI_CONFIG_IO_BYTE_CMD );
++ wmb();
++
++ writel( data, PCI_CONFIG_IO_WRITE_DATA );
++
++ if ( CheckAndClearBusError() )
++ {
++ printk(KERN_DEBUG "PCI: failed to write io\n");
++ }
++ spin_unlock_irqrestore(&oxnas_lock, flags);
++}
++
++
++unsigned int pciio_read(u32 addr, unsigned int size)
++{
++ // setup byte enables
++ unsigned long flags;
++ unsigned int be = 0x0000000f >> (4-size);
++ unsigned int trunc = (addr & 0x00000003);
++ be <<= trunc;
++ be = (~be) & 0x00000000f;
++
++
++ //printk(KERN_DEBUG "$YPCI: pciio_read[ 0x%x ] ( 0x%x == ", size, addr );
++
++ /* Setup the io read address (rounded down to word boundry) */
++ spin_lock_irqsave(&oxnas_lock, flags);
++ writel( addr, PCI_CONFIG_IO_CYCLE_ADDR );
++ wmb();
++
++ /* issue the config io read command to the config io cmd reg */
++ writel( ( be << PCI_CONFIG_IO_BYTE_ENABLES_START) |
++ ( PCI_BUS_CMD_IO_READ << PCI_CONFIG_IO_CMD_START ),
++ PCI_CONFIG_IO_BYTE_CMD );
++ wmb();
++
++ if ( CheckAndClearBusError() )
++ {
++ printk(KERN_DEBUG "PCI: failed to read io\n");
++ }
++
++ be = readl( PCI_CONFIG_IO_READ_DATA );
++ //printk("0x%x )\n", be);
++
++ if ( CheckAndClearBusError() )
++ {
++ printk(KERN_DEBUG "PCI: failed to read io\n");
++ }
++
++ spin_unlock_irqrestore(&oxnas_lock, flags);
++
++ be >>= (trunc*8);
++ be &= (0xffffffff >> ((4-size)*8));
++
++
++ return be;
++}
++
++
++static int oxnas_read_config(struct pci_bus *bus, unsigned int devfn, int where,
++ int size, u32 *value)
++{
++ // unsigned long flags;
++ unsigned long flags;
++ unsigned int temp;
++ unsigned long addr = ( 0x00000800 << (PCI_SLOT(devfn)-1) ) |
++ ( PCI_FUNC(devfn) << 8 ) |
++ ( where & 0xfc );
++
++ /* Setup the config io read address (rounded down to word boundry) */
++ temp = addr;
++
++ // printk(KERN_DEBUG "PCI: %s::%u oxnas_read_config( %u, %d, %d, )\n", bus->name, bus->number, devfn, where, size );
++ spin_lock_irqsave(&oxnas_lock, flags);
++ CheckAndClearBusError();
++
++ // printk(KERN_DEBUG "PCI: writel( 0x%08lx, 0x%08lx)\n", temp, PCI_CONFIG_IO_CYCLE_ADDR );
++ writel( temp, PCI_CONFIG_IO_CYCLE_ADDR );
++ wmb();
++
++ /* issue the config io read command to the config io cmd reg */
++ temp = ( ( 0x00 << PCI_CONFIG_IO_BYTE_ENABLES_START) |
++ ( PCI_BUS_CMD_CONFIGURATION_READ << PCI_CONFIG_IO_CMD_START ) );
++ // printk(KERN_DEBUG "PCI: writel( 0x%08lx, 0x%08lx)\n", temp, PCI_CONFIG_IO_BYTE_CMD);
++ writel( temp, PCI_CONFIG_IO_BYTE_CMD );
++ wmb();
++
++ if ( CheckAndClearBusError() )
++ {
++ spin_unlock_irqrestore(&oxnas_lock, flags);
++// printk(KERN_DEBUG "PCI: failed to read config\n" );
++ *value = 0xffffffff;
++ return PCIBIOS_DEVICE_NOT_FOUND;
++ }
++
++ wmb();
++ *value=readl(PCI_CONFIG_IO_READ_DATA);
++ spin_unlock_irqrestore(&oxnas_lock, flags);
++
++ /* Read the result from the config io read data reg */
++ switch (size) {
++ case 1:
++ // printk(KERN_DEBUG "PCI: readb( 0x%lx )\n", PCI_CONFIG_IO_READ_DATA );
++ *value>>=(where&3);
++ *value&=0x000000ff;
++ break;
++ case 2:
++ // printk(KERN_DEBUG "PCI: readw( 0x%lx )\n", PCI_CONFIG_IO_READ_DATA );
++ *value>>=(where&2);
++ *value&=0x0000ffff;
++ break;
++ case 4:
++ // printk(KERN_DEBUG "PCI: readl( 0x%lx )\n", PCI_CONFIG_IO_READ_DATA );
++ break;
++ }
++ // printk(KERN_DEBUG "PCI: $Goxnas_read_config_%s( 0x%lx ) == 0x%lx\n",
++ // size == 1 ? "byte" : size == 2 ? "short" : "word",
++ // (unsigned long) addr,
++ // (unsigned long) *value);
++
++ return PCIBIOS_SUCCESSFUL;
++}
++
++static int oxnas_write_config(struct pci_bus *bus, unsigned int devfn, int where,
++ int size, u32 value)
++{
++ unsigned long flags;
++ unsigned long byteEnables = ~(( 0xffffffff >> (32 - size) ) << (where&3));
++ unsigned long addr = ( 0x00000800 << (PCI_SLOT(devfn)-1) ) |
++ ( PCI_FUNC(devfn) << 8 ) |
++ ( where & 0xfc );
++ value <<= 8*(where & 0x00000003);
++
++ // printk(KERN_DEBUG "$GPCI: %s::%u oxnas_write_config_%s( 0x%lx, 0x%lx & 0x%lx)\n",
++ // bus->name,
++ // bus->number,
++ // size == 1 ? "byte" : size == 2 ? "short" : "word",
++ // (unsigned long) addr,
++ // (unsigned long) value,
++ // (unsigned long) byteEnables );
++
++ if ( PCI_SLOT(devfn) > 15 )
++ {
++ /* only 16 devices supported */
++ return PCIBIOS_DEVICE_NOT_FOUND;
++ }
++
++
++ spin_lock_irqsave(&oxnas_lock, flags);
++ CheckAndClearBusError();
++
++ /* Setup the config io read address (rounded down to word boundry) */
++ // printk(KERN_DEBUG "PCI: writel( 0x%lx, 0x%lx)\n", addr, PCI_CONFIG_IO_CYCLE_ADDR );
++ writel( addr, PCI_CONFIG_IO_CYCLE_ADDR );
++ wmb();
++
++ /* issue the config io read command to the config io cmd reg */
++ // printk(KERN_DEBUG "PCI: writel( 0x%lx, 0x%lx )\n",
++ // ( (byteEnables & 0xf) << PCI_CONFIG_IO_BYTE_ENABLES_START) |
++ // ( PCI_BUS_CMD_CONFIGURATION_WRITE << PCI_CONFIG_IO_CMD_START ),
++ // PCI_CONFIG_IO_BYTE_CMD );
++
++ writel( ( (byteEnables & 0xf) << PCI_CONFIG_IO_BYTE_ENABLES_START) |
++ ( PCI_BUS_CMD_CONFIGURATION_WRITE << PCI_CONFIG_IO_CMD_START ),
++ PCI_CONFIG_IO_BYTE_CMD );
++ wmb();
++
++ /* write the value... */
++ // printk(KERN_DEBUG "PCI: writel( 0x%lx, 0x%lx )\n", value, PCI_CONFIG_IO_WRITE_DATA );
++ writel( value, PCI_CONFIG_IO_WRITE_DATA );
++ wmb();
++
++ if ( CheckAndClearBusError() )
++ {
++ printk(KERN_DEBUG "PCI: failed to write config\n");
++ return PCIBIOS_DEVICE_NOT_FOUND;
++ }
++
++ spin_unlock_irqrestore(&oxnas_lock, flags);
++ return PCIBIOS_SUCCESSFUL;
++}
++
++
++// #if PCI_BUS_NONMEM_START & 0x000fffff
++// #error PCI_BUS_NONMEM_START must be megabyte aligned
++// #endif
++// #if PCI_BUS_PREMEM_START & 0x000fffff
++// #error PCI_BUS_PREMEM_START must be megabyte aligned
++// #endif
++//
++
++static struct resource io_mem = {
++ .name = "PCI I/O Space",
++ .start = 0x00001000,
++ .end = 0xffff0000,
++ .flags = IORESOURCE_IO,
++};
++
++static struct resource non_mem = {
++ .name = "PCI non-prefetchable",
++ .start = PCI_BASE_PA + PCI_BUS_NONMEM_START,
++ .end = PCI_BASE_PA + PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE - 1,
++ .flags = IORESOURCE_MEM,
++};
++
++static struct resource pre_mem = {
++ .name = "PCI prefetchable",
++ .start = PCI_BASE_PA + PCI_BUS_PREMEM_START,
++ .end = PCI_BASE_PA + PCI_BUS_PREMEM_START + PCI_BUS_PREMEM_SIZE - 1,
++ .flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,
++};
++
++
++/*
++ * This routine handles multiple bridges.
++ */
++static u8 __init oxnas_swizzle(struct pci_dev *dev, u8 *pinp)
++{
++// printk(KERN_DEBUG "PCI: oxnas_swizzle\n");
++ return pci_std_swizzle(dev, pinp);
++}
++
++
++// static int irq_tab[4] __initdata = {
++// IRQ_AP_PCIINT0, IRQ_AP_PCIINT1, IRQ_AP_PCIINT2, IRQ_AP_PCIINT3
++// };
++
++
++/*
++ * map the specified device/slot/pin to an IRQ. This works out such
++ * that ..
++ */
++static int __init oxnas_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
++{
++ BUG_ON(pin < 1 || pin > 4);
++
++// printk(KERN_DEBUG "PCI: oxnas_map_irq %d,%d,%d = %d\n", dev->bus->number, dev->devfn, slot, PCI_A_INTERRUPT /*pci_irq_table[pin-1]*/ );
++ return PCI_A_INTERRUPT;
++}
++
++
++static int __init oxnas_pci_setup_resources(struct resource **resource)
++{
++ /*
++ * bus->resource[0] is the IO resource for this bus
++ * bus->resource[1] is the mem resource for this bus
++ * bus->resource[2] is the prefetch mem resource for this bus
++ */
++
++ resource[0] = &io_mem;
++ resource[1] = &pre_mem;
++ resource[2] = &non_mem;
++
++ // these regions apply to incomming transactions on PCI
++ oxnas_pci_write_core_config( 0xffffffff , SYNOPSYS_PCI_MEMORY_BASE_ADDRESS );
++ oxnas_pci_write_core_config( 0xffffffff , SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS );
++ oxnas_pci_write_core_config( 0xffffffff , SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS );
++
++// printk(KERN_DEBUG "PCI: SYNOPSYS_PCI_MEMORY_BASE_ADDRESS $YWindow Size == 0x%08x\n", (u32) oxnas_pci_read_core_config(SYNOPSYS_PCI_MEMORY_BASE_ADDRESS ) );
++// printk(KERN_DEBUG "PCI: SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS $YWindow Size == 0x%08x\n", (u32) oxnas_pci_read_core_config(SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS ) );
++// printk(KERN_DEBUG "PCI: SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS $YWindow Size == 0x%08x\n", (u32) oxnas_pci_read_core_config(SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS ) );
++
++ oxnas_pci_write_core_config( SDRAM_PA , SYNOPSYS_PCI_MEMORY_BASE_ADDRESS );
++ oxnas_pci_write_core_config( SDRAM_PA , SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS );
++ oxnas_pci_write_core_config( SDRAM_PA , SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS );
++
++// printk(KERN_DEBUG "PCI: SYNOPSYS_PCI_MEMORY_BASE_ADDRESS == 0x%08x\n", (u32) oxnas_pci_read_core_config(SYNOPSYS_PCI_MEMORY_BASE_ADDRESS ) );
++// printk(KERN_DEBUG "PCI: SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS == 0x%08x\n", (u32) oxnas_pci_read_core_config(SYNOPSYS_PCI_DUAL_CYCLE_BASE_ADDRESS ) );
++// printk(KERN_DEBUG "PCI: SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS == 0x%08x\n", (u32) oxnas_pci_read_core_config(SYNOPSYS_PCI_IO_MEM_BASE_ADDRESS ) );
++ return 1;
++}
++
++
++int __init oxnas_pci_setup(int nr, struct pci_sys_data *sys)
++{
++ int ret = 0;
++
++// printk(KERN_DEBUG "PCI: oxnas_pci_setup nr == %u\n", nr);
++ if (nr == 0) {
++ /* the PCI core has been setup so that the top nybble is forced to 0, so
++ we need to offset by whatever is in the top nybble or the devices won't
++ recognise their memory accesses */
++ sys->mem_offset = PCI_BASE_PA & 0xf0000000 ;
++
++ // ioremap is not called on IO ports. this should shift the physical
++ // address to the statically mapped virtual one after the BARS have been
++ // setup.
++ sys->io_offset = 0;
++
++ spin_lock_init(&oxnas_lock);
++ ret = oxnas_pci_setup_resources(sys->resource);
++ }
++
++ return ret;
++}
++
++
++static struct pci_ops oxnas_pci_ops = {
++ .read = oxnas_read_config,
++ .write = oxnas_write_config,
++};
++
++
++struct pci_bus *oxnas_pci_scan_bus(int nr, struct pci_sys_data *sys)
++{
++// printk(KERN_DEBUG "PCI: oxnas_pci_scan_bus\n");
++ return pci_scan_bus(sys->busnr, &oxnas_pci_ops, sys);
++}
++
++void __init oxnas_pci_preinit(void)
++{
++ unsigned int temp;
++ unsigned long flags;
++// printk(KERN_DEBUG "PCI: oxnas_pci_preinit\n");
++
++ // Configure GPIO lines which map PCI INTA for both minipci and planar as active low
++ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
++ *((volatile unsigned long*)GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE) |= ((1UL << PCI_GPIO_INTA_MINIPCI) | (1UL << PCI_GPIO_INTA_PLANAR));
++ *((volatile unsigned long*)GPIO_A_LEVEL_INTERRUPT_ENABLE) |= ((1UL << PCI_GPIO_INTA_MINIPCI) | (1UL << PCI_GPIO_INTA_PLANAR));
++ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
++
++ /*
++ printk(KERN_DEBUG "\n\nPCI: GPIO ABse 0x%08x\n", GPIO_1_BASE );
++ for ( temp=0;temp<0x40; temp += 4 )
++ {
++ printk(KERN_DEBUG " GPIO ABse + 0x%02x == 0x%08x\n",temp, readl( GPIO_1_BASE+temp ) );
++ }
++ */
++
++ // put pci into host mode
++ temp = ( 0 << SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO5 ) |
++ ( 0 << SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO4 ) |
++ ( 0 << SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO3 ) |
++ ( 0 << SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO2 ) |
++ ( 0 << SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO1 ) |
++ ( 0 << SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO0 ) |
++ ( 0 << SYSCTL_PCI_CTRL1_ENPU ) |
++ ( 0 << SYSCTL_PCI_CTRL1_ENCB ) |
++ ( 0 << SYSCTL_PCI_CTRL1_SYSPCI_STATIC_REQ ) |
++ ( 1 << SYSCTL_PCI_CTRL1_SS_HOST_E ) |
++ ( 0 << SYSCTL_PCI_CTRL1_SYSPCI_PAKING_ENABLE ) |
++ ( 0 << SYSCTL_PCI_CTRL1_SYSPCI_PAKING_MASTE ) |
++ ( 0 << SYSCTL_PCI_CTRL1_SS_CADBUS_E ) |
++ ( 0 << SYSCTL_PCI_CTRL1_SS_MINIPCI_ ) |
++ ( 0 << SYSCTL_PCI_CTRL1_SS_INT_MASK_0 ) |
++ ( 0 << SYSCTL_PCI_CTRL1_INT_STATUS_0 ) |
++ ( 0 << SYSCTL_PCI_CTRL1_APP_EQUIES_NOM_CLK ) |
++ ( 0 << SYSCTL_PCI_CTRL1_APP_CBUS_INT_N ) |
++ ( 0 << SYSCTL_PCI_CTRL1_APP_CSTSCHG_N );
++
++// printk(KERN_DEBUG "PCI: pci into host mode - writel( 0x%08x, 0x%08x )\n", (u32) temp, (u32) (SYS_CTRL_PCI_CTRL1) );
++ writel( temp, SYS_CTRL_PCI_CTRL1 );
++
++ /* the interrupt lines map directly to the GPIO lines, so disable any
++ primary, secondary and tertiary functionality */
++ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
++
++ // Interrupt line the cardbus/mini-PCI slot
++ *((volatile unsigned long*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0) &= ~(1UL << PCI_GPIO_INTA_MINIPCI);
++ *((volatile unsigned long*)SYS_CTRL_GPIO_SECSEL_CTRL_0) &= ~(1UL << PCI_GPIO_INTA_MINIPCI);
++ *((volatile unsigned long*)SYS_CTRL_GPIO_TERTSEL_CTRL_0) &= ~(1UL << PCI_GPIO_INTA_MINIPCI);
++
++ // Interrupt line for VIA-SATA PCI device
++ *((volatile unsigned long*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0) &= ~(1UL << PCI_GPIO_INTA_PLANAR);
++ *((volatile unsigned long*)SYS_CTRL_GPIO_SECSEL_CTRL_0) &= ~(1UL << PCI_GPIO_INTA_PLANAR);
++ *((volatile unsigned long*)SYS_CTRL_GPIO_TERTSEL_CTRL_0) &= ~(1UL << PCI_GPIO_INTA_PLANAR);
++
++#ifdef CONFIG_ARCH_OXNAS_PCI_CLKOUT_0
++ *((volatile unsigned long*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_0);
++ *((volatile unsigned long*)SYS_CTRL_GPIO_SECSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_0);
++ *((volatile unsigned long*)SYS_CTRL_GPIO_TERTSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_0);
++#endif // CONFIG_ARCH_OXNAS_PCI_CLKOUT_0
++
++#ifdef CONFIG_ARCH_OXNAS_PCI_CLKOUT_1
++ *((volatile unsigned long*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_1);
++ *((volatile unsigned long*)SYS_CTRL_GPIO_SECSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_1);
++ *((volatile unsigned long*)SYS_CTRL_GPIO_TERTSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_1);
++#endif // CONFIG_ARCH_OXNAS_PCI_CLKOUT_1
++
++#ifdef CONFIG_ARCH_OXNAS_PCI_CLKOUT_2
++ *((volatile unsigned long*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_2);
++ *((volatile unsigned long*)SYS_CTRL_GPIO_SECSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_2);
++ *((volatile unsigned long*)SYS_CTRL_GPIO_TERTSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_2);
++#endif // CONFIG_ARCH_OXNAS_PCI_CLKOUT_2
++
++#ifdef CONFIG_ARCH_OXNAS_PCI_CLKOUT_3
++ *((volatile unsigned long*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_3);
++ *((volatile unsigned long*)SYS_CTRL_GPIO_SECSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_3);
++ *((volatile unsigned long*)SYS_CTRL_GPIO_TERTSEL_CTRL_0) |= (1UL << PCI_GPIO_CLKO_3);
++#endif // CONFIG_ARCH_OXNAS_PCI_CLKOUT_3
++
++// printk(KERN_DEBUG "PCI: set gnt and req functions for pci arbiters\n" );
++
++#ifdef CONFIG_ARCH_OXNAS_PCI_REQGNT_0
++ *((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_REQ_N0);
++ *((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_GNT_N0);
++#endif // CONFIG_ARCH_OXNAS_PCI_REQGNT_0
++
++#ifdef CONFIG_ARCH_OXNAS_PCI_REQGNT_1
++ *((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_REQ_N1);
++ *((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_GNT_N1);
++#endif // CONFIG_ARCH_OXNAS_PCI_REQGNT_1
++
++#ifdef CONFIG_ARCH_OXNAS_PCI_REQGNT_2
++ *((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_REQ_N2);
++ *((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_GNT_N2);
++#endif // CONFIG_ARCH_OXNAS_PCI_REQGNT_2
++
++#ifdef CONFIG_ARCH_OXNAS_PCI_REQGNT_3
++ *((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_REQ_N2);
++ *((volatile unsigned long*) SYS_CTRL_GPIO_PRIMSEL_CTRL_0 ) |= (1UL << PCI_GNT_N2);
++#endif // CONFIG_ARCH_OXNAS_PCI_REQGNT_3
++
++ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
++
++ // no eeprom to setup core, so perform eeporm functions --------------------
++ // setup the data to write to enable pci config
++// printk(KERN_DEBUG "PCI: enable core features\n" );
++ oxnas_pci_write_core_config(
++ PCI_COMMAND_IO |
++ PCI_COMMAND_MEMORY |
++ PCI_COMMAND_MASTER |
++ PCI_COMMAND_SPECIAL |
++ PCI_COMMAND_INVALIDATE |
++ PCI_COMMAND_VGA_PALETTE |
++ PCI_COMMAND_PARITY |
++ PCI_COMMAND_WAIT |
++ PCI_COMMAND_SERR |
++ PCI_COMMAND_FAST_BACK /* |
++ PCI_COMMAND_INTX_DISABLE, */,
++ PCI_COMMAND );
++
++// printk(KERN_DEBUG "PCI: PCI_COMMAND == 0x%08x\n", (u32) oxnas_pci_read_core_config(PCI_COMMAND) );
++}
++
++void __init oxnas_pci_postinit(void)
++{
++// printk(KERN_DEBUG "PCI: oxnas_pci_postinit\n");
++}
++
++static struct hw_pci oxnas_pci __initdata = {
++ .swizzle = oxnas_swizzle,
++ .map_irq = oxnas_map_irq,
++ .setup = oxnas_pci_setup,
++ .nr_controllers = 1,
++ .scan = oxnas_pci_scan_bus,
++ .preinit = oxnas_pci_preinit,
++ .postinit = oxnas_pci_postinit,
++};
++
++static int __init oxnas_pci_init(void)
++{
++ pci_common_init(&oxnas_pci);
++ return 0;
++}
++
++static void __exit oxnas_pci_exit(void)
++{
++ // if ( resource[0] ) {
++ // int errVal = release_resource(resource[0];
++ // if ( errVal ) {
++ // printk(KERN_ERR "PCI: unable to release csrRegister space %d", errVal );
++ // }
++ // }
++
++ // Put the PCI core into reset, but don't stop the clock as the PCI arbiter
++ // still requires it in order to be able to grant the static bus access to
++ // the PCI I/Os
++ writel(1UL << SYS_CTRL_RSTEN_PCI_BIT, SYS_CTRL_RSTEN_SET_CTRL);
++
++ return;
++}
++
++subsys_initcall(oxnas_pci_init);
++module_exit(oxnas_pci_exit);
++
++#endif
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/power_button.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/power_button.c
+--- linux-2.6.24/arch/arm/mach-oxnas/power_button.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/power_button.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,270 @@
++/*
++ * linux/arch/arm/mach-oxnas/power_button.c
++ *
++ * Copyright (C) 2006 Oxford Semiconductor Ltd
++ *
++ * 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 <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/timer.h>
++#include <linux/kobject.h>
++#include <linux/workqueue.h>
++#include <asm/hardware.h>
++#include <asm/io.h>
++
++MODULE_LICENSE("GPL v2");
++
++// Global variable to hold LED inversion state
++extern int oxnas_global_invert_leds;
++
++// Make a module parameter to set whether LED are inverted
++static int invert_leds = 0;
++module_param(invert_leds, bool, S_IRUGO|S_IWUSR);
++
++#if (CONFIG_OXNAS_POWER_BUTTON_GPIO < 32)
++#define SWITCH_NUM CONFIG_OXNAS_POWER_BUTTON_GPIO
++#define IRQ_NUM GPIO_1_INTERRUPT
++#define INT_STATUS_REG GPIO_A_INTERRUPT_STATUS_REGISTER
++#define SWITCH_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_0
++#define SWITCH_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_0
++#define SWITCH_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_0
++#define SWITCH_CLR_OE_REG GPIO_A_OUTPUT_ENABLE_CLEAR
++#define DEBOUNCE_REG GPIO_A_INPUT_DEBOUNCE_ENABLE
++#define LEVEL_INT_REG GPIO_A_LEVEL_INTERRUPT_ENABLE
++#define FALLING_INT_REG GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE
++#define DATA_REG GPIO_A_DATA
++#else
++#define SWITCH_NUM ((CONFIG_OXNAS_POWER_BUTTON_GPIO) - 32)
++#define IRQ_NUM GPIO_2_INTERRUPT
++#define INT_STATUS_REG GPIO_B_INTERRUPT_STATUS_REGISTER
++#define SWITCH_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_1
++#define SWITCH_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_1
++#define SWITCH_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_1
++#define SWITCH_CLR_OE_REG GPIO_B_OUTPUT_ENABLE_CLEAR
++#define DEBOUNCE_REG GPIO_B_INPUT_DEBOUNCE_ENABLE
++#define LEVEL_INT_REG GPIO_B_LEVEL_INTERRUPT_ENABLE
++#define FALLING_INT_REG GPIO_B_FALLING_EDGE_ACTIVE_LOW_ENABLE
++#define DATA_REG GPIO_B_DATA
++#endif
++
++#define SWITCH_MASK (1UL << (SWITCH_NUM))
++
++#define TIMER_INTERVAL_JIFFIES ((HZ) >> 3) /* An eigth of a second */
++#define TIMER_COUNT_LIMIT 24 /* In eigths of a second */
++
++extern spinlock_t oxnas_gpio_spinlock;
++
++static unsigned long count;
++static struct timer_list timer;
++
++/** Have to use active low level interupt generation, as otherwise might miss
++ * interrupts that arrive concurrently with a PCI interrupt, as PCI interrupts
++ * are generated via GPIO pins and std PCI drivers will not know that there
++ * may be other pending GPIO interrupt sources waiting to be serviced and will
++ * simply return IRQ_HANDLED if they see themselves as having generated the
++ * interrupt, thus preventing later chained handlers from being called
++ */
++static irqreturn_t int_handler(int irq, void* dev_id)
++{
++ int status = IRQ_NONE;
++ unsigned int int_status = readl((volatile unsigned long *)INT_STATUS_REG);
++
++ /* Is the interrupt for us? */
++ if (int_status & SWITCH_MASK) {
++ /* Disable the power button GPIO line interrupt */
++ spin_lock(&oxnas_gpio_spinlock);
++ writel(readl(FALLING_INT_REG) & ~SWITCH_MASK, FALLING_INT_REG);
++ spin_unlock(&oxnas_gpio_spinlock);
++
++ /* Zeroise button hold down counter */
++ count = 0;
++
++ /* Start hold down timer with a timeout of 1/8 second */
++ mod_timer(&timer, jiffies + TIMER_INTERVAL_JIFFIES);
++
++ /* Only mark interrupt as serviced if no other unmasked GPIO interrupts
++ are pending */
++ if (!readl((volatile unsigned long *)INT_STATUS_REG)) {
++ status = IRQ_HANDLED;
++ }
++ }
++
++ return status;
++}
++
++/*
++ * Device driver object
++ */
++typedef struct power_button_driver_s {
++ /** sysfs dir tree root for power button driver */
++ struct kset kset;
++ struct kobject power_button;
++} power_button_driver_t;
++
++static power_button_driver_t power_button_driver;
++
++static void work_handler(struct work_struct * not_used) {
++ kobject_uevent(&power_button_driver.power_button, KOBJ_OFFLINE);
++}
++
++DECLARE_WORK(power_button_hotplug_work, work_handler);
++
++static void timer_handler(unsigned long data)
++{
++ unsigned long flags;
++
++ /* Is the power button still pressed? */
++ if (!(readl(DATA_REG) & SWITCH_MASK)) {
++ /* Yes, so increment count of how many timer intervals have passed since
++ power button was pressed */
++ if (++count == TIMER_COUNT_LIMIT) {
++ schedule_work(&power_button_hotplug_work);
++ } else {
++ /* Restart timer with a timeout of 1/8 second */
++ mod_timer(&timer, jiffies + TIMER_INTERVAL_JIFFIES);
++ }
++ } else {
++ /* The h/w debounced power button has been released, so reenable the
++ active low interrupt detection to trap the user's next attempt to
++ power down */
++ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
++ writel(readl(FALLING_INT_REG) | SWITCH_MASK, FALLING_INT_REG);
++ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
++ }
++}
++
++static struct kobj_type ktype_power_button = {
++ .release = 0,
++ .sysfs_ops = 0,
++ .default_attrs = 0,
++};
++
++static int power_button_hotplug_filter(struct kset* kset, struct kobject* kobj) {
++ return get_ktype(kobj) == &ktype_power_button;
++}
++
++static const char* power_button_hotplug_name(struct kset* kset, struct kobject* kobj) {
++ return "oxnas_power_button";
++}
++
++static struct kset_uevent_ops power_button_uevent_ops = {
++ .filter = power_button_hotplug_filter,
++ .name = power_button_hotplug_name,
++ .uevent = NULL,
++};
++
++static int power_button_prep_sysfs(void)
++{
++ int err = 0;
++
++ /* prep the sysfs interface for use */
++ kobject_set_name(&power_button_driver.kset.kobj, "power-button");
++ power_button_driver.kset.ktype = &ktype_power_button;
++
++ err = subsystem_register(&power_button_driver.kset);
++ if (err)
++ return err;
++
++ /* setup hotplugging */
++ power_button_driver.kset.uevent_ops = &power_button_uevent_ops;
++
++ /* setup the heirarchy, the name will be set on detection */
++ kobject_init(&power_button_driver.power_button);
++ power_button_driver.power_button.kset = kset_get(&power_button_driver.kset);
++ power_button_driver.power_button.parent = &power_button_driver.kset.kobj;
++
++ return 0;
++}
++
++static int power_button_build_sysfs(void) {
++ kobject_set_name(&power_button_driver.power_button, "power-button-1");
++ return kobject_add(&power_button_driver.power_button);
++}
++
++static int __init power_button_init(void)
++{
++ int err = 0;
++ unsigned long flags;
++
++ /* Copy the LED inversion module parameter into the global variable */
++ oxnas_global_invert_leds = invert_leds;
++
++ err = power_button_prep_sysfs();
++ if (err)
++ return -EINVAL;
++
++ err = power_button_build_sysfs();
++ if (err)
++ return -EINVAL;
++
++ /* Setup the timer that will time how long the user holds down the power
++ button */
++ init_timer(&timer);
++ timer.data = 0;
++ timer.function = timer_handler;
++
++ /* Install a shared interrupt handler on the appropriate GPIO bank's
++ interrupt line */
++ if (request_irq(IRQ_NUM, int_handler, IRQF_SHARED, "Power Button", &power_button_driver)) {
++ printk(KERN_ERR "Power Button: cannot register IRQ %d\n", IRQ_NUM);
++ del_timer_sync(&timer);
++ return -EIO;
++ }
++
++ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
++ /* Disable primary, secondary and teriary GPIO functions on switch lines */
++ writel(readl(SWITCH_PRISEL_REG) & ~SWITCH_MASK, SWITCH_PRISEL_REG);
++ writel(readl(SWITCH_SECSEL_REG) & ~SWITCH_MASK, SWITCH_SECSEL_REG);
++ writel(readl(SWITCH_TERSEL_REG) & ~SWITCH_MASK, SWITCH_TERSEL_REG);
++
++ /* Enable GPIO input on switch line */
++ writel(SWITCH_MASK, SWITCH_CLR_OE_REG);
++
++ /* Set up the power button GPIO line for active low, debounced interrupt */
++ writel(readl(DEBOUNCE_REG) | SWITCH_MASK, DEBOUNCE_REG);
++ writel(readl(LEVEL_INT_REG) | SWITCH_MASK, LEVEL_INT_REG);
++ writel(readl(FALLING_INT_REG) | SWITCH_MASK, FALLING_INT_REG);
++ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
++
++ printk(KERN_INFO "Power button driver registered\n");
++ return 0;
++}
++
++static void __exit power_button_exit(void)
++{
++ unsigned long flags;
++
++ kobject_del(&power_button_driver.power_button);
++ subsystem_unregister(&power_button_driver.kset);
++
++ /* Deactive the timer */
++ del_timer_sync(&timer);
++
++ /* Disable interrupt generation by the power button GPIO line */
++ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
++ writel(readl(FALLING_INT_REG) & ~SWITCH_MASK, FALLING_INT_REG);
++ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
++
++ /* Remove the handler for the shared interrupt line */
++ free_irq(IRQ_NUM, &power_button_driver);
++}
++
++/**
++ * macros to register intiialisation and exit functions with kernal
++ */
++module_init(power_button_init);
++module_exit(power_button_exit);
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/samba_reserve.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/samba_reserve.c
+--- linux-2.6.24/arch/arm/mach-oxnas/samba_reserve.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/samba_reserve.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,50 @@
++/*
++ * linux/arch/arm/mach-oxnas/samba_receive.c
++ *
++ * Copyright (C) 2008 Oxford Semiconductor Ltd
++ *
++ * 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 <linux/errno.h>
++#include <linux/file.h>
++#include <linux/fs.h>
++#include <linux/kernel.h>
++
++typedef struct xfs_flock64 {
++ __s16 l_type;
++ __s16 l_whence;
++ __s64 l_start;
++ __s64 l_len; /* len == 0 means until end of file */
++ __s32 l_sysid;
++ __u32 l_pid;
++ __s32 l_pad[4]; /* reserve area */
++} xfs_flock64_t;
++
++#define XFS_IOC_RESVSP64 _IOW ('X', 42, struct xfs_flock64)
++
++asmlinkage long sys_samba_reserve(
++ int fd,
++ void __user *info)
++{
++ struct file *file = fget(fd);
++ long ret = -EINVAL;
++
++ /* Do I need any locking around the unlocked_ioctl() call? */
++ ret = file->f_op->unlocked_ioctl(file, XFS_IOC_RESVSP64, (unsigned long)info);
++
++ fput(file);
++
++ return ret;
++}
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/thermAndFan.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/thermAndFan.c
+--- linux-2.6.24/arch/arm/mach-oxnas/thermAndFan.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/thermAndFan.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,738 @@
++/*
++ * Device driver for the i2c thermostat found on the iBook G4, Albook G4
++ *
++ * Copyright (C) 2003, 2004 Colin Leroy, Rasmus Rohde, Benjamin Herrenschmidt
++ *
++ * Documentation from
++ * http://www.analog.com/UploadedFiles/Data_Sheets/115254175ADT7467_pra.pdf
++ * http://www.analog.com/UploadedFiles/Data_Sheets/3686221171167ADT7460_b.pdf
++ *
++ */
++
++
++#include <linux/types.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/miscdevice.h>
++#include <linux/smp_lock.h>
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/sched.h>
++#include <linux/i2c.h>
++#include <linux/proc_fs.h>
++#include <linux/capability.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/spinlock.h>
++#include <linux/smp_lock.h>
++#include <linux/wait.h>
++#include <linux/suspend.h>
++#include <linux/kthread.h>
++#include <linux/moduleparam.h>
++#include <linux/freezer.h>
++
++#include <asm/io.h>
++#include <asm/system.h>
++#include <asm/sections.h>
++#include <asm/uaccess.h>
++#include <asm/bitops.h>
++
++#include "asm/arch-oxnas/taco.h"
++#include "thermistorCalibration.h"
++
++//#define DEBUG 1
++#undef DEBUG
++
++/* Set this define to simulate different temperature values and test the
++ * working of the fan control module
++ */
++//#define SIMULATE_TEMPERATURE 1
++#undef SIMULATE_TEMPERATURE
++
++/******************************************************************************
++ * *
++ * delta t = dutyCycle.Period *
++ * *
++ * PWM in >----+ V' = Vcc - Vt *
++ * | -------- *
++ * _|_ Vcc *
++ * | | | *
++ * \| | Rt = delta t *
++ * | | ------------- *
++ * |\| -C.ln( V' ) *
++ * | | *
++ * | |\ delta t is discovered by the hardware which performs a *
++ * !_! \ varies the PWM duty cycle until one is found that just *
++ * | trips the Vt threshold. *
++ * | *
++ * |-----------> V in (Schmidt trigger @ Vt) *
++ * | *
++ * ___!___ *
++ * _______ C ( eg 100nF ) *
++ * | *
++ * | *
++ * | *
++ * ---+--- *
++ * *
++ * Steinhart Thermistor approximation: *
++ * *
++ * 1/T = A + B.ln(Rt) + C.ln(Rt)^3 *
++ * *
++ ******************************************************************************/
++
++#define MAX_FAN_RATIO_CHANGE 20
++#define OXSEMI_FAN_SPEED_RATIO_MIN 0
++#define OXSEMI_FAN_SPEED_RATIO_MAX 255
++#define FAN_SPEED_RATIO_SET (PWM_DATA_2)
++#define MIN_TEMP_COUNT_CHANGE 2
++
++/* This is not absolute temperature but counter val - thermistorCalibration*/
++static int hot_limit = 16;
++
++#ifdef OXNAS_TACHO_Ox810
++static int cold_limit = 104;
++#else /* OXNAS_TACHO_Ox810 */
++static int cold_limit = 200;
++#endif /* OXNAS_TACHO_Ox810 */
++
++static int min_fan_speed_ratio = 64;
++
++#ifdef OXNAS_TACHO_Ox810
++static int fan_pulse_per_rev = 1;
++static int output_flag = 0;
++static int current_temp = 0;
++static int current_speed = 0;
++#endif /* OXNAS_TACHO_Ox810 */
++
++MODULE_AUTHOR( "Chris Ford" );
++
++#ifdef OXNAS_TACHO_Ox810
++MODULE_DESCRIPTION( "Driver for Temperature sense and Fan control of ox810" );
++#else /* OXNAS_TACHO_Ox810 */
++MODULE_DESCRIPTION( "Driver for Fan and temp sense of ox800" );
++#endif /* OXNAS_TACHO_Ox810 */
++
++MODULE_LICENSE( "GPL" );
++
++module_param(hot_limit, int, 0644);
++MODULE_PARM_DESC(hot_limit, "Thermistor input for maximum fan drive");
++
++module_param(cold_limit, int, 0644);
++MODULE_PARM_DESC(cold_limit,"Thermistor input for minimum fan drive");
++
++module_param(min_fan_speed_ratio, int, 0644);
++MODULE_PARM_DESC(min_fan_speed_ratio,"Specify starting( minimum) fan drive (0-255) (default 64)");
++
++#ifdef OXNAS_TACHO_Ox810
++module_param(fan_pulse_per_rev, int, 0644);
++MODULE_PARM_DESC(fan_pulse_per_rev,"Specify the number of pulses per revolution of fan - 1(default) or 2");
++
++module_param(output_flag, bool, 0644);
++MODULE_PARM_DESC(output_flag,"Flag to specify whether temperature and speed output to user is required");
++
++module_param(current_temp, int, S_IRUGO);
++MODULE_PARM_DESC(current_temp,"Read only for the current temperature in counts");
++
++module_param(current_speed, int, S_IRUGO);
++MODULE_PARM_DESC(current_speed,"Read only for the current speed in rpm");
++#endif /* OXNAS_TACHO_Ox810 */
++
++
++struct thermostat {
++ int temps;
++ int cached_temp;
++ int curr_speed;
++ int last_speed;
++ int set_speed;
++ int last_var;
++ struct semaphore sem;
++// struct cdev cdev;
++};
++
++static struct thermostat* thermostat = NULL;
++static struct task_struct* thread_therm = NULL;
++
++
++static int write_reg( int reg, u32 data )
++{
++ writel( data, reg );
++ return 0;
++}
++
++static int read_reg( int reg )
++{
++ int data = 0;
++ data = readl( reg );
++ return data;
++}
++
++/** GetTemperatureCounter is an internal function to the module that reads the
++ * temperature as a counter value and returns it to the caller. The counter
++ * value is used in all the internal calculations avoiding the necessity to
++ * convert to Kelvin for interpretation. For corresponding temperature values
++ * in Kelvin look at thermistoCalilbration.h
++ */
++int GetTemperatureCounter(void)
++{
++ u32 res;
++
++/* printk(KERN_INFO "T&F?::GetTemperatureCounter ----\n");
++ */
++ /* Test to ensure we are ready.
++ */
++ if ( !thermostat ) {
++ printk(KERN_INFO "T&F?::$RERROR - Temperature conv not started\n");
++ return -1;
++ }
++
++ while ( !( read_reg( TACHO_THERMISTOR_CONTROL ) &
++ (1 << TACHO_THERMISTOR_CONTROL_THERM_VALID) ) ) {
++ printk(KERN_INFO "T&F?::$rWarning - Temperature reading not stabalised\n");
++ msleep(100);
++ }
++
++ res = read_reg( TACHO_THERMISTOR_RC_COUNTER ) & TACHO_THERMISTOR_RC_COUNTER_MASK;
++
++#ifdef DEBUG
++ printk(KERN_INFO "Therm&Fan - Temperature Counter - %d \n",res);
++#endif
++
++ return res;
++}
++
++/** This function converts the unit of the temperature from counts to
++ * temperature in Kelvin
++ */
++int ConverttoKelvin(int tempCount)
++{
++ u32 res, arrayIndex;
++
++ /* Convert the Counter Value to Temperature in Kelvin */
++ arrayIndex = tempCount/THERM_INTERPOLATION_STEP;
++ res = TvsCnt[arrayIndex];
++ if ((THERM_ENTRIES_IN_CALIB_TABLE - 2) > arrayIndex)
++ res -= (tempCount % THERM_INTERPOLATION_STEP) * (TvsCnt[arrayIndex] - TvsCnt[arrayIndex + 1]) / THERM_INTERPOLATION_STEP;
++ else
++ res -= (tempCount % THERM_INTERPOLATION_STEP) * (TvsCnt[THERM_ENTRIES_IN_CALIB_TABLE - 2] - TvsCnt[THERM_ENTRIES_IN_CALIB_TABLE - 1]) / THERM_INTERPOLATION_STEP;
++
++#ifdef DEBUG
++ printk(KERN_INFO "Get Temperature- Temperature in Kelvin = %d\n", res);
++#endif
++ return res;
++}
++
++/**
++ * GetTemperature reads the temperature from the thermistor and converts it
++ * to the corresponding Kelvin equivalent
++ */
++int GetTemperature(void)
++{
++ u32 tempCount;
++ tempCount = GetTemperatureCounter();
++ return ConverttoKelvin(tempCount);
++}
++
++/**
++ * GetFanRPM will read the fan tacho register and convert the value to
++ * RPM.
++ * @return an int that represents the fan speed in RPM, or a
++ * negative value in the case of error.
++ */
++int GetFanRPM(void)
++{
++ u32 res;
++ u32 iCounterValue;
++
++#ifdef OXNAS_TACHO_Ox810
++
++ if(thermostat->last_speed == OXSEMI_FAN_SPEED_RATIO_MIN)
++ {
++#ifdef DEBUG
++ printk(KERN_INFO "ThernAndFan::GetFanRPM - Fan Speed %d \n", OXSEMI_FAN_SPEED_RATIO_MIN);
++#endif
++ return OXSEMI_FAN_SPEED_RATIO_MIN;
++ }
++
++ write_reg( TACHO_FAN_ONE_SHOT_CONTROL, (1 << TACHO_FAN_ONE_SHOT_CONTROL_START));
++
++ while ( !(read_reg( TACHO_FAN_SPEED_COUNTER ) &
++ (1 << TACHO_FAN_SPEED_COUNTER_COUNT_VALID) ) ) {
++/* printk(KERN_INFO "ThernAndFan::$rWarning - Fan Counter reading not stabalised\n");
++ */ msleep(100);
++ }
++
++#endif /* OXNAS_TACHO_Ox810 */
++
++ iCounterValue = read_reg( TACHO_FAN_SPEED_COUNTER )
++ & TACHO_FAN_SPEED_COUNTER_MASK;
++
++#ifndef OXNAS_TACHO_Ox810 /* Code thats only for non ox810 versions */
++ if(iCounterValue == TACHO_FAN_SPEED_COUNTER_MASK)
++ {
++ /* speed less than measurable */
++#ifdef DEBUG
++ printk(KERN_INFO "ThernAndFan::GetFanRPM - RPM < 117 - returning 0\n");
++#endif
++ return 0;
++ }
++#endif
++
++ ++iCounterValue;
++
++#ifdef OXNAS_TACHO_Ox810
++ /* Fan Speed (rpm) = 60 * 2000 / (counter value +1) * pulses per rev */
++ res = (60 * 2000 ) / (iCounterValue * fan_pulse_per_rev);
++#else /* OXNAS_TACHO_Ox810 */
++ /* Fan Speed (rpm) = 60 * 2000 / (counter value +1) */
++ res = 60 * 2000 / iCounterValue;
++#endif /* OXNAS_TACHO_Ox810 */
++
++#ifdef SIMULATE_TEMPERATURE
++ printk(KERN_INFO "thermAndFan::GetFanRPM == %d\n", res);
++#endif /*SIMULATE_TEMPERATURE */
++
++ return res;
++}
++
++#ifdef OXNAS_TACHO_Ox810
++
++static void read_sensors(struct thermostat *th)
++{
++ static int state;
++#ifdef SIMULATE_TEMPERATURE
++ static int curTemp = 30;
++#endif /* SIMULATE_TEMPERATURE */
++
++ if ( !th ) {
++ printk(KERN_INFO "thermAndFan::read_sensors $RTH NOT ESTABLISHED YET\n");
++ return;
++ }
++ switch(state){
++ case 0:
++ th->temps = GetTemperatureCounter();
++
++ /* Set to speed measurement */
++ write_reg( TACHO_FAN_SPEED_CONTROL,
++ (1 << (TACHO_FAN_SPEED_CONTROL_PWM_ENABLE_BASE
++ + TACHO_FAN_SPEED_CONTROL_PWM_USED))
++ | (1 << TACHO_FAN_SPEED_CONTROL_FAN_COUNT_MODE));
++ state = 1;
++
++ if(output_flag) /* Set the temperature to user space here */
++ {
++ current_temp = th->temps;
++ }
++
++ #ifdef SIMULATE_TEMPERATURE
++ th->temps = curTemp;
++ curTemp += 5;
++ if(curTemp > cold_limit + 20)
++ curTemp = hot_limit - 20;
++ printk(KERN_INFO "thermAndFan::read_sensors Temp Set to - %d\n", curTemp);
++ #endif /* SIMULATE_TEMPERATURE */
++ break;
++
++ case 1:
++ default:
++
++ th->curr_speed = GetFanRPM();
++
++ /* Set to Temperature measurement */
++ write_reg( TACHO_THERMISTOR_CONTROL, ((1 << TACHO_THERMISTOR_CONTROL_THERM_ENABLE)
++ | (0 << TACHO_THERMISTOR_CONTROL_THERM_VALID)) );
++ state = 0;
++
++ if(output_flag) /* Set the speed to user space here */
++ {
++ current_speed = th->curr_speed;
++ }
++ break;
++ }
++}
++
++#else /* OXNAS_TACHO_Ox810 */
++
++static void read_sensors(struct thermostat *th)
++{
++ static int state;
++
++ if ( !th ) {
++ printk(KERN_INFO "thermAndFan::read_sensors $RTH NOT ESTABLISHED YET\n");
++ return;
++ }
++
++ switch (state) {
++ case 0: /* Get the temperature */
++ th->temps = GetTemperatureCounter();
++ write_reg( TACHO_CLOCK_DIVIDER, TACHO_CORE_TACHO_DIVIDER_VALUE );
++ state = 1;
++ break;
++
++ case 1:
++ /* Get the fan speed */
++ th->curr_speed = GetFanRPM();
++ /* free fall to default case needed */
++/* break;
++ */
++ default:
++ /* Stop the thermister measuring */
++ write_reg( TACHO_THERMISTOR_CONTROL, 0 );
++ write_reg( TACHO_CLOCK_DIVIDER, TACHO_CORE_THERM_DIVIDER_VALUE );
++ /* Start the thermister measuring */
++ write_reg( TACHO_THERMISTOR_CONTROL, (1 << TACHO_THERMISTOR_CONTROL_THERM_ENABLE) );
++ state = 0;
++ break;
++ }
++}
++
++#endif /* OXNAS_TACHO_Ox810 */
++
++
++#ifdef DEBUG
++/**
++ * DumpTachoRegisters is a debug function used to inspect hte tacho registers.
++ */
++void DumpTachoRegisters(void)
++{
++
++ printk(KERN_INFO \
++ "\n<Taco Registers> ---------------------------------\n"
++ " TACHO_FAN_SPEED_COUNTER == 0x%08x\n"
++ " TACHO_THERMISTOR_RC_COUNTER == 0x%08x\n"
++ " TACHO_THERMISTOR_CONTROL == 0x%08x\n"
++ " TACHO_CLOCK_DIVIDER == 0x%08x\n"
++ " PWM_CORE_CLK_DIVIDER_VALUE == 0x%08x\n"
++ " FAN_SPEED_RATIO_SET == 0x%08x\n"
++ "<\\Taco Registers> --------------------------------\n\n",
++ (u32) (read_reg( TACHO_FAN_SPEED_COUNTER) & TACHO_FAN_SPEED_COUNTER_MASK),
++ (u32) (read_reg( TACHO_THERMISTOR_RC_COUNTER) & TACHO_THERMISTOR_RC_COUNTER_MASK),
++ (u32) read_reg( TACHO_THERMISTOR_CONTROL ),
++ (u32) (read_reg( TACHO_CLOCK_DIVIDER) & TACHO_CLOCK_DIVIDER_MASK),
++ (u32) read_reg( PWM_CLOCK_DIVIDER ),
++ (u32) read_reg( FAN_SPEED_RATIO_SET ) );
++}
++#else
++void DumpTachoRegisters(void) {}
++#endif
++
++static void write_fan_speed(struct thermostat *th, int speed)
++{
++/* printk(KERN_INFO "thermAndFan::write_fan_speed %u\n", speed);
++*/
++ /* The fan speed can vary between the max and the min speed ratio or
++ * it can be min ratio value of 0
++ */
++ if (speed > OXSEMI_FAN_SPEED_RATIO_MAX)
++ speed = OXSEMI_FAN_SPEED_RATIO_MAX;
++ else if ((speed < min_fan_speed_ratio) && (speed > OXSEMI_FAN_SPEED_RATIO_MIN))
++ speed = min_fan_speed_ratio;
++ else if (speed < OXSEMI_FAN_SPEED_RATIO_MIN)
++ speed = OXSEMI_FAN_SPEED_RATIO_MIN;
++
++ if (th->last_speed == speed)
++ return;
++
++ write_reg( FAN_SPEED_RATIO_SET, speed );
++
++#ifdef SIMULATE_TEMPERATURE
++ printk(KERN_INFO "Speed Ratio Written - %d\n", speed);
++#endif /* SIMULATE_TEMPERATURE */
++
++ th->last_speed = speed;
++}
++
++#ifdef DEBUG
++static void display_stats(struct thermostat *th)
++{
++ if ( 1 || th->temps != th->cached_temp) {
++ printk(KERN_INFO
++ "thermAndFan:: Temperature infos:\n"
++ " * thermostats: %d;\n"
++ " * pwm: %d;\n"
++ " * fan speed: %d RPM\n\n",
++ th->temps,
++ min_fan_speed_ratio,
++ GetFanRPM());
++ th->cached_temp = th->temps;
++ }
++}
++#endif
++
++/*
++ * Use fuzzy logic type approach to creating the new fan speed.
++ * if count < cold_limit fan should be off.
++ * if count > hot_limit fan should be full on.
++ * if count between limits set proportionally to base speed + proportional element.
++ */
++static void update_fan_speed(struct thermostat *th)
++{
++ int var = th->temps;
++
++/* remember that var = 1/T ie smaller var higher temperature and faster fan speed needed */
++ if (abs(var - th->last_var) >= MIN_TEMP_COUNT_CHANGE) {
++ int new_speed;
++
++ if(var < cold_limit){
++
++ if (var < hot_limit)
++ {
++ th->last_var = var;
++ /* too hot for proportional control */
++ new_speed = OXSEMI_FAN_SPEED_RATIO_MAX;
++ }
++ else
++ {
++ /* fan speed it the user selected starting value for the fan
++ * so scale operatation from nominal at cold limit to max at hot limit.
++ */
++ new_speed = OXSEMI_FAN_SPEED_RATIO_MAX -
++ (OXSEMI_FAN_SPEED_RATIO_MAX - min_fan_speed_ratio) * (var - hot_limit)/(cold_limit - hot_limit);
++
++ if (th->set_speed == 0 ) th->set_speed = min_fan_speed_ratio;
++
++ if ((new_speed - th->set_speed) > MAX_FAN_RATIO_CHANGE)
++ new_speed = th->set_speed + MAX_FAN_RATIO_CHANGE;
++ else if ((new_speed - th->set_speed) < -MAX_FAN_RATIO_CHANGE)
++ new_speed = th->set_speed - MAX_FAN_RATIO_CHANGE;
++ else
++ th->last_var = var;
++ }
++ }
++ else {
++
++ th->last_var = var;
++ /* var greater than low limit - too cold for fan. */
++ new_speed = OXSEMI_FAN_SPEED_RATIO_MIN;
++ }
++
++ write_fan_speed(th, new_speed);
++ th->set_speed = new_speed;
++ }
++}
++
++static int monitor_task(void *arg)
++{
++ struct thermostat* th = arg;
++
++ while(!kthread_should_stop()) {
++ if (unlikely(freezing(current)))
++ refrigerator();
++
++ msleep_interruptible(2000);
++
++#ifdef DEBUG
++ DumpTachoRegisters();
++#endif
++
++ read_sensors(th);
++
++ update_fan_speed(th);
++
++#ifdef DEBUG
++ /* be carefule with the stats displayed. The Fan Counter value depends
++ * on what value is written in the register during the read sensors
++ * call. If its in temperature read setting, the fan counter and hence
++ * the rpm will be WRONG
++ */
++ display_stats(th);
++#endif
++ }
++
++ return 0;
++}
++
++static int
++oxsemi_therm_read(char *buf, char **start, off_t offset,
++ int len, int *eof, void *unused)
++{
++ len = sprintf(buf,
++ "Thermostat And Fan state ---------\n"
++ " temps_counter == %d\n"
++ " speed_ratio_set == %d\n"
++ " measured-fan_speed == %d\n"
++ " last_temp_counter == %d\n\n",
++ thermostat->temps,
++ thermostat->last_speed,
++ thermostat->curr_speed,
++ thermostat->last_var );
++ //*start = buf;
++ return len;
++}
++
++static struct proc_dir_entry *proc_oxsemi_therm;
++
++
++static struct file_operations oxsemi_therm_fops = {
++ .owner = THIS_MODULE,
++ .open = nonseekable_open,
++};
++
++static struct miscdevice oxsemi_therm_miscdev = {
++ TEMP_MINOR,
++ "temp",
++ &oxsemi_therm_fops
++};
++
++static int __init oxsemi_therm_init(void)
++{
++ struct thermostat* th;
++ int rc, ret;
++
++ if (thermostat)
++ return 0;
++
++ read_reg(SYS_CTRL_RSTEN_CTRL);
++
++/* release fan/tacho from system reset */
++ *((volatile unsigned long *) SYS_CTRL_RSTEN_CLR_CTRL) = (1UL << SYS_CTRL_RSTEN_MISC_BIT);
++
++/* Pull Down the GPIO 29 from the software */
++#ifdef OXNAS_TACHO_Ox810
++ *((volatile unsigned long *) SYSCTRL_GPIO_PULLUP_CTRL_0) |= TEMP_TACHO_PULLUP_CTRL_VALUE;
++#endif /* OXNAS_TACHO_Ox810 */
++
++/* printk(KERN_INFO "thermAndFan: mux out therm and fan pins onto GPIO)\n" );
++ */
++ *((volatile unsigned long *) SYS_CTRL_GPIO_PRIMSEL_CTRL_0) &= ~(1UL << SECONDARY_FUNCTION_ENABLE_FAN_PWM2);
++ *((volatile unsigned long *) SYS_CTRL_GPIO_PRIMSEL_CTRL_0) |= (1UL << PRIMARY_FUNCTION_ENABLE_FAN_TACHO);
++ *((volatile unsigned long *) SYS_CTRL_GPIO_PRIMSEL_CTRL_0) |= (1UL << PRIMARY_FUNCTION_ENABLE_FAN_TEMP);
++
++/* disable secondary use */
++ *((volatile unsigned long *) SYS_CTRL_GPIO_SECSEL_CTRL_0) |= (1UL << SECONDARY_FUNCTION_ENABLE_FAN_PWM2);
++ *((volatile unsigned long *) SYS_CTRL_GPIO_SECSEL_CTRL_0) &= ~(1UL << PRIMARY_FUNCTION_ENABLE_FAN_TACHO);
++ *((volatile unsigned long *) SYS_CTRL_GPIO_SECSEL_CTRL_0) &= ~(1UL << PRIMARY_FUNCTION_ENABLE_FAN_TEMP);
++
++/* disable tertiary use */
++ *((volatile unsigned long *) SYS_CTRL_GPIO_TERTSEL_CTRL_0) &= ~(1UL << SECONDARY_FUNCTION_ENABLE_FAN_PWM2);
++ *((volatile unsigned long *) SYS_CTRL_GPIO_TERTSEL_CTRL_0) &= ~(1UL << PRIMARY_FUNCTION_ENABLE_FAN_TACHO);
++ *((volatile unsigned long *) SYS_CTRL_GPIO_TERTSEL_CTRL_0) &= ~(1UL << PRIMARY_FUNCTION_ENABLE_FAN_TEMP);
++
++ read_reg(SYS_CTRL_RSTEN_CTRL);
++ read_reg(SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
++ read_reg(SYS_CTRL_GPIO_SECSEL_CTRL_0);
++ read_reg(SYS_CTRL_GPIO_TERTSEL_CTRL_0);
++
++ th = (struct thermostat *)
++ kmalloc(sizeof(struct thermostat), GFP_KERNEL);
++
++ if (!th)
++ return -ENOMEM;
++
++ memset(th, 0, sizeof(struct thermostat));
++ init_MUTEX( &th->sem );
++
++ rc = read_reg(TACHO_CLOCK_DIVIDER);
++ if (rc < 0) {
++ printk(KERN_ERR "thermAndFan: Thermostat failed to read config ");
++ kfree(th);
++ return -ENODEV;
++ }
++
++ /* Set the Tacho clock divider up */
++/* printk(KERN_INFO "thermAndFan: Setting tacho core frequency divider to %d\n", TACHO_CORE_THERM_DIVIDER_VALUE );
++ */
++#ifdef OXNAS_TACHO_Ox810
++ write_reg( TACHO_CLOCK_DIVIDER, TACHO_CORE_TACHO_DIVIDER_VALUE );
++
++ /* check tacho divider set correctly */
++ rc = read_reg(TACHO_CLOCK_DIVIDER);
++ /* Comparing a 10 bit value to a 32 bit return value */
++ if ((rc & TACHO_CORE_TACHO_DIVIDER_VALUE) != TACHO_CORE_TACHO_DIVIDER_VALUE) {
++ printk(KERN_ERR "thermAndFan: Set Tacho Divider Value Failed readback:%d\n", rc);
++ kfree(th);
++ return -ENODEV;
++ }
++
++#else /* OXNAS_TACHO_Ox810 */
++ write_reg( TACHO_CLOCK_DIVIDER, TACHO_CORE_THERM_DIVIDER_VALUE );
++
++/* check tacho divider set correctly */
++ rc = read_reg(TACHO_CLOCK_DIVIDER);
++ /* Comparing a 10 bit value to a 32 bit return value */
++ if ((rc & TACHO_CORE_THERM_DIVIDER_VALUE) != TACHO_CORE_THERM_DIVIDER_VALUE) {
++ printk(KERN_ERR "thermAndFan: Thermostat failed to set config tacho divider readback:%d\n", rc);
++ kfree(th);
++ return -ENODEV;
++ }
++
++#endif /* OXNAS_TACHO_Ox810 */
++
++/* printk(KERN_INFO "thermAndFan: Setting PWM core frequency divider to %d\n", PWM_CORE_CLK_DIVIDER_VALUE );
++ */
++ write_reg( PWM_CLOCK_DIVIDER, PWM_CORE_CLK_DIVIDER_VALUE );
++
++#ifdef OXNAS_TACHO_Ox810
++ printk(KERN_INFO "thermAndFan: initializing - ox810\n");
++#else /* OXNAS_TACHO_Ox810 */
++ printk(KERN_INFO "thermAndFan: initializing\n");
++#endif /* OXNAS_TACHO_Ox810 */
++
++#ifdef DEBUG
++ DumpTachoRegisters();
++#endif
++
++ thermostat = th;
++
++ /* Start the thermister measuring */
++ write_reg( TACHO_THERMISTOR_CONTROL, (1 << TACHO_THERMISTOR_CONTROL_THERM_ENABLE) );
++
++ /* Start Speed measuring */
++#ifdef OXNAS_TACHO_Ox810
++ write_reg( TACHO_FAN_SPEED_CONTROL,
++ (1 << (TACHO_FAN_SPEED_CONTROL_PWM_ENABLE_BASE
++ + TACHO_FAN_SPEED_CONTROL_PWM_USED))
++ | (1 << TACHO_FAN_SPEED_CONTROL_FAN_COUNT_MODE));
++#endif /* OXNAS_TACHO_Ox810 */
++
++ /* be sure to really write fan speed the first time */
++ th->last_speed = -2;
++ th->last_var = -80;
++
++ /* Set fan to initial speed */
++ write_fan_speed(th, min_fan_speed_ratio);
++
++ thread_therm = kthread_run(monitor_task, th, "kfand");
++
++ if (thread_therm == ERR_PTR(-ENOMEM)) {
++ printk(KERN_INFO "thermAndFan: Kthread creation failed\n");
++ thread_therm = NULL;
++ return -ENOMEM;
++ }
++
++ ret = misc_register(&oxsemi_therm_miscdev);
++ if (ret < 0)
++ return ret;
++
++ proc_oxsemi_therm = create_proc_entry("therm-fan", 0, NULL);
++ if (proc_oxsemi_therm) {
++ proc_oxsemi_therm->read_proc = oxsemi_therm_read;
++ } else {
++ printk(KERN_ERR "therm-fan: unable to register /proc/therm\n");
++ }
++
++ return 0;
++}
++
++
++static void __exit oxsemi_therm_exit(void)
++{
++ if ( thread_therm )
++ {
++ kthread_stop(thread_therm);
++ }
++
++ remove_proc_entry("therm-fan", NULL);
++ misc_deregister(&oxsemi_therm_miscdev);
++
++ kfree(thermostat);
++ thermostat = NULL;
++/* return fan/tacho to system reset */
++ *((volatile unsigned long *) SYS_CTRL_RSTEN_SET_CTRL) |= (1UL << SYS_CTRL_RSTEN_MISC_BIT);
++}
++
++
++module_init(oxsemi_therm_init);
++module_exit(oxsemi_therm_exit);
++
++
++/* End of File */
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/thermistorCalibration.h linux-2.6.24-oxe810/arch/arm/mach-oxnas/thermistorCalibration.h
+--- linux-2.6.24/arch/arm/mach-oxnas/thermistorCalibration.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/thermistorCalibration.h 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,149 @@
++#ifndef __THERMISTOR_LOOKUP_TABLE_10K3A_H
++#define __THERMISTOR_LOOKUP_TABLE_10K3A_H
++
++/* Thermistor is a 10K3A*/
++/* THERM_COEF_A == 0.001129241*/
++/* THERM_COEF_B == 0.0002341077. */
++/* THERM_COEF_C == 0.00000008775468. */
++
++/* Capacitor is 100 nF */
++/* Stepped frequency increment is 128000 Hz */
++/* Schmitdt trigger threshold assumed: 1 / 3.3 V */
++
++
++/* Inverse C.ln(V') == 216 */
++#define THERM_INTERPOLATION_STEP 8
++#define THERM_ENTRIES_IN_CALIB_TABLE 128
++
++static const unsigned long TvsCnt[THERM_ENTRIES_IN_CALIB_TABLE] = {
++ 416, /* == 143.37 deg C: Count == 0, R == 216 Ohms */
++ 340, /* == 67.07 deg C: Count == 8, R == 1948 Ohms */
++ 323, /* == 49.59 deg C: Count == 16, R == 3679 Ohms */
++ 313, /* == 39.76 deg C: Count == 24, R == 5410 Ohms */
++ 306, /* == 33 deg C: Count == 32, R == 7141 Ohms */
++ 301, /* == 27.9 deg C: Count == 40, R == 8873 Ohms */
++ 297, /* == 23.82 deg C: Count == 48, R == 10604 Ohms */
++ 293, /* == 20.43 deg C: Count == 56, R == 12335 Ohms */
++ 291, /* == 17.55 deg C: Count == 64, R == 14066 Ohms */
++ 288, /* == 15.04 deg C: Count == 72, R == 15798 Ohms */
++ 286, /* == 12.82 deg C: Count == 80, R == 17529 Ohms */
++ 284, /* == 10.84 deg C: Count == 88, R == 19260 Ohms */
++ 282, /* == 9.04 deg C: Count == 96, R == 20991 Ohms */
++ 280, /* == 7.41 deg C: Count == 104, R == 22722 Ohms */
++ 279, /* == 5.91 deg C: Count == 112, R == 24454 Ohms */
++ 278, /* == 4.53 deg C: Count == 120, R == 26185 Ohms */
++ 276, /* == 3.25 deg C: Count == 128, R == 27916 Ohms */
++ 275, /* == 2.05 deg C: Count == 136, R == 29647 Ohms */
++ 274, /* == 0.93 deg C: Count == 144, R == 31379 Ohms */
++ 273, /* == -0.12 deg C: Count == 152, R == 33110 Ohms */
++ 272, /* == -1.12 deg C: Count == 160, R == 34841 Ohms */
++ 271, /* == -2.06 deg C: Count == 168, R == 36572 Ohms */
++ 270, /* == -2.95 deg C: Count == 176, R == 38304 Ohms */
++ 269, /* == -3.8 deg C: Count == 184, R == 40035 Ohms */
++ 268, /* == -4.6 deg C: Count == 192, R == 41766 Ohms */
++ 268, /* == -5.37 deg C: Count == 200, R == 43497 Ohms */
++ 267, /* == -6.11 deg C: Count == 208, R == 45229 Ohms */
++ 266, /* == -6.81 deg C: Count == 216, R == 46960 Ohms */
++ 266, /* == -7.49 deg C: Count == 224, R == 48691 Ohms */
++ 265, /* == -8.14 deg C: Count == 232, R == 50422 Ohms */
++ 264, /* == -8.77 deg C: Count == 240, R == 52154 Ohms */
++ 264, /* == -9.37 deg C: Count == 248, R == 53885 Ohms */
++ 263, /* == -9.95 deg C: Count == 256, R == 55616 Ohms */
++ 262, /* == -10.52 deg C: Count == 264, R == 57347 Ohms */
++ 262, /* == -11.06 deg C: Count == 272, R == 59078 Ohms */
++ 261, /* == -11.59 deg C: Count == 280, R == 60810 Ohms */
++ 261, /* == -12.1 deg C: Count == 288, R == 62541 Ohms */
++ 260, /* == -12.59 deg C: Count == 296, R == 64272 Ohms */
++ 260, /* == -13.07 deg C: Count == 304, R == 66003 Ohms */
++ 259, /* == -13.53 deg C: Count == 312, R == 67735 Ohms */
++ 259, /* == -13.99 deg C: Count == 320, R == 69466 Ohms */
++ 259, /* == -14.43 deg C: Count == 328, R == 71197 Ohms */
++ 258, /* == -14.86 deg C: Count == 336, R == 72928 Ohms */
++ 258, /* == -15.27 deg C: Count == 344, R == 74660 Ohms */
++ 257, /* == -15.68 deg C: Count == 352, R == 76391 Ohms */
++ 257, /* == -16.08 deg C: Count == 360, R == 78122 Ohms */
++ 257, /* == -16.46 deg C: Count == 368, R == 79853 Ohms */
++ 256, /* == -16.84 deg C: Count == 376, R == 81585 Ohms */
++ 256, /* == -17.21 deg C: Count == 384, R == 83316 Ohms */
++ 255, /* == -17.57 deg C: Count == 392, R == 85047 Ohms */
++ 255, /* == -17.92 deg C: Count == 400, R == 86778 Ohms */
++ 255, /* == -18.26 deg C: Count == 408, R == 88510 Ohms */
++ 254, /* == -18.6 deg C: Count == 416, R == 90241 Ohms */
++ 254, /* == -18.93 deg C: Count == 424, R == 91972 Ohms */
++ 254, /* == -19.25 deg C: Count == 432, R == 93703 Ohms */
++ 253, /* == -19.57 deg C: Count == 440, R == 95434 Ohms */
++ 253, /* == -19.88 deg C: Count == 448, R == 97166 Ohms */
++ 253, /* == -20.18 deg C: Count == 456, R == 98897 Ohms */
++ 253, /* == -20.48 deg C: Count == 464, R == 100628 Ohms */
++ 252, /* == -20.77 deg C: Count == 472, R == 102359 Ohms */
++ 252, /* == -21.06 deg C: Count == 480, R == 104091 Ohms */
++ 252, /* == -21.34 deg C: Count == 488, R == 105822 Ohms */
++ 251, /* == -21.62 deg C: Count == 496, R == 107553 Ohms */
++ 251, /* == -21.89 deg C: Count == 504, R == 109284 Ohms */
++ 251, /* == -22.16 deg C: Count == 512, R == 111016 Ohms */
++ 251, /* == -22.42 deg C: Count == 520, R == 112747 Ohms */
++ 250, /* == -22.68 deg C: Count == 528, R == 114478 Ohms */
++ 250, /* == -22.93 deg C: Count == 536, R == 116209 Ohms */
++ 250, /* == -23.18 deg C: Count == 544, R == 117941 Ohms */
++ 250, /* == -23.43 deg C: Count == 552, R == 119672 Ohms */
++ 249, /* == -23.67 deg C: Count == 560, R == 121403 Ohms */
++ 249, /* == -23.91 deg C: Count == 568, R == 123134 Ohms */
++ 249, /* == -24.14 deg C: Count == 576, R == 124866 Ohms */
++ 249, /* == -24.37 deg C: Count == 584, R == 126597 Ohms */
++ 248, /* == -24.6 deg C: Count == 592, R == 128328 Ohms */
++ 248, /* == -24.82 deg C: Count == 600, R == 130059 Ohms */
++ 248, /* == -25.04 deg C: Count == 608, R == 131790 Ohms */
++ 248, /* == -25.26 deg C: Count == 616, R == 133522 Ohms */
++ 248, /* == -25.47 deg C: Count == 624, R == 135253 Ohms */
++ 247, /* == -25.68 deg C: Count == 632, R == 136984 Ohms */
++ 247, /* == -25.89 deg C: Count == 640, R == 138715 Ohms */
++ 247, /* == -26.1 deg C: Count == 648, R == 140447 Ohms */
++ 247, /* == -26.3 deg C: Count == 656, R == 142178 Ohms */
++ 247, /* == -26.5 deg C: Count == 664, R == 143909 Ohms */
++ 246, /* == -26.69 deg C: Count == 672, R == 145640 Ohms */
++ 246, /* == -26.89 deg C: Count == 680, R == 147372 Ohms */
++ 246, /* == -27.08 deg C: Count == 688, R == 149103 Ohms */
++ 246, /* == -27.27 deg C: Count == 696, R == 150834 Ohms */
++ 246, /* == -27.46 deg C: Count == 704, R == 152565 Ohms */
++ 245, /* == -27.64 deg C: Count == 712, R == 154297 Ohms */
++ 245, /* == -27.82 deg C: Count == 720, R == 156028 Ohms */
++ 245, /* == -28 deg C: Count == 728, R == 157759 Ohms */
++ 245, /* == -28.18 deg C: Count == 736, R == 159490 Ohms */
++ 245, /* == -28.36 deg C: Count == 744, R == 161222 Ohms */
++ 244, /* == -28.53 deg C: Count == 752, R == 162953 Ohms */
++ 244, /* == -28.7 deg C: Count == 760, R == 164684 Ohms */
++ 244, /* == -28.87 deg C: Count == 768, R == 166415 Ohms */
++ 244, /* == -29.04 deg C: Count == 776, R == 168146 Ohms */
++ 244, /* == -29.21 deg C: Count == 784, R == 169878 Ohms */
++ 244, /* == -29.37 deg C: Count == 792, R == 171609 Ohms */
++ 243, /* == -29.53 deg C: Count == 800, R == 173340 Ohms */
++ 243, /* == -29.69 deg C: Count == 808, R == 175071 Ohms */
++ 243, /* == -29.85 deg C: Count == 816, R == 176803 Ohms */
++ 243, /* == -30.01 deg C: Count == 824, R == 178534 Ohms */
++ 243, /* == -30.16 deg C: Count == 832, R == 180265 Ohms */
++ 243, /* == -30.32 deg C: Count == 840, R == 181996 Ohms */
++ 243, /* == -30.47 deg C: Count == 848, R == 183728 Ohms */
++ 242, /* == -30.62 deg C: Count == 856, R == 185459 Ohms */
++ 242, /* == -30.77 deg C: Count == 864, R == 187190 Ohms */
++ 242, /* == -30.92 deg C: Count == 872, R == 188921 Ohms */
++ 242, /* == -31.06 deg C: Count == 880, R == 190653 Ohms */
++ 242, /* == -31.21 deg C: Count == 888, R == 192384 Ohms */
++ 242, /* == -31.35 deg C: Count == 896, R == 194115 Ohms */
++ 242, /* == -31.49 deg C: Count == 904, R == 195846 Ohms */
++ 241, /* == -31.63 deg C: Count == 912, R == 197578 Ohms */
++ 241, /* == -31.77 deg C: Count == 920, R == 199309 Ohms */
++ 241, /* == -31.91 deg C: Count == 928, R == 201040 Ohms */
++ 241, /* == -32.04 deg C: Count == 936, R == 202771 Ohms */
++ 241, /* == -32.18 deg C: Count == 944, R == 204502 Ohms */
++ 241, /* == -32.31 deg C: Count == 952, R == 206234 Ohms */
++ 241, /* == -32.44 deg C: Count == 960, R == 207965 Ohms */
++ 240, /* == -32.58 deg C: Count == 968, R == 209696 Ohms */
++ 240, /* == -32.71 deg C: Count == 976, R == 211427 Ohms */
++ 240, /* == -32.83 deg C: Count == 984, R == 213159 Ohms */
++ 240, /* == -32.96 deg C: Count == 992, R == 214890 Ohms */
++ 240, /* == -33.09 deg C: Count == 1000, R == 216621 Ohms */
++ 240, /* == -33.21 deg C: Count == 1008, R == 218352 Ohms */
++ 240, /* == -33.34 deg C: Count == 1016, R == 220084 Ohms */
++};
++
++#endif
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/time.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/time.c
+--- linux-2.6.24/arch/arm/mach-oxnas/time.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/time.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,159 @@
++/*
++ * linux/arch/arm/mach-oxnas/irq.c
++ *
++ * 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 <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++
++#include <asm/io.h>
++#include <asm/hardware.h>
++#include <asm/mach/time.h>
++
++#ifdef CONFIG_OXNAS_AHB_MON
++#include <asm/arch/ahb_mon.h>
++#endif // CONFIG_OXNAS_AHB_MON
++
++#ifdef CONFIG_OXNAS_DDR_MON
++static int client = 0;
++#endif // CONFIG_OXNAS_DDR_MON
++
++static irqreturn_t OXNAS_timer_interrupt(int irq, void *dev_id)
++{
++#ifdef CONFIG_OXNAS_DDR_MON
++ static const int NUM_MON_CLIENTS = 8;
++#endif // CONFIG_OXNAS_DDR_MON
++
++ write_seqlock(&xtime_lock);
++
++ // Clear the timer interrupt - any write will do
++ *((volatile unsigned long*)TIMER1_CLEAR) = 0;
++
++ timer_tick();
++
++ write_sequnlock(&xtime_lock);
++
++#ifdef CONFIG_OXNAS_DDR_MON
++ if (!(jiffies % CONFIG_OXNAS_MONITOR_SUBSAMPLE)) {
++ // Read the DDR core bus monitors
++ u32 diag_reg_contents = readl(DDR_DIAG_REG);
++ u32 holdoffs = (diag_reg_contents >> DDR_DIAG_HOLDOFFS_BIT) & ((1UL << DDR_DIAG_HOLDOFFS_NUM_BITS) - 1);
++ u32 writes = (diag_reg_contents >> DDR_DIAG_WRITES_BIT) & ((1UL << DDR_DIAG_WRITES_NUM_BITS) - 1);
++ u32 reads = (diag_reg_contents >> DDR_DIAG_READS_BIT) & ((1UL << DDR_DIAG_READS_NUM_BITS) - 1);
++
++ printk(KERN_INFO "$WC %d: H=%u, W=%u, R=%u\n", client, holdoffs, writes, reads);
++ // Re-arm the DDR core bus monitors
++ writel(client << DDR_MON_CLIENT_BIT, DDR_MON_REG);
++ if (++client >= NUM_MON_CLIENTS) {
++ client = 0;
++ }
++ }
++#endif // CONFIG_OXNAS_DDR_MON
++
++#ifdef CONFIG_OXNAS_AHB_MON
++ if (!(jiffies % CONFIG_OXNAS_MONITOR_SUBSAMPLE)) {
++ read_ahb_monitors();
++ restart_ahb_monitors();
++ }
++#endif // CONFIG_OXNAS_AHB_MON
++
++ return IRQ_HANDLED;
++}
++
++static struct irqaction oxnas_timer_irq = {
++ .name = "Jiffy tick",
++ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
++ .handler = OXNAS_timer_interrupt
++};
++
++static void /*__init*/ oxnas_init_time(void)
++{
++ // Connect the timer interrupt handler
++ oxnas_timer_irq.handler = OXNAS_timer_interrupt;
++ setup_irq(TIMER_1_INTERRUPT, &oxnas_timer_irq);
++
++ // Stop both timers before programming them
++ *((volatile unsigned long*)TIMER1_CONTROL) = 0;
++ *((volatile unsigned long*)TIMER2_CONTROL) = 0;
++
++ // Setup timer 1 load value
++ *((volatile unsigned long*)TIMER1_LOAD) = TIMER_1_LOAD_VALUE;
++
++ // Setup timer 1 prescaler, periodic operation and start it
++ *((volatile unsigned long*)TIMER1_CONTROL) =
++ (TIMER_1_PRESCALE_ENUM << TIMER_PRESCALE_BIT) |
++ (TIMER_1_MODE << TIMER_MODE_BIT) |
++ (TIMER_ENABLE_ENABLE << TIMER_ENABLE_BIT);
++
++ // Setup timer 2 prescaler, free-running operation and start it
++ // This will not be used to generate interrupt, just as a hi-res source of
++ // timing information
++ *((volatile unsigned long*)TIMER2_CONTROL) =
++ (TIMER_2_PRESCALE_ENUM << TIMER_PRESCALE_BIT) |
++ (TIMER_2_MODE << TIMER_MODE_BIT) |
++ (TIMER_ENABLE_ENABLE << TIMER_ENABLE_BIT);
++
++#ifdef CONFIG_OXNAS_DDR_MON
++ // Arm the DDR core bus monitors, start with client zero
++ writel(client << DDR_MON_CLIENT_BIT, DDR_MON_REG);
++#endif // CONFIG_OXNAS_DDR_MON
++
++#ifdef CONFIG_OXNAS_AHB_MON
++ // Monitor all accesses
++ init_ahb_monitors(AHB_MON_HWRITE_READS_AND_WRITES, 0, 0, 0, 0);
++#endif // CONFIG_OXNAS_AHB_MON
++}
++
++/*
++ * Returns number of microseconds since last clock tick interrupt.
++ * Note that interrupts will be disabled when this is called
++ * Should take account of any pending timer tick interrupt
++ */
++static unsigned long oxnas_gettimeoffset(void)
++{
++ // How long since last timer interrupt?
++ unsigned long ticks_since_last_intr =
++ (unsigned long)TIMER_1_LOAD_VALUE - *((volatile unsigned long*)TIMER1_VALUE);
++
++ // Is there a timer interrupt pending
++ int timer_int_pending =
++ *((volatile unsigned long*)RPS_IRQ_RAW_STATUS) & (1UL << TIMER_1_INTERRUPT);
++
++ if (timer_int_pending) {
++ // Sample time since last timer interrupt again. Theoretical race between
++ // interrupt occuring and ARM reading value before reload has taken
++ // effect, but in practice it's not going to happen because it takes
++ // multiple clock cycles for the ARM to read the timer value register
++ unsigned long ticks2 = (unsigned long)TIMER_1_LOAD_VALUE - *((volatile unsigned long*)TIMER1_VALUE);
++
++ // If the timer interrupt which hasn't yet been serviced, and thus has
++ // not yet contributed to the tick count, occured before our initial
++ // read of the current timer value then we need to account for a whole
++ // timer interrupt period
++ if (ticks_since_last_intr <= ticks2) {
++ // Add on a whole timer interrupt period, as the tick count will have
++ // wrapped around since the previously seen timer interrupt (?)
++ ticks_since_last_intr += TIMER_1_LOAD_VALUE;
++ }
++ }
++
++ return TICKS_TO_US(ticks_since_last_intr);
++}
++
++struct sys_timer oxnas_timer = {
++ .init = oxnas_init_time,
++ .offset = oxnas_gettimeoffset,
++};
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/usb-test-mode.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/usb-test-mode.c
+--- linux-2.6.24/arch/arm/mach-oxnas/usb-test-mode.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/usb-test-mode.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,253 @@
++/*
++ * arch/arm/mach-oxnas/usb-test-mode.c
++ *
++ * Copyright (C) 2006 Oxford Semiconductor Ltd
++ *
++ * 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 <linux/types.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/miscdevice.h>
++#include <linux/smp_lock.h>
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/sched.h>
++#include <linux/i2c.h>
++#include <linux/proc_fs.h>
++#include <linux/capability.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/spinlock.h>
++#include <linux/smp_lock.h>
++#include <linux/wait.h>
++#include <linux/suspend.h>
++#include <linux/kthread.h>
++#include <linux/moduleparam.h>
++#include <linux/interrupt.h>
++
++#include <asm/io.h>
++#include <asm/system.h>
++#include <asm/sections.h>
++#include <asm/uaccess.h>
++#include <asm/bitops.h>
++
++#include <asm/hardware.h>
++
++
++/* usb test masks and offsets */
++#define TEST_MASK 0xF
++#define TEST_OFFSET 16
++
++#define MODULE_VERS "0.1"
++#define MODULE_NAME "usb_test_mode"
++MODULE_AUTHOR( "John Larkworthy" );
++MODULE_DESCRIPTION( "Driver to put usb ports in test modes" );
++MODULE_LICENSE( "GPL" );
++
++
++static struct proc_dir_entry *proc_dir_usb_test_read, *usb_test_dir;
++
++
++/* create proc filing system entries to accept configuration data */
++static int usb_test_write_entries(const char *name, write_proc_t *w, int data)
++{
++ struct proc_dir_entry * entry = create_proc_entry(name, 0222, usb_test_dir);
++ if (entry) {
++ entry->write_proc = w;
++ entry->data = (void *)data;
++ entry->owner = THIS_MODULE;
++ return 0;
++ }
++ else
++ {
++ return -ENOMEM;
++ }
++}
++
++
++
++#if 0
++static int
++oxsemi_usb_test_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
++{
++ //int i = (int __user *)arg;
++
++ printk(KERN_INFO "usb test:: usb_test_ioctl\n");
++ switch(cmd) {
++ case SET_TEST_MODE:
++ break;
++ // etc...
++
++ default:
++ return -ENOIOCTLCMD;
++ }
++
++ return 0;
++}
++#endif
++
++static int
++oxsemi_usb_test_read(char *buf, char **start, off_t offset,
++ int count, int *eof, void *unused)
++{
++
++ int i;
++ int len = 0;
++ long unsigned *usbport;
++
++ usbport = (long unsigned *) (USB_BASE+0x184);
++
++ for (i=0; i < 3; i++)
++ {
++ len += sprintf(buf+len, "usb port %d [%p]:%08lx \n", i, (usbport+4*i) , *(usbport+i));
++ }
++ *eof=1;
++ return len;
++}
++
++static int
++oxsemi_usb_test_write(struct file *file, const char *buf, unsigned long count, void * data)
++{
++ int len;
++ long int *usbport;
++ char local[10];
++ int result;
++ int test_mode;
++ unsigned long flags;
++
++ if (count > 9)
++ len= 9;
++ else
++ len=count;
++
++ if (copy_from_user(&local, buf, len))
++ return -EFAULT;
++
++ /* extract value from buffer and store */
++ result = sscanf(local, "%1d", &test_mode);
++ if (result != 1)
++ return -EINVAL;
++
++ usbport = (long int *) (USB_BASE+0X184 + (4* (int) data));
++ printk(KERN_ERR "usb-test-write : [%08lx] <- %08lx \n",
++ (long unsigned) usbport,
++ (long unsigned) ((test_mode & TEST_MASK) << TEST_OFFSET));
++ /* lock system while this is updated */
++ local_irq_save(flags);
++ *usbport = (*usbport & ~(TEST_MASK<<TEST_OFFSET)) | ((test_mode & TEST_MASK) << TEST_OFFSET);
++ local_irq_restore(flags);
++ printk(KERN_ERR "usb-test-writen: [%08lx]:%08lx \n", (long unsigned) usbport, (long unsigned) *usbport);
++ return len;
++}
++
++
++static int __init oxsemi_usb_test_init(void)
++{
++ int rv;
++ int i;
++ char name[] = "usb-test/write0"; /* overwritten with new name below */
++
++ usb_test_dir = proc_mkdir(MODULE_NAME, NULL);
++ if (usb_test_dir == NULL) {
++ printk(KERN_ERR "usb-test: unable to register /proc/usb-test\n");
++ rv= -ENOMEM;
++ goto out;
++ }
++
++ usb_test_dir->owner= THIS_MODULE;
++
++ proc_dir_usb_test_read = create_proc_entry("read", 0444, usb_test_dir);
++ if (proc_dir_usb_test_read) {
++ proc_dir_usb_test_read->read_proc = oxsemi_usb_test_read;
++ } else {
++ printk(KERN_ERR "usb-test: unable to register /proc/usb-test/read\n");
++ rv = -ENOMEM;
++ goto no_read;
++ }
++ /* create port write file entries */
++ for (i=0;i<3;i++)
++ {
++ sprintf(name,"write%d",i+1);
++ rv = usb_test_write_entries(name, &oxsemi_usb_test_write, i);
++ if (rv < 0)
++ {
++ while (i != 0)
++ {
++ i--;
++ /* remove any allocated entries */
++ sprintf(name,"usb-test/write%d",i+1);
++ remove_proc_entry (name, usb_test_dir);
++ }
++ goto no_write;
++ }
++ }
++ printk(KERN_INFO "%s %s initialised\n", MODULE_NAME, MODULE_VERS);
++
++ return 0;
++ no_write:
++ remove_proc_entry("usb-test/read", usb_test_dir);
++ no_read:
++ remove_proc_entry(MODULE_NAME, NULL);
++ out:
++ return rv;
++}
++
++
++static void __exit oxsemi_usb_test_exit(void)
++{
++ char name[] = "usb-test/write0";
++ int i;
++
++ for (i = 0; i < 3; i++)
++ {
++ sprintf(name, "write%1d", (i+1));
++ remove_proc_entry(name, usb_test_dir);
++ }
++
++ remove_proc_entry("read", usb_test_dir);
++ remove_proc_entry(MODULE_NAME, NULL);
++
++ printk(KERN_INFO "%s %s removed\n", MODULE_NAME, MODULE_VERS);
++
++}
++
++
++module_init(oxsemi_usb_test_init);
++module_exit(oxsemi_usb_test_exit);
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/user_recovery_button.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/user_recovery_button.c
+--- linux-2.6.24/arch/arm/mach-oxnas/user_recovery_button.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/user_recovery_button.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,260 @@
++/*
++ * linux/arch/arm/mach-oxnas/user_recovery_button.c
++ *
++ * Copyright (C) 2008 Oxford Semiconductor Ltd
++ *
++ * 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 <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/timer.h>
++#include <linux/kobject.h>
++#include <linux/workqueue.h>
++#include <asm/hardware.h>
++#include <asm/io.h>
++
++MODULE_LICENSE("GPL v2");
++
++#if (CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO < 32)
++#define SWITCH_NUM CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO
++#define IRQ_NUM GPIO_1_INTERRUPT
++#define INT_STATUS_REG GPIO_A_INTERRUPT_STATUS_REGISTER
++#define SWITCH_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_0
++#define SWITCH_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_0
++#define SWITCH_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_0
++#define SWITCH_CLR_OE_REG GPIO_A_OUTPUT_ENABLE_CLEAR
++#define DEBOUNCE_REG GPIO_A_INPUT_DEBOUNCE_ENABLE
++#define LEVEL_INT_REG GPIO_A_LEVEL_INTERRUPT_ENABLE
++#define FALLING_INT_REG GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE
++#define DATA_REG GPIO_A_DATA
++#else
++#define SWITCH_NUM ((CONFIG_OXNAS_USER_RECOVERY_BUTTON_GPIO) - 32)
++#define IRQ_NUM GPIO_2_INTERRUPT
++#define INT_STATUS_REG GPIO_B_INTERRUPT_STATUS_REGISTER
++#define SWITCH_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_1
++#define SWITCH_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_1
++#define SWITCH_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_1
++#define SWITCH_CLR_OE_REG GPIO_B_OUTPUT_ENABLE_CLEAR
++#define DEBOUNCE_REG GPIO_B_INPUT_DEBOUNCE_ENABLE
++#define LEVEL_INT_REG GPIO_B_LEVEL_INTERRUPT_ENABLE
++#define FALLING_INT_REG GPIO_B_FALLING_EDGE_ACTIVE_LOW_ENABLE
++#define DATA_REG GPIO_B_DATA
++#endif
++
++#define SWITCH_MASK (1UL << (SWITCH_NUM))
++
++#define TIMER_INTERVAL_JIFFIES ((HZ) >> 3) /* An eigth of a second */
++#define TIMER_COUNT_LIMIT 32 /* In eigths of a second */
++
++extern spinlock_t oxnas_gpio_spinlock;
++
++static unsigned long count;
++static struct timer_list timer;
++
++/** Have to use active low level interupt generation, as otherwise might miss
++ * interrupts that arrive concurrently with a PCI interrupt, as PCI interrupts
++ * are generated via GPIO pins and std PCI drivers will not know that there
++ * may be other pending GPIO interrupt sources waiting to be serviced and will
++ * simply return IRQ_HANDLED if they see themselves as having generated the
++ * interrupt, thus preventing later chained handlers from being called
++ */
++static irqreturn_t int_handler(int irq, void* dev_id)
++{
++ int status = IRQ_NONE;
++ unsigned int int_status = readl((volatile unsigned long *)INT_STATUS_REG);
++
++ /* Is the interrupt for us? */
++ if (int_status & SWITCH_MASK) {
++ /* Disable the user recovery button GPIO line interrupt */
++ spin_lock(&oxnas_gpio_spinlock);
++ writel(readl(FALLING_INT_REG) & ~SWITCH_MASK, FALLING_INT_REG);
++ spin_unlock(&oxnas_gpio_spinlock);
++
++ /* Zeroise button hold down counter */
++ count = 0;
++
++ /* Start hold down timer with a timeout of 1/8 second */
++ mod_timer(&timer, jiffies + TIMER_INTERVAL_JIFFIES);
++
++ /* Only mark interrupt as serviced if no other unmasked GPIO interrupts
++ are pending */
++ if (!readl((volatile unsigned long *)INT_STATUS_REG)) {
++ status = IRQ_HANDLED;
++ }
++ }
++
++ return status;
++}
++
++/*
++ * Device driver object
++ */
++typedef struct recovery_button_driver_s {
++ /** sysfs dir tree root for recovery button driver */
++ struct kset kset;
++ struct kobject recovery_button;
++} recovery_button_driver_t;
++
++static recovery_button_driver_t recovery_button_driver;
++
++static void work_handler(struct work_struct * not_used) {
++ kobject_uevent(&recovery_button_driver.recovery_button, KOBJ_OFFLINE);
++}
++
++DECLARE_WORK(recovery_button_hotplug_work, work_handler);
++
++static void timer_handler(unsigned long data)
++{
++ unsigned long flags;
++
++ /* Is the user recovery button still pressed? */
++ if (!(readl(DATA_REG) & SWITCH_MASK)) {
++ /* Yes, so increment count of how many timer intervals have passed since
++ user recovery button was pressed */
++ if (++count == TIMER_COUNT_LIMIT) {
++ schedule_work(&recovery_button_hotplug_work);
++ } else {
++ /* Restart timer with a timeout of 1/8 second */
++ mod_timer(&timer, jiffies + TIMER_INTERVAL_JIFFIES);
++ }
++ } else {
++ /* The h/w debounced user recovery button has been released, so reenable the
++ active low interrupt detection to trap the user's next attempt to
++ recover */
++ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
++ writel(readl(FALLING_INT_REG) | SWITCH_MASK, FALLING_INT_REG);
++ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
++ }
++}
++
++static struct kobj_type ktype_recovery_button = {
++ .release = 0,
++ .sysfs_ops = 0,
++ .default_attrs = 0,
++};
++
++static int recovery_button_hotplug_filter(struct kset* kset, struct kobject* kobj) {
++ return get_ktype(kobj) == &ktype_recovery_button;
++}
++
++static const char* recovery_button_hotplug_name(struct kset* kset, struct kobject* kobj) {
++ return "oxnas_user_recovery";
++}
++
++static struct kset_uevent_ops recovery_button_uevent_ops = {
++ .filter = recovery_button_hotplug_filter,
++ .name = recovery_button_hotplug_name,
++ .uevent = NULL,
++};
++
++static int recovery_button_prep_sysfs(void)
++{
++ int err = 0;
++
++ /* prep the sysfs interface for use */
++ kobject_set_name(&recovery_button_driver.kset.kobj, "recovery-button");
++ recovery_button_driver.kset.ktype = &ktype_recovery_button;
++
++ err = subsystem_register(&recovery_button_driver.kset);
++ if (err)
++ return err;
++
++ /* setup hotplugging */
++ recovery_button_driver.kset.uevent_ops = &recovery_button_uevent_ops;
++
++ /* setup the heirarchy, the name will be set on detection */
++ kobject_init(&recovery_button_driver.recovery_button);
++ recovery_button_driver.recovery_button.kset = kset_get(&recovery_button_driver.kset);
++ recovery_button_driver.recovery_button.parent = &recovery_button_driver.kset.kobj;
++
++ return 0;
++}
++
++static int recovery_button_build_sysfs(void) {
++ kobject_set_name(&recovery_button_driver.recovery_button, "recovery-button-1");
++ return kobject_add(&recovery_button_driver.recovery_button);
++}
++
++static int __init recovery_button_init(void)
++{
++ int err = 0;
++ unsigned long flags;
++
++ err = recovery_button_prep_sysfs();
++ if (err)
++ return -EINVAL;
++
++ err = recovery_button_build_sysfs();
++ if (err)
++ return -EINVAL;
++
++ /* Setup the timer that will time how long the user holds down the recovery
++ button */
++ init_timer(&timer);
++ timer.data = 0;
++ timer.function = timer_handler;
++
++ /* Install a shared interrupt handler on the appropriate GPIO bank's
++ interrupt line */
++ if (request_irq(IRQ_NUM, int_handler, IRQF_SHARED, "User Recovery Button", &recovery_button_driver)) {
++ printk(KERN_ERR "User Recovery Button: cannot register IRQ %d\n", IRQ_NUM);
++ del_timer_sync(&timer);
++ return -EIO;
++ }
++
++ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
++ /* Disable primary, secondary and teriary GPIO functions on switch lines */
++ writel(readl(SWITCH_PRISEL_REG) & ~SWITCH_MASK, SWITCH_PRISEL_REG);
++ writel(readl(SWITCH_SECSEL_REG) & ~SWITCH_MASK, SWITCH_SECSEL_REG);
++ writel(readl(SWITCH_TERSEL_REG) & ~SWITCH_MASK, SWITCH_TERSEL_REG);
++
++ /* Enable GPIO input on switch line */
++ writel(SWITCH_MASK, SWITCH_CLR_OE_REG);
++
++ /* Set up the user recovery button GPIO line for active low, debounced interrupt */
++ writel(readl(DEBOUNCE_REG) | SWITCH_MASK, DEBOUNCE_REG);
++ writel(readl(LEVEL_INT_REG) | SWITCH_MASK, LEVEL_INT_REG);
++ writel(readl(FALLING_INT_REG) | SWITCH_MASK, FALLING_INT_REG);
++ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
++
++ printk(KERN_INFO "Recovery button driver registered\n");
++ return 0;
++}
++
++static void __exit recovery_button_exit(void)
++{
++ unsigned long flags;
++
++ kobject_del(&recovery_button_driver.recovery_button);
++ subsystem_unregister(&recovery_button_driver.kset);
++
++ /* Deactive the timer */
++ del_timer_sync(&timer);
++
++ /* Disable interrupt generation by the recovery button GPIO line */
++ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
++ writel(readl(FALLING_INT_REG) & ~SWITCH_MASK, FALLING_INT_REG);
++ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
++
++ /* Remove the handler for the shared interrupt line */
++ free_irq(IRQ_NUM, &recovery_button_driver);
++}
++
++/**
++ * macros to register intiialisation and exit functions with kernal
++ */
++module_init(recovery_button_init);
++module_exit(recovery_button_exit);
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/wdc-fan.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/wdc-fan.c
+--- linux-2.6.24/arch/arm/mach-oxnas/wdc-fan.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/wdc-fan.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,336 @@
++/*
++ * linux/arch/arm/mach-oxnas/wdc-fan.c
++ *
++ * Copyright (C) 2006-2007 Western Digital
++ *
++ * 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 <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/ctype.h>
++#include <linux/platform_device.h>
++#include <asm/hardware.h>
++
++/* Human recognizable driver name. */
++#define DRIVER_NAME "WDC_Fan"
++
++/* GPIOs for the fan on the Galaxy 2NC platform. All are on GPIO_A */
++#define FAN_MASK_LOW (1 << GPIO_29)
++#define FAN_MASK_HIGH (1 << GPIO_8)
++
++#define FAN_MASK ( FAN_MASK_LOW | FAN_MASK_HIGH )
++
++
++/* I/O register access (FIXME: why not use the standard linux macros?) */
++#define ox_writel(data, addr) (*(volatile unsigned long*)addr = (data))
++#define ox_readl(addr) (*(volatile unsigned long*)addr)
++#define writel(data, addr) (*(volatile u32*)addr = (data))
++#define readl(addr) (*(volatile u32*)addr)
++#define CLEAR(addr, mask) writel(readl(addr) & ~mask, addr)
++
++enum fan_speeds
++{
++ FAN_OFF = 0,
++ FAN_SPEED_MAX = 100
++};
++
++typedef struct s_fan_device_state
++{
++ unsigned char speed; /* Range FAN_OFF .. FAN_SPEED_MAX */
++} fan_device_state;
++
++
++/*
++ * Driver-global variables.
++ */
++
++/* Number of successful probes. */
++/* TODO: protect this variable??!? */
++static int fans_found;
++
++/* This spinlock protects the GPIO setup code from
++ interrupts but is not SMP-correct. */
++static spinlock_t oxnas_gpio_spinlock;
++
++/* Device instance state.
++ Only one fan is supported, so this can be a global variable. */
++static fan_device_state fan_state;
++
++
++/*
++ * Device attribute getter/setters
++ */
++static ssize_t fan_speed_show (struct device*, struct device_attribute*,
++ char *buf);
++
++static ssize_t fan_speed_store(struct device*, struct device_attribute*,
++ const char *buf, size_t count);
++
++/* Declare device attributes using the functions above.
++ Contrary to the macro's name, DEVICE_ATTR declares a dev_attr_... */
++static DEVICE_ATTR(speed, 0644, fan_speed_show, fan_speed_store);
++
++
++static void set_fan_speed(unsigned char speed);
++
++static int fan_probe (struct platform_device *pdev);
++static int fan_remove(struct platform_device *pdev);
++
++
++
++/***************************************************************************/
++/* FUNCTION: fan_probe */
++/* */
++/* PURPOSE: */
++/* Look for fans and do initialize. */
++/***************************************************************************/
++int fan_probe(struct platform_device *pdev)
++{
++ int rc = 0;
++
++ do {
++ unsigned long lock_flags;
++
++ printk(KERN_DEBUG "Fan probe\n");
++
++ memset(&fan_state, sizeof(fan_state), 0);
++
++ /* Setup the fan-control GPIO lines properly. */
++ spin_lock_irqsave(&oxnas_gpio_spinlock, lock_flags);
++
++ do {
++ /* Enable desired GPIO drivers by disabling other functions. */
++ CLEAR(SYS_CTRL_GPIO_PRIMSEL_CTRL_0, FAN_MASK);
++ CLEAR(SYS_CTRL_GPIO_SECSEL_CTRL_0, FAN_MASK);
++ CLEAR(SYS_CTRL_GPIO_TERTSEL_CTRL_0, FAN_MASK);
++
++ /* Turn off the fan... then enable its outputs. */
++ writel(FAN_MASK, GPIO_A_OUTPUT_CLEAR);
++ writel(FAN_MASK, GPIO_A_OUTPUT_ENABLE_SET);
++
++ } while (0);
++
++ spin_unlock_irqrestore(&oxnas_gpio_spinlock, lock_flags);
++
++
++ /* Create an entry in sysfs so user apps can control the fan. */
++ rc = device_create_file(&pdev->dev, &dev_attr_speed);
++ if (rc < 0) break;
++
++ fans_found++;
++
++ set_fan_speed(FAN_OFF);
++
++ } while(0);
++
++
++ /* Cleanup if any errors occured. */
++ if(rc < 0)
++ {
++ fan_remove(pdev);
++ }
++
++ return rc;
++}
++
++
++/***************************************************************************/
++/* FUNCTION: fan_remove */
++/* */
++/* PURPOSE: */
++/* Deactive the fan device(s) */
++/***************************************************************************/
++int fan_remove(struct platform_device *pdev)
++{
++ printk(KERN_DEBUG "Fan remove\n");
++
++ /* Undo everything that might have been done by fan_probe() */
++
++ device_remove_file(&pdev->dev, &dev_attr_speed);
++
++ writel(FAN_MASK, GPIO_A_OUTPUT_ENABLE_CLEAR);
++
++ return 0;
++}
++
++
++/***************************************************************************/
++/* */
++/* sysfs attribute I/O - user-space control points */
++/* */
++/***************************************************************************/
++
++/* fan_speed_show()
++ *
++ * Called when the speed setting attribute is read;
++ * returns the current fan speed.
++ */
++ssize_t fan_speed_show(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ /* TODO: Check sizeof buf? Nobody else does*/
++
++ return sprintf(buf, "%u\n", fan_state.speed);
++}
++
++/* fan_speed_store()
++ *
++ * Called when the speed setting attribute is written;
++ * sets a new fan speed.
++ */
++ssize_t fan_speed_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ char *end;
++ long newSpeed;
++
++ newSpeed = simple_strtol(buf, &end, 10);
++ while (*end)
++ {
++ if (!isspace(*end++)) return -EINVAL;
++ }
++
++ if (newSpeed < 0) newSpeed = 0;
++ if (newSpeed > FAN_SPEED_MAX) newSpeed = FAN_SPEED_MAX;
++
++ set_fan_speed( (unsigned char)newSpeed );
++
++ return count; /* Entire string was consumed and validated. */
++}
++
++/* set_fan_speed()
++ *
++ * Sets the fan's speed by twiddling its power control (GPO) lines.
++ */
++void set_fan_speed(unsigned char newSpeed)
++{
++int oldSpeed = fan_state.speed;
++
++ /* Round the requested fan speed to the nearest supported
++ value and set the fan's power lines appropriately. */
++
++ /* The 2NC platform has three fan settings: off, low, hi-speed. */
++
++ if (newSpeed < 10)
++ {
++ fan_state.speed = FAN_OFF; /* Turn off the fan. */
++ writel(FAN_MASK_LOW | FAN_MASK_HIGH, GPIO_A_OUTPUT_CLEAR);
++ }
++ else if (newSpeed < 75)
++ {
++ fan_state.speed = 50; /* Set to low speed. */
++ writel(FAN_MASK_HIGH, GPIO_A_OUTPUT_CLEAR);
++ writel(FAN_MASK_LOW, GPIO_A_OUTPUT_SET);
++ }
++ else
++ {
++ fan_state.speed = FAN_SPEED_MAX; /* Set to max (high) speed. */
++ writel(FAN_MASK_LOW | FAN_MASK_HIGH, GPIO_A_OUTPUT_SET);
++ }
++
++ if (oldSpeed != fan_state.speed)
++ {
++#if 0
++ printk(KERN_DEBUG "WDC Fan speed set %u\n", fan_state.speed);
++#endif
++ }
++}
++
++
++/***************************************************************************/
++/* DATA STRUCTURE: wdc_leds_driver */
++/* */
++/* PURPOSE: */
++/* Describe the wdc-leds platform device driver */
++/***************************************************************************/
++static struct platform_driver fan_driver =
++{
++ .probe = fan_probe,
++ .remove = fan_remove,
++ .driver =
++ {
++ .name = "wdc-fan",
++ },
++};
++
++static struct platform_device *fan_device;
++
++/***************************************************************************/
++/* FUNCTION: wdc_leds_init */
++/* */
++/* PURPOSE: */
++/* Perform module initialization */
++/***************************************************************************/
++static int __init wdc_fan_init(void)
++{
++ int rc = 0;
++
++ fans_found = 0;
++ spin_lock_init(&oxnas_gpio_spinlock);
++
++ rc = platform_driver_register(&fan_driver);
++ if (rc) goto quit;
++
++ fan_device = platform_device_register_simple("wdc-fan", -1, NULL, 0);
++ if (IS_ERR(fan_device))
++ {
++ rc = PTR_ERR(fan_device);
++ fan_device = NULL;
++
++ platform_driver_unregister(&fan_driver);
++ goto quit;
++ }
++
++
++quit:
++ if (rc)
++ {
++ printk(KERN_ERR DRIVER_NAME " init failed, rc=%i\n", rc);
++ }
++ else
++ {
++ printk(KERN_INFO DRIVER_NAME " initialized\n");
++ }
++
++ return rc;
++}
++
++
++/***************************************************************************/
++/* FUNCTION: wdc_leds_exit */
++/* */
++/* PURPOSE: */
++/* Perform module unloading and cleanup */
++/***************************************************************************/
++static void __exit wdc_fan_exit(void)
++{
++ platform_device_unregister(fan_device);
++ platform_driver_unregister(&fan_driver);
++
++ printk(KERN_INFO DRIVER_NAME " goodbye!\n");
++}
++
++
++module_init(wdc_fan_init);
++module_exit(wdc_fan_exit);
++
++MODULE_AUTHOR("James Lin");
++MODULE_DESCRIPTION("Western Digital NetCenter/2NC Fan Control");
++MODULE_LICENSE("GPL");
++
++/*EOF*/
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/wdc-leds.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/wdc-leds.c
+--- linux-2.6.24/arch/arm/mach-oxnas/wdc-leds.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/wdc-leds.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,1299 @@
++/*
++ * linux/arch/arm/mach-oxnas/wdc-leds.c
++ *
++ * Copyright (C) 2006 Western Digital
++ *
++ * 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 <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/timer.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/leds.h>
++#include <asm/hardware.h>
++
++#define DEBUG
++
++#ifdef DEBUG
++ #define DUMP(A,B) printk(KERN_INFO A,B);
++#else
++ #define DUMP(A,B)
++#endif
++
++/* Number of LEDs */
++#define NUM_ACTIVITY_LEDS 4
++#define NUM_FUEL_GAUGE_LEDS 6
++
++/* Timer Values and Pulse Width Modulation */
++#define PWM_RESOLUTION 255
++#define TIMER_LED_MODE TIMER_MODE_PERIODIC
++
++#define PWM_CLOCK_DATA (
++
++#define LED100 (PWM_RESOLUTION) /* 100% duty cycle */
++#define LED50 (PWM_RESOLUTION / 2) /* 50% duty cycle */
++#define LED25 (PWM_RESOLUTION / 4) /* 25% duty cycle */
++
++#define STEP_RESOLUTION (16) /* change intensity in 16 steps */
++
++/* Setup Timer2 prescaler, operation mode, and start it */
++#define PERIODIC_INTERRUPT \
++ ( \
++ (TIMER_PRESCALE_256 << TIMER_PRESCALE_BIT) | \
++ (TIMER_LED_MODE << TIMER_MODE_BIT) | \
++ (TIMER_ENABLE_ENABLE << TIMER_ENABLE_BIT) \
++ )
++
++/*
++ * Target frame rate is 60Hz. Slower frame rates flicker badly.
++ * Since each frame has 16 divisions to perform the pulse width
++ * modulation that means we need the timer set to 960Hz (i.e. 60 * 16)
++ *
++ * With a system clock of 25Mhz and a load register value of 1627 prescaled 256
++ * to achieve 60Hz:
++ * 25Mhz / 256 / 1627 = ~60
++ */
++#define FAST_TIMER_INT (1627) /* Timer2 count down */
++#define SYS_CLOCK (25000000) /* System clock frequency */
++#define PRESCALE_VALUE (256) /* Value set in prescaler */
++#define PWM_PRESCALE 814 /* Value loaded on PWM clock register */
++#define MAX_PWM 255
++#define SLOW_TPS ((SYS_CLOCK/PRESCALE_VALUE) / FAST_TIMER_INT)
++
++/* The GPIO assignent to LED Masks need to make sure that the
++ * LED_MASK_GPIO_A and LED_MASK_GPIO_B are set appropriately
++ * based on the GPIOs assigned
++ */
++
++/* GPIO bits dedicated to LEDs */
++#define LED_MASK_ACT12 (1 << GPIO_6) /* Activity 12 o'clock */
++#define LED_MASK_ACT3 (1 << GPIO_7) /* Activity 3 o'clock */
++#define LED_MASK_ACT6 (1 << GPIO_5) /* Activity 6 o'clock */
++#define LED_MASK_ACT9 (1 << GPIO_34) /* Activity 9 o'clock */
++#define LED_MASK_FG12 (1 << GPIO_10) /* Fuel Gauge 10 o'clock */
++#define LED_MASK_FG2 (1 << GPIO_9) /* Fuel Gauge 8 o'clock */
++#define LED_MASK_FG4 (1 << GPIO_25) /* Fuel Gauge 6 o'clock */
++#define LED_MASK_FG6 (1 << GPIO_26) /* Fuel Gauge 4 o'clock */
++#define LED_MASK_FG8 (1 << GPIO_27) /* Fuel Gauge 2 o'clock */
++#define LED_MASK_FG10 (1 << GPIO_33) /* Fuel Gauge 12 o'clock */
++
++/*
++ * Mask for all the LEDs in the Fuel Gauge. This is in frame buffer format
++ * (see LED frame buffer design assumption comments below, near the
++ * frame_buffer declaration).
++ */
++#define LED_MASK_FUEL_GAUGE \
++ ( \
++ LED_MASK_FG12 | \
++ LED_MASK_FG2 | \
++ LED_MASK_FG4 | \
++ LED_MASK_FG6 | \
++ LED_MASK_FG8 | \
++ LED_MASK_FG10 \
++ )
++
++/* Mask for all the Activity LEDs */
++#define LED_MASK_ACTIVITY \
++ ( \
++ LED_MASK_ACT12 | \
++ LED_MASK_ACT3 | \
++ LED_MASK_ACT6 | \
++ LED_MASK_ACT9 \
++ )
++
++/* The GPIO_A and GPIO_B Masks below need to be set based on the
++ * GPIO numbers that are assigned for the LED MASKS
++ */
++
++/* Mask for all the LEDs on GPIO_A */
++#define LED_MASK_GPIO_A \
++ ( \
++ LED_MASK_ACT12 | \
++ LED_MASK_ACT3 | \
++ LED_MASK_ACT6 | \
++ LED_MASK_FG12 | \
++ LED_MASK_FG2 | \
++ LED_MASK_FG4 | \
++ LED_MASK_FG6 | \
++ LED_MASK_FG8 \
++ )
++
++/* Mask for all the LEDs on GPIO_B */
++#define LED_MASK_GPIO_B \
++ ( \
++ LED_MASK_ACT9 | \
++ LED_MASK_FG10 \
++ )
++
++/* I/O register access (FIXME: why not use the standard linux macros?) */
++#define ox_writel(data, addr) (*(volatile unsigned long*)addr = (data))
++#define ox_readl(addr) (*(volatile unsigned long*)addr)
++#define writel(data, addr) (*(volatile u32*)addr = (data))
++#define readl(addr) (*(volatile u32*)addr)
++#define CLEAR(addr, mask) writel(readl(addr) & ~mask, addr)
++
++
++/* Variables to hold the number of LED classes created */
++static int leds_created;
++
++/* Variables to save/restore timer register values */
++static u32 timer_load;
++static u32 timer_control;
++
++/* LED polarity */
++static int negative_led_logic = 0;
++module_param(negative_led_logic, bool, 0);
++
++/*
++ * States for the main LED behavior state machine. The order of these states
++ * is important. In particular, the TRANS states use this ordering so that
++ * incrementing the state variable walks through the ordering shown below.
++ * This allows most of the TRANS states to share common code.
++ */
++enum {
++ FULLY_ON__ENTRY, /* FullyOn - Initialize */
++ FULLY_ON__RE_ENTRY, /* FullyOn - Initialize (skipping POR) */
++ FULLY_ON__POR_RAMP_UP, /* FullyOn - Ramp up full ring */
++ FULLY_ON__POR_HOLD, /* FullyOn - Hold a while with full ring */
++ FULLY_ON__RAMP_UP, /* FullyOn - Ramp up full ring (skipping POR) */
++ FULLY_ON__ACTIVITY, /* FullyOn - Read/write activity */
++ FULLY_ON__IDLE_HOLD, /* FullyOn - Hold a while for no R/W activity */
++ FULLY_ON__RAMP_DOWN, /* FullyOn - Ramp down full ring */
++ STANDBY__ENTRY, /* Standby - Initialize */
++ STANDBY__DARK, /* Standby - Full ring off */
++ STANDBY__RAMP_UP, /* Standby - Ramp up full ring */
++ STANDBY__RAMP_DOWN, /* Standby - Ramp down full ring */
++ POWER_OFF__ENTRY, /* PowerOff - Initialize */
++ POWER_OFF__DARK, /* PowerOff - Full ring off */
++ DEGRADED__ENTRY, /* Degraded - Initialize */
++ DEGRADED__BLINK1, /* Degraded - Blink step1 */
++ DEGRADED__BLINK2, /* Degraded - Blink step2 */
++ OVERTEMP__ENTRY, /* OverTemp - Initialize */
++ OVERTEMP__BLINK1, /* OverTemp - Blink step1 */
++ OVERTEMP__BLINK2, /* OverTemp - Blink step2 */
++ TRANS__ENTRY, /* Transition - Initialize */
++ TRANS__1_UP, /* 1st cycle - up 12 & 6 - down 9 & 3 o'clock */
++ TRANS__1_DN, /* 1st cycle - down 12 & 6 - up 9 & 3 o'clock */
++ TRANS__2_UP, /* 2nd cycle - up 12 & 6 - down 9 & 3 o'clock */
++ TRANS__2_DN, /* 2nd cycle - down 12 & 6 - up 9 & 3 o'clock */
++ TRANS__3_UP, /* 3rd cycle - up 12 & 6 - down 9 & 3 o'clock */
++ TRANS__3_DN, /* 3rd cycle - down 12 & 6 - up 9 & 3 o'clock */
++ TRANS__4_UP, /* 4th cycle - up 12 & 6 - down 9 & 3 o'clock */
++ TRANS__4_DN /* 4th cycle - down 12 & 6 - down 9 & 3 o'clock */
++};
++
++
++/* Pattern for the activity behavior */
++const u16 activity_pattern[NUM_ACTIVITY_LEDS] = {
++ LED100,
++ LED25,
++ 0,
++ 0
++};
++
++
++/* Various LED state machine constants */
++#define TRANS_STEP (1)
++#define SLEEP_HI (0)
++#define SLEEP_LO (-STEP_RESOLUTION)
++#define NUM_POWER_STEPS (STEP_RESOLUTION)
++#define NUM_BREATHE_STEPS (SLEEP_HI - SLEEP_LO)
++#define NUM_TRANS_STEPS ((SLEEP_HI - SLEEP_LO) / TRANS_STEP)
++#define BIT_MASK_FUEL_GAUGE ((1 << NUM_FUEL_GAUGE_LEDS) - 1)
++
++/*
++ * Calculate various speeds of the LED state machine based on the system
++ * clock frequency, the hardware timer prescaler, and the hardware timer
++ * load register value. This results in a calculation of the ticks per
++ * second (TPS) of the timer interrupt used to perform the pulse width
++ * modulation and the slower TPS of the tasklet that performs the main
++ * state machine of the LED behavior. The remaining speeds are
++ * calculated from the slow TPS.
++ */
++ #define RW_SPEED (SLOW_TPS / 4) /* want ~4Hz */
++#define BLINK_SPEED (SLOW_TPS / 2) /* want ~2Hz */
++#define HOLD_BREATH (SLOW_TPS * 4) /* want ~4sec */
++#define HOLD_ON_ENTER (SLOW_TPS * 10) /* want ~10sec */
++#define POWER_SPEED (SLOW_TPS / NUM_POWER_STEPS)
++#define BREATHE_SPEED (SLOW_TPS / NUM_BREATHE_STEPS)
++#define TRANS_SPEED (SLOW_TPS / NUM_TRANS_STEPS)
++
++#if \
++ (!SLOW_TPS) || \
++ (!RW_SPEED) || \
++ (!BLINK_SPEED) || \
++ (!POWER_SPEED) || \
++ (!BREATHE_SPEED) || \
++ (!TRANS_SPEED)
++# error TPS calculation(s) resulted in zero!
++#endif
++
++
++/* Variables for main LED behavior state machine */
++static int state;
++static int next_state;
++static int active_count;
++static int count;
++static u32 fuel_gauge_bits; /* see LED frame buffer design assumption */
++static u8 need_to_display_current_fuel_gauge;
++static u8 inner_ring_rotate;
++static u8 ignore_activity;
++static s8 active_tail;
++static s8 ramp1;
++static s8 ramp2;
++static s8 activity_led[NUM_ACTIVITY_LEDS];
++static u16 rebuild_percentage; /* 0=not rebuilding */
++
++
++/*
++ * Declare tasklet for the LED behavior state machine. The interrupt will
++ * only handle the pulse width modulation which can be performed quickly.
++ * The slower LED behavior state machine does not need to execute at such
++ * a high frequency so it will be executed by a tasklet that is
++ * periodically scheduled by the interrupt.
++ */
++void wdc_leds_behavior(unsigned long);
++DECLARE_TASKLET(wdc_leds_behavior_tasklet, wdc_leds_behavior, 0);
++
++
++/***************************************************************************/
++/* FUNCTION: wdc_leds_interrupt */
++/* */
++/* PURPOSE: */
++/* Interrupt handler for the wdc-leds pulse width modulation */
++/***************************************************************************/
++static irqreturn_t wdc_leds_interrupt
++ (int irq, void *dev_id) {
++ ox_writel(0, TIMER2_CLEAR);
++
++
++ tasklet_schedule(&wdc_leds_behavior_tasklet);
++
++ return IRQ_HANDLED;
++}
++
++
++/***************************************************************************/
++/* FUNCTION: get_inner_ring_bits */
++/* */
++/* PURPOSE: */
++/* Convert the bit map of inner ring LEDs into the GPIO bit map */
++/***************************************************************************/
++static u32 get_inner_ring_bits(u16 value)
++{
++ u32 pattern = 0;
++
++ // Convert the bit map to the GPIO bit pattern
++ if (value & (1 << 0))
++ pattern |= LED_MASK_FG2;
++ if (value & (1 << 1))
++ pattern |= LED_MASK_FG4;
++ if (value & (1 << 2))
++ pattern |= LED_MASK_FG6;
++ if (value & (1 << 3))
++ pattern |= LED_MASK_FG8;
++ if (value & (1 << 4))
++ pattern |= LED_MASK_FG10;
++ if (value & (1 << 5))
++ pattern |= LED_MASK_FG12;
++
++ return pattern;
++}
++
++
++/***************************************************************************/
++/* FUNCTION: get_percentage_pattern */
++/* */
++/* PURPOSE: */
++/* Convert a percentage to a inner ring bit map. Note, we never display */
++/* less than 1 LED for a percentage so that something is alway visible. */
++/***************************************************************************/
++static u16 get_percentage_pattern(u16 percentage)
++{
++ if (percentage >= 50) {
++ if (percentage >= 67) {
++ if (percentage >= 83) {
++ if (percentage >= 97) {
++ return 0x3F; // 6 LEDs is >= 97%
++ } else {
++ return 0x1F; // 5 LEDs is >= 83%
++ }
++ } else {
++ return 0x0F; // 4 LEDs is >= 67%
++ }
++ } else {
++ return 0x07; // 3 LEDs is >= 50%
++ }
++ } else {
++ if (percentage >= 33) {
++ return 0x03; // 2 LEDs is >= 33%
++ } else {
++ return 0x01; // 1 LED is >= 0%
++ }
++ }
++}
++
++
++/***************************************************************************/
++/* FUNCTION: set_led */
++/* */
++/* PURPOSE: */
++/* Set frame buffer for the requested brightness on the requested LED(s) */
++/***************************************************************************/
++static void set_led(u32 led_bits, s8 value)
++{
++ u32 bit;
++ s8 count = 0;
++
++ if (negative_led_logic) {
++ value = MAX_PWM - value;
++ }
++
++ for (bit = 1; bit > 0; bit <<= 1, ++count) {
++ if (bit & led_bits) writel(value, ((u32 *)PWM_DATA_REGISTER_BASE + count ));
++ }
++}
++
++
++/***************************************************************************/
++/* FUNCTION: display_inner_ring */
++/* */
++/* PURPOSE: */
++/* Set frame buffer for the requested inner ring bit map */
++/***************************************************************************/
++static void display_inner_ring(u32 inner_ring_bits)
++{
++ set_led(~inner_ring_bits & LED_MASK_FUEL_GAUGE, 0);
++ set_led(inner_ring_bits, LED100);
++}
++
++
++/***************************************************************************/
++/* FUNCTION: display_current_fuel_gauge */
++/* */
++/* PURPOSE: */
++/* Display the current Fuel Gauge if it is not already being displayed */
++/***************************************************************************/
++static void display_current_fuel_gauge(void)
++{
++ if (need_to_display_current_fuel_gauge) {
++ display_inner_ring(fuel_gauge_bits);
++ need_to_display_current_fuel_gauge = 0;
++ }
++}
++
++
++/***************************************************************************/
++/* FUNCTION: handle_inner_ring */
++/* */
++/* PURPOSE: */
++/* Perform the LED behavior for the inner ring */
++/***************************************************************************/
++static void handle_inner_ring(void)
++{
++ /* If currently rebuilding then display the rebuild percentage as */
++ /* a series of LEDs representing the percentage complete rotating */
++ /* around the inner ring. Note, the percentage is rotated to */
++ /* distinguish it from normal fuel gauge behavior. */
++ if (rebuild_percentage) {
++ /* Convert the rebuild percentage into a bit map of LEDs */
++ u32 rotated_pattern = get_percentage_pattern(rebuild_percentage);
++ /* Now rotate that pattern */
++ rotated_pattern <<= inner_ring_rotate;
++ rotated_pattern |= (rotated_pattern >> NUM_FUEL_GAUGE_LEDS);
++ rotated_pattern &= BIT_MASK_FUEL_GAUGE;
++ /* Now display the rotated pattern on the inner ring */
++ display_inner_ring(get_inner_ring_bits(rotated_pattern));
++ if (++inner_ring_rotate >= NUM_FUEL_GAUGE_LEDS) {
++ inner_ring_rotate = 0;
++ }
++
++ need_to_display_current_fuel_gauge = 1;
++ }
++
++ /* Otherwise not rebuilding so just display normal fuel gauge */
++ else {
++ display_current_fuel_gauge();
++ }
++}
++
++
++/***************************************************************************/
++/* FUNCTION: get_next_state_from_fully_on */
++/* */
++/* PURPOSE: */
++/* Movement to STANDBY or POWER_OFF requires TRANSITION behavior; */
++/* Otherwise just jump to next_state */
++/***************************************************************************/
++static int get_next_state_from_fully_on(void)
++{
++ switch (next_state) {
++ case STANDBY__ENTRY:
++ case POWER_OFF__ENTRY:
++ return TRANS__ENTRY;
++ default:
++ return next_state;
++ }
++}
++
++/***************************************************************************/
++/* FUNCTION: wdc_leds_behavior_init */
++/* */
++/* PURPOSE: */
++/* Initialization for LED behavior main state machine */
++/***************************************************************************/
++void wdc_leds_behavior_init(void)
++{
++ /* State machine variables */
++ state = FULLY_ON__ENTRY;
++ next_state = FULLY_ON__ENTRY;
++ /* Outer ring variables */
++ active_count = 0;
++ count = 0;
++ ignore_activity = 0;
++ active_tail = NUM_ACTIVITY_LEDS - 1;
++ ramp1 = 0;
++ ramp2 = 0;
++ activity_led[0] = 0;
++ activity_led[1] = 0;
++ activity_led[2] = 0;
++ activity_led[3] = 0;
++ /* Inner ring variables */
++ inner_ring_rotate = 0;
++ rebuild_percentage = 0;
++ fuel_gauge_bits = 0;
++ need_to_display_current_fuel_gauge = 1;
++}
++
++/***************************************************************************/
++/* FUNCTION: wdc_leds_behavior */
++/* */
++/* PURPOSE: */
++/* LED behavior main state machine */
++/***************************************************************************/
++void wdc_leds_behavior(unsigned long unused)
++{
++ static u8 been_there_done_that = 0;
++ s8 j, k;
++ switch (state) {
++ case FULLY_ON__ENTRY:
++ case FULLY_ON__RE_ENTRY:
++ inner_ring_rotate = 0;
++ need_to_display_current_fuel_gauge = 1;
++ activity_led[0] = LED100;
++ activity_led[1] = LED100;
++ activity_led[2] = LED100;
++ activity_led[3] = LED100;
++ ramp1 = -STEP_RESOLUTION;
++ ramp2 = -STEP_RESOLUTION;
++ if (state == FULLY_ON__RE_ENTRY) {
++ /* Don't go through the POR hold period for a re-entry */
++ count = 0;
++ state = FULLY_ON__RAMP_UP;
++ break;
++ }
++ count = 0;
++ state = FULLY_ON__POR_RAMP_UP;
++ /* Fall through */
++ case FULLY_ON__POR_RAMP_UP:
++ if (--count > 0)
++ break;
++ count = POWER_SPEED;
++ ++ramp2;
++ if (++ramp1 < 0)
++ break;
++ count = HOLD_ON_ENTER;
++ state = FULLY_ON__POR_HOLD;
++ break;
++ case FULLY_ON__POR_HOLD:
++ display_current_fuel_gauge();
++ if (--count > 0)
++ break;
++ active_count = 0;
++ count = 0;
++ state = FULLY_ON__RAMP_UP;
++ break;
++ case FULLY_ON__RAMP_UP:
++ if (next_state != FULLY_ON__ENTRY) {
++ state = get_next_state_from_fully_on();
++ break;
++ }
++
++ display_current_fuel_gauge();
++ if (--count > 0)
++ break;
++ count = POWER_SPEED;
++ ++ramp2;
++ if (++ramp1 >= 0) {
++ ramp1 = 0;
++ ramp2 = 0;
++ }
++ if (active_count == 0) {
++ activity_led[0] = LED100;
++ activity_led[1] = LED100;
++ activity_led[2] = LED100;
++ activity_led[3] = LED100;
++ break;
++ }
++
++ activity_led[0] = 0;
++ activity_led[1] = 0;
++ activity_led[2] = 0;
++ activity_led[3] = 0;
++ count = 0;
++ ramp1 = 0;
++ ramp2 = 0;
++ state = FULLY_ON__ACTIVITY;
++ /* Fall through */
++ case FULLY_ON__ACTIVITY:
++ if (next_state != FULLY_ON__ENTRY) {
++ state = get_next_state_from_fully_on();
++ break;
++ }
++
++ if (--count > 0)
++ break;
++ count = RW_SPEED;
++ handle_inner_ring();
++ if (active_count) {
++ j = active_tail =
++ ((active_tail >
++ 0) ? (active_tail - 1) : (NUM_ACTIVITY_LEDS - 1)
++ );
++ k = NUM_ACTIVITY_LEDS;
++ while (k--) {
++ activity_led[j] = activity_pattern[k];
++ j = ((j > 0) ? (j - 1) : (NUM_ACTIVITY_LEDS - 1));
++ }
++ ramp1 = 0;
++ ramp2 = 0;
++ }
++ if (active_count == 0) {
++ count = RW_SPEED;
++ state = FULLY_ON__IDLE_HOLD;
++ }
++ active_count = 0;
++ break;
++ case FULLY_ON__IDLE_HOLD:
++ if (--count > 0)
++ break;
++ count = 0;
++ state = FULLY_ON__RAMP_DOWN;
++ break;
++ case FULLY_ON__RAMP_DOWN:
++ if (--count > 0)
++ break;
++ count = POWER_SPEED;
++ --ramp2;
++ if ((--ramp1 <= -STEP_RESOLUTION) || active_count) {
++ display_current_fuel_gauge();
++ ramp1 = -STEP_RESOLUTION;
++ ramp2 = -STEP_RESOLUTION;
++ state = FULLY_ON__RAMP_UP;
++ }
++ break;
++ case STANDBY__ENTRY:
++ activity_led[0] = LED100;
++ activity_led[1] = LED100;
++ activity_led[2] = LED100;
++ activity_led[3] = LED100;
++ ramp1 = -STEP_RESOLUTION;
++ ramp2 = -STEP_RESOLUTION;
++ count = HOLD_BREATH;
++ state = STANDBY__DARK;
++ display_current_fuel_gauge();
++ /* Fall through */
++ case STANDBY__DARK:
++ if (next_state != STANDBY__ENTRY) {
++ state = next_state;
++ break;
++ }
++
++ if (--count > 0)
++ break;
++ state = STANDBY__RAMP_UP;
++ break;
++ case STANDBY__RAMP_UP:
++ ramp2++;
++ ramp1++;
++ if (ramp1 < SLEEP_HI)
++ break;
++ state = STANDBY__RAMP_DOWN;
++ break;
++ case STANDBY__RAMP_DOWN:
++ ramp2--;
++ if (ramp1-- > -STEP_RESOLUTION)
++ break;
++ state = STANDBY__ENTRY;
++ break;
++ case POWER_OFF__ENTRY:
++ display_inner_ring(0x00);
++ activity_led[0] = 0;
++ activity_led[1] = 0;
++ activity_led[2] = 0;
++ activity_led[3] = 0;
++ ramp1 = 0;
++ ramp2 = 0;
++ state = POWER_OFF__DARK;
++ /* Fall through */
++ case POWER_OFF__DARK:
++ if (next_state != POWER_OFF__ENTRY) {
++ state = next_state;
++ break;
++ }
++ break;
++ case DEGRADED__ENTRY:
++ display_inner_ring(get_inner_ring_bits(BIT_MASK_FUEL_GAUGE));
++ ramp1 = 0;
++ ramp2 = 0;
++ activity_led[0] = 0;
++ activity_led[1] = 0;
++ activity_led[2] = 0;
++ activity_led[3] = 0;
++ count = BLINK_SPEED;
++ state = DEGRADED__BLINK1;
++ /* Fall through */
++ case DEGRADED__BLINK1:
++ if (next_state != DEGRADED__ENTRY) {
++ display_inner_ring(0);
++ state = TRANS__ENTRY;
++ break;
++ }
++
++ if (--count > 0)
++ break;
++ display_inner_ring(0);
++ activity_led[0] = LED100;
++ activity_led[1] = LED100;
++ activity_led[2] = LED100;
++ activity_led[3] = LED100;
++ count = BLINK_SPEED;
++ state = DEGRADED__BLINK2;
++ break;
++ case DEGRADED__BLINK2:
++ if (--count > 0)
++ break;
++ state = DEGRADED__ENTRY;
++ break;
++ case OVERTEMP__ENTRY:
++ display_inner_ring(0);
++ ramp1 = 0;
++ ramp2 = 0;
++ activity_led[0] = 0;
++ activity_led[1] = 0;
++ activity_led[2] = 0;
++ activity_led[3] = 0;
++ count = BLINK_SPEED;
++ state = OVERTEMP__BLINK1;
++ /* Fall through */
++ case OVERTEMP__BLINK1:
++ if (next_state != OVERTEMP__ENTRY) {
++ display_inner_ring(0);
++ state = TRANS__ENTRY;
++ break;
++ }
++
++ if (--count > 0)
++ break;
++ display_inner_ring(get_inner_ring_bits(BIT_MASK_FUEL_GAUGE));
++ activity_led[0] = LED100;
++ activity_led[1] = LED100;
++ activity_led[2] = LED100;
++ activity_led[3] = LED100;
++ count = BLINK_SPEED;
++ state = OVERTEMP__BLINK2;
++ break;
++ case OVERTEMP__BLINK2:
++ if (--count > 0)
++ break;
++ state = OVERTEMP__ENTRY;
++ break;
++ case TRANS__ENTRY:
++ activity_led[0] = LED100;
++ activity_led[1] = LED100;
++ activity_led[2] = LED100;
++ activity_led[3] = LED100;
++ ramp1 = SLEEP_LO;
++ ramp2 = SLEEP_HI;
++ state = TRANS__1_UP;
++ /* Fall through */
++ case TRANS__1_UP:
++ case TRANS__2_UP:
++ case TRANS__3_UP:
++ case TRANS__4_UP:
++ ramp2 -= TRANS_STEP;
++ ramp1 += TRANS_STEP;
++ if ((ramp1 - TRANS_STEP) < SLEEP_HI)
++ break;
++ state++;
++ break;
++ case TRANS__4_DN:
++ if (ramp1 <= -STEP_RESOLUTION) {
++ if (next_state == TRANS__ENTRY) {
++ /*
++ * If no one told us where to go then just go to FullyOn, but
++ * don't go through the POR hold period because that makes
++ * the next transition display for the next button press wait
++ * too long.
++ *
++ * Note, that next_state needs to be set to FULLY_ON__ENTRY
++ * because it is used for the test whether or not to leave
++ * the FullyOn state even though we are entering FullyOn
++ * through the re-entry path.
++ */
++ next_state = FULLY_ON__ENTRY;
++ state = FULLY_ON__RE_ENTRY;
++ } else {
++ state = next_state;
++ }
++ break;
++ }
++ ramp2 -= TRANS_STEP;
++ /* Fall through */
++ case TRANS__1_DN:
++ case TRANS__2_DN:
++ case TRANS__3_DN:
++ ramp2 += TRANS_STEP;
++ ramp1 -= TRANS_STEP;
++ if ((ramp1 + TRANS_STEP) > -STEP_RESOLUTION)
++ break;
++ ramp1 = SLEEP_LO;
++ ramp2 = SLEEP_HI;
++ state++;
++ break;
++ default:
++ if (!been_there_done_that) {
++ printk(KERN_ERR "Invalid LED behavior state\n");
++ been_there_done_that = 1;
++ return;
++ }
++ }
++
++ /* Set the activity brightness according to value and ramp */
++ set_led(LED_MASK_ACT12, activity_led[0] + ramp1);
++ set_led(LED_MASK_ACT9, activity_led[1] + ramp2);
++ set_led(LED_MASK_ACT6, activity_led[2] + ramp1);
++ set_led(LED_MASK_ACT3, activity_led[3] + ramp2);
++}
++
++
++/***************************************************************************/
++/* FUNCTION: wdc_leds_set_power */
++/* */
++/* PURPOSE: */
++/* Set the "power" LED to the requested behavior */
++/***************************************************************************/
++static void wdc_leds_set_power
++ (struct led_classdev *led_cdev, enum led_brightness value) {
++ if (value >= 255) {
++ next_state = FULLY_ON__ENTRY;
++ } else if (value > 0) {
++ next_state = STANDBY__ENTRY;
++ } else {
++ next_state = POWER_OFF__ENTRY;
++ }
++}
++
++
++/***************************************************************************/
++/* FUNCTION: wdc_leds_set_activity */
++/* */
++/* PURPOSE: */
++/* Trigger activity display behavior */
++/***************************************************************************/
++static void wdc_leds_set_activity
++ (struct led_classdev *led_cdev, enum led_brightness value) {
++ if (!ignore_activity && (value > 0)) {
++ active_count++;
++ }
++}
++
++
++/***************************************************************************/
++/* FUNCTION: wdc_leds_set_ignore_activity */
++/* */
++/* PURPOSE: */
++/* Set the "ignore activity" setting */
++/***************************************************************************/
++static void wdc_leds_set_ignore_activity
++ (struct led_classdev *led_cdev, enum led_brightness value) {
++ ignore_activity = value;
++}
++
++
++/***************************************************************************/
++/* FUNCTION: wdc_leds_set_transition */
++/* */
++/* PURPOSE: */
++/* Trigger "transition" display behavior */
++/***************************************************************************/
++static void wdc_leds_set_transition
++ (struct led_classdev *led_cdev, enum led_brightness value) {
++ next_state = ((value > 0) ? TRANS__ENTRY : FULLY_ON__ENTRY);
++}
++
++
++/***************************************************************************/
++/* FUNCTION: wdc_leds_set_fuel_gauge */
++/* */
++/* PURPOSE: */
++/* Set the fuel gauge to the requested value (treated as a percentage) */
++/***************************************************************************/
++static void wdc_leds_set_fuel_gauge
++ (struct led_classdev *led_cdev, enum led_brightness value) {
++ fuel_gauge_bits = get_inner_ring_bits(get_percentage_pattern(value));
++ need_to_display_current_fuel_gauge = 1;
++}
++
++
++/***************************************************************************/
++/* FUNCTION: wdc_leds_set_fg_bitmap */
++/* */
++/* PURPOSE: */
++/* Set the fuel gauge to the requested value (treated as a bitmap) */
++/***************************************************************************/
++static void wdc_leds_set_fg_bitmap
++ (struct led_classdev *led_cdev, enum led_brightness value) {
++ fuel_gauge_bits = get_inner_ring_bits((u16) value);
++ need_to_display_current_fuel_gauge = 1;
++}
++
++
++/***************************************************************************/
++/* FUNCTION: wdc_leds_set_rebuilding */
++/* */
++/* PURPOSE: */
++/* Set the rebuilding behavior (value = % complete, 0 = not rebuilding) */
++/***************************************************************************/
++static void wdc_leds_set_rebuilding
++ (struct led_classdev *led_cdev, enum led_brightness value) {
++ rebuild_percentage = value;
++}
++
++
++/***************************************************************************/
++/* FUNCTION: wdc_leds_set_degraded */
++/* */
++/* PURPOSE: */
++/* Set the degraded mode display behavior */
++/***************************************************************************/
++static void wdc_leds_set_degraded
++ (struct led_classdev *led_cdev, enum led_brightness value) {
++ next_state = ((value > 0) ? DEGRADED__ENTRY : FULLY_ON__ENTRY);
++}
++
++
++/***************************************************************************/
++/* FUNCTION: wdc_leds_set_over_temp */
++/* */
++/* PURPOSE: */
++/* Set the over temperature mode display behavior */
++/***************************************************************************/
++static void wdc_leds_set_over_temp
++ (struct led_classdev *led_cdev, enum led_brightness value) {
++ next_state = ((value > 0) ? OVERTEMP__ENTRY : FULLY_ON__ENTRY);
++}
++
++
++/***************************************************************************/
++/* DATA STRUCTURE: wdc_leds_power */
++/* */
++/* PURPOSE: */
++/* Describe the wdc-leds "power" pseudo-LED */
++/***************************************************************************/
++static struct led_classdev wdc_leds_power = {
++ .name = "wdc-leds:power",.brightness_set = wdc_leds_set_power,
++};
++
++/***************************************************************************/
++/* DATA STRUCTURE: wdc_leds_activity */
++/* */
++/* PURPOSE: */
++/* Describe the wdc-leds "activity" pseudo-LED */
++/***************************************************************************/
++static struct led_classdev wdc_leds_activity = {
++ .name = "wdc-leds:activity",.brightness_set =
++ wdc_leds_set_activity,.default_trigger = "sata-disk"
++};
++
++/***************************************************************************/
++/* DATA STRUCTURE: wdc_leds_ignore_activity */
++/* */
++/* PURPOSE: */
++/* Describe the wdc-leds "ignore-activity" pseudo-LED */
++/***************************************************************************/
++static struct led_classdev wdc_leds_ignore_activity = {
++ .name = "wdc-leds:ignore-act",.brightness_set =
++ wdc_leds_set_ignore_activity,
++};
++
++/***************************************************************************/
++/* DATA STRUCTURE: wdc_leds_transition */
++/* */
++/* PURPOSE: */
++/* Describe the wdc-leds "transition" pseudo-LED */
++/***************************************************************************/
++static struct led_classdev wdc_leds_transition = {
++ .name = "wdc-leds:transition",.brightness_set =
++ wdc_leds_set_transition,
++};
++
++/***************************************************************************/
++/* DATA STRUCTURE: wdc_leds_fuel_gauge */
++/* */
++/* PURPOSE: */
++/* Describe the wdc-leds "fuel-gauge" LEDs (brightness = % full) */
++/***************************************************************************/
++static struct led_classdev wdc_leds_fuel_gauge = {
++ .name = "wdc-leds:fuel-gauge",.brightness_set =
++ wdc_leds_set_fuel_gauge,
++};
++
++/***************************************************************************/
++/* DATA STRUCTURE: wdc_leds_fg_bitmap */
++/* */
++/* PURPOSE: */
++/* Describe the wdc-leds "fuel-gauge" LEDs (brightness = bitmap) */
++/***************************************************************************/
++static struct led_classdev wdc_leds_fg_bitmap = {
++ .name = "wdc-leds:fg-bitmap",.brightness_set = wdc_leds_set_fg_bitmap,
++};
++
++/***************************************************************************/
++/* DATA STRUCTURE: wdc_leds_rebuilding */
++/* */
++/* PURPOSE: */
++/* Describe the wdc-leds RAID1 "rebuilding" mode pseudo-LED */
++/* (brightness = % complete) */
++/***************************************************************************/
++static struct led_classdev wdc_leds_rebuilding = {
++ .name = "wdc-leds:rebuilding",.brightness_set =
++ wdc_leds_set_rebuilding,
++};
++
++/***************************************************************************/
++/* DATA STRUCTURE: wdc_leds_degraded */
++/* */
++/* PURPOSE: */
++/* Describe the wdc-leds "degraded" mode pseudo-LED */
++/***************************************************************************/
++static struct led_classdev wdc_leds_degraded = {
++ .name = "wdc-leds:degraded",.brightness_set = wdc_leds_set_degraded,
++};
++
++/***************************************************************************/
++/* DATA STRUCTURE: wdc_leds_over_temp */
++/* */
++/* PURPOSE: */
++/* Describe the wdc-leds "over-temp" pseudo-LED */
++/***************************************************************************/
++static struct led_classdev wdc_leds_over_temp = {
++ .name = "wdc-leds:over-temp",.brightness_set = wdc_leds_set_over_temp,
++};
++
++/***************************************************************************/
++/* DATA STRUCTURE: wdc_leds_classes[] */
++/* */
++/* PURPOSE: */
++/* Array of LED classes to create/destroy */
++/***************************************************************************/
++static struct led_classdev *wdc_led_classes[] = {
++ &wdc_leds_power,
++ &wdc_leds_activity,
++ &wdc_leds_ignore_activity,
++ &wdc_leds_transition,
++ &wdc_leds_fuel_gauge,
++ &wdc_leds_fg_bitmap,
++ &wdc_leds_rebuilding,
++ &wdc_leds_degraded,
++ &wdc_leds_over_temp
++};
++
++#ifdef DEBUG
++static ssize_t show_registers (struct device *dev, struct device_attribute *attr, char *buf)
++{
++ char * out = buf;
++ u32 clock_data = readl(PWM_CLOCK_REGISTER);
++ u32 data_ptr = PWM_CLOCK_REGISTER;
++ u8 no_pwms = (clock_data >> 16);
++ u8 i;
++ /* report hardware status here */
++ out += sprintf(buf,"PWM drive registers\n");
++ out += sprintf(out, "clock register:0x%08x @ 0x%08x\n", clock_data, data_ptr);
++
++ for (i = 0; i < no_pwms; ++i)
++ {
++ data_ptr=(u32)((u32 *)PWM_BASE+i);
++ out+= sprintf(out,"%d:%d @ 0x%08x\n", i, (u8)readl(data_ptr),data_ptr);
++ }
++
++ return out - buf;
++}
++
++/* create a register 'file' to enbale reading back the pwm drive register status */
++static DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
++
++static int create_debug_files(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ return device_create_file(dev, &dev_attr_registers);
++}
++
++static void remove_debug_files(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ device_remove_file(dev, &dev_attr_registers);
++}
++#endif
++
++
++#ifdef CONFIG_PM
++/***************************************************************************/
++/* FUNCTION: wdc_leds_suspend */
++/* */
++/* PURPOSE: */
++/* Suspend all LED class devices created by this driver */
++/***************************************************************************/
++static int wdc_leds_suspend(struct platform_device *pdev,
++ pm_message_t state)
++{
++ int n = leds_created;
++ while (n > 0) {
++ if (--n < ARRAY_SIZE(wdc_led_classes)) {
++ led_classdev_suspend(wdc_led_classes[n]);
++ }
++ }
++
++return 0}
++
++/***************************************************************************/
++/* FUNCTION: wdc_leds_resume */
++/* */
++/* PURPOSE: */
++/* Wake up all LED class devices created by this driver */
++/***************************************************************************/
++static int wdc_leds_resume(struct platform_device *pdev,
++ pm_message_t state)
++{
++ int n = leds_created;
++ while (n > 0) {
++ if (--n < ARRAY_SIZE(wdc_led_classes)) {
++ led_classdev_resume(wdc_led_classes[n]);
++ }
++ }
++
++return 0}
++#endif /* CONFIG_PM */
++
++/***************************************************************************/
++/* FUNCTION: wdc_leds_probe */
++/* */
++/* PURPOSE: */
++/* Perform any necessary probing and initial setup for wdc-leds device */
++/***************************************************************************/
++static int wdc_leds_probe(struct platform_device *pdev)
++{
++ int rc;
++ int timer_changed = 0;
++ int interrupt_allocated = 0;
++ leds_created = 0;
++ do {
++ /* Enable LED output drivers and disable other uses */
++ CLEAR(SYS_CTRL_GPIO_PRIMSEL_CTRL_0, LED_MASK_GPIO_A);
++ CLEAR(SYS_CTRL_GPIO_SECSEL_CTRL_0, LED_MASK_GPIO_A);
++ CLEAR(SYS_CTRL_GPIO_TERTSEL_CTRL_0, LED_MASK_GPIO_A);
++
++ CLEAR(SYS_CTRL_GPIO_PRIMSEL_CTRL_1, LED_MASK_GPIO_B);
++ CLEAR(SYS_CTRL_GPIO_SECSEL_CTRL_1, LED_MASK_GPIO_B);
++ CLEAR(SYS_CTRL_GPIO_TERTSEL_CTRL_1, LED_MASK_GPIO_B);
++ /* Turn off all the LEDs */
++ if (negative_led_logic) {
++ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_SET);
++ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_SET);
++ } else {
++ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_CLEAR);
++ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_CLEAR);
++ }
++
++ /* bring PWM module out of reset and enable clock */
++ writel((1<<SYS_CTRL_RSTEN_MISC_BIT), SYS_CTRL_RSTEN_CLR_CTRL);
++ //writel(PWM_CLOCK, SYS_CTRL_CKEN_SET_CTRL);
++
++ /* enable PWM clock */
++ writel(PWM_PRESCALE, PWM_CLOCK_REGISTER);
++
++ /* Initialize frame buffer to everything off */
++ set_led(LED_MASK_FUEL_GAUGE | LED_MASK_ACTIVITY, 0);
++ /* Enable output to the LEDs */
++ writel(LED_MASK_GPIO_A, SYS_CTRL_GPIO_PWMSEL_CTRL_0);
++ writel(LED_MASK_GPIO_B, SYS_CTRL_GPIO_PWMSEL_CTRL_1);
++ /* Initialize the LED behavior state machine */
++ wdc_leds_behavior_init();
++ /* Save Timer2 state for restoring later */
++ timer_load = ox_readl(TIMER2_LOAD);
++ timer_control = ox_readl(TIMER2_CONTROL);
++ ox_writel(0, TIMER2_CONTROL);
++ timer_changed = 1;
++ /* Setup Timer2 for LED control */
++ rc = request_irq
++ (TIMER_2_INTERRUPT,
++ wdc_leds_interrupt, 0, "led_pwm", 0);
++ if (rc < 0) {
++ printk(KERN_ERR "failed to get IRQ\n");
++ break;
++ }
++
++ interrupt_allocated = 1;
++ ox_writel(FAST_TIMER_INT, TIMER2_LOAD);
++ ox_writel(PERIODIC_INTERRUPT, TIMER2_CONTROL);
++ /* Register each LED class device */
++ while (leds_created < ARRAY_SIZE(wdc_led_classes)) {
++ rc = led_classdev_register(&pdev->dev,
++ wdc_led_classes[leds_created]);
++ if (rc < 0) {
++ printk(KERN_ERR "failed to register led class \"%s\"\n",
++ wdc_led_classes[leds_created]->name);
++ break;
++ }
++
++ ++leds_created;
++ }
++ }
++ while (0);
++ /* If we failed then perform any needed clean up */
++ if (rc < 0) {
++ /* Unregister any classes we registered */
++ while (leds_created > 0) {
++ if (--leds_created < ARRAY_SIZE(wdc_led_classes)) {
++ led_classdev_unregister(wdc_led_classes[leds_created]);
++ }
++ }
++
++ /* Free the interrupt if we allocated one */
++ if (interrupt_allocated) {
++ free_irq(TIMER_2_INTERRUPT, 0);
++ }
++
++ /* Restore Timer2 if we changed it */
++ if (timer_changed) {
++ ox_writel(timer_load, TIMER2_LOAD);
++ ox_writel(timer_control, TIMER2_CONTROL);
++ }
++ }
++#ifdef DEBUG
++ create_debug_files(pdev);
++#endif
++ return rc;
++}
++
++
++/***************************************************************************/
++/* FUNCTION: wdc_leds_remove */
++/* */
++/* PURPOSE: */
++/* Perform steps to remove the wdc-leds device */
++/***************************************************************************/
++static int wdc_leds_remove(struct platform_device *pdev)
++{
++ while (leds_created > 0) {
++ if (--leds_created < ARRAY_SIZE(wdc_led_classes)) {
++ led_classdev_unregister(wdc_led_classes[leds_created]);
++ }
++ }
++
++ ox_writel(0, TIMER2_CONTROL);
++ free_irq(TIMER_2_INTERRUPT, 0);
++ ox_writel(timer_load, TIMER2_LOAD);
++ ox_writel(timer_control, TIMER2_CONTROL);
++ /* Turn off all the LEDs */
++ if (negative_led_logic) {
++ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_SET);
++ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_SET);
++ } else {
++ writel(LED_MASK_GPIO_A, GPIO_A_OUTPUT_CLEAR);
++ writel(LED_MASK_GPIO_B, GPIO_B_OUTPUT_CLEAR);
++ }
++ /* put PWM module back into reset and disable clock */
++ writel((1<<SYS_CTRL_RSTEN_MISC_BIT), SYS_CTRL_RSTEN_SET_CTRL);
++ // writel(PWM_CLOCK, SYS_CTRL_CKEN_CLR_CTRL);
++#ifdef DEBUG
++ remove_debug_files(pdev);
++#endif
++ return 0;
++}
++
++
++/***************************************************************************/
++/* DATA STRUCTURE: wdc_leds_driver */
++/* */
++/* PURPOSE: */
++/* Describe the wdc-leds platform device driver */
++/***************************************************************************/
++static struct platform_driver wdc_leds_driver = {
++ .probe = wdc_leds_probe,.remove = wdc_leds_remove,
++#ifdef CONFIG_PM
++ .suspend = wdc_leds_suspend,.resume = wdc_leds_resume,
++#endif /* CONFIG_PM */
++ .driver = {
++ .name = "wdc-leds",},
++};
++
++/* Pointer to device returned by platform_device_register_simple */
++static struct platform_device *wdc_leds;
++/***************************************************************************/
++/* FUNCTION: wdc_leds_init */
++/* */
++/* PURPOSE: */
++/* Perform module initialization */
++/***************************************************************************/
++static int __init wdc_leds_init(void)
++{
++ int ret;
++ printk
++ (KERN_INFO "wdc-leds: SLOW_TPS=%d\n",
++ SLOW_TPS);
++ ret = platform_driver_register(&wdc_leds_driver);
++ if (!ret) {
++ wdc_leds =
++ platform_device_register_simple("wdc-leds", -1, NULL, 0);
++ }
++
++ return ret;
++}
++
++
++/***************************************************************************/
++/* FUNCTION: wdc_leds_exit */
++/* */
++/* PURPOSE: */
++/* Perform module unloading and cleanup */
++/***************************************************************************/
++static void __exit wdc_leds_exit(void)
++{
++ if (wdc_leds) {
++ platform_device_unregister(wdc_leds);
++ }
++ platform_driver_unregister(&wdc_leds_driver);
++}
++
++
++module_init(wdc_leds_init);
++module_exit(wdc_leds_exit);
++MODULE_AUTHOR("Michael Webster");
++MODULE_DESCRIPTION("WDC 2NC LEDs");
++MODULE_LICENSE("GPL");
++/******************************* End of File *********************************/
+diff -Nurd linux-2.6.24/arch/arm/mach-oxnas/wdc-ledtrig-sata.c linux-2.6.24-oxe810/arch/arm/mach-oxnas/wdc-ledtrig-sata.c
+--- linux-2.6.24/arch/arm/mach-oxnas/wdc-ledtrig-sata.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-oxnas/wdc-ledtrig-sata.c 2008-06-11 17:47:55.000000000 +0200
+@@ -0,0 +1,78 @@
++/*
++ * linux/arch/arm/mach-oxnas/wdc-ledtrig-sata.c
++ *
++ * Copyright (C) 2006 Western Digital
++ *
++ * 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 <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/leds.h>
++
++
++DEFINE_LED_TRIGGER(wdc_ledtrig_sata);
++
++
++/***************************************************************************/
++/* FUNCTION: wdc_ledtrig_sata_activity */
++/* */
++/* PURPOSE: */
++/* Entry point to trip the trigger (called from within SATA driver) */
++/***************************************************************************/
++void wdc_ledtrig_sata_activity(void)
++{
++ led_trigger_event(wdc_ledtrig_sata, LED_FULL);
++}
++EXPORT_SYMBOL(wdc_ledtrig_sata_activity);
++
++
++/***************************************************************************/
++/* FUNCTION: wdc_ledtrig_sata_init */
++/* */
++/* PURPOSE: */
++/* Perform module initialization */
++/***************************************************************************/
++static int __init wdc_ledtrig_sata_init(void)
++{
++ printk("<1>Hello, LED trigger\n");
++
++ led_trigger_register_simple("sata-disk", &wdc_ledtrig_sata);
++ return 0;
++}
++
++
++/***************************************************************************/
++/* FUNCTION: wdc_ledtrig_sata_exit */
++/* */
++/* PURPOSE: */
++/* Perform module unloading and cleanup */
++/***************************************************************************/
++static void __exit wdc_ledtrig_sata_exit(void)
++{
++ led_trigger_unregister_simple(wdc_ledtrig_sata);
++
++ printk("<1>Goodbye LED trigger\n");
++}
++
++
++module_init(wdc_ledtrig_sata_init);
++module_exit(wdc_ledtrig_sata_exit);
++
++MODULE_AUTHOR("Michael Webster");
++MODULE_DESCRIPTION("WDC 2NC LED trigger");
++MODULE_LICENSE("GPL");
++
++/******************************* End of File *********************************/
+diff -Nurd linux-2.6.24/arch/arm/mach-pxa/clock.c linux-2.6.24-oxe810/arch/arm/mach-pxa/clock.c
+--- linux-2.6.24/arch/arm/mach-pxa/clock.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mach-pxa/clock.c 2008-06-11 17:47:55.000000000 +0200
+@@ -23,18 +23,27 @@
+ static DEFINE_MUTEX(clocks_mutex);
+ static DEFINE_SPINLOCK(clocks_lock);
+
++static struct clk *clk_lookup(struct device *dev, const char *id)
++{
++ struct clk *p;
++
++ list_for_each_entry(p, &clocks, node)
++ if (strcmp(id, p->name) == 0 && p->dev == dev)
++ return p;
++
++ return NULL;
++}
++
+ struct clk *clk_get(struct device *dev, const char *id)
+ {
+ struct clk *p, *clk = ERR_PTR(-ENOENT);
+
+ mutex_lock(&clocks_mutex);
+- list_for_each_entry(p, &clocks, node) {
+- if (strcmp(id, p->name) == 0 &&
+- (p->dev == NULL || p->dev == dev)) {
+- clk = p;
+- break;
+- }
+- }
++ p = clk_lookup(dev, id);
++ if (!p)
++ p = clk_lookup(NULL, id);
++ if (p)
++ clk = p;
+ mutex_unlock(&clocks_mutex);
+
+ return clk;
+diff -Nurd linux-2.6.24/arch/arm/mm/Kconfig linux-2.6.24-oxe810/arch/arm/mm/Kconfig
+--- linux-2.6.24/arch/arm/mm/Kconfig 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mm/Kconfig 2008-06-11 17:47:57.000000000 +0200
+@@ -171,8 +171,8 @@
+ # ARM926T
+ config CPU_ARM926T
+ bool "Support ARM926T processor"
+- depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI
+- default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI
++ depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI || ARCH_OXNAS
++ default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_NS9XXX || ARCH_DAVINCI || ARCH_OXNAS
+ select CPU_32v5
+ select CPU_ABRT_EV5TJ
+ select CPU_CACHE_VIVT
+diff -Nurd linux-2.6.24/arch/arm/mm/init.c linux-2.6.24-oxe810/arch/arm/mm/init.c
+--- linux-2.6.24/arch/arm/mm/init.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mm/init.c 2008-06-11 17:47:57.000000000 +0200
+@@ -173,9 +173,19 @@
+ #ifdef CONFIG_MMU
+ struct map_desc map;
+
++#ifdef CONFIG_OXNAS_MAP_SRAM
++ /*
++ * Assume only a single bank and stop the overwrite of the first section
++ * descriptor
++ */
++ map.pfn = __phys_to_pfn(bank->start + 1024*1024);
++ map.virtual = __phys_to_virt(bank->start) + 1024*1024;
++ map.length = bank->size - 1024*1024;
++#else // CONFIG_OXNAS_MAP_SRAM
+ map.pfn = __phys_to_pfn(bank->start);
+ map.virtual = __phys_to_virt(bank->start);
+ map.length = bank->size;
++#endif // CONFIG_OXNAS_MAP_SRAM
+ map.type = MT_MEMORY;
+
+ create_mapping(&map);
+diff -Nurd linux-2.6.24/arch/arm/mm/mmu.c linux-2.6.24-oxe810/arch/arm/mm/mmu.c
+--- linux-2.6.24/arch/arm/mm/mmu.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mm/mmu.c 2008-06-11 17:47:57.000000000 +0200
+@@ -617,6 +617,15 @@
+ reserve_bootmem_node(pgdat, __pa(swapper_pg_dir),
+ PTRS_PER_PGD * sizeof(pgd_t));
+
++#ifdef CONFIG_OXNAS_MAP_SRAM
++ /*
++ * Reserve the page table describing the first MB of address space in 4KB
++ * pages so we can map SRAM over part of it. This didn't work for some reason
++ * so instead reserve first 0x4000 as some other archs do
++ */
++ res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
++#endif // CONFIG_OXNAS_MAP_SRAM
++
+ /*
+ * Hmm... This should go elsewhere, but we really really need to
+ * stop things allocating the low memory; ideally we need a better
+diff -Nurd linux-2.6.24/arch/arm/mm/proc-arm926.S linux-2.6.24-oxe810/arch/arm/mm/proc-arm926.S
+--- linux-2.6.24/arch/arm/mm/proc-arm926.S 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/arm/mm/proc-arm926.S 2008-06-11 17:47:57.000000000 +0200
+@@ -245,6 +245,7 @@
+ *
+ * (same as v4wb)
+ */
++.section ".text.arm926_dma_clean_range"
+ ENTRY(arm926_dma_inv_range)
+ #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+ tst r0, #CACHE_DLINESIZE - 1
+@@ -259,6 +260,7 @@
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
++.section ".text.other"
+
+ /*
+ * dma_clean_range(start, end)
+@@ -270,6 +272,7 @@
+ *
+ * (same as v4wb)
+ */
++.section ".text.arm926_dma_clean_range"
+ ENTRY(arm926_dma_clean_range)
+ #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+ bic r0, r0, #CACHE_DLINESIZE - 1
+@@ -280,6 +283,7 @@
+ #endif
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
++.section ".text.other"
+
+ /*
+ * dma_flush_range(start, end)
+@@ -289,6 +293,7 @@
+ * - start - virtual start address
+ * - end - virtual end address
+ */
++.section ".text.arm926_dma_flush_range"
+ ENTRY(arm926_dma_flush_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+ 1:
+@@ -302,6 +307,7 @@
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
++.section ".text.other"
+
+ ENTRY(arm926_cache_fns)
+ .long arm926_flush_kern_cache_all
+diff -Nurd linux-2.6.24/arch/mips/kernel/i8259.c linux-2.6.24-oxe810/arch/mips/kernel/i8259.c
+--- linux-2.6.24/arch/mips/kernel/i8259.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/mips/kernel/i8259.c 2008-06-11 17:48:37.000000000 +0200
+@@ -338,8 +338,10 @@
+
+ init_8259A(0);
+
+- for (i = I8259A_IRQ_BASE; i < I8259A_IRQ_BASE + 16; i++)
++ for (i = I8259A_IRQ_BASE; i < I8259A_IRQ_BASE + 16; i++) {
+ set_irq_chip_and_handler(i, &i8259A_chip, handle_level_irq);
++ set_irq_probe(i);
++ }
+
+ setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2);
+ }
+diff -Nurd linux-2.6.24/arch/mips/kernel/irq.c linux-2.6.24-oxe810/arch/mips/kernel/irq.c
+--- linux-2.6.24/arch/mips/kernel/irq.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/mips/kernel/irq.c 2008-06-11 17:48:37.000000000 +0200
+@@ -145,6 +145,11 @@
+
+ void __init init_IRQ(void)
+ {
++ int i;
++
++ for (i = 0; i < NR_IRQS; i++)
++ set_irq_noprobe(i);
++
+ arch_init_irq();
+
+ #ifdef CONFIG_KGDB
+diff -Nurd linux-2.6.24/arch/powerpc/platforms/chrp/pci.c linux-2.6.24-oxe810/arch/powerpc/platforms/chrp/pci.c
+--- linux-2.6.24/arch/powerpc/platforms/chrp/pci.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/powerpc/platforms/chrp/pci.c 2008-06-11 17:47:35.000000000 +0200
+@@ -354,7 +354,7 @@
+ * mode as well. The same fixup must be done to the class-code property in
+ * the IDE node /pci@80000000/ide@C,1
+ */
+-static void __devinit chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide)
++static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide)
+ {
+ u8 progif;
+ struct pci_dev *viaisa;
+@@ -375,4 +375,4 @@
+
+ pci_dev_put(viaisa);
+ }
+-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata);
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata);
+diff -Nurd linux-2.6.24/arch/powerpc/platforms/powermac/feature.c linux-2.6.24-oxe810/arch/powerpc/platforms/powermac/feature.c
+--- linux-2.6.24/arch/powerpc/platforms/powermac/feature.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/powerpc/platforms/powermac/feature.c 2008-06-11 17:47:38.000000000 +0200
+@@ -2565,6 +2565,8 @@
+
+ /* Locate core99 Uni-N */
+ uninorth_node = of_find_node_by_name(NULL, "uni-n");
++ uninorth_maj = 1;
++
+ /* Locate G5 u3 */
+ if (uninorth_node == NULL) {
+ uninorth_node = of_find_node_by_name(NULL, "u3");
+@@ -2575,8 +2577,10 @@
+ uninorth_node = of_find_node_by_name(NULL, "u4");
+ uninorth_maj = 4;
+ }
+- if (uninorth_node == NULL)
++ if (uninorth_node == NULL) {
++ uninorth_maj = 0;
+ return;
++ }
+
+ addrp = of_get_property(uninorth_node, "reg", NULL);
+ if (addrp == NULL)
+@@ -3029,3 +3033,8 @@
+ pmac_agp_resume(pmac_agp_bridge);
+ }
+ EXPORT_SYMBOL(pmac_resume_agp_for_card);
++
++int pmac_get_uninorth_variant(void)
++{
++ return uninorth_maj;
++}
+diff -Nurd linux-2.6.24/arch/s390/lib/uaccess_pt.c linux-2.6.24-oxe810/arch/s390/lib/uaccess_pt.c
+--- linux-2.6.24/arch/s390/lib/uaccess_pt.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/s390/lib/uaccess_pt.c 2008-06-11 17:48:25.000000000 +0200
+@@ -406,6 +406,8 @@
+ {
+ int ret;
+
++ if (!current->mm)
++ return -EFAULT;
+ spin_lock(¤t->mm->page_table_lock);
+ uaddr = (int __user *) __dat_user_addr((unsigned long) uaddr);
+ if (!uaddr) {
+diff -Nurd linux-2.6.24/arch/s390/lib/uaccess_std.c linux-2.6.24-oxe810/arch/s390/lib/uaccess_std.c
+--- linux-2.6.24/arch/s390/lib/uaccess_std.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/s390/lib/uaccess_std.c 2008-06-11 17:48:25.000000000 +0200
+@@ -293,10 +293,10 @@
+
+ asm volatile(
+ " sacf 256\n"
+- " cs %1,%4,0(%5)\n"
+- "0: lr %0,%1\n"
+- "1: sacf 0\n"
+- EX_TABLE(0b,1b)
++ "0: cs %1,%4,0(%5)\n"
++ "1: lr %0,%1\n"
++ "2: sacf 0\n"
++ EX_TABLE(0b,2b) EX_TABLE(1b,2b)
+ : "=d" (ret), "+d" (oldval), "=m" (*uaddr)
+ : "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr)
+ : "cc", "memory" );
+diff -Nurd linux-2.6.24/arch/sparc/kernel/Makefile linux-2.6.24-oxe810/arch/sparc/kernel/Makefile
+--- linux-2.6.24/arch/sparc/kernel/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/sparc/kernel/Makefile 2008-06-11 17:48:46.000000000 +0200
+@@ -1,4 +1,4 @@
+-# $Id: Makefile,v 1.62 2000/12/15 00:41:17 davem Exp $
++#
+ # Makefile for the linux kernel.
+ #
+
+@@ -12,7 +12,8 @@
+ sys_sparc.o sunos_asm.o systbls.o \
+ time.o windows.o cpu.o devices.o sclow.o \
+ tadpole.o tick14.o ptrace.o sys_solaris.o \
+- unaligned.o muldiv.o semaphore.o prom.o of_device.o devres.o
++ unaligned.o una_asm.o muldiv.o semaphore.o \
++ prom.o of_device.o devres.o
+
+ devres-y = ../../../kernel/irq/devres.o
+
+diff -Nurd linux-2.6.24/arch/sparc/kernel/una_asm.S linux-2.6.24-oxe810/arch/sparc/kernel/una_asm.S
+--- linux-2.6.24/arch/sparc/kernel/una_asm.S 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/arch/sparc/kernel/una_asm.S 2008-06-11 17:48:46.000000000 +0200
+@@ -0,0 +1,153 @@
++/* una_asm.S: Kernel unaligned trap assembler helpers.
++ *
++ * Copyright (C) 1996,2005,2008 David S. Miller (davem@davemloft.net)
++ * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
++ */
++
++#include <linux/errno.h>
++
++ .text
++
++retl_efault:
++ retl
++ mov -EFAULT, %o0
++
++ /* int __do_int_store(unsigned long *dst_addr, int size,
++ * unsigned long *src_val)
++ *
++ * %o0 = dest_addr
++ * %o1 = size
++ * %o2 = src_val
++ *
++ * Return '0' on success, -EFAULT on failure.
++ */
++ .globl __do_int_store
++__do_int_store:
++ ld [%o2], %g1
++ cmp %1, 2
++ be 2f
++ cmp %1, 4
++ be 1f
++ srl %g1, 24, %g2
++ srl %g1, 16, %g7
++4: stb %g2, [%o0]
++ srl %g1, 8, %g2
++5: stb %g7, [%o0 + 1]
++ ld [%o2 + 4], %g7
++6: stb %g2, [%o0 + 2]
++ srl %g7, 24, %g2
++7: stb %g1, [%o0 + 3]
++ srl %g7, 16, %g1
++8: stb %g2, [%o0 + 4]
++ srl %g7, 8, %g2
++9: stb %g1, [%o0 + 5]
++10: stb %g2, [%o0 + 6]
++ b 0f
++11: stb %g7, [%o0 + 7]
++1: srl %g1, 16, %g7
++12: stb %g2, [%o0]
++ srl %g1, 8, %g2
++13: stb %g7, [%o0 + 1]
++14: stb %g2, [%o0 + 2]
++ b 0f
++15: stb %g1, [%o0 + 3]
++2: srl %g1, 8, %g2
++16: stb %g2, [%o0]
++17: stb %g1, [%o0 + 1]
++0: retl
++ mov 0, %o0
++
++ .section __ex_table,#alloc
++ .word 4b, retl_efault
++ .word 5b, retl_efault
++ .word 6b, retl_efault
++ .word 7b, retl_efault
++ .word 8b, retl_efault
++ .word 9b, retl_efault
++ .word 10b, retl_efault
++ .word 11b, retl_efault
++ .word 12b, retl_efault
++ .word 13b, retl_efault
++ .word 14b, retl_efault
++ .word 15b, retl_efault
++ .word 16b, retl_efault
++ .word 17b, retl_efault
++ .previous
++
++ /* int do_int_load(unsigned long *dest_reg, int size,
++ * unsigned long *saddr, int is_signed)
++ *
++ * %o0 = dest_reg
++ * %o1 = size
++ * %o2 = saddr
++ * %o3 = is_signed
++ *
++ * Return '0' on success, -EFAULT on failure.
++ */
++ .globl do_int_load
++do_int_load:
++ cmp %o1, 8
++ be 9f
++ cmp %o1, 4
++ be 6f
++4: ldub [%o2], %g1
++5: ldub [%o2 + 1], %g2
++ sll %g1, 8, %g1
++ tst %o3
++ be 3f
++ or %g1, %g2, %g1
++ sll %g1, 16, %g1
++ sra %g1, 16, %g1
++3: b 0f
++ st %g1, [%o0]
++6: ldub [%o2 + 1], %g2
++ sll %g1, 24, %g1
++7: ldub [%o2 + 2], %g7
++ sll %g2, 16, %g2
++8: ldub [%o2 + 3], %g3
++ sll %g7, 8, %g7
++ or %g3, %g2, %g3
++ or %g7, %g3, %g7
++ or %g1, %g7, %g1
++ b 0f
++ st %g1, [%o0]
++9: ldub [%o2], %g1
++10: ldub [%o2 + 1], %g2
++ sll %g1, 24, %g1
++11: ldub [%o2 + 2], %g7
++ sll %g2, 16, %g2
++12: ldub [%o2 + 3], %g3
++ sll %g7, 8, %g7
++ or %g1, %g2, %g1
++ or %g7, %g3, %g7
++ or %g1, %g7, %g7
++13: ldub [%o2 + 4], %g1
++ st %g7, [%o0]
++14: ldub [%o2 + 5], %g2
++ sll %g1, 24, %g1
++15: ldub [%o2 + 6], %g7
++ sll %g2, 16, %g2
++16: ldub [%o2 + 7], %g3
++ sll %g7, 8, %g7
++ or %g1, %g2, %g1
++ or %g7, %g3, %g7
++ or %g1, %g7, %g7
++ st %g7, [%o0 + 4]
++0: retl
++ mov 0, %o0
++
++ .section __ex_table,#alloc
++ .word 4b, retl_efault
++ .word 5b, retl_efault
++ .word 6b, retl_efault
++ .word 7b, retl_efault
++ .word 8b, retl_efault
++ .word 9b, retl_efault
++ .word 10b, retl_efault
++ .word 11b, retl_efault
++ .word 12b, retl_efault
++ .word 13b, retl_efault
++ .word 14b, retl_efault
++ .word 15b, retl_efault
++ .word 16b, retl_efault
++ .previous
+diff -Nurd linux-2.6.24/arch/sparc/kernel/unaligned.c linux-2.6.24-oxe810/arch/sparc/kernel/unaligned.c
+--- linux-2.6.24/arch/sparc/kernel/unaligned.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/sparc/kernel/unaligned.c 2008-06-11 17:48:46.000000000 +0200
+@@ -175,157 +175,31 @@
+ panic(str);
+ }
+
+-#define do_integer_load(dest_reg, size, saddr, is_signed, errh) ({ \
+-__asm__ __volatile__ ( \
+- "cmp %1, 8\n\t" \
+- "be 9f\n\t" \
+- " cmp %1, 4\n\t" \
+- "be 6f\n" \
+-"4:\t" " ldub [%2], %%l1\n" \
+-"5:\t" "ldub [%2 + 1], %%l2\n\t" \
+- "sll %%l1, 8, %%l1\n\t" \
+- "tst %3\n\t" \
+- "be 3f\n\t" \
+- " add %%l1, %%l2, %%l1\n\t" \
+- "sll %%l1, 16, %%l1\n\t" \
+- "sra %%l1, 16, %%l1\n" \
+-"3:\t" "b 0f\n\t" \
+- " st %%l1, [%0]\n" \
+-"6:\t" "ldub [%2 + 1], %%l2\n\t" \
+- "sll %%l1, 24, %%l1\n" \
+-"7:\t" "ldub [%2 + 2], %%g7\n\t" \
+- "sll %%l2, 16, %%l2\n" \
+-"8:\t" "ldub [%2 + 3], %%g1\n\t" \
+- "sll %%g7, 8, %%g7\n\t" \
+- "or %%l1, %%l2, %%l1\n\t" \
+- "or %%g7, %%g1, %%g7\n\t" \
+- "or %%l1, %%g7, %%l1\n\t" \
+- "b 0f\n\t" \
+- " st %%l1, [%0]\n" \
+-"9:\t" "ldub [%2], %%l1\n" \
+-"10:\t" "ldub [%2 + 1], %%l2\n\t" \
+- "sll %%l1, 24, %%l1\n" \
+-"11:\t" "ldub [%2 + 2], %%g7\n\t" \
+- "sll %%l2, 16, %%l2\n" \
+-"12:\t" "ldub [%2 + 3], %%g1\n\t" \
+- "sll %%g7, 8, %%g7\n\t" \
+- "or %%l1, %%l2, %%l1\n\t" \
+- "or %%g7, %%g1, %%g7\n\t" \
+- "or %%l1, %%g7, %%g7\n" \
+-"13:\t" "ldub [%2 + 4], %%l1\n\t" \
+- "st %%g7, [%0]\n" \
+-"14:\t" "ldub [%2 + 5], %%l2\n\t" \
+- "sll %%l1, 24, %%l1\n" \
+-"15:\t" "ldub [%2 + 6], %%g7\n\t" \
+- "sll %%l2, 16, %%l2\n" \
+-"16:\t" "ldub [%2 + 7], %%g1\n\t" \
+- "sll %%g7, 8, %%g7\n\t" \
+- "or %%l1, %%l2, %%l1\n\t" \
+- "or %%g7, %%g1, %%g7\n\t" \
+- "or %%l1, %%g7, %%g7\n\t" \
+- "st %%g7, [%0 + 4]\n" \
+-"0:\n\n\t" \
+- ".section __ex_table,#alloc\n\t" \
+- ".word 4b, " #errh "\n\t" \
+- ".word 5b, " #errh "\n\t" \
+- ".word 6b, " #errh "\n\t" \
+- ".word 7b, " #errh "\n\t" \
+- ".word 8b, " #errh "\n\t" \
+- ".word 9b, " #errh "\n\t" \
+- ".word 10b, " #errh "\n\t" \
+- ".word 11b, " #errh "\n\t" \
+- ".word 12b, " #errh "\n\t" \
+- ".word 13b, " #errh "\n\t" \
+- ".word 14b, " #errh "\n\t" \
+- ".word 15b, " #errh "\n\t" \
+- ".word 16b, " #errh "\n\n\t" \
+- ".previous\n\t" \
+- : : "r" (dest_reg), "r" (size), "r" (saddr), "r" (is_signed) \
+- : "l1", "l2", "g7", "g1", "cc"); \
+-})
+-
+-#define store_common(dst_addr, size, src_val, errh) ({ \
+-__asm__ __volatile__ ( \
+- "ld [%2], %%l1\n" \
+- "cmp %1, 2\n\t" \
+- "be 2f\n\t" \
+- " cmp %1, 4\n\t" \
+- "be 1f\n\t" \
+- " srl %%l1, 24, %%l2\n\t" \
+- "srl %%l1, 16, %%g7\n" \
+-"4:\t" "stb %%l2, [%0]\n\t" \
+- "srl %%l1, 8, %%l2\n" \
+-"5:\t" "stb %%g7, [%0 + 1]\n\t" \
+- "ld [%2 + 4], %%g7\n" \
+-"6:\t" "stb %%l2, [%0 + 2]\n\t" \
+- "srl %%g7, 24, %%l2\n" \
+-"7:\t" "stb %%l1, [%0 + 3]\n\t" \
+- "srl %%g7, 16, %%l1\n" \
+-"8:\t" "stb %%l2, [%0 + 4]\n\t" \
+- "srl %%g7, 8, %%l2\n" \
+-"9:\t" "stb %%l1, [%0 + 5]\n" \
+-"10:\t" "stb %%l2, [%0 + 6]\n\t" \
+- "b 0f\n" \
+-"11:\t" " stb %%g7, [%0 + 7]\n" \
+-"1:\t" "srl %%l1, 16, %%g7\n" \
+-"12:\t" "stb %%l2, [%0]\n\t" \
+- "srl %%l1, 8, %%l2\n" \
+-"13:\t" "stb %%g7, [%0 + 1]\n" \
+-"14:\t" "stb %%l2, [%0 + 2]\n\t" \
+- "b 0f\n" \
+-"15:\t" " stb %%l1, [%0 + 3]\n" \
+-"2:\t" "srl %%l1, 8, %%l2\n" \
+-"16:\t" "stb %%l2, [%0]\n" \
+-"17:\t" "stb %%l1, [%0 + 1]\n" \
+-"0:\n\n\t" \
+- ".section __ex_table,#alloc\n\t" \
+- ".word 4b, " #errh "\n\t" \
+- ".word 5b, " #errh "\n\t" \
+- ".word 6b, " #errh "\n\t" \
+- ".word 7b, " #errh "\n\t" \
+- ".word 8b, " #errh "\n\t" \
+- ".word 9b, " #errh "\n\t" \
+- ".word 10b, " #errh "\n\t" \
+- ".word 11b, " #errh "\n\t" \
+- ".word 12b, " #errh "\n\t" \
+- ".word 13b, " #errh "\n\t" \
+- ".word 14b, " #errh "\n\t" \
+- ".word 15b, " #errh "\n\t" \
+- ".word 16b, " #errh "\n\t" \
+- ".word 17b, " #errh "\n\n\t" \
+- ".previous\n\t" \
+- : : "r" (dst_addr), "r" (size), "r" (src_val) \
+- : "l1", "l2", "g7", "g1", "cc"); \
+-})
++/* una_asm.S */
++extern int do_int_load(unsigned long *dest_reg, int size,
++ unsigned long *saddr, int is_signed);
++extern int __do_int_store(unsigned long *dst_addr, int size,
++ unsigned long *src_val);
+
+-#define do_integer_store(reg_num, size, dst_addr, regs, errh) ({ \
+- unsigned long *src_val; \
+- static unsigned long zero[2] = { 0, }; \
+- \
+- if (reg_num) src_val = fetch_reg_addr(reg_num, regs); \
+- else { \
+- src_val = &zero[0]; \
+- if (size == 8) \
+- zero[1] = fetch_reg(1, regs); \
+- } \
+- store_common(dst_addr, size, src_val, errh); \
+-})
++static int do_int_store(int reg_num, int size, unsigned long *dst_addr,
++ struct pt_regs *regs)
++{
++ unsigned long zero[2] = { 0, 0 };
++ unsigned long *src_val;
++
++ if (reg_num)
++ src_val = fetch_reg_addr(reg_num, regs);
++ else {
++ src_val = &zero[0];
++ if (size == 8)
++ zero[1] = fetch_reg(1, regs);
++ }
++ return __do_int_store(dst_addr, size, src_val);
++}
+
+ extern void smp_capture(void);
+ extern void smp_release(void);
+
+-#define do_atomic(srcdest_reg, mem, errh) ({ \
+- unsigned long flags, tmp; \
+- \
+- smp_capture(); \
+- local_irq_save(flags); \
+- tmp = *srcdest_reg; \
+- do_integer_load(srcdest_reg, 4, mem, 0, errh); \
+- store_common(mem, 4, &tmp, errh); \
+- local_irq_restore(flags); \
+- smp_release(); \
+-})
+-
+ static inline void advance(struct pt_regs *regs)
+ {
+ regs->pc = regs->npc;
+@@ -342,9 +216,7 @@
+ return !floating_point_load_or_store_p(insn);
+ }
+
+-void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("kernel_mna_trap_fault");
+-
+-void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
++static void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
+ {
+ unsigned long g2 = regs->u_regs [UREG_G2];
+ unsigned long fixup = search_extables_range(regs->pc, &g2);
+@@ -379,48 +251,34 @@
+ printk("Unsupported unaligned load/store trap for kernel at <%08lx>.\n",
+ regs->pc);
+ unaligned_panic("Wheee. Kernel does fpu/atomic unaligned load/store.");
+-
+- __asm__ __volatile__ ("\n"
+-"kernel_unaligned_trap_fault:\n\t"
+- "mov %0, %%o0\n\t"
+- "call kernel_mna_trap_fault\n\t"
+- " mov %1, %%o1\n\t"
+- :
+- : "r" (regs), "r" (insn)
+- : "o0", "o1", "o2", "o3", "o4", "o5", "o7",
+- "g1", "g2", "g3", "g4", "g5", "g7", "cc");
+ } else {
+ unsigned long addr = compute_effective_address(regs, insn);
++ int err;
+
+ #ifdef DEBUG_MNA
+ printk("KMNA: pc=%08lx [dir=%s addr=%08lx size=%d] retpc[%08lx]\n",
+ regs->pc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]);
+ #endif
+- switch(dir) {
++ switch (dir) {
+ case load:
+- do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
+- size, (unsigned long *) addr,
+- decode_signedness(insn),
+- kernel_unaligned_trap_fault);
++ err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
++ regs),
++ size, (unsigned long *) addr,
++ decode_signedness(insn));
+ break;
+
+ case store:
+- do_integer_store(((insn>>25)&0x1f), size,
+- (unsigned long *) addr, regs,
+- kernel_unaligned_trap_fault);
+- break;
+-#if 0 /* unsupported */
+- case both:
+- do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs),
+- (unsigned long *) addr,
+- kernel_unaligned_trap_fault);
++ err = do_int_store(((insn>>25)&0x1f), size,
++ (unsigned long *) addr, regs);
+ break;
+-#endif
+ default:
+ panic("Impossible kernel unaligned trap.");
+ /* Not reached... */
+ }
+- advance(regs);
++ if (err)
++ kernel_mna_trap_fault(regs, insn);
++ else
++ advance(regs);
+ }
+ }
+
+@@ -459,9 +317,7 @@
+ return 0;
+ }
+
+-void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("user_mna_trap_fault");
+-
+-void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
++static void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
+ {
+ siginfo_t info;
+
+@@ -485,7 +341,7 @@
+ if(!ok_for_user(regs, insn, dir)) {
+ goto kill_user;
+ } else {
+- int size = decode_access_size(insn);
++ int err, size = decode_access_size(insn);
+ unsigned long addr;
+
+ if(floating_point_load_or_store_p(insn)) {
+@@ -496,48 +352,34 @@
+ addr = compute_effective_address(regs, insn);
+ switch(dir) {
+ case load:
+- do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
+- size, (unsigned long *) addr,
+- decode_signedness(insn),
+- user_unaligned_trap_fault);
++ err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
++ regs),
++ size, (unsigned long *) addr,
++ decode_signedness(insn));
+ break;
+
+ case store:
+- do_integer_store(((insn>>25)&0x1f), size,
+- (unsigned long *) addr, regs,
+- user_unaligned_trap_fault);
++ err = do_int_store(((insn>>25)&0x1f), size,
++ (unsigned long *) addr, regs);
+ break;
+
+ case both:
+-#if 0 /* unsupported */
+- do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs),
+- (unsigned long *) addr,
+- user_unaligned_trap_fault);
+-#else
+ /*
+ * This was supported in 2.4. However, we question
+ * the value of SWAP instruction across word boundaries.
+ */
+ printk("Unaligned SWAP unsupported.\n");
+- goto kill_user;
+-#endif
++ err = -EFAULT;
+ break;
+
+ default:
+ unaligned_panic("Impossible user unaligned trap.");
+-
+- __asm__ __volatile__ ("\n"
+-"user_unaligned_trap_fault:\n\t"
+- "mov %0, %%o0\n\t"
+- "call user_mna_trap_fault\n\t"
+- " mov %1, %%o1\n\t"
+- :
+- : "r" (regs), "r" (insn)
+- : "o0", "o1", "o2", "o3", "o4", "o5", "o7",
+- "g1", "g2", "g3", "g4", "g5", "g7", "cc");
+ goto out;
+ }
+- advance(regs);
++ if (err)
++ goto kill_user;
++ else
++ advance(regs);
+ goto out;
+ }
+
+diff -Nurd linux-2.6.24/arch/sparc/lib/rwsem.S linux-2.6.24-oxe810/arch/sparc/lib/rwsem.S
+--- linux-2.6.24/arch/sparc/lib/rwsem.S 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/sparc/lib/rwsem.S 2008-06-11 17:48:47.000000000 +0200
+@@ -7,7 +7,7 @@
+ #include <asm/ptrace.h>
+ #include <asm/psr.h>
+
+- .section .sched.text
++ .section .sched.text, "ax"
+ .align 4
+
+ .globl ___down_read
+diff -Nurd linux-2.6.24/arch/sparc64/lib/rwsem.S linux-2.6.24-oxe810/arch/sparc64/lib/rwsem.S
+--- linux-2.6.24/arch/sparc64/lib/rwsem.S 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/sparc64/lib/rwsem.S 2008-06-11 17:48:11.000000000 +0200
+@@ -6,7 +6,7 @@
+
+ #include <asm/rwsem-const.h>
+
+- .section .sched.text
++ .section .sched.text, "ax"
+
+ .globl __down_read
+ __down_read:
+diff -Nurd linux-2.6.24/arch/sparc64/mm/fault.c linux-2.6.24-oxe810/arch/sparc64/mm/fault.c
+--- linux-2.6.24/arch/sparc64/mm/fault.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/sparc64/mm/fault.c 2008-06-11 17:48:12.000000000 +0200
+@@ -244,16 +244,8 @@
+ if (regs->tstate & TSTATE_PRIV) {
+ const struct exception_table_entry *entry;
+
+- if (asi == ASI_P && (insn & 0xc0800000) == 0xc0800000) {
+- if (insn & 0x2000)
+- asi = (regs->tstate >> 24);
+- else
+- asi = (insn >> 5);
+- }
+-
+- /* Look in asi.h: All _S asis have LS bit set */
+- if ((asi & 0x1) &&
+- (entry = search_exception_tables(regs->tpc))) {
++ entry = search_exception_tables(regs->tpc);
++ if (entry) {
+ regs->tpc = entry->fixup;
+ regs->tnpc = regs->tpc + 4;
+ return;
+@@ -294,7 +286,7 @@
+ unsigned long tpc = regs->tpc;
+
+ /* Sanity check the PC. */
+- if ((tpc >= KERNBASE && tpc < (unsigned long) _etext) ||
++ if ((tpc >= KERNBASE && tpc < (unsigned long) __init_end) ||
+ (tpc >= MODULES_VADDR && tpc < MODULES_END)) {
+ /* Valid, no problems... */
+ } else {
+diff -Nurd linux-2.6.24/arch/x86/ia32/ia32_signal.c linux-2.6.24-oxe810/arch/x86/ia32/ia32_signal.c
+--- linux-2.6.24/arch/x86/ia32/ia32_signal.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/x86/ia32/ia32_signal.c 2008-06-11 17:48:21.000000000 +0200
+@@ -494,7 +494,7 @@
+ regs->ss = __USER32_DS;
+
+ set_fs(USER_DS);
+- regs->eflags &= ~TF_MASK;
++ regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
+ if (test_thread_flag(TIF_SINGLESTEP))
+ ptrace_notify(SIGTRAP);
+
+@@ -600,7 +600,7 @@
+ regs->ss = __USER32_DS;
+
+ set_fs(USER_DS);
+- regs->eflags &= ~TF_MASK;
++ regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
+ if (test_thread_flag(TIF_SINGLESTEP))
+ ptrace_notify(SIGTRAP);
+
+diff -Nurd linux-2.6.24/arch/x86/kernel/Makefile_32 linux-2.6.24-oxe810/arch/x86/kernel/Makefile_32
+--- linux-2.6.24/arch/x86/kernel/Makefile_32 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/x86/kernel/Makefile_32 2008-06-11 17:48:20.000000000 +0200
+@@ -19,7 +19,8 @@
+ obj-$(CONFIG_X86_CPUID) += cpuid.o
+ obj-$(CONFIG_MICROCODE) += microcode.o
+ obj-$(CONFIG_PCI) += early-quirks.o
+-obj-$(CONFIG_APM) += apm_32.o
++apm-y := apm_32.o
++obj-$(CONFIG_APM) += apm.o
+ obj-$(CONFIG_X86_SMP) += smp_32.o smpboot_32.o tsc_sync.o
+ obj-$(CONFIG_SMP) += smpcommon_32.o
+ obj-$(CONFIG_X86_TRAMPOLINE) += trampoline_32.o
+diff -Nurd linux-2.6.24/arch/x86/kernel/apic_32.c linux-2.6.24-oxe810/arch/x86/kernel/apic_32.c
+--- linux-2.6.24/arch/x86/kernel/apic_32.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/x86/kernel/apic_32.c 2008-06-11 17:48:20.000000000 +0200
+@@ -154,7 +154,7 @@
+ /**
+ * enable_NMI_through_LVT0 - enable NMI through local vector table 0
+ */
+-void enable_NMI_through_LVT0 (void * dummy)
++void __cpuinit enable_NMI_through_LVT0(void)
+ {
+ unsigned int v = APIC_DM_NMI;
+
+diff -Nurd linux-2.6.24/arch/x86/kernel/apic_64.c linux-2.6.24-oxe810/arch/x86/kernel/apic_64.c
+--- linux-2.6.24/arch/x86/kernel/apic_64.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/x86/kernel/apic_64.c 2008-06-11 17:48:20.000000000 +0200
+@@ -151,7 +151,7 @@
+ return send_status;
+ }
+
+-void enable_NMI_through_LVT0 (void * dummy)
++void enable_NMI_through_LVT0(void)
+ {
+ unsigned int v;
+
+diff -Nurd linux-2.6.24/arch/x86/kernel/io_apic_32.c linux-2.6.24-oxe810/arch/x86/kernel/io_apic_32.c
+--- linux-2.6.24/arch/x86/kernel/io_apic_32.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/x86/kernel/io_apic_32.c 2008-06-11 17:48:20.000000000 +0200
+@@ -2080,7 +2080,7 @@
+ .eoi = ack_apic,
+ };
+
+-static void setup_nmi (void)
++static void __init setup_nmi(void)
+ {
+ /*
+ * Dirty trick to enable the NMI watchdog ...
+@@ -2093,7 +2093,7 @@
+ */
+ apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ...");
+
+- on_each_cpu(enable_NMI_through_LVT0, NULL, 1, 1);
++ enable_NMI_through_LVT0();
+
+ apic_printk(APIC_VERBOSE, " done.\n");
+ }
+diff -Nurd linux-2.6.24/arch/x86/kernel/io_apic_64.c linux-2.6.24-oxe810/arch/x86/kernel/io_apic_64.c
+--- linux-2.6.24/arch/x86/kernel/io_apic_64.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/x86/kernel/io_apic_64.c 2008-06-11 17:48:20.000000000 +0200
+@@ -1565,7 +1565,7 @@
+ .end = end_lapic_irq,
+ };
+
+-static void setup_nmi (void)
++static void __init setup_nmi(void)
+ {
+ /*
+ * Dirty trick to enable the NMI watchdog ...
+@@ -1578,7 +1578,7 @@
+ */
+ printk(KERN_INFO "activating NMI Watchdog ...");
+
+- enable_NMI_through_LVT0(NULL);
++ enable_NMI_through_LVT0();
+
+ printk(" done.\n");
+ }
+@@ -1654,7 +1654,7 @@
+ *
+ * FIXME: really need to revamp this for modern platforms only.
+ */
+-static inline void check_timer(void)
++static inline void __init check_timer(void)
+ {
+ struct irq_cfg *cfg = irq_cfg + 0;
+ int apic1, pin1, apic2, pin2;
+diff -Nurd linux-2.6.24/arch/x86/kernel/process_64.c linux-2.6.24-oxe810/arch/x86/kernel/process_64.c
+--- linux-2.6.24/arch/x86/kernel/process_64.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/x86/kernel/process_64.c 2008-06-11 17:48:20.000000000 +0200
+@@ -212,14 +212,13 @@
+ current_thread_info()->status |= TS_POLLING;
+ /* endless idle loop with no priority at all */
+ while (1) {
++ tick_nohz_stop_sched_tick();
+ while (!need_resched()) {
+ void (*idle)(void);
+
+ if (__get_cpu_var(cpu_idle_state))
+ __get_cpu_var(cpu_idle_state) = 0;
+
+- tick_nohz_stop_sched_tick();
+-
+ rmb();
+ idle = pm_idle;
+ if (!idle)
+diff -Nurd linux-2.6.24/arch/x86/kernel/signal_32.c linux-2.6.24-oxe810/arch/x86/kernel/signal_32.c
+--- linux-2.6.24/arch/x86/kernel/signal_32.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/x86/kernel/signal_32.c 2008-06-11 17:48:20.000000000 +0200
+@@ -396,7 +396,7 @@
+ * The tracer may want to single-step inside the
+ * handler too.
+ */
+- regs->eflags &= ~TF_MASK;
++ regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
+ if (test_thread_flag(TIF_SINGLESTEP))
+ ptrace_notify(SIGTRAP);
+
+@@ -489,7 +489,7 @@
+ * The tracer may want to single-step inside the
+ * handler too.
+ */
+- regs->eflags &= ~TF_MASK;
++ regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
+ if (test_thread_flag(TIF_SINGLESTEP))
+ ptrace_notify(SIGTRAP);
+
+diff -Nurd linux-2.6.24/arch/x86/kernel/signal_64.c linux-2.6.24-oxe810/arch/x86/kernel/signal_64.c
+--- linux-2.6.24/arch/x86/kernel/signal_64.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/x86/kernel/signal_64.c 2008-06-11 17:48:20.000000000 +0200
+@@ -295,7 +295,7 @@
+ see include/asm-x86_64/uaccess.h for details. */
+ set_fs(USER_DS);
+
+- regs->eflags &= ~TF_MASK;
++ regs->eflags &= ~(TF_MASK | X86_EFLAGS_DF);
+ if (test_thread_flag(TIF_SINGLESTEP))
+ ptrace_notify(SIGTRAP);
+ #ifdef DEBUG_SIG
+diff -Nurd linux-2.6.24/arch/x86/kernel/smpboot_32.c linux-2.6.24-oxe810/arch/x86/kernel/smpboot_32.c
+--- linux-2.6.24/arch/x86/kernel/smpboot_32.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/x86/kernel/smpboot_32.c 2008-06-11 17:48:20.000000000 +0200
+@@ -405,7 +405,7 @@
+ setup_secondary_clock();
+ if (nmi_watchdog == NMI_IO_APIC) {
+ disable_8259A_irq(0);
+- enable_NMI_through_LVT0(NULL);
++ enable_NMI_through_LVT0();
+ enable_8259A_irq(0);
+ }
+ /*
+diff -Nurd linux-2.6.24/arch/x86/kernel/smpboot_64.c linux-2.6.24-oxe810/arch/x86/kernel/smpboot_64.c
+--- linux-2.6.24/arch/x86/kernel/smpboot_64.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/x86/kernel/smpboot_64.c 2008-06-11 17:48:20.000000000 +0200
+@@ -338,7 +338,7 @@
+
+ if (nmi_watchdog == NMI_IO_APIC) {
+ disable_8259A_irq(0);
+- enable_NMI_through_LVT0(NULL);
++ enable_NMI_through_LVT0();
+ enable_8259A_irq(0);
+ }
+
+diff -Nurd linux-2.6.24/arch/x86/mm/pageattr_64.c linux-2.6.24-oxe810/arch/x86/mm/pageattr_64.c
+--- linux-2.6.24/arch/x86/mm/pageattr_64.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/x86/mm/pageattr_64.c 2008-06-11 17:48:22.000000000 +0200
+@@ -207,7 +207,7 @@
+ if (__pa(address) < KERNEL_TEXT_SIZE) {
+ unsigned long addr2;
+ pgprot_t prot2;
+- addr2 = __START_KERNEL_map + __pa(address);
++ addr2 = __START_KERNEL_map + __pa(address) - phys_base;
+ /* Make sure the kernel mappings stay executable */
+ prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot)));
+ err = __change_page_attr(addr2, pfn, prot2,
+diff -Nurd linux-2.6.24/arch/x86/pci/mmconfig-shared.c linux-2.6.24-oxe810/arch/x86/pci/mmconfig-shared.c
+--- linux-2.6.24/arch/x86/pci/mmconfig-shared.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/x86/pci/mmconfig-shared.c 2008-06-11 17:48:22.000000000 +0200
+@@ -22,42 +22,9 @@
+ #define MMCONFIG_APER_MIN (2 * 1024*1024)
+ #define MMCONFIG_APER_MAX (256 * 1024*1024)
+
+-DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
+-
+ /* Indicate if the mmcfg resources have been placed into the resource table. */
+ static int __initdata pci_mmcfg_resources_inserted;
+
+-/* K8 systems have some devices (typically in the builtin northbridge)
+- that are only accessible using type1
+- Normally this can be expressed in the MCFG by not listing them
+- and assigning suitable _SEGs, but this isn't implemented in some BIOS.
+- Instead try to discover all devices on bus 0 that are unreachable using MM
+- and fallback for them. */
+-static void __init unreachable_devices(void)
+-{
+- int i, bus;
+- /* Use the max bus number from ACPI here? */
+- for (bus = 0; bus < PCI_MMCFG_MAX_CHECK_BUS; bus++) {
+- for (i = 0; i < 32; i++) {
+- unsigned int devfn = PCI_DEVFN(i, 0);
+- u32 val1, val2;
+-
+- pci_conf1_read(0, bus, devfn, 0, 4, &val1);
+- if (val1 == 0xffffffff)
+- continue;
+-
+- if (pci_mmcfg_arch_reachable(0, bus, devfn)) {
+- raw_pci_ops->read(0, bus, devfn, 0, 4, &val2);
+- if (val1 == val2)
+- continue;
+- }
+- set_bit(i + 32 * bus, pci_mmcfg_fallback_slots);
+- printk(KERN_NOTICE "PCI: No mmconfig possible on device"
+- " %02x:%02x\n", bus, i);
+- }
+- }
+-}
+-
+ static const char __init *pci_mmcfg_e7520(void)
+ {
+ u32 win;
+@@ -270,8 +237,6 @@
+ return;
+
+ if (pci_mmcfg_arch_init()) {
+- if (type == 1)
+- unreachable_devices();
+ if (known_bridge)
+ pci_mmcfg_insert_resources(IORESOURCE_BUSY);
+ pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
+diff -Nurd linux-2.6.24/arch/x86/pci/mmconfig_32.c linux-2.6.24-oxe810/arch/x86/pci/mmconfig_32.c
+--- linux-2.6.24/arch/x86/pci/mmconfig_32.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/x86/pci/mmconfig_32.c 2008-06-11 17:48:22.000000000 +0200
+@@ -30,10 +30,6 @@
+ struct acpi_mcfg_allocation *cfg;
+ int cfg_num;
+
+- if (seg == 0 && bus < PCI_MMCFG_MAX_CHECK_BUS &&
+- test_bit(PCI_SLOT(devfn) + 32*bus, pci_mmcfg_fallback_slots))
+- return 0;
+-
+ for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) {
+ cfg = &pci_mmcfg_config[cfg_num];
+ if (cfg->pci_segment == seg &&
+@@ -68,13 +64,16 @@
+ u32 base;
+
+ if ((bus > 255) || (devfn > 255) || (reg > 4095)) {
+- *value = -1;
++err: *value = -1;
+ return -EINVAL;
+ }
+
++ if (reg < 256)
++ return pci_conf1_read(seg,bus,devfn,reg,len,value);
++
+ base = get_base_addr(seg, bus, devfn);
+ if (!base)
+- return pci_conf1_read(seg,bus,devfn,reg,len,value);
++ goto err;
+
+ spin_lock_irqsave(&pci_config_lock, flags);
+
+@@ -105,9 +104,12 @@
+ if ((bus > 255) || (devfn > 255) || (reg > 4095))
+ return -EINVAL;
+
++ if (reg < 256)
++ return pci_conf1_write(seg,bus,devfn,reg,len,value);
++
+ base = get_base_addr(seg, bus, devfn);
+ if (!base)
+- return pci_conf1_write(seg,bus,devfn,reg,len,value);
++ return -EINVAL;
+
+ spin_lock_irqsave(&pci_config_lock, flags);
+
+@@ -134,12 +136,6 @@
+ .write = pci_mmcfg_write,
+ };
+
+-int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus,
+- unsigned int devfn)
+-{
+- return get_base_addr(seg, bus, devfn) != 0;
+-}
+-
+ int __init pci_mmcfg_arch_init(void)
+ {
+ printk(KERN_INFO "PCI: Using MMCONFIG\n");
+diff -Nurd linux-2.6.24/arch/x86/pci/mmconfig_64.c linux-2.6.24-oxe810/arch/x86/pci/mmconfig_64.c
+--- linux-2.6.24/arch/x86/pci/mmconfig_64.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/x86/pci/mmconfig_64.c 2008-06-11 17:48:22.000000000 +0200
+@@ -40,9 +40,7 @@
+ static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
+ {
+ char __iomem *addr;
+- if (seg == 0 && bus < PCI_MMCFG_MAX_CHECK_BUS &&
+- test_bit(32*bus + PCI_SLOT(devfn), pci_mmcfg_fallback_slots))
+- return NULL;
++
+ addr = get_virt(seg, bus);
+ if (!addr)
+ return NULL;
+@@ -56,13 +54,16 @@
+
+ /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
+ if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
+- *value = -1;
++err: *value = -1;
+ return -EINVAL;
+ }
+
++ if (reg < 256)
++ return pci_conf1_read(seg,bus,devfn,reg,len,value);
++
+ addr = pci_dev_base(seg, bus, devfn);
+ if (!addr)
+- return pci_conf1_read(seg,bus,devfn,reg,len,value);
++ goto err;
+
+ switch (len) {
+ case 1:
+@@ -88,9 +89,12 @@
+ if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
+ return -EINVAL;
+
++ if (reg < 256)
++ return pci_conf1_write(seg,bus,devfn,reg,len,value);
++
+ addr = pci_dev_base(seg, bus, devfn);
+ if (!addr)
+- return pci_conf1_write(seg,bus,devfn,reg,len,value);
++ return -EINVAL;
+
+ switch (len) {
+ case 1:
+@@ -126,12 +130,6 @@
+ return addr;
+ }
+
+-int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus,
+- unsigned int devfn)
+-{
+- return pci_dev_base(seg, bus, devfn) != NULL;
+-}
+-
+ int __init pci_mmcfg_arch_init(void)
+ {
+ int i;
+diff -Nurd linux-2.6.24/arch/x86/pci/pci.h linux-2.6.24-oxe810/arch/x86/pci/pci.h
+--- linux-2.6.24/arch/x86/pci/pci.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/arch/x86/pci/pci.h 2008-06-11 17:48:22.000000000 +0200
+@@ -98,13 +98,6 @@
+
+ /* pci-mmconfig.c */
+
+-/* Verify the first 16 busses. We assume that systems with more busses
+- get MCFG right. */
+-#define PCI_MMCFG_MAX_CHECK_BUS 16
+-extern DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
+-
+-extern int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus,
+- unsigned int devfn);
+ extern int __init pci_mmcfg_arch_init(void);
+
+ /*
+diff -Nurd linux-2.6.24/block/ll_rw_blk.c linux-2.6.24-oxe810/block/ll_rw_blk.c
+--- linux-2.6.24/block/ll_rw_blk.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/block/ll_rw_blk.c 2008-06-11 17:46:40.000000000 +0200
+@@ -1424,6 +1424,13 @@
+ else
+ max_sectors = q->max_sectors;
+
++ /*
++ * If the RAID modes of the bio associated with the request differs
++ * from the merge candidate bio, it can't be merged
++ */
++ if (req->bio->bi_raid != bio->bi_raid)
++ return 0;
++
+ if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
+ req->cmd_flags |= REQ_NOMERGE;
+ if (req == q->last_merge)
+@@ -1462,6 +1469,12 @@
+ else
+ max_sectors = q->max_sectors;
+
++ /*
++ * If the RAID modes of the bio associated with the request differs
++ * from the merge candidate bio, it can't be merged
++ */
++ if (req->bio->bi_raid != bio->bi_raid)
++ return 0;
+
+ if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
+ req->cmd_flags |= REQ_NOMERGE;
+@@ -1502,6 +1515,17 @@
+ */
+ if (req->special || next->special)
+ return 0;
++
++ /*
++ * If the RAID modes of the bio associated with the two requests differ
++ * then they cannot be merged.
++ *
++ BUG_ON(!req);
++ BUG_ON(!req->bio);
++ BUG_ON(!next);
++ BUG_ON(!next->bio);
++ if (req->bio->bi_raid != next->bio->bi_raid)
++ return 0;*/
+
+ /*
+ * Will it become too large?
+@@ -2965,7 +2989,7 @@
+
+ static int __make_request(struct request_queue *q, struct bio *bio)
+ {
+- struct request *req;
++ struct request *req = 0;
+ int el_ret, nr_sectors, barrier, err;
+ const unsigned short prio = bio_prio(bio);
+ const int sync = bio_sync(bio);
+@@ -2992,6 +3016,15 @@
+ goto get_rq;
+
+ el_ret = elv_merge(q, &req, bio);
++
++ /* if the bio raid modes differ, force a no-merge */
++ if ((!ELEVATOR_NO_MERGE) &&
++ (req) &&
++ (req->bio) &&
++ (bio->bi_raid != req->bio->bi_raid )) {
++ el_ret = ELEVATOR_NO_MERGE;
++ }
++
+ switch (el_ret) {
+ case ELEVATOR_BACK_MERGE:
+ BUG_ON(!rq_mergeable(req));
+diff -Nurd linux-2.6.24/crypto/async_tx/async_xor.c linux-2.6.24-oxe810/crypto/async_tx/async_xor.c
+--- linux-2.6.24/crypto/async_tx/async_xor.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/crypto/async_tx/async_xor.c 2008-06-11 17:43:37.000000000 +0200
+@@ -264,7 +264,7 @@
+
+ BUG_ON(src_cnt <= 1);
+
+- if (tx) {
++ if (tx && src_cnt <= device->max_xor) {
+ dma_addr_t dma_addr;
+ enum dma_data_direction dir;
+
+diff -Nurd linux-2.6.24/crypto/xcbc.c linux-2.6.24-oxe810/crypto/xcbc.c
+--- linux-2.6.24/crypto/xcbc.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/crypto/xcbc.c 2008-06-11 17:43:39.000000000 +0200
+@@ -124,6 +124,11 @@
+ unsigned int offset = sg[i].offset;
+ unsigned int slen = sg[i].length;
+
++ if (unlikely(slen > nbytes))
++ slen = nbytes;
++
++ nbytes -= slen;
++
+ while (slen > 0) {
+ unsigned int len = min(slen, ((unsigned int)(PAGE_SIZE)) - offset);
+ char *p = crypto_kmap(pg, 0) + offset;
+@@ -177,7 +182,6 @@
+ offset = 0;
+ pg++;
+ }
+- nbytes-=sg[i].length;
+ i++;
+ } while (nbytes>0);
+
+diff -Nurd linux-2.6.24/crypto/xts.c linux-2.6.24-oxe810/crypto/xts.c
+--- linux-2.6.24/crypto/xts.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/crypto/xts.c 2008-06-11 17:43:39.000000000 +0200
+@@ -77,16 +77,16 @@
+ }
+
+ struct sinfo {
+- be128 t;
++ be128 *t;
+ struct crypto_tfm *tfm;
+ void (*fn)(struct crypto_tfm *, u8 *, const u8 *);
+ };
+
+ static inline void xts_round(struct sinfo *s, void *dst, const void *src)
+ {
+- be128_xor(dst, &s->t, src); /* PP <- T xor P */
++ be128_xor(dst, s->t, src); /* PP <- T xor P */
+ s->fn(s->tfm, dst, dst); /* CC <- E(Key1,PP) */
+- be128_xor(dst, dst, &s->t); /* C <- T xor CC */
++ be128_xor(dst, dst, s->t); /* C <- T xor CC */
+ }
+
+ static int crypt(struct blkcipher_desc *d,
+@@ -101,7 +101,6 @@
+ .tfm = crypto_cipher_tfm(ctx->child),
+ .fn = fn
+ };
+- be128 *iv;
+ u8 *wsrc;
+ u8 *wdst;
+
+@@ -109,20 +108,20 @@
+ if (!w->nbytes)
+ return err;
+
++ s.t = (be128 *)w->iv;
+ avail = w->nbytes;
+
+ wsrc = w->src.virt.addr;
+ wdst = w->dst.virt.addr;
+
+ /* calculate first value of T */
+- iv = (be128 *)w->iv;
+- tw(crypto_cipher_tfm(ctx->tweak), (void *)&s.t, w->iv);
++ tw(crypto_cipher_tfm(ctx->tweak), w->iv, w->iv);
+
+ goto first;
+
+ for (;;) {
+ do {
+- gf128mul_x_ble(&s.t, &s.t);
++ gf128mul_x_ble(s.t, s.t);
+
+ first:
+ xts_round(&s, wdst, wsrc);
+diff -Nurd linux-2.6.24/drivers/acorn/char/defkeymap-l7200.c linux-2.6.24-oxe810/drivers/acorn/char/defkeymap-l7200.c
+--- linux-2.6.24/drivers/acorn/char/defkeymap-l7200.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/acorn/char/defkeymap-l7200.c 2008-06-11 17:49:37.000000000 +0200
+@@ -347,40 +347,40 @@
+ };
+
+ struct kbdiacruc accent_table[MAX_DIACR] = {
+- {'`', 'A', '\300'}, {'`', 'a', '\340'},
+- {'\'', 'A', '\301'}, {'\'', 'a', '\341'},
+- {'^', 'A', '\302'}, {'^', 'a', '\342'},
+- {'~', 'A', '\303'}, {'~', 'a', '\343'},
+- {'"', 'A', '\304'}, {'"', 'a', '\344'},
+- {'O', 'A', '\305'}, {'o', 'a', '\345'},
+- {'0', 'A', '\305'}, {'0', 'a', '\345'},
+- {'A', 'A', '\305'}, {'a', 'a', '\345'},
+- {'A', 'E', '\306'}, {'a', 'e', '\346'},
+- {',', 'C', '\307'}, {',', 'c', '\347'},
+- {'`', 'E', '\310'}, {'`', 'e', '\350'},
+- {'\'', 'E', '\311'}, {'\'', 'e', '\351'},
+- {'^', 'E', '\312'}, {'^', 'e', '\352'},
+- {'"', 'E', '\313'}, {'"', 'e', '\353'},
+- {'`', 'I', '\314'}, {'`', 'i', '\354'},
+- {'\'', 'I', '\315'}, {'\'', 'i', '\355'},
+- {'^', 'I', '\316'}, {'^', 'i', '\356'},
+- {'"', 'I', '\317'}, {'"', 'i', '\357'},
+- {'-', 'D', '\320'}, {'-', 'd', '\360'},
+- {'~', 'N', '\321'}, {'~', 'n', '\361'},
+- {'`', 'O', '\322'}, {'`', 'o', '\362'},
+- {'\'', 'O', '\323'}, {'\'', 'o', '\363'},
+- {'^', 'O', '\324'}, {'^', 'o', '\364'},
+- {'~', 'O', '\325'}, {'~', 'o', '\365'},
+- {'"', 'O', '\326'}, {'"', 'o', '\366'},
+- {'/', 'O', '\330'}, {'/', 'o', '\370'},
+- {'`', 'U', '\331'}, {'`', 'u', '\371'},
+- {'\'', 'U', '\332'}, {'\'', 'u', '\372'},
+- {'^', 'U', '\333'}, {'^', 'u', '\373'},
+- {'"', 'U', '\334'}, {'"', 'u', '\374'},
+- {'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
+- {'T', 'H', '\336'}, {'t', 'h', '\376'},
+- {'s', 's', '\337'}, {'"', 'y', '\377'},
+- {'s', 'z', '\337'}, {'i', 'j', '\377'},
++ {'`', 'A', 0300}, {'`', 'a', 0340},
++ {'\'', 'A', 0301}, {'\'', 'a', 0341},
++ {'^', 'A', 0302}, {'^', 'a', 0342},
++ {'~', 'A', 0303}, {'~', 'a', 0343},
++ {'"', 'A', 0304}, {'"', 'a', 0344},
++ {'O', 'A', 0305}, {'o', 'a', 0345},
++ {'0', 'A', 0305}, {'0', 'a', 0345},
++ {'A', 'A', 0305}, {'a', 'a', 0345},
++ {'A', 'E', 0306}, {'a', 'e', 0346},
++ {',', 'C', 0307}, {',', 'c', 0347},
++ {'`', 'E', 0310}, {'`', 'e', 0350},
++ {'\'', 'E', 0311}, {'\'', 'e', 0351},
++ {'^', 'E', 0312}, {'^', 'e', 0352},
++ {'"', 'E', 0313}, {'"', 'e', 0353},
++ {'`', 'I', 0314}, {'`', 'i', 0354},
++ {'\'', 'I', 0315}, {'\'', 'i', 0355},
++ {'^', 'I', 0316}, {'^', 'i', 0356},
++ {'"', 'I', 0317}, {'"', 'i', 0357},
++ {'-', 'D', 0320}, {'-', 'd', 0360},
++ {'~', 'N', 0321}, {'~', 'n', 0361},
++ {'`', 'O', 0322}, {'`', 'o', 0362},
++ {'\'', 'O', 0323}, {'\'', 'o', 0363},
++ {'^', 'O', 0324}, {'^', 'o', 0364},
++ {'~', 'O', 0325}, {'~', 'o', 0365},
++ {'"', 'O', 0326}, {'"', 'o', 0366},
++ {'/', 'O', 0330}, {'/', 'o', 0370},
++ {'`', 'U', 0331}, {'`', 'u', 0371},
++ {'\'', 'U', 0332}, {'\'', 'u', 0372},
++ {'^', 'U', 0333}, {'^', 'u', 0373},
++ {'"', 'U', 0334}, {'"', 'u', 0374},
++ {'\'', 'Y', 0335}, {'\'', 'y', 0375},
++ {'T', 'H', 0336}, {'t', 'h', 0376},
++ {'s', 's', 0337}, {'"', 'y', 0377},
++ {'s', 'z', 0337}, {'i', 'j', 0377},
+ };
+
+ unsigned int accent_table_size = 68;
+diff -Nurd linux-2.6.24/drivers/acpi/blacklist.c linux-2.6.24-oxe810/drivers/acpi/blacklist.c
+--- linux-2.6.24/drivers/acpi/blacklist.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/acpi/blacklist.c 2008-06-11 17:49:40.000000000 +0200
+@@ -208,24 +208,24 @@
+ * Disable OSI(Linux) warnings on all "Acer, inc."
+ *
+ * _OSI(Linux) disables the latest Windows BIOS code:
++ * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3100"),
+ * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5050"),
++ * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
+ * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5580"),
+ * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 3010"),
+ * _OSI(Linux) effect unknown:
+ * DMI_MATCH(DMI_PRODUCT_NAME, "Ferrari 5000"),
+ */
+- {
+- .callback = dmi_disable_osi_linux,
+- .ident = "Acer, inc.",
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "Acer, inc."),
+- },
+- },
++ /*
++ * note that dmi_check_system() uses strstr()
++ * to match sub-strings rather than !strcmp(),
++ * so "Acer" below matches "Acer, inc." above.
++ */
+ /*
+ * Disable OSI(Linux) warnings on all "Acer"
+ *
+ * _OSI(Linux) effect unknown:
+- * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
++ * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"),
+ * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
+ * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720Z"),
+ * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5520"),
+@@ -300,7 +300,7 @@
+ DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
+ },
+ },
+- { /* OSI(Linux) touches USB, breaks suspend to disk */
++ { /* OSI(Linux) touches USB, unknown side-effect */
+ .callback = dmi_disable_osi_linux,
+ .ident = "Dell Dimension 5150",
+ .matches = {
+@@ -474,6 +474,11 @@
+ *
+ * _OSI(Linux) confirmed to be a NOP:
+ * DMI_MATCH(DMI_PRODUCT_NAME, "P1-J150B"),
++ * with DMI_MATCH(DMI_BOARD_NAME, "ROCKY"),
++ *
++ * unknown:
++ * DMI_MATCH(DMI_PRODUCT_NAME, "S1-MDGDG"),
++ * with DMI_MATCH(DMI_BOARD_NAME, "ROCKY"),
+ */
+ {
+ .callback = dmi_disable_osi_linux,
+diff -Nurd linux-2.6.24/drivers/acpi/osl.c linux-2.6.24-oxe810/drivers/acpi/osl.c
+--- linux-2.6.24/drivers/acpi/osl.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/acpi/osl.c 2008-06-11 17:49:40.000000000 +0200
+@@ -120,7 +120,7 @@
+ */
+ #define OSI_LINUX_ENABLE 0
+
+-struct osi_linux {
++static struct osi_linux {
+ unsigned int enable:1;
+ unsigned int dmi:1;
+ unsigned int cmdline:1;
+@@ -1213,24 +1213,24 @@
+ *
+ * Returns 0 on success
+ */
+-int acpi_dmi_dump(void)
++static int acpi_dmi_dump(void)
+ {
+
+ if (!dmi_available)
+ return -1;
+
+ printk(KERN_NOTICE PREFIX "DMI System Vendor: %s\n",
+- dmi_get_slot(DMI_SYS_VENDOR));
++ dmi_get_system_info(DMI_SYS_VENDOR));
+ printk(KERN_NOTICE PREFIX "DMI Product Name: %s\n",
+- dmi_get_slot(DMI_PRODUCT_NAME));
++ dmi_get_system_info(DMI_PRODUCT_NAME));
+ printk(KERN_NOTICE PREFIX "DMI Product Version: %s\n",
+- dmi_get_slot(DMI_PRODUCT_VERSION));
++ dmi_get_system_info(DMI_PRODUCT_VERSION));
+ printk(KERN_NOTICE PREFIX "DMI Board Name: %s\n",
+- dmi_get_slot(DMI_BOARD_NAME));
++ dmi_get_system_info(DMI_BOARD_NAME));
+ printk(KERN_NOTICE PREFIX "DMI BIOS Vendor: %s\n",
+- dmi_get_slot(DMI_BIOS_VENDOR));
++ dmi_get_system_info(DMI_BIOS_VENDOR));
+ printk(KERN_NOTICE PREFIX "DMI BIOS Date: %s\n",
+- dmi_get_slot(DMI_BIOS_DATE));
++ dmi_get_system_info(DMI_BIOS_DATE));
+
+ return 0;
+ }
+diff -Nurd linux-2.6.24/drivers/ata/Kconfig linux-2.6.24-oxe810/drivers/ata/Kconfig
+--- linux-2.6.24/drivers/ata/Kconfig 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/ata/Kconfig 2008-06-11 17:50:32.000000000 +0200
+@@ -182,15 +182,49 @@
+ firmware in the BIOS. This driver can sometimes handle
+ otherwise unsupported hardware.
+
++config SATA_OX800
++ bool "Oxford Semiconductor OX800 SATA support"
++ depends on ARCH_OXNAS && OXNAS_VERSION_0X800
++ default n
++ help
++ This option enables support for the 924 based sata core
++
++config SATA_OX810
++ bool "Oxford Semiconductor OX810 SATA support"
++ depends on ARCH_OXNAS && OXNAS_VERSION_0X810
++ default n
++ help
++ This option enables support for the 934 based sata core
++
+ config SATA_FSL
+ tristate "Freescale 3.0Gbps SATA support"
+ depends on PPC_MPC837x
+ help
+ This option enables support for Freescale 3.0Gbps SATA controller.
+ It can be found on MPC837x and MPC8315.
+-
+ If unsure, say N.
+
++config SATA_OXNAS_SINGLE_SATA
++ bool "Force OXNAS family devices to only use one SATA port"
++ depends on SATA_OX800 || SATA_OX810
++ default n
++ help
++ Prevents the ox800sata module from registering its second sata port, this
++ reduces startup time on systems where only one port is physically present
++ on the board/chip periphery.
++
++config SATA_OXNAS_DISK_LIGHT
++ bool "Whether OXNAS family device should use a SATA disk activity light"
++ depends on SATA_OX800 || SATA_OX810
++ default n
++
++config SATA_OXNAS_DISK_LIGHT_GPIO_LINE
++ int "GPIO line of the disk light"
++ depends on SATA_OXNAS_DISK_LIGHT
++ default 29
++ help
++ Selects the GPIO line of the disk activity light.
++
+ config PATA_ALI
+ tristate "ALi PATA support (Experimental)"
+ depends on PCI && EXPERIMENTAL
+diff -Nurd linux-2.6.24/drivers/ata/Makefile linux-2.6.24-oxe810/drivers/ata/Makefile
+--- linux-2.6.24/drivers/ata/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/ata/Makefile 2008-06-11 17:50:32.000000000 +0200
+@@ -18,6 +18,8 @@
+ obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
+ obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
+ obj-$(CONFIG_SATA_FSL) += sata_fsl.o
++obj-$(CONFIG_SATA_OX800) += ox800sata.o
++obj-$(CONFIG_SATA_OX810) += ox810sata.o
+
+ obj-$(CONFIG_PATA_ALI) += pata_ali.o
+ obj-$(CONFIG_PATA_AMD) += pata_amd.o
+diff -Nurd linux-2.6.24/drivers/ata/libata-core.c linux-2.6.24-oxe810/drivers/ata/libata-core.c
+--- linux-2.6.24/drivers/ata/libata-core.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/ata/libata-core.c 2008-06-11 17:50:32.000000000 +0200
+@@ -140,6 +140,8 @@
+ */
+ void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis)
+ {
++
++ VPRINTK("\n");
+ fis[0] = 0x27; /* Register - Host to Device FIS */
+ fis[1] = pmp & 0xf; /* Port multiplier number*/
+ if (is_cmd)
+@@ -182,6 +184,8 @@
+
+ void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf)
+ {
++
++ VPRINTK("\n");
+ tf->command = fis[2]; /* status */
+ tf->feature = fis[3]; /* error */
+
+@@ -245,6 +249,8 @@
+
+ int index, fua, lba48, write;
+
++
++ VPRINTK("\n");
+ fua = (tf->flags & ATA_TFLAG_FUA) ? 4 : 0;
+ lba48 = (tf->flags & ATA_TFLAG_LBA48) ? 2 : 0;
+ write = (tf->flags & ATA_TFLAG_WRITE) ? 1 : 0;
+@@ -288,6 +294,8 @@
+ {
+ u64 block = 0;
+
++
++ VPRINTK("\n");
+ if (tf->flags & ATA_TFLAG_LBA) {
+ if (tf->flags & ATA_TFLAG_LBA48) {
+ block |= (u64)tf->hob_lbah << 40;
+@@ -336,6 +344,8 @@
+ u64 block, u32 n_block, unsigned int tf_flags,
+ unsigned int tag)
+ {
++
++ VPRINTK("\n");
+ tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+ tf->flags |= tf_flags;
+
+@@ -454,6 +464,8 @@
+ unsigned int mwdma_mask,
+ unsigned int udma_mask)
+ {
++
++ VPRINTK("\n");
+ return ((pio_mask << ATA_SHIFT_PIO) & ATA_MASK_PIO) |
+ ((mwdma_mask << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA) |
+ ((udma_mask << ATA_SHIFT_UDMA) & ATA_MASK_UDMA);
+@@ -474,6 +486,7 @@
+ unsigned int *mwdma_mask,
+ unsigned int *udma_mask)
+ {
++ VPRINTK("\n");
+ if (pio_mask)
+ *pio_mask = (xfer_mask & ATA_MASK_PIO) >> ATA_SHIFT_PIO;
+ if (mwdma_mask)
+@@ -510,6 +523,7 @@
+ int highbit = fls(xfer_mask) - 1;
+ const struct ata_xfer_ent *ent;
+
++ VPRINTK("\n");
+ for (ent = ata_xfer_tbl; ent->shift >= 0; ent++)
+ if (highbit >= ent->shift && highbit < ent->shift + ent->bits)
+ return ent->base + highbit - ent->shift;
+@@ -532,6 +546,7 @@
+ {
+ const struct ata_xfer_ent *ent;
+
++ VPRINTK("\n");
+ for (ent = ata_xfer_tbl; ent->shift >= 0; ent++)
+ if (xfer_mode >= ent->base && xfer_mode < ent->base + ent->bits)
+ return 1 << (ent->shift + xfer_mode - ent->base);
+@@ -554,6 +569,7 @@
+ {
+ const struct ata_xfer_ent *ent;
+
++ VPRINTK("\n");
+ for (ent = ata_xfer_tbl; ent->shift >= 0; ent++)
+ if (xfer_mode >= ent->base && xfer_mode < ent->base + ent->bits)
+ return ent->shift;
+@@ -600,6 +616,7 @@
+ };
+ int highbit;
+
++ VPRINTK("\n");
+ highbit = fls(xfer_mask) - 1;
+ if (highbit >= 0 && highbit < ARRAY_SIZE(xfer_mode_str))
+ return xfer_mode_str[highbit];
+@@ -613,6 +630,7 @@
+ "3.0 Gbps",
+ };
+
++ VPRINTK("\n");
+ if (spd == 0 || (spd - 1) >= ARRAY_SIZE(spd_str))
+ return "<unknown>";
+ return spd_str[spd - 1];
+@@ -620,6 +638,7 @@
+
+ void ata_dev_disable(struct ata_device *dev)
+ {
++ VPRINTK("\n");
+ if (ata_dev_enabled(dev)) {
+ if (ata_msg_drv(dev->link->ap))
+ ata_dev_printk(dev, KERN_WARNING, "disabled\n");
+@@ -638,6 +657,7 @@
+ unsigned int err_mask;
+ int rc;
+
++ VPRINTK("\n");
+ /*
+ * disallow DIPM for drivers which haven't set
+ * ATA_FLAG_IPM. This is because when DIPM is enabled,
+@@ -732,6 +752,7 @@
+ int rc = 0;
+ struct ata_port *ap = dev->link->ap;
+
++ VPRINTK("\n");
+ /* set HIPM first, then DIPM */
+ if (ap->ops->enable_pm)
+ rc = ap->ops->enable_pm(ap, policy);
+@@ -764,6 +785,7 @@
+ {
+ struct ata_port *ap = dev->link->ap;
+
++ VPRINTK("\n");
+ ata_dev_set_dipm(dev, MAX_PERFORMANCE);
+ if (ap->ops->disable_pm)
+ ap->ops->disable_pm(ap);
+@@ -772,6 +794,7 @@
+
+ void ata_lpm_schedule(struct ata_port *ap, enum link_pm policy)
+ {
++ VPRINTK("\n");
+ ap->pm_policy = policy;
+ ap->link.eh_info.action |= ATA_EHI_LPM;
+ ap->link.eh_info.flags |= ATA_EHI_NO_AUTOPSY;
+@@ -786,6 +809,7 @@
+ struct ata_device *dev;
+ int i;
+
++ VPRINTK("\n");
+ for (i = 0; i < host->n_ports; i++) {
+ ap = host->ports[i];
+ ata_port_for_each_link(link, ap) {
+@@ -799,6 +823,7 @@
+ {
+ int i;
+
++ VPRINTK("\n");
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+ ata_lpm_schedule(ap, ap->pm_policy);
+@@ -828,6 +853,11 @@
+ static unsigned int ata_devchk(struct ata_port *ap, unsigned int device)
+ {
+ struct ata_ioports *ioaddr = &ap->ioaddr;
++ VPRINTK("\n");
++ if (ap->ops->dev_chk) {
++ return ap->ops->dev_chk(ap,device);
++ } else {
++
+ u8 nsect, lbal;
+
+ ap->ops->dev_select(ap, device);
+@@ -848,6 +878,7 @@
+ return 1; /* we found a device */
+
+ return 0; /* nothing found */
++ }
+ }
+
+ /**
+@@ -938,6 +969,7 @@
+ unsigned int class;
+ u8 err;
+
++ VPRINTK("\n");
+ ap->ops->dev_select(ap, dev->devno);
+
+ memset(&tf, 0, sizeof(tf));
+@@ -998,6 +1030,7 @@
+ {
+ unsigned int c;
+
++ VPRINTK("\n");
+ while (len > 0) {
+ c = id[ofs] >> 8;
+ *s = c;
+@@ -1031,6 +1064,7 @@
+ {
+ unsigned char *p;
+
++ VPRINTK("\n");
+ WARN_ON(!(len & 1));
+
+ ata_id_string(id, s, ofs, len - 1);
+@@ -1043,6 +1077,7 @@
+
+ static u64 ata_id_n_sectors(const u16 *id)
+ {
++ VPRINTK("\n");
+ if (ata_id_has_lba(id)) {
+ if (ata_id_has_lba48(id))
+ return ata_id_u64(id, 100);
+@@ -1060,6 +1095,7 @@
+ {
+ u64 sectors = 0;
+
++ VPRINTK("\n");
+ sectors |= ((u64)(tf->hob_lbah & 0xff)) << 40;
+ sectors |= ((u64)(tf->hob_lbam & 0xff)) << 32;
+ sectors |= (tf->hob_lbal & 0xff) << 24;
+@@ -1074,6 +1110,7 @@
+ {
+ u64 sectors = 0;
+
++ VPRINTK("\n");
+ sectors |= (tf->device & 0x0f) << 24;
+ sectors |= (tf->lbah & 0xff) << 16;
+ sectors |= (tf->lbam & 0xff) << 8;
+@@ -1100,6 +1137,7 @@
+ struct ata_taskfile tf;
+ int lba48 = ata_id_has_lba48(dev->id);
+
++ VPRINTK("\n");
+ ata_tf_init(dev, &tf);
+
+ /* always clear all address registers */
+@@ -1150,6 +1188,7 @@
+ struct ata_taskfile tf;
+ int lba48 = ata_id_has_lba48(dev->id);
+
++ VPRINTK("\n");
+ new_sectors--;
+
+ ata_tf_init(dev, &tf);
+@@ -1208,6 +1247,7 @@
+ u64 native_sectors;
+ int rc;
+
++ VPRINTK("\n");
+ /* do we need to do it? */
+ if (dev->class != ATA_DEV_ATA ||
+ !ata_id_has_lba(dev->id) || !ata_id_hpa_enabled(dev->id) ||
+@@ -1305,6 +1345,7 @@
+ unsigned int mask;
+ u8 mode;
+
++ VPRINTK("\n");
+ /* Pack the DMA modes */
+ mask = ((dev->id[63] >> 8) << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA;
+ if (dev->id[53] & 0x04)
+@@ -1341,6 +1382,7 @@
+ */
+ void ata_noop_dev_select(struct ata_port *ap, unsigned int device)
+ {
++ VPRINTK("\n");
+ }
+
+
+@@ -1363,6 +1405,7 @@
+ {
+ u8 tmp;
+
++ VPRINTK("\n");
+ if (device == 0)
+ tmp = ATA_DEVICE_OBS;
+ else
+@@ -1394,6 +1437,7 @@
+ void ata_dev_select(struct ata_port *ap, unsigned int device,
+ unsigned int wait, unsigned int can_sleep)
+ {
++ VPRINTK("\n");
+ if (ata_msg_probe(ap))
+ ata_port_printk(ap, KERN_INFO, "ata_dev_select: ENTER, "
+ "device %u, wait %u\n", device, wait);
+@@ -1469,6 +1513,7 @@
+ unsigned int pio_mask, mwdma_mask, udma_mask;
+
+ /* Usual case. Word 53 indicates word 64 is valid */
++ VPRINTK("\n");
+ if (id[ATA_ID_FIELD_VALID] & (1 << 1)) {
+ pio_mask = id[ATA_ID_PIO_MODES] & 0x03;
+ pio_mask <<= 3;
+@@ -1571,6 +1616,7 @@
+ {
+ struct completion *waiting = qc->private_data;
+
++ VPRINTK("\n");
+ complete(waiting);
+ }
+
+@@ -1613,6 +1659,7 @@
+ unsigned int err_mask;
+ int rc;
+
++ VPRINTK("\n");
+ spin_lock_irqsave(ap->lock, flags);
+
+ /* no internal command while frozen */
+@@ -1729,7 +1776,11 @@
+ *tf = qc->result_tf;
+ err_mask = qc->err_mask;
+
+- ata_qc_free(qc);
++ if (ap->ops->qc_free) {
++ ap->ops->qc_free(qc);
++ } else {
++ ata_qc_free(qc);
++ }
+ link->active_tag = preempted_tag;
+ link->sactive = preempted_sactive;
+ ap->qc_active = preempted_qc_active;
+@@ -1783,6 +1834,7 @@
+ struct scatterlist *psg = NULL, sg;
+ unsigned int n_elem = 0;
+
++ VPRINTK("\n");
+ if (dma_dir != DMA_NONE) {
+ WARN_ON(!buf);
+ sg_init_one(&sg, buf, buflen);
+@@ -1812,6 +1864,7 @@
+ {
+ struct ata_taskfile tf;
+
++ VPRINTK("\n");
+ ata_tf_init(dev, &tf);
+
+ tf.command = cmd;
+@@ -1831,6 +1884,7 @@
+
+ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
+ {
++ VPRINTK("\n");
+ /* Controller doesn't support IORDY. Probably a pointless check
+ as the caller should know this */
+ if (adev->link->ap->flags & ATA_FLAG_NO_IORDY)
+@@ -1854,6 +1908,7 @@
+
+ static u32 ata_pio_mask_no_iordy(const struct ata_device *adev)
+ {
++ VPRINTK("\n");
+ /* If we have no drive specific rule, then PIO 2 is non IORDY */
+ if (adev->id[ATA_ID_FIELD_VALID] & 2) { /* EIDE */
+ u16 pio = adev->id[ATA_ID_EIDE_PIO];
+@@ -1900,12 +1955,15 @@
+ int may_fallback = 1, tried_spinup = 0;
+ int rc;
+
++ VPRINTK("\n");
+ if (ata_msg_ctl(ap))
+ ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__);
+
+ ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */
+ retry:
+ ata_tf_init(dev, &tf);
++
++ tf.device |= ATA_LBA ;
+
+ switch (class) {
+ case ATA_DEV_ATA:
+@@ -2043,6 +2101,7 @@
+ static inline u8 ata_dev_knobble(struct ata_device *dev)
+ {
+ struct ata_port *ap = dev->link->ap;
++ VPRINTK("\n");
+ return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id)));
+ }
+
+@@ -2052,6 +2111,7 @@
+ struct ata_port *ap = dev->link->ap;
+ int hdepth = 0, ddepth = ata_id_queue_depth(dev->id);
+
++ VPRINTK("\n");
+ if (!ata_id_has_ncq(dev->id)) {
+ desc[0] = '\0';
+ return;
+@@ -2096,6 +2156,7 @@
+ char modelbuf[ATA_ID_PROD_LEN+1];
+ int rc;
+
++ VPRINTK("\n");
+ if (!ata_dev_enabled(dev) && ata_msg_info(ap)) {
+ ata_dev_printk(dev, KERN_INFO, "%s: ENTER/EXIT -- nodev\n",
+ __FUNCTION__);
+@@ -2334,7 +2395,7 @@
+ }
+
+ if (ap->ops->dev_config)
+- ap->ops->dev_config(dev);
++ ap->ops->dev_config(ap, dev);
+
+ if (ata_msg_probe(ap))
+ ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n",
+@@ -2358,6 +2419,7 @@
+
+ int ata_cable_40wire(struct ata_port *ap)
+ {
++ VPRINTK("\n");
+ return ATA_CBL_PATA40;
+ }
+
+@@ -2371,6 +2433,7 @@
+
+ int ata_cable_80wire(struct ata_port *ap)
+ {
++ VPRINTK("\n");
+ return ATA_CBL_PATA80;
+ }
+
+@@ -2383,6 +2446,7 @@
+
+ int ata_cable_unknown(struct ata_port *ap)
+ {
++ VPRINTK("\n");
+ return ATA_CBL_PATA_UNK;
+ }
+
+@@ -2395,6 +2459,7 @@
+
+ int ata_cable_sata(struct ata_port *ap)
+ {
++ VPRINTK("\n");
+ return ATA_CBL_SATA;
+ }
+
+@@ -2420,6 +2485,7 @@
+ int rc;
+ struct ata_device *dev;
+
++ VPRINTK("\n");
+ ata_port_probe(ap);
+
+ ata_link_for_each_dev(dev, &ap->link)
+@@ -2560,6 +2626,7 @@
+
+ void ata_port_probe(struct ata_port *ap)
+ {
++ VPRINTK("\n");
+ ap->flags &= ~ATA_FLAG_DISABLED;
+ }
+
+@@ -2576,6 +2643,7 @@
+ {
+ u32 sstatus, scontrol, tmp;
+
++ VPRINTK("\n");
+ if (sata_scr_read(link, SCR_STATUS, &sstatus))
+ return;
+ sata_scr_read(link, SCR_CONTROL, &scontrol);
+@@ -2604,6 +2672,7 @@
+ {
+ struct ata_link *link = adev->link;
+ struct ata_device *pair = &link->device[1 - adev->devno];
++ VPRINTK("\n");
+ if (!ata_dev_enabled(pair))
+ return NULL;
+ return pair;
+@@ -2624,6 +2693,7 @@
+
+ void ata_port_disable(struct ata_port *ap)
+ {
++ VPRINTK("\n");
+ ap->link.device[0].class = ATA_DEV_NONE;
+ ap->link.device[1].class = ATA_DEV_NONE;
+ ap->flags |= ATA_FLAG_DISABLED;
+@@ -2648,6 +2718,7 @@
+ u32 sstatus, spd, mask;
+ int rc, highbit;
+
++ VPRINTK("\n");
+ if (!sata_scr_valid(link))
+ return -EOPNOTSUPP;
+
+@@ -2693,6 +2764,7 @@
+ struct ata_link *host_link = &link->ap->link;
+ u32 limit, target, spd;
+
++ VPRINTK("\n");
+ limit = link->sata_spd_limit;
+
+ /* Don't configure downstream link faster than upstream link.
+@@ -2732,6 +2804,7 @@
+ {
+ u32 scontrol;
+
++ VPRINTK("\n");
+ if (sata_scr_read(link, SCR_CONTROL, &scontrol))
+ return 1;
+
+@@ -2756,6 +2829,7 @@
+ u32 scontrol;
+ int rc;
+
++ VPRINTK("\n");
+ if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
+ return rc;
+
+@@ -2822,6 +2896,7 @@
+
+ static void ata_timing_quantize(const struct ata_timing *t, struct ata_timing *q, int T, int UT)
+ {
++ VPRINTK("\n");
+ q->setup = EZ(t->setup * 1000, T);
+ q->act8b = EZ(t->act8b * 1000, T);
+ q->rec8b = EZ(t->rec8b * 1000, T);
+@@ -2835,6 +2910,7 @@
+ void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b,
+ struct ata_timing *m, unsigned int what)
+ {
++ VPRINTK("\n");
+ if (what & ATA_TIMING_SETUP ) m->setup = max(a->setup, b->setup);
+ if (what & ATA_TIMING_ACT8B ) m->act8b = max(a->act8b, b->act8b);
+ if (what & ATA_TIMING_REC8B ) m->rec8b = max(a->rec8b, b->rec8b);
+@@ -2849,6 +2925,7 @@
+ {
+ const struct ata_timing *t;
+
++ VPRINTK("\n");
+ for (t = ata_timing; t->mode != speed; t++)
+ if (t->mode == 0xFF)
+ return NULL;
+@@ -2861,6 +2938,7 @@
+ const struct ata_timing *s;
+ struct ata_timing p;
+
++ VPRINTK("\n");
+ /*
+ * Find the mode.
+ */
+@@ -2948,6 +3026,7 @@
+ unsigned int pio_mask, mwdma_mask, udma_mask;
+ int quiet, highbit;
+
++ VPRINTK("\n");
+ quiet = !!(sel & ATA_DNXFER_QUIET);
+ sel &= ~ATA_DNXFER_QUIET;
+
+@@ -3021,6 +3100,7 @@
+ unsigned int err_mask;
+ int rc;
+
++ VPRINTK("\n");
+ dev->flags &= ~ATA_DFLAG_PIO;
+ if (dev->xfer_shift == ATA_SHIFT_PIO)
+ dev->flags |= ATA_DFLAG_PIO;
+@@ -3087,6 +3167,7 @@
+ struct ata_device *dev;
+ int rc = 0, used_dma = 0, found = 0;
+
++ VPRINTK("\n");
+ /* step 1: calculate xfer_mask */
+ ata_link_for_each_dev(dev, link) {
+ unsigned int pio_mask, dma_mask;
+@@ -3191,6 +3272,7 @@
+ {
+ struct ata_port *ap = link->ap;
+
++ VPRINTK("\n");
+ /* has private set_mode? */
+ if (ap->ops->set_mode)
+ return ap->ops->set_mode(link, r_failed_dev);
+@@ -3213,6 +3295,7 @@
+ static inline void ata_tf_to_host(struct ata_port *ap,
+ const struct ata_taskfile *tf)
+ {
++ VPRINTK("\n");
+ ap->ops->tf_load(ap, tf);
+ ap->ops->exec_command(ap, tf);
+ }
+@@ -3238,6 +3321,7 @@
+ unsigned long timer_start, timeout;
+ u8 status;
+
++ VPRINTK("\n");
+ status = ata_busy_wait(ap, ATA_BUSY, 300);
+ timer_start = jiffies;
+ timeout = timer_start + tmout_pat;
+@@ -3291,6 +3375,7 @@
+ {
+ unsigned long until = jiffies + ATA_TMOUT_FF_WAIT;
+
++ VPRINTK("\n");
+ if (time_before(until, deadline))
+ deadline = until;
+
+@@ -3346,6 +3431,7 @@
+ unsigned long start = jiffies;
+ int warned = 0;
+
++ VPRINTK("\n");
+ while (1) {
+ u8 status = ata_chk_status(ap);
+ unsigned long now = jiffies;
+@@ -3377,6 +3463,7 @@
+ unsigned int dev1 = devmask & (1 << 1);
+ int rc, ret = 0;
+
++ VPRINTK("\n");
+ /* if device 0 was found in ata_devchk, wait for its
+ * BSY bit to clear
+ */
+@@ -3432,19 +3519,36 @@
+ static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
+ unsigned long deadline)
+ {
+- struct ata_ioports *ioaddr = &ap->ioaddr;
++ /* create a task file to control ctl register */
++ struct ata_taskfile tf ;
+
+ DPRINTK("ata%u: bus reset via SRST\n", ap->print_id);
+
++ memset(&tf, 0, sizeof(tf));
++#if 0
+ /* software reset. causes dev0 to be selected */
+- iowrite8(ap->ctl, ioaddr->ctl_addr);
++ tf.ctl = ap->ctl;
++ ap->ops->tf_load(ap,&tf);
+ udelay(20); /* FIXME: flush */
+- iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
++
++ tf.ctl = ap->ctl | ATA_SRST;
++ ap->ops->tf_load(ap,&tf);
+ udelay(20); /* FIXME: flush */
+- iowrite8(ap->ctl, ioaddr->ctl_addr);
++
++ tf.ctl = ap->ctl;
++ ap->ops->tf_load(ap,&tf);
+
+- /* wait a while before checking status */
+- ata_wait_after_reset(ap, deadline);
++ /* spec mandates ">= 2ms" before checking status.
++ * We wait 150ms, because that was the magic delay used for
++ * ATAPI devices in Hale Landis's ATADRVR, for the period of time
++ * between when the ATA command register is written, and then
++ * status is checked. Because waiting for "a while" before
++ * checking status is fine, post SRST, we perform this magic
++ * delay here as well.
++ *
++ * Old drivers/ide uses the 2mS rule and then waits for ready
++ */
++ msleep(150);
+
+ /* Before we perform post reset processing we want to see if
+ * the bus shows 0xFF because the odd clown forgets the D7
+@@ -3452,7 +3556,7 @@
+ */
+ if (ata_chk_status(ap) == 0xFF)
+ return -ENODEV;
+-
++#endif
+ return ata_bus_post_reset(ap, devmask, deadline);
+ }
+
+@@ -3479,7 +3583,6 @@
+ void ata_bus_reset(struct ata_port *ap)
+ {
+ struct ata_device *device = ap->link.device;
+- struct ata_ioports *ioaddr = &ap->ioaddr;
+ unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
+ u8 err;
+ unsigned int dev0, dev1 = 0, devmask = 0;
+@@ -3530,8 +3633,11 @@
+ goto err_out;
+
+ if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) {
++ /** @todo fix by using tf/tf_load as in ata_bus_softreset */
++ #if 0
+ /* set up device control for ATA_FLAG_SATA_RESET */
+ iowrite8(ap->ctl, ioaddr->ctl_addr);
++ #endif
+ }
+
+ DPRINTK("EXIT\n");
+@@ -3575,6 +3681,7 @@
+ u32 last, cur;
+ int rc;
+
++ VPRINTK("\n");
+ t = jiffies + msecs_to_jiffies(params[2]);
+ if (time_before(t, deadline))
+ deadline = t;
+@@ -3633,6 +3740,7 @@
+ u32 scontrol;
+ int rc;
+
++ VPRINTK("\n");
+ if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
+ return rc;
+
+@@ -3673,6 +3781,7 @@
+ const unsigned long *timing = sata_ehc_deb_timing(ehc);
+ int rc;
+
++ VPRINTK("\n");
+ /* handle link resume */
+ if ((ehc->i.flags & ATA_EHI_RESUME_LINK) &&
+ (link->flags & ATA_LFLAG_HRST_TO_RESUME))
+@@ -3939,9 +4048,12 @@
+ return;
+ }
+
++ /** @todo fix by using tf/tf_load as in ata_bus_softreset */
++ #if 0
+ /* set up device control */
+ if (ap->ioaddr.ctl_addr)
+ iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
++ #endif
+
+ DPRINTK("EXIT\n");
+ }
+@@ -3969,6 +4081,7 @@
+ unsigned char model[2][ATA_ID_PROD_LEN + 1];
+ unsigned char serial[2][ATA_ID_SERNO_LEN + 1];
+
++ VPRINTK("\n");
+ if (dev->class != new_class) {
+ ata_dev_printk(dev, KERN_INFO, "class mismatch %d != %d\n",
+ dev->class, new_class);
+@@ -4015,6 +4128,7 @@
+ u16 *id = (void *)dev->link->ap->sector_buf;
+ int rc;
+
++ VPRINTK("\n");
+ /* read ID data */
+ rc = ata_dev_read_id(dev, &class, readid_flags, id);
+ if (rc)
+@@ -4049,6 +4163,7 @@
+ u64 n_sectors = dev->n_sectors;
+ int rc;
+
++ VPRINTK("\n");
+ if (!ata_dev_enabled(dev))
+ return -ENODEV;
+
+@@ -4186,6 +4301,7 @@
+ const char *p;
+ int len;
+
++ VPRINTK("\n");
+ /*
+ * check for trailing wildcard: *\0
+ */
+@@ -4210,6 +4326,7 @@
+ unsigned char model_rev[ATA_ID_FW_REV_LEN + 1];
+ const struct ata_blacklist_entry *ad = ata_device_blacklist;
+
++ VPRINTK("\n");
+ ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
+ ata_id_c_string(dev->id, model_rev, ATA_ID_FW_REV, sizeof(model_rev));
+
+@@ -4227,6 +4344,7 @@
+
+ static int ata_dma_blacklisted(const struct ata_device *dev)
+ {
++ VPRINTK("\n");
+ /* We don't support polling DMA.
+ * DMA blacklist those ATAPI devices with CDB-intr (and use PIO)
+ * if the LLDD handles only interrupts in the HSM_ST_LAST state.
+@@ -4247,6 +4365,7 @@
+
+ static int ata_is_40wire(struct ata_device *dev)
+ {
++ VPRINTK("\n");
+ if (dev->horkage & ATA_HORKAGE_IVB)
+ return ata_drive_40wire_relaxed(dev->id);
+ return ata_drive_40wire(dev->id);
+@@ -4271,6 +4390,7 @@
+ struct ata_host *host = ap->host;
+ unsigned long xfer_mask;
+
++ VPRINTK("\n");
+ /* controller modes available */
+ xfer_mask = ata_pack_xfermask(ap->pio_mask,
+ ap->mwdma_mask, ap->udma_mask);
+@@ -4525,6 +4645,7 @@
+ struct scatterlist *sg;
+ unsigned int idx;
+
++ VPRINTK("\n");
+ WARN_ON(qc->__sg == NULL);
+ WARN_ON(qc->n_elem == 0 && qc->pad_len == 0);
+
+@@ -4579,6 +4700,7 @@
+ struct scatterlist *sg;
+ unsigned int idx;
+
++ VPRINTK("\n");
+ WARN_ON(qc->__sg == NULL);
+ WARN_ON(qc->n_elem == 0 && qc->pad_len == 0);
+
+@@ -4640,6 +4762,7 @@
+ {
+ struct ata_port *ap = qc->ap;
+
++ VPRINTK("\n");
+ /* Don't allow DMA if it isn't multiple of 16 bytes. Quite a
+ * few ATAPI devices choke on such DMA requests.
+ */
+@@ -4669,6 +4792,7 @@
+ */
+ static int atapi_qc_may_overflow(struct ata_queued_cmd *qc)
+ {
++ VPRINTK("\n");
+ if (qc->tf.protocol != ATA_PROT_ATAPI &&
+ qc->tf.protocol != ATA_PROT_ATAPI_DMA)
+ return 0;
+@@ -4708,6 +4832,7 @@
+ {
+ struct ata_link *link = qc->dev->link;
+
++ VPRINTK("\n");
+ if (qc->tf.protocol == ATA_PROT_NCQ) {
+ if (!ata_tag_valid(link->active_tag))
+ return 0;
+@@ -4730,6 +4855,7 @@
+ */
+ void ata_qc_prep(struct ata_queued_cmd *qc)
+ {
++ VPRINTK("\n");
+ if (!(qc->flags & ATA_QCFLAG_DMAMAP))
+ return;
+
+@@ -4747,6 +4873,7 @@
+ */
+ void ata_dumb_qc_prep(struct ata_queued_cmd *qc)
+ {
++ VPRINTK("\n");
+ if (!(qc->flags & ATA_QCFLAG_DMAMAP))
+ return;
+
+@@ -4770,6 +4897,7 @@
+
+ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
+ {
++ VPRINTK("\n");
+ qc->flags |= ATA_QCFLAG_SINGLE;
+
+ qc->__sg = &qc->sgent;
+@@ -4799,6 +4927,7 @@
+ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
+ unsigned int n_elem)
+ {
++ VPRINTK("\n");
+ qc->flags |= ATA_QCFLAG_SG;
+ qc->__sg = sg;
+ qc->n_elem = n_elem;
+@@ -4827,6 +4956,7 @@
+ dma_addr_t dma_address;
+ int trim_sg = 0;
+
++ VPRINTK("\n");
+ /* we must lengthen transfers to end on a 32-bit boundary */
+ qc->pad_len = sg->length & 3;
+ if (qc->pad_len) {
+@@ -5001,6 +5131,7 @@
+ struct ata_port *ap = adev->link->ap;
+ unsigned int words = buflen >> 1;
+
++ VPRINTK("\n");
+ /* Transfer multiple of 2 bytes */
+ if (write_data)
+ iowrite16_rep(ap->ioaddr.data_addr, buf, words);
+@@ -5039,6 +5170,7 @@
+ unsigned int buflen, int write_data)
+ {
+ unsigned long flags;
++ VPRINTK("\n");
+ local_irq_save(flags);
+ ata_data_xfer(adev, buf, buflen, write_data);
+ local_irq_restore(flags);
+@@ -5063,6 +5195,7 @@
+ unsigned int offset;
+ unsigned char *buf;
+
++ VPRINTK("\n");
+ if (qc->curbytes == qc->nbytes - qc->sect_size)
+ ap->hsm_task_state = HSM_ST_LAST;
+
+@@ -5114,6 +5247,7 @@
+
+ static void ata_pio_sectors(struct ata_queued_cmd *qc)
+ {
++ VPRINTK("\n");
+ if (is_multi_taskfile(&qc->tf)) {
+ /* READ/WRITE MULTIPLE */
+ unsigned int nsect;
+@@ -5187,6 +5321,7 @@
+ unsigned char *buf;
+ unsigned int offset, count;
+
++ VPRINTK("\n");
+ next_sg:
+ sg = qc->cursg;
+ if (unlikely(!sg)) {
+@@ -5287,6 +5422,7 @@
+ unsigned int ireason, bc_lo, bc_hi, bytes;
+ int i_write, do_write = (qc->tf.flags & ATA_TFLAG_WRITE) ? 1 : 0;
+
++ VPRINTK("\n");
+ /* Abuse qc->result_tf for temp storage of intermediate TF
+ * here to save some kernel stack usage.
+ * For normal completion, qc->result_tf is not relevant. For
+@@ -5333,6 +5469,7 @@
+
+ static inline int ata_hsm_ok_in_wq(struct ata_port *ap, struct ata_queued_cmd *qc)
+ {
++ VPRINTK("\n");
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ return 1;
+
+@@ -5365,6 +5502,7 @@
+ struct ata_port *ap = qc->ap;
+ unsigned long flags;
+
++ VPRINTK("\n");
+ if (ap->ops->error_handler) {
+ if (in_wq) {
+ spin_lock_irqsave(ap->lock, flags);
+@@ -5415,6 +5553,7 @@
+ unsigned long flags = 0;
+ int poll_next;
+
++ VPRINTK("\n");
+ WARN_ON((qc->flags & ATA_QCFLAG_ACTIVE) == 0);
+
+ /* Make sure ata_qc_issue_prot() does not throw things
+@@ -5649,6 +5788,7 @@
+ u8 status;
+ int poll_next;
+
++ VPRINTK("\n");
+ fsm_start:
+ WARN_ON(ap->hsm_task_state == HSM_ST_IDLE);
+
+@@ -5664,6 +5804,9 @@
+ msleep(2);
+ status = ata_busy_wait(ap, ATA_BUSY, 10);
+ if (status & ATA_BUSY) {
++ if (ap->ops->pio_task)
++ ata_port_queue_task(ap, ap->ops->pio_task, qc, ATA_SHORT_PAUSE);
++ else
+ ata_port_queue_task(ap, ata_pio_task, qc, ATA_SHORT_PAUSE);
+ return;
+ }
+@@ -5693,6 +5836,7 @@
+ struct ata_queued_cmd *qc = NULL;
+ unsigned int i;
+
++ VPRINTK("\n");
+ /* no command while frozen */
+ if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
+ return NULL;
+@@ -5723,7 +5867,14 @@
+ struct ata_port *ap = dev->link->ap;
+ struct ata_queued_cmd *qc;
+
+- qc = ata_qc_new(ap);
++ VPRINTK("\n");
++ /* if a specialised version is not available, call the default */
++ if (ap->ops->qc_new) {
++ qc = ap->ops->qc_new(ap);
++ } else {
++ qc = ata_qc_new(ap);
++ }
++
+ if (qc) {
+ qc->scsicmd = NULL;
+ qc->ap = ap;
+@@ -5750,6 +5901,7 @@
+ struct ata_port *ap = qc->ap;
+ unsigned int tag;
+
++ VPRINTK("\n");
+ WARN_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
+
+ qc->flags = 0;
+@@ -5765,6 +5917,7 @@
+ struct ata_port *ap = qc->ap;
+ struct ata_link *link = qc->dev->link;
+
++ VPRINTK("\n");
+ WARN_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
+ WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE));
+
+@@ -5801,6 +5954,7 @@
+ {
+ struct ata_port *ap = qc->ap;
+
++ VPRINTK("\n");
+ qc->result_tf.flags = qc->tf.flags;
+ ap->ops->tf_read(ap, &qc->result_tf);
+ }
+@@ -5820,6 +5974,7 @@
+ {
+ struct ata_port *ap = qc->ap;
+
++ VPRINTK("\n");
+ /* XXX: New EH and old EH use different mechanisms to
+ * synchronize EH with regular execution path.
+ *
+@@ -5913,6 +6068,7 @@
+ u32 done_mask;
+ int i;
+
++ VPRINTK("\n");
+ done_mask = ap->qc_active ^ qc_active;
+
+ if (unlikely(done_mask & qc_active)) {
+@@ -5942,6 +6098,7 @@
+ {
+ struct ata_port *ap = qc->ap;
+
++ VPRINTK("\n");
+ switch (qc->tf.protocol) {
+ case ATA_PROT_NCQ:
+ case ATA_PROT_DMA:
+@@ -5979,6 +6136,7 @@
+ struct ata_port *ap = qc->ap;
+ struct ata_link *link = qc->dev->link;
+
++ VPRINTK("\n");
+ /* Make sure only one non-NCQ command is outstanding. The
+ * check is skipped for old EH because it reuses active qc to
+ * request ATAPI sense.
+@@ -6057,6 +6215,7 @@
+ {
+ struct ata_port *ap = qc->ap;
+
++ VPRINTK("\n");
+ /* Use polling pio if the LLD doesn't handle
+ * interrupt driven pio and atapi CDB interrupt.
+ */
+@@ -6084,18 +6243,24 @@
+ /* start the command */
+ switch (qc->tf.protocol) {
+ case ATA_PROT_NODATA:
++ VPRINTK("ATA_PROT_NODATA\n");
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ ata_qc_set_polling(qc);
+
+ ata_tf_to_host(ap, &qc->tf);
+ ap->hsm_task_state = HSM_ST_LAST;
+
+- if (qc->tf.flags & ATA_TFLAG_POLLING)
++ if (qc->tf.flags & ATA_TFLAG_POLLING) {
++ if (ap->ops->pio_task)
++ ata_port_queue_task(ap, ap->ops->pio_task, qc, 0);
++ else
+ ata_port_queue_task(ap, ata_pio_task, qc, 0);
++ }
+
+ break;
+
+ case ATA_PROT_DMA:
++ VPRINTK("ATA_PROT_DMA\n");
+ WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
+
+ ap->ops->tf_load(ap, &qc->tf); /* load tf registers */
+@@ -6105,6 +6270,7 @@
+ break;
+
+ case ATA_PROT_PIO:
++ VPRINTK("ATA_PROT_PIO\n");
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ ata_qc_set_polling(qc);
+
+@@ -6113,6 +6279,9 @@
+ if (qc->tf.flags & ATA_TFLAG_WRITE) {
+ /* PIO data out protocol */
+ ap->hsm_task_state = HSM_ST_FIRST;
++ if (ap->ops->pio_task)
++ ata_port_queue_task(ap, ap->ops->pio_task, qc, 0);
++ else
+ ata_port_queue_task(ap, ata_pio_task, qc, 0);
+
+ /* always send first data block using
+@@ -6122,8 +6291,12 @@
+ /* PIO data in protocol */
+ ap->hsm_task_state = HSM_ST;
+
+- if (qc->tf.flags & ATA_TFLAG_POLLING)
++ if (qc->tf.flags & ATA_TFLAG_POLLING) {
++ if (ap->ops->pio_task)
++ ata_port_queue_task(ap, ap->ops->pio_task, qc, 0);
++ else
+ ata_port_queue_task(ap, ata_pio_task, qc, 0);
++ }
+
+ /* if polling, ata_pio_task() handles the rest.
+ * otherwise, interrupt handler takes over from here.
+@@ -6134,6 +6307,7 @@
+
+ case ATA_PROT_ATAPI:
+ case ATA_PROT_ATAPI_NODATA:
++ VPRINTK("ATA_PROT_ATAPI / ATA_PROT_ATAPI_NODATA\n");
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ ata_qc_set_polling(qc);
+
+@@ -6143,11 +6317,16 @@
+
+ /* send cdb by polling if no cdb interrupt */
+ if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) ||
+- (qc->tf.flags & ATA_TFLAG_POLLING))
++ (qc->tf.flags & ATA_TFLAG_POLLING)) {
++ if (ap->ops->pio_task)
++ ata_port_queue_task(ap, ap->ops->pio_task, qc, 0);
++ else
+ ata_port_queue_task(ap, ata_pio_task, qc, 0);
++ }
+ break;
+
+ case ATA_PROT_ATAPI_DMA:
++ VPRINTK("ATA_PROT_ATAPI_DMA\n");
+ WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
+
+ ap->ops->tf_load(ap, &qc->tf); /* load tf registers */
+@@ -6155,8 +6334,12 @@
+ ap->hsm_task_state = HSM_ST_FIRST;
+
+ /* send cdb by polling if no cdb interrupt */
+- if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
++ if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) {
++ if (ap->ops->pio_task)
++ ata_port_queue_task(ap, ap->ops->pio_task, qc, 0);
++ else
+ ata_port_queue_task(ap, ata_pio_task, qc, 0);
++ }
+ break;
+
+ default:
+@@ -6291,6 +6474,7 @@
+ unsigned int handled = 0;
+ unsigned long flags;
+
++ VPRINTK("\n");
+ /* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */
+ spin_lock_irqsave(&host->lock, flags);
+
+@@ -6330,6 +6514,7 @@
+ {
+ struct ata_port *ap = link->ap;
+
++ VPRINTK("\n");
+ return (ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read;
+ }
+
+@@ -6351,6 +6536,7 @@
+ */
+ int sata_scr_read(struct ata_link *link, int reg, u32 *val)
+ {
++ VPRINTK("\n");
+ if (ata_is_host_link(link)) {
+ struct ata_port *ap = link->ap;
+
+@@ -6380,6 +6566,7 @@
+ */
+ int sata_scr_write(struct ata_link *link, int reg, u32 val)
+ {
++ VPRINTK("\n");
+ if (ata_is_host_link(link)) {
+ struct ata_port *ap = link->ap;
+
+@@ -6408,6 +6595,7 @@
+ */
+ int sata_scr_write_flush(struct ata_link *link, int reg, u32 val)
+ {
++ VPRINTK("\n");
+ if (ata_is_host_link(link)) {
+ struct ata_port *ap = link->ap;
+ int rc;
+@@ -6442,6 +6630,7 @@
+ {
+ u32 sstatus;
+
++ VPRINTK("\n");
+ if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 &&
+ (sstatus & 0xf) == 0x3)
+ return 1;
+@@ -6466,6 +6655,7 @@
+ {
+ u32 sstatus;
+
++ VPRINTK("\n");
+ if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 &&
+ (sstatus & 0xf) != 0x3)
+ return 1;
+@@ -6477,6 +6667,7 @@
+ unsigned int err_mask;
+ u8 cmd;
+
++ VPRINTK("\n");
+ if (!ata_try_flush_cache(dev))
+ return 0;
+
+@@ -6506,6 +6697,7 @@
+ unsigned long flags;
+ int i, rc;
+
++ VPRINTK("\n");
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+ struct ata_link *link;
+@@ -6568,6 +6760,7 @@
+ {
+ int rc;
+
++ VPRINTK("\n");
+ /*
+ * disable link pm on all ports before requesting
+ * any pm activity
+@@ -6593,6 +6786,7 @@
+ */
+ void ata_host_resume(struct ata_host *host)
+ {
++ VPRINTK("\n");
+ ata_host_request_pm(host, PMSG_ON, ATA_EH_SOFTRESET,
+ ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0);
+ host->dev->power.power_state = PMSG_ON;
+@@ -6619,6 +6813,7 @@
+ struct device *dev = ap->dev;
+ int rc;
+
++ VPRINTK("\n");
+ ap->prd = dmam_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma,
+ GFP_KERNEL);
+ if (!ap->prd)
+@@ -6648,6 +6843,7 @@
+ struct ata_port *ap = link->ap;
+ unsigned long flags;
+
++ VPRINTK("\n");
+ /* SATA spd limit is bound to the first device */
+ link->sata_spd_limit = link->hw_sata_spd_limit;
+ link->sata_spd = 0;
+@@ -6683,6 +6879,7 @@
+ {
+ int i;
+
++ VPRINTK("\n");
+ /* clear everything except for devices */
+ memset(link, 0, offsetof(struct ata_link, device[0]));
+
+@@ -6719,6 +6916,7 @@
+ u32 scontrol, spd;
+ int rc;
+
++ VPRINTK("\n");
+ rc = sata_scr_read(link, SCR_CONTROL, &scontrol);
+ if (rc)
+ return rc;
+@@ -6797,6 +6995,7 @@
+ struct ata_host *host = dev_get_drvdata(gendev);
+ int i;
+
++ VPRINTK("\n");
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+
+@@ -6903,6 +7102,7 @@
+ struct ata_host *host;
+ int i, j;
+
++ VPRINTK("\n");
+ host = ata_host_alloc(dev, n_ports);
+ if (!host)
+ return NULL;
+@@ -6934,6 +7134,7 @@
+ struct ata_host *host = dev_get_drvdata(gendev);
+ int i;
+
++ VPRINTK("\n");
+ WARN_ON(!(host->flags & ATA_HOST_STARTED));
+
+ for (i = 0; i < host->n_ports; i++) {
+@@ -6969,6 +7170,8 @@
+ void *start_dr = NULL;
+ int i, rc;
+
++ VPRINTK("\n");
++
+ if (host->flags & ATA_HOST_STARTED)
+ return 0;
+
+@@ -7007,6 +7210,7 @@
+ ata_eh_freeze_port(ap);
+ }
+
++
+ if (start_dr)
+ devres_add(host->dev, start_dr);
+ host->flags |= ATA_HOST_STARTED;
+@@ -7038,6 +7242,7 @@
+ void ata_host_init(struct ata_host *host, struct device *dev,
+ unsigned long flags, const struct ata_port_operations *ops)
+ {
++ VPRINTK("\n");
+ spin_lock_init(&host->lock);
+ host->dev = dev;
+ host->flags = flags;
+@@ -7064,6 +7269,7 @@
+ {
+ int i, rc;
+
++ VPRINTK("\n");
+ /* host must have been started */
+ if (!(host->flags & ATA_HOST_STARTED)) {
+ dev_printk(KERN_ERR, host->dev,
+@@ -7203,6 +7409,7 @@
+ {
+ int i, rc;
+
++ VPRINTK("\n");
+ rc = ata_host_start(host);
+ if (rc)
+ return rc;
+@@ -7246,6 +7453,7 @@
+ struct ata_link *link;
+ struct ata_device *dev;
+
++ VPRINTK("\n");
+ if (!ap->ops->error_handler)
+ goto skip_eh;
+
+@@ -7293,6 +7501,7 @@
+ {
+ int i;
+
++ VPRINTK("\n");
+ for (i = 0; i < host->n_ports; i++)
+ ata_port_detach(host->ports[i]);
+
+@@ -7314,6 +7523,7 @@
+
+ void ata_std_ports(struct ata_ioports *ioaddr)
+ {
++ VPRINTK("\n");
+ ioaddr->data_addr = ioaddr->cmd_addr + ATA_REG_DATA;
+ ioaddr->error_addr = ioaddr->cmd_addr + ATA_REG_ERR;
+ ioaddr->feature_addr = ioaddr->cmd_addr + ATA_REG_FEATURE;
+@@ -7345,6 +7555,7 @@
+ struct device *dev = &pdev->dev;
+ struct ata_host *host = dev_get_drvdata(dev);
+
++ VPRINTK("\n");
+ ata_host_detach(host);
+ }
+
+@@ -7353,6 +7564,7 @@
+ {
+ unsigned long tmp = 0;
+
++ VPRINTK("\n");
+ switch (bits->width) {
+ case 1: {
+ u8 tmp8 = 0;
+@@ -7385,6 +7597,7 @@
+ #ifdef CONFIG_PM
+ void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg)
+ {
++ VPRINTK("\n");
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
+
+@@ -7396,6 +7609,7 @@
+ {
+ int rc;
+
++ VPRINTK("\n");
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+
+@@ -7415,6 +7629,7 @@
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ int rc = 0;
+
++ VPRINTK("\n");
+ rc = ata_host_suspend(host, mesg);
+ if (rc)
+ return rc;
+@@ -7429,6 +7644,7 @@
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ int rc;
+
++ VPRINTK("\n");
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc == 0)
+ ata_host_resume(host);
+@@ -7442,6 +7658,7 @@
+ static int __init ata_init(void)
+ {
+ ata_probe_timeout *= HZ;
++ VPRINTK("\n");
+ ata_wq = create_workqueue("ata");
+ if (!ata_wq)
+ return -ENOMEM;
+@@ -7458,6 +7675,7 @@
+
+ static void __exit ata_exit(void)
+ {
++ VPRINTK("\n");
+ destroy_workqueue(ata_wq);
+ destroy_workqueue(ata_aux_wq);
+ }
+@@ -7473,6 +7691,7 @@
+ int rc;
+ unsigned long flags;
+
++ VPRINTK("\n");
+ spin_lock_irqsave(&ata_ratelimit_lock, flags);
+
+ if (time_after(jiffies, ratelimit_time)) {
+@@ -7516,6 +7735,7 @@
+ unsigned long timeout;
+ u32 tmp;
+
++ VPRINTK("\n");
+ tmp = ioread32(reg);
+
+ /* Calculate timeout _after_ the first read to make sure
+@@ -7541,11 +7761,13 @@
+
+ static u8 ata_dummy_check_status(struct ata_port *ap)
+ {
++ VPRINTK("\n");
+ return ATA_DRDY;
+ }
+
+ static unsigned int ata_dummy_qc_issue(struct ata_queued_cmd *qc)
+ {
++ VPRINTK("\n");
+ return AC_ERR_SYSTEM;
+ }
+
+diff -Nurd linux-2.6.24/drivers/ata/libata-eh.c linux-2.6.24-oxe810/drivers/ata/libata-eh.c
+--- linux-2.6.24/drivers/ata/libata-eh.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/ata/libata-eh.c 2008-06-11 17:50:32.000000000 +0200
+@@ -89,6 +89,8 @@
+ static void __ata_ehi_pushv_desc(struct ata_eh_info *ehi, const char *fmt,
+ va_list args)
+ {
++ VPRINTK("\n");
++
+ ehi->desc_len += vscnprintf(ehi->desc + ehi->desc_len,
+ ATA_EH_DESC_LEN - ehi->desc_len,
+ fmt, args);
+@@ -108,6 +110,8 @@
+ {
+ va_list args;
+
++ VPRINTK("\n");
++
+ va_start(args, fmt);
+ __ata_ehi_pushv_desc(ehi, fmt, args);
+ va_end(args);
+@@ -128,6 +132,8 @@
+ {
+ va_list args;
+
++ VPRINTK("\n");
++
+ if (ehi->desc_len)
+ __ata_ehi_push_desc(ehi, ", ");
+
+@@ -147,6 +153,8 @@
+ */
+ void ata_ehi_clear_desc(struct ata_eh_info *ehi)
+ {
++ VPRINTK("\n");
++
+ ehi->desc[0] = '\0';
+ ehi->desc_len = 0;
+ }
+@@ -168,6 +176,8 @@
+ {
+ va_list args;
+
++ VPRINTK("\n");
++
+ WARN_ON(!(ap->pflags & ATA_PFLAG_INITIALIZING));
+
+ if (ap->link.eh_info.desc_len)
+@@ -202,6 +212,8 @@
+ char *type = "";
+ unsigned long long start, len;
+
++ VPRINTK("\n");
++
+ if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM)
+ type = "m";
+ else if (pci_resource_flags(pdev, bar) & IORESOURCE_IO)
+@@ -223,6 +235,8 @@
+ {
+ struct ata_ering_entry *ent;
+
++ VPRINTK("\n");
++
+ WARN_ON(!err_mask);
+
+ ering->cursor++;
+@@ -236,6 +250,8 @@
+
+ static void ata_ering_clear(struct ata_ering *ering)
+ {
++ VPRINTK("\n");
++
+ memset(ering, 0, sizeof(*ering));
+ }
+
+@@ -246,6 +262,8 @@
+ int idx, rc = 0;
+ struct ata_ering_entry *ent;
+
++ VPRINTK("\n");
++
+ idx = ering->cursor;
+ do {
+ ent = &ering->ring[idx];
+@@ -264,6 +282,8 @@
+ {
+ struct ata_eh_context *ehc = &dev->link->eh_context;
+
++ VPRINTK("\n");
++
+ return ehc->i.action | ehc->i.dev_action[dev->devno];
+ }
+
+@@ -272,6 +292,8 @@
+ {
+ struct ata_device *tdev;
+
++ VPRINTK("\n");
++
+ if (!dev) {
+ ehi->action &= ~action;
+ ata_link_for_each_dev(tdev, link)
+@@ -537,8 +559,11 @@
+ void ata_port_wait_eh(struct ata_port *ap)
+ {
+ unsigned long flags;
++
+ DEFINE_WAIT(wait);
+
++ VPRINTK("\n");
++
+ retry:
+ spin_lock_irqsave(ap->lock, flags);
+
+@@ -564,6 +589,8 @@
+ unsigned int tag;
+ int nr = 0;
+
++ VPRINTK("\n");
++
+ /* count only non-internal commands */
+ for (tag = 0; tag < ATA_MAX_QUEUE - 1; tag++)
+ if (ata_qc_from_tag(ap, tag))
+@@ -578,6 +605,8 @@
+ unsigned long flags;
+ int cnt;
+
++ VPRINTK("\n");
++
+ spin_lock_irqsave(ap->lock, flags);
+
+ cnt = ata_eh_nr_in_flight(ap);
+@@ -627,6 +656,8 @@
+ {
+ int cnt;
+
++ VPRINTK("\n");
++
+ /* already scheduled? */
+ if (ap->pflags & ATA_PFLAG_EH_PENDING)
+ return;
+@@ -661,6 +692,8 @@
+ {
+ struct ata_port *ap = qc->ap;
+
++ VPRINTK("\n");
++
+ WARN_ON(!ap->ops->error_handler);
+
+ qc->flags |= ATA_QCFLAG_FAILED;
+@@ -686,6 +719,8 @@
+ */
+ void ata_port_schedule_eh(struct ata_port *ap)
+ {
++ VPRINTK("\n");
++
+ WARN_ON(!ap->ops->error_handler);
+
+ if (ap->pflags & ATA_PFLAG_INITIALIZING)
+@@ -701,6 +736,8 @@
+ {
+ int tag, nr_aborted = 0;
+
++ VPRINTK("\n");
++
+ WARN_ON(!ap->ops->error_handler);
+
+ /* we're gonna abort all commands, no need for fast drain */
+@@ -736,6 +773,8 @@
+ */
+ int ata_link_abort(struct ata_link *link)
+ {
++ VPRINTK("\n");
++
+ return ata_do_link_abort(link->ap, link);
+ }
+
+@@ -753,6 +792,8 @@
+ */
+ int ata_port_abort(struct ata_port *ap)
+ {
++ VPRINTK("\n");
++
+ return ata_do_link_abort(ap, NULL);
+ }
+
+@@ -776,6 +817,8 @@
+ */
+ static void __ata_port_freeze(struct ata_port *ap)
+ {
++ VPRINTK("\n");
++
+ WARN_ON(!ap->ops->error_handler);
+
+ if (ap->ops->freeze)
+@@ -802,6 +845,8 @@
+ {
+ int nr_aborted;
+
++ VPRINTK("\n");
++
+ WARN_ON(!ap->ops->error_handler);
+
+ nr_aborted = ata_port_abort(ap);
+@@ -828,6 +873,8 @@
+ u32 sntf;
+ int rc;
+
++ VPRINTK("\n");
++
+ if (!(ap->flags & ATA_FLAG_AN))
+ return 0;
+
+@@ -896,6 +943,8 @@
+ {
+ unsigned long flags;
+
++ VPRINTK("\n");
++
+ if (!ap->ops->error_handler)
+ return;
+
+@@ -917,6 +966,8 @@
+ {
+ unsigned long flags;
+
++ VPRINTK("\n");
++
+ if (!ap->ops->error_handler)
+ return;
+
+@@ -943,6 +994,8 @@
+ struct scsi_cmnd *scmd = qc->scsicmd;
+ unsigned long flags;
+
++ VPRINTK("\n");
++
+ spin_lock_irqsave(ap->lock, flags);
+ qc->scsidone = ata_eh_scsidone;
+ __ata_qc_complete(qc);
+@@ -962,6 +1015,8 @@
+ void ata_eh_qc_complete(struct ata_queued_cmd *qc)
+ {
+ struct scsi_cmnd *scmd = qc->scsicmd;
++ VPRINTK("\n");
++
+ scmd->retries = scmd->allowed;
+ __ata_eh_qc_complete(qc);
+ }
+@@ -980,6 +1035,8 @@
+ void ata_eh_qc_retry(struct ata_queued_cmd *qc)
+ {
+ struct scsi_cmnd *scmd = qc->scsicmd;
++ VPRINTK("\n");
++
+ if (!qc->err_mask && scmd->retries)
+ scmd->retries--;
+ __ata_eh_qc_complete(qc);
+@@ -1000,6 +1057,8 @@
+ struct ata_port *ap = link->ap;
+ unsigned long flags;
+
++ VPRINTK("\n");
++
+ ata_dev_disable(dev);
+
+ spin_lock_irqsave(ap->lock, flags);
+@@ -1039,6 +1098,8 @@
+ struct ata_eh_context *ehc = &link->eh_context;
+ unsigned long flags;
+
++ VPRINTK("\n");
++
+ spin_lock_irqsave(ap->lock, flags);
+
+ /* Reset is represented by combination of actions and EHI
+@@ -1079,6 +1140,8 @@
+ {
+ struct ata_eh_context *ehc = &link->eh_context;
+
++ VPRINTK("\n");
++
+ /* if reset is complete, clear all reset actions & reset modifier */
+ if (action & ATA_EH_RESET_MASK) {
+ action |= ATA_EH_RESET_MASK;
+@@ -1104,6 +1167,8 @@
+ */
+ static const char *ata_err_string(unsigned int err_mask)
+ {
++ VPRINTK("\n");
++
+ if (err_mask & AC_ERR_HOST_BUS)
+ return "host bus error";
+ if (err_mask & AC_ERR_ATA_BUS)
+@@ -1184,6 +1249,8 @@
+ u8 csum;
+ int i;
+
++ VPRINTK("\n");
++
+ err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, buf, 1);
+ if (err_mask)
+ return -EIO;
+@@ -1289,6 +1356,8 @@
+ unsigned int err_mask = 0, action = 0;
+ u32 hotplug_mask;
+
++ VPRINTK("\n");
++
+ if (serror & SERR_PERSISTENT) {
+ err_mask |= AC_ERR_ATA_BUS;
+ action |= ATA_EH_HARDRESET;
+@@ -1347,6 +1416,8 @@
+ struct ata_taskfile tf;
+ int tag, rc;
+
++ VPRINTK("\n");
++
+ /* if frozen, we can't do much */
+ if (ap->pflags & ATA_PFLAG_FROZEN)
+ return;
+@@ -1408,6 +1479,8 @@
+ unsigned int tmp, action = 0;
+ u8 stat = tf->command, err = tf->feature;
+
++ VPRINTK("\n");
++
+ if ((stat & (ATA_BUSY | ATA_DRQ | ATA_DRDY)) != ATA_DRDY) {
+ qc->err_mask |= AC_ERR_HSM;
+ return ATA_EH_SOFTRESET;
+@@ -1453,6 +1526,8 @@
+
+ static int ata_eh_categorize_error(int is_io, unsigned int err_mask)
+ {
++ VPRINTK("\n");
++
+ if (err_mask & AC_ERR_ATA_BUS)
+ return 1;
+
+@@ -1480,6 +1555,8 @@
+ struct speed_down_verdict_arg *arg = void_arg;
+ int cat = ata_eh_categorize_error(ent->is_io, ent->err_mask);
+
++ VPRINTK("\n");
++
+ if (ent->timestamp < arg->since)
+ return -1;
+
+@@ -1525,6 +1602,8 @@
+ struct speed_down_verdict_arg arg;
+ unsigned int verdict = 0;
+
++ VPRINTK("\n");
++
+ /* scan past 10 mins of error history */
+ memset(&arg, 0, sizeof(arg));
+ arg.since = j64 - min(j64, j10mins);
+@@ -1569,6 +1648,8 @@
+ unsigned int verdict;
+ unsigned int action = 0;
+
++ VPRINTK("\n");
++
+ /* don't bother if Cat-0 error */
+ if (ata_eh_categorize_error(is_io, err_mask) == 0)
+ return 0;
+@@ -1763,6 +1844,8 @@
+ {
+ struct ata_link *link;
+
++ VPRINTK("\n");
++
+ ata_port_for_each_link(link, ap)
+ ata_eh_link_autopsy(link);
+
+@@ -1790,6 +1873,8 @@
+ char tries_buf[6];
+ int tag, nr_failed = 0;
+
++ VPRINTK("\n");
++
+ if (ehc->i.flags & ATA_EHI_QUIET)
+ return;
+
+@@ -1954,6 +2039,8 @@
+ {
+ struct ata_link *link;
+
++ VPRINTK("\n");
++
+ __ata_port_for_each_link(link, ap)
+ ata_eh_link_report(link);
+ }
+@@ -1964,6 +2051,8 @@
+ struct ata_device *dev;
+ int rc;
+
++ VPRINTK("\n");
++
+ ata_link_for_each_dev(dev, link)
+ classes[dev->devno] = ATA_DEV_UNKNOWN;
+
+@@ -1993,6 +2082,8 @@
+ int rc, int classify,
+ const unsigned int *classes)
+ {
++ VPRINTK("\n");
++
+ if (link->flags & ATA_LFLAG_NO_SRST)
+ return 0;
+ if (rc == -EAGAIN)
+@@ -2026,6 +2117,8 @@
+ u32 sstatus;
+ int rc;
+
++ VPRINTK("\n");
++
+ /* about to reset */
+ spin_lock_irqsave(ap->lock, flags);
+ ap->pflags |= ATA_PFLAG_RESETTING;
+@@ -2334,6 +2427,8 @@
+ struct ata_device *dev;
+ int cnt = 0;
+
++ VPRINTK("\n");
++
+ ata_link_for_each_dev(dev, link)
+ if (ata_dev_enabled(dev))
+ cnt++;
+@@ -2345,6 +2440,8 @@
+ struct ata_device *dev;
+ int cnt = 0;
+
++ VPRINTK("\n");
++
+ ata_link_for_each_dev(dev, link)
+ if (dev->class == ATA_DEV_UNKNOWN)
+ cnt++;
+@@ -2356,6 +2453,8 @@
+ struct ata_eh_context *ehc = &link->eh_context;
+ struct ata_device *dev;
+
++ VPRINTK("\n");
++
+ /* skip disabled links */
+ if (link->flags & ATA_LFLAG_DISABLED)
+ return 1;
+@@ -2379,6 +2478,8 @@
+ {
+ struct ata_eh_context *ehc = &dev->link->eh_context;
+
++ VPRINTK("\n");
++
+ ehc->tries[dev->devno]--;
+
+ switch (err) {
+@@ -2638,6 +2739,8 @@
+ {
+ int tag;
+
++ VPRINTK("\n");
++
+ /* retry or finish qcs */
+ for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
+ struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag);
+@@ -2697,6 +2800,8 @@
+ struct ata_device *dev;
+ int rc;
+
++ VPRINTK("\n");
++
+ ata_eh_autopsy(ap);
+ ata_eh_report(ap);
+
+@@ -2725,6 +2830,8 @@
+ unsigned long flags;
+ int rc = 0;
+
++ VPRINTK("\n");
++
+ /* are we suspending? */
+ spin_lock_irqsave(ap->lock, flags);
+ if (!(ap->pflags & ATA_PFLAG_PM_PENDING) ||
+@@ -2781,6 +2888,8 @@
+ unsigned long flags;
+ int rc = 0;
+
++ VPRINTK("\n");
++
+ /* are we resuming? */
+ spin_lock_irqsave(ap->lock, flags);
+ if (!(ap->pflags & ATA_PFLAG_PM_PENDING) ||
+diff -Nurd linux-2.6.24/drivers/ata/libata-scsi.c linux-2.6.24-oxe810/drivers/ata/libata-scsi.c
+--- linux-2.6.24/drivers/ata/libata-scsi.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/ata/libata-scsi.c 2008-06-11 17:50:32.000000000 +0200
+@@ -1477,7 +1477,10 @@
+
+ qc->scsidone(cmd);
+
+- ata_qc_free(qc);
++ if (ap->ops->qc_free)
++ ap->ops->qc_free(qc);
++ else
++ ata_qc_free(qc);
+ }
+
+ /**
+@@ -1552,13 +1555,19 @@
+ return 0;
+
+ early_finish:
+- ata_qc_free(qc);
++ if (qc->ap->ops->qc_free)
++ qc->ap->ops->qc_free(qc);
++ else
++ ata_qc_free(qc);
+ qc->scsidone(cmd);
+ DPRINTK("EXIT - early finish (good or error)\n");
+ return 0;
+
+ err_did:
+- ata_qc_free(qc);
++ if (qc->ap->ops->qc_free)
++ qc->ap->ops->qc_free(qc);
++ else
++ ata_qc_free(qc);
+ cmd->result = (DID_ERROR << 16);
+ qc->scsidone(cmd);
+ err_mem:
+@@ -1566,7 +1575,10 @@
+ return 0;
+
+ defer:
+- ata_qc_free(qc);
++ if (qc->ap->ops->qc_free)
++ qc->ap->ops->qc_free(qc);
++ else
++ ata_qc_free(qc);
+ DPRINTK("EXIT - defer\n");
+ if (rc == ATA_DEFER_LINK)
+ return SCSI_MLQUEUE_DEVICE_BUSY;
+@@ -2314,7 +2326,10 @@
+ }
+
+ qc->scsidone(qc->scsicmd);
+- ata_qc_free(qc);
++ if (qc->ap->ops->qc_free)
++ qc->ap->ops->qc_free(qc);
++ else
++ ata_qc_free(qc);
+ }
+
+ /* is it pointless to prefer PIO for "safety reasons"? */
+@@ -2403,7 +2418,10 @@
+
+ qc->scsicmd->result = SAM_STAT_CHECK_CONDITION;
+ qc->scsidone(cmd);
+- ata_qc_free(qc);
++ if (qc->ap->ops->qc_free)
++ qc->ap->ops->qc_free(qc);
++ else
++ ata_qc_free(qc);
+ return;
+ }
+
+@@ -2448,7 +2466,10 @@
+ }
+
+ qc->scsidone(cmd);
+- ata_qc_free(qc);
++ if (qc->ap->ops->qc_free)
++ qc->ap->ops->qc_free(qc);
++ else
++ ata_qc_free(qc);
+ }
+ /**
+ * atapi_xlat - Initialize PACKET taskfile
+@@ -2694,6 +2715,12 @@
+ if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0)
+ goto invalid_fld;
+
++ /** @NOTE: OX800/OX810 driver needs polling for PIO and no data commands */
++ if ((tf->protocol == ATA_PROT_PIO) ||
++ (tf->protocol == ATA_PROT_NODATA)) {
++ tf->flags |= ATA_TFLAG_POLLING;
++ }
++
+ /*
+ * 12 and 16 byte CDBs use different offsets to
+ * provide the various register values.
+diff -Nurd linux-2.6.24/drivers/ata/ox800sata.c linux-2.6.24-oxe810/drivers/ata/ox800sata.c
+--- linux-2.6.24/drivers/ata/ox800sata.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/ata/ox800sata.c 2008-06-11 17:50:32.000000000 +0200
+@@ -0,0 +1,2184 @@
++/**************************************************************************
++ *
++ * Copyright (c) 2004 Oxford Semiconductor Ltd.
++ *
++ * 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, 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.
++ *
++ * Module Name:
++ * ox800sata.c
++ *
++ * Abstract:
++ * A driver to interface the 924 based sata core present in the ox800
++ * with libata and scsi
++ */
++
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/device.h>
++#include <linux/string.h>
++#include <linux/sysdev.h>
++#include <linux/module.h>
++#include <linux/leds.h>
++
++#include <scsi/scsi_host.h>
++#include <scsi/scsi_cmnd.h>
++#include <scsi/scsi_device.h>
++#include <asm/io.h>
++
++#include <asm/arch/hardware.h>
++#include <asm/arch/dma.h>
++#include <asm/arch/memory.h>
++#include <asm/arch/sata.h>
++#include <linux/platform_device.h>
++
++/***************************************************************************
++* DEBUG CONTROL
++***************************************************************************/
++//#define SATA_DEBUG
++//#define SATA_DUMP_REGS
++//#define SATA_TF_DUMP
++//#define CRAZY_DUMP_DEBUG
++
++#if 0
++ #ifdef writel
++ #undef writel
++ #endif
++ #define writel(v,a) {printk("[%p]<=%08x\n",a,v);*((volatile u32*)(a)) = v;}
++#endif
++
++#if 0
++ #ifdef readl
++ #undef readl
++ #endif
++ static inline u32 myreadl(u32 a) {u32 v =(*((volatile u32*)(a)));printk("[%p]=>%08x\n",a,v);return v;}
++ #define readl(a) (myreadl(a))
++#endif
++
++
++#include <linux/libata.h>
++/***************************************************************************
++* CONSTANTS
++***************************************************************************/
++
++#define DRIVER_AUTHOR "Oxford Semiconductor Ltd."
++#define DRIVER_DESC "924 SATA core controler"
++#define DRIVER_NAME "oxnassata"
++
++#define SATA_ABORT_WAIT_MS 5000
++#define SATA_SRST_WAIT_MS 5000
++
++/**************************************************************************
++* PROTOTYPES
++**************************************************************************/
++static int ox800sata_init_one(struct platform_device *);
++static int ox800sata_remove_one(struct platform_device *);
++
++static void ox800sata_port_disable(struct ata_port *);
++static void ox800sata_dev_config(struct ata_device *);
++static void ox800sata_set_piomode(struct ata_port *, struct ata_device *);
++static void ox800sata_set_dmamode(struct ata_port *, struct ata_device *);
++static void ox800sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf);
++static void ox800sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
++static void ox800sata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
++static u8 ox800sata_check_status(struct ata_port *ap);
++static u8 ox800sata_check_altstatus(struct ata_port *ap);
++static void ox800sata_dev_select(struct ata_port *ap, unsigned int device);
++static void ox800sata_phy_reset(struct ata_port *ap);
++static void ox800sata_bmdma_setup(struct ata_queued_cmd *qc);
++static void ox800sata_bmdma_start(struct ata_queued_cmd *qc);
++static u8 ox800sata_bmdma_status(struct ata_port *ap);
++static struct ata_queued_cmd* ox800sata_qc_new(struct ata_port *ap);
++static void ox800sata_qc_free(struct ata_queued_cmd *qc);
++static unsigned int ox800sata_qc_issue(struct ata_queued_cmd *qc);
++static void ox800sata_eng_timeout(struct ata_port *ap);
++static irqreturn_t ox800sata_irq_handler(int, void *);
++static void ox800sata_eng_timeout(struct ata_port *ap);
++static void ox800sata_irq_clear(struct ata_port *);
++static int ox800sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
++static int ox800sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
++static int ox800sata_port_start(struct ata_port *ap);
++static void ox800sata_port_stop(struct ata_port *ap);
++static void ox800sata_host_stop(struct ata_host *host_set);
++static unsigned int ox800sata_devchk(struct ata_port *ap,unsigned int device);
++static u32* ox800sata_get_io_base(struct ata_port* ap);
++static u32* ox800sata_get_bbp_base(void);
++static u8 ox800sata_irq_ack(struct ata_port *ap, unsigned int chk_drq);
++static u8 ox800sata_irq_on(struct ata_port *ap);
++static void ox800sata_bmdma_stop(struct ata_queued_cmd *qc);
++static void CrazyDumpDebug(struct ata_port *ap);
++static void ox800sata_spot_the_end(struct work_struct *work);
++static void ox800sata_timeout_cleanup( struct ata_port *ap );
++static void ox800sata_reset_core( void );
++static void ox800sata_pio_start(struct work_struct *work);
++static void ox800sata_pio_task(struct work_struct *work);
++static void ox800sata_post_reset_init(struct ata_port* ap);
++static u32 __ox800sata_scr_read(u32* core_addr, unsigned int sc_reg);
++static void __ox800sata_scr_write(u32* core_addr, unsigned int sc_reg, u32 val);
++
++/**************************************************************************
++* STRUCTURES
++**************************************************************************/
++typedef struct
++{
++ struct platform_driver driver;
++ struct ata_port* ap[2];
++ struct workqueue_struct* spot_the_end_q;
++} ox800sata_driver_t;
++
++/**
++ * Struct to hold private (specific to this driver) data for each queued
++ * command, all queued commands will point to a per-port private data
++ * structure. This is a completely unresearched decision that will surely
++ * cause some untracable bug in the future.
++ */
++typedef struct
++{
++ oxnas_dma_channel_t* DmaChannel;
++ oxnas_dma_sg_entry_t* sg_entries;
++ struct spot_the_end_work_s {
++ struct work_struct worker;
++ struct ata_port* ap;
++ } spot_the_end_work;
++ int port_disabled;
++ u32 ErrorsWithNoCommamnd;
++ u32 int_status;
++ u32 in_cleanup;
++} ox800sata_private_data;
++
++ox800sata_driver_t ox800sata_driver =
++{
++ .driver =
++ {
++ .driver.name = DRIVER_NAME,
++ .driver.bus = &platform_bus_type,
++ .probe = ox800sata_init_one,
++ .remove = ox800sata_remove_one,
++ },
++ .ap = {0,0},
++};
++
++/** If we were writing this in C++ then we would be deriving a subclass of
++ata_port, these would be the overridden functions*/
++static struct ata_port_operations ox800sata_port_ops =
++{
++ .port_disable = ox800sata_port_disable,
++ .dev_config = ox800sata_dev_config,
++ .set_piomode = ox800sata_set_piomode,
++ .set_dmamode = ox800sata_set_dmamode,
++ .tf_load = ox800sata_tf_load,
++ .tf_read = ox800sata_tf_read,
++ .exec_command = ox800sata_exec_command,
++ .check_status = ox800sata_check_status,
++ .check_altstatus = ox800sata_check_altstatus,
++ .dev_select = ox800sata_dev_select,
++ .phy_reset = ox800sata_phy_reset,
++ .bmdma_setup = ox800sata_bmdma_setup,
++ .bmdma_start = ox800sata_bmdma_start,
++ .bmdma_stop = ox800sata_bmdma_stop,
++ .bmdma_status = ox800sata_bmdma_status,
++ .qc_new = ox800sata_qc_new,
++ .qc_free = ox800sata_qc_free,
++ .qc_prep = ata_qc_prep,
++ .qc_issue = ox800sata_qc_issue,
++ .eng_timeout = ox800sata_eng_timeout,
++ .irq_handler = ox800sata_irq_handler,
++ .irq_clear = ox800sata_irq_clear,
++ .scr_read = ox800sata_scr_read,
++ .scr_write = ox800sata_scr_write,
++ .port_start = ox800sata_port_start,
++ .port_stop = ox800sata_port_stop,
++ .host_stop = ox800sata_host_stop,
++ .dev_chk = ox800sata_devchk,
++ .irq_on = ox800sata_irq_on,
++ .irq_ack = ox800sata_irq_ack,
++ .pio_task = ox800sata_pio_start,
++};
++
++/** the scsi_host_template structure describes the basic capabilities of libata
++and our 921 core to the SCSI framework, it contains the addresses of functions
++in the libata library that handle top level comands from the SCSI library */
++static struct scsi_host_template ox800sata_sht =
++{
++ .module = THIS_MODULE,
++ .name = DRIVER_NAME,
++ .ioctl = ata_scsi_ioctl,
++ .queuecommand = ata_scsi_queuecmd,
++/* .eh_strategy_handler= ata_scsi_error,*/
++ .can_queue = ATA_DEF_QUEUE,
++ .this_id = ATA_SHT_THIS_ID,
++/* .sg_tablesize = LIBATA_MAX_PRD,*/
++ .sg_tablesize = CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES,
++ .max_sectors = 256, // Use the full 28-bit SATA value
++ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
++ .emulated = ATA_SHT_EMULATED,
++ .use_clustering = ATA_SHT_USE_CLUSTERING,
++ .proc_name = DRIVER_NAME,
++ .dma_boundary = ~0UL, // NAS has no DMA boundary restrictions
++ .slave_configure = ata_scsi_slave_config,
++ .bios_param = ata_std_bios_param,
++ .unchecked_isa_dma = 0,
++
++};
++
++/** after PIO read operations, DRQ can remain set even when all the data has
++been read, when set, PretendDRQIsClear will mask out the DRQ bit in
++ox800sata_check_status operation */
++static char PretendDRQIsClear;
++
++/**
++ * used as a store for atomic test and set operations used to coordinate so
++ * that only one port is processing comnmands at any time */
++static unsigned long ox800sata_command_active;
++
++/**
++ * A record of which drives have accumulated raid faults. A set bit indicates
++ * a fault has occured on that drive */
++static u32 ox800sata_accumulated_RAID_faults = 0;
++
++/**************************************************************************/
++MODULE_LICENSE("GPL");
++MODULE_VERSION(1.0);
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
++
++/**************************************************************************
++* FUCTIONS
++* prefix all with "ox800sata_"
++**************************************************************************/
++
++/**
++ * Gets the base address of the ata core from the ata_port structure
++ * @param ap pointer to the appropriate ata_port structure
++ * @return the base address of the SATA core
++ */
++static u32* ox800sata_get_io_base(struct ata_port* ap)
++{
++ // return (u32* )SATA0_REGS_BASE;
++
++ return (u32* )ap->host->iomap;
++}
++
++/**
++ * Gets the base address of the core that contains the BBP registers
++ * @return the base address of the SATA core that contains the BBP registers
++ */
++static u32* ox800sata_get_bbp_base(void)
++{
++ return (u32* )SATA0_REGS_BASE;;
++}
++
++/**
++ * Gets the base address of the sata link registers core from the
++ * ata_port structure
++ * @param ap pointer to the appropriate ata_port structure
++ * @return the base address of the SATA core
++ */
++static u32* ox800sata_get_link_base(struct ata_port* ap)
++{
++ u8* link_base = (u8* )ap->host->iomap +
++ ((u8* )SATA0_LINK_REGS_BASE - (u8* )SATA0_REGS_BASE);
++
++ return (u32* )link_base;
++}
++
++/**
++ * Turns on the cores clock and resets it
++ */
++static void ox800sata_reset_core( void ){
++ // Enable the clock to the SATA block
++ writel(1UL << SYS_CTRL_CKEN_SATA_BIT, SYS_CTRL_CKEN_SET_CTRL);
++ wmb();
++
++ // reset both MAC and PHY
++ writel(1UL << SYS_CTRL_RSTEN_SATA_BIT, SYS_CTRL_RSTEN_SET_CTRL);
++ writel(1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT, SYS_CTRL_RSTEN_SET_CTRL);
++ wmb();
++ udelay(50);
++
++ // un-reset both MAC and PHY
++ writel(1UL << SYS_CTRL_RSTEN_SATA_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
++ writel(1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
++ wmb();
++ udelay(50);
++}
++
++/**
++ * port capabilities for the ox800 sata ports.
++ */
++static const struct ata_port_info ox800sata_port_info = {
++ .flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET | ATA_FLAG_NO_LEGACY,
++ .pio_mask = 0x1f, /* pio modes 0..4*/
++ .mwdma_mask = 0x07, /* mwdma0-2 */
++ .udma_mask = 0x7f, /* udma0-5 */
++ .port_ops = &ox800sata_port_ops,
++};
++
++/**
++ * The driver probe function.
++ * Registered with the amba bus driver as a parameter of ox800sata_driver.bus
++ * it will register the ata device with kernel first performing any
++ * initialisation required (if the correct device is present).
++ * @param pdev Pointer to the 921 device structure
++ * @param port where on the bus the port was found, ignored and probably wrong
++ * @return 0 if no errors
++ */
++static int ox800sata_init_one(struct platform_device* pdev)
++{
++
++ u32 version;
++#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
++ unsigned long reg;
++#endif // CONFIG_SATA_OXNAS_DISK_LIGHT
++ struct ata_host *host;
++ const struct ata_port_info* port_info[] = { &ox800sata_port_info, NULL };
++
++ void __iomem* iomem;
++ struct resource* memres = platform_get_resource(pdev, IORESOURCE_MEM, 0 );
++ int irq = platform_get_irq(pdev, 0);
++
++ DPRINTK("\n");
++
++ /* check resourses for sanity */
++ if ((memres == NULL) || (irq < 0)) {
++ return 0;
++ }
++ iomem = (void __iomem* ) memres->start;
++
++ /* check we support this version of the core */
++ version = readl(((u32* )iomem) + OX800SATA_VERSION) & 0xff;
++ switch (version)
++ {
++ case OX800SATA_CORE_VERSION:
++ printk(KERN_INFO"ox800sata: OX800 sata core.\n");
++ break;
++ default:
++ printk(KERN_ERR"ox800sata: unknown sata core (version register = 0x%08x)\n",version);
++ return 0;
++ break;
++ }
++
++ /* reset the core */
++ ox800sata_reset_core();
++
++ /* initialise a work queue to spot the end of transfers */
++ ox800sata_driver.spot_the_end_q = create_singlethread_workqueue("sata-endQ");
++ if (!ox800sata_driver.spot_the_end_q) {
++ printk(KERN_ERR DRIVER_NAME " Couldn't create a work queue.\n");
++ return -1;
++ }
++
++#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
++ /* setup path */
++ reg = ~(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE) & readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
++ writel(reg, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
++ reg = ~(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE) & readl(SYS_CTRL_GPIO_SECSEL_CTRL_0);
++ writel(reg, SYS_CTRL_GPIO_SECSEL_CTRL_0);
++ reg = ~(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE) & readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0);
++ writel(reg, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
++
++ /* enable output */
++ writel(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_ENABLE);
++
++ /* disk light off */
++ writel(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_CLEAR);
++#endif /* CONFIG_SATA_OXNAS_DISK_LIGHT */
++
++ /* setup the probe_ent structure which is basically info about the ports
++ capabilities */
++
++ /* allocate memory and check */
++ host = ata_host_alloc_pinfo(&(pdev->dev), port_info, OX800SATA_MAX_PORTS );
++ if (!host) {
++ printk(KERN_ERR DRIVER_NAME " Couldn't create an ata host.\n");
++ destroy_workqueue(ox800sata_driver.spot_the_end_q);
++ }
++
++ /* set to base of ata core */
++ host->iomap = iomem;
++
++ /* call ata_device_add and begin probing for drives*/
++ ata_host_activate(host,
++ irq,
++ ox800sata_irq_handler,
++ 0,
++ &ox800sata_sht );
++
++ return 0;
++}
++
++/**
++ * Called when the amba bus tells this device to remove itself.
++ * @param pdev pointer to the device that needs to be shutdown
++ */
++static int ox800sata_remove_one(struct platform_device* pdev)
++{
++ struct ata_host *host_set = dev_get_drvdata( &(pdev->dev) );
++ struct ata_port *ap;
++ unsigned int i;
++
++
++ for (i = 0; i < host_set->n_ports; i++)
++ {
++ ap = host_set->ports[i];
++ scsi_remove_host( ap->scsi_host );
++ }
++
++ /** @TODO etc. */
++
++ // Disable the clock to the SATA block
++ writel(1UL << SYS_CTRL_CKEN_SATA_BIT, SYS_CTRL_CKEN_CLR_CTRL);
++
++ return 0;
++}
++
++/**
++ * module initialisation
++ * @return success
++ */
++static int __init ox800sata_init( void )
++{
++ int ret;
++
++ printk(KERN_INFO"ox800sata init \n");
++
++ ret = platform_driver_register( &ox800sata_driver.driver );
++
++ return ret;
++}
++
++/**
++ * module cleanup
++ */
++static void __exit ox800sata_exit( void )
++{
++ platform_driver_unregister( &ox800sata_driver.driver );
++}
++
++/**
++ * macros to register intiialisation and exit functions with kernal
++ */
++module_init(ox800sata_init);
++module_exit(ox800sata_exit);
++
++/**
++ * Called from ata_bus_probe() and ata_bus_reset() error paths, as well as
++ * when unregistering from the SCSI module (rmmod, hot unplug).
++ * @param port The port to disable
++ */
++static void ox800sata_port_disable(struct ata_port* port)
++{
++ DPRINTK("\n");
++}
++
++/**
++ * Called after IDENTIFY [PACKET] DEVICE is issued to each device found.
++ * Typically used to apply device-specific fixups prior to issue of
++ * SET FEATURES - XFER MODE, and prior to operation.
++ * @param port The port to configure
++ * @param pdev The hardware associated with controlling the port
++ */
++static void ox800sata_dev_config(struct ata_device* pdev)
++{
++ u32 reg;
++ u32 *ioaddr = ox800sata_get_io_base(pdev->ap);
++
++ DPRINTK("\n");
++
++ /* if needed, set the bits to put the interface into 48-bit node */
++ if (pdev->flags & ATA_DFLAG_LBA48) {
++ reg = readl( ioaddr + OX800SATA_DRIVE_CONTROL );
++
++ /* mask out the pair of bits associaed with each port */
++ reg &= ~( 3 << (pdev->ap->port_no * 2) );
++
++ /* set the mode pair associated with each port */
++ reg |= 2 << (pdev->ap->port_no * 2);
++ writel(reg ,ioaddr + OX800SATA_DRIVE_CONTROL);
++ }
++}
++
++/**
++ * Hooks called prior to the issue of SET FEATURES - XFER MODE command.
++ * dev->pio_mode is guaranteed to be valid when ->set_piomode() is called
++ *
++ * If we're doing PIO, we need to disable the burst buffer port to stop it
++ * trying to do a DMA transfer of the data.
++ *
++ * @param port The port to configure
++ * @param pdev The hardware associated with controlling the port
++ */
++static void ox800sata_set_piomode(struct ata_port* port, struct ata_device* pdev)
++{
++ u32 Register;
++ u32 *ioaddr = ox800sata_get_bbp_base();
++
++ DPRINTK("\n");
++
++ /* disable burst buffer DMA */
++ Register = readl( ioaddr + OX800SATA_BURST_CONTROL );
++ Register |= OX800SATA_BBC_DREQ_DIS ;
++ writel(Register ,ioaddr + OX800SATA_BURST_CONTROL);
++ PretendDRQIsClear = 0;
++}
++
++/**
++ * Hooks called prior to the issue of SET FEATURES - XFER MODE command.
++ * dev->dma_mode is guaranteed to be valid when ->set_dmamode() is called.
++ *
++ * When doing a DMA transfer, we need to enable the burst buffer port as this
++ * may have been disabled by a previous command.
++ *
++ * @param port The port to configure
++ * @param pdev The hardware associated with controlling the port
++ */
++static void ox800sata_set_dmamode(struct ata_port* port, struct ata_device* pdev)
++{
++ u32 Register;
++ u32 *ioaddr = ox800sata_get_bbp_base();
++
++ DPRINTK("\n");
++
++ /* enable burst buffer DMA */
++ Register = readl( ioaddr + OX800SATA_BURST_CONTROL );
++ Register &= ~OX800SATA_BBC_DREQ_DIS;
++ writel(Register ,ioaddr + OX800SATA_BURST_CONTROL);
++}
++
++/**
++ * Output the taskfile for diagnostic reasons, it will always appear in the
++ * debug output as if it's a task file being written.
++ * @param tf The taskfile to output
++ */
++static void tfdump(const struct ata_taskfile* tf)
++{
++ if (tf->flags & ATA_TFLAG_LBA48) {
++#ifdef SATA_TF_DUMP
++ printk("Cmd %x Ft %x%x, LBA-48 %02x%02x%02x%02x%02x%02x, nsect %02x%02x, ctl %02x, dev %x\n",
++#else // SATA_TF_DUMP
++ DPRINTK("Cmd %x Ft %x%x, LBA-48 %02x%02x%02x%02x%02x%02x, nsect %02x%02x, ctl %02x, dev %x\n",
++#endif // SATA_TF_DUMP
++ tf->command,
++
++ tf->hob_feature,
++ tf->feature,
++
++ tf->hob_lbah,
++ tf->hob_lbam,
++ tf->hob_lbal,
++ tf->lbah,
++ tf->lbam,
++ tf->lbal,
++
++ tf->hob_nsect,
++ tf->nsect,
++ tf->ctl,
++ tf->device );
++ }else{
++#ifdef SATA_TF_DUMP
++ printk("Cmd %x Ft %x, LBA-28 %01x%02x%02x%02x, nsect %02x, ctl %02x, dev %x\n",
++#else // SATA_TF_DUMP
++ DPRINTK("Cmd %x Ft %x, LBA-28 %01x%02x%02x%02x, nsect %02x, ctl %02x, dev %x\n",
++#endif // SATA_TF_DUMP
++ tf->command,
++
++ tf->feature,
++
++ tf->device & 0x0f,
++ tf->lbah,
++ tf->lbam,
++ tf->lbal,
++
++ tf->nsect,
++ tf->ctl,
++ tf->device );
++ }
++}
++
++/**
++ * called to write a taskfile into the ORB registers
++ * @param ap hardware with the registers in
++ * @param tf taskfile to write to the registers
++ */
++static void ox800sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
++{
++ u32 count = 0;
++ u32 Orb1 = 0;
++ u32 Orb2 = 0;
++ u32 Orb3 = 0;
++ u32 Orb4 = 0;
++ u32 Command_Reg;
++ u32 *ioaddr = ox800sata_get_io_base(ap);
++ unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
++
++ do {
++ Command_Reg = readl(ioaddr + OX800SATA_SATA_COMMAND );
++ if (!(Command_Reg & CMD_CORE_BUSY))
++ break;
++ count++;
++ if ( in_atomic() ) {
++ mdelay(1);
++ } else {
++ msleep(1);
++ }
++ } while (count < 10);
++
++ /* if the control register has changed, write it */
++ if (tf->ctl != ap->last_ctl)
++ {
++ //DPRINTK("ap->last_ctl = %02x",ap->last_ctl);
++ Orb4 |= (tf->ctl) << 24;
++
++ /* write value to register */
++ writel(Orb4, ioaddr + OX800SATA_ORB4 );
++
++ ap->last_ctl = tf->ctl;
++ }
++
++ /* check if the ctl register has interrupts disabled or enabled and
++ modify the interrupt enable registers on the ata core as required */
++ if (tf->ctl & ATA_NIEN)
++ {
++ /* interrupts disabled */
++ ox800sata_irq_clear(ap);
++ }
++ else
++ {
++ /* interrupts enabled */
++ ox800sata_irq_on(ap);
++ }
++
++ /* write 48 or 28 bit tf parameters */
++ if (is_addr)
++ {
++ /* set LBA bit as it's an address */
++ Orb1 |= (tf->device & ATA_LBA) << 24;
++
++ if (tf->flags & ATA_TFLAG_LBA48)
++ {
++ //DPRINTK(KERN_INFO" 48 bit tf load \n");
++ Orb1 |= ATA_LBA << 24;
++
++ Orb2 |= (tf->hob_nsect) << 8 ;
++
++ Orb3 |= (tf->hob_lbal) << 24;
++
++ Orb4 |= (tf->hob_lbam) << 0 ;
++ Orb4 |= (tf->hob_lbah) << 8 ;
++ Orb4 |= (tf->hob_feature)<< 16;
++ } else {
++ Orb1 |= (tf->device & 0xf)<< 24;
++ }
++
++ /* write 28-bit lba */
++ //DPRINTK(KERN_INFO" 28 bit tf load\n");
++ Orb1 |= (tf->lbal) << 0 ;
++ Orb1 |= (tf->lbam) << 8 ;
++ Orb1 |= (tf->lbah) << 16;
++
++ Orb2 |= (tf->nsect) << 0 ;
++ Orb2 |= (tf->feature) << 16;
++ Orb2 |= (tf->command) << 24;
++
++ Orb3 |= (tf->lbal) << 0 ;
++ Orb3 |= (tf->lbam) << 8 ;
++ Orb3 |= (tf->lbah) << 16;
++
++ Orb4 |= (tf->ctl) << 24;
++
++ /* write values to registers */
++ writel(Orb1, ioaddr + OX800SATA_ORB1 );
++ writel(Orb2, ioaddr + OX800SATA_ORB2 );
++ writel(Orb3, ioaddr + OX800SATA_ORB3 );
++ writel(Orb4, ioaddr + OX800SATA_ORB4 );
++ }
++
++ if (tf->flags & ATA_TFLAG_DEVICE)
++ {
++ Orb1 |= (tf->device) << 24;
++
++ /* write value to register */
++ writel(Orb1, ioaddr + OX800SATA_ORB1 );
++ }
++
++ tfdump(tf);
++
++}
++
++/**
++ * Called to read the hardware registers / DMA buffers, to
++ * obtain the current set of taskfile register values.
++ * @param ap hardware with the registers in
++ * @param tf taskfile to read the registers into
++ */
++static void ox800sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
++{
++ u32 *ioaddr = ox800sata_get_io_base(ap);
++
++ /* read the orb registers */
++ u32 Orb1 = readl( ioaddr + OX800SATA_ORB1 );
++ u32 Orb2 = readl( ioaddr + OX800SATA_ORB2 );
++ u32 Orb3 = readl( ioaddr + OX800SATA_ORB3 );
++ u32 Orb4 = readl( ioaddr + OX800SATA_ORB4 );
++
++ DPRINTK("\n");
++
++ /* read common 28/48 bit tf parameters */
++ tf->device = (Orb1 >> 24);
++ tf->nsect = (Orb2 >> 0);
++ tf->feature = (Orb2 >> 16);
++ tf->command = ox800sata_check_status(ap);
++
++ /* read 48 or 28 bit tf parameters */
++ if (tf->flags & ATA_TFLAG_LBA48)
++ {
++ //DPRINTK(KERN_INFO" 48 bit tf read \n");
++ tf->hob_nsect = (Orb2 >> 8 ) ;
++
++ tf->lbal = (Orb3 >> 0 ) ;
++ tf->lbam = (Orb3 >> 8 ) ;
++ tf->lbah = (Orb3 >> 16) ;
++ tf->hob_lbal = (Orb3 >> 24) ;
++
++ tf->hob_lbam = (Orb4 >> 0 ) ;
++ tf->hob_lbah = (Orb4 >> 8 ) ;
++ /* feature ext and control are write only */
++
++ }
++ else
++ {
++ /* read 28-bit lba */
++ //DPRINTK(KERN_INFO" 28 bit tf read\n");
++ tf->lbal = (Orb1 >> 0 ) ;
++ tf->lbam = (Orb1 >> 8 ) ;
++ tf->lbah = (Orb1 >> 16) ;
++ }
++
++ /* fixup NAS SATA core's non-std status reporting */
++ if (PretendDRQIsClear)
++ {
++ tf->command &= ~ATA_DRQ;
++ }
++
++ tfdump(tf);
++}
++
++/**
++ * Causes an ATA command, previously loaded with ->tf_load(), to be
++ * initiated in hardware. The command is written into the registers again just
++ * to be sure. All the other registers that are in Orb2 are also written at the
++ * same time. The command is initiated in hardware by a poke to the COMMAND
++ * register.
++ * @param ap hardware with the registers in
++ * @param tf taskfile to write to the registers
++ */
++static void ox800sata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
++{
++ u32 count =0;
++ u32 *ioaddr = ox800sata_get_io_base(ap);
++ u32 Orb2 ;
++ u32 Command_Reg;
++ ox800sata_private_data* private_data ;
++
++ //DPRINTK(KERN_INFO"ox800sata_exec_command cmd %02x\n", tf->command);
++ do {
++ Command_Reg = readl(ioaddr + OX800SATA_SATA_COMMAND );
++ if (!(Command_Reg & CMD_CORE_BUSY))
++ break;
++ count++;
++ if ( in_atomic() ) {
++ mdelay(1);
++ } else {
++ msleep(1);
++ }
++ } while (count < 10);
++
++ /* write all the things in Orb 2 */
++ Orb2 = (tf->nsect) << 0 ;
++ if (tf->flags & ATA_TFLAG_LBA48)
++ {
++ Orb2 |= (tf->hob_nsect) << 8 ;
++ }
++ Orb2 |= (tf->feature) << 16;
++ Orb2 |= (tf->command) << 24;
++ writel( Orb2 , ioaddr + OX800SATA_ORB2 );
++ wmb();
++
++ do {
++ Command_Reg = readl(ioaddr + OX800SATA_SATA_COMMAND );
++ if (!(Command_Reg & CMD_CORE_BUSY))
++ break;
++ count++;
++ if ( in_atomic() ) {
++ mdelay(1);
++ } else {
++ msleep(1);
++ }
++ } while (count < 10);
++
++ /* if the drive has become disconnected, executing a command will be a
++ problem */
++ private_data = (ox800sata_private_data*)ap->private_data;
++
++ /* Command that the orb registers get written to drive */
++ Command_Reg &= ~SATA_OPCODE_MASK;
++ Command_Reg |= CMD_WRITE_TO_ORB_REGS;
++ writel( Command_Reg , ioaddr + OX800SATA_SATA_COMMAND );
++ wmb();
++}
++
++
++/**
++ * Reads the Status ATA shadow register from hardware. Due to a fault with PIO
++ * transfers, it it sometimes necessary to mask out the DRQ bit
++ * @param ap hardware with the registers in
++ * @return The status register
++ */
++static u8 ox800sata_check_status(struct ata_port *ap)
++{
++ u32 Reg;
++ u8 result;
++ u8 state;
++ u32 *ioaddr = ox800sata_get_io_base(ap);
++
++// VPRINTK(KERN_INFO"ox800sata_check_status ");
++
++ /* read byte 3 of Orb2 register */
++ result = readl(ioaddr + OX800SATA_ORB2 ) >> 24;
++
++ /* set DRQ when core is in PIO transfer states */
++ state = readl(ioaddr + OX800SATA_SATA_CONTROL) & OX800SATA_SATA_CONTROL_TRANS_MASK;
++ if ((state == OX800SATA_TRANS_PIOITRANS) || (state == OX800SATA_TRANS_PIOOTRANS)) {
++ result |= ATA_DRQ;
++ }
++
++ if (PretendDRQIsClear)
++ {
++// VPRINTK("(ignoring DRQ) ");
++ result &= ~ATA_DRQ;
++ }
++
++ /* use error informatian from raw interupt status */
++ if (readl(ioaddr + OX800SATA_INT_STATUS) & OX800SATA_RAW_ERROR) {
++ result |= ATA_ERR;
++ } else {
++ result &= ~ATA_ERR;
++ }
++
++ /* check for the drive going missing indicated by SCR status bits 0-3 = 0 */
++ ox800sata_scr_read(ap, SCR_STATUS, &Reg);
++ if (!(Reg & 0x1)) {
++ result |= ATA_DF;
++ result |= ATA_ERR;
++ }
++ //VPRINTK("%02x\n",result);
++
++ return result;
++}
++
++/**
++ * Reads the alt status ATA shadow register from hardware.
++ * @param ap hardware with the registers in
++ * @return The alt status register
++ */
++static u8 ox800sata_check_altstatus(struct ata_port *ap)
++{
++ u8 result;
++ u32 *ioaddr = ox800sata_get_io_base(ap);
++
++ //DPRINTK(KERN_INFO"ox800sata_check_altstatus base=%p\n",ioaddr);
++
++ /* read byte 3 of Orb4 register */
++ result = ( readl(ioaddr + OX800SATA_ORB4 ) >> 24 ) ;
++
++ //DPRINTK(KERN_INFO"alternate status register %02x\n",result);
++
++ return result;
++}
++
++/**
++ * Use the method defined in the ATA specification to make either device 0,
++ * or device 1, active on the ATA channel. If we ever get port multipliers
++ * to work, this will be where they would switch.
++ *
++ * @param ap hardware with the registers in
++ * @param number of the device to talk to (0..)
++ */
++static void ox800sata_dev_select(struct ata_port *ap, unsigned int device)
++{
++ /* currently only one i/f, but this may not always be the case */
++ const unsigned char interface_no = 0;
++
++ u32 *ioaddr = ox800sata_get_io_base(ap);
++ DPRINTK(" i/f=%d dev=%d\n", interface_no, device);
++
++ writel(
++ (interface_no << 4) | device ,
++ ioaddr + OX800SATA_DEVICE_SELECT );
++}
++
++/**
++ * The very first step in the probe phase. Actions vary depending on the bus
++ * type, typically. After waking up the device and probing for device presence
++ * (PATA and SATA), typically a soft reset (SRST) will be performed. Drivers
++ * typically use the helper functions ata_bus_reset() or sata_phy_reset() for
++ * this hook.
++ *
++ * This should reset the SATA core and Phisical layer then jump back into the
++ * libata libraries for lots of other resetting
++ *
++ * @param ap hardware with the registers in
++ */
++static void ox800sata_phy_reset(struct ata_port *ap)
++{
++ u32 *ioaddr = ox800sata_get_io_base(ap);
++
++ //DPRINTK(KERN_INFO"ox800sata_phy_reset base = %p\n", ioaddr);
++
++ /* turn ata core on */
++ writel( (1 << SYS_CTRL_CKEN_SATA_BIT), SYS_CTRL_CKEN_SET_CTRL);
++
++ /* stop all the interrupts in the ata core */
++ writel( ~0, ioaddr + OX800SATA_INT_DISABLE);
++ writel( ~0, ioaddr + OX800SATA_INT_CLEAR);
++
++ /* get libata to perform a soft reset */
++ sata_phy_reset(ap);
++
++}
++
++/**
++ * When setting up an IDE BMDMA transaction, these hooks arm (->bmdma_setup)
++ * and fire (->bmdma_start) the hardware's DMA engine.
++ *
++ * @param qc the queued command to issue
++ */
++static void ox800sata_bmdma_setup(struct ata_queued_cmd *qc)
++{
++ ox800sata_private_data* PrivateData ;
++ oxnas_dma_direction_t direction;
++
++#ifdef SATA_DEBUG
++ printk(KERN_INFO"ox800sata_bmdma_setup: %s, %d element%s\n", (qc->dma_dir == DMA_FROM_DEVICE) ? "Read" : "Write", qc->n_elem, qc->n_elem ? "s" : "");
++#else // SATA_DEBUG
++ DPRINTK(" %s, %d element%s\n", (qc->dma_dir == DMA_FROM_DEVICE) ? "Read" : "Write", qc->n_elem, qc->n_elem ? "s" : "");
++#endif // SATA_DEBUG
++
++ qc->private_data = qc->ap->private_data;
++ PrivateData = (ox800sata_private_data* )qc->private_data;
++
++ // We check for DMA completion from ISR which cannot wait for all DMA channel
++ // housekeeping to complete, so need to wait here is case we try to reuse
++ // channel before that housekeeping has completed
++ while (oxnas_dma_is_active(PrivateData->DmaChannel)) {
++ printk("DMA Setup Channel still active\n");
++ }
++
++ /* Do not use DMA callback */
++ oxnas_dma_set_callback(PrivateData->DmaChannel, OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
++
++ /* decide on DMA direction */
++ direction = (qc->dma_dir == DMA_FROM_DEVICE) ? OXNAS_DMA_FROM_DEVICE :
++ OXNAS_DMA_TO_DEVICE;
++
++/* Expect transfers to be multiples of 4KB */
++//struct scatterlist* sle = qc->sg;
++//while (sg_dma_len(sle)) {
++// BUG_ON(sg_dma_len(sle) % 4096);
++// ++sle;
++//}
++
++ /* now set-up the DMA transfer */
++ if (qc->n_elem > 1)
++ {
++#ifdef SATA_DEBUG
++ u32 total=0;
++ int i=0;
++ struct scatterlist* sg = qc->__sg;
++ printk("Lengths: ");
++ do {
++ u32 len = sg_dma_len(sg++);
++ printk("%u ", len);
++ total += len;
++ } while (++i < qc->n_elem);
++ printk("\nTotal len = %u\n", total);
++#endif // SATA_DEBUG
++ /* try and setup scatter gather controller */
++/* if (oxnas_dma_device_set_sg(PrivateData->DmaChannel,
++ direction,
++ qc->__sg,
++ qc->n_elem,
++ &oxnas_sata_dma_settings,
++ OXNAS_DMA_MODE_INC )) {
++ printk(KERN_ERR"Failed to setup DMA with disk.\n");
++ return;
++ }*/
++ if (oxnas_dma_device_set_prd(
++ PrivateData->DmaChannel,
++ direction,
++ qc->ap->prd,
++ &oxnas_sata_dma_settings,
++ OXNAS_DMA_MODE_INC,
++ PrivateData->sg_entries)) {
++ printk(KERN_ERR"Failed to setup DMA with disk.\n");
++ return;
++ }
++ }
++ else
++ {
++#ifdef SATA_DEBUG
++ printk("Total len = %u\n", sg_dma_len(qc->__sg));
++#endif // SATA_DEBUG
++ /* setup a single dma */
++ oxnas_dma_device_set( PrivateData->DmaChannel,
++ direction,
++ (unsigned char* )sg_dma_address(qc->__sg),
++ sg_dma_len(qc->__sg),
++ &oxnas_sata_dma_settings,
++ OXNAS_DMA_MODE_INC,
++ 1); /* paused */
++ }
++}
++
++/**
++ * When setting up an IDE BMDMA transaction, these hooks arm (->ignedmdma_setup)
++ * and fire (->bmdma_start) the hardware's DMA engine.
++ *
++ * @param qc the queued command to issue
++ */
++static void ox800sata_bmdma_start(struct ata_queued_cmd *qc)
++{
++ ox800sata_private_data* PrivateData ;
++ DPRINTK("\n");
++ PrivateData = (ox800sata_private_data* )(qc->private_data);
++
++ {
++ /* turn on the fifo */
++ u32 Register;
++ u32 *ioaddr = ox800sata_get_bbp_base();
++ Register = readl( ioaddr + OX800SATA_BURST_CONTROL );
++ Register &= ~OX800SATA_BBC_FIFO_DIS;
++ writel(Register ,ioaddr + OX800SATA_BURST_CONTROL);
++ }
++
++ /* if the drive has become disconnected, executing a command will be a
++ problem */
++ {
++ /* start DMA transfer */
++ oxnas_dma_start( PrivateData->DmaChannel );
++ qc->ap->ops->exec_command(qc->ap, &(qc->tf));
++ }
++}
++
++
++/**
++ * ata_qc_new - Request an available ATA command, for queueing
++ * @ap: Port associated with device @dev
++ * @dev: Device from whom we request an available command structure
++ *
++ * LOCKING:
++ */
++
++static struct ata_queued_cmd* ox800sata_qc_new(struct ata_port *ap)
++{
++ struct ata_queued_cmd *qc = NULL;
++
++ /* first see if we're not doing a command */
++ if (!test_and_set_bit(0, &ox800sata_command_active)) {
++ /* now set the standard bits for compatibility */
++ set_bit(0, &ap->qc_allocated);
++ qc = ata_qc_from_tag(ap, 0);
++
++#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
++ /* disk light on */
++ writel(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_SET);
++#endif // CONFIG_SATA_OXNAS_DISK_LIGHT
++#ifdef CONFIG_WDC_LEDS_TRIGGER_SATA_DISK
++ wdc_ledtrig_sata_activity();
++#endif // CONFIG_WDC_LEDS_TRIGGER_SATA_DISK
++ } else
++ DPRINTK("Command active flag still set\n");
++
++ if (qc)
++ qc->tag = 0;
++
++ return qc;
++}
++
++
++/**
++ *
++ */
++static void ox800sata_qc_free(struct ata_queued_cmd *qc)
++{
++ struct ata_port *ap = qc->ap;
++ unsigned int tag, do_clear = 0;
++
++ DPRINTK("\n");
++
++ qc->flags = 0;
++ tag = qc->tag;
++ if (likely(ata_tag_valid(tag))) {
++ if (tag == ap->active_tag)
++ ap->active_tag = ATA_TAG_POISON;
++ qc->tag = ATA_TAG_POISON;
++ do_clear = 1;
++ }
++
++ if (likely(do_clear)) {
++ clear_bit(tag, &ap->qc_allocated);
++ clear_bit(0, &ox800sata_command_active);
++
++#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
++ /* disk light off */
++ writel(1 << CONFIG_OX800SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_CLEAR);
++#endif /* CONFIG_SATA_OXNAS_DISK_LIGHT */
++ }
++}
++
++/**
++ * qc_issue is used to make a command active, once the hardware and S/G tables
++ * have been prepared. IDE BMDMA drivers use the helper function
++ * ata_qc_issue_prot() for taskfile protocol-based dispatch. More advanced drivers
++ * roll their own ->qc_issue implementation, using this as the "issue new ATA
++ * command to hardware" hook.
++ * @param qc the queued command to issue
++ */
++static unsigned int ox800sata_qc_issue(struct ata_queued_cmd *qc)
++{
++ u32 Register;
++ int this_port_fail;
++ ox800sata_private_data* private_data = (ox800sata_private_data*)qc->ap->private_data ;
++ u32 *ioaddr = ox800sata_get_bbp_base();
++ u32 reg;
++ u32 raid_reg = 0; /* default to no raid */
++
++ DPRINTK("\n");
++
++ /* get raid settings from the bio if they exist */
++ if (qc->scsicmd && qc->scsicmd->request && qc->scsicmd->request->bio) {
++ struct bio* bio;
++ bio = qc->scsicmd->request->bio;
++ raid_reg = bio->bi_raid ;
++ if (raid_reg) DPRINTK(" raid reg 0x%08x\n",raid_reg);
++ }
++
++ /* check cable is still connected */
++ ox800sata_scr_read(qc->ap, SCR_STATUS, ®);
++ private_data->port_disabled |= (!(reg & 1));
++
++ this_port_fail = private_data->port_disabled;
++
++ if (raid_reg) {
++ int port0fail, port1fail;
++ port0fail = (! (__ox800sata_scr_read((u32* )SATA0_LINK_REGS_BASE, 0x20 + (4 * SCR_STATUS) ) & 1 ) );
++ port1fail = (! (__ox800sata_scr_read((u32* )SATA1_LINK_REGS_BASE, 0x20 + (4 * SCR_STATUS) ) & 1 ) );
++ this_port_fail |= port1fail;
++
++ ox800sata_accumulated_RAID_faults |= port0fail ? 1 : 0 ;
++ ox800sata_accumulated_RAID_faults |= port1fail ? 2 : 0 ;
++ }
++
++ if (!this_port_fail ) {
++ writel(raid_reg ,ioaddr + OX800SATA_RAID_CONTROL);
++
++ DPRINTK(" enabling burst buffer DMA\n");
++ Register = readl( ioaddr + OX800SATA_BURST_CONTROL );
++ Register &= ~OX800SATA_BBC_DREQ_DIS;
++ writel(Register ,ioaddr + OX800SATA_BURST_CONTROL);
++
++ /* call the default, this should be changed to take advantage of orb
++ registers, etc... */
++ return ata_qc_issue_prot(qc);
++ } else {
++ /* record the error */
++ qc->err_mask |= AC_ERR_ATA_BUS;
++
++ /* offline the SCSI device */
++ printk(KERN_ERR"ata%u offline\n", qc->ap->print_id);
++ scsi_device_set_state(qc->scsicmd->device, SDEV_OFFLINE);
++ return 0;
++ }
++}
++
++/**
++ * This is a high level error handling function, called from the error
++ * handling thread, when a command times out.
++ *
++ * @todo possibly remove this function and revert to only calling the default
++ *
++ * @param ap hardware with the registers in
++ */
++static void ox800sata_eng_timeout(struct ata_port *ap)
++{
++ struct ata_queued_cmd *qc;
++ ox800sata_private_data* pd = (ox800sata_private_data*)ap->private_data;
++ DPRINTK("\n");
++
++ /* set the in cleanup flag */
++ pd->in_cleanup = 1;
++
++ /* if we're a PIO command existing cleanup won't be called */
++ qc = ata_qc_from_tag(ap, ap->active_tag);
++ if (qc->tf.protocol == ATA_PROT_PIO) {
++ /* reset the core */
++ ox800sata_timeout_cleanup(ap);
++ }
++
++ /* call strandard lib ata function */
++ ata_eng_timeout( ap );
++
++ /* clear the in cleanup flag */
++ pd->in_cleanup = 0;
++}
++
++/**
++ * irq_handler is the interrupt handling routine registered with the system,
++ * by libata.
++ */
++static irqreturn_t ox800sata_irq_handler(int irq,
++ void* dev_instance)
++{
++ struct ata_port *ap = ((struct ata_host *)dev_instance)->ports[0];
++ ox800sata_private_data *pd;
++ u32 *ioaddr;
++ u32 int_status;
++
++ DPRINTK("irq = %d\n", irq);
++
++ if (!ap || !ap->private_data)
++ BUG();
++
++ pd = (ox800sata_private_data*)ap->private_data;
++ ioaddr = ox800sata_get_io_base(ap);
++
++ int_status = readl(ioaddr + OX800SATA_INT_STATUS);
++ while (int_status & OX800SATA_INT_MASKABLE) {
++ /* store interrupt status for the bottom end */
++ pd->int_status |= int_status;
++
++ /* Clear and mask pending interrupts */
++ writel(int_status, ioaddr + OX800SATA_INT_CLEAR);
++ writel(int_status, ioaddr + OX800SATA_INT_DISABLE);
++
++ int_status = readl(ioaddr + OX800SATA_INT_STATUS);
++ }
++
++ // Wait a short while for the DMA to finish and if it doesn't start a thread
++ // to poll for the finish
++ pd->spot_the_end_work.ap = ap;
++ if (!oxnas_dma_raw_isactive(pd->DmaChannel)) {
++ ox800sata_spot_the_end(&(pd->spot_the_end_work.worker));
++ } else {
++ udelay(100);
++ if (!oxnas_dma_raw_isactive(pd->DmaChannel)) {
++ ox800sata_spot_the_end(&(pd->spot_the_end_work.worker));
++ } else {
++ /* Start a worker thread looking for the DMA channel to become idle */
++ queue_work(ox800sata_driver.spot_the_end_q, &pd->spot_the_end_work.worker);
++ }
++ }
++
++ return IRQ_HANDLED;
++}
++
++/**
++ * Work for a work queue, this will check for errors then wait for the DMA to
++ * complete. On the DMA completing it will call ata_qc_complete
++ */
++static void ox800sata_spot_the_end(struct work_struct *work)
++{
++ struct spot_the_end_work_s* stew =
++ container_of(work, struct spot_the_end_work_s, worker);
++ struct ata_port* ap = stew->ap;
++ ox800sata_private_data* PrivateData = (ox800sata_private_data* )ap->private_data;
++ struct ata_queued_cmd* qc = ata_qc_from_tag(ap, ap->active_tag);
++ unsigned long flags = 0;
++
++ /* If there's no command ending associated with this IRQ, ignore it. */
++ if ((qc == NULL) ||
++ !(PrivateData->int_status & OX800SATA_INT_END_OF_CMD)) {
++ DPRINTK(" qc=null\n");
++ return;
++ }
++
++ /* Look to see if the core is indicating an error condition after a RAID
++ * command */
++ if (qc->scsicmd &&
++ qc->scsicmd->request &&
++ qc->scsicmd->request->bio &&
++ qc->scsicmd->request->bio->bi_raid ) {
++ unsigned long Port0Irq = readl(((u32)(SATA0_REGS_BASE)) + OX800SATA_INT_STATUS);
++ unsigned long Port1Irq = readl(((u32)(SATA1_REGS_BASE)) + OX800SATA_INT_STATUS);
++
++ if (test_bit(OX800SATA_INT_ERROR, &Port0Irq)) {
++ printk("disk 0 error in raid\n");
++ ox800sata_accumulated_RAID_faults |= 1;
++ }
++ if (test_bit(OX800SATA_INT_ERROR, &Port1Irq)) {
++ printk("disk 1 error in raid\n");
++ ox800sata_accumulated_RAID_faults |= 2;
++ }
++ }
++
++ if (!in_irq()) {
++ /* wait for the DMA to finish */
++ while (oxnas_dma_is_active(PrivateData->DmaChannel)) {
++ schedule();
++ }
++ }
++
++ /* The command may have aborted, this is indicated by the interrupt bit
++ * being masked */
++ if (PrivateData->in_cleanup) {
++ return;
++ }
++
++ if (!(qc->flags & ATA_QCFLAG_ACTIVE)) {
++ printk(KERN_WARNING "**** QC already completed! ****\n");
++ return;
++ }
++
++ /* get the error status */
++ qc->err_mask = ac_err_mask(ata_chk_status(ap));
++
++ /* tell libata we're done */
++ DPRINTK(" returning err_mask=0x%x\n", qc->err_mask);
++ local_irq_save(flags);
++ PrivateData->int_status = 0;
++ local_irq_restore(flags);
++ ata_qc_complete(qc);
++}
++
++/**
++ * ox800sata_irq_clear is called during probe just before the interrupt handler is
++ * registered, to be sure hardware is quiet. It clears and masks interrupt bits
++ * in the SATA core.
++ *
++ * @param ap hardware with the registers in
++ */
++static void ox800sata_irq_clear(struct ata_port* ap)
++{
++ u32 *ioaddr = ox800sata_get_io_base(ap);
++ //DPRINTK(KERN_INFO"ox800sata_irq_clear\n");
++
++ writel( ~0, ioaddr + OX800SATA_INT_DISABLE );
++ writel( ~0, ioaddr + OX800SATA_INT_CLEAR );
++}
++
++static u32 __ox800sata_scr_read(u32* core_addr, unsigned int sc_reg)
++{
++ u32 result;
++ u32 patience;
++
++ /* we've got 8 other registers in before the start of the standard ones */
++ writel(sc_reg, core_addr + OX800SATA_LINK_RD_ADDR );
++
++ for (patience = 0x100000;patience > 0;--patience)
++ {
++ if (readl(core_addr + OX800SATA_LINK_CONTROL) & 0x00000001)
++ break;
++ }
++
++ result = readl(core_addr + OX800SATA_LINK_DATA);
++
++ //DPRINTK(KERN_INFO"ox800sata_scr_read: [0x%02x]->0x%08x\n", sc_reg, result);
++ return result;
++}
++
++/**
++ * Read standard SATA phy registers. Currently only used if
++ * ->phy_reset hook called the sata_phy_reset() helper function.
++ *
++ * These registers are in another clock domain to the processor, access is via
++ * some bridging registers
++ *
++ * @param ap hardware with the registers in
++ * @param sc_reg the SATA PHY register
++ * @return the value in the register
++ */
++static int ox800sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
++{
++ u32* ioaddr = ox800sata_get_link_base(ap);
++ *val = __ox800sata_scr_read(ioaddr, 0x20 + (sc_reg*4) );
++ return 0;
++}
++
++static void __ox800sata_scr_write(u32* core_addr, unsigned int sc_reg, u32 val)
++{
++ u32 patience;
++
++ //DPRINTK(KERN_INFO"ox800sata_scr_write: [0x%02x]<-0x%08x\n", sc_reg, val);
++ writel(val, core_addr + OX800SATA_LINK_DATA );
++ writel(sc_reg , core_addr + OX800SATA_LINK_WR_ADDR );
++
++ for (patience = 0x100000;patience > 0;--patience)
++ {
++ if (readl(core_addr + OX800SATA_LINK_CONTROL) & 0x00000001)
++ break;
++ }
++}
++/**
++ * Write standard SATA phy registers. Currently only used if
++ * phy_reset hook called the sata_phy_reset() helper function.
++ *
++ * These registers are in another clock domain to the processor, access is via
++ * some bridging registers
++ *
++ * @param ap hardware with the registers in
++ * @param sc_reg the SATA PHY register
++ * @param val the value to write into the register
++ */
++static int ox800sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
++{
++ u32 *ioaddr = ox800sata_get_link_base(ap);
++ __ox800sata_scr_write(ioaddr, 0x20 + (sc_reg * 4), val);
++ return 0;
++}
++
++/**
++ * port_start() is called just after the data structures for each port are
++ * initialized. Typically this is used to alloc per-port DMA buffers, tables
++ * rings, enable DMA engines and similar tasks.
++ *
++ * @return 0 = success
++ * @param ap hardware with the registers in
++ */
++static int ox800sata_port_start(struct ata_port *ap)
++{
++ ox800sata_private_data* pd;
++ struct device* pdev = ap->host->dev;
++
++ ap->prd = dma_alloc_coherent(pdev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_DMA);
++ if (!ap->prd) {
++ return -ENOMEM;
++ }
++
++ /* allocate port private data memory and attach to port */
++ if (!ap->private_data) {
++ ap->private_data = kmalloc(sizeof(ox800sata_private_data), GFP_KERNEL);
++ }
++
++ if (!ap->private_data) {
++ return -ENOMEM;
++ }
++
++ pd = (ox800sata_private_data* )ap->private_data;
++ pd->DmaChannel = 0;
++ pd->sg_entries = 0;
++
++ DPRINTK("ap = %p, pd = %p\n",ap,ap->private_data);
++
++ // Allocate DMA SG entries
++ if (oxnas_dma_alloc_sg_entries(&pd->sg_entries, CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES)) {
++ printk(KERN_WARNING "ox800sata_port_start() Failed to obtain DMA SG entries\n");
++ return -ENOMEM;
++ }
++
++ // Hold on to a DMA channel for the life of the SATA driver
++ pd->DmaChannel = oxnas_dma_request(1);
++ if (!pd->DmaChannel) {
++ printk(KERN_WARNING "ox800sata_port_start() Failed to obtain DMA channel\n");
++ return -ENOMEM;
++ }
++
++ /* declare a work item to spot when a command finishes */
++ INIT_WORK(&(pd->spot_the_end_work.worker), &ox800sata_spot_the_end);
++
++ /* initialise to zero */
++ pd->ErrorsWithNoCommamnd = 0;
++ pd->port_disabled = 0;
++ pd->int_status = 0;
++ pd->in_cleanup = 0;
++
++ /* store the ata_port painter in the driver structure (BAD, should really
++ be in the device) */
++ if (ox800sata_get_io_base(ap) == (u32*)SATA0_REGS_BASE) {
++ ox800sata_driver.ap[0] = ap;
++ } else if (ox800sata_get_io_base(ap) == (u32*)SATA1_REGS_BASE) {
++ ox800sata_driver.ap[1] = ap;
++ }
++
++ // turn ata core on
++ writel((1 << SYS_CTRL_CKEN_SATA_BIT), SYS_CTRL_CKEN_SET_CTRL);
++
++ /* post reset init needs to be called for both ports as there's one reset
++ for both ports*/
++ if (ox800sata_driver.ap[0]) {
++ ox800sata_post_reset_init(ox800sata_driver.ap[0]);
++ }
++ if (ox800sata_driver.ap[1]) {
++ ox800sata_post_reset_init(ox800sata_driver.ap[1]);
++ }
++
++ return 0;
++}
++
++static void ox800sata_post_reset_init(struct ata_port* ap)
++{
++ u32 patience;
++ u32* link_addr = ox800sata_get_link_base(ap);
++ u32* ioaddr = ox800sata_get_io_base(ap);
++ uint dev;
++
++ /* turn on phy error detection by removing the masks */
++ writel(0x30003, link_addr + OX800SATA_LINK_DATA );
++ wmb();
++ writel(0x0C, link_addr + OX800SATA_LINK_WR_ADDR );
++ wmb();
++ for (patience = 0x100000;patience > 0;--patience)
++ {
++ if (readl(link_addr + OX800SATA_LINK_CONTROL) & 0x00000001)
++ break;
++ }
++
++ /* Set FIS modes to flush rather than softtrans */
++ writel(0xff, ioaddr + OX800SATA_REG_ACCESS);
++
++ /* go through all the devices and configure them */
++ for (dev = 0; dev < ATA_MAX_DEVICES; ++dev) {
++ if ( ap->device[dev].class == ATA_DEV_ATA )
++ ox800sata_dev_config( &(ap->device[dev]) );
++ }
++}
++
++/**
++ * port_stop() is called after ->host_stop(). It's sole function is to
++ * release DMA/memory resources, now that they are no longer actively being
++ * used.
++ */
++static void ox800sata_port_stop(struct ata_port *ap)
++{
++ ox800sata_private_data* pd = (ox800sata_private_data* )ap->private_data;
++
++ DPRINTK("\n");
++
++ if (pd->DmaChannel) {
++ oxnas_dma_free(pd->DmaChannel);
++ pd->DmaChannel = 0;
++ }
++
++ if (pd->sg_entries) {
++ oxnas_dma_free_sg_entries(pd->sg_entries);
++ pd->sg_entries = 0;
++ }
++
++ kfree(pd);
++}
++
++/**
++ * host_stop() is called when the rmmod or hot unplug process begins. The
++ * hook must stop all hardware interrupts, DMA engines, etc.
++ *
++ * @param ap hardware with the registers in
++ */
++static void ox800sata_host_stop(struct ata_host *host_set)
++{
++ DPRINTK("\n");
++}
++
++/**
++ * PATA device presence detection
++ * @param ap ATA channel to examine
++ * @param device Device to examine (starting at zero)
++ * @return true if something found
++ *
++ * This technique was originally described in
++ * Hale Landis's ATADRVR (www.ata-atapi.com), and
++ * later found its way into the ATA/ATAPI spec.
++ *
++ * Write a pattern to the ATA shadow registers,
++ * and if a device is present, it will respond by
++ * correctly storing and echoing back the
++ * ATA shadow register contents.
++ *
++ * LOCKING:
++ * caller.
++ */
++static unsigned int ox800sata_devchk(struct ata_port *ap,unsigned int device)
++{
++ DPRINTK("\n");
++
++ return 0; /* nothing found */
++}
++
++static void ox800sata_pio_start(struct work_struct *work)
++{
++ u32 burst_reg;
++ struct ata_port *ap = container_of(work, struct ata_port, port_task.work);
++ ox800sata_private_data* pd = (ox800sata_private_data*)ap->private_data;
++ struct ata_queued_cmd* qc = ap->port_task_data;
++ u32* ioaddr = ox800sata_get_io_base(ap);
++ unsigned long flags = 0;
++
++ // We check for DMA completion from ISR which cannot wait for all DMA channel
++ // housekeeping to complete, so need to wait here is case we try to reuse
++ // channel before that housekeeping has completed
++ while (oxnas_dma_is_active(pd->DmaChannel)) {
++ printk(KERN_WARNING "PIO start Channel still active\n");
++ }
++
++ if (qc->tf.protocol != ATA_PROT_NODATA) {
++ oxnas_dma_direction_t direction = (qc->dma_dir == DMA_FROM_DEVICE) ?
++ OXNAS_DMA_FROM_DEVICE :
++ OXNAS_DMA_TO_DEVICE;
++
++ /* Do not use DMA callback */
++ oxnas_dma_set_callback(pd->DmaChannel, OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
++
++ /* map memory for dma */
++ dma_map_sg(NULL, qc->__sg, qc->n_elem, qc->dma_dir);
++
++ /* setup a scatter gather dma */
++ oxnas_dma_device_set_sg(pd->DmaChannel,
++ direction,
++ qc->__sg,
++ qc->n_elem,
++ &oxnas_sata_dma_settings,
++ OXNAS_DMA_MODE_INC);
++
++ oxnas_dma_start(pd->DmaChannel);
++
++ /* turn on the fifo */
++ burst_reg = readl( ioaddr + OX800SATA_BURST_CONTROL );
++ burst_reg &= ~OX800SATA_BBC_DREQ_DIS;
++ writel(burst_reg, ioaddr + OX800SATA_BURST_CONTROL);
++
++ if (oxnas_dma_is_active(pd->DmaChannel)) {
++ /* if the DMA is still busy, schedule a task to poll again in 1 ms */
++ ata_port_queue_task(ap, ox800sata_pio_task, qc, ATA_SHORT_PAUSE);
++ return;
++ }
++
++ /* cleanup DMA */
++ dma_unmap_sg(NULL, qc->__sg, qc->n_elem, qc->dma_dir);
++ } else {
++ /* if the core is still busy, reschedule */
++ if (readl(ioaddr + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY) {
++ ata_port_queue_task(ap, ox800sata_pio_task, qc, ATA_SHORT_PAUSE);
++ return;
++ }
++ }
++
++ /* notify of completion */
++ PretendDRQIsClear = 1;
++ qc->err_mask = ac_err_mask(ata_chk_status(ap));
++ spin_lock_irqsave(ap->lock, flags);
++ ap->ops->irq_on(ap);
++ ata_qc_complete(qc);
++ spin_unlock_irqrestore(ap->lock, flags);
++}
++
++/**
++ * This is the top level of the PIO task. It is responsible for organising the
++ * transfer of data, collecting and reacting to status changes and notification
++ * of command completion.
++ *
++ */
++static void ox800sata_pio_task(struct work_struct *work)
++{
++ struct ata_port *ap = container_of(work, struct ata_port, port_task.work);
++ struct ata_queued_cmd *qc = ap->port_task_data;
++ unsigned long flags = 0;
++
++ if (qc->tf.protocol != ATA_PROT_NODATA) {
++ ox800sata_private_data* pd = (ox800sata_private_data* )ap->private_data;
++
++ if (oxnas_dma_is_active(pd->DmaChannel)) {
++ /* if the DMA is still busy, re-schedule the task */
++ /* try again in 1 ms */
++ ata_port_queue_task(ap, ox800sata_pio_task, qc, ATA_SHORT_PAUSE);
++ return;
++ }
++
++ /* cleanup DMA */
++ dma_unmap_sg(NULL, qc->__sg, qc->n_elem, qc->dma_dir);
++ } else {
++ u32* ioaddr = ox800sata_get_io_base(ap);
++
++ /* if the core is still busy, reschedule */
++ if (readl(ioaddr + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY) {
++ ata_port_queue_task(ap, ox800sata_pio_task, qc, ATA_SHORT_PAUSE);
++ return;
++ }
++ }
++
++ /* notify of completion */
++ PretendDRQIsClear = 1;
++ qc->err_mask = ac_err_mask(ata_chk_status(ap));
++ spin_lock_irqsave(ap->lock, flags);
++ ap->ops->irq_on(ap);
++ ata_qc_complete(qc);
++ spin_unlock_irqrestore(ap->lock, flags);
++}
++
++static void ox800sata_bmdma_stop(struct ata_queued_cmd *qc)
++{
++ struct ata_port *ap = qc->ap;
++ ox800sata_private_data* private_data = (ox800sata_private_data*)ap->private_data;
++
++ /* Check if DMA is in progress, if so abort */
++ if (oxnas_dma_is_active(private_data->DmaChannel)) {
++ /*
++ * Attempt to abort any current transfer:
++ * Abort DMA transfer at the DMA controller,
++ */
++ printk(KERN_ERR "ox800sata_bmdma_stop - aborting DMA\n");
++
++ oxnas_dma_abort(private_data->DmaChannel);
++
++ /* perform core cleanups and resets */
++ ox800sata_timeout_cleanup(ap);
++ }
++}
++
++/**
++ *
++ */
++static void ox800sata_timeout_cleanup( struct ata_port *ap ) {
++ u32* io_base = ox800sata_get_io_base(ap);
++ u32* bbp_base = ox800sata_get_bbp_base();
++ int idle;
++ u32 reg;
++ int loops;
++
++ /* Test SATA core idle state */
++ CrazyDumpDebug(ap);
++ idle = !(readl(io_base + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY);
++
++
++ printk(KERN_ERR "ox800sata_timeout_cleanup() ata%u idle = %d\n", ap->print_id, idle);
++
++ if (!idle) {
++ /*
++ * Assert SATA core and burst buffer port Force_EOT
++ */
++ printk(KERN_INFO "ox800sata_timeout_cleanup - aborting SATA... (may take upto 5 seconds)\n");
++
++ reg = readl(io_base + OX800SATA_DEVICE_CONTROL);
++ reg |= OX800SATA_DEVICE_CONTROL_ABORT;
++ writel(reg, io_base + OX800SATA_DEVICE_CONTROL);
++
++ reg = readl(bbp_base + OX800SATA_BURST_CONTROL);
++ reg |= OX800SATA_BBC_FORCE_EOT;
++ writel(reg, bbp_base + OX800SATA_BURST_CONTROL);
++
++ /* Wait for SATA core to go idle */
++ idle = 0;
++ loops = SATA_ABORT_WAIT_MS;
++ while(1) {
++ /* Test SATA core idle state */
++ idle = !(readl(io_base + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY);
++ if (idle || (loops-- <= 0)) {
++ break;
++ }
++ /* Wait a millisecond before testing again */
++ udelay(1000);
++ }
++
++ /* Deassert SATA core abort - BBP Force_EOT is self-clearing` */
++ reg = readl(io_base + OX800SATA_DEVICE_CONTROL);
++ reg &= ~OX800SATA_DEVICE_CONTROL_ABORT;
++ writel(reg, io_base + OX800SATA_DEVICE_CONTROL);
++
++ DPRINTK("idle = %d, %d loops remaining\n", idle, loops);
++
++ if (!idle) {
++ /*
++ * SATA core did not go idle, so attempt a core reset:
++ * Assert both SATA core internal reset and ORB4 srst
++ * Deassert both SATA core internal reset and ORB4 srst
++ */
++#if 0
++ printk(KERN_INFO "ox800sata_timeout_cleanup - internal SATA reset... (may take upto 5 seconds)\n");
++
++ reg = readl(io_base + OX800SATA_SATA_CONTROL);
++ reg |= OX800SATA_SCTL_RESET;
++ writel(reg, io_base + OX800SATA_SATA_CONTROL);
++
++ reg = readl(io_base + OX800SATA_ORB4);
++ reg |= OX800SATA_ORB4_SRST;
++ writel(reg, io_base + OX800SATA_ORB4);
++
++ /* Wait for SATA core to go idle */
++ idle = 0;
++ loops = SATA_SRST_WAIT_MS;
++ while(1) {
++ /* Test SATA core idle state */
++ idle = !(readl(io_base + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY);
++ if (idle || (loops-- <= 0)) {
++ break;
++ }
++ /* Wait a millisecond before testing again */
++ udelay(1000);
++ }
++
++ reg = readl(io_base + OX800SATA_ORB4);
++ reg &= ~OX800SATA_ORB4_SRST;
++ writel(reg, io_base + OX800SATA_ORB4);
++
++ reg = readl(io_base + OX800SATA_SATA_CONTROL);
++ reg &= ~OX800SATA_SCTL_RESET;
++ writel(reg, io_base + OX800SATA_SATA_CONTROL);
++ udelay(1000);
++
++ DPRINTK("idle = %d, %d loops remaining\n", idle, loops);
++#endif
++ idle = !(readl(io_base + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY);
++ if (!idle) {
++ /*
++ * SATA core did not go idle, so cause a SATA core reset from the RPS
++ * NB It may be required to reset both SATA cores if have a dual system
++ */
++ printk(KERN_INFO "ox800sata_timeout_cleanup - RPS SATA core reset\n");
++
++ writel(1UL << SYS_CTRL_RSTEN_SATA_BIT, SYS_CTRL_RSTEN_SET_CTRL);
++ udelay(1000);
++ writel(1UL << SYS_CTRL_RSTEN_SATA_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
++
++ /* Read SATA core idle state */
++ idle = !(readl(io_base + OX800SATA_SATA_COMMAND) & CMD_CORE_BUSY);
++
++ printk(KERN_INFO"idle = %d\n", idle);
++
++ /* Perform any SATA core re-initialisation after reset */
++ /* post reset init needs to be called for both ports as there's one reset
++ for both ports*/
++ if (ox800sata_driver.ap[0])
++ ox800sata_post_reset_init(ox800sata_driver.ap[0]);
++ if (ox800sata_driver.ap[1])
++ ox800sata_post_reset_init(ox800sata_driver.ap[1]);
++ }
++ }
++ }
++}
++
++/**
++ * bmdma_status return a made up version of a BMDMA status register
++ *
++ * @param ap Hardware with the registers in
++ * @return the value ATA_DMA_INTR if the interrupt came from the DMA finishing
++ */
++static u8 ox800sata_bmdma_status(struct ata_port *ap)
++{
++ ox800sata_private_data* PrivateData ;
++ PrivateData = (ox800sata_private_data* )ap->private_data;
++
++ {
++ u32 interrupt_status;
++ u32 *ioaddr = ox800sata_get_io_base(ap);
++ interrupt_status = readl(ioaddr + OX800SATA_INT_STATUS );
++ DPRINTK(" irq bits are %08x \n",interrupt_status);
++ }
++/* if( oxnas_dma_is_active( PrivateData->DmaChannel ) )
++ {
++ CrazyDumpDebug(ap);
++ return 0;
++ }
++ else*/
++ {
++ return ATA_DMA_INTR;
++ }
++}
++
++/**
++ * turn on the interrupts from the ata drive
++ * wait for idle, clear any pending interrupts.
++ *
++ * @param ap Hardware with the registers in
++ */
++static u8 ox800sata_irq_on(struct ata_port *ap)
++{
++ u32* ioaddr = ox800sata_get_io_base(ap);
++ u8 tmp;
++
++ //DPRINTK(KERN_INFO"ox800sata_irq_on\n");
++
++ /* enable End of command interrupt */
++ writel(OX800SATA_INT_END_OF_CMD, ioaddr + OX800SATA_INT_CLEAR);
++ writel(OX800SATA_INT_END_OF_CMD, ioaddr + OX800SATA_INT_ENABLE);
++ tmp = ata_wait_idle(ap);
++
++ return tmp;
++}
++
++/**
++ * Acknowledges any pending interrupts, by clearing them, but not disabling
++ * them.
++ *
++ * @param ap Hardware with the registers in
++ */
++static u8 ox800sata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
++{
++ u32* ioaddr = ox800sata_get_io_base(ap);
++ unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
++ u8 status;
++
++ //DPRINTK(KERN_INFO"921ish_irq_ack\n");
++ status = ata_busy_wait(ap, bits, 1000);
++ if (status & bits)
++ {
++ DPRINTK("abnormal status 0x%X\n", status);
++ }
++
++ /* clear the end of command interrupt bit */
++ writel(OX800SATA_INT_END_OF_CMD, ioaddr + OX800SATA_INT_CLEAR);
++
++ return status;
++}
++
++/**
++ * Outputs all the registers in the SATA core for diagnosis of faults.
++ *
++ * @param ap Hardware with the registers in
++ */
++static void CrazyDumpDebug(struct ata_port *ap)
++{
++#ifdef CRAZY_DUMP_DEBUG
++ u32 offset;
++ u32 result;
++ u32 patience;
++ u32* ioaddr;
++
++ /* IRQ flags for calling port */
++ {
++ ox800sata_private_data* PrivateData = (ox800sata_private_data* )ap->private_data;
++ printk("IRQ %08x\n",PrivateData->int_status);
++ }
++
++ /* port 0 */
++ ioaddr = (u32* )SATA0_REGS_BASE;
++ printk("Port 0 High level registers\n");
++ for(offset = 0; offset < 32;offset++)
++ {
++ printk("[%02x] %08x\n", offset * 4, readl(ioaddr + offset));
++ }
++
++ printk("Port 0 link layer registers\n");
++ ioaddr = (u32* )SATA0_LINK_REGS_BASE;
++ for(offset = 0; offset < 15;++offset)
++ {
++ writel( (offset*4), ioaddr + OX800SATA_LINK_RD_ADDR );
++ wmb();
++
++ for (patience = 0x100000;patience > 0;--patience)
++ {
++ if (readl(ioaddr + OX800SATA_LINK_CONTROL) & 0x00000001)
++ break;
++ }
++
++ result = readl(ioaddr + OX800SATA_LINK_DATA);
++ printk("[%02x] %08x\n", offset*4, result);
++ }
++
++ /* port 1 */
++ ioaddr = (u32* )SATA1_REGS_BASE;
++ printk("Port 1 High level registers\n");
++ for(offset = 0; offset < 32;offset++)
++ {
++ printk("[%02x] %08x\n", offset * 4, readl(ioaddr + offset));
++ }
++
++ printk("Port 1 link layer registers\n");
++ ioaddr = (u32* )SATA1_LINK_REGS_BASE;
++ for(offset = 0; offset < 15;++offset)
++ {
++ writel( (offset*4), ioaddr + OX800SATA_LINK_RD_ADDR );
++ wmb();
++
++ for (patience = 0x100000;patience > 0;--patience)
++ {
++ if (readl(ioaddr + OX800SATA_LINK_CONTROL) & 0x00000001)
++ break;
++ }
++
++ result = readl(ioaddr + OX800SATA_LINK_DATA);
++ printk("[%02x] %08x\n", offset*4, result);
++ }
++
++ oxnas_dma_dump_registers();
++#endif
++}
++
++/**************************************************************************
++* DEVICE CODE
++**************************************************************************/
++
++/**
++ * Describes the identity of the SATA core and the resources it requires
++ */
++static struct resource ox800sata_port0_resources[] = {
++ {
++ .name = "sata_port_0_registers",
++ .start = SATA0_REGS_BASE,
++ .end = (SATA0_LINK_REGS_BASE + 64),
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "sata_irq",
++ .start = SATA_1_INTERRUPT,
++ .flags = IORESOURCE_IRQ,
++ }
++};
++
++static struct resource ox800sata_port1_resources[] = {
++ {
++ .name = "sata_port_1_registers",
++ .start = SATA1_REGS_BASE,
++ .end = (SATA1_LINK_REGS_BASE + 64),
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "sata_irq",
++ .start = SATA_2_INTERRUPT,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device ox800sata_dev0 =
++{
++ .name = DRIVER_NAME,
++ .id = 0,
++ .num_resources = 2,
++ .resource = ox800sata_port0_resources,
++ .dev.coherent_dma_mask = 0xffffffff,
++};
++
++static struct platform_device ox800sata_dev1 =
++{
++ .name = DRIVER_NAME,
++ .id = 1,
++ .num_resources = 2,
++ .resource = ox800sata_port1_resources,
++ .dev.coherent_dma_mask = 0xffffffff,
++};
++
++/**
++ * module initialisation
++ * @return success is 0
++ */
++static int __init ox800sata_device_init( void )
++{
++ int ret;
++
++ DPRINTK("\n");
++
++ {
++ // register the ata device for the driver to find
++ ret = platform_device_register( &ox800sata_dev0 );
++ DPRINTK(" %i\n", ret);
++ }
++
++#ifndef SATA_OXNAS_SINGLE_SATA
++ {
++ // register the ata device for the driver to find
++ ret = platform_device_register( &ox800sata_dev1 );
++ DPRINTK(" %i\n", ret);
++ }
++#endif /* SATA_OXNAS_SINGLE_SATA */
++
++ return ret;
++}
++
++/**
++ * module cleanup
++ */
++static void __exit ox800sata_device_exit( void )
++{
++ platform_device_unregister( &ox800sata_dev0 );
++ platform_device_unregister( &ox800sata_dev1 );
++}
++
++/**
++ * Returns accumulated RAID faults and then clears the accumulation
++ * @return accumulated RAID faults indicated by set bits
++ */
++int oxnassata_RAID_faults( void ) {
++ int temp = ox800sata_accumulated_RAID_faults;
++ ox800sata_accumulated_RAID_faults = 0;
++ return temp;
++}
++
++/**
++ * Returns ox800 port number the request queue is serviced by.
++ *
++ * @param queue The queue under investigation.
++ * @return The ox800 sata port number servicing the queue or -1 if not found.
++ */
++int oxnassata_get_port_no(struct request_queue* q)
++{
++ struct ata_port* ap = 0;
++ struct scsi_device* sdev = 0;
++
++ /* check port 0 */
++ ap = ox800sata_driver.ap[0];
++ if (ap)
++ shost_for_each_device(sdev, ap->scsi_host) {
++ if (sdev->request_queue == q) {
++ DPRINTK("Queue %p on port 0\n", q);
++ return 0;
++ }
++ }
++
++ /* check port 1 */
++ ap = ox800sata_driver.ap[1];
++ if (ap)
++ shost_for_each_device(sdev, ap->scsi_host) {
++ if (sdev->request_queue == q) {
++ DPRINTK("Queue %p on port 1\n", q);
++ return 1;
++ }
++ }
++
++ /* not found */
++ return -1;
++}
++
++/**
++ * @return true if all the drives attached to the internal SATA ports use the
++ * same LBA size.
++ */
++int oxnassata_LBA_schemes_compatible( void )
++{
++ unsigned long flags0 ;
++ unsigned long flags1 ;
++ struct ata_port* ap ;
++
++ /* check port 0 */
++ ap = ox800sata_driver.ap[0];
++ if (ap)
++ flags0 = ap->device[0].flags & ATA_DFLAG_LBA48 ;
++ else
++ return 0;
++
++ /* check port 1 */
++ ap = ox800sata_driver.ap[1];
++ if (ap)
++ flags1 = ap->device[0].flags & ATA_DFLAG_LBA48 ;
++ else
++ return 0;
++
++ /* compare */
++ return (flags0 == flags1);
++}
++
++/**
++ * macros to register intiialisation and exit functions with kernal
++ */
++module_init(ox800sata_device_init);
++module_exit(ox800sata_device_exit);
++
++EXPORT_SYMBOL( oxnassata_RAID_faults );
++EXPORT_SYMBOL( oxnassata_get_port_no );
++EXPORT_SYMBOL( oxnassata_LBA_schemes_compatible );
+diff -Nurd linux-2.6.24/drivers/ata/ox810sata.c linux-2.6.24-oxe810/drivers/ata/ox810sata.c
+--- linux-2.6.24/drivers/ata/ox810sata.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/ata/ox810sata.c 2008-06-11 17:50:32.000000000 +0200
+@@ -0,0 +1,2423 @@
++/**************************************************************************
++ *
++ * Copyright (c) 2007 Oxford Semiconductor Ltd.
++ *
++ * 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, 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.
++ *
++ * Module Name:
++ * ox810sata.c
++ *
++ * Abstract:
++ * A driver to interface the 934 based sata core present in the ox810
++ * with libata and scsi
++ */
++
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/device.h>
++#include <linux/string.h>
++#include <linux/sysdev.h>
++#include <linux/module.h>
++#include <linux/leds.h>
++
++#include <scsi/scsi_host.h>
++#include <scsi/scsi_cmnd.h>
++#include <scsi/scsi_device.h>
++#include <asm/io.h>
++
++#include <linux/platform_device.h>
++#include <asm/arch/hardware.h>
++#include <asm/arch/dma.h>
++#include <asm/arch/memory.h>
++#include <asm/arch/ox810sata.h>
++
++#include <linux/proc_fs.h>
++
++/***************************************************************************
++* DEBUG CONTROL
++***************************************************************************/
++//#define SATA_DEBUG
++//#define SATA_DUMP_REGS
++//#define SATA_TF_DUMP
++//#define DEBUG_EOT_FAILURE
++#define ERROR_INJECTION
++
++#define CRAZY_DUMP_DEBUG
++#if 0
++typedef struct {
++ u32 a;
++ u32 d;
++ u32 w;
++} regaccess;
++static u32 regindex = 0;
++static regaccess regarray[1024];
++#endif
++
++#if 0
++ #ifdef writel
++ #undef writel
++ #endif
++ #define writel(v,a) {printk("[%p]<=%08x\n",a,v);*((volatile u32*)(a)) = v;}
++ //#define writel(vv,aa) {regarray[regindex].a=(aa); regarray[regindex].d=(vv); regarray[regindex].w=1; ++regindex; regindex &= 1023;*((volatile u32*)(aa)) = (vv);}
++#endif
++
++#if 0
++ #ifdef readl
++ #undef readl
++ #endif
++ static inline u32 myreadl(u32 a) {u32 v =(*((volatile u32*)(a)));printk("[%p]=>%08x\n",a,v);return v;}
++ //static inline u32 myreadl(u32 a) {u32 v =(*((volatile u32*)(a)));regarray[regindex].a=a; regarray[regindex].d=v; regarray[regindex].w=0; ++regindex; regindex &= 1023;return v;}
++ #define readl(a) (myreadl(a))
++#endif
++
++
++#include <linux/libata.h>
++/***************************************************************************
++* CONSTANTS
++***************************************************************************/
++
++#define DRIVER_AUTHOR "Oxford Semiconductor Ltd."
++#define DRIVER_DESC "934 SATA core controler"
++#define DRIVER_NAME "oxnassata"
++
++#define SATA_ABORT_WAIT_MS 5000
++#define SATA_SRST_WAIT_MS 5000
++
++/**************************************************************************
++* PROTOTYPES
++**************************************************************************/
++static int ox810sata_init_one(struct platform_device *);
++static int ox810sata_remove_one(struct platform_device *);
++
++static void ox810sata_dev_config(struct ata_port *, struct ata_device *);
++static void ox810sata_set_piomode(struct ata_port *, struct ata_device *);
++static void ox810sata_set_dmamode(struct ata_port *, struct ata_device *);
++static void ox810sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf);
++static void ox810sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
++static void ox810sata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
++static u8 ox810sata_check_status(struct ata_port *ap);
++static inline u8 ox810sata_check_altstatus(struct ata_port *ap);
++static void ox810sata_dev_select(struct ata_port *ap, unsigned int device);
++static void ox810sata_phy_reset(struct ata_port *ap);
++static void ox810sata_bmdma_setup(struct ata_queued_cmd *qc);
++static void ox810sata_bmdma_start(struct ata_queued_cmd *qc);
++static u8 ox810sata_bmdma_status(struct ata_port *ap);
++static struct ata_queued_cmd* ox810sata_qc_new(struct ata_port *ap);
++static void ox810sata_qc_free(struct ata_queued_cmd *qc);
++static unsigned int ox810sata_qc_issue(struct ata_queued_cmd *qc);
++static void ox810sata_eng_timeout(struct ata_port *ap);
++static irqreturn_t ox810sata_irq_handler(int, void *);
++static void ox810sata_eng_timeout(struct ata_port *ap);
++static void ox810sata_irq_clear(struct ata_port *);
++static int ox810sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
++static int ox810sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
++static int ox810sata_port_start(struct ata_port *ap);
++static void ox810sata_port_stop(struct ata_port *ap);
++static void ox810sata_host_stop(struct ata_host *host_set);
++static unsigned int ox810sata_devchk(struct ata_port *ap,unsigned int device);
++static u32* ox810sata_get_io_base(struct ata_port* ap);
++static u8 ox810sata_irq_on(struct ata_port *ap);
++static void ox810sata_bmdma_stop(struct ata_queued_cmd *qc);
++static void CrazyDumpDebug( void );
++static void ox810sata_spot_the_end(struct work_struct *work);
++static void ox810sata_timeout_cleanup(struct ata_port *ap);
++static void ox810sata_error_handler(struct ata_port *ap);
++static void ox810sata_reset_core(void);
++static int ox810sata_prereset(struct ata_link *link, unsigned long deadline);
++static int ox810sata_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline);
++static void ox810sata_postreset(struct ata_link *link, unsigned int *classes);
++static void ox810sata_pio_start(struct work_struct *work);
++static void ox810sata_pio_task(struct work_struct *work);
++static void ox810sata_post_reset_init(struct ata_port* ap);
++static u32 inline __ox810sata_scr_read(u32* core_addr, unsigned int sc_reg);
++static void __ox810sata_scr_write(u32* core_addr, unsigned int sc_reg, u32 val);
++#ifdef ERROR_INJECTION
++static int ox810sata_error_inject_show(char *page, char **start, off_t off, int count, int *eof, void *data);
++static int ox810sata_error_inject_store(struct file *file,const char __user *buffer,unsigned long count,void *data);
++#endif
++
++/**************************************************************************
++* STRUCTURES
++**************************************************************************/
++typedef struct
++{
++ struct kobject kobj;
++ struct platform_driver driver;
++ struct ata_port* ap[2];
++ u32 error_inject;
++ struct workqueue_struct* spot_the_end_q;
++ u32 hw_raid_active;
++ struct ata_port* active_port;
++} ox810sata_driver_t;
++
++/**
++ * Struct to hold per-port private (specific to this driver) data (still
++ * un-researched).
++ */
++typedef struct
++{
++ oxnas_dma_channel_t* DmaChannel;
++ oxnas_dma_sg_entry_t* sg_entries;
++ struct spot_the_end_work_s {
++ struct work_struct worker;
++ struct ata_port* ap;
++ } spot_the_end_work;
++ u32 ErrorsWithNoCommamnd;
++ u32 int_status;
++ u32 in_cleanup;
++} ox810sata_private_data;
++
++ox810sata_driver_t ox810sata_driver =
++{
++ .driver =
++ {
++ .driver.name = DRIVER_NAME,
++ .driver.bus = &platform_bus_type,
++ .probe = ox810sata_init_one,
++ .remove = ox810sata_remove_one,
++ },
++ .ap = {0,0},
++ .error_inject = 0,
++ .hw_raid_active = 0,
++ .active_port = 0,
++};
++
++/** If we were writing this in C++ then we would be deriving a subclass of
++ata_port, these would be the overridden functions*/
++static struct ata_port_operations ox810sata_port_ops =
++{
++ .dev_config = ox810sata_dev_config,
++ .set_piomode = ox810sata_set_piomode,
++ .set_dmamode = ox810sata_set_dmamode,
++ .tf_load = ox810sata_tf_load,
++ .tf_read = ox810sata_tf_read,
++ .exec_command = ox810sata_exec_command,
++ .check_status = ox810sata_check_status,
++ .check_altstatus = ox810sata_check_altstatus,
++ .dev_select = ox810sata_dev_select,
++ .phy_reset = ox810sata_phy_reset,
++ .bmdma_setup = ox810sata_bmdma_setup,
++ .bmdma_start = ox810sata_bmdma_start,
++ .bmdma_stop = ox810sata_bmdma_stop,
++ .bmdma_status = ox810sata_bmdma_status,
++ .qc_new = ox810sata_qc_new,
++ .qc_free = ox810sata_qc_free,
++ .qc_prep = ata_qc_prep,
++ .qc_issue = ox810sata_qc_issue,
++ .eng_timeout = ox810sata_eng_timeout,
++ .irq_handler = ox810sata_irq_handler,
++ .irq_clear = ox810sata_irq_clear,
++ .scr_read = ox810sata_scr_read,
++ .scr_write = ox810sata_scr_write,
++ .port_start = ox810sata_port_start,
++ .port_stop = ox810sata_port_stop,
++ .host_stop = ox810sata_host_stop,
++ .dev_chk = ox810sata_devchk,
++ .irq_on = ox810sata_irq_on,
++ .pio_task = ox810sata_pio_start,
++ .error_handler = ox810sata_error_handler,
++ .post_internal_cmd = ox810sata_bmdma_stop,
++};
++
++/** the scsi_host_template structure describes the basic capabilities of libata
++and our 921 core to the SCSI framework, it contains the addresses of functions
++in the libata library that handle top level comands from the SCSI library */
++static struct scsi_host_template ox810sata_sht =
++{
++ .module = THIS_MODULE,
++ .name = DRIVER_NAME,
++ .ioctl = ata_scsi_ioctl,
++ .queuecommand = ata_scsi_queuecmd,
++/* .eh_strategy_handler= ata_scsi_error,*/
++ .can_queue = ATA_DEF_QUEUE,
++ .this_id = ATA_SHT_THIS_ID,
++/* .sg_tablesize = LIBATA_MAX_PRD,*/
++ .sg_tablesize = CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES,
++ .max_sectors = 256, // Use the full 28-bit SATA value
++ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
++ .emulated = ATA_SHT_EMULATED,
++ .use_clustering = ATA_SHT_USE_CLUSTERING,
++ .proc_name = DRIVER_NAME,
++ .dma_boundary = ~0UL, // NAS has no DMA boundary restrictions
++ .slave_configure = ata_scsi_slave_config,
++ .bios_param = ata_std_bios_param,
++ .unchecked_isa_dma = 0,
++
++};
++
++/** after PIO read operations, DRQ can remain set even when all the data has
++been read, when set, PretendDRQIsClear will mask out the DRQ bit in
++ox810sata_check_status operation */
++static char PretendDRQIsClear;
++
++/**
++ * used as a store for atomic test and set operations used to coordinate so
++ * that only one port is processing comnmands at any time */
++static unsigned long ox810sata_command_active = 0;
++
++/**
++ * A record of which drives have accumulated raid faults. A set bit indicates
++ * a fault has occured on that drive */
++static u32 ox810sata_accumulated_RAID_faults = 0;
++
++/**************************************************************************/
++MODULE_LICENSE("GPL");
++MODULE_VERSION(1.0);
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
++
++/**************************************************************************
++* FUCTIONS
++* prefix all with "ox810sata_"
++**************************************************************************/
++
++/**
++ * Gets the base of the ox810 port associated with the ata-port as known
++ * by lib-ata, The value returned changes to the single RAID port when
++ * hardware RAID commands are active.
++ *
++ * @param ap pointer to the appropriate ata_port structure
++ * @return the base address of the SATA core
++ */
++static inline u32* ox810sata_get_tfio_base(struct ata_port* ap)
++{
++ if ((ox810sata_driver.hw_raid_active) &&
++ (ox810sata_driver.active_port == ap)) {
++ return (u32* )SATARAID_REGS_BASE;
++ } else {
++ return (u32* )ap->host->iomap;
++ }
++}
++
++/**
++ * Gets the base address of the ata core from the ata_port structure. The value
++ * returned will remain the same when hardware raid is active.
++ *
++ * @param ap pointer to the appropriate ata_port structure
++ * @return the base address of the SATA core
++ */
++static inline u32* ox810sata_get_io_base(struct ata_port* ap)
++{
++ return (u32* )ap->host->iomap;
++}
++
++/**
++ * Turns on the cores clock and resets it
++ */
++static void ox810sata_reset_core( void ){
++ // Enable the clock to the SATA block
++ writel(1UL << SYS_CTRL_CKEN_SATA_BIT, SYS_CTRL_CKEN_SET_CTRL);
++ wmb();
++
++ // reset Controller, Link and PHY
++ writel( (1UL << SYS_CTRL_RSTEN_SATA_BIT) |
++ (1UL << SYS_CTRL_RSTEN_SATA_LINK_BIT) |
++ (1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT), SYS_CTRL_RSTEN_SET_CTRL);
++ wmb();
++ udelay(50);
++
++ // un-reset the PHY, then Link and Controller
++ writel(1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
++ udelay(50);
++ writel( (1UL << SYS_CTRL_RSTEN_SATA_LINK_BIT) |
++ (1UL << SYS_CTRL_RSTEN_SATA_BIT), SYS_CTRL_RSTEN_CLR_CTRL);
++ udelay(50);
++}
++
++/**
++ * port capabilities for the ox810 sata ports.
++ */
++static const struct ata_port_info ox810sata_port_info = {
++ .flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET | ATA_FLAG_NO_LEGACY,
++ .pio_mask = 0x1f, /* pio modes 0..4*/
++ .mwdma_mask = 0x07, /* mwdma0-2 */
++ .udma_mask = 0x7f, /* udma0-5 */
++ .port_ops = &ox810sata_port_ops,
++};
++
++/**
++ * The driver probe function.
++ * Registered with the amba bus driver as a parameter of ox810sata_driver.bus
++ * it will register the ata device with kernel first performing any
++ * initialisation required (if the correct device is present).
++ * @param pdev Pointer to the 921 device structure
++ * @return 0 if no errors
++ */
++static int ox810sata_init_one(struct platform_device* pdev)
++{
++ u32 version;
++#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
++ unsigned long reg;
++#endif // CONFIG_SATA_OXNAS_DISK_LIGHT
++ struct ata_host *host;
++ void __iomem* iomem;
++ const struct ata_port_info* port_info[] = { &ox810sata_port_info, NULL };
++ struct resource* memres = platform_get_resource(pdev, IORESOURCE_MEM, 0 );
++ int irq = platform_get_irq(pdev, 0);
++
++ /* check resourses for sanity */
++ if ((memres == NULL) || (irq < 0)) {
++ return 0;
++ }
++ iomem = (void __iomem* ) memres->start;
++
++ /* check we support this version of the core */
++ version = readl(((u32* )iomem) + OX810SATA_VERSION);
++ switch (version) {
++ case OX810SATA_CORE_VERSION:
++ printk(KERN_INFO"ox810sata: OX810 sata core.\n");
++ break;
++ default:
++ printk(KERN_ERR"ox810sata: unknown sata core (version register = 0x%08x)\n",version);
++ return 0;
++ break;
++ }
++
++ /* initialise a work queue to spot the end of transfers */
++ ox810sata_driver.spot_the_end_q = create_singlethread_workqueue("sata-endQ");
++ if (!ox810sata_driver.spot_the_end_q) {
++ printk(KERN_ERR DRIVER_NAME " Couldn't create a work queue.\n");
++ return -1;
++ }
++
++#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
++ /* setup path */
++ reg = ~(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE) & readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
++ writel(reg, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
++ reg = ~(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE) & readl(SYS_CTRL_GPIO_SECSEL_CTRL_0);
++ writel(reg, SYS_CTRL_GPIO_SECSEL_CTRL_0);
++ reg = ~(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE) & readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0);
++ writel(reg, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
++
++ /* enable output */
++ writel(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_ENABLE);
++
++ /* disk light off */
++ writel(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_CLEAR);
++#endif /* CONFIG_SATA_OXNAS_DISK_LIGHT */
++
++ /* setup the probe_ent structure which is basically info about the ports
++ capabilities */
++
++ /* allocate memory and check */
++ host = ata_host_alloc_pinfo(&(pdev->dev), port_info, OX810SATA_MAX_PORTS);
++ if (!host) {
++ printk(KERN_ERR DRIVER_NAME " Couldn't create an ata host.\n");
++ destroy_workqueue(ox810sata_driver.spot_the_end_q);
++ }
++
++ /* set to base of ata core */
++ host->iomap = iomem;
++
++ /* call ata_device_add and begin probing for drives*/
++ ata_host_activate(host, irq, ox810sata_irq_handler, IRQF_SHARED, &ox810sata_sht);
++
++ return 0;
++}
++
++/**
++ * Called when the amba bus tells this device to remove itself.
++ * @param pdev pointer to the device that needs to be shutdown
++ */
++static int ox810sata_remove_one(struct platform_device* pdev)
++{
++ struct ata_host *host_set = dev_get_drvdata( &(pdev->dev) );
++ struct ata_port *ap;
++ unsigned int i;
++
++ for (i = 0; i < host_set->n_ports; i++)
++ {
++ ap = host_set->ports[i];
++ scsi_remove_host( ap->scsi_host );
++ }
++
++ /** @TODO etc. */
++
++ // Disable the clock to the SATA block
++ writel(1UL << SYS_CTRL_CKEN_SATA_BIT, SYS_CTRL_CKEN_CLR_CTRL);
++
++ return 0;
++}
++
++/**
++ * module initialisation
++ * @return success
++ */
++static int __init ox810sata_init( void )
++{
++ int ret;
++
++ ret = platform_driver_register( &ox810sata_driver.driver );
++ DPRINTK(" %i\n", ret);
++
++#ifdef ERROR_INJECTION
++{
++ struct proc_dir_entry *res=create_proc_entry("ox810sata_errorinject",0,NULL);
++ if (res) {
++ res->read_proc=ox810sata_error_inject_show;
++ res->write_proc=ox810sata_error_inject_store;
++ res->data=NULL;
++ }
++ //create_proc_read_entry("ox810sata_errorinject", 0, NULL, ox810sata_error_inject_show, NULL);
++}
++#endif
++ return ret;
++}
++
++/**
++ * module cleanup
++ */
++static void __exit ox810sata_exit( void )
++{
++ platform_driver_unregister( &ox810sata_driver.driver );
++}
++
++/**
++ * macros to register intiialisation and exit functions with kernal
++ */
++module_init(ox810sata_init);
++module_exit(ox810sata_exit);
++
++/**
++ * Called after IDENTIFY [PACKET] DEVICE is issued to each device found.
++ * Typically used to apply device-specific fixups prior to issue of
++ * SET FEATURES - XFER MODE, and prior to operation.
++ * @param port The port to configure
++ * @param pdev The hardware associated with controlling the port
++ */
++static void ox810sata_dev_config(struct ata_port *ap, struct ata_device* pdev)
++{
++ u32 reg;
++ u32 *ioaddr = ox810sata_get_io_base(ap);
++
++ /* Set the bits to put the interface into 28 or 48-bit node */
++ reg = readl(ioaddr + OX810SATA_DRIVE_CONTROL);
++
++ /* mask out the pair of bits associaed with each port */
++ reg &= ~(3 << (ap->port_no * 2));
++
++ /* set the mode pair associated with each port */
++ reg |= ((pdev->flags & ATA_DFLAG_LBA48) ? OX810SATA_DR_CON_48 :
++ OX810SATA_DR_CON_28) << (ap->port_no * 2);
++ writel(reg, ioaddr + OX810SATA_DRIVE_CONTROL);
++
++ /* if this is an ATA-6 disk, put the port into ATA-5 auto translate mode */
++ if (pdev->flags & ATA_DFLAG_LBA48) {
++ reg = readl(ioaddr + OX810SATA_PORT_CONTROL);
++ reg |= 2;
++ writel(reg, ioaddr + OX810SATA_PORT_CONTROL);
++ }
++}
++
++/**
++ * nothing to do
++ *
++ * @param port The port to configure
++ * @param pdev The hardware associated with controlling the port
++ */
++static void ox810sata_set_piomode(struct ata_port* port, struct ata_device* pdev)
++{
++}
++
++/**
++ * nothing to do
++ *
++ * @param port The port to configure
++ * @param pdev The hardware associated with controlling the port
++ */
++static void ox810sata_set_dmamode(struct ata_port* port, struct ata_device* pdev)
++{
++}
++
++/**
++ * Output the taskfile for diagnostic reasons, it will always appear in the
++ * debug output as if it's a task file being written.
++ * @param tf The taskfile to output
++ */
++static void tfdump(const struct ata_taskfile* tf)
++{
++ if (tf->flags & ATA_TFLAG_LBA48) {
++#ifdef SATA_TF_DUMP
++ printk("Cmd %x Ft %x%x, LBA-48 %02x%02x%02x%02x%02x%02x, nsect %02x%02x, ctl %02x, dev %x\n",
++#else // SATA_TF_DUMP
++ DPRINTK("Cmd %x Ft %x%x, LBA-48 %02x%02x%02x%02x%02x%02x, nsect %02x%02x, ctl %02x, dev %x\n",
++#endif // SATA_TF_DUMP
++ tf->command,
++
++ tf->hob_feature,
++ tf->feature,
++
++ tf->hob_lbah,
++ tf->hob_lbam,
++ tf->hob_lbal,
++ tf->lbah,
++ tf->lbam,
++ tf->lbal,
++
++ tf->hob_nsect,
++ tf->nsect,
++ tf->ctl,
++ tf->device );
++ } else {
++#ifdef SATA_TF_DUMP
++ printk("Cmd %x Ft %x, LBA-28 %01x%02x%02x%02x, nsect %02x, ctl %02x, dev %x\n",
++#else // SATA_TF_DUMP
++ DPRINTK("Cmd %x Ft %x, LBA-28 %01x%02x%02x%02x, nsect %02x, ctl %02x, dev %x\n",
++#endif // SATA_TF_DUMP
++ tf->command,
++
++ tf->feature,
++
++ tf->device & 0x0f,
++ tf->lbah,
++ tf->lbam,
++ tf->lbal,
++
++ tf->nsect,
++ tf->ctl,
++ tf->device );
++ }
++}
++
++/**
++ * called to write a taskfile into the ORB registers
++ * @param ap hardware with the registers in
++ * @param tf taskfile to write to the registers
++ */
++static void ox810sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
++{
++ u32 count = 0;
++ u32 Orb1 = 0;
++ u32 Orb2 = 0;
++ u32 Orb3 = 0;
++ u32 Orb4 = 0;
++ u32 Command_Reg;
++ u32 *ioaddr = ox810sata_get_tfio_base(ap);
++ unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
++
++ /* wait a maximum of 10ms for the core to be idle */
++ do {
++ Command_Reg = readl(ioaddr + OX810SATA_SATA_COMMAND);
++ if (!(Command_Reg & CMD_CORE_BUSY)) {
++ break;
++ }
++ count++;
++ udelay(50);
++ } while (count < 200);
++
++ /* if the control register has changed, write it */
++ if (tf->ctl != ap->last_ctl)
++ {
++ //DPRINTK("ap->last_ctl = %02x",ap->last_ctl);
++ Orb4 |= (tf->ctl) << 24;
++
++ /* write value to register */
++ writel(Orb4, ioaddr + OX810SATA_ORB4);
++
++ ap->last_ctl = tf->ctl;
++
++ /** @todo find a more elegant way to do this */
++ /* if the new control value is a soft reset, command the core to send a
++ control FIS */
++ if (tf->ctl & ATA_SRST) {
++ writel(CMD_WRITE_TO_ORB_REGS_NO_COMMAND, ioaddr + OX810SATA_SATA_COMMAND);
++ }
++ }
++
++ /* check if the ctl register has interrupts disabled or enabled and
++ modify the interrupt enable registers on the ata core as required */
++ if (tf->ctl & ATA_NIEN) {
++ /* interrupts disabled */
++ ox810sata_irq_clear(ap);
++ } else {
++ /* interrupts enabled */
++ ox810sata_irq_on(ap);
++ }
++
++ /* write 48 or 28 bit tf parameters */
++ if (is_addr) {
++ /* set LBA bit as it's an address */
++ Orb1 |= (tf->device & ATA_LBA) << 24;
++
++ if (tf->flags & ATA_TFLAG_LBA48) {
++ //DPRINTK(KERN_INFO" 48 bit tf load \n");
++ Orb1 |= ATA_LBA << 24;
++
++ Orb2 |= (tf->hob_nsect) << 8 ;
++
++ Orb3 |= (tf->hob_lbal) << 24;
++
++ Orb4 |= (tf->hob_lbam) << 0 ;
++ Orb4 |= (tf->hob_lbah) << 8 ;
++ Orb4 |= (tf->hob_feature)<< 16;
++ } else {
++ Orb3 |= (tf->device & 0xf)<< 24;
++ }
++
++ /* write 28-bit lba */
++ //DPRINTK(KERN_INFO" 28 bit tf load\n");
++ Orb2 |= (tf->nsect) << 0 ;
++ Orb2 |= (tf->feature) << 16;
++ Orb2 |= (tf->command) << 24;
++
++ Orb3 |= (tf->lbal) << 0 ;
++ Orb3 |= (tf->lbam) << 8 ;
++ Orb3 |= (tf->lbah) << 16;
++
++ Orb4 |= (tf->ctl) << 24;
++
++ /* write values to registers */
++ writel(Orb1, ioaddr + OX810SATA_ORB1 );
++ writel(Orb2, ioaddr + OX810SATA_ORB2 );
++ writel(Orb3, ioaddr + OX810SATA_ORB3 );
++ writel(Orb4, ioaddr + OX810SATA_ORB4 );
++ }
++
++ if (tf->flags & ATA_TFLAG_DEVICE) {
++ Orb1 |= (tf->device) << 24;
++
++ /* write value to register */
++ writel(Orb1, ioaddr + OX810SATA_ORB1);
++ }
++
++ tfdump(tf);
++}
++
++/**
++ * Called to read the hardware registers / DMA buffers, to
++ * obtain the current set of taskfile register values.
++ * @param ap hardware with the registers in
++ * @param tf taskfile to read the registers into
++ */
++static void ox810sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
++{
++ u32 *ioaddr = ox810sata_get_tfio_base(ap);
++
++ /* read the orb registers */
++ u32 Orb1 = readl(ioaddr + OX810SATA_ORB1);
++ u32 Orb2 = readl(ioaddr + OX810SATA_ORB2);
++ u32 Orb3 = readl(ioaddr + OX810SATA_ORB3);
++ u32 Orb4 = readl(ioaddr + OX810SATA_ORB4);
++
++ /* read common 28/48 bit tf parameters */
++ tf->device = (Orb1 >> 24);
++ tf->nsect = (Orb2 >> 0);
++ tf->feature = (Orb2 >> 16);
++ tf->command = ox810sata_check_status(ap);
++
++ /* read 48 or 28 bit tf parameters */
++ if (tf->flags & ATA_TFLAG_LBA48) {
++ //DPRINTK(KERN_INFO" 48 bit tf read \n");
++ tf->hob_nsect = (Orb2 >> 8) ;
++
++ tf->lbal = (Orb3 >> 0) ;
++ tf->lbam = (Orb3 >> 8) ;
++ tf->lbah = (Orb3 >> 16) ;
++ tf->hob_lbal = (Orb3 >> 24) ;
++
++ tf->hob_lbam = (Orb4 >> 0) ;
++ tf->hob_lbah = (Orb4 >> 8) ;
++ /* feature ext and control are write only */
++ } else {
++ /* read 28-bit lba */
++ //DPRINTK(KERN_INFO" 28 bit tf read\n");
++ tf->lbal = (Orb3 >> 0) ;
++ tf->lbam = (Orb3 >> 8) ;
++ tf->lbah = (Orb3 >> 16) ;
++ }
++
++ tfdump(tf);
++}
++
++/**
++ * Causes an ATA command, previously loaded with ->tf_load(), to be
++ * initiated in hardware. The command is written into the registers again just
++ * to be sure. All the other registers that are in Orb2 are also written at the
++ * same time. The command is initiated in hardware by a poke to the COMMAND
++ * register.
++ * @param ap hardware with the registers in
++ * @param tf taskfile to write to the registers
++ */
++static void ox810sata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
++{
++ u32 count =0;
++ u32 *ioaddr = ox810sata_get_tfio_base(ap);
++ u32 Orb2;
++ u32 Command_Reg;
++
++#ifdef ERROR_INJECTION
++ static u32 prand = 10;
++ if (ox810sata_driver.error_inject) {
++ u32 *portaddr = ox810sata_get_io_base(ap);
++ prand = prand ? prand - 1 : 100;
++ if ( prand < ox810sata_driver.error_inject) {
++ DPRINTK("ox810sata_exec_command: error injection on\n");
++ __ox810sata_scr_write( portaddr, 0x14 , 0xd );
++ } else {
++ __ox810sata_scr_write( portaddr, 0x14 , 0x1 );
++ DPRINTK("ox810sata_exec_command: error injection off\n");
++ }
++ }
++#endif
++
++ VPRINTK("\n");
++ /* Wait a maximum af 10ms for the core to go idle */
++ do {
++ Command_Reg = readl(ioaddr + OX810SATA_SATA_COMMAND);
++ if (!(Command_Reg & CMD_CORE_BUSY)) {
++ break;
++ }
++ count++;
++ udelay(50);
++ } while (count < 200);
++
++ /* write all the things in Orb 2 */
++ Orb2 = (tf->nsect) << 0 ;
++ if (tf->flags & ATA_TFLAG_LBA48) {
++ Orb2 |= (tf->hob_nsect) << 8;
++ }
++ Orb2 |= (tf->feature) << 16;
++ Orb2 |= (tf->command) << 24;
++ writel(Orb2 , ioaddr + OX810SATA_ORB2);
++ wmb();
++
++ do {
++ Command_Reg = readl(ioaddr + OX810SATA_SATA_COMMAND);
++ if (!(Command_Reg & CMD_CORE_BUSY)) {
++ break;
++ }
++ count++;
++ udelay(50);
++ } while (count < 200);
++
++ /* Command that the orb registers get written to drive */
++ Command_Reg &= ~SATA_OPCODE_MASK;
++ Command_Reg |= CMD_WRITE_TO_ORB_REGS;
++ writel(Command_Reg , ioaddr + OX810SATA_SATA_COMMAND);
++ wmb();
++}
++
++
++/**
++ * Reads the Status ATA shadow register from hardware. Due to a fault with PIO
++ * transfers, it it sometimes necessary to mask out the DRQ bit
++ * @param ap hardware with the registers in
++ * @return The status register
++ */
++static u8 ox810sata_check_status(struct ata_port *ap)
++{
++ u32 Reg;
++ u8 status;
++ u32 *ioaddr = ox810sata_get_tfio_base(ap);
++
++// VPRINTK(KERN_INFO"ox810sata_check_status ");
++
++ /* read byte 3 of Orb2 register */
++ status = readl(ioaddr + OX810SATA_ORB2) >> 24;
++
++ /* check for the drive going missing indicated by SCR status bits 0-3 = 0 */
++ if ( ox810sata_driver.hw_raid_active ) {
++ u32 Temp;
++ ox810sata_scr_read(ox810sata_driver.ap[0], SCR_STATUS, &Temp );
++ ox810sata_scr_read(ox810sata_driver.ap[1], SCR_STATUS, &Reg);
++ Reg |= Temp;
++ } else {
++ ox810sata_scr_read(ap, SCR_STATUS, &Reg );
++ }
++ if (!(Reg & 0x1)) {
++ status |= ATA_DF;
++ status |= ATA_ERR;
++ }
++ //VPRINTK("%02x\n",result);
++
++ return status;
++}
++
++/**
++ * Reads the alt status ATA shadow register from hardware.
++ * @param ap hardware with the registers in
++ * @return The alt status register
++ */
++static u8 ox810sata_check_altstatus(struct ata_port *ap)
++{
++ return readl(ox810sata_get_tfio_base(ap) + OX810SATA_ORB4) >> 24;
++}
++
++/**
++ * Use the method defined in the ATA specification to make either device 0,
++ * or device 1, active on the ATA channel. If we ever get port multipliers
++ * to work, this will be where they would switch.
++ *
++ * @param ap hardware with the registers in
++ * @param number of the device to talk to (0..)
++ */
++static void ox810sata_dev_select(struct ata_port *ap, unsigned int device)
++{
++}
++
++/**
++ * The very first step in the probe phase. Actions vary depending on the bus
++ * type, typically. After waking up the device and probing for device presence
++ * (PATA and SATA), typically a soft reset (SRST) will be performed. Drivers
++ * typically use the helper functions ata_bus_reset() or sata_phy_reset() for
++ * this hook.
++ *
++ * This should reset the SATA core and Phisical layer then jump back into the
++ * libata libraries for lots of other resetting
++ *
++ * @param ap hardware with the registers in
++ */
++static void ox810sata_phy_reset(struct ata_port *ap)
++{
++ u32 *ioaddr = ox810sata_get_io_base(ap);
++
++ DPRINTK(KERN_INFO "base = %p\n", ioaddr);
++
++ /* turn ata core on */
++ writel((1 << SYS_CTRL_CKEN_SATA_BIT), SYS_CTRL_CKEN_SET_CTRL);
++
++ /* stop all the interrupts in the ata core */
++ writel(~0, ioaddr + OX810SATA_INT_DISABLE);
++ writel(~0, ioaddr + OX810SATA_INT_CLEAR);
++
++ /* get libata to perform a soft reset */
++ ata_port_probe(ap);
++ ata_bus_reset(ap);
++}
++
++/**
++ * When setting up an IDE BMDMA transaction, these hooks arm (->bmdma_setup)
++ * and fire (->bmdma_start) the hardware's DMA engine.
++ *
++ * @param qc the queued command to issue
++ */
++static void ox810sata_bmdma_setup(struct ata_queued_cmd *qc)
++{
++ ox810sata_private_data* PrivateData ;
++ oxnas_dma_direction_t direction;
++
++#ifdef SATA_DEBUG
++ printk(KERN_INFO"ox810sata_bmdma_setup: %s, %d element%s\n", (qc->dma_dir == DMA_FROM_DEVICE) ? "Read" : "Write", qc->n_elem, qc->n_elem ? "s" : "");
++#else // SATA_DEBUG
++ DPRINTK(" %s, %d element%s\n", (qc->dma_dir == DMA_FROM_DEVICE) ? "Read" : "Write", qc->n_elem, qc->n_elem ? "s" : "");
++#endif // SATA_DEBUG
++
++ qc->private_data = qc->ap->private_data;
++ PrivateData = (ox810sata_private_data* )qc->private_data;
++
++ // We check for DMA completion from ISR which cannot wait for all DMA channel
++ // housekeeping to complete, so need to wait here is case we try to reuse
++ // channel before that housekeeping has completed
++ while (oxnas_dma_is_active(PrivateData->DmaChannel)) {
++ printk("DMA Setup Channel still active\n");
++ }
++
++ /* Do not use DMA callback */
++ oxnas_dma_set_callback(PrivateData->DmaChannel, OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
++
++ /* decide on DMA direction */
++ direction = (qc->dma_dir == DMA_FROM_DEVICE) ? OXNAS_DMA_FROM_DEVICE :
++ OXNAS_DMA_TO_DEVICE;
++
++ /* now set-up the DMA transfer */
++ if (qc->n_elem > 1)
++ {
++#ifdef SATA_DEBUG
++ u32 total=0;
++ int i=0;
++ struct scatterlist* sg = qc->__sg;
++ printk("Lengths: ");
++ do {
++ u32 len = sg_dma_len(sg++);
++ printk("%u ", len);
++ total += len;
++ } while (++i < qc->n_elem);
++ printk("\nTotal len = %u\n", total);
++#endif // SATA_DEBUG
++ /* try and setup scatter gather controller */
++ if (oxnas_dma_device_set_prd(
++ PrivateData->DmaChannel,
++ direction,
++ qc->ap->prd,
++ &oxnas_sata_dma_settings,
++ OXNAS_DMA_MODE_INC,
++ PrivateData->sg_entries)) {
++ printk(KERN_ERR"Failed to setup DMA with disk.\n");
++ return;
++ }
++ }
++ else
++ {
++#ifdef SATA_DEBUG
++ printk("Total len = %u\n", sg_dma_len(qc->__sg));
++#endif // SATA_DEBUG
++ /* setup a single dma */
++ oxnas_dma_device_set( PrivateData->DmaChannel,
++ direction,
++ (unsigned char* )sg_dma_address(qc->__sg),
++ sg_dma_len(qc->__sg),
++ &oxnas_sata_dma_settings,
++ OXNAS_DMA_MODE_INC,
++ 1); /* paused */
++ }
++}
++
++/**
++ * When setting up an IDE BMDMA transaction, these hooks arm (->ignedmdma_setup)
++ * and fire (->bmdma_start) the hardware's DMA engine.
++ *
++ * @param qc the queued command to issue
++ */
++static void ox810sata_bmdma_start(struct ata_queued_cmd *qc)
++{
++ ox810sata_private_data* PrivateData ;
++ DPRINTK("\n");
++ PrivateData = (ox810sata_private_data*)(qc->private_data);
++
++ /* start DMA transfer */
++ oxnas_dma_start(PrivateData->DmaChannel);
++ qc->ap->ops->exec_command(qc->ap, &(qc->tf));
++}
++
++
++/**
++ * ata_qc_new - Request an available ATA command, for queueing
++ * @ap: Port associated with device @dev
++ * @dev: Device from whom we request an available command structure
++ *
++ * LOCKING:
++ */
++
++static struct ata_queued_cmd* ox810sata_qc_new(struct ata_port *ap)
++{
++ struct ata_queued_cmd *qc = NULL;
++
++ VPRINTK("\n");
++ /* no command while frozen */
++ if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
++ return NULL;
++
++ /* check to see that there are no internal commands active on either port*/
++ if ((ox810sata_driver.ap[0]) && (ox810sata_driver.ap[0]->qc_allocated))
++ return qc;
++ if ((ox810sata_driver.ap[1]) && (ox810sata_driver.ap[1]->qc_allocated))
++ return qc;
++
++ /* check if we're not doing a command */
++ if (test_and_set_bit(0, &ox810sata_command_active))
++ return qc;
++
++ /* now set the standard bits for compatibility */
++ set_bit(0, &ap->qc_allocated);
++ qc = __ata_qc_from_tag(ap, 0);
++
++#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
++ /* disk light on */
++ writel(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_SET);
++#endif // CONFIG_SATA_OXNAS_DISK_LIGHT
++#ifdef CONFIG_WDC_LEDS_TRIGGER_SATA_DISK
++ wdc_ledtrig_sata_activity();
++#endif // CONFIG_WDC_LEDS_TRIGGER_SATA_DISK
++
++ if (qc) {
++ qc->tag = 0;
++ }
++
++ return qc;
++}
++
++
++/**
++ *
++ */
++static void ox810sata_qc_free(struct ata_queued_cmd *qc)
++{
++ unsigned int tag;
++ struct ata_port *ap = qc->ap;
++
++ DPRINTK("\n");
++
++ qc->flags = 0;
++ tag = qc->tag;
++ if (likely(ata_tag_valid(tag))) {
++ qc->tag = ATA_TAG_POISON;
++ VPRINTK("clearing active bits\n");
++ clear_bit(tag, &ap->qc_allocated);
++ clear_bit(0, &ox810sata_command_active);
++
++#ifdef CONFIG_SATA_OXNAS_DISK_LIGHT
++ /* disk light off */
++ writel(1 << CONFIG_OX810SATA_DISK_LIGHT_GPIO_LINE, GPIO_A_OUTPUT_CLEAR);
++#endif /* CONFIG_SATA_OXNAS_DISK_LIGHT */
++ }
++}
++
++/**
++ * qc_issue is used to make a command active, once the hardware and S/G tables
++ * have been prepared. IDE BMDMA drivers use the helper function
++ * ata_qc_issue_prot() for taskfile protocol-based dispatch. More advanced drivers
++ * roll their own ->qc_issue implementation, using this as the "issue new ATA
++ * command to hardware" hook.
++ * @param qc the queued command to issue
++ */
++static unsigned int ox810sata_qc_issue(struct ata_queued_cmd *qc)
++{
++ int this_port_fail;
++ struct bio* bio;
++ u32 reg;
++ ox810sata_private_data* private_data = (ox810sata_private_data*)qc->ap->private_data ;
++ u32 raid_reg = 0; /* default to no raid */
++ int port0fail = 0;
++ int port1fail = 0;
++ unsigned long flags = 0;
++
++ DPRINTK("\n");
++
++ /* get raid settings from the bio if they exist */
++ if (qc->scsicmd && qc->scsicmd->request && qc->scsicmd->request->bio) {
++ bio = qc->scsicmd->request->bio;
++ raid_reg = bio->bi_raid ;
++ //if (raid_reg) {printk("Hardware RAID :");tfdump(&qc->tf);}
++
++ }
++ ox810sata_driver.hw_raid_active = raid_reg;
++ ox810sata_driver.active_port = qc->ap;
++
++ /* check cable is still connected */
++ ox810sata_scr_read(qc->ap, SCR_STATUS, ®);
++ this_port_fail = (!(reg & 1));
++
++ /* check for failed ports prior to issuing raid-ed commands */
++ if (raid_reg) {
++ port0fail = (! (__ox810sata_scr_read((u32* )SATA0_REGS_BASE, 0x20 + (4 * SCR_STATUS) ) & 1 ) );
++ port1fail = (! (__ox810sata_scr_read((u32* )SATA1_REGS_BASE, 0x20 + (4 * SCR_STATUS) ) & 1 ) );
++ this_port_fail |= port1fail;
++
++ ox810sata_accumulated_RAID_faults |= port0fail ? 1 : 0 ;
++ ox810sata_accumulated_RAID_faults |= port1fail ? 2 : 0 ;
++ }
++
++ if (!this_port_fail) {
++ /* clear phy/link errors */
++ if (ox810sata_driver.ap[0])
++ ox810sata_scr_write(ox810sata_driver.ap[0], SCR_ERROR, ~0);
++ if (ox810sata_driver.ap[1])
++ ox810sata_scr_write(ox810sata_driver.ap[1], SCR_ERROR, ~0);
++
++ /* clear errors on both hosts */
++ reg = readl((u32* )SATA0_REGS_BASE + OX810SATA_SATA_CONTROL);
++ reg |= OX810SATA_SCTL_CLR_ERR ;
++ writel(reg, (u32* )SATA0_REGS_BASE + OX810SATA_SATA_CONTROL);
++ reg = readl((u32* )SATA1_REGS_BASE + OX810SATA_SATA_CONTROL);
++ reg |= OX810SATA_SCTL_CLR_ERR ;
++ writel(reg, (u32* )SATA1_REGS_BASE + OX810SATA_SATA_CONTROL);
++ reg = readl((u32* )SATARAID_REGS_BASE + OX810SATA_SATA_CONTROL);
++ reg |= OX810SATA_SCTL_CLR_ERR ;
++ writel(reg, (u32* )SATARAID_REGS_BASE + OX810SATA_SATA_CONTROL);
++
++ /* clear all interrupt bits */
++ writel(~0, (u32* )SATA0_REGS_BASE + OX810SATA_INT_CLEAR);
++ writel(~0, (u32* )SATA1_REGS_BASE + OX810SATA_INT_CLEAR);
++ writel(~0, (u32* )SATARAID_REGS_BASE + OX810SATA_INT_CLEAR);
++ writel(~0, OX810SATA_CORE_IEC );
++
++ /* hardware RAID */
++ if ( raid_reg ) {
++ /* set interrupt mode for raid controller interrupts only */
++ writel(OX810SATA_RAID_INTS_WANTED, OX810SATA_CORE_IES );
++
++ /* at the moment we only do raid-1 */
++ writel(OXNASSATA_RAID1, OX810SATA_RAID_CONTROL);
++ writel(OXNASSATA_RAID_TWODISKS, OX810SATA_RAID_SET);
++ } else {
++ /* set normal interrupt scheme */
++ writel(OX810SATA_NORMAL_INTS_WANTED, OX810SATA_CORE_IES);
++
++ /* Set the RAID controller hardware to idle */
++ writel(OXNASSATA_NOTRAID, OX810SATA_RAID_CONTROL);
++ }
++
++ /* call the default, this should be changed to take advantage of orb
++ registers, etc... */
++ return ata_qc_issue_prot(qc);
++ } else {
++ /* record the error */
++ qc->err_mask |= AC_ERR_ATA_BUS;
++
++ /* maybee call ata qc complete? */
++ local_irq_save(flags);
++ ox810sata_irq_clear(qc->ap);
++ private_data->int_status = 0;
++ local_irq_restore(flags);
++ ata_qc_complete(qc);
++
++ return 0;
++ }
++}
++
++/**
++ * This is a high level error handling function, called from the error
++ * handling thread, when a command times out.
++ *
++ * @param ap hardware with the registers in
++ */
++static void ox810sata_eng_timeout(struct ata_port *ap)
++{
++ struct ata_queued_cmd *qc;
++ ox810sata_private_data* pd = (ox810sata_private_data*)ap->private_data;
++ DPRINTK("\n");
++
++ /* set the in cleanup flag */
++ pd->in_cleanup = 1;
++
++ /* if we're a PIO command existing cleanup won't be called */
++ qc = ata_qc_from_tag(ap, ap->link.active_tag);
++ if (qc->tf.protocol == ATA_PROT_PIO) {
++ /* reset the core */
++ ox810sata_timeout_cleanup(ap);
++ }
++
++ /* clear the in cleanup flag */
++ pd->in_cleanup = 0;
++}
++
++/**
++ * irq_handler is the interrupt handling routine registered with the system,
++ * by libata.
++ */
++static irqreturn_t ox810sata_irq_handler(
++ int irq,
++ void *dev_instance)
++{
++ struct ata_port *ap = ((struct ata_host *)dev_instance)->ports[0];
++ ox810sata_private_data *pd;
++ u32 *ioaddr;
++ u32 int_status;
++ u32 count ;
++
++ DPRINTK("irq = %d\n", irq);
++
++ if (!ap || !ap->private_data)
++ BUG();
++
++ /* check the ISR for the port to see if it created the interrupt */
++ ioaddr = ox810sata_get_tfio_base(ap);
++ int_status = readl(ioaddr + OX810SATA_INT_STATUS);
++ if ( !(int_status & OX810SATA_INT_WANT ) ) {
++ VPRINTK("not me!\n");
++ return IRQ_NONE;
++ }
++
++ pd = (ox810sata_private_data*)ap->private_data;
++ while (int_status & OX810SATA_INT_MASKABLE) {
++ /* store interrupt status for the bottom end */
++ pd->int_status |= int_status;
++
++ /* Clear and mask pending interrupts */
++ writel(int_status, ioaddr + OX810SATA_INT_CLEAR);
++ writel(int_status, ioaddr + OX810SATA_INT_DISABLE);
++
++ int_status = readl(ioaddr + OX810SATA_INT_STATUS);
++ }
++
++ // Wait a short while for the DMA to finish and if it doesn't start a thread
++ // to poll for the finish
++ pd->spot_the_end_work.ap = ap;
++ for (count = 0; count < 10; ++count) {
++ if (!oxnas_dma_raw_isactive(pd->DmaChannel)) {
++ ox810sata_spot_the_end(&(pd->spot_the_end_work.worker));
++ break;
++ }
++ udelay(100);
++ }
++
++ if (count == 10) {
++ /* Start a worker thread looking for the DMA channel to become idle */
++ VPRINTK("queueing work \n");
++ queue_work(ox810sata_driver.spot_the_end_q, &pd->spot_the_end_work.worker);
++ }
++ VPRINTK("done\n");
++ return IRQ_HANDLED;
++}
++
++/**
++ * Work for a work queue, this will check for errors then wait for the DMA to
++ * complete. On the DMA completing it will call ata_qc_complete
++ */
++static void ox810sata_spot_the_end(struct work_struct *work)
++{
++ struct spot_the_end_work_s* stew =
++ container_of(work, struct spot_the_end_work_s, worker);
++ struct ata_port* ap = stew->ap;
++ ox810sata_private_data* PrivateData = (ox810sata_private_data* )ap->private_data;
++ struct ata_queued_cmd* qc = ata_qc_from_tag(ap, ap->link.active_tag);
++ unsigned long flags = 0;
++
++ VPRINTK("\n");
++
++ /* If there's no command ending associated with this IRQ, ignore it. */
++ if (qc == NULL) {
++ DPRINTK(" qc=null\n");
++ return;
++ }
++
++ /* The command may have aborted, this is indicated by the interrupt bit
++ * being masked */
++ if (PrivateData->in_cleanup) {
++ DPRINTK("cleanup\n");
++ return;
++ }
++
++ /* get the status before any error cleanup */
++ qc->err_mask = ac_err_mask(ata_chk_status(ap));
++
++ /* Look to see if the core is indicating an error condition after a RAID
++ * command */
++ if (qc->scsicmd &&
++ qc->scsicmd->request &&
++ qc->scsicmd->request->bio &&
++ qc->scsicmd->request->bio->bi_raid ) {
++ unsigned long Port0Irq = readl(((u32)(SATA0_REGS_BASE)) + OX810SATA_INT_STATUS);
++ unsigned long Port1Irq = readl(((u32)(SATA1_REGS_BASE)) + OX810SATA_INT_STATUS);
++
++ if (OX810SATA_RAW_ERROR & Port0Irq) {
++ printk(KERN_DEBUG"disk 0 error in hw-raid\n");
++ ox810sata_accumulated_RAID_faults |= 1;
++ }
++ if (OX810SATA_RAW_ERROR & Port1Irq) {
++ printk(KERN_DEBUG"disk 1 error in hw-raid\n");
++ ox810sata_accumulated_RAID_faults |= 2;
++ }
++ }
++
++ /* if there was an error and the command hasn't finished, then we need to
++ * abort the command */
++ if ((PrivateData->int_status & 0xfffe) &&
++ !(PrivateData->int_status & 0x1) &&
++ (qc->tf.protocol == ATA_PROT_DMA))
++ {
++ DPRINTK(" int status 0x%08x, ata%u \n",PrivateData->int_status,ap->id);
++ local_irq_save(flags);
++ ox810sata_irq_clear(ap);
++ PrivateData->int_status = 0;
++ local_irq_restore(flags);
++ ata_qc_complete(qc);
++ return;
++ }
++
++ if (!in_irq()) {
++ /* wait for the DMA to finish */
++ while (oxnas_dma_is_active(PrivateData->DmaChannel)) {
++ schedule();
++ }
++ }
++
++ if (!(qc->flags & ATA_QCFLAG_ACTIVE)) {
++ printk(KERN_WARNING "OX810 SATA: Command already completed!\n");
++ return;
++ }
++
++ /** @debug check for any padding */
++ if(0)
++ {
++ unsigned int reg;
++ reg = readl(OX810SATA_EXCESS);
++ if (reg) {
++ printk("command finished with a hint of padding\n");
++ CrazyDumpDebug();
++ }
++ }
++
++ /* tell libata we're done */
++ DPRINTK(" returning err_mask=0x%x\n", qc->err_mask);
++ local_irq_save(flags);
++ ox810sata_irq_clear(ap);
++ PrivateData->int_status = 0;
++ local_irq_restore(flags);
++ ata_qc_complete(qc);
++}
++
++/**
++ * ox810sata_irq_clear is called during probe just before the interrupt handler is
++ * registered, to be sure hardware is quiet. It clears and masks interrupt bits
++ * in the SATA core.
++ *
++ * @param ap hardware with the registers in
++ */
++static void ox810sata_irq_clear(struct ata_port* ap)
++{
++ u32 *ioaddr = ox810sata_get_tfio_base(ap);
++ //DPRINTK(KERN_INFO"ox810sata_irq_clear\n");
++
++ writel(~0, ioaddr + OX810SATA_INT_DISABLE);
++ writel(~0, ioaddr + OX810SATA_INT_CLEAR);
++}
++
++static inline u32 __ox810sata_scr_read(u32* core_addr, unsigned int sc_reg)
++{
++ u32 result;
++ u32 patience;
++
++ /* we've got 8 other registers in before the start of the standard ones */
++ writel(sc_reg, core_addr + OX810SATA_LINK_RD_ADDR );
++
++ for (patience = 0x100000; patience > 0; --patience) {
++ if (readl(core_addr + OX810SATA_LINK_CONTROL) & 0x00000001) {
++ break;
++ }
++ }
++
++ result = readl(core_addr + OX810SATA_LINK_DATA);
++
++ //DPRINTK(KERN_INFO"ox810sata_scr_read: [0x%02x]->0x%08x\n", sc_reg, result);
++ return result;
++}
++
++/**
++ * Read standard SATA phy registers. Currently only used if
++ * ->phy_reset hook called the sata_phy_reset() helper function.
++ *
++ * These registers are in another clock domain to the processor, access is via
++ * some bridging registers
++ *
++ * @param ap hardware with the registers in
++ * @param sc_reg the SATA PHY register
++ * @return the value in the register
++ */
++static int ox810sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
++{
++ u32* ioaddr = ox810sata_get_io_base(ap);
++ *val = __ox810sata_scr_read(ioaddr, 0x20 + (sc_reg*4));
++ return 0;
++}
++
++static void __ox810sata_scr_write(u32* core_addr, unsigned int sc_reg, u32 val)
++{
++ u32 patience;
++
++ //DPRINTK(KERN_INFO"ox810sata_scr_write: [0x%02x]<-0x%08x\n", sc_reg, val);
++ writel(val, core_addr + OX810SATA_LINK_DATA );
++ wmb();
++ writel(sc_reg , core_addr + OX810SATA_LINK_WR_ADDR );
++ wmb();
++
++ for (patience = 0x100000; patience > 0;--patience) {
++ if (readl(core_addr + OX810SATA_LINK_CONTROL) & 0x00000001) {
++ break;
++ }
++ }
++}
++/**
++ * Write standard SATA phy registers. Currently only used if
++ * phy_reset hook called the sata_phy_reset() helper function.
++ *
++ * These registers are in another clock domain to the processor, access is via
++ * some bridging registers
++ *
++ * @param ap hardware with the registers in
++ * @param sc_reg the SATA PHY register
++ * @param val the value to write into the register
++ */
++static int ox810sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
++{
++ u32 *ioaddr = ox810sata_get_io_base(ap);
++ __ox810sata_scr_write(ioaddr, 0x20 + (sc_reg * 4), val);
++ return 0;
++}
++
++/**
++ * port_start() is called just after the data structures for each port are
++ * initialized. Typically this is used to alloc per-port DMA buffers, tables
++ * rings, enable DMA engines and similar tasks.
++ *
++ * @return 0 = success
++ * @param ap hardware with the registers in
++ */
++static int ox810sata_port_start(struct ata_port *ap)
++{
++ ox810sata_private_data* pd;
++ struct device* pdev = ap->host->dev;
++
++ ap->prd = dma_alloc_coherent(pdev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_DMA);
++ if (!ap->prd) {
++ return -ENOMEM;
++ }
++
++ /* allocate port private data memory and attach to port */
++ if (!ap->private_data) {
++ ap->private_data = kmalloc(sizeof(ox810sata_private_data), GFP_KERNEL);
++ }
++
++ if (!ap->private_data) {
++ return -ENOMEM;
++ }
++
++ pd = (ox810sata_private_data* )ap->private_data;
++ pd->DmaChannel = 0;
++ pd->sg_entries = 0;
++
++ DPRINTK("ap = %p, pd = %p\n",ap,ap->private_data);
++
++ // Allocate DMA SG entries
++ if (oxnas_dma_alloc_sg_entries(&pd->sg_entries, CONFIG_ARCH_OXNAS_MAX_SATA_SG_ENTRIES, 0)) {
++ printk(KERN_WARNING "ox810sata_port_start() Failed to obtain DMA SG entries\n");
++ return -ENOMEM;
++ }
++
++ // Hold on to a DMA channel for the life of the SATA driver
++ pd->DmaChannel = oxnas_dma_request(1);
++
++ if (!pd->DmaChannel) {
++ printk(KERN_WARNING "ox810sata_port_start() Failed to obtain DMA channel\n");
++ return -ENOMEM;
++ }
++
++ /* declare a work item to spot when a command finishes */
++ INIT_WORK(&(pd->spot_the_end_work.worker), &ox810sata_spot_the_end);
++
++ /* initialise to zero */
++ pd->ErrorsWithNoCommamnd = 0;
++ pd->int_status = 0;
++ pd->in_cleanup = 0;
++
++ /* store the ata_port pointer in the driver structure */
++ if (ox810sata_get_io_base(ap) == (u32*)SATA0_REGS_BASE) {
++ ox810sata_driver.ap[0] = ap;
++ } else if (ox810sata_get_io_base(ap) == (u32*)SATA1_REGS_BASE) {
++ ox810sata_driver.ap[1] = ap;
++ }
++
++ // turn ata core on
++ writel((1 << SYS_CTRL_CKEN_SATA_BIT), SYS_CTRL_CKEN_SET_CTRL);
++
++ /* post reset init needs to be called for both ports as there's one reset
++ for both ports*/
++ if (ox810sata_driver.ap[0]) {
++ ox810sata_post_reset_init(ox810sata_driver.ap[0]);
++ }
++ if (ox810sata_driver.ap[1]) {
++ ox810sata_post_reset_init(ox810sata_driver.ap[1]);
++ }
++
++ return 0;
++}
++
++static void ox810sata_post_reset_init(struct ata_port* ap)
++{
++ u32 patience;
++ u32* ioaddr = ox810sata_get_io_base(ap);
++ uint dev;
++
++ /* turn on phy error detection by removing the masks */
++ writel(0x30003, ioaddr + OX810SATA_LINK_DATA );
++ wmb();
++ writel(0x0C, ioaddr + OX810SATA_LINK_WR_ADDR );
++ wmb();
++ for (patience = 0x100000; patience > 0;--patience) {
++ if (readl(ioaddr + OX810SATA_LINK_CONTROL) & 0x00000001) {
++ break;
++ }
++ }
++
++ /* enable interrupts for ports */
++ VPRINTK("Enable interrupts\n");
++ writel(~0, OX810SATA_CORE_IEC);
++ writel(OX810SATA_NORMAL_INTS_WANTED, OX810SATA_CORE_IES);
++
++ /* go through all the devices and configure them */
++ for (dev = 0; dev < ATA_MAX_DEVICES; ++dev) {
++ if (ap->link.device[dev].class == ATA_DEV_ATA) {
++ ox810sata_phy_reset(ap);
++ ox810sata_dev_config(ap, &(ap->link.device[dev]));
++ }
++ }
++
++ /* disable padding */
++/* {
++ unsigned int reg = readl(OX810SATA_DEVICE_CONTROL);
++ reg &= ~OX810SATA_DEVICE_CONTROL_PAD ;
++ writel(reg, OX810SATA_DEVICE_CONTROL);
++ }*/
++ {
++ unsigned int reg = readl(OX810SATA_DEVICE_CONTROL);
++ reg |= OX810SATA_DEVICE_CONTROL_PADPAT ;
++ writel(reg, OX810SATA_DEVICE_CONTROL);
++ }
++}
++
++/**
++ * port_stop() is called after ->host_stop(). It's sole function is to
++ * release DMA/memory resources, now that they are no longer actively being
++ * used.
++ */
++static void ox810sata_port_stop(struct ata_port *ap)
++{
++ ox810sata_private_data* pd = (ox810sata_private_data* )ap->private_data;
++
++ DPRINTK("\n");
++
++ if (pd->DmaChannel) {
++ oxnas_dma_free(pd->DmaChannel);
++ pd->DmaChannel = 0;
++ }
++
++ if (pd->sg_entries) {
++ oxnas_dma_free_sg_entries(pd->sg_entries);
++ pd->sg_entries = 0;
++ }
++
++ kfree(pd);
++}
++
++/**
++ * host_stop() is called when the rmmod or hot unplug process begins. The
++ * hook must stop all hardware interrupts, DMA engines, etc.
++ *
++ * @param ap hardware with the registers in
++ */
++static void ox810sata_host_stop(struct ata_host *host_set)
++{
++ DPRINTK("\n");
++}
++
++/**
++ * PATA device presence detection
++ * @param ap ATA channel to examine
++ * @param device Device to examine (starting at zero)
++ * @return true if something found
++ *
++ * This technique was originally described in
++ * Hale Landis's ATADRVR (www.ata-atapi.com), and
++ * later found its way into the ATA/ATAPI spec.
++ *
++ * Write a pattern to the ATA shadow registers,
++ * and if a device is present, it will respond by
++ * correctly storing and echoing back the
++ * ATA shadow register contents.
++ *
++ * LOCKING:
++ * caller.
++ */
++static unsigned int ox810sata_devchk(struct ata_port *ap,unsigned int device)
++{
++ DPRINTK("\n");
++
++ return 0; /* nothing found */
++}
++
++static void ox810sata_pio_start(struct work_struct *work)
++{
++ struct ata_port *ap = container_of(work, struct ata_port, port_task.work);
++ ox810sata_private_data* pd = (ox810sata_private_data*)ap->private_data;
++ struct ata_queued_cmd* qc = ap->port_task_data;
++ u32* ioaddr = ox810sata_get_io_base(ap);
++ unsigned long flags = 0;
++
++ VPRINTK("\n");
++ // We check for DMA completion from ISR which cannot wait for all DMA channel
++ // housekeeping to complete, so need to wait here is case we try to reuse
++ // channel before that housekeeping has completed
++ if (oxnas_dma_is_active(pd->DmaChannel)) {
++ printk(KERN_WARNING "PIO start Channel still active\n");
++ /* if the DMA is still busy, schedule a task to poll again in 1 ms */
++ ata_port_queue_task(ap, ox810sata_pio_start, qc, ATA_SHORT_PAUSE);
++ return;
++ }
++
++ if (qc->tf.protocol != ATA_PROT_NODATA) {
++ oxnas_dma_direction_t direction = (qc->dma_dir == DMA_FROM_DEVICE) ?
++ OXNAS_DMA_FROM_DEVICE :
++ OXNAS_DMA_TO_DEVICE;
++
++ /* Do not use DMA callback */
++ oxnas_dma_set_callback(pd->DmaChannel, OXNAS_DMA_CALLBACK_NUL, OXNAS_DMA_CALLBACK_ARG_NUL);
++
++ /* map memory for dma */
++ dma_map_sg(NULL, qc->__sg, qc->n_elem, qc->dma_dir);
++
++ /* setup a scatter gather dma */
++ oxnas_dma_device_set_sg(pd->DmaChannel,
++ direction,
++ qc->__sg,
++ qc->n_elem,
++ &oxnas_sata_dma_settings,
++ OXNAS_DMA_MODE_INC,
++ 0);
++
++ oxnas_dma_start(pd->DmaChannel);
++
++ if (oxnas_dma_is_active(pd->DmaChannel)) {
++ /* if the DMA is still busy, schedule a task to poll again in 1 ms */
++ ata_port_queue_task(ap, ox810sata_pio_task, qc, ATA_SHORT_PAUSE);
++ return;
++ }
++
++ /* cleanup DMA */
++ dma_unmap_sg(NULL, qc->__sg, qc->n_elem, qc->dma_dir);
++ } else {
++ /* if the core is still busy, reschedule */
++ if (readl(ioaddr + OX810SATA_SATA_COMMAND) & CMD_CORE_BUSY) {
++ ata_port_queue_task(ap, ox810sata_pio_task, qc, ATA_SHORT_PAUSE);
++ return;
++ }
++ }
++
++ /* notify of completion */
++ PretendDRQIsClear = 1;
++ qc->err_mask = ac_err_mask(ata_chk_status(ap));
++ spin_lock_irqsave(ap->lock, flags);
++ ap->ops->irq_on(ap);
++ ata_qc_complete(qc);
++ spin_unlock_irqrestore(ap->lock, flags);
++}
++
++/**
++ * This is the top level of the PIO task. It is responsible for organising the
++ * transfer of data, collecting and reacting to status changes and notification
++ * of command completion.
++ *
++ */
++static void ox810sata_pio_task(struct work_struct *work)
++{
++ struct ata_port *ap = container_of(work, struct ata_port, port_task.work);
++ struct ata_queued_cmd *qc = ap->port_task_data;
++ u32* ioaddr = ox810sata_get_io_base(ap);
++ unsigned long flags = 0;
++ VPRINTK("\n");
++
++ if (qc->tf.protocol != ATA_PROT_NODATA) {
++ ox810sata_private_data* pd = (ox810sata_private_data* )ap->private_data;
++
++ /* if the DMA is still busy and there is no error, re-schedule the task */
++ /* try again in 1 ms */
++ if ((oxnas_dma_is_active(pd->DmaChannel)) &&
++ !(readl(ioaddr + OX810SATA_INT_STATUS) & OX810SATA_RAW_ERROR) ) {
++ ata_port_queue_task(ap, ox810sata_pio_task, qc, ATA_SHORT_PAUSE);
++ return;
++ }
++
++ /* cleanup DMA */
++ dma_unmap_sg(NULL, qc->__sg, qc->n_elem, qc->dma_dir);
++ } else {
++ /* if the core is still busy, reschedule */
++ if ((readl(ioaddr + OX810SATA_SATA_COMMAND) & CMD_CORE_BUSY) &&
++ !(readl(ioaddr + OX810SATA_INT_STATUS) & OX810SATA_RAW_ERROR) ) {
++ ata_port_queue_task(ap, ox810sata_pio_task, qc, ATA_SHORT_PAUSE);
++ return;
++ }
++ }
++
++ /* notify of completion */
++ PretendDRQIsClear = 1;
++ qc->err_mask = ac_err_mask(ata_chk_status(ap));
++ spin_lock_irqsave(ap->lock, flags);
++ ap->ops->irq_on(ap);
++ ata_qc_complete(qc);
++ spin_unlock_irqrestore(ap->lock, flags);
++}
++
++static void ox810sata_bmdma_stop(struct ata_queued_cmd *qc)
++{
++ struct ata_port *ap = qc->ap;
++ ox810sata_private_data* private_data = (ox810sata_private_data*)ap->private_data;
++
++ /* Check if DMA is in progress, if so abort */
++ if (oxnas_dma_is_active(private_data->DmaChannel)) {
++ /*
++ * Attempt to abort any current transfer:
++ * Abort DMA transfer at the DMA controller,
++ */
++ printk(KERN_ERR "ox810sata_bmdma_stop - aborting DMA\n");
++
++ oxnas_dma_abort(private_data->DmaChannel, 1);
++ }
++
++ /* perform core cleanups and resets as required */
++ ox810sata_timeout_cleanup(ap);
++}
++
++/**
++ * @param ap ata port, not used
++ */
++static void ox810sata_timeout_cleanup(struct ata_port *ap) {
++ u32 reg;
++ u32 patience;
++
++// CrazyDumpDebug();
++
++ /* Clear error bits in both ports */
++ reg = readl((u32*)SATA0_REGS_BASE + OX810SATA_SATA_CONTROL);
++ reg |= OX810SATA_SCTL_CLR_ERR ;
++ writel(reg, (u32*)SATA0_REGS_BASE + OX810SATA_SATA_CONTROL);
++ reg = readl((u32*)SATA1_REGS_BASE + OX810SATA_SATA_CONTROL);
++ reg |= OX810SATA_SCTL_CLR_ERR ;
++ writel(reg, (u32*)SATA1_REGS_BASE + OX810SATA_SATA_CONTROL);
++ reg = readl((u32* )SATARAID_REGS_BASE + OX810SATA_SATA_CONTROL);
++ reg |= OX810SATA_SCTL_CLR_ERR ;
++ writel(reg, (u32* )SATARAID_REGS_BASE + OX810SATA_SATA_CONTROL);
++
++ /* Test SATA core idle state */
++ if ( !(~readl(OX810SATA_IDLE_STATUS) & OX810SATA_IDLE_CORES) ) {
++ return;
++ }
++
++// CrazyDumpDebug();
++
++ /* abort DMA */
++ printk(KERN_INFO"ox810sata aborting DMA.\n");
++ reg = readl(OX810SATA_DEVICE_CONTROL);
++ writel(reg | OX810SATA_DEVICE_CONTROL_ABORT, OX810SATA_DEVICE_CONTROL);
++
++ /* wait until patience runs out for the core to go idle */
++ patience = 50;
++ do {
++ /* if the core is idle, clear the abort bit and return */
++ if ( !(~readl(OX810SATA_IDLE_STATUS) & OX810SATA_IDLE_CORES) ) {
++ writel(reg & ~OX810SATA_DEVICE_CONTROL_ABORT, OX810SATA_DEVICE_CONTROL);
++ return;
++ }
++ mdelay(1);
++ } while (--patience);
++ writel(reg & ~OX810SATA_DEVICE_CONTROL_ABORT, OX810SATA_DEVICE_CONTROL);
++
++// CrazyDumpDebug();
++
++ /* command a sync escape on both ports */
++ printk(KERN_INFO"ox810sata sending sync escapes\n");
++
++ /* port 0 */
++ reg = readl((u32*)SATA0_REGS_BASE + OX810SATA_SATA_COMMAND);
++ reg &= ~SATA_OPCODE_MASK;
++ reg |= CMD_SYNC_ESCAPE;
++ writel(reg, (u32*)SATA0_REGS_BASE + OX810SATA_SATA_COMMAND);
++
++ /* wait until patience runs out for the core to go idle */
++ patience = 50;
++ do {
++ /* if the core is idle, clear the abort bit and return */
++ if ( !(~readl(OX810SATA_IDLE_STATUS) & OX810SATA_IDLE_CORES) ) {
++ return;
++ }
++ mdelay(1);
++ } while (--patience);
++
++ /* port 1 */
++ reg = readl((u32*)SATA1_REGS_BASE + OX810SATA_SATA_COMMAND);
++ reg &= ~SATA_OPCODE_MASK;
++ reg |= CMD_SYNC_ESCAPE;
++ writel(reg, (u32*)SATA1_REGS_BASE + OX810SATA_SATA_COMMAND);
++
++ /* wait until patience runs out for the core to go idle */
++ patience = 50;
++ do {
++ /* if the core is idle, clear the abort bit and return */
++ if ( !(~readl(OX810SATA_IDLE_STATUS) & OX810SATA_IDLE_CORES) ) {
++ return;
++ }
++ mdelay(1);
++ } while (--patience);
++
++// CrazyDumpDebug();
++
++ /* SATA core did not go idle, so cause a SATA core reset from the RPS */
++ CrazyDumpDebug();
++ printk(KERN_INFO "ox810sata core reset\n");
++ ox810sata_reset_core();
++
++ /* Read SATA core idle state */
++ if (~readl(OX810SATA_IDLE_STATUS) & OX810SATA_IDLE_CORES) {
++ printk(KERN_INFO"ox810sata core still busy\n");
++ CrazyDumpDebug();
++ }
++
++ /* Perform any SATA core re-initialisation after reset */
++ /* post reset init needs to be called for both ports as there's one reset
++ for both ports*/
++ if (ox810sata_driver.ap[0]) {
++ ox810sata_post_reset_init(ox810sata_driver.ap[0]);
++ }
++ if (ox810sata_driver.ap[1]) {
++ ox810sata_post_reset_init(ox810sata_driver.ap[1]);
++ }
++}
++
++
++static void ox810sata_error_handler(struct ata_port *ap)
++{
++ return ata_bmdma_drive_eh(ap, ox810sata_prereset, ata_std_softreset,
++ ox810sata_hardreset, ox810sata_postreset);
++}
++
++
++
++/**
++ * bmdma_status return a made up version of a BMDMA status register
++ *
++ * @param ap Hardware with the registers in
++ * @return the value ATA_DMA_INTR if the interrupt came from the DMA finishing
++ */
++static u8 ox810sata_bmdma_status(struct ata_port *ap)
++{
++ return ATA_DMA_INTR;
++}
++
++/**
++ * turn on the interrupts from the ata drive
++ * wait for idle, clear any pending interrupts.
++ *
++ * @param ap Hardware with the registers in
++ */
++static u8 ox810sata_irq_on(struct ata_port *ap)
++{
++ u32* ioaddr = ox810sata_get_tfio_base(ap);
++ u8 tmp;
++
++ //DPRINTK(KERN_INFO"ox810sata_irq_on\n");
++
++ /* enable End of command interrupt */
++ writel(~0, ioaddr + OX810SATA_INT_CLEAR);
++ writel(OX810SATA_INT_WANT, ioaddr + OX810SATA_INT_ENABLE);
++ tmp = ata_wait_idle(ap);
++
++ return tmp;
++}
++
++/**
++ * ox810_prereset - prepare for reset
++ * @param link ATA link to be reset
++ * @param deadline deadline jiffies for the operation
++ *
++ * link is about to be reset. Initialize it. Failure from
++ * prereset makes libata abort whole reset sequence and give up
++ * that port, so prereset should be best-effort. It does its
++ * best to prepare for reset sequence but if things go wrong, it
++ * should just whine, not fail.
++ *
++ * LOCKING:
++ * Kernel thread context (may sleep)
++ *
++ * RETURNS:
++ * 0 on success, -errno otherwise.
++ */
++static int ox810sata_prereset(struct ata_link *link, unsigned long deadline) {
++ struct ata_port *ap = link->ap;
++ struct ata_eh_context *ehc = &link->eh_context;
++ const unsigned long *timing = sata_ehc_deb_timing(ehc);
++ ox810sata_private_data* private_data;
++ int rc;
++
++ VPRINTK("\n");
++ /* handle link resume */
++ if ((ehc->i.flags & ATA_EHI_RESUME_LINK) && (link->flags & ATA_LFLAG_HRST_TO_RESUME))
++ ehc->i.action |= ATA_EH_HARDRESET;
++
++ /* Some PMPs don't work with only SRST, force hardreset if PMP
++ * is supported.
++ */
++ if (ap->flags & ATA_FLAG_PMP)
++ ehc->i.action |= ATA_EH_HARDRESET;
++
++ /* if we're about to do hardreset, nothing more to do */
++ if (ehc->i.action & ATA_EH_HARDRESET)
++ return 0;
++
++ /* we want both ports to be idle as soft-reset requires being able to send
++ commands. If a command is running, abort it. */
++ private_data = (ox810sata_private_data*)ap->private_data;
++
++ /* Check if DMA is in progress, if so abort */
++ if (oxnas_dma_is_active(private_data->DmaChannel)) {
++ /*
++ * Attempt to abort any current transfer:
++ * Abort DMA transfer at the DMA controller,
++ */
++ printk(KERN_ERR "aborting DMA\n");
++ oxnas_dma_abort(private_data->DmaChannel, 1);
++ }
++
++ /* perform core cleanups and resets */
++ ox810sata_timeout_cleanup(NULL);
++
++ /* if SATA, resume link */
++ if (ap->flags & ATA_FLAG_SATA) {
++ rc = sata_link_resume(link, timing, deadline);
++ /* whine about phy resume failure but proceed */
++ if (rc && rc != -EOPNOTSUPP)
++ ata_link_printk(link, KERN_WARNING, "failed to resume "
++ "link for reset (errno=%d)\n", rc);
++ }
++
++ /* Wait for !BSY if the controller can wait for the first D2H
++ * Reg FIS and we don't know that no device is attached.
++ */
++ if (!(link->flags & ATA_LFLAG_SKIP_D2H_BSY) && !ata_link_offline(link)) {
++ rc = ata_wait_ready(ap, deadline);
++ if (rc && rc != -ENODEV) {
++ ata_link_printk(link, KERN_WARNING, "device not ready "
++ "(errno=%d), forcing hardreset\n", rc);
++ ehc->i.action |= ATA_EH_HARDRESET;
++ }
++ }
++
++ return 0;
++}
++/**
++ * sata_std_hardreset - reset host port via SATA phy reset
++ * @link: link to reset
++ * @class: resulting class of attached device
++ * @deadline: deadline jiffies for the operation
++ *
++ * SATA phy-reset host port using DET bits of SControl register,
++ * wait for !BSY and classify the attached device.
++ *
++ * LOCKING:
++ * Kernel thread context (may sleep)
++ *
++ * RETURNS:
++ * 0 on success, -errno otherwise.
++ */
++static int ox810sata_hardreset(struct ata_link *link, unsigned int *class,
++ unsigned long deadline)
++{
++ struct ata_port *ap = link->ap;
++ const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
++ int rc;
++
++ DPRINTK("ENTER\n");
++
++ /* do hardreset */
++ rc = sata_link_hardreset(link, timing, deadline);
++ if (rc) {
++ ata_link_printk(link, KERN_ERR,
++ "COMRESET failed (errno=%d)\n", rc);
++ return rc;
++ }
++
++ /* TODO: phy layer with polling, timeouts, etc. */
++ if (ata_link_offline(link)) {
++ *class = ATA_DEV_NONE;
++ DPRINTK("EXIT, link offline\n");
++ return 0;
++ }
++
++ /* wait a while before checking status */
++ ata_wait_after_reset(ap, deadline);
++
++ /* If PMP is supported, we have to do follow-up SRST. Note
++ * that some PMPs don't send D2H Reg FIS after hardreset at
++ * all if the first port is empty. Wait for it just for a
++ * second and request follow-up SRST.
++ */
++ if (ap->flags & ATA_FLAG_PMP) {
++ ata_wait_ready(ap, jiffies + HZ);
++ return -EAGAIN;
++ }
++
++ rc = ata_wait_ready(ap, deadline);
++ /* link occupied, -ENODEV too is an error */
++ if (rc) {
++ ata_link_printk(link, KERN_ERR,
++ "COMRESET failed (errno=%d)\n", rc);
++ return rc;
++ }
++
++ *class = ata_dev_try_classify(link->device, 1, NULL);
++
++ DPRINTK("EXIT, class=%u\n", *class);
++ return 0;
++}
++
++/**
++ * ata_std_postreset - standard postreset callback
++ * @link: the target ata_link
++ * @classes: classes of attached devices
++ *
++ * This function is invoked after a successful reset. Note that
++ * the device might have been reset more than once using
++ * different reset methods before postreset is invoked.
++ *
++ * LOCKING:
++ * Kernel thread context (may sleep)
++ */
++static void ox810sata_postreset(struct ata_link *link, unsigned int *classes)
++{
++ struct ata_port *ap = link->ap;
++ u32 serror;
++ unsigned int dev;
++
++ DPRINTK("ENTER\n");
++
++ /* print link status */
++ sata_print_link_status(link);
++
++ /* clear SError */
++ if (sata_scr_read(link, SCR_ERROR, &serror) == 0)
++ sata_scr_write(link, SCR_ERROR, serror);
++ link->eh_info.serror = 0;
++
++ /* turn on phy error detection by removing the masks */
++ __ox810sata_scr_write((u32* )SATA0_REGS_BASE , 0x0c, 0x30003 );
++ __ox810sata_scr_write((u32* )SATA1_REGS_BASE , 0x0c, 0x30003 );
++
++ /* bail out if no device is present */
++ if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
++ DPRINTK("EXIT, no device\n");
++ return;
++ }
++
++ /* go through all the devices and configure them */
++ for (dev = 0; dev < ATA_MAX_DEVICES; ++dev) {
++ if (ap->link.device[dev].class == ATA_DEV_ATA) {
++ ox810sata_dev_config(ap, &(ap->link.device[dev]));
++ }
++ }
++
++ /* disable padding */
++ {
++ unsigned int reg = readl(OX810SATA_DEVICE_CONTROL);
++ reg &= ~OX810SATA_DEVICE_CONTROL_PAD ;
++ writel(reg, OX810SATA_DEVICE_CONTROL);
++ }
++
++ /** @todo fix by using tf/tf_load as in ata_bus_softreset */
++ #if 0
++ /* set up device control */
++ if (ap->ioaddr.ctl_addr)
++ iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
++ #endif
++
++ DPRINTK("EXIT\n");
++}
++
++/**
++ * Outputs all the registers in the SATA core for diagnosis of faults.
++ *
++ * @param ap Hardware with the registers in
++ */
++static void CrazyDumpDebug()
++{
++#ifdef CRAZY_DUMP_DEBUG
++ u32 offset;
++ u32 result;
++ u32 patience;
++ volatile u32* ioaddr;
++
++#if 0
++ {
++ u32 i ;
++ for(i = 0;i < 1024;++i) {
++ printk("[%08x]%s%08x\n",
++ regarray[regindex].a,
++ regarray[regindex].w ? "<=" : "=>",
++ regarray[regindex].d
++ );
++ ++regindex;
++ regindex &= 1023;
++ }
++ }
++#endif
++
++ /* port 0 */
++ ioaddr = (u32* )SATA0_REGS_BASE;
++ printk("Port 0 High level registers\n");
++ for(offset = 0; offset < 48;offset++)
++ {
++ printk("[%02x] %08x\n", offset * 4, *(ioaddr + offset));
++ }
++
++ printk("Port 0 link layer registers\n");
++ for(offset = 0; offset < 16;++offset)
++ {
++ *(ioaddr + OX810SATA_LINK_RD_ADDR ) = (offset*4);
++ wmb();
++
++ for (patience = 0x100000;patience > 0;--patience)
++ {
++ if (*(ioaddr + OX810SATA_LINK_CONTROL) & 0x00000001)
++ break;
++ }
++
++ result = *(ioaddr + OX810SATA_LINK_DATA);
++ printk("[%02x] %08x\n", offset*4, result);
++ }
++
++ /* port 1 */
++ ioaddr = (u32* )SATA1_REGS_BASE;
++ printk("Port 1 High level registers\n");
++ for(offset = 0; offset < 48;offset++)
++ {
++ printk("[%02x] %08x\n", offset * 4, *(ioaddr + offset));
++ }
++
++ printk("Port 1 link layer registers\n");
++ for(offset = 0; offset < 16;++offset)
++ {
++ *(ioaddr + OX810SATA_LINK_RD_ADDR ) = (offset*4);
++ wmb();
++
++ for (patience = 0x100000;patience > 0;--patience)
++ {
++ if (*(ioaddr + OX810SATA_LINK_CONTROL) & 0x00000001)
++ break;
++ }
++
++ result = *(ioaddr + OX810SATA_LINK_DATA);
++ printk("[%02x] %08x\n", offset*4, result);
++ }
++
++ /* port 14 */
++ ioaddr = (u32* )SATARAID_REGS_BASE;
++ printk("RAID registers\n");
++ for(offset = 0; offset < 48;offset++)
++ {
++ printk("[%02x] %08x\n", offset * 4, *(ioaddr + offset));
++ }
++
++ /* port 15 */
++ ioaddr = (u32* )SATACORE_REGS_BASE;
++ printk("CORE registers\n");
++ for(offset = 0; offset < 48;offset++)
++ {
++ printk("[%02x] %08x\n", offset * 4, *(ioaddr + offset));
++ }
++
++ oxnas_dma_dump_registers();
++
++#endif
++}
++
++/**************************************************************************
++* DEVICE CODE
++**************************************************************************/
++
++/**
++ * Describes the identity of the SATA core and the resources it requires
++ */
++static struct resource ox810sata_port0_resources[] = {
++ {
++ .name = "sata_port_0_registers",
++ .start = SATA0_REGS_BASE,
++ .end = SATA0_REGS_BASE + 0xff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "sata_irq",
++ .start = SATA_1_INTERRUPT,
++ .flags = IORESOURCE_IRQ,
++ }
++};
++
++static struct resource ox810sata_port1_resources[] = {
++ {
++ .name = "sata_port_1_registers",
++ .start = SATA1_REGS_BASE,
++ .end = SATA1_REGS_BASE + 0xff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "sata_irq",
++ .start = SATA_1_INTERRUPT,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device ox810sata_dev0 =
++{
++ .name = DRIVER_NAME,
++ .id = 0,
++ .num_resources = 2,
++ .resource = ox810sata_port0_resources,
++ .dev.coherent_dma_mask = 0xffffffff,
++};
++
++static struct platform_device ox810sata_dev1 =
++{
++ .name = DRIVER_NAME,
++ .id = 1,
++ .num_resources = 2,
++ .resource = ox810sata_port1_resources,
++ .dev.coherent_dma_mask = 0xffffffff,
++};
++
++/**
++ * module initialisation
++ * @return success is 0
++ */
++static int __init ox810sata_device_init( void )
++{
++ int ret;
++
++ /* reset the core */
++ ox810sata_reset_core();
++
++ {
++ // register the ata device for the driver to find
++ ret = platform_device_register( &ox810sata_dev0 );
++ DPRINTK(" %i\n", ret);
++ }
++
++#ifndef CONFIG_OX810SATA_SINGLE_SATA
++ {
++ // register the ata device for the driver to find
++ ret = platform_device_register( &ox810sata_dev1 );
++ DPRINTK(" %i\n", ret);
++ }
++#endif /* CONFIG_OX810_SINGLE_SATA */
++
++ return ret;
++}
++
++/**
++ * module cleanup
++ */
++static void __exit ox810sata_device_exit(void)
++{
++ platform_device_unregister( &ox810sata_dev0 );
++ platform_device_unregister( &ox810sata_dev1 );
++}
++
++/**
++ * Returns accumulated RAID faults and then clears the accumulation
++ * @return accumulated RAID faults indicated by set bits
++ */
++int oxnassata_RAID_faults( void ) {
++ int temp = ox810sata_accumulated_RAID_faults;
++ ox810sata_accumulated_RAID_faults = 0;
++ return temp;
++}
++
++/**
++ * Returns ox810 port number the request queue is serviced by.
++ *
++ * @param queue The queue under investigation.
++ * @return The ox810 sata port number servicing the queue or -1 if not found.
++ */
++int oxnassata_get_port_no(struct request_queue* q)
++{
++ struct ata_port* ap = 0;
++ struct scsi_device* sdev = 0;
++
++ /* check port 0 */
++ ap = ox810sata_driver.ap[0];
++ if (ap)
++ shost_for_each_device(sdev, ap->scsi_host) {
++ if (sdev->request_queue == q) {
++ DPRINTK("Queue %p on port 0\n", q);
++ return 0;
++ }
++ }
++
++ /* check port 1 */
++ ap = ox810sata_driver.ap[1];
++ if (ap)
++ shost_for_each_device(sdev, ap->scsi_host) {
++ if (sdev->request_queue == q) {
++ DPRINTK("Queue %p on port 1\n", q);
++ return 1;
++ }
++ }
++
++ /* not found */
++ return -1;
++}
++
++/**
++ * @return true if all the drives attached to the internal SATA ports use the
++ * same LBA size.
++ */
++int oxnassata_LBA_schemes_compatible( void )
++{
++ unsigned long flags0 ;
++ unsigned long flags1 ;
++ struct ata_port* ap ;
++
++ /* check port 0 */
++ ap = ox810sata_driver.ap[0];
++ if (ap)
++ flags0 = ap->link.device[0].flags & ATA_DFLAG_LBA48 ;
++ else
++ return 0;
++
++ /* check port 1 */
++ ap = ox810sata_driver.ap[1];
++ if (ap)
++ flags1 = ap->link.device[0].flags & ATA_DFLAG_LBA48 ;
++ else
++ return 0;
++
++ /* compare */
++ return (flags0 == flags1);
++}
++
++EXPORT_SYMBOL( oxnassata_RAID_faults );
++EXPORT_SYMBOL( oxnassata_get_port_no );
++EXPORT_SYMBOL( oxnassata_LBA_schemes_compatible );
++
++
++#ifdef ERROR_INJECTION
++
++/**
++ * @param kobj Not Used
++ * @param attr Used to determine which file is being accessed
++ * @param buffer Space to put the file contents
++ * @return The number of bytes transferred or an error
++ */
++static int ox810sata_error_inject_show(
++ char *page, char **start, off_t off, int count, int *eof, void *data)
++{
++ if (page)
++ {
++ if ( ox810sata_driver.error_inject ) {
++ page[0] = ox810sata_driver.error_inject + '0';
++ page[1] = '\n';
++ page[2] = 0;
++ return 3;
++ } else {
++ strcpy(page, "off\n" );
++ return 5;
++ }
++ }
++
++ /* if we get here, there's been an error */
++ return -EIO;
++}
++
++
++static int ox810sata_error_inject_store(struct file *file,
++ const char __user *buffer,
++ unsigned long count,
++ void *data) {
++ if (count)
++ {
++ if ((buffer[0] >= '0') &&
++ (buffer[0] <= '9')) {
++ ox810sata_driver.error_inject = buffer[0] - '0';
++ }
++ return count;
++ }
++
++ /* if we get here, there's been an error */
++ return -EIO;
++}
++
++#endif /* ERROR_INJECTION */
++
++
++
++/**
++ * macros to register intiialisation and exit functions with kernal
++ */
++module_init(ox810sata_device_init);
++module_exit(ox810sata_device_exit);
+diff -Nurd linux-2.6.24/drivers/ata/pata_hpt366.c linux-2.6.24-oxe810/drivers/ata/pata_hpt366.c
+--- linux-2.6.24/drivers/ata/pata_hpt366.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/ata/pata_hpt366.c 2008-06-11 17:50:32.000000000 +0200
+@@ -27,7 +27,7 @@
+ #include <linux/libata.h>
+
+ #define DRV_NAME "pata_hpt366"
+-#define DRV_VERSION "0.6.1"
++#define DRV_VERSION "0.6.2"
+
+ struct hpt_clock {
+ u8 xfer_speed;
+@@ -180,9 +180,9 @@
+ if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
+ mask &= ~ATA_MASK_UDMA;
+ if (hpt_dma_blacklisted(adev, "UDMA3", bad_ata66_3))
+- mask &= ~(0x07 << ATA_SHIFT_UDMA);
++ mask &= ~(0xF8 << ATA_SHIFT_UDMA);
+ if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4))
+- mask &= ~(0x0F << ATA_SHIFT_UDMA);
++ mask &= ~(0xF0 << ATA_SHIFT_UDMA);
+ }
+ return ata_pci_default_filter(adev, mask);
+ }
+diff -Nurd linux-2.6.24/drivers/ata/pata_hpt37x.c linux-2.6.24-oxe810/drivers/ata/pata_hpt37x.c
+--- linux-2.6.24/drivers/ata/pata_hpt37x.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/ata/pata_hpt37x.c 2008-06-11 17:50:32.000000000 +0200
+@@ -24,7 +24,7 @@
+ #include <linux/libata.h>
+
+ #define DRV_NAME "pata_hpt37x"
+-#define DRV_VERSION "0.6.9"
++#define DRV_VERSION "0.6.11"
+
+ struct hpt_clock {
+ u8 xfer_speed;
+@@ -281,7 +281,7 @@
+ if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
+ mask &= ~ATA_MASK_UDMA;
+ if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
+- mask &= ~(0x1F << ATA_SHIFT_UDMA);
++ mask &= ~(0xE0 << ATA_SHIFT_UDMA);
+ }
+ return ata_pci_default_filter(adev, mask);
+ }
+@@ -297,7 +297,7 @@
+ {
+ if (adev->class == ATA_DEV_ATA) {
+ if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
+- mask &= ~ (0x1F << ATA_SHIFT_UDMA);
++ mask &= ~(0xE0 << ATA_SHIFT_UDMA);
+ }
+ return ata_pci_default_filter(adev, mask);
+ }
+diff -Nurd linux-2.6.24/drivers/ata/pata_serverworks.c linux-2.6.24-oxe810/drivers/ata/pata_serverworks.c
+--- linux-2.6.24/drivers/ata/pata_serverworks.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/ata/pata_serverworks.c 2008-06-11 17:50:32.000000000 +0200
+@@ -226,7 +226,7 @@
+
+ for (i = 0; (p = csb_bad_ata100[i]) != NULL; i++) {
+ if (!strcmp(p, model_num))
+- mask &= ~(0x1F << ATA_SHIFT_UDMA);
++ mask &= ~(0xE0 << ATA_SHIFT_UDMA);
+ }
+ return ata_pci_default_filter(adev, mask);
+ }
+diff -Nurd linux-2.6.24/drivers/base/firmware_class.c linux-2.6.24-oxe810/drivers/base/firmware_class.c
+--- linux-2.6.24/drivers/base/firmware_class.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/base/firmware_class.c 2008-06-11 17:50:32.000000000 +0200
+@@ -292,7 +292,8 @@
+
+ static inline void fw_setup_device_id(struct device *f_dev, struct device *dev)
+ {
+- snprintf(f_dev->bus_id, BUS_ID_SIZE, "firmware-%s", dev->bus_id);
++ /* XXX warning we should watch out for name collisions */
++ strlcpy(f_dev->bus_id, dev->bus_id, BUS_ID_SIZE);
+ }
+
+ static int fw_register_device(struct device **dev_p, const char *fw_name,
+diff -Nurd linux-2.6.24/drivers/base/platform.c linux-2.6.24-oxe810/drivers/base/platform.c
+--- linux-2.6.24/drivers/base/platform.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/base/platform.c 2008-06-11 17:50:32.000000000 +0200
+@@ -647,7 +647,7 @@
+ high_totalram += high_totalram - 1;
+ mask = (((u64)high_totalram) << 32) + 0xffffffff;
+ }
+- return mask & *dev->dma_mask;
++ return mask;
+ }
+ EXPORT_SYMBOL_GPL(dma_get_required_mask);
+ #endif
+diff -Nurd linux-2.6.24/drivers/block/ub.c linux-2.6.24-oxe810/drivers/block/ub.c
+--- linux-2.6.24/drivers/block/ub.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/block/ub.c 2008-06-11 17:49:32.000000000 +0200
+@@ -657,7 +657,6 @@
+ if ((cmd = ub_get_cmd(lun)) == NULL)
+ return -1;
+ memset(cmd, 0, sizeof(struct ub_scsi_cmd));
+- sg_init_table(cmd->sgv, UB_MAX_REQ_SG);
+
+ blkdev_dequeue_request(rq);
+
+@@ -668,6 +667,7 @@
+ /*
+ * get scatterlist from block layer
+ */
++ sg_init_table(&urq->sgv[0], UB_MAX_REQ_SG);
+ n_elem = blk_rq_map_sg(lun->disk->queue, rq, &urq->sgv[0]);
+ if (n_elem < 0) {
+ /* Impossible, because blk_rq_map_sg should not hit ENOMEM. */
+diff -Nurd linux-2.6.24/drivers/char/defkeymap.c_shipped linux-2.6.24-oxe810/drivers/char/defkeymap.c_shipped
+--- linux-2.6.24/drivers/char/defkeymap.c_shipped 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/char/defkeymap.c_shipped 2008-06-11 17:49:52.000000000 +0200
+@@ -223,40 +223,40 @@
+ };
+
+ struct kbdiacruc accent_table[MAX_DIACR] = {
+- {'`', 'A', '\300'}, {'`', 'a', '\340'},
+- {'\'', 'A', '\301'}, {'\'', 'a', '\341'},
+- {'^', 'A', '\302'}, {'^', 'a', '\342'},
+- {'~', 'A', '\303'}, {'~', 'a', '\343'},
+- {'"', 'A', '\304'}, {'"', 'a', '\344'},
+- {'O', 'A', '\305'}, {'o', 'a', '\345'},
+- {'0', 'A', '\305'}, {'0', 'a', '\345'},
+- {'A', 'A', '\305'}, {'a', 'a', '\345'},
+- {'A', 'E', '\306'}, {'a', 'e', '\346'},
+- {',', 'C', '\307'}, {',', 'c', '\347'},
+- {'`', 'E', '\310'}, {'`', 'e', '\350'},
+- {'\'', 'E', '\311'}, {'\'', 'e', '\351'},
+- {'^', 'E', '\312'}, {'^', 'e', '\352'},
+- {'"', 'E', '\313'}, {'"', 'e', '\353'},
+- {'`', 'I', '\314'}, {'`', 'i', '\354'},
+- {'\'', 'I', '\315'}, {'\'', 'i', '\355'},
+- {'^', 'I', '\316'}, {'^', 'i', '\356'},
+- {'"', 'I', '\317'}, {'"', 'i', '\357'},
+- {'-', 'D', '\320'}, {'-', 'd', '\360'},
+- {'~', 'N', '\321'}, {'~', 'n', '\361'},
+- {'`', 'O', '\322'}, {'`', 'o', '\362'},
+- {'\'', 'O', '\323'}, {'\'', 'o', '\363'},
+- {'^', 'O', '\324'}, {'^', 'o', '\364'},
+- {'~', 'O', '\325'}, {'~', 'o', '\365'},
+- {'"', 'O', '\326'}, {'"', 'o', '\366'},
+- {'/', 'O', '\330'}, {'/', 'o', '\370'},
+- {'`', 'U', '\331'}, {'`', 'u', '\371'},
+- {'\'', 'U', '\332'}, {'\'', 'u', '\372'},
+- {'^', 'U', '\333'}, {'^', 'u', '\373'},
+- {'"', 'U', '\334'}, {'"', 'u', '\374'},
+- {'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
+- {'T', 'H', '\336'}, {'t', 'h', '\376'},
+- {'s', 's', '\337'}, {'"', 'y', '\377'},
+- {'s', 'z', '\337'}, {'i', 'j', '\377'},
++ {'`', 'A', 0300}, {'`', 'a', 0340},
++ {'\'', 'A', 0301}, {'\'', 'a', 0341},
++ {'^', 'A', 0302}, {'^', 'a', 0342},
++ {'~', 'A', 0303}, {'~', 'a', 0343},
++ {'"', 'A', 0304}, {'"', 'a', 0344},
++ {'O', 'A', 0305}, {'o', 'a', 0345},
++ {'0', 'A', 0305}, {'0', 'a', 0345},
++ {'A', 'A', 0305}, {'a', 'a', 0345},
++ {'A', 'E', 0306}, {'a', 'e', 0346},
++ {',', 'C', 0307}, {',', 'c', 0347},
++ {'`', 'E', 0310}, {'`', 'e', 0350},
++ {'\'', 'E', 0311}, {'\'', 'e', 0351},
++ {'^', 'E', 0312}, {'^', 'e', 0352},
++ {'"', 'E', 0313}, {'"', 'e', 0353},
++ {'`', 'I', 0314}, {'`', 'i', 0354},
++ {'\'', 'I', 0315}, {'\'', 'i', 0355},
++ {'^', 'I', 0316}, {'^', 'i', 0356},
++ {'"', 'I', 0317}, {'"', 'i', 0357},
++ {'-', 'D', 0320}, {'-', 'd', 0360},
++ {'~', 'N', 0321}, {'~', 'n', 0361},
++ {'`', 'O', 0322}, {'`', 'o', 0362},
++ {'\'', 'O', 0323}, {'\'', 'o', 0363},
++ {'^', 'O', 0324}, {'^', 'o', 0364},
++ {'~', 'O', 0325}, {'~', 'o', 0365},
++ {'"', 'O', 0326}, {'"', 'o', 0366},
++ {'/', 'O', 0330}, {'/', 'o', 0370},
++ {'`', 'U', 0331}, {'`', 'u', 0371},
++ {'\'', 'U', 0332}, {'\'', 'u', 0372},
++ {'^', 'U', 0333}, {'^', 'u', 0373},
++ {'"', 'U', 0334}, {'"', 'u', 0374},
++ {'\'', 'Y', 0335}, {'\'', 'y', 0375},
++ {'T', 'H', 0336}, {'t', 'h', 0376},
++ {'s', 's', 0337}, {'"', 'y', 0377},
++ {'s', 'z', 0337}, {'i', 'j', 0377},
+ };
+
+ unsigned int accent_table_size = 68;
+diff -Nurd linux-2.6.24/drivers/char/drm/drm_stub.c linux-2.6.24-oxe810/drivers/char/drm/drm_stub.c
+--- linux-2.6.24/drivers/char/drm/drm_stub.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/char/drm/drm_stub.c 2008-06-11 17:49:50.000000000 +0200
+@@ -218,6 +218,7 @@
+ if (ret)
+ goto err_g1;
+
++ pci_set_master(pdev);
+ if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
+ printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
+ goto err_g2;
+diff -Nurd linux-2.6.24/drivers/char/drm/drm_vm.c linux-2.6.24-oxe810/drivers/char/drm/drm_vm.c
+--- linux-2.6.24/drivers/char/drm/drm_vm.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/char/drm/drm_vm.c 2008-06-11 17:49:50.000000000 +0200
+@@ -506,6 +506,7 @@
+ vma->vm_ops = &drm_vm_dma_ops;
+
+ vma->vm_flags |= VM_RESERVED; /* Don't swap */
++ vma->vm_flags |= VM_DONTEXPAND;
+
+ vma->vm_file = filp; /* Needed for drm_vm_open() */
+ drm_vm_open_locked(vma);
+@@ -655,6 +656,7 @@
+ return -EINVAL; /* This should never happen. */
+ }
+ vma->vm_flags |= VM_RESERVED; /* Don't swap */
++ vma->vm_flags |= VM_DONTEXPAND;
+
+ vma->vm_file = filp; /* Needed for drm_vm_open() */
+ drm_vm_open_locked(vma);
+diff -Nurd linux-2.6.24/drivers/char/mspec.c linux-2.6.24-oxe810/drivers/char/mspec.c
+--- linux-2.6.24/drivers/char/mspec.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/char/mspec.c 2008-06-11 17:49:52.000000000 +0200
+@@ -283,7 +283,7 @@
+ vdata->refcnt = ATOMIC_INIT(1);
+ vma->vm_private_data = vdata;
+
+- vma->vm_flags |= (VM_IO | VM_RESERVED | VM_PFNMAP);
++ vma->vm_flags |= (VM_IO | VM_RESERVED | VM_PFNMAP | VM_DONTEXPAND);
+ if (vdata->type == MSPEC_FETCHOP || vdata->type == MSPEC_UNCACHED)
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_ops = &mspec_vm_ops;
+diff -Nurd linux-2.6.24/drivers/char/vt.c linux-2.6.24-oxe810/drivers/char/vt.c
+--- linux-2.6.24/drivers/char/vt.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/char/vt.c 2008-06-11 17:49:52.000000000 +0200
+@@ -702,6 +702,7 @@
+ if (is_switch) {
+ set_leds();
+ compute_shiftstate();
++ notify_update(vc);
+ }
+ }
+
+diff -Nurd linux-2.6.24/drivers/dma/Kconfig linux-2.6.24-oxe810/drivers/dma/Kconfig
+--- linux-2.6.24/drivers/dma/Kconfig 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/dma/Kconfig 2008-06-11 17:49:45.000000000 +0200
+@@ -4,7 +4,7 @@
+
+ menuconfig DMADEVICES
+ bool "DMA Engine support"
+- depends on (PCI && X86) || ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX
++ depends on (PCI && X86) || ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX || ARCH_OXNAS
+ help
+ DMA engines can do asynchronous data transfers without
+ involving the host CPU. Currently, this framework can be
+@@ -36,6 +36,14 @@
+ help
+ Enable support for the Intel(R) IOP Series RAID engines.
+
++config OXNAS_ADMA
++ tristate "Oxford Semiconductor ADAM support"
++ depends on ARCH_OXNAS
++ select ASYNC_CORE
++ select DMA_ENGINE
++ help
++ Enable support for the Oxford Semiconductor async. DMA engine
++
+ config DMA_ENGINE
+ bool
+
+diff -Nurd linux-2.6.24/drivers/dma/Makefile linux-2.6.24-oxe810/drivers/dma/Makefile
+--- linux-2.6.24/drivers/dma/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/dma/Makefile 2008-06-11 17:49:45.000000000 +0200
+@@ -3,3 +3,4 @@
+ obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o
+ ioatdma-objs := ioat.o ioat_dma.o ioat_dca.o
+ obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
++obj-$(CONFIG_OXNAS_ADMA) += oxnas_adma.o
+diff -Nurd linux-2.6.24/drivers/dma/ioat_dma.c linux-2.6.24-oxe810/drivers/dma/ioat_dma.c
+--- linux-2.6.24/drivers/dma/ioat_dma.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/dma/ioat_dma.c 2008-06-11 17:49:45.000000000 +0200
+@@ -726,6 +726,7 @@
+
+ if (new) {
+ new->len = len;
++ new->async_tx.ack = 0;
+ return &new->async_tx;
+ } else
+ return NULL;
+@@ -749,6 +750,7 @@
+
+ if (new) {
+ new->len = len;
++ new->async_tx.ack = 0;
+ return &new->async_tx;
+ } else
+ return NULL;
+diff -Nurd linux-2.6.24/drivers/dma/oxnas_adma.c linux-2.6.24-oxe810/drivers/dma/oxnas_adma.c
+--- linux-2.6.24/drivers/dma/oxnas_adma.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/dma/oxnas_adma.c 2008-06-11 17:49:45.000000000 +0200
+@@ -0,0 +1,272 @@
++/*
++ * drivers/dma/oxnas_adma.c
++ *
++ * Copyright (C) 2008 Oxford Semiconductor Ltd
++ *
++ * 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 <linux/dmaengine.h>
++#include <linux/platform_device.h>
++#include <asm/dma.h>
++
++/* MODULE API */
++MODULE_VERSION("1.0");
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Oxford Semiconductor Ltd.");
++
++typedef struct oxnas_adma_device {
++ struct dma_device common;
++ struct platform_device *platform_device;
++} oxnas_adma_device_t;
++
++typedef struct oxnas_adma_channel {
++ struct dma_chan common;
++ oxnas_dma_channel_t *oxnas_channel;
++ /* Need a queue for pending descriptors */
++ /* May need a queue for completed descriptors that haven't been acked yet */
++} oxnas_adma_channel_t;
++
++typedef struct oxnas_adma_desc {
++ struct dma_async_tx_descriptor async_desc;
++ size_t len;
++ dma_addr_t src_adr;
++ dma_addr_t dst_adr;
++} oxnas_adma_desc_t;
++
++static int __devexit oxnas_adma_remove(struct platform_device *dev)
++{
++ oxnas_adma_device_t *oxnas_adma_device = platform_get_drvdata(dev);
++ struct dma_device *dma_device = &oxnas_adma_device->common;
++ struct dma_chan *channel, *_channel;
++
++ dma_async_device_unregister(dma_device);
++
++ list_for_each_entry_safe(channel, _channel, &dma_device->channels, device_node) {
++ list_del(&channel->device_node);
++ kfree(channel);
++ }
++ kfree(oxnas_adma_device);
++
++ return 0;
++}
++
++static void oxnas_adma_set_src(dma_addr_t addr, struct dma_async_tx_descriptor *tx, int index)
++{
++ oxnas_adma_desc_t *desc = container_of(tx, oxnas_adma_desc_t, async_desc);
++ desc->src_adr = addr;
++}
++
++static void oxnas_adm_set_dest(dma_addr_t addr, struct dma_async_tx_descriptor *tx, int index)
++{
++ oxnas_adma_desc_t *desc = container_of(tx, oxnas_adma_desc_t, async_desc);
++ desc->dst_adr = addr;
++}
++
++static void oxnas_dma_callback(
++ oxnas_dma_channel_t *channel,
++ oxnas_callback_arg_t arg,
++ oxnas_dma_callback_status_t status,
++ u16 checksum,
++ int interrupt_count)
++{
++ oxnas_adma_desc_t *desc = (oxnas_adma_desc_t*)arg;
++
++ /* Use cookies to record that this descriptor's transfer has completed */
++
++ /* Store the completion status with the descriptor */
++
++ /* If there is a queued descriptor, start its transfer now - if that's
++ possible from a DMA callback - with the callback arg updated */
++}
++
++static dma_cookie_t oxnas_adma_submit_tx(struct dma_async_tx_descriptor *tx)
++{
++ oxnas_adma_desc_t *desc = container_of(tx, oxnas_adma_desc_t, async_desc);
++ oxnas_adma_channel_t *channel = container_of(tx->chan, oxnas_adma_channel_t, common);
++ dma_cookie_t cookie;
++
++ if (oxnas_dma_set(channel->oxnas_channel,
++ (unsigned char*)desc->src_adr,
++ desc->len,
++ (unsigned char*)desc->dst_adr,
++ OXNAS_DMA_MODE_INC,
++ OXNAS_DMA_MODE_INC,
++ 0, 0)) {
++ return -1;
++ }
++
++ /* Allocate a cookie for this descriptor */
++ cookie = -1;
++
++ /* Be careful to syn. properly with DMA callback here */
++ if (oxnas_dma_is_active(channel->oxnas_channel)) {
++ /* Queue the new descriptor to be started when current transfer completes */
++ } else {
++ /* Start the new transfer */
++ oxnas_dma_set_callback(channel->oxnas_channel, oxnas_dma_callback, desc)
++ oxnas_dma_start(channel->oxnas_channel);
++ }
++
++ return cookie;
++}
++
++/** Allocate a DMA channel and prepare it for memory to memory transfers. Could
++ * preallocate descriptors here
++ */
++static int oxnas_adma_alloc_chan_resources(struct dma_chan *chan)
++{
++ oxnas_adma_channel_t *channel = container_of(chan, oxnas_adma_channel_t, common);
++
++ channel->oxnas_channel = oxnas_dma_request(0);
++ if (!channel->oxnas_channel) {
++ return 0;
++ }
++
++ /* Pretend we've allocated one descriptor */
++ return 1;
++}
++
++static void oxnas_adma_free_chan_resources(struct dma_chan *chan)
++{
++ oxnas_adma_channel_t *channel = container_of(chan, oxnas_adma_channel_t, common);
++ oxnas_dma_free(channel->oxnas_channel);
++
++ /* May need to free leftover descriptors here as well */
++}
++
++/** Poll for the DMA channel's active status. There can be multiple transfers
++ * queued with the DMA channel identified by cookies, so should be checking
++ * lists containing all pending transfers and all completed transfers that have
++ * not yet been polled for completion
++ */
++static enum dma_status oxnas_adma_is_tx_complete(
++ struct dma_chan *chan,
++ dma_cookie_t cookie,
++ dma_cookie_t *last,
++ dma_cookie_t *used)
++{
++ oxnas_adma_channel_t *channel = container_of(chan, oxnas_adma_channel_t, common);
++
++ /* Use cookies to report completion status */
++
++ return oxnas_dma_is_active(channel->oxnas_channel) ? DMA_IN_PROGRESS : DMA_SUCCESS;
++}
++
++/** To push outstanding transfers to h/w. This should use the list of pending
++ * transfers identified by cookies to select the next transfer and pass this to
++ * the hardware
++ */
++static void oxnas_adma_issue_pending(struct dma_chan *chan)
++{
++ /* If there isn't a transfer in progress and one is queued start it now,
++ being careful to sync. with DMA callback function */
++}
++
++static void oxnas_adma_dependency_added(struct dma_chan *chan)
++{
++ /* What is supposed to happen here? */
++}
++
++/** Allocate descriptors capable of mapping the requested length of memory */
++static struct dma_async_tx_descriptor *oxnas_adma_prep_dma_memcpy(struct dma_chan *chan, size_t len, int int_en)
++{
++ oxnas_adma_desc_t *desc = kzalloc(sizeof(oxnas_adma_desc_t), GFP_KERNEL);
++ if (unlikely(!desc)) {
++ return NULL;
++ }
++
++ desc->async_desc.tx_set_src = oxnas_adma_set_src;
++ desc->async_desc.tx_set_dest = oxnas_adm_set_dest;
++ desc->async_desc.tx_submit = oxnas_adma_submit_tx;
++ desc->len = len;
++
++ return &desc->async_desc;
++}
++
++static int enumerate_dma_channels(struct dma_device *dma_device)
++{
++ int i;
++
++ dma_device->chancnt = 3;
++
++ for (i = 0; i < dma_device->chancnt; i++) {
++ oxnas_adma_channel_t *channel = kzalloc(sizeof(oxnas_adma_channel_t), GFP_KERNEL);
++ if (!channel) {
++ dma_device->chancnt = i;
++ break;
++ }
++
++ channel->common.device = dma_device;
++ list_add_tail(&channel->common.device_node, &dma_device->channels);
++ }
++
++ return dma_device->chancnt;
++}
++
++static int __devinit oxnas_adma_probe(struct platform_device *platform_device)
++{
++ oxnas_adma_device_t *oxnas_adma_device;
++ struct dma_device *dma_device;
++
++ oxnas_adma_device = kzalloc(sizeof(oxnas_adma_device_t), GFP_KERNEL);
++ if (!oxnas_adma_device) {
++ return -ENOMEM;
++ }
++
++ oxnas_adma_device->platform_device = platform_device;
++ dma_device = &oxnas_adma_device->common;
++
++ platform_set_drvdata(platform_device, oxnas_adma_device);
++
++ INIT_LIST_HEAD(&dma_device->channels);
++ enumerate_dma_channels(dma_device);
++
++ dma_cap_set(DMA_MEMCPY, dma_device->cap_mask);
++ dma_device->device_alloc_chan_resources = oxnas_adma_alloc_chan_resources;
++ dma_device->device_free_chan_resources = oxnas_adma_free_chan_resources;
++ dma_device->device_is_tx_complete = oxnas_adma_is_tx_complete;
++ dma_device->device_issue_pending = oxnas_adma_issue_pending;
++ dma_device->device_dependency_added = oxnas_adma_dependency_added;
++ dma_device->dev = &platform_device->dev;
++ dma_device->device_prep_dma_memcpy = oxnas_adma_prep_dma_memcpy;
++
++ dma_async_device_register(dma_device);
++
++ return 0;
++}
++
++static struct platform_driver oxnas_adma_driver = {
++ .probe = oxnas_adma_probe,
++ .remove = oxnas_adma_remove,
++ .driver = {
++ .owner = THIS_MODULE,
++ .name = "oxnas-adma",
++ },
++};
++
++static int __init oxnas_adma_init_module(void)
++{
++ return platform_driver_register(&oxnas_adma_driver);
++}
++
++module_init(oxnas_adma_init_module);
++
++static void __exit oxnas_adma_exit_module(void)
++{
++ platform_driver_unregister(&oxnas_adma_driver);
++ return;
++}
++
++module_exit(oxnas_adma_exit_module);
+diff -Nurd linux-2.6.24/drivers/firmware/dmi_scan.c linux-2.6.24-oxe810/drivers/firmware/dmi_scan.c
+--- linux-2.6.24/drivers/firmware/dmi_scan.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/firmware/dmi_scan.c 2008-06-11 17:49:40.000000000 +0200
+@@ -469,12 +469,3 @@
+
+ return year;
+ }
+-
+-/**
+- * dmi_get_slot - return dmi_ident[slot]
+- * @slot: index into dmi_ident[]
+- */
+-char *dmi_get_slot(int slot)
+-{
+- return(dmi_ident[slot]);
+-}
+diff -Nurd linux-2.6.24/drivers/i2c/algos/Kconfig linux-2.6.24-oxe810/drivers/i2c/algos/Kconfig
+--- linux-2.6.24/drivers/i2c/algos/Kconfig 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/i2c/algos/Kconfig 2008-06-11 17:50:33.000000000 +0200
+@@ -34,6 +34,10 @@
+ This support is also available as a module. If so, the module
+ will be called i2c-algo-pca.
+
++config I2C_ALGOOXSEMI
++ tristate "OXNAS I2C interface"
++ depends on I2C
++
+ config I2C_ALGO_SGI
+ tristate "I2C SGI interfaces"
+ depends on SGI_IP22 || SGI_IP32 || X86_VISWS
+diff -Nurd linux-2.6.24/drivers/i2c/algos/Makefile linux-2.6.24-oxe810/drivers/i2c/algos/Makefile
+--- linux-2.6.24/drivers/i2c/algos/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/i2c/algos/Makefile 2008-06-11 17:50:34.000000000 +0200
+@@ -5,6 +5,7 @@
+ obj-$(CONFIG_I2C_ALGOBIT) += i2c-algo-bit.o
+ obj-$(CONFIG_I2C_ALGOPCF) += i2c-algo-pcf.o
+ obj-$(CONFIG_I2C_ALGOPCA) += i2c-algo-pca.o
++obj-$(CONFIG_I2C_ALGOOXSEMI) += i2c-algo-oxnas.o
+ obj-$(CONFIG_I2C_ALGO_SGI) += i2c-algo-sgi.o
+
+ ifeq ($(CONFIG_I2C_DEBUG_ALGO),y)
+diff -Nurd linux-2.6.24/drivers/i2c/algos/i2c-algo-oxnas.c linux-2.6.24-oxe810/drivers/i2c/algos/i2c-algo-oxnas.c
+--- linux-2.6.24/drivers/i2c/algos/i2c-algo-oxnas.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/i2c/algos/i2c-algo-oxnas.c 2008-06-11 17:50:33.000000000 +0200
+@@ -0,0 +1,858 @@
++/*
++ * i2c-algo-oxnas.c i2x driver algorithms for MPCoxnas
++ * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
++ *
++ 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.
++ *
++ */
++
++// XXX todo
++// timeout sleep?
++
++
++/* $Id: i2c-algo-oxnas.c,v 1.15 2004/11/20 08:02:24 khali Exp $ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/delay.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/errno.h>
++#include <linux/sched.h>
++#include "linux/i2c.h"
++#include "linux/i2c-algo-oxnas.h"
++#include <asm/bitops.h>
++
++
++
++#define OXNAS_MAX_READ 513
++/* #define I2C_CHIP_ERRATA */ /* Try uncomment this if you have an older CPU(earlier than rev D4) */ //NOTE
++static wait_queue_head_t iic_wait;
++
++int oxnas_debug = 1;
++int oxnas_scan = 1;
++
++static inline void oxnas_iic_algo_dump_reg( void )
++{
++ i2c_registers_oxnas_t* i2c = (i2c_registers_oxnas_t*) I2C_BASE; // SERIAL_MASTER_CONTROL_BASE;
++
++ printk( KERN_INFO "\n\n ==================================================================" );
++ printk( KERN_INFO " i2c->SerialControlRegister; == 0x%08x @ %p\n", i2c->SerialControlRegister , &(i2c->SerialControlRegister ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x00; */
++ printk( KERN_INFO " i2c->SerialAddressRegister; == 0x%08x @ %p\n", i2c->SerialAddressRegister , &(i2c->SerialAddressRegister ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x04; */
++ printk( KERN_INFO " i2c->SerialSWControlOutRegister; == 0x%08x @ %p\n", i2c->SerialSWControlOutRegister , &(i2c->SerialSWControlOutRegister ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x08; */
++ printk( KERN_INFO " i2c->SerialSWControlInRegister; == 0x%08x @ %p\n", i2c->SerialSWControlInRegister , &(i2c->SerialSWControlInRegister ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x0C; */
++ printk( KERN_INFO " i2c->SerialInterruptStatusRegister; == 0x%08x @ %p\n", i2c->SerialInterruptStatusRegister , &(i2c->SerialInterruptStatusRegister ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x10; */
++ printk( KERN_INFO " i2c->SerialInterruptEnableRegister; == 0x%08x @ %p\n", i2c->SerialInterruptEnableRegister , &(i2c->SerialInterruptEnableRegister ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x14; */
++ printk( KERN_INFO "\n" ); /* PAD REGISTER PACKING ***/
++ printk( KERN_INFO " i2c->SerialReadData1Register; == 0x%08x @ %p\n", i2c->SerialReadData1Register , &(i2c->SerialReadData1Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x20; */
++ printk( KERN_INFO " i2c->SerialReadData2Register; == 0x%08x @ %p\n", i2c->SerialReadData2Register , &(i2c->SerialReadData2Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x24; */
++ printk( KERN_INFO " i2c->SerialReadData3Register; == 0x%08x @ %p\n", i2c->SerialReadData3Register , &(i2c->SerialReadData3Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x28; */
++ printk( KERN_INFO " i2c->SerialReadData4Register; == 0x%08x @ %p\n", i2c->SerialReadData4Register , &(i2c->SerialReadData4Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x2C; */
++ printk( KERN_INFO "\n" ); /* PAD REGISTER PACKING ***/
++ printk( KERN_INFO " i2c->SerialWriteData1Register; == 0x%08x @ %p\n", i2c->SerialWriteData1Register , &(i2c->SerialWriteData1Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x40; */
++ printk( KERN_INFO " i2c->SerialWriteData2Register; == 0x%08x @ %p\n", i2c->SerialWriteData2Register , &(i2c->SerialWriteData2Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x44; */
++ printk( KERN_INFO " i2c->SerialWriteData3Register; == 0x%08x @ %p\n", i2c->SerialWriteData3Register , &(i2c->SerialWriteData3Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x48; */
++ printk( KERN_INFO " i2c->SerialWriteData4Register; == 0x%08x @ %p\n", i2c->SerialWriteData4Register , &(i2c->SerialWriteData4Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x4C; */
++ printk( KERN_INFO "\n" ); /* PAD REGISTER PACKING ***/
++ printk( KERN_INFO " i2c->GenericSerialControlRegister; == 0x%08x @ %p\n", i2c->GenericSerialControlRegister , &(i2c->GenericSerialControlRegister ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x80; */
++ printk( KERN_INFO "\n" ); /* PAD REGISTER PACKING ***/
++ printk( KERN_INFO " i2c->GenericSerialInterruptStatusRegister; == 0x%08x @ %p\n", i2c->GenericSerialInterruptStatusRegister , &(i2c->GenericSerialInterruptStatusRegister ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x90; */
++ printk( KERN_INFO " i2c->GenericSerialInterruptEnableRegister; == 0x%08x @ %p\n", i2c->GenericSerialInterruptEnableRegister , &(i2c->GenericSerialInterruptEnableRegister ) ); /* SERIAL_MASTER_CONTROL_BASE + 0x94; */
++ printk( KERN_INFO "\n" ); /* PAD REGISTER PACKING ***/
++ printk( KERN_INFO " i2c->GenericSerialReadData1Register; == 0x%08x @ %p\n", i2c->GenericSerialReadData1Register , &(i2c->GenericSerialReadData1Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0xA0; */
++ printk( KERN_INFO " i2c->GenericSerialReadData2Register; == 0x%08x @ %p\n", i2c->GenericSerialReadData2Register , &(i2c->GenericSerialReadData2Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0xA4; */
++ printk( KERN_INFO " i2c->GenericSerialReadData3Register; == 0x%08x @ %p\n", i2c->GenericSerialReadData3Register , &(i2c->GenericSerialReadData3Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0xA8; */
++ printk( KERN_INFO " i2c->GenericSerialReadData4Register; == 0x%08x @ %p\n", i2c->GenericSerialReadData4Register , &(i2c->GenericSerialReadData4Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0xAC; */
++ printk( KERN_INFO "\n" ); /* PAD REGISTER PACKING ***/
++ printk( KERN_INFO " i2c->GenericSerialWriteData1Register; == 0x%08x @ %p\n", i2c->GenericSerialWriteData1Register , &(i2c->GenericSerialWriteData1Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0xC0; */
++ printk( KERN_INFO " i2c->GenericSerialWriteData2Register; == 0x%08x @ %p\n", i2c->GenericSerialWriteData2Register , &(i2c->GenericSerialWriteData2Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0xC4; */
++ printk( KERN_INFO " i2c->GenericSerialWriteData3Register; == 0x%08x @ %p\n", i2c->GenericSerialWriteData3Register , &(i2c->GenericSerialWriteData3Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0xC8; */
++ printk( KERN_INFO " i2c->GenericSerialWriteData4Register; == 0x%08x @ %p\n", i2c->GenericSerialWriteData4Register , &(i2c->GenericSerialWriteData4Register ) ); /* SERIAL_MASTER_CONTROL_BASE + 0xCC; */
++ printk( KERN_INFO "\n\n ==================================================================" );
++
++
++}
++
++static inline int oxnas_iic_algo_bus_reset( volatile struct i2c_algo_oxnas_data* oxnas )
++{
++ /* perform a bus reset to clean up */
++
++ unsigned long flags, tmo;
++ volatile i2c_registers_oxnas_t *pI2C = (i2c_registers_oxnas_t *) oxnas;
++
++ local_irq_save(flags);
++ oxnas->iTransferInProgress_ = 1;
++
++ pI2C->SerialControlRegister =
++ (I2C_SCR_RESET << I2C_SCR_TRANSACTION_TYPE_BIT ) |
++ (I2C_SCR_RESET << I2C_SCR_TRANSACTION_PROGRESS_BIT );
++
++ /* Wait for IIC transfer */
++ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
++
++ // Flag that the transfer has finished
++ oxnas->iTransferInProgress_ = 0;
++
++ local_irq_restore(flags);
++
++ return (tmo < 1*HZ);
++}
++
++
++static void
++oxnas_iic_algo_interrupt(void *dev_id, struct pt_regs *regs)
++{
++ volatile i2c_registers_oxnas_t *i2cReg = (i2c_registers_oxnas_t *)dev_id;
++ if (oxnas_debug)
++ printk("oxnas_iic_algo_interrupt(dev_id=%p)\n", dev_id);
++
++ /* Clear interrupt.
++ */
++ i2cReg->SerialInterruptStatusRegister &= ~(1UL << I2C_ISR_INTERRUPT_STATUS_BIT);
++
++ /* Get 'me going again.
++ */
++ wake_up_interruptible(&iic_wait);
++}
++
++static void
++oxnas_iic_algo_init(struct i2c_algo_oxnas_data *oxnas)
++{
++ u32 temp;
++ volatile i2c_registers_oxnas_t* i2c = oxnas->i2c;
++
++ if (oxnas_debug) printk(KERN_INFO "oxnas_iic_algo_init()\n");
++
++ /* Initialize
++ * Set up the IIC parameters
++ */
++ temp = i2c->SerialControlRegister & I2C_SCR_READ_MASK;
++ temp >>= I2C_SCR_AUTO_INCREMENT_BUFFER_SIZE_BIT;
++ temp &= ~(0xffffffff << ( I2C_SCR_AUTO_INCREMENT_BUFFER_SIZE_NUM_BITS ));
++ oxnas->iMaxAutoIncTransfer_ = temp;
++
++ // Initialise the Serial controller(s)
++ {
++ // syslib::Lock lock(mutex);
++
++ // TODO: Ensure the Serial block is properly reset
++ // BlockResetRegister& blockResetRegister = BlockResetRegister::Acquire();
++ // blockResetRegister.ResetSerial();
++ // blockResetRegister.CommitWrites();
++ // blockResetRegister.Release();
++
++ // TODO: Enable the clock to the Serial block
++ // ClockStartRegister& clockStartRegister = ClockStartRegister::Acquire();
++ // clockStartRegister.RefreshReadData();
++ // clockStartRegister.StartSerialClock();
++ // clockStartRegister.CommitWrites();
++ // clockStartRegister.Release();
++
++ // TODO: Set the Serial clock rate
++ // SerialClockSelectRegister& serialClockSelectRegister = SerialClockSelectRegister::GetInstance();
++ // serialClockSelectRegister.SetClockRate(SerialClockSelectRegister::PLL_DIV_32768);
++ // serialClockSelectRegister.CommitWrites();
++
++ // Disable the Serial Interrupt
++ if (oxnas_debug) printk(KERN_INFO " - Disabling pre existing i2c interrupt\n");
++ i2c->SerialInterruptEnableRegister &= ~(1UL << I2C_IER_SERIAL_ENABLE_BIT);
++
++ // Disable the Generic serial Interrupt
++ if (oxnas_debug) printk(KERN_INFO " - Disabling pre existing gen serial interrupt\n");
++ i2c->SerialInterruptEnableRegister &= ~(1UL << I2C_IER_GEN_ENABLE_BIT);
++
++ // Clear any pending Serial interrupts
++ if ( i2c->SerialInterruptStatusRegister | (1UL << I2C_ISR_INTERRUPT_STATUS_BIT) )
++ {
++ // Yes, so clear the interrupt
++ if (oxnas_debug) printk(KERN_INFO " - Clearing pre existing i2c interrupt\n");
++ *( &(i2c->SerialInterruptStatusRegister) ) |= (1UL << I2C_ISR_INTERRUPT_STATUS_BIT);
++ }
++
++ // Clear any pending Generic serial interrupts
++ if ( i2c->SerialInterruptStatusRegister | (1UL << I2C_ISR_GEN_INTERRUPT_STATUS_BIT) )
++ {
++ // Yes, so clear the interrupt
++ if (oxnas_debug) printk(KERN_INFO " - Clearing pre existing generic serial interrupt\n");
++ *( &(i2c->SerialInterruptStatusRegister) ) |= (1UL << I2C_ISR_GEN_INTERRUPT_STATUS_BIT);
++ }
++
++
++ // Initialise the generic serial hardware, which shares reset,
++ // clock and interrupt hardware with the Serial controller(s)
++ // TODO: GenericSerialHelper::Init();
++
++ }
++
++ init_waitqueue_head(&iic_wait);
++
++ /* Install interrupt handler.
++ */
++ if (oxnas_debug) {
++ printk ("%s[%d] Install ISR for IRQ %d\n",
++ __func__,__LINE__, I2C_INTERRUPT );
++ }
++
++ (*oxnas->setisr)( (int) I2C_INTERRUPT, &oxnas_iic_algo_interrupt, (void *)i2c);
++if (oxnas_debug)oxnas_iic_algo_dump_reg();
++}
++
++
++static int
++oxnas_iic_algo_shutdown(struct i2c_algo_oxnas_data *oxnas)
++{
++ volatile i2c_registers_oxnas_t *i2c = oxnas->i2c;
++
++ if (oxnas_debug) printk("oxnas_iic_algo_shutdown()\n");
++
++ /* Shut down IIC.
++ */
++ // TODO: syslib::Lock lock(mutex);
++
++ // TODO: Reset Serial block to ensure there are no actve transfers
++ // BlockResetRegister& blockResetRegister = BlockResetRegister::Acquire();
++ // blockResetRegister.ResetSerial();
++ // blockResetRegister.CommitWrites();
++ // blockResetRegister.Release();
++
++ // Disable the Serial Interrupt
++ if (oxnas_debug) printk(KERN_INFO " - Disabling pre existing i2c interrupt\n");
++ i2c->SerialInterruptEnableRegister &= ~(1UL << I2C_IER_SERIAL_ENABLE_BIT);
++
++ // Disable the Generic serial Interrupt
++ if (oxnas_debug) printk(KERN_INFO " - Disabling pre existing gen serial interrupt\n");
++ i2c->SerialInterruptEnableRegister &= ~(1UL << I2C_IER_GEN_ENABLE_BIT);
++
++
++ // Shutdown the generic serial hardware, which shares reset, clock and
++ // interrupt hardware with the Serial controller(s)
++ // TODO: GenericSerialHelper::Shutdown();
++
++ // TODO: Disable the clock to the Serial block
++ // ClockStopRegister& clockStopRegister = ClockStopRegister::Acquire();
++ // clockStopRegister.RefreshReadData();
++ // clockStopRegister.StopSerialClock();
++ // clockStopRegister.CommitWrites();
++ // clockStopRegister.Release();
++
++ (*oxnas->clearisr)( (int) I2C_INTERRUPT, (void *)i2c);
++if (oxnas_debug)oxnas_iic_algo_dump_reg();
++
++ return(0);
++}
++
++
++#define BD_SC_NAK ((ushort)0x0004) /* NAK - did not respond */
++#define BD_SC_OV ((ushort)0x0002) /* OV - receive overrun */
++#define OXNAS_CR_CLOSE_RXBD ((ushort)0x0007)
++
++static void force_close(struct i2c_algo_oxnas_data *oxnas)
++{
++ volatile i2c_registers_oxnas_t *i2c = oxnas->i2c;
++
++ if (oxnas_debug) printk("force_close()\n");
++
++ *( &(i2c->SerialControlRegister) ) |= (1UL << I2C_SCR_ABORT_BIT);
++
++ /* perform a bus reset to clean up */
++ oxnas_iic_algo_bus_reset(oxnas);
++
++if (oxnas_debug)oxnas_iic_algo_dump_reg();
++}
++
++
++/* Read from IIC...
++ * abyte = address byte, with r/w flag already set
++ */
++static int
++oxnas_iic_algo_read(struct i2c_algo_oxnas_data *oxnas, u_char abyte, char *readBuffer, int readBufferLength)
++{
++ volatile i2c_registers_oxnas_t *i2c = oxnas->i2c;
++ const unsigned char* pData;
++ unsigned long flags, tmo, temp, bytesTransfered;
++
++
++ if (oxnas_debug) printk("oxnas_iic_algo_read(abyte=0x%x)\n", abyte);
++
++ if (readBufferLength >= oxnas->iMaxAutoIncTransfer_ ) {
++ if (oxnas_debug) printk("oxnas_iic_algo_read $RFailed to reaad %d auto. max is %d\n", readBufferLength, oxnas->iMaxAutoIncTransfer_ );
++ return -EINVAL;
++ }
++
++
++ if( 1 /*TODO: Split into multipacks. */ )
++ {
++
++ local_irq_save(flags);
++
++ /* QUESTION: Does this get locked by the parent? it should be!! */
++ oxnas->iTransferInProgress_ = 1;
++ oxnas->iError_ = 0;
++
++ // Set up the 7-bit slave address
++ i2c->SerialAddressRegister = I2C_SAR_WRITE_MASK & ((abyte >> 1) << I2C_SAR_SEVEN_BIT_ADDRESS_BIT);
++
++ // Setup the control register
++ temp = ( I2C_SCR_READ << I2C_SCR_READ_WRITE_BIT ) |
++ ( I2C_SCR_NORMAL << I2C_SCR_TRANSACTION_TYPE_BIT ) |
++ ( I2C_SCR_SEVEN_BIT << I2C_SCR_ADDRESS_MODE_BIT ) |
++ ( 0 << I2C_SCR_SCCB_MODE_ENABLE_BIT ) |
++ ( 1 << I2C_SCR_SCCB_MODE_RESPECT_ACK_BIT ) |
++ ( 1 << I2C_SCR_AUTO_INCREMENT_ENABLE_BIT ) |
++ ( 1 << I2C_SCR_ENABLE_SLAVE_HOLD_OFF_BIT ) |
++ ( 0 << I2C_SCR_HIGH_SPEED_DRIVE_BIT ) |
++ ( readBufferLength << I2C_SCR_BYTES_TO_TRANSFER_BIT );
++
++ temp &= I2C_SCR_WRITE_MASK;
++ i2c->SerialControlRegister = temp;
++
++ /* Enable some interupts */
++ *( &(i2c->SerialInterruptEnableRegister) ) |= (1UL << I2C_IER_SERIAL_ENABLE_BIT);
++
++ /* Begin transmission */
++ *( &(i2c->SerialControlRegister) ) |= (1UL << I2C_SCR_TRANSACTION_PROGRESS_BIT);
++
++ /* Wait for IIC transfer */
++ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
++
++ /* Woken. Copy data out of special registers. */
++
++ temp = i2c->SerialControlRegister;
++
++ // How many bytes were read from the slave?
++ bytesTransfered = (temp >> I2C_SCR_BYTES_TO_TRANSFER_BIT) &
++ ~(0xffffffff << I2C_SCR_BYTES_TO_TRANSFER_NUM_BITS);
++
++ // Did the transfer fail
++ if ( temp | (1UL << I2C_SCR_TRANSACTION_STATUS_BIT) )
++ {
++ // Yes, so remember the error
++ oxnas->iError_ = 1;
++ readBufferLength = 0;
++ }
++ else if (readBuffer)
++ {
++ if (bytesTransfered > readBufferLength)
++ {
++ // More bytes were read than we have buffer space to
++ // store them
++ oxnas->iError_ = 1;
++ }
++ else
++ {
++ // Copy the received data into the buffer that was provided by the
++ // original caller to the Read() or ReadImmediate() method
++ if (bytesTransfered > 0)
++ {
++ int i=0;
++ temp = i2c->SerialReadData1Register;
++ pData = (const unsigned char*) (&temp);
++ readBuffer[i++] = *pData++;
++ if (bytesTransfered > 1)
++ {
++ readBuffer[i++] = *pData++;
++ if (bytesTransfered > 2)
++ {
++ readBuffer[i++] = *pData++;
++ if (bytesTransfered > 3)
++ {
++ readBuffer[i++] = *pData++;
++ }
++ }
++ }
++
++ if (bytesTransfered > 4)
++ {
++ temp = i2c->SerialReadData2Register;
++ pData = (const unsigned char*) (&temp);
++ readBuffer[i++] = *pData++;
++ if (bytesTransfered > 5)
++ {
++ readBuffer[i++] = *pData++;
++ if (bytesTransfered > 6)
++ {
++ readBuffer[i++] = *pData++;
++ if (bytesTransfered > 7)
++ {
++ readBuffer[i++] = *pData++;
++ }
++ }
++ }
++ }
++
++ if (bytesTransfered > 8)
++ {
++ temp = i2c->SerialReadData3Register;
++ pData = (const unsigned char*) (&temp);
++ if (bytesTransfered > 9)
++ {
++ readBuffer[i++] = *pData++;
++ if (bytesTransfered > 10)
++ {
++ readBuffer[i++] = *pData++;
++ if (bytesTransfered > 11)
++ {
++ readBuffer[i++] = *pData++;
++ }
++ }
++ }
++ }
++
++ if (bytesTransfered > 12)
++ {
++ temp = i2c->SerialReadData4Register;
++ pData = (const unsigned char*) (&temp);
++ if (bytesTransfered > 13)
++ {
++ readBuffer[i++] = *pData++;
++ if (bytesTransfered > 14)
++ {
++ readBuffer[i++] = *pData++;
++ if (bytesTransfered > 15)
++ {
++ readBuffer[i++] = *pData++;
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++
++
++ // Flag that the transfer has finished
++ oxnas->iTransferInProgress_ = 0;
++
++ local_irq_restore(flags);
++ }
++
++ /* IDEA: busy wait for small transfers, its faster time_after(jiffies, tmo) */
++
++ if (signal_pending(current) || !tmo){
++ force_close(oxnas);
++ if(oxnas_debug)
++ printk("IIC read: timeout!\n");
++ return -EIO;
++ }
++
++ if ( i2c->SerialControlRegister | (1UL << I2C_SCR_TRANSACTION_STATUS_BIT) ) {
++ if (oxnas_debug)
++ printk("IIC read; no ack\n");
++ return -EREMOTEIO;
++ }
++
++ if (bytesTransfered > readBufferLength) {
++ if (oxnas_debug)
++ printk("IIC read; Overrun\n");
++ return -EREMOTEIO;;
++ }
++
++ if (oxnas_debug) printk("read %u bytes\n", readBufferLength);
++
++ if (bytesTransfered < readBufferLength) {
++ if (oxnas_debug)
++ printk("IIC read; short, wanted %lu got %ld\n",
++ bytesTransfered, readBufferLength);
++ return 0;
++ }
++
++ return bytesTransfered;
++}
++
++
++static void LoadWriteRegisters(
++ volatile i2c_registers_oxnas_t *i2c,
++ char *data,
++ int length )
++{
++ // Copy the data to be transmited into the write registers
++ u32 temp;
++ if (length > 0)
++ {
++ int i=0;
++ unsigned char* pData = (unsigned char*) &temp;
++ *pData++ = (data[i++]);
++ if (length > 1)
++ {
++ *pData++ = (data[i++]);
++ if (length > 2)
++ {
++ *pData++ = (data[i++]);
++ if (length > 3)
++ {
++ *pData++ = (data[i++]);
++ }
++ }
++ }
++ i2c->SerialWriteData1Register = temp;
++
++ if (length > 4)
++ {
++ pData = (unsigned char*) (&temp);
++ *pData++ = (data[i++]);
++ if (length > 5)
++ {
++ *pData++ = (data[i++]);
++ if (length > 6)
++ {
++ *pData++ = (data[i++]);
++ if (length > 7)
++ {
++ *pData++ = (data[i++]);
++ }
++ }
++ }
++ i2c->SerialWriteData2Register = temp;
++ }
++
++ if (length > 8)
++ {
++ pData = (unsigned char*) (&temp);
++ *pData++ = (data[i++]);
++ if (length > 9)
++ {
++ *pData++ = (data[i++]);
++ if (length > 10)
++ {
++ *pData++ = (data[i++]);
++ if (length > 11)
++ {
++ *pData++ = (data[i++]);
++ }
++ }
++ }
++ i2c->SerialWriteData3Register = temp;
++ }
++
++ if (length > 12)
++ {
++ pData = (unsigned char*) (&temp);
++ *pData++ = (data[i++]);
++ if (length > 13)
++ {
++ *pData++ = (data[i++]);
++ if (length > 14)
++ {
++ *pData++ = (data[i++]);
++ if (length > 15)
++ {
++ *pData++ = (data[i++]);
++ }
++ }
++ }
++ i2c->SerialWriteData4Register = temp;
++ }
++ }
++}
++
++
++/* Write to IIC...
++ * addr = address byte, with r/w flag already set
++ */
++static int
++oxnas_iic_algo_write(struct i2c_algo_oxnas_data *oxnas, u_char abyte, char *buf,int count)
++{
++ volatile i2c_registers_oxnas_t *i2c = oxnas->i2c;
++ unsigned long flags, tmo, bytesTransfered, temp;
++
++ if (oxnas_debug) printk("oxnas_iic_algo_write(abyte=0x%x)\n", abyte);
++
++ if (count >= oxnas->iMaxAutoIncTransfer_ ) {
++ if (oxnas_debug) printk("oxnas_iic_algo_read $RFailed to reaad %d auto. max is %d\n", count, oxnas->iMaxAutoIncTransfer_ );
++ return -EINVAL;
++ }
++
++ if( 1 /* TODO: Split longer messages */ )
++ {
++ LoadWriteRegisters( i2c, buf, count );
++
++ local_irq_save(flags);
++
++ /* QUESTION: Does this get locked by the parent? it should be!! */
++ oxnas->iTransferInProgress_ = 1;
++ oxnas->iError_ = 0;
++
++ // Set up the 7-bit slave address
++ i2c->SerialAddressRegister = I2C_SAR_WRITE_MASK & ((abyte >> 1) << I2C_SAR_SEVEN_BIT_ADDRESS_BIT);
++
++ // Setup the control register
++ temp = ( I2C_SCR_WRITE << I2C_SCR_READ_WRITE_BIT ) |
++ ( I2C_SCR_NORMAL << I2C_SCR_TRANSACTION_TYPE_BIT ) |
++ ( I2C_SCR_SEVEN_BIT << I2C_SCR_ADDRESS_MODE_BIT ) |
++ ( 0 << I2C_SCR_SCCB_MODE_ENABLE_BIT ) |
++ ( 1 << I2C_SCR_SCCB_MODE_RESPECT_ACK_BIT ) |
++ ( 1 << I2C_SCR_AUTO_INCREMENT_ENABLE_BIT ) |
++ ( 1 << I2C_SCR_ENABLE_SLAVE_HOLD_OFF_BIT ) |
++ ( 0 << I2C_SCR_HIGH_SPEED_DRIVE_BIT ) |
++ ( count << I2C_SCR_BYTES_TO_TRANSFER_BIT );
++
++ temp &= I2C_SCR_WRITE_MASK;
++ i2c->SerialControlRegister = temp;
++
++ /* Enable some interupts */
++ *( &(i2c->SerialInterruptEnableRegister) ) |= (1UL << I2C_IER_SERIAL_ENABLE_BIT);
++
++ /* Begin transmission */
++ *( &i2c->SerialControlRegister ) |= (1UL << I2C_SCR_TRANSACTION_PROGRESS_BIT);
++
++ /* Begin transmission */
++
++ /* Wait for IIC transfer */
++ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
++ local_irq_restore(flags);
++ }
++
++ /* IDEA: busy wait for small transfers, its faster time_after(jiffies, tmo) */
++
++
++ if (signal_pending(current) || !tmo){
++ force_close(oxnas);
++ if(oxnas_debug)
++ printk("IIC read: timeout!\n");
++ return -EIO;
++ }
++
++ if ( i2c->SerialControlRegister | (1UL << I2C_SCR_TRANSACTION_STATUS_BIT)) {
++ if (oxnas_debug)
++ printk("IIC read; no ack\n");
++ return -EREMOTEIO;
++ }
++
++ // How many bytes were read from the slave?
++ bytesTransfered = (temp >> I2C_SCR_BYTES_TO_TRANSFER_BIT) &
++ ~(0xffffffff << I2C_SCR_BYTES_TO_TRANSFER_NUM_BITS);
++
++ if (bytesTransfered > count) {
++ if (oxnas_debug)
++ printk("IIC read; Overrun\n");
++ return -EREMOTEIO;;
++ }
++
++ if (oxnas_debug) printk("read %lu bytes\n", bytesTransfered);
++
++ if (bytesTransfered < count) {
++ if (oxnas_debug)
++ printk("IIC read; short, wanted %u got %lu\n",
++ count, bytesTransfered);
++ return 0;
++ }
++
++ return bytesTransfered;
++}
++
++/* See if an IIC address exists..
++ * addr = 7 bit address, unshifted
++ */
++static int
++oxnas_iic_algo_tryaddress(struct i2c_algo_oxnas_data *oxnas, int addr)
++{
++ volatile i2c_registers_oxnas_t *i2c = oxnas->i2c;
++ unsigned long flags, length, tmo, temp, bytesTransfered;
++
++ if (oxnas_debug) printk("oxnas_iic_algo_tryaddress(oxnas=%p/%p,addr=%d)\n", oxnas, i2c, addr);
++
++ /* do a simple read */
++ length = 2;
++
++ {
++ local_irq_save(flags);
++
++ /* QUESTION: Does this get locked by the parent? it should be!! */
++ oxnas->iTransferInProgress_ = 1;
++ oxnas->iError_ = 0;
++
++ // Set up the 7-bit slave address
++ i2c->SerialAddressRegister = I2C_SAR_WRITE_MASK & ((addr) << I2C_SAR_SEVEN_BIT_ADDRESS_BIT);
++
++ // Setup the control register
++ temp = ( I2C_SCR_WRITE << I2C_SCR_READ_WRITE_BIT ) |
++ ( I2C_SCR_NORMAL << I2C_SCR_TRANSACTION_TYPE_BIT ) |
++ ( I2C_SCR_SEVEN_BIT << I2C_SCR_ADDRESS_MODE_BIT ) |
++ ( 0 << I2C_SCR_SCCB_MODE_ENABLE_BIT ) |
++ ( 1 << I2C_SCR_SCCB_MODE_RESPECT_ACK_BIT ) |
++ ( 1 << I2C_SCR_AUTO_INCREMENT_ENABLE_BIT ) |
++ ( 1 << I2C_SCR_ENABLE_SLAVE_HOLD_OFF_BIT ) |
++ ( 0 << I2C_SCR_HIGH_SPEED_DRIVE_BIT ) |
++ ( length << I2C_SCR_BYTES_TO_TRANSFER_BIT );
++
++ temp &= I2C_SCR_WRITE_MASK;
++ i2c->SerialControlRegister = temp;
++
++ /* Enable some interupts */
++ *( &(i2c->SerialInterruptEnableRegister) ) |= (1UL << I2C_IER_SERIAL_ENABLE_BIT);
++
++ /* Begin transmission */
++ *( &i2c->SerialControlRegister ) |= (1UL << I2C_SCR_TRANSACTION_PROGRESS_BIT);
++
++ /* Begin transmission */
++
++ /* Wait for IIC transfer */
++ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
++ local_irq_restore(flags);
++ }
++
++ /* IDEA: busy wait for small transfers, its faster time_after(jiffies, tmo) */
++
++
++ if (signal_pending(current) || !tmo){
++ force_close(oxnas);
++ if(oxnas_debug)
++ printk("$rIIC test_addr: timeout!\n");
++ return -EIO;
++ }
++
++ if ( i2c->SerialControlRegister | (1UL << I2C_SCR_TRANSACTION_STATUS_BIT)) {
++ if (oxnas_debug)
++ printk("$rIIC test_addr; no ack\n");
++ return -EREMOTEIO;
++ }
++
++ // How many bytes were read from the slave?
++ bytesTransfered = (temp >> I2C_SCR_BYTES_TO_TRANSFER_BIT) &
++ ~(0xffffffff << I2C_SCR_BYTES_TO_TRANSFER_NUM_BITS);
++
++ if (bytesTransfered > 2) {
++ if (oxnas_debug)
++ printk("$rIIC test_addr; Overrun\n");
++ return -EREMOTEIO;;
++ }
++
++ if (oxnas_debug) printk("$rtest_addr %lu bytes\n", bytesTransfered);
++
++ if (bytesTransfered < 2) {
++ if (oxnas_debug)
++ printk("$rIIC test_addr; short, wanted %d got %lu\n",
++ 2, bytesTransfered);
++ return 0;
++ }
++ printk("$GIIC found @ test_addr (oxnas=%p,addr=%d)\n", oxnas, addr);
++ return 1;
++}
++
++static int oxnas_xfer(
++ struct i2c_adapter *adap,
++ struct i2c_msg msgs[],
++ int num)
++{
++ struct i2c_algo_oxnas_data *oxnas = adap->algo_data;
++ struct i2c_msg *pmsg;
++ int i, ret;
++ u_char addr;
++
++ if (oxnas_debug > 1) printk("oxnas_xfer()\n");
++ for (i = 0; i < num; i++) {
++ pmsg = &msgs[i];
++
++ if (oxnas_debug)
++ printk("i2c-algo-oxnas.o: "
++ "#%d addr=0x%x flags=0x%x len=%d\n buf=%lx\n",
++ i, pmsg->addr, pmsg->flags, pmsg->len, (unsigned long)pmsg->buf);
++
++ addr = pmsg->addr << 1;
++ if (pmsg->flags & I2C_M_RD )
++ addr |= 1;
++ if (pmsg->flags & I2C_M_REV_DIR_ADDR )
++ addr ^= 1;
++
++ if (!(pmsg->flags & I2C_M_NOSTART)) {
++ }
++ if (pmsg->flags & I2C_M_RD ) {
++ /* read bytes into buffer*/
++ ret = oxnas_iic_algo_read(oxnas, addr, pmsg->buf, pmsg->len);
++ if (oxnas_debug)
++ printk("i2c-algo-oxnas.o: read %d bytes\n", ret);
++ if (ret < pmsg->len ) {
++ return (ret<0)? ret : -EREMOTEIO;
++ }
++ } else {
++ /* write bytes from buffer */
++ ret = oxnas_iic_algo_write(oxnas, addr, pmsg->buf, pmsg->len);
++ if (oxnas_debug)
++ printk("i2c-algo-oxnas.o: wrote %d\n", ret);
++ if (ret < pmsg->len ) {
++ return (ret<0) ? ret : -EREMOTEIO;
++ }
++ }
++ }
++ return (num);
++}
++
++static u32 oxnas_func(struct i2c_adapter *adap)
++{
++ if (oxnas_debug > 1) printk("oxnas_func(I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING)\n");
++
++ return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
++ I2C_FUNC_PROTOCOL_MANGLING;
++}
++
++/* -----exported algorithm data: ------------------------------------- */
++
++static struct i2c_algorithm oxnas_algo = {
++ .name = "Oxnas algorithm",
++ .id = I2C_ALGO_OCP,
++ .master_xfer = oxnas_xfer,
++ .functionality = oxnas_func,
++};
++
++/*
++ * registering functions to load algorithms at runtime
++ */
++int i2c_oxnas_algo_add_bus(struct i2c_adapter *adap)
++{
++ int i;
++ struct i2c_algo_oxnas_data *oxnas = adap->algo_data;
++
++ if (oxnas_debug) printk("i2c_oxnas_algo_add_bus: hw routines for %s registered.\n", adap->name);
++
++ /* register new adapter to i2c module... */
++
++ adap->id |= oxnas_algo.id;
++ adap->algo = &oxnas_algo;
++
++ oxnas_iic_algo_init(oxnas);
++ i2c_add_adapter(adap);
++
++ /* scan bus */
++ if ( oxnas_scan ) {
++ if (oxnas_debug) printk(KERN_INFO " i2c_oxnas_algo_add_bus: scanning bus %s...\n", adap->name);
++ for (i = 0; i < 128; i++) {
++ if (oxnas_debug) printk(KERN_INFO " scanning addr %d...\n", i);
++ if (oxnas_iic_algo_tryaddress(oxnas, i)) {
++ printk("(%02x)",i<<1);
++ }
++ }
++ printk("\n");
++ }
++
++ return 0;
++}
++
++
++int i2c_oxnas_algo_del_bus(struct i2c_adapter *adap)
++{
++ struct i2c_algo_oxnas_data *oxnas = adap->algo_data;
++
++ oxnas_iic_algo_shutdown(oxnas);
++
++ return i2c_del_adapter(adap);
++}
++
++EXPORT_SYMBOL(i2c_oxnas_algo_add_bus);
++EXPORT_SYMBOL(i2c_oxnas_algo_del_bus);
++
++MODULE_AUTHOR("Chris FOrd <....>");
++MODULE_DESCRIPTION("I2C-Bus oxnas algorithm");
++MODULE_LICENSE("GPL");
++
+diff -Nurd linux-2.6.24/drivers/i2c/busses/Kconfig linux-2.6.24-oxe810/drivers/i2c/busses/Kconfig
+--- linux-2.6.24/drivers/i2c/busses/Kconfig 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/i2c/busses/Kconfig 2008-06-11 17:50:33.000000000 +0200
+@@ -321,6 +321,15 @@
+ This driver can also be built as a module. If so, the module
+ will be called i2c-nforce2.
+
++config I2C_OXNAS_BITBASH
++ tristate "OXNAS bitbashed I2C interface"
++ depends on I2C_ALGOBIT
++ help
++ Say Y here if you want to use I2C GPIO bit-bash interface
++
++ This driver can also be built as a module. If so, the module
++ will be called i2c-oxnas-bitbash.
++
+ config I2C_OCORES
+ tristate "OpenCores I2C Controller"
+ depends on EXPERIMENTAL
+diff -Nurd linux-2.6.24/drivers/i2c/busses/Makefile linux-2.6.24-oxe810/drivers/i2c/busses/Makefile
+--- linux-2.6.24/drivers/i2c/busses/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/i2c/busses/Makefile 2008-06-11 17:50:33.000000000 +0200
+@@ -28,6 +28,7 @@
+ obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o
+ obj-$(CONFIG_I2C_OMAP) += i2c-omap.o
+ obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o
++obj-$(CONFIG_I2C_OXNAS_BITBASH) += i2c-oxnas-bitbash.o
+ obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o
+ obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o
+ obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o
+diff -Nurd linux-2.6.24/drivers/i2c/busses/i2c-oxnas-bitbash.c linux-2.6.24-oxe810/drivers/i2c/busses/i2c-oxnas-bitbash.c
+--- linux-2.6.24/drivers/i2c/busses/i2c-oxnas-bitbash.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/i2c/busses/i2c-oxnas-bitbash.c 2008-06-11 17:50:33.000000000 +0200
+@@ -0,0 +1,158 @@
++/*
++ * drivers/i2c/busses/i2c_oxnas_bitbash.c
++ *
++ * Copyright (C) 2006-2008 Oxford Semiconductor Ltd
++ *
++ * 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 <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/i2c.h>
++#include <linux/i2c-algo-bit.h>
++#include <asm/hardware.h>
++#include <asm/io.h>
++
++#define I2C_OXNAS_BITBASH_I2C_SDA_OUT (1UL << (CONFIG_OXNAS_I2C_SDA))
++#define I2C_OXNAS_BITBASH_I2C_SCL_OUT (1UL << (CONFIG_OXNAS_I2C_SCL))
++#define I2C_OXNAS_BB_PULSEWIDTH (40)
++#define OPEN_COLLECTOR_CLOCK 1
++
++extern spinlock_t oxnas_gpio_spinlock;
++
++static void i2c_oxnas_bitbash_setsda(void *data,int state)
++{
++ if (state) {
++ // tristae as input to set line on bus
++ writel(I2C_OXNAS_BITBASH_I2C_SDA_OUT, GPIO_A_OUTPUT_ENABLE_CLEAR);
++ } else {
++ // tristate as output (with latch to zero) to assert zero on the bus
++ writel(I2C_OXNAS_BITBASH_I2C_SDA_OUT, GPIO_A_OUTPUT_CLEAR);
++ writel(I2C_OXNAS_BITBASH_I2C_SDA_OUT, GPIO_A_OUTPUT_ENABLE_SET);
++ }
++}
++
++static void i2c_oxnas_bitbash_setscl(void *data,int state)
++{
++#if OPEN_COLLECTOR_CLOCK
++ if (state) {
++ // tristae as input to set line on bus
++ writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_ENABLE_CLEAR);
++ } else {
++ // tristate as output (with latch to zero) to assert zero on the bus
++ writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_CLEAR);
++ writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_ENABLE_SET);
++ }
++#else // driven clock
++ if (state) {
++ // tristae as input to set line on bus
++ writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_SET);
++ writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_ENABLE_CLEAR);
++ } else {
++ // tristate as output (with latch to zero) to assert zero on the bus
++ writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_CLEAR);
++ writel(I2C_OXNAS_BITBASH_I2C_SCL_OUT, GPIO_A_OUTPUT_ENABLE_SET);
++ }
++
++#endif
++}
++
++static int i2c_oxnas_bitbash_getsda(void *data)
++{
++ return ((readl(GPIO_A_DATA ) & I2C_OXNAS_BITBASH_I2C_SDA_OUT) != 0);
++}
++
++static int i2c_oxnas_bitbash_getscl(void *data)
++{
++ return ((readl(GPIO_A_DATA ) & I2C_OXNAS_BITBASH_I2C_SCL_OUT) != 0);
++}
++
++static struct i2c_algo_bit_data bit_i2c_oxnas_bitbash_data = {
++ .setsda = i2c_oxnas_bitbash_setsda,
++ .setscl = i2c_oxnas_bitbash_setscl,
++ .getsda = i2c_oxnas_bitbash_getsda,
++ .getscl = i2c_oxnas_bitbash_getscl,
++ .udelay = I2C_OXNAS_BB_PULSEWIDTH,
++ .timeout = HZ
++};
++
++static struct i2c_adapter oxnas_i2c_bitbash_adapter = {
++ .owner = THIS_MODULE,
++ .name = "i2c_oxnas_bitbash adapter driver",
++ .id = I2C_HW_B_OXNAS,
++ .algo_data = &bit_i2c_oxnas_bitbash_data,
++};
++
++static int __init i2c_oxnas_bitbash_init(void)
++{
++ unsigned long flags;
++ unsigned long mask = I2C_OXNAS_BITBASH_I2C_SDA_OUT | I2C_OXNAS_BITBASH_I2C_SCL_OUT;
++ int ret = 0;
++
++ /* Dedicate the GPIO over to i2c.
++ * NOTE: This may be confusing, but we are not using the i2c core here we
++ * are using bit-bashed GPIO, so we must disable the primary, secondary and
++ * tertiary functions of the relevant GPIO pins
++ */
++ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
++ writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) & ~mask, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
++ writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0) & ~mask, SYS_CTRL_GPIO_SECSEL_CTRL_0);
++ writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0) & ~mask, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
++ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
++
++ i2c_oxnas_bitbash_setsda(NULL, 1);
++ i2c_oxnas_bitbash_setscl(NULL, 1);
++ ret = i2c_bit_add_bus(&oxnas_i2c_bitbash_adapter);
++ if (!ret) {
++#if defined(CONFIG_OXNAS_RTC) || defined(CONFIG_OXNAS_RTC_MODULE)
++ /* Register the ST MT4100 RTC */
++ struct i2c_board_info rtc_info = {
++ .driver_name = "rtc-ds1307",
++ .type = "m41t00",
++ .flags = 0,
++ .addr = 0x68,
++ .platform_data = NULL,
++ .irq = 0
++ };
++
++ struct i2c_client *client = i2c_new_device(&oxnas_i2c_bitbash_adapter, &rtc_info);
++ if (!client) {
++ printk(KERN_WARNING "OXNAS bit-bash I2C driver failed to register RTC device\n");
++ ret = -EIO;
++ }
++#endif // CONFIG_OXNAS_RTC || CONFIG_OXNAS_RTC_MODULE
++ }
++
++ printk(KERN_INFO "OXNAS bit-bash I2C driver initialisation %s\n", ret ? "failed": "OK");
++ return ret;
++}
++
++static void __exit i2c_oxnas_bitbash_exit(void)
++{
++ i2c_oxnas_bitbash_setsda(NULL, 1);
++ i2c_oxnas_bitbash_setscl(NULL, 1);
++ i2c_del_adapter(&oxnas_i2c_bitbash_adapter);
++}
++
++MODULE_AUTHOR("Brian Clarke");
++MODULE_DESCRIPTION("OXNAS bit-bash I2C bus driver");
++MODULE_LICENSE("GPL");
++MODULE_VERSION("v2.0");
++
++module_init (i2c_oxnas_bitbash_init);
++module_exit (i2c_oxnas_bitbash_exit);
++
+diff -Nurd linux-2.6.24/drivers/leds/Kconfig linux-2.6.24-oxe810/drivers/leds/Kconfig
+--- linux-2.6.24/drivers/leds/Kconfig 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/leds/Kconfig 2008-06-11 17:50:12.000000000 +0200
+@@ -62,6 +62,20 @@
+ This option enables support for LEDs connected to GPIO lines
+ on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440.
+
++config WDC_LEDS_OXNAS800
++ tristate "LED Support for WDC OXNAS800 GPIO LEDs"
++ depends on LEDS_CLASS && ARCH_OXNAS
++ help
++ This option enables support for LEDs connected to GPIO lines on
++ Oxford Semiconductor NAS800 in the Western Digital My Book NAS.
++
++config OXNAS_WD810_LEDS
++ tristate "LED Support for 810 based WD NAS"
++ depends on LEDS_CLASS && ARCH_OXNAS
++ help
++ This option enables support for LEDs connected to GPIO lines on the
++ Oxford Semiconductor OX810 in the Western Digital NAS
++
+ config LEDS_AMS_DELTA
+ tristate "LED Support for the Amstrad Delta (E3)"
+ depends on LEDS_CLASS && MACH_AMS_DELTA
+@@ -137,6 +151,13 @@
+ This allows LEDs to be controlled by IDE disk activity.
+ If unsure, say Y.
+
++config WDC_LEDS_TRIGGER_SATA_DISK
++ bool "WDC LED SATA Disk Trigger"
++ depends on LEDS_TRIGGERS
++ help
++ This allows WDC LEDs to be controlled by SATA disk activity.
++ If unsure, say Y.
++
+ config LEDS_TRIGGER_HEARTBEAT
+ tristate "LED Heartbeat Trigger"
+ depends on LEDS_TRIGGERS
+diff -Nurd linux-2.6.24/drivers/macintosh/smu.c linux-2.6.24-oxe810/drivers/macintosh/smu.c
+--- linux-2.6.24/drivers/macintosh/smu.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/macintosh/smu.c 2008-06-11 17:49:30.000000000 +0200
+@@ -85,6 +85,7 @@
+ u32 cmd_buf_abs; /* command buffer absolute */
+ struct list_head cmd_list;
+ struct smu_cmd *cmd_cur; /* pending command */
++ int broken_nap;
+ struct list_head cmd_i2c_list;
+ struct smu_i2c_cmd *cmd_i2c_cur; /* pending i2c command */
+ struct timer_list i2c_timer;
+@@ -135,6 +136,19 @@
+ fend = faddr + smu->cmd_buf->length + 2;
+ flush_inval_dcache_range(faddr, fend);
+
++
++ /* We also disable NAP mode for the duration of the command
++ * on U3 based machines.
++ * This is slightly racy as it can be written back to 1 by a sysctl
++ * but that never happens in practice. There seem to be an issue with
++ * U3 based machines such as the iMac G5 where napping for the
++ * whole duration of the command prevents the SMU from fetching it
++ * from memory. This might be related to the strange i2c based
++ * mechanism the SMU uses to access memory.
++ */
++ if (smu->broken_nap)
++ powersave_nap = 0;
++
+ /* This isn't exactly a DMA mapping here, I suspect
+ * the SMU is actually communicating with us via i2c to the
+ * northbridge or the CPU to access RAM.
+@@ -211,6 +225,10 @@
+ misc = cmd->misc;
+ mb();
+ cmd->status = rc;
++
++ /* Re-enable NAP mode */
++ if (smu->broken_nap)
++ powersave_nap = 1;
+ bail:
+ /* Start next command if any */
+ smu_start_cmd();
+@@ -461,7 +479,7 @@
+ if (np == NULL)
+ return -ENODEV;
+
+- printk(KERN_INFO "SMU driver %s %s\n", VERSION, AUTHOR);
++ printk(KERN_INFO "SMU: Driver %s %s\n", VERSION, AUTHOR);
+
+ if (smu_cmdbuf_abs == 0) {
+ printk(KERN_ERR "SMU: Command buffer not allocated !\n");
+@@ -533,6 +551,11 @@
+ goto fail;
+ }
+
++ /* U3 has an issue with NAP mode when issuing SMU commands */
++ smu->broken_nap = pmac_get_uninorth_variant() < 4;
++ if (smu->broken_nap)
++ printk(KERN_INFO "SMU: using NAP mode workaround\n");
++
+ sys_ctrler = SYS_CTRLER_SMU;
+ return 0;
+
+diff -Nurd linux-2.6.24/drivers/md/Kconfig linux-2.6.24-oxe810/drivers/md/Kconfig
+--- linux-2.6.24/drivers/md/Kconfig 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/md/Kconfig 2008-06-11 17:50:20.000000000 +0200
+@@ -229,6 +229,22 @@
+
+ If unsure, say N.
+
++config DM_OX_CRYPT
++ tristate "OX800 Hardware Cryptograpy target support"
++ depends on BLK_DEV_DM && EXPERIMENTAL && CRYPTO_OXAESLRW
++ ---help---
++ Based on dm-crypt by Fruhwirth & Saout it has been modified
++ to work with the LRW-AES core in the OX800 NAS chip from
++ Oxford Semiconductor Ltd.
++
++ This device-mapper target allows you to create a device that
++ transparently encrypts the data on it.
++
++ To compile this code as a module, choose M here: the module will
++ be called dm-ox-crypt.
++
++ If unsure, say N.
++
+ config DM_SNAPSHOT
+ tristate "Snapshot target (EXPERIMENTAL)"
+ depends on BLK_DEV_DM && EXPERIMENTAL
+diff -Nurd linux-2.6.24/drivers/md/Makefile linux-2.6.24-oxe810/drivers/md/Makefile
+--- linux-2.6.24/drivers/md/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/md/Makefile 2008-06-11 17:50:20.000000000 +0200
+@@ -33,6 +33,7 @@
+ obj-$(CONFIG_BLK_DEV_MD) += md-mod.o
+ obj-$(CONFIG_BLK_DEV_DM) += dm-mod.o
+ obj-$(CONFIG_DM_CRYPT) += dm-crypt.o
++obj-$(CONFIG_DM_OX_CRYPT) += dm-ox-crypt.o
+ obj-$(CONFIG_DM_DELAY) += dm-delay.o
+ obj-$(CONFIG_DM_MULTIPATH) += dm-multipath.o dm-round-robin.o
+ obj-$(CONFIG_DM_MULTIPATH_EMC) += dm-emc.o
+diff -Nurd linux-2.6.24/drivers/md/dm-ox-crypt.c linux-2.6.24-oxe810/drivers/md/dm-ox-crypt.c
+--- linux-2.6.24/drivers/md/dm-ox-crypt.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/md/dm-ox-crypt.c 2008-06-11 17:50:20.000000000 +0200
+@@ -0,0 +1,791 @@
++/* linux/drivers/md/dm-ox-crypt.c
++ *
++ * OX800 DPE core compatable device encryption
++ */
++
++/*
++ * Copyright (C) 2003 Christophe Saout <christophe@saout.de>
++ * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
++ *
++ * This file is released under the GPL.
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/bio.h>
++#include <linux/blkdev.h>
++#include <linux/mempool.h>
++#include <linux/slab.h>
++#include <linux/crypto.h>
++#include <linux/workqueue.h>
++#include <asm/atomic.h>
++#include <asm/scatterlist.h>
++#include <asm/page.h>
++#include <asm/arch/cipher.h>
++
++#include "dm.h"
++
++#define DM_MSG_PREFIX "ox-crypt: "
++
++/*
++ * per bio private data
++ */
++struct oxcrypt_io {
++ struct dm_target *target;
++ struct bio *bio;
++ struct bio *first_clone;
++ struct work_struct work;
++ atomic_t pending;
++ int error;
++};
++
++/*
++ * context holding the current state of a multi-part conversion
++ */
++struct convert_context {
++ struct bio *bio_in;
++ struct bio *bio_out;
++ unsigned int offset_in;
++ unsigned int offset_out;
++ unsigned int idx_in;
++ unsigned int idx_out;
++ sector_t sector;
++ int write;
++};
++
++struct oxcrypt_config;
++
++struct oxcrypt_iv_operations {
++ int (*ctr)(struct oxcrypt_config *cc, struct dm_target *ti,
++ const char *opts);
++ void (*dtr)(struct oxcrypt_config *cc);
++ const char *(*status)(struct oxcrypt_config *cc);
++ int (*generator)(struct oxcrypt_config *cc, u8 *iv, sector_t sector);
++};
++
++/*
++ * Crypt: maps a linear range of a block device
++ * and encrypts / decrypts at the same time.
++ */
++
++struct oxcrypt_config {
++ struct dm_dev *dev;
++ sector_t start;
++
++ /*
++ * pool for per bio private data and
++ * for encryption buffer pages
++ */
++ mempool_t *io_pool;
++ mempool_t *page_pool;
++
++ /*
++ * crypto related data
++ */
++ struct oxcrypt_iv_operations *iv_gen_ops;
++ void *iv_gen_private;
++ sector_t iv_offset;
++ unsigned int iv_size;
++
++ struct crypto_tfm *tfm;
++ u8 key[OX800DPE_KEYSIZE]; /* size of key is fixed by hardware */
++ u8 iv_key[OX800DPE_KEYSIZE];
++};
++
++#define MIN_IOS 256
++#define MIN_POOL_PAGES 32
++#define MIN_BIO_PAGES 8
++
++static struct kmem_cache *_oxcrypt_io_pool;
++
++/*
++ * Mempool alloc and free functions for the page
++ */
++static void *mempool_alloc_page(gfp_t gfp_mask, void *data)
++{
++ return alloc_page(gfp_mask);
++}
++
++static void mempool_free_page(void *page, void *data)
++{
++ __free_page(page);
++}
++
++
++/*
++ * Different IV generation algorithms:
++ *
++ * oxsemi:
++ * Uses the 32 sector number and a reproducable hash of target device
++ * properties to generate bits 35-32
++ *
++ */
++
++static int oxcrypt_iv_oxsemi_gen(struct oxcrypt_config *cc, u8 *iv, sector_t sector)
++{
++ *((u32* )iv) = cpu_to_le32(sector & 0xffffffff);
++ *( ((u32* )iv) + 1) = 0; /** @todo bits 35 - 32 */
++
++ return 0;
++}
++
++static struct oxcrypt_iv_operations oxcrypt_iv_oxsemi_ops = {
++ .generator = oxcrypt_iv_oxsemi_gen
++};
++
++
++/*static inline*/ int
++oxcrypt_convert_scatterlist(struct oxcrypt_config *cc, struct scatterlist *out,
++ struct scatterlist *in, unsigned int length,
++ int write, sector_t sector)
++{
++ u8 iv[OX800DPE_KEYSIZE];
++ int r = 0;
++
++ if (cc->iv_gen_ops) { /* probably no need to check this */
++ u8* pri = cc->key;
++ u8* twe = cc->iv_key;
++
++ r = cc->iv_gen_ops->generator(cc, iv, sector);
++ if (r < 0)
++ return r;
++
++ if (write)
++ r = ox800_aeslrw_encrypt(in, out, 1, iv, pri, twe);
++ else
++ r = ox800_aeslrw_decrypt(in, out, 1, iv, pri, twe);
++ } else {
++ BUG();
++ }
++
++ //printk("back\n");
++ if (r < 0) {
++ printk(KERN_ERR"oxcrypt_convert_scatterlist: core driver returned error %d\n",r);
++ }
++
++ return r;
++}
++
++static void
++oxcrypt_convert_init(struct oxcrypt_config *cc, struct convert_context *ctx,
++ struct bio *bio_out, struct bio *bio_in,
++ sector_t sector, int write)
++{
++ ctx->bio_in = bio_in;
++ ctx->bio_out = bio_out;
++ ctx->offset_in = 0;
++ ctx->offset_out = 0;
++ ctx->idx_in = bio_in ? bio_in->bi_idx : 0;
++ ctx->idx_out = bio_out ? bio_out->bi_idx : 0;
++ ctx->sector = sector + cc->iv_offset;
++ ctx->write = write;
++}
++
++/**
++ * Encrypt / decrypt data from one bio to another one (can be the same one)
++ *
++ * @todo This only goes atr one sector at a time, could it be made to this in
++ * a scatter gather list of multiple sectors?
++ */
++static int oxcrypt_convert(struct oxcrypt_config *cc,
++ struct convert_context *ctx)
++{
++ int r = 0;
++ struct bio_vec *bv_in ;
++ struct bio_vec *bv_out ;
++ struct scatterlist sg_in;
++ struct scatterlist sg_out;
++
++ //printk("oxcrypt_convert config %p context %p \n", cc, ctx);
++
++ while(ctx->idx_in < ctx->bio_in->bi_vcnt &&
++ ctx->idx_out < ctx->bio_out->bi_vcnt) {
++
++ bv_in = bio_iovec_idx(ctx->bio_in, ctx->idx_in);
++ bv_out = bio_iovec_idx(ctx->bio_out, ctx->idx_out);
++
++ sg_in.page = bv_in->bv_page;
++ sg_in.offset = bv_in->bv_offset + ctx->offset_in;
++ sg_in.length = 1 << SECTOR_SHIFT;
++
++ sg_out.page = bv_out->bv_page;
++ sg_out.offset = bv_out->bv_offset + ctx->offset_out;
++ sg_out.length = 1 << SECTOR_SHIFT;
++
++ ctx->offset_in += sg_in.length;
++ if (ctx->offset_in >= bv_in->bv_len) {
++ ctx->offset_in = 0;
++ ctx->idx_in++;
++ }
++
++ ctx->offset_out += sg_out.length;
++ if (ctx->offset_out >= bv_out->bv_len) {
++ ctx->offset_out = 0;
++ ctx->idx_out++;
++ }
++
++ r = oxcrypt_convert_scatterlist(cc, &sg_out, &sg_in, sg_in.length,
++ ctx->write, ctx->sector);
++ if (r < 0)
++ break;
++
++ ctx->sector++;
++ }
++
++ return r;
++}
++
++/*
++ * Generate a new unfragmented bio with the given size
++ * This should never violate the device limitations
++ * May return a smaller bio when running out of pages
++ */
++static struct bio *
++oxcrypt_alloc_buffer(struct oxcrypt_config *cc, unsigned int size,
++ struct bio *base_bio, unsigned int *bio_vec_idx)
++{
++ struct bio *bio;
++ unsigned int nr_iovecs = dm_div_up(size, PAGE_SIZE);
++ int gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
++ unsigned long flags = current->flags;
++ unsigned int i;
++
++ /*
++ * Tell VM to act less aggressively and fail earlier.
++ * This is not necessary but increases throughput.
++ * FIXME: Is this really intelligent?
++ */
++ current->flags &= ~PF_MEMALLOC;
++
++ if (base_bio)
++ bio = bio_clone(base_bio, GFP_NOIO);
++ else
++ bio = bio_alloc(GFP_NOIO, nr_iovecs);
++ if (!bio) {
++ if (flags & PF_MEMALLOC)
++ current->flags |= PF_MEMALLOC;
++ return NULL;
++ }
++
++ /* if the last bio was not complete, continue where that one ended */
++ bio->bi_idx = *bio_vec_idx;
++ bio->bi_vcnt = *bio_vec_idx;
++ bio->bi_size = 0;
++ bio->bi_flags &= ~(1 << BIO_SEG_VALID);
++
++ /* bio->bi_idx pages have already been allocated */
++ size -= bio->bi_idx * PAGE_SIZE;
++
++ for(i = bio->bi_idx; i < nr_iovecs; i++) {
++ struct bio_vec *bv = bio_iovec_idx(bio, i);
++
++ bv->bv_page = mempool_alloc(cc->page_pool, gfp_mask);
++ if (!bv->bv_page)
++ break;
++
++ /*
++ * if additional pages cannot be allocated without waiting,
++ * return a partially allocated bio, the caller will then try
++ * to allocate additional bios while submitting this partial bio
++ */
++ if ((i - bio->bi_idx) == (MIN_BIO_PAGES - 1))
++ gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT;
++
++ bv->bv_offset = 0;
++ if (size > PAGE_SIZE)
++ bv->bv_len = PAGE_SIZE;
++ else
++ bv->bv_len = size;
++
++ bio->bi_size += bv->bv_len;
++ bio->bi_vcnt++;
++ size -= bv->bv_len;
++ }
++
++ if (flags & PF_MEMALLOC)
++ current->flags |= PF_MEMALLOC;
++
++ if (!bio->bi_size) {
++ bio_put(bio);
++ return NULL;
++ }
++
++ /*
++ * Remember the last bio_vec allocated to be able
++ * to correctly continue after the splitting.
++ */
++ *bio_vec_idx = bio->bi_vcnt;
++
++ return bio;
++}
++
++static void oxcrypt_free_buffer_pages(struct oxcrypt_config *cc,
++ struct bio *bio, unsigned int bytes)
++{
++ unsigned int i, start, end;
++ struct bio_vec *bv;
++
++ /*
++ * This is ugly, but Jens Axboe thinks that using bi_idx in the
++ * endio function is too dangerous at the moment, so I calculate the
++ * correct position using bi_vcnt and bi_size.
++ * The bv_offset and bv_len fields might already be modified but we
++ * know that we always allocated whole pages.
++ * A fix to the bi_idx issue in the kernel is in the works, so
++ * we will hopefully be able to revert to the cleaner solution soon.
++ */
++ i = bio->bi_vcnt - 1;
++ bv = bio_iovec_idx(bio, i);
++ end = (i << PAGE_SHIFT) + (bv->bv_offset + bv->bv_len) - bio->bi_size;
++ start = end - bytes;
++
++ start >>= PAGE_SHIFT;
++ if (!bio->bi_size)
++ end = bio->bi_vcnt;
++ else
++ end >>= PAGE_SHIFT;
++
++ for(i = start; i < end; i++) {
++ bv = bio_iovec_idx(bio, i);
++ BUG_ON(!bv->bv_page);
++ mempool_free(bv->bv_page, cc->page_pool);
++ bv->bv_page = NULL;
++ }
++}
++
++/*
++ * One of the bios was finished. Check for completion of
++ * the whole request and correctly clean up the buffer.
++ */
++static void dec_pending(struct oxcrypt_io *io, int error)
++{
++ struct oxcrypt_config *cc = (struct oxcrypt_config *) io->target->private;
++
++ if (error < 0)
++ io->error = error;
++
++ if (!atomic_dec_and_test(&io->pending))
++ return;
++
++ if (io->first_clone)
++ bio_put(io->first_clone);
++
++ bio_endio(io->bio, io->bio->bi_size, io->error);
++
++ mempool_free(io, cc->io_pool);
++}
++
++/*
++ * kcryptd:
++ *
++ * Needed because it would be very unwise to do decryption in an
++ * interrupt context, so bios returning from read requests get
++ * queued here.
++ */
++static struct workqueue_struct *_kcryptd_workqueue;
++
++static void kcryptd_do_work(struct work_struct *work)
++{
++ struct oxcrypt_io *io = container_of(work, struct oxcrypt_io, work);
++ struct oxcrypt_config *cc = (struct oxcrypt_config *) io->target->private;
++ struct convert_context ctx;
++ int r;
++
++ oxcrypt_convert_init(cc, &ctx, io->bio, io->bio,
++ io->bio->bi_sector - io->target->begin, 0);
++
++ /* printk("kcryptd_do_work %d sectors\n", ctx.bio_in->bi_vcnt ); */
++ r = oxcrypt_convert(cc, &ctx);
++
++ dec_pending(io, r);
++}
++
++static void kcryptd_queue_io(struct oxcrypt_io *io)
++{
++ INIT_WORK(&io->work, kcryptd_do_work);
++ queue_work(_kcryptd_workqueue, &io->work);
++}
++
++/*
++ * Decode key from its hex representation
++ */
++static int oxcrypt_decode_key(u8 *key, char *hex, unsigned int size)
++{
++ char buffer[3];
++ char *endp;
++ unsigned int i;
++
++ buffer[2] = '\0';
++
++ for(i = 0; i < size; i++) {
++ buffer[0] = *hex++;
++ buffer[1] = *hex++;
++ key[i] = (u8)simple_strtoul(buffer, &endp, 16);
++
++ if (endp != &buffer[2])
++ return -EINVAL;
++ }
++
++ if (*hex != '\0')
++ return -EINVAL;
++
++ /*
++ printk(KERN_INFO"key =");
++ for (i = 0; i < OX800DPE_KEYSIZE; ++i)
++ printk("%02x", key[i]);
++ printk("\n");
++ */
++
++ return 0;
++}
++
++/*
++ * Encode key into its hex representation
++ */
++static void oxcrypt_encode_key(char *hex, u8 *key, unsigned int size)
++{
++ unsigned int i;
++
++ for(i = 0; i < size; i++) {
++ sprintf(hex, "%02x", *key);
++ hex += 2;
++ key++;
++ }
++}
++
++/*
++ * Construct an encryption mapping, much simpler:
++ * <key> <iv-key> <iv_offset> <dev_path> <start>
++ */
++static int oxcrypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
++{
++ struct oxcrypt_config *cc;
++ unsigned long long tmpll;
++
++ if (argc != 5) {
++ ti->error = DM_MSG_PREFIX "Not enough arguments";
++ return -EINVAL;
++ }
++
++ cc = kmalloc(sizeof(*cc) , GFP_KERNEL);
++ if (cc == NULL) {
++ ti->error =
++ DM_MSG_PREFIX "Cannot allocate transparent encryption context";
++ return -ENOMEM;
++ }
++
++ memset( cc, 0, sizeof(*cc) );
++
++ if (oxcrypt_decode_key(cc->key, argv[0], OX800DPE_KEYSIZE) < 0) {
++ ti->error = DM_MSG_PREFIX "Error decoding key";
++ goto bad1;
++ }
++
++ if (oxcrypt_decode_key(cc->iv_key, argv[1], OX800DPE_KEYSIZE) < 0) {
++ ti->error = DM_MSG_PREFIX "Error decoding iv key";
++ goto bad1;
++ }
++
++ /*
++ * Force the ivmode to the ox-semi version
++ */
++ cc->iv_gen_ops = &oxcrypt_iv_oxsemi_ops;
++
++ cc->io_pool = mempool_create(MIN_IOS, mempool_alloc_slab,
++ mempool_free_slab, _oxcrypt_io_pool);
++ if (!cc->io_pool) {
++ ti->error = DM_MSG_PREFIX "Cannot allocate crypt io mempool";
++ goto bad3;
++ }
++
++ cc->page_pool = mempool_create(MIN_POOL_PAGES, mempool_alloc_page,
++ mempool_free_page, NULL);
++ if (!cc->page_pool) {
++ ti->error = DM_MSG_PREFIX "Cannot allocate page mempool";
++ goto bad4;
++ }
++
++ if (sscanf(argv[2], "%llu", &tmpll) != 1) {
++ ti->error = DM_MSG_PREFIX "Invalid iv_offset sector";
++ goto bad5;
++ }
++ cc->iv_offset = tmpll;
++
++ if (sscanf(argv[4], "%llu", &tmpll) != 1) {
++ ti->error = DM_MSG_PREFIX "Invalid device sector";
++ goto bad5;
++ }
++ cc->start = tmpll;
++
++ if (dm_get_device(ti, argv[3], cc->start, ti->len,
++ dm_table_get_mode(ti->table), &cc->dev)) {
++ ti->error = DM_MSG_PREFIX "Device lookup failed";
++ goto bad5;
++ }
++
++
++ ti->private = cc;
++
++ return 0;
++
++bad5:
++ mempool_destroy(cc->page_pool);
++bad4:
++ mempool_destroy(cc->io_pool);
++bad3:
++ if (cc->iv_gen_ops && cc->iv_gen_ops->dtr)
++ cc->iv_gen_ops->dtr(cc);
++bad1:
++ kfree(cc);
++ return -EINVAL;
++}
++
++static void oxcrypt_dtr(struct dm_target *ti)
++{
++ struct oxcrypt_config *cc = (struct oxcrypt_config *) ti->private;
++
++ mempool_destroy(cc->page_pool);
++ mempool_destroy(cc->io_pool);
++
++ if (cc->iv_gen_ops && cc->iv_gen_ops->dtr)
++ cc->iv_gen_ops->dtr(cc);
++ dm_put_device(ti, cc->dev);
++
++ kfree(cc);
++}
++
++static int oxcrypt_endio(struct bio *bio, unsigned int done, int error)
++{
++ struct oxcrypt_io *io = (struct oxcrypt_io *) bio->bi_private;
++ struct oxcrypt_config *cc = (struct oxcrypt_config *) io->target->private;
++
++ if (bio_data_dir(bio) == WRITE) {
++ /*
++ * free the processed pages, even if
++ * it's only a partially completed write
++ */
++ oxcrypt_free_buffer_pages(cc, bio, done);
++ }
++
++ if (bio->bi_size)
++ return 1;
++
++ bio_put(bio);
++
++ /*
++ * successful reads are decrypted by the worker thread
++ */
++ if ((bio_data_dir(bio) == READ)
++ && bio_flagged(bio, BIO_UPTODATE)) {
++ kcryptd_queue_io(io);
++ return 0;
++ }
++
++ dec_pending(io, error);
++ return error;
++}
++
++static struct bio *
++oxcrypt_clone(struct oxcrypt_config *cc, struct oxcrypt_io *io, struct bio *bio,
++ sector_t sector, unsigned int *bvec_idx,
++ struct convert_context *ctx)
++{
++ struct bio *clone;
++
++ if (bio_data_dir(bio) == WRITE) {
++ clone = oxcrypt_alloc_buffer(cc, bio->bi_size,
++ io->first_clone, bvec_idx);
++ if (clone) {
++ ctx->bio_out = clone;
++ if (oxcrypt_convert(cc, ctx) < 0) {
++ oxcrypt_free_buffer_pages(cc, clone,
++ clone->bi_size);
++ bio_put(clone);
++ return NULL;
++ }
++ }
++ } else {
++ /*
++ * The block layer might modify the bvec array, so always
++ * copy the required bvecs because we need the original
++ * one in order to decrypt the whole bio data *afterwards*.
++ */
++ clone = bio_alloc(GFP_NOIO, bio_segments(bio));
++ if (clone) {
++ clone->bi_idx = 0;
++ clone->bi_vcnt = bio_segments(bio);
++ clone->bi_size = bio->bi_size;
++ memcpy(clone->bi_io_vec, bio_iovec(bio),
++ sizeof(struct bio_vec) * clone->bi_vcnt);
++ }
++ }
++
++ if (!clone)
++ return NULL;
++
++ clone->bi_private = io;
++ clone->bi_end_io = oxcrypt_endio;
++ clone->bi_bdev = cc->dev->bdev;
++ clone->bi_sector = cc->start + sector;
++ clone->bi_rw = bio->bi_rw;
++
++ return clone;
++}
++
++static int oxcrypt_map(struct dm_target *ti, struct bio *bio,
++ union map_info *map_context)
++{
++ struct oxcrypt_config *cc = (struct oxcrypt_config *) ti->private;
++ struct oxcrypt_io *io = mempool_alloc(cc->io_pool, GFP_NOIO);
++ struct convert_context ctx;
++ struct bio *clone;
++ unsigned int remaining = bio->bi_size;
++ sector_t sector = bio->bi_sector - ti->begin;
++ unsigned int bvec_idx = 0;
++
++ io->target = ti;
++ io->bio = bio;
++ io->first_clone = NULL;
++ io->error = 0;
++ atomic_set(&io->pending, 1); /* hold a reference */
++
++ if (bio_data_dir(bio) == WRITE)
++ oxcrypt_convert_init(cc, &ctx, NULL, bio, sector, 1);
++
++ /*
++ * The allocated buffers can be smaller than the whole bio,
++ * so repeat the whole process until all the data can be handled.
++ */
++ while (remaining) {
++ clone = oxcrypt_clone(cc, io, bio, sector, &bvec_idx, &ctx);
++ if (!clone)
++ goto cleanup;
++
++ if (!io->first_clone) {
++ /*
++ * hold a reference to the first clone, because it
++ * holds the bio_vec array and that can't be freed
++ * before all other clones are released
++ */
++ bio_get(clone);
++ io->first_clone = clone;
++ }
++ atomic_inc(&io->pending);
++
++ remaining -= clone->bi_size;
++ sector += bio_sectors(clone);
++
++ generic_make_request(clone);
++
++ /* out of memory -> run queues */
++ if (remaining)
++ congestion_wait(bio_data_dir(clone), HZ/100);
++ }
++
++ /* drop reference, clones could have returned before we reach this */
++ dec_pending(io, 0);
++ return 0;
++
++cleanup:
++ if (io->first_clone) {
++ dec_pending(io, -ENOMEM);
++ return 0;
++ }
++
++ /* if no bio has been dispatched yet, we can directly return the error */
++ mempool_free(io, cc->io_pool);
++ return -ENOMEM;
++}
++
++static int oxcrypt_status(struct dm_target *ti, status_type_t type,
++ char *result, unsigned int maxlen)
++{
++ struct oxcrypt_config *cc = (struct oxcrypt_config *) ti->private;
++ char buffer[32];
++ const char *cipher;
++ const char *chainmode = NULL;
++ unsigned int sz = 0;
++
++ switch (type) {
++ case STATUSTYPE_INFO:
++ result[0] = '\0';
++ break;
++
++ case STATUSTYPE_TABLE:
++ cipher = "AES";
++
++ chainmode = "ecb";
++
++ DMEMIT("%s-%s ", cipher, chainmode);
++
++ oxcrypt_encode_key(result + sz, cc->key, OX800DPE_KEYSIZE);
++ sz += OX800DPE_KEYSIZE << 1;
++
++ format_dev_t(buffer, cc->dev->bdev->bd_dev);
++ DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset,
++ buffer, (unsigned long long)cc->start);
++ break;
++ }
++ return 0;
++}
++
++static struct target_type oxcrypt_target = {
++ .name = "ox-crypt",
++ .version= {1, 1, 0},
++ .module = THIS_MODULE,
++ .ctr = oxcrypt_ctr,
++ .dtr = oxcrypt_dtr,
++ .map = oxcrypt_map,
++ .status = oxcrypt_status,
++};
++
++static int __init dm_oxcrypt_init(void)
++{
++ int r;
++
++ _oxcrypt_io_pool = kmem_cache_create("dm-ox-oxcrypt_io",
++ sizeof(struct oxcrypt_io),
++ 0, 0, NULL);
++ if (!_oxcrypt_io_pool)
++ return -ENOMEM;
++
++ _kcryptd_workqueue = create_workqueue("kcryptd");
++ if (!_kcryptd_workqueue) {
++ r = -ENOMEM;
++ DMERR("couldn't create kcryptd");
++ goto bad1;
++ }
++
++ r = dm_register_target(&oxcrypt_target);
++ if (r < 0) {
++ DMERR("register failed %d", r);
++ goto bad2;
++ }
++
++ return 0;
++
++bad2:
++ destroy_workqueue(_kcryptd_workqueue);
++bad1:
++ kmem_cache_destroy(_oxcrypt_io_pool);
++ return r;
++}
++
++static void __exit dm_oxcrypt_exit(void)
++{
++ int r = dm_unregister_target(&oxcrypt_target);
++
++ if (r < 0)
++ DMERR("unregister failed %d", r);
++
++ destroy_workqueue(_kcryptd_workqueue);
++ kmem_cache_destroy(_oxcrypt_io_pool);
++}
++
++module_init(dm_oxcrypt_init);
++module_exit(dm_oxcrypt_exit);
++
++MODULE_AUTHOR("Oxford Semiconductor based on work of Christophe Saout");
++MODULE_DESCRIPTION(DM_NAME " target for hardware encryption / decryption");
++MODULE_LICENSE("GPL");
+diff -Nurd linux-2.6.24/drivers/md/raid1.c linux-2.6.24-oxe810/drivers/md/raid1.c
+--- linux-2.6.24/drivers/md/raid1.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/md/raid1.c 2008-06-11 17:50:20.000000000 +0200
+@@ -34,6 +34,12 @@
+ #include "dm-bio-list.h"
+ #include <linux/raid/raid1.h>
+ #include <linux/raid/bitmap.h>
++#ifdef CONFIG_SATA_OX800
++#include <asm/arch/sata.h>
++#endif
++#ifdef CONFIG_SATA_OX810
++#include <asm/arch/ox810sata.h>
++#endif
+
+ #define DEBUG 0
+ #if DEBUG
+@@ -67,6 +73,79 @@
+ return r1_bio;
+ }
+
++/**
++ * Assesses if the current raid configuration is suitable for implementation
++ * by the raid HW, if so, will enable it
++ */
++static void raid1_hw_raidable(mddev_t *mddev)
++{
++ mdk_rdev_t *rdev0;
++ mdk_rdev_t *rdev1;
++ conf_t *conf = mddev_to_conf(mddev);
++
++ /*default to SW RAID */
++ conf->hw_raid1_settings = 0;
++
++#if defined(CONFIG_SATA_OX800) || defined(CONFIG_SATA_OX810)
++ /* if this drive is suitable for HW raid then enable it */
++ if (mddev->raid_disks != 2) {
++ printk(KERN_NOTICE"raid1 not hw raidable %d disks (needs to be 2)\n",mddev->raid_disks);
++ return;
++ }
++
++ rdev0 = rcu_dereference(conf->mirrors[0].rdev);
++ rdev1 = rcu_dereference(conf->mirrors[1].rdev);
++
++ /* are there two working disks */
++ if (!rdev0 ||
++ !rdev1 ||
++ test_bit(Faulty, &rdev0->flags) ||
++ test_bit(Faulty, &rdev1->flags) ) {
++ printk(KERN_NOTICE"raid1 not hw raidable, needs two working disks.\n");
++ return;
++ }
++
++ if (!rdev0->bdev ||
++ !rdev1->bdev ||
++ !rdev0->bdev->bd_part ||
++ !rdev1->bdev->bd_part ) {
++ printk(KERN_NOTICE"raid1 not hw raidable, mirrors not ready\n");
++ return;
++ }
++
++ if (rdev0->bdev->bd_part->start_sect !=
++ rdev1->bdev->bd_part->start_sect) {
++ printk(KERN_NOTICE"raid1 not hw raidable, partition start sectors differ %lu, %lu\n",
++ rdev0->bdev->bd_part->start_sect,
++ rdev1->bdev->bd_part->start_sect);
++ return;
++ }
++
++ if (!rdev0->bdev->bd_disk ||
++ !rdev0->bdev->bd_disk->queue ||
++ (oxnassata_get_port_no(rdev0->bdev->bd_disk->queue) < 0)) {
++ printk(KERN_NOTICE"raid1 not hw raidable, RAID disk 0 not on internal SATA port.\n");
++ return;
++ }
++
++ if (!rdev1->bdev->bd_disk ||
++ !rdev1->bdev->bd_disk->queue ||
++ (oxnassata_get_port_no(rdev1->bdev->bd_disk->queue) < 0)) {
++ printk(KERN_NOTICE"raid1 not hw raidable, RAID disk 1 not on internal SATA port.\n");
++ return;
++ }
++
++ /* cannot mix 28 and 48-bit LBA devices */
++ if (!oxnassata_LBA_schemes_compatible()) {
++ printk(KERN_NOTICE"raid0 not hw raidable, disks need to use same LBA size (28 vs 48)\n");
++ return;
++ }
++
++ conf->hw_raid1_settings = OXNASSATA_RAID1;
++ printk(KERN_NOTICE"raid1 using hardware RAID 0x%08x\n",conf->hw_raid1_settings);
++#endif /*CONFIG_SCSI_OX800SATA*/
++}
++
+ static void r1bio_pool_free(void *r1_bio, void *data)
+ {
+ kfree(r1_bio);
+@@ -325,9 +404,29 @@
+ r1_bio->bios[mirror] = NULL;
+ to_put = bio;
+ if (!uptodate) {
++#if defined(CONFIG_SATA_OX800) || defined(CONFIG_SATA_OX810)
++ if ((mirror == 0) && (bio->bi_raid)) {
++ /* command was sent to part 0 for both drives, need to find
++ * which drive caused the error */
++ int device = oxnassata_RAID_faults();
++
++ /* it's unlikely, but both disks could fail at once */
++ if (device & 1) md_error(r1_bio->mddev, conf->mirrors[0].rdev);
++ if (device & 2) md_error(r1_bio->mddev, conf->mirrors[1].rdev);
++
++ /* an I/O failed, we can't clear the bitmap */
++ set_bit(R1BIO_Degraded, &r1_bio->state);
++
++ if (!(device & 3))
++ set_bit(R1BIO_Uptodate, &r1_bio->state);
++ } else {
++#endif // CONFIG_SCSI_OX800SATA
+ md_error(r1_bio->mddev, conf->mirrors[mirror].rdev);
+ /* an I/O failed, we can't clear the bitmap */
+ set_bit(R1BIO_Degraded, &r1_bio->state);
++#if defined(CONFIG_SATA_OX800) || defined(CONFIG_SATA_OX810)
++ }
++#endif // CONFIG_SCSI_OX800SATA
+ } else
+ /*
+ * Set R1BIO_Uptodate in our master bio, so that
+@@ -824,6 +923,53 @@
+ }
+ #endif
+ rcu_read_lock();
++
++ /* start of oxsemi hw raid code */
++ if ((rcu_dereference(conf->mirrors[0].rdev)) &&
++ (rcu_dereference(conf->mirrors[1].rdev)) &&
++ !test_bit(Faulty, &rcu_dereference(conf->mirrors[0].rdev)->flags) &&
++ !test_bit(Faulty, &rcu_dereference(conf->mirrors[1].rdev)->flags) &&
++ (conf->hw_raid1_settings) )
++ {
++ struct bio *mbio;
++
++ rdev = rcu_dereference(conf->mirrors[0].rdev);
++ atomic_inc(&rdev->nr_pending);
++ r1_bio->bios[0] = bio;
++ targets++;
++
++ rcu_read_unlock();
++
++ /* do behind I/O ? */
++ if (bitmap &&
++ atomic_read(&bitmap->behind_writes) < bitmap->max_write_behind &&
++ (behind_pages = alloc_behind_pages(bio)) != NULL)
++ set_bit(R1BIO_BehindIO, &r1_bio->state);
++
++ atomic_set(&r1_bio->remaining, 0);
++ atomic_set(&r1_bio->behind_remaining, 0);
++
++ do_barriers = bio_barrier(bio);
++ if (do_barriers)
++ set_bit(R1BIO_Barrier, &r1_bio->state);
++
++ bio_list_init(&bl);
++
++ mbio = bio_clone(bio, GFP_NOIO);
++ r1_bio->bios[0] = mbio;
++
++ mbio->bi_sector = r1_bio->sector + conf->mirrors[0].rdev->data_offset;
++ mbio->bi_bdev = conf->mirrors[0].rdev->bdev;
++ mbio->bi_end_io = raid1_end_write_request;
++ mbio->bi_rw = WRITE | do_barriers | do_sync;
++ mbio->bi_private = r1_bio;
++ mbio->bi_raid = conf->hw_raid1_settings ;
++
++ atomic_inc(&r1_bio->remaining);
++
++ bio_list_add(&bl, mbio);
++ /* end of hw_raid code */
++ } else {
+ for (i = 0; i < disks; i++) {
+ if ((rdev=rcu_dereference(conf->mirrors[i].rdev)) != NULL &&
+ !test_bit(Faulty, &rdev->flags)) {
+@@ -896,6 +1042,8 @@
+
+ bio_list_add(&bl, mbio);
+ }
++ }
++
+ kfree(behind_pages); /* the behind pages are attached to the bios now */
+
+ bitmap_startwrite(bitmap, bio->bi_sector, r1_bio->sectors,
+@@ -969,6 +1117,9 @@
+ printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n"
+ " Operation continuing on %d devices\n",
+ bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded);
++
++ /* check to see if this new configuration is supported by hardware RAID */
++ raid1_hw_raidable(mddev);
+ }
+
+ static void print_conf(conf_t *conf)
+@@ -1027,6 +1178,9 @@
+ }
+ }
+
++ /* check to see if this new configuration is supported by hardware RAID */
++ raid1_hw_raidable(mddev);
++
+ print_conf(conf);
+ return 0;
+ }
+@@ -1064,6 +1218,9 @@
+ break;
+ }
+
++ /* check to see if this new configuration is supported by hardware RAID */
++ raid1_hw_raidable(mddev);
++
+ print_conf(conf);
+ return found;
+ }
+@@ -1092,6 +1249,8 @@
+ }
+ }
+ abort:
++ /* check to see if this new configuration is supported by hardware RAID */
++ raid1_hw_raidable(mddev);
+
+ print_conf(conf);
+ return err;
+@@ -1719,6 +1878,7 @@
+ bio->bi_size = 0;
+ bio->bi_end_io = NULL;
+ bio->bi_private = NULL;
++ bio->bi_raid = 0;
+
+ rdev = rcu_dereference(conf->mirrors[i].rdev);
+ if (rdev == NULL ||
+@@ -1966,6 +2126,9 @@
+ */
+ mddev->array_size = mddev->size;
+
++ /* check to see if this new configuration is supported by hardware RAID */
++ raid1_hw_raidable(mddev);
++
+ mddev->queue->unplug_fn = raid1_unplug;
+ mddev->queue->backing_dev_info.congested_fn = raid1_congested;
+ mddev->queue->backing_dev_info.congested_data = mddev;
+@@ -2035,6 +2198,9 @@
+ }
+ mddev->size = mddev->array_size;
+ mddev->resync_max_sectors = sectors;
++ /* check to see if this new configuration is supported by hardware RAID */
++ raid1_hw_raidable(mddev);
++
+ return 0;
+ }
+
+@@ -2138,6 +2304,9 @@
+ mddev->delta_disks = 0;
+
+ conf->last_used = 0; /* just make sure it is in-range */
++ /* check to see if this new configuration is supported by hardware RAID */
++ raid1_hw_raidable(mddev);
++
+ lower_barrier(conf);
+
+ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+diff -Nurd linux-2.6.24/drivers/media/video/cx23885/cx23885-cards.c linux-2.6.24-oxe810/drivers/media/video/cx23885/cx23885-cards.c
+--- linux-2.6.24/drivers/media/video/cx23885/cx23885-cards.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/media/video/cx23885/cx23885-cards.c 2008-06-11 17:48:59.000000000 +0200
+@@ -138,6 +138,10 @@
+ .card = CX23885_BOARD_HAUPPAUGE_HVR1800,
+ },{
+ .subvendor = 0x0070,
++ .subdevice = 0x7809,
++ .card = CX23885_BOARD_HAUPPAUGE_HVR1800,
++ },{
++ .subvendor = 0x0070,
+ .subdevice = 0x7911,
+ .card = CX23885_BOARD_HAUPPAUGE_HVR1250,
+ },{
+diff -Nurd linux-2.6.24/drivers/message/fusion/mptsas.c linux-2.6.24-oxe810/drivers/message/fusion/mptsas.c
+--- linux-2.6.24/drivers/message/fusion/mptsas.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/message/fusion/mptsas.c 2008-06-11 17:49:11.000000000 +0200
+@@ -1699,6 +1699,11 @@
+ if (error)
+ goto out_free_consistent;
+
++ if (!buffer->NumPhys) {
++ error = -ENODEV;
++ goto out_free_consistent;
++ }
++
+ /* save config data */
+ port_info->num_phys = buffer->NumPhys;
+ port_info->phy_info = kcalloc(port_info->num_phys,
+diff -Nurd linux-2.6.24/drivers/net/Kconfig linux-2.6.24-oxe810/drivers/net/Kconfig
+--- linux-2.6.24/drivers/net/Kconfig 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/Kconfig 2008-06-11 17:50:11.000000000 +0200
+@@ -2368,6 +2368,14 @@
+ To compile this driver as a module, choose M here. The module
+ will be called atl1.
+
++config SYNOPSYS_GMAC
++ tristate "Synopsys Gigabit MAC"
++ select CRC32
++ select MII
++ depends on ARCH_OXNAS
++ help
++ Driver for the Synopsys Gigabit MAC
++
+ endif # NETDEV_1000
+
+ #
+diff -Nurd linux-2.6.24/drivers/net/bonding/bond_main.c linux-2.6.24-oxe810/drivers/net/bonding/bond_main.c
+--- linux-2.6.24/drivers/net/bonding/bond_main.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/bonding/bond_main.c 2008-06-11 17:50:00.000000000 +0200
+@@ -4883,14 +4883,16 @@
+ down_write(&bonding_rwsem);
+
+ /* Check to see if the bond already exists. */
+- list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
+- if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) {
+- printk(KERN_ERR DRV_NAME
++ if (name) {
++ list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
++ if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) {
++ printk(KERN_ERR DRV_NAME
+ ": cannot add bond %s; it already exists\n",
+- name);
+- res = -EPERM;
+- goto out_rtnl;
+- }
++ name);
++ res = -EPERM;
++ goto out_rtnl;
++ }
++ }
+
+ bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "",
+ ether_setup);
+diff -Nurd linux-2.6.24/drivers/net/dl2k.h linux-2.6.24-oxe810/drivers/net/dl2k.h
+--- linux-2.6.24/drivers/net/dl2k.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/dl2k.h 2008-06-11 17:50:11.000000000 +0200
+@@ -388,8 +388,8 @@
+ MII_MSSR_CFG_RES = 0x4000,
+ MII_MSSR_LOCAL_RCV_STATUS = 0x2000,
+ MII_MSSR_REMOTE_RCVR = 0x1000,
+- MII_MSSR_LP_1000BT_HD = 0x0800,
+- MII_MSSR_LP_1000BT_FD = 0x0400,
++ MII_MSSR_LP_1000BT_FD = 0x0800,
++ MII_MSSR_LP_1000BT_HD = 0x0400,
+ MII_MSSR_IDLE_ERR_COUNT = 0x00ff,
+ };
+
+diff -Nurd linux-2.6.24/drivers/net/e1000e/netdev.c linux-2.6.24-oxe810/drivers/net/e1000e/netdev.c
+--- linux-2.6.24/drivers/net/e1000e/netdev.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/e1000e/netdev.c 2008-06-11 17:50:07.000000000 +0200
+@@ -1686,6 +1686,9 @@
+ else
+ rctl |= E1000_RCTL_LPE;
+
++ /* Enable hardware CRC frame stripping */
++ rctl |= E1000_RCTL_SECRC;
++
+ /* Setup buffer sizes */
+ rctl &= ~E1000_RCTL_SZ_4096;
+ rctl |= E1000_RCTL_BSEX;
+@@ -1751,9 +1754,6 @@
+
+ /* Enable Packet split descriptors */
+ rctl |= E1000_RCTL_DTYP_PS;
+-
+- /* Enable hardware CRC frame stripping */
+- rctl |= E1000_RCTL_SECRC;
+
+ psrctl |= adapter->rx_ps_bsize0 >>
+ E1000_PSRCTL_BSIZE0_SHIFT;
+diff -Nurd linux-2.6.24/drivers/net/forcedeth.c linux-2.6.24-oxe810/drivers/net/forcedeth.c
+--- linux-2.6.24/drivers/net/forcedeth.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/forcedeth.c 2008-06-11 17:50:11.000000000 +0200
+@@ -5593,35 +5593,35 @@
+ },
+ { /* MCP77 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32),
+- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
++ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ },
+ { /* MCP77 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33),
+- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
++ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ },
+ { /* MCP77 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34),
+- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
++ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ },
+ { /* MCP77 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35),
+- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
++ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ },
+ { /* MCP79 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36),
+- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
++ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ },
+ { /* MCP79 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37),
+- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
++ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ },
+ { /* MCP79 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38),
+- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
++ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ },
+ { /* MCP79 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39),
+- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
++ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ },
+ {0,},
+ };
+diff -Nurd linux-2.6.24/drivers/net/macb.c linux-2.6.24-oxe810/drivers/net/macb.c
+--- linux-2.6.24/drivers/net/macb.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/macb.c 2008-06-11 17:50:11.000000000 +0200
+@@ -148,7 +148,7 @@
+
+ if (phydev->duplex)
+ reg |= MACB_BIT(FD);
+- if (phydev->speed)
++ if (phydev->speed == SPEED_100)
+ reg |= MACB_BIT(SPD);
+
+ macb_writel(bp, NCFGR, reg);
+diff -Nurd linux-2.6.24/drivers/net/mii.c linux-2.6.24-oxe810/drivers/net/mii.c
+--- linux-2.6.24/drivers/net/mii.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/mii.c 2008-06-11 17:50:11.000000000 +0200
+@@ -46,11 +46,13 @@
+ u32 advert, bmcr, lpa, nego;
+ u32 advert2 = 0, bmcr2 = 0, lpa2 = 0;
+
++ int supports_gmii = mii->mdio_read(dev, mii->phy_id, MII_BMSR) & BMSR_ESTATEN;
++
+ ecmd->supported =
+ (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
+ SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII);
+- if (mii->supports_gmii)
++ if (supports_gmii)
+ ecmd->supported |= SUPPORTED_1000baseT_Half |
+ SUPPORTED_1000baseT_Full;
+
+@@ -65,7 +67,7 @@
+
+ ecmd->advertising = ADVERTISED_TP | ADVERTISED_MII;
+ advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE);
+- if (mii->supports_gmii)
++ if (supports_gmii)
+ advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
+
+ if (advert & ADVERTISE_10HALF)
+@@ -83,7 +85,7 @@
+
+ bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
+ lpa = mii->mdio_read(dev, mii->phy_id, MII_LPA);
+- if (mii->supports_gmii) {
++ if (supports_gmii) {
+ bmcr2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
+ lpa2 = mii->mdio_read(dev, mii->phy_id, MII_STAT1000);
+ }
+@@ -132,6 +134,8 @@
+ {
+ struct net_device *dev = mii->dev;
+
++ int supports_gmii = mii->mdio_read(dev, mii->phy_id, MII_BMSR) & BMSR_ESTATEN;
++
+ if (ecmd->speed != SPEED_10 &&
+ ecmd->speed != SPEED_100 &&
+ ecmd->speed != SPEED_1000)
+@@ -146,7 +150,7 @@
+ return -EINVAL;
+ if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE)
+ return -EINVAL;
+- if ((ecmd->speed == SPEED_1000) && (!mii->supports_gmii))
++ if ((ecmd->speed == SPEED_1000) && (!supports_gmii))
+ return -EINVAL;
+
+ /* ignore supported, maxtxpkt, maxrxpkt */
+@@ -166,7 +170,7 @@
+ /* advertise only what has been requested */
+ advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE);
+ tmp = advert & ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
+- if (mii->supports_gmii) {
++ if (supports_gmii) {
+ advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
+ tmp2 = advert2 & ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
+ }
+@@ -178,7 +182,7 @@
+ tmp |= ADVERTISE_100HALF;
+ if (ecmd->advertising & ADVERTISED_100baseT_Full)
+ tmp |= ADVERTISE_100FULL;
+- if (mii->supports_gmii) {
++ if (supports_gmii) {
+ if (ecmd->advertising & ADVERTISED_1000baseT_Half)
+ tmp2 |= ADVERTISE_1000HALF;
+ if (ecmd->advertising & ADVERTISED_1000baseT_Full)
+@@ -188,7 +192,7 @@
+ mii->mdio_write(dev, mii->phy_id, MII_ADVERTISE, tmp);
+ mii->advertising = tmp;
+ }
+- if ((mii->supports_gmii) && (advert2 != tmp2))
++ if (advert2 != tmp2)
+ mii->mdio_write(dev, mii->phy_id, MII_CTRL1000, tmp2);
+
+ /* turn on autonegotiation, and force a renegotiate */
+@@ -312,6 +316,7 @@
+ unsigned int old_carrier, new_carrier;
+ int advertise, lpa, media, duplex;
+ int lpa2 = 0;
++ int supports_gmii = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR) & BMSR_ESTATEN;
+
+ /* if forced media, go no further */
+ if (mii->force_media)
+@@ -348,7 +353,7 @@
+ mii->advertising = advertise;
+ }
+ lpa = mii->mdio_read(mii->dev, mii->phy_id, MII_LPA);
+- if (mii->supports_gmii)
++ if (supports_gmii)
+ lpa2 = mii->mdio_read(mii->dev, mii->phy_id, MII_STAT1000);
+
+ /* figure out media and duplex from advertise and LPA values */
+@@ -373,6 +378,148 @@
+ return 0; /* duplex did not change */
+ }
+
++
++unsigned int mii_check_media_ex(
++ struct mii_if_info *mii,
++ unsigned int ok_to_print,
++ unsigned int init_media,
++ int *has_gigabit_changed,
++ int *has_pause_changed,
++ void (*link_state_change_callback)(int link_state, void* arg),
++ void *link_state_change_arg)
++{
++ unsigned int old_carrier, new_carrier;
++ int advertise, lpa;
++ unsigned int negotiated_10_100;
++ int advertise2 = 0, lpa2 = 0;
++ unsigned int negotiated_1000;
++ int duplex = 0;
++ int using_100 = 0;
++ int using_1000 = 0;
++ int using_pause = 0;
++ int duplex_changed = 0;
++ int changed_100 = 0;
++ int changed_1000 = 0;
++ int changed_pause = 0;
++ int supports_gmii = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR) & BMSR_ESTATEN;
++
++ // Initialise user's locations for returned gigabit and pause changed values
++ // to no-change
++ *has_gigabit_changed = 0;
++ *has_pause_changed = 0;
++
++ /* if forced media, go no further */
++ if (mii->force_media)
++ return 0; /* duplex did not change */
++
++ /* check current and old link status */
++ old_carrier = netif_carrier_ok(mii->dev) ? 1 : 0;
++ new_carrier = (unsigned int) mii_link_ok(mii);
++
++ /* if carrier state did not change, this is a "bounce",
++ * just exit as everything is already set correctly
++ */
++ if ((!init_media) && (old_carrier == new_carrier))
++ return 0; /* duplex did not change */
++
++ /* no carrier, nothing much to do */
++ if (!new_carrier) {
++ netif_carrier_off(mii->dev);
++ if (ok_to_print) {
++ printk(KERN_INFO "%s: link down\n", mii->dev->name);
++ }
++ link_state_change_callback(0, link_state_change_arg);
++ return 0; /* duplex did not change */
++ }
++
++ /*
++ * we have carrier, see who's on the other end
++ */
++ netif_carrier_on(mii->dev);
++
++ /* Get our advertise values */
++ if ((!init_media) && (mii->advertising))
++ advertise = mii->advertising;
++ else {
++ advertise = mii->mdio_read(mii->dev, mii->phy_id, MII_ADVERTISE);
++ mii->advertising = advertise;
++ }
++//printk("mii_check_media_ex() MII_ADVERTISE read as 0x%08x\n", advertise);
++ if (supports_gmii) {
++ advertise2 = mii->mdio_read(mii->dev, mii->phy_id, MII_CTRL1000);
++//printk("mii_check_media_ex() MII_CTRL1000 read as 0x%08x\n", advertise2);
++ }
++
++ /* Get link partner advertise values */
++ lpa = mii->mdio_read(mii->dev, mii->phy_id, MII_LPA);
++//printk("mii_check_media_ex() MII_LPA read as 0x%08x\n", lpa);
++ if (supports_gmii) {
++ lpa2 = mii->mdio_read(mii->dev, mii->phy_id, MII_STAT1000);
++//printk("mii_check_media_ex() MII_STAT1000 read as 0x%08x\n", lpa2);
++ }
++
++//printk("Us pause = %d, async pause = %d\n", advertise & ADVERTISE_PAUSE_CAP, advertise & ADVERTISE_PAUSE_ASYM);
++//printk("Link partner pause = %d, async pause = %d\n", lpa & LPA_PAUSE_CAP, lpa & LPA_PAUSE_ASYM);
++
++ /* Determine negotiated mode/duplex from our and link partner's advertise values */
++ negotiated_10_100 = mii_nway_result(lpa & advertise);
++ negotiated_1000 = mii_nway_result_1000(lpa2, advertise2);
++
++ /* Determine the rate we're operating at */
++ if (negotiated_1000 & (LPA_1000FULL | LPA_1000HALF)) {
++ using_1000 = 1;
++ duplex = (negotiated_1000 & LPA_1000FULL) ? 1 : 0;
++ } else {
++ if (negotiated_10_100 & (LPA_100FULL | LPA_100HALF)) {
++ using_100 = 1;
++ }
++ duplex = (negotiated_10_100 & ADVERTISE_FULL) ? 1 : 0;
++ }
++
++ /* Does link partner advertise that we can send pause frames to it? */
++ using_pause = (lpa & LPA_PAUSE_CAP) ? 1 : 0;
++
++ if (ok_to_print)
++ printk(KERN_INFO "%s: link up, %sMbps, %s-duplex, %s pause, lpa 0x%04X\n",
++ mii->dev->name,
++ using_1000 ? "1000" :
++ using_100 ? "100" : "10",
++ duplex ? "full" : "half",
++ using_pause ? "using" : "not using",
++ lpa);
++
++ link_state_change_callback(1, link_state_change_arg);
++
++ if (mii->full_duplex != duplex) {
++ duplex_changed = 1;
++ }
++ if (mii->using_100 != using_100) {
++ changed_100 = 1;
++ }
++ if (mii->using_1000 != using_1000) {
++ changed_1000 = 1;
++ }
++ if (mii->using_pause != using_pause) {
++ changed_pause = 1;
++ }
++
++ if (init_media || changed_100 || changed_1000 || changed_pause || duplex_changed) {
++ mii->full_duplex = duplex;
++ mii->using_100 = using_100;
++ mii->using_1000 = using_1000;
++ mii->using_pause = using_pause;
++ if (init_media || changed_1000) {
++ *has_gigabit_changed = 1;
++ }
++ if (init_media || changed_pause) {
++ *has_pause_changed = 1;
++ }
++ return init_media || duplex_changed;
++ }
++
++ return 0; /* duplex did not change */
++}
++
+ /**
+ * generic_mii_ioctl - main MII ioctl interface
+ * @mii_if: the MII interface
+@@ -465,6 +612,7 @@
+ EXPORT_SYMBOL(mii_ethtool_sset);
+ EXPORT_SYMBOL(mii_check_link);
+ EXPORT_SYMBOL(mii_check_media);
++EXPORT_SYMBOL(mii_check_media_ex);
+ EXPORT_SYMBOL(mii_check_gmii_support);
+ EXPORT_SYMBOL(generic_mii_ioctl);
+
+diff -Nurd linux-2.6.24/drivers/net/niu.c linux-2.6.24-oxe810/drivers/net/niu.c
+--- linux-2.6.24/drivers/net/niu.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/niu.c 2008-06-11 17:50:11.000000000 +0200
+@@ -33,8 +33,8 @@
+
+ #define DRV_MODULE_NAME "niu"
+ #define PFX DRV_MODULE_NAME ": "
+-#define DRV_MODULE_VERSION "0.6"
+-#define DRV_MODULE_RELDATE "January 5, 2008"
++#define DRV_MODULE_VERSION "0.7"
++#define DRV_MODULE_RELDATE "February 18, 2008"
+
+ static char version[] __devinitdata =
+ DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
+@@ -1616,12 +1616,13 @@
+ if (index >= niu_num_alt_addr(np))
+ return -EINVAL;
+
+- if (np->flags & NIU_FLAGS_XMAC)
++ if (np->flags & NIU_FLAGS_XMAC) {
+ reg = XMAC_ADDR_CMPEN;
+- else
++ mask = 1 << index;
++ } else {
+ reg = BMAC_ADDR_CMPEN;
+-
+- mask = 1 << index;
++ mask = 1 << (index + 1);
++ }
+
+ val = nr64_mac(reg);
+ if (on)
+@@ -5147,7 +5148,12 @@
+ index++;
+ }
+ } else {
+- for (i = 0; i < niu_num_alt_addr(np); i++) {
++ int alt_start;
++ if (np->flags & NIU_FLAGS_XMAC)
++ alt_start = 0;
++ else
++ alt_start = 1;
++ for (i = alt_start; i < niu_num_alt_addr(np); i++) {
+ err = niu_enable_alt_mac(np, i, 0);
+ if (err)
+ printk(KERN_WARNING PFX "%s: Error %d "
+diff -Nurd linux-2.6.24/drivers/net/niu.h linux-2.6.24-oxe810/drivers/net/niu.h
+--- linux-2.6.24/drivers/net/niu.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/niu.h 2008-06-11 17:50:11.000000000 +0200
+@@ -499,7 +499,7 @@
+ #define BMAC_ADDR2 0x00110UL
+ #define BMAC_ADDR2_ADDR2 0x000000000000ffffULL
+
+-#define BMAC_NUM_ALT_ADDR 7
++#define BMAC_NUM_ALT_ADDR 6
+
+ #define BMAC_ALT_ADDR0(NUM) (0x00118UL + (NUM)*0x18UL)
+ #define BMAC_ALT_ADDR0_ADDR0 0x000000000000ffffULL
+diff -Nurd linux-2.6.24/drivers/net/pcmcia/smc91c92_cs.c linux-2.6.24-oxe810/drivers/net/pcmcia/smc91c92_cs.c
+--- linux-2.6.24/drivers/net/pcmcia/smc91c92_cs.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/pcmcia/smc91c92_cs.c 2008-06-11 17:50:04.000000000 +0200
+@@ -559,8 +559,16 @@
+
+ /* Read the station address from the CIS. It is stored as the last
+ (fourth) string in the Version 1 Version/ID tuple. */
+- if (link->prod_id[3]) {
+- station_addr = link->prod_id[3];
++ tuple->DesiredTuple = CISTPL_VERS_1;
++ if (first_tuple(link, tuple, parse) != CS_SUCCESS) {
++ rc = -1;
++ goto free_cfg_mem;
++ }
++ /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
++ if (next_tuple(link, tuple, parse) != CS_SUCCESS)
++ first_tuple(link, tuple, parse);
++ if (parse->version_1.ns > 3) {
++ station_addr = parse->version_1.str + parse->version_1.ofs[3];
+ if (cvt_ascii_address(dev, station_addr) == 0) {
+ rc = 0;
+ goto free_cfg_mem;
+diff -Nurd linux-2.6.24/drivers/net/sky2.c linux-2.6.24-oxe810/drivers/net/sky2.c
+--- linux-2.6.24/drivers/net/sky2.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/sky2.c 2008-06-11 17:50:11.000000000 +0200
+@@ -621,6 +621,7 @@
+ static const u32 phy_power[] = { PCI_Y2_PHY1_POWD, PCI_Y2_PHY2_POWD };
+ static const u32 coma_mode[] = { PCI_Y2_PHY1_COMA, PCI_Y2_PHY2_COMA };
+
++ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+ reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
+ /* Turn on/off phy power saving */
+ if (onoff)
+@@ -632,7 +633,8 @@
+ reg1 |= coma_mode[port];
+
+ sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
+- reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
++ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
++ sky2_pci_read32(hw, PCI_DEV_REG1);
+
+ udelay(100);
+ }
+@@ -1412,6 +1414,7 @@
+ imask |= portirq_msk[port];
+ sky2_write32(hw, B0_IMSK, imask);
+
++ sky2_set_multicast(dev);
+ return 0;
+
+ err_out:
+@@ -2426,6 +2429,7 @@
+ if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) {
+ u16 pci_err;
+
++ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+ pci_err = sky2_pci_read16(hw, PCI_STATUS);
+ if (net_ratelimit())
+ dev_err(&pdev->dev, "PCI hardware error (0x%x)\n",
+@@ -2433,12 +2437,14 @@
+
+ sky2_pci_write16(hw, PCI_STATUS,
+ pci_err | PCI_STATUS_ERROR_BITS);
++ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+ }
+
+ if (status & Y2_IS_PCI_EXP) {
+ /* PCI-Express uncorrectable Error occurred */
+ u32 err;
+
++ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+ err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
+ sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
+ 0xfffffffful);
+@@ -2446,6 +2452,7 @@
+ dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err);
+
+ sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
++ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+ }
+
+ if (status & Y2_HWE_L1_MASK)
+@@ -2811,6 +2818,7 @@
+ }
+
+ sky2_power_on(hw);
++ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+ for (i = 0; i < hw->ports; i++) {
+ sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
+@@ -3533,8 +3541,6 @@
+ err = sky2_up(dev);
+ if (err)
+ dev_close(dev);
+- else
+- sky2_set_multicast(dev);
+ }
+
+ return err;
+@@ -4368,8 +4374,6 @@
+ dev_close(dev);
+ goto out;
+ }
+-
+- sky2_set_multicast(dev);
+ }
+ }
+
+diff -Nurd linux-2.6.24/drivers/net/via-velocity.c linux-2.6.24-oxe810/drivers/net/via-velocity.c
+--- linux-2.6.24/drivers/net/via-velocity.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/via-velocity.c 2008-06-11 17:50:11.000000000 +0200
+@@ -72,7 +72,6 @@
+ #include <linux/mii.h>
+ #include <linux/in.h>
+ #include <linux/if_arp.h>
+-#include <linux/if_vlan.h>
+ #include <linux/ip.h>
+ #include <linux/tcp.h>
+ #include <linux/udp.h>
+@@ -81,170 +80,50 @@
+
+ #include "via-velocity.h"
+
++// Default MAC address
++static const u8 DEFAULT_MAC_ADDRESS[] = { 0x00, 0x30, 0xe0, 0x00, 0x00, 0xff };
++static u32 mac_hi=0;
++static u32 mac_lo=0;
+
+-static int velocity_nics = 0;
+-static int msglevel = MSG_LEVEL_INFO;
+-
+-/**
+- * mac_get_cam_mask - Read a CAM mask
+- * @regs: register block for this velocity
+- * @mask: buffer to store mask
+- *
+- * Fetch the mask bits of the selected CAM and store them into the
+- * provided mask buffer.
+- */
+-
+-static void mac_get_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
+-{
+- int i;
+-
+- /* Select CAM mask */
+- BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
+-
+- writeb(0, ®s->CAMADDR);
+-
+- /* read mask */
+- for (i = 0; i < 8; i++)
+- *mask++ = readb(&(regs->MARCAM[i]));
+-
+- /* disable CAMEN */
+- writeb(0, ®s->CAMADDR);
+-
+- /* Select mar */
+- BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
+-
+-}
+-
+-
+-/**
+- * mac_set_cam_mask - Set a CAM mask
+- * @regs: register block for this velocity
+- * @mask: CAM mask to load
+- *
+- * Store a new mask into a CAM
+- */
+-
+-static void mac_set_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
+-{
+- int i;
+- /* Select CAM mask */
+- BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
+-
+- writeb(CAMADDR_CAMEN, ®s->CAMADDR);
+-
+- for (i = 0; i < 8; i++) {
+- writeb(*mask++, &(regs->MARCAM[i]));
+- }
+- /* disable CAMEN */
+- writeb(0, ®s->CAMADDR);
+-
+- /* Select mar */
+- BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
+-}
+-
+-static void mac_set_vlan_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
+-{
+- int i;
+- /* Select CAM mask */
+- BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
+-
+- writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL, ®s->CAMADDR);
+-
+- for (i = 0; i < 8; i++) {
+- writeb(*mask++, &(regs->MARCAM[i]));
+- }
+- /* disable CAMEN */
+- writeb(0, ®s->CAMADDR);
+-
+- /* Select mar */
+- BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
+-}
+-
+-/**
+- * mac_set_cam - set CAM data
+- * @regs: register block of this velocity
+- * @idx: Cam index
+- * @addr: 2 or 6 bytes of CAM data
+- *
+- * Load an address or vlan tag into a CAM
+- */
+-
+-static void mac_set_cam(struct mac_regs __iomem * regs, int idx, const u8 *addr)
+-{
+- int i;
+-
+- /* Select CAM mask */
+- BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
+-
+- idx &= (64 - 1);
+-
+- writeb(CAMADDR_CAMEN | idx, ®s->CAMADDR);
+-
+- for (i = 0; i < 6; i++) {
+- writeb(*addr++, &(regs->MARCAM[i]));
+- }
+- BYTE_REG_BITS_ON(CAMCR_CAMWR, ®s->CAMCR);
+-
+- udelay(10);
++#define EXTRA_RX_SKB_SPACE 32
++#define MAX_HW_FRAGMENTS 6
++//#define VELOCITY_ZERO_COPY_SUPPORT
++//#define LOAD_FROM_EEPROM
+
+- writeb(0, ®s->CAMADDR);
++#define VELOCITY_DESC_IN_SRAM
+
+- /* Select mar */
+- BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
+-}
++#ifdef VELOCITY_DESC_IN_SRAM
++#include <asm/arch/desc_alloc.h>
++#endif // VELOCITY_DESC_IN_SRAM
+
+-static void mac_set_vlan_cam(struct mac_regs __iomem * regs, int idx,
+- const u8 *addr)
++/* Parse netdev kernel cmdline options */
++static int __init do_setup(char *str)
+ {
++ int i;
++ int ints[5]; // Hold arg count and four args
+
+- /* Select CAM mask */
+- BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
+-
+- idx &= (64 - 1);
+-
+- writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, ®s->CAMADDR);
+- writew(*((u16 *) addr), ®s->MARCAM[0]);
+-
+- BYTE_REG_BITS_ON(CAMCR_CAMWR, ®s->CAMCR);
+-
+- udelay(10);
+-
+- writeb(0, ®s->CAMADDR);
+-
+- /* Select mar */
+- BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
++ get_options(str, sizeof(ints)/sizeof(int), ints);
++ for (i=1; i<=ints[0]; i++) {
++ switch (i) {
++ case 3:
++ mac_hi = ints[i];
++ break;
++ case 4:
++ mac_lo = ints[i];
++ break;
++ default:
++ break;
++ }
++ }
++ return 0;
+ }
++__setup("netdev=",do_setup);
+
+-
+-/**
+- * mac_wol_reset - reset WOL after exiting low power
+- * @regs: register block of this velocity
+- *
+- * Called after we drop out of wake on lan mode in order to
+- * reset the Wake on lan features. This function doesn't restore
+- * the rest of the logic from the result of sleep/wakeup
+- */
+-
+-static void mac_wol_reset(struct mac_regs __iomem * regs)
+-{
+-
+- /* Turn off SWPTAG right after leaving power mode */
+- BYTE_REG_BITS_OFF(STICKHW_SWPTAG, ®s->STICKHW);
+- /* clear sticky bits */
+- BYTE_REG_BITS_OFF((STICKHW_DS1 | STICKHW_DS0), ®s->STICKHW);
+-
+- BYTE_REG_BITS_OFF(CHIPGCR_FCGMII, ®s->CHIPGCR);
+- BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, ®s->CHIPGCR);
+- /* disable force PME-enable */
+- writeb(WOLCFG_PMEOVR, ®s->WOLCFGClr);
+- /* disable power-event config bit */
+- writew(0xFFFF, ®s->WOLCRClr);
+- /* clear power status */
+- writew(0xFFFF, ®s->WOLSRClr);
+-}
++static int velocity_nics = 0;
++static int msglevel = MSG_LEVEL_INFO;
+
+ static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
+-static const struct ethtool_ops velocity_ethtool_ops;
++static struct ethtool_ops velocity_ethtool_ops;
+
+ /*
+ Define module options
+@@ -269,6 +148,15 @@
+ #define TX_DESC_DEF 64
+ VELOCITY_PARAM(TxDescriptors, "Number of transmit descriptors");
+
++#define VLAN_ID_MIN 0
++#define VLAN_ID_MAX 4095
++#define VLAN_ID_DEF 0
++/* VID_setting[] is used for setting the VID of NIC.
++ 0: default VID.
++ 1-4094: other VIDs.
++*/
++VELOCITY_PARAM(VID_setting, "802.1Q VLAN ID");
++
+ #define RX_THRESH_MIN 0
+ #define RX_THRESH_MAX 3
+ #define RX_THRESH_DEF 0
+@@ -282,7 +170,8 @@
+
+ #define DMA_LENGTH_MIN 0
+ #define DMA_LENGTH_MAX 7
+-#define DMA_LENGTH_DEF 0
++#define DMA_LENGTH_100M_DEF 6
++#define DMA_LENGTH_1000M_DEF 6
+
+ /* DMA_length[] is used for controlling the DMA length
+ 0: 8 DWORDs
+@@ -294,7 +183,15 @@
+ 6: SF(flush till emply)
+ 7: SF(flush till emply)
+ */
+-VELOCITY_PARAM(DMA_length, "DMA length");
++VELOCITY_PARAM(DMA_length_100M, "DMA length 100M");
++VELOCITY_PARAM(DMA_length_1000M, "DMA length 1000M");
++
++#define TAGGING_DEF 0
++/* enable_tagging[] is used for enabling 802.1Q VID tagging.
++ 0: disable VID seeting(default).
++ 1: enable VID setting.
++*/
++VELOCITY_PARAM(enable_tagging, "Enable 802.1Q tagging");
+
+ #define IP_ALIG_DEF 0
+ /* IP_byte_align[] is used for IP header DWORD byte aligned
+@@ -378,7 +275,7 @@
+ static int velocity_open(struct net_device *dev);
+ static int velocity_change_mtu(struct net_device *dev, int mtu);
+ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev);
+-static int velocity_intr(int irq, void *dev_instance);
++static int velocity_intr(int irq, void *dev_instance, struct pt_regs *regs);
+ static void velocity_set_multi(struct net_device *dev);
+ static struct net_device_stats *velocity_get_stats(struct net_device *dev);
+ static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+@@ -401,25 +298,23 @@
+ static u32 mii_check_media_mode(struct mac_regs __iomem * regs);
+ static u32 check_connection_type(struct mac_regs __iomem * regs);
+ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status);
++static void hw_set_mac_address(struct velocity_info *vptr, unsigned char* addr);
++static int set_mac_address(struct net_device *dev, void *p);
+
+ #ifdef CONFIG_PM
+
+ static int velocity_suspend(struct pci_dev *pdev, pm_message_t state);
+ static int velocity_resume(struct pci_dev *pdev);
+
+-static DEFINE_SPINLOCK(velocity_dev_list_lock);
+-static LIST_HEAD(velocity_dev_list);
+-
+-#endif
+-
+-#if defined(CONFIG_PM) && defined(CONFIG_INET)
+-
+ static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr);
+
+ static struct notifier_block velocity_inetaddr_notifier = {
+ .notifier_call = velocity_netdev_event,
+ };
+
++static DEFINE_SPINLOCK(velocity_dev_list_lock);
++static LIST_HEAD(velocity_dev_list);
++
+ static void velocity_register_notifier(void)
+ {
+ register_inetaddr_notifier(&velocity_inetaddr_notifier);
+@@ -430,12 +325,12 @@
+ unregister_inetaddr_notifier(&velocity_inetaddr_notifier);
+ }
+
+-#else
++#else /* CONFIG_PM */
+
+ #define velocity_register_notifier() do {} while (0)
+ #define velocity_unregister_notifier() do {} while (0)
+
+-#endif
++#endif /* !CONFIG_PM */
+
+ /*
+ * Internal board variants. At the moment we have only one
+@@ -466,7 +361,7 @@
+ * a pointer a static string valid while the driver is loaded.
+ */
+
+-static const char __devinit *get_chip_name(enum chip_type chip_id)
++static char __devinit *get_chip_name(enum chip_type chip_id)
+ {
+ int i;
+ for (i = 0; chip_info_table[i].name != NULL; i++)
+@@ -557,11 +452,11 @@
+ if (val == -1)
+ *opt |= (def ? flag : 0);
+ else if (val < 0 || val > 1) {
+- printk(KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (0-1)\n",
++ printk(KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (0-1)\n",
+ devname, name);
+ *opt |= (def ? flag : 0);
+ } else {
+- printk(KERN_INFO "%s: set parameter %s to %s\n",
++ printk(KERN_INFO "%s: set parameter %s to %s\n",
+ devname, name, val ? "TRUE" : "FALSE");
+ *opt |= (val ? flag : 0);
+ }
+@@ -581,10 +476,12 @@
+ {
+
+ velocity_set_int_opt(&opts->rx_thresh, rx_thresh[index], RX_THRESH_MIN, RX_THRESH_MAX, RX_THRESH_DEF, "rx_thresh", devname);
+- velocity_set_int_opt(&opts->DMA_length, DMA_length[index], DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_DEF, "DMA_length", devname);
++ velocity_set_int_opt(&opts->DMA_length_100M, DMA_length_100M[index], DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_100M_DEF, "DMA_length 100M", devname);
++ velocity_set_int_opt(&opts->DMA_length_1000M, DMA_length_1000M[index], DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_1000M_DEF, "DMA_length 1000M", devname);
+ velocity_set_int_opt(&opts->numrx, RxDescriptors[index], RX_DESC_MIN, RX_DESC_MAX, RX_DESC_DEF, "RxDescriptors", devname);
+ velocity_set_int_opt(&opts->numtx, TxDescriptors[index], TX_DESC_MIN, TX_DESC_MAX, TX_DESC_DEF, "TxDescriptors", devname);
+-
++ velocity_set_int_opt(&opts->vid, VID_setting[index], VLAN_ID_MIN, VLAN_ID_MAX, VLAN_ID_DEF, "VID_setting", devname);
++ velocity_set_bool_opt(&opts->flags, enable_tagging[index], TAGGING_DEF, VELOCITY_FLAGS_TAGGING, "enable_tagging", devname);
+ velocity_set_bool_opt(&opts->flags, txcsum_offload[index], TX_CSUM_DEF, VELOCITY_FLAGS_TX_CSUM, "txcsum_offload", devname);
+ velocity_set_int_opt(&opts->flow_cntl, flow_control[index], FLOW_CNTL_MIN, FLOW_CNTL_MAX, FLOW_CNTL_DEF, "flow_control", devname);
+ velocity_set_bool_opt(&opts->flags, IP_byte_align[index], IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN, "IP_byte_align", devname);
+@@ -606,61 +503,35 @@
+ static void velocity_init_cam_filter(struct velocity_info *vptr)
+ {
+ struct mac_regs __iomem * regs = vptr->mac_regs;
+- unsigned short vid;
+
+ /* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */
+ WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, ®s->MCFG);
+ WORD_REG_BITS_ON(MCFG_VIDFR, ®s->MCFG);
+
+ /* Disable all CAMs */
+- memset(vptr->vCAMmask, 0, sizeof(u8) * 8);
+- memset(vptr->mCAMmask, 0, sizeof(u8) * 8);
+- mac_set_vlan_cam_mask(regs, vptr->vCAMmask);
+- mac_set_cam_mask(regs, vptr->mCAMmask);
++ memset(vptr->vCAMmask, 0, VCAM_SIZE / 8);
++ memset(vptr->mCAMmask, 0, MCAM_SIZE / 8);
++ mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM);
++ mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM);
+
+ /* Enable first VCAM */
+- if (vptr->vlgrp) {
+- for (vid = 0; vid < VLAN_VID_MASK; vid++) {
+- if (vlan_group_get_device(vptr->vlgrp, vid)) {
+- /* If Tagging option is enabled and
+- VLAN ID is not zero, then
+- turn on MCFG_RTGOPT also */
+- if (vid != 0)
+- WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG);
++ if (vptr->flags & VELOCITY_FLAGS_TAGGING) {
++ /* If Tagging option is enabled and VLAN ID is not zero, then
++ turn on MCFG_RTGOPT also */
++ if (vptr->options.vid != 0)
++ WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG);
+
+- mac_set_vlan_cam(regs, 0, (u8 *) &vid);
+- }
+- }
++ mac_set_cam(regs, 0, (u8 *) & (vptr->options.vid), VELOCITY_VLAN_ID_CAM);
+ vptr->vCAMmask[0] |= 1;
+- mac_set_vlan_cam_mask(regs, vptr->vCAMmask);
++ mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM);
+ } else {
+ u16 temp = 0;
+- mac_set_vlan_cam(regs, 0, (u8 *) &temp);
++ mac_set_cam(regs, 0, (u8 *) &temp, VELOCITY_VLAN_ID_CAM);
+ temp = 1;
+- mac_set_vlan_cam_mask(regs, (u8 *) &temp);
++ mac_set_cam_mask(regs, (u8 *) &temp, VELOCITY_VLAN_ID_CAM);
+ }
+ }
+
+-static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
+-{
+- struct velocity_info *vptr = netdev_priv(dev);
+-
+- spin_lock_irq(&vptr->lock);
+- velocity_init_cam_filter(vptr);
+- spin_unlock_irq(&vptr->lock);
+-}
+-
+-static void velocity_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
+-{
+- struct velocity_info *vptr = netdev_priv(dev);
+-
+- spin_lock_irq(&vptr->lock);
+- vlan_group_set_device(vptr->vlgrp, vid, NULL);
+- velocity_init_cam_filter(vptr);
+- spin_unlock_irq(&vptr->lock);
+-}
+-
+-
+ /**
+ * velocity_rx_reset - handle a receive reset
+ * @vptr: velocity we are resetting
+@@ -690,6 +561,61 @@
+ }
+
+ /**
++ * Cause the eeprom to be read into the chip.
++ * @returns Zero on success
++ */
++int mac_eeprom_reload(struct mac_regs __iomem *regs)
++{
++#if 0
++{
++int i;
++unsigned char __iomem *ptr = (unsigned char __iomem *)regs;
++printk("Before eeprom load regs:\n");
++printk("0x00:\t");
++for (i=0; i <= MAC_REG_BYTEMSK3_3; ++i) {
++ printk("0x%02x\t", readb(&(ptr[i])));
++ if (!((i+1) % 8)) {
++ printk("\n0x%02x:\t", i+1);
++ }
++}
++}
++#endif
++ BYTE_REG_BITS_ON(EECSR_RELOAD, &((regs)->EECSR));
++ mdelay(100);
++#if 0
++{
++int i;
++unsigned char __iomem *ptr = (unsigned char __iomem *)regs;
++printk("\nAfter eeprom load regs:\n");
++printk("0x00:\t");
++for (i=0; i <= MAC_REG_BYTEMSK3_3; ++i) {
++ printk("0x%02x\t", readb(&(ptr[i])));
++ if (!((i+1) % 8)) {
++ printk("\n0x%02x:\t", i+1);
++ }
++}
++}
++#endif
++ return BYTE_REG_BITS_IS_ON(EECSR_RELOAD, &((regs)->EECSR));
++}
++
++
++static inline void mac_set_dma_length(struct velocity_info *vptr)
++{
++ struct mac_regs __iomem *regs = vptr->mac_regs;
++ int burst_size = vptr->options.DMA_length_100M;
++
++ if (!(vptr->mii_status & VELOCITY_LINK_FAIL) &&
++ (vptr->options.spd_dpx == SPD_DPX_AUTO) &&
++ (vptr->mii_status & VELOCITY_SPEED_1000)) {
++ burst_size = vptr->options.DMA_length_1000M;
++ }
++
++//printk("Setting fifo burst size to %d\n", burst_size);
++ BYTE_REG_BITS_SET(burst_size, 0x07, &(regs->DCFG));
++}
++
++/**
+ * velocity_init_registers - initialise MAC registers
+ * @vptr: velocity to init
+ * @type: type of initialisation (hot or cold)
+@@ -698,7 +624,7 @@
+ * hardware.
+ */
+
+-static void velocity_init_registers(struct velocity_info *vptr,
++static void velocity_init_registers(struct velocity_info *vptr,
+ enum velocity_init_type type)
+ {
+ struct mac_regs __iomem * regs = vptr->mac_regs;
+@@ -726,11 +652,12 @@
+ netif_wake_queue(vptr->dev);
+ }
+
++ mac_set_dma_length(vptr);
+ enable_flow_control_ability(vptr);
+
+ mac_clear_isr(regs);
+ writel(CR0_STOP, ®s->CR0Clr);
+- writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT),
++ writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT),
+ ®s->CR0Set);
+
+ break;
+@@ -743,16 +670,27 @@
+ velocity_soft_reset(vptr);
+ mdelay(5);
+
++#ifdef LOAD_FROM_EEPROM
+ mac_eeprom_reload(regs);
++#endif // LOAD_FROM_EEPROM
++
+ for (i = 0; i < 6; i++) {
+ writeb(vptr->dev->dev_addr[i], &(regs->PAR[i]));
+ }
++
++ // Initialise the hardware's record of our primary MAC address
++ hw_set_mac_address(vptr, vptr->dev->dev_addr);
++
++ /*
++ * Set LED Select bits to CASE_1
++ */
++ BYTE_REG_BITS_SET(CFGA_PHYLEDS1, (CFGA_PHYLEDS1 | CFGA_PHYLEDS0), &(regs->CFGA));
++
+ /*
+ * clear Pre_ACPI bit.
+ */
+ BYTE_REG_BITS_OFF(CFGA_PACPI, &(regs->CFGA));
+ mac_set_rx_thresh(regs, vptr->options.rx_thresh);
+- mac_set_dma_length(regs, vptr->options.DMA_length);
+
+ writeb(WOLCFG_SAM | WOLCFG_SAB, ®s->WOLCFGSet);
+ /*
+@@ -805,7 +743,9 @@
+ netif_wake_queue(vptr->dev);
+ }
+
++ mac_set_dma_length(vptr);
+ enable_flow_control_ability(vptr);
++
+ mac_hw_mibs_init(regs);
+ mac_write_int_mask(vptr->int_mask, regs);
+ mac_clear_isr(regs);
+@@ -866,7 +806,7 @@
+ * can support more than MAX_UNITS.
+ */
+ if (velocity_nics >= MAX_UNITS) {
+- dev_notice(&pdev->dev, "already found %d NICs.\n",
++ dev_notice(&pdev->dev, "already found %d NICs.\n",
+ velocity_nics);
+ return -ENODEV;
+ }
+@@ -876,15 +816,16 @@
+ dev_err(&pdev->dev, "allocate net device failed.\n");
+ goto out;
+ }
+-
++
+ /* Chain it all together */
+-
++
++ SET_MODULE_OWNER(dev);
+ SET_NETDEV_DEV(dev, &pdev->dev);
+ vptr = netdev_priv(dev);
+
+
+ if (first) {
+- printk(KERN_INFO "%s Ver. %s\n",
++ printk(KERN_INFO "%s Ver. %s\n",
+ VELOCITY_FULL_DRV_NAM, VELOCITY_VERSION);
+ printk(KERN_INFO "Copyright (c) 2002, 2003 VIA Networking Technologies, Inc.\n");
+ printk(KERN_INFO "Copyright (c) 2004 Red Hat Inc.\n");
+@@ -898,7 +839,7 @@
+ dev->irq = pdev->irq;
+
+ ret = pci_enable_device(pdev);
+- if (ret < 0)
++ if (ret < 0)
+ goto err_free_dev;
+
+ ret = velocity_get_pci_info(vptr, pdev);
+@@ -928,19 +869,32 @@
+ for (i = 0; i < 6; i++)
+ dev->dev_addr[i] = readb(®s->PAR[i]);
+
++ // Tell the kernel of our MAC address
++ if ((mac_hi==0)&&(mac_lo==0)) {
++ memcpy(dev->dev_addr, DEFAULT_MAC_ADDRESS, dev->addr_len);
++ } else {
++ int i;
++ for (i=0; i < dev->addr_len; i++) {
++ if (i < sizeof(u32)) {
++ dev->dev_addr[i] = ((mac_hi >> (((sizeof(u32)-1)-i)*8)) & 0xff);
++ } else {
++ dev->dev_addr[i] = ((mac_lo >> (((sizeof(u32)+1)-i)*8)) & 0xff);
++ }
++ }
++ }
+
+ velocity_get_options(&vptr->options, velocity_nics, dev->name);
+
+- /*
++ /*
+ * Mask out the options cannot be set to the chip
+ */
+-
++
+ vptr->options.flags &= info->flags;
+
+ /*
+ * Enable the chip specified capbilities
+ */
+-
++
+ vptr->flags = vptr->options.flags | (info->flags & 0xFF000000UL);
+
+ vptr->wol_opts = vptr->options.wol_opts;
+@@ -957,17 +911,14 @@
+ dev->do_ioctl = velocity_ioctl;
+ dev->ethtool_ops = &velocity_ethtool_ops;
+ dev->change_mtu = velocity_change_mtu;
+-
+- dev->vlan_rx_add_vid = velocity_vlan_rx_add_vid;
+- dev->vlan_rx_kill_vid = velocity_vlan_rx_kill_vid;
+-
++ dev->set_mac_address = set_mac_address;
+ #ifdef VELOCITY_ZERO_COPY_SUPPORT
+ dev->features |= NETIF_F_SG;
+ #endif
+- dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER;
+
+- if (vptr->flags & VELOCITY_FLAGS_TX_CSUM)
++ if (vptr->flags & VELOCITY_FLAGS_TX_CSUM) {
+ dev->features |= NETIF_F_IP_CSUM;
++ }
+
+ ret = register_netdev(dev);
+ if (ret < 0)
+@@ -978,9 +929,9 @@
+
+ velocity_print_info(vptr);
+ pci_set_drvdata(pdev, dev);
+-
++
+ /* and leave the chip powered down */
+-
++
+ pci_set_power_state(pdev, PCI_D3hot);
+ #ifdef CONFIG_PM
+ {
+@@ -1019,9 +970,9 @@
+ struct net_device *dev = vptr->dev;
+
+ printk(KERN_INFO "%s: %s\n", dev->name, get_chip_name(vptr->chip_id));
+- printk(KERN_INFO "%s: Ethernet Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
+- dev->name,
+- dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
++ printk(KERN_INFO "%s: Ethernet Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
++ dev->name,
++ dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+ dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+ }
+
+@@ -1044,7 +995,6 @@
+ vptr->pdev = pdev;
+ vptr->chip_id = info->chip_id;
+ vptr->num_txq = info->txqueue;
+- vptr->multicast_limit = MCAM_SIZE;
+ spin_lock_init(&vptr->lock);
+ INIT_LIST_HEAD(&vptr->list);
+ }
+@@ -1061,12 +1011,12 @@
+ static int __devinit velocity_get_pci_info(struct velocity_info *vptr, struct pci_dev *pdev)
+ {
+ vptr->rev_id = pdev->revision;
+-
++
+ pci_set_master(pdev);
+
+ vptr->ioaddr = pci_resource_start(pdev, 0);
+ vptr->memaddr = pci_resource_start(pdev, 1);
+-
++
+ if (!(pci_resource_flags(pdev, 0) & IORESOURCE_IO)) {
+ dev_err(&pdev->dev,
+ "region #0 is not an I/O resource, aborting.\n");
+@@ -1105,20 +1055,25 @@
+ u8 *pool;
+
+ /*
+- * Allocate all RD/TD rings a single pool
++ * Allocate all RD/TD rings a single pool
+ */
+-
+- psize = vptr->options.numrx * sizeof(struct rx_desc) +
++
++ psize = vptr->options.numrx * sizeof(struct rx_desc) +
+ vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq;
+
+ /*
+ * pci_alloc_consistent() fulfills the requirement for 64 bytes
+ * alignment
+ */
+- pool = pci_alloc_consistent(vptr->pdev, psize, &pool_dma);
++#ifdef VELOCITY_DESC_IN_SRAM
++ pool = (u8*)GMAC_DESC_ALLOC_START;
++ pool_dma = GMAC_DESC_ALLOC_START_PA;
++#else
++ pool = pci_alloc_consistent(vptr->pdev, psize, &pool_dma);
++#endif // VELOCITY_DESC_IN_SRAM
+
+ if (pool == NULL) {
+- printk(KERN_ERR "%s : DMA memory allocation failed.\n",
++ printk(KERN_ERR "%s : DMA memory allocation failed.\n",
+ vptr->dev->name);
+ return -ENOMEM;
+ }
+@@ -1130,13 +1085,15 @@
+ vptr->rd_pool_dma = pool_dma;
+
+ tsize = vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq;
+- vptr->tx_bufs = pci_alloc_consistent(vptr->pdev, tsize,
++ vptr->tx_bufs = pci_alloc_consistent(vptr->pdev, tsize,
+ &vptr->tx_bufs_dma);
+
+ if (vptr->tx_bufs == NULL) {
+- printk(KERN_ERR "%s: DMA memory allocation failed.\n",
++ printk(KERN_ERR "%s: DMA memory allocation failed.\n",
+ vptr->dev->name);
++#ifndef VELOCITY_DESC_IN_SRAM
+ pci_free_consistent(vptr->pdev, psize, pool, pool_dma);
++#endif // !VELOCITY_DESC_IN_SRAM
+ return -ENOMEM;
+ }
+
+@@ -1167,10 +1124,12 @@
+ {
+ int size;
+
+- size = vptr->options.numrx * sizeof(struct rx_desc) +
++ size = vptr->options.numrx * sizeof(struct rx_desc) +
+ vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq;
+
++#ifndef VELOCITY_DESC_IN_SRAM
+ pci_free_consistent(vptr->pdev, size, vptr->rd_ring, vptr->rd_pool_dma);
++#endif // !VELOCITY_DESC_IN_SRAM
+
+ size = vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq;
+
+@@ -1219,7 +1178,7 @@
+ break;
+ }
+ done++;
+- dirty = (dirty < vptr->options.numrx - 1) ? dirty + 1 : 0;
++ dirty = (dirty < vptr->options.numrx - 1) ? dirty + 1 : 0;
+ } while (dirty != vptr->rd_curr);
+
+ if (done) {
+@@ -1241,15 +1200,14 @@
+
+ static int velocity_init_rd_ring(struct velocity_info *vptr)
+ {
+- int ret;
+- int mtu = vptr->dev->mtu;
+-
+- vptr->rx_buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32;
++ int ret = -ENOMEM;
++ unsigned int rsize = sizeof(struct velocity_rd_info) *
++ vptr->options.numrx;
+
+- vptr->rd_info = kcalloc(vptr->options.numrx,
+- sizeof(struct velocity_rd_info), GFP_KERNEL);
+- if (!vptr->rd_info)
+- return -ENOMEM;
++ vptr->rd_info = kmalloc(rsize, GFP_KERNEL);
++ if(vptr->rd_info == NULL)
++ goto out;
++ memset(vptr->rd_info, 0, rsize);
+
+ vptr->rd_filled = vptr->rd_dirty = vptr->rd_curr = 0;
+
+@@ -1259,7 +1217,7 @@
+ "%s: failed to allocate RX buffer.\n", vptr->dev->name);
+ velocity_free_rd_ring(vptr);
+ }
+-
++out:
+ return ret;
+ }
+
+@@ -1306,26 +1264,28 @@
+ * Returns zero on success or a negative posix errno code for
+ * failure.
+ */
+-
++
+ static int velocity_init_td_ring(struct velocity_info *vptr)
+ {
+ int i, j;
+ dma_addr_t curr;
+ struct tx_desc *td;
+ struct velocity_td_info *td_info;
++ unsigned int tsize = sizeof(struct velocity_td_info) *
++ vptr->options.numtx;
+
+ /* Init the TD ring entries */
+ for (j = 0; j < vptr->num_txq; j++) {
+ curr = vptr->td_pool_dma[j];
+
+- vptr->td_infos[j] = kcalloc(vptr->options.numtx,
+- sizeof(struct velocity_td_info),
+- GFP_KERNEL);
+- if (!vptr->td_infos[j]) {
++ vptr->td_infos[j] = kmalloc(tsize, GFP_KERNEL);
++ if(vptr->td_infos[j] == NULL)
++ {
+ while(--j >= 0)
+ kfree(vptr->td_infos[j]);
+ return -ENOMEM;
+ }
++ memset(vptr->td_infos[j], 0, tsize);
+
+ for (i = 0; i < vptr->options.numtx; i++, curr += sizeof(struct tx_desc)) {
+ td = &(vptr->td_rings[j][i]);
+@@ -1340,31 +1300,12 @@
+ return 0;
+ }
+
+-/*
+- * FIXME: could we merge this with velocity_free_tx_buf ?
+- */
+-
+-static void velocity_free_td_ring_entry(struct velocity_info *vptr,
+- int q, int n)
++static void velocity_free_td_ring_entry(struct velocity_info *vptr, int q, int n)
+ {
+ struct velocity_td_info * td_info = &(vptr->td_infos[q][n]);
+- int i;
+-
+- if (td_info == NULL)
+- return;
+
+- if (td_info->skb) {
+- for (i = 0; i < td_info->nskb_dma; i++)
+- {
+- if (td_info->skb_dma[i]) {
+- pci_unmap_single(vptr->pdev, td_info->skb_dma[i],
+- td_info->skb->len, PCI_DMA_TODEVICE);
+- td_info->skb_dma[i] = (dma_addr_t) NULL;
+- }
+- }
+- dev_kfree_skb(td_info->skb);
+- td_info->skb = NULL;
+- }
++ if (td_info && td_info->skb)
++ velocity_free_tx_buf(vptr, td_info);
+ }
+
+ /**
+@@ -1374,17 +1315,16 @@
+ * Free up the transmit ring for this particular velocity adapter.
+ * We free the ring contents but not the ring itself.
+ */
+-
++
+ static void velocity_free_td_ring(struct velocity_info *vptr)
+ {
+ int i, j;
+
+- for (j = 0; j < vptr->num_txq; j++) {
++ for (j=0; j < vptr->num_txq; j++) {
+ if (vptr->td_infos[j] == NULL)
+ continue;
+- for (i = 0; i < vptr->options.numtx; i++) {
++ for (i=0; i < vptr->options.numtx; i++) {
+ velocity_free_td_ring_entry(vptr, j, i);
+-
+ }
+ kfree(vptr->td_infos[j]);
+ vptr->td_infos[j] = NULL;
+@@ -1400,14 +1340,14 @@
+ * any received packets from the receive queue. Hand the ring
+ * slots back to the adapter for reuse.
+ */
+-
++
+ static int velocity_rx_srv(struct velocity_info *vptr, int status)
+ {
+ struct net_device_stats *stats = &vptr->stats;
+ int rd_curr = vptr->rd_curr;
+ int works = 0;
+
+- do {
++ while (1) {
+ struct rx_desc *rd = vptr->rd_ring + rd_curr;
+
+ if (!vptr->rd_info[rd_curr].skb)
+@@ -1422,15 +1362,19 @@
+ * Don't drop CE or RL error frame although RXOK is off
+ */
+ if ((rd->rdesc0.RSR & RSR_RXOK) || (!(rd->rdesc0.RSR & RSR_RXOK) && (rd->rdesc0.RSR & (RSR_CE | RSR_RL)))) {
+- if (velocity_receive_frame(vptr, rd_curr) < 0)
+- stats->rx_dropped++;
++ if (velocity_receive_frame(vptr, rd_curr) < 0) {
++ /* velocity_receive_frame() has already recorded the type of */
++ /* so just inc overall rx error count */
++ ++stats->rx_errors;
++ }
+ } else {
+ if (rd->rdesc0.RSR & RSR_CRC)
+ stats->rx_crc_errors++;
+ if (rd->rdesc0.RSR & RSR_FAE)
+ stats->rx_frame_errors++;
+
+- stats->rx_dropped++;
++ /* We've had an error of some sort so inc. overall rx error count */
++ ++stats->rx_errors;
+ }
+
+ rd->inten = 1;
+@@ -1440,7 +1384,9 @@
+ rd_curr++;
+ if (rd_curr >= vptr->options.numrx)
+ rd_curr = 0;
+- } while (++works <= 15);
++
++ ++works;
++ }
+
+ vptr->rd_curr = rd_curr;
+
+@@ -1461,14 +1407,14 @@
+ * Process the status bits for the received packet and determine
+ * if the checksum was computed and verified by the hardware
+ */
+-
++
+ static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb)
+ {
+ skb->ip_summed = CHECKSUM_NONE;
+
+ if (rd->rdesc1.CSM & CSM_IPKT) {
+ if (rd->rdesc1.CSM & CSM_IPOK) {
+- if ((rd->rdesc1.CSM & CSM_TCPKT) ||
++ if ((rd->rdesc1.CSM & CSM_TCPKT) ||
+ (rd->rdesc1.CSM & CSM_UDPKT)) {
+ if (!(rd->rdesc1.CSM & CSM_TUPOK)) {
+ return;
+@@ -1499,20 +1445,19 @@
+ if (pkt_size < rx_copybreak) {
+ struct sk_buff *new_skb;
+
+- new_skb = dev_alloc_skb(pkt_size + 2);
++ /* Always realign IP header to quad boundary if copying anyway */
++ new_skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
+ if (new_skb) {
+ new_skb->dev = vptr->dev;
+ new_skb->ip_summed = rx_skb[0]->ip_summed;
+
+- if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN)
+- skb_reserve(new_skb, 2);
++ skb_reserve(new_skb, NET_IP_ALIGN);
+
+- skb_copy_from_linear_data(rx_skb[0], new_skb->data,
+- pkt_size);
++ memcpy(new_skb->data, rx_skb[0]->data, pkt_size);
+ *rx_skb = new_skb;
+ ret = 0;
+ }
+-
++
+ }
+ return ret;
+ }
+@@ -1529,13 +1474,10 @@
+ static inline void velocity_iph_realign(struct velocity_info *vptr,
+ struct sk_buff *skb, int pkt_size)
+ {
+- /* FIXME - memmove ? */
+ if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN) {
+- int i;
+-
+- for (i = pkt_size; i >= 0; i--)
+- *(skb->data + i + 2) = *(skb->data + i);
+- skb_reserve(skb, 2);
++//printk("velocity_iph_realign()\n");
++ memmove(skb->data + NET_IP_ALIGN, skb->data, pkt_size);
++ skb_reserve(skb, NET_IP_ALIGN);
+ }
+ }
+
+@@ -1543,11 +1485,11 @@
+ * velocity_receive_frame - received packet processor
+ * @vptr: velocity we are handling
+ * @idx: ring index
+- *
++ *
+ * A packet has arrived. We process the packet and if appropriate
+ * pass the frame up the network stack
+ */
+-
++
+ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
+ {
+ void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int);
+@@ -1558,7 +1500,7 @@
+ struct sk_buff *skb;
+
+ if (rd->rdesc0.RSR & (RSR_STP | RSR_EDP)) {
+- VELOCITY_PRT(MSG_LEVEL_VERBOSE, KERN_ERR " %s : the received frame span multple RDs.\n", vptr->dev->name);
++ VELOCITY_PRT(MSG_LEVEL_VERBOSE, KERN_ERR " %s : the received frame spans multple RDs.\n", vptr->dev->name);
+ stats->rx_length_errors++;
+ return -EINVAL;
+ }
+@@ -1567,6 +1509,7 @@
+ vptr->stats.multicast++;
+
+ skb = rd_info->skb;
++ skb->dev = vptr->dev;
+
+ pci_dma_sync_single_for_cpu(vptr->pdev, rd_info->skb_dma,
+ vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
+@@ -1574,7 +1517,6 @@
+ /*
+ * Drop frame not meeting IEEE 802.3
+ */
+-
+ if (vptr->flags & VELOCITY_FLAGS_VAL_PKT_LEN) {
+ if (rd->rdesc0.RSR & RSR_RL) {
+ stats->rx_length_errors++;
+@@ -1596,9 +1538,11 @@
+ PCI_DMA_FROMDEVICE);
+
+ skb_put(skb, pkt_len - 4);
+- skb->protocol = eth_type_trans(skb, vptr->dev);
++ skb->protocol = eth_type_trans(skb, skb->dev);
+
+ stats->rx_bytes += pkt_len;
++ ++stats->rx_packets;
++
+ netif_rx(skb);
+
+ return 0;
+@@ -1614,7 +1558,7 @@
+ * requires *64* byte alignment of the buffer which makes life
+ * less fun than would be ideal.
+ */
+-
++
+ static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
+ {
+ struct rx_desc *rd = &(vptr->rd_ring[idx]);
+@@ -1631,11 +1575,10 @@
+ skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->data & 63);
+ rd_info->skb->dev = vptr->dev;
+ rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
+-
++
+ /*
+ * Fill in the descriptor to match
+- */
+-
++ */
+ *((u32 *) & (rd->rdesc0)) = 0;
+ rd->len = cpu_to_le32(vptr->rx_buf_sz);
+ rd->inten = 1;
+@@ -1651,9 +1594,9 @@
+ *
+ * Scan the queues looking for transmitted packets that
+ * we can complete and clean up. Update any statistics as
+- * necessary/
++ * neccessary/
+ */
+-
++
+ static int velocity_tx_srv(struct velocity_info *vptr, u32 status)
+ {
+ struct tx_desc *td;
+@@ -1665,7 +1608,7 @@
+ struct net_device_stats *stats = &vptr->stats;
+
+ for (qnum = 0; qnum < vptr->num_txq; qnum++) {
+- for (idx = vptr->td_tail[qnum]; vptr->td_used[qnum] > 0;
++ for (idx = vptr->td_tail[qnum]; vptr->td_used[qnum] > 0;
+ idx = (idx + 1) % vptr->options.numtx) {
+
+ /*
+@@ -1677,8 +1620,7 @@
+ if (td->tdesc0.owner == OWNED_BY_NIC)
+ break;
+
+- if ((works++ > 15))
+- break;
++ ++works;
+
+ if (td->tdesc0.TSR & TSR0_TERR) {
+ stats->tx_errors++;
+@@ -1730,7 +1672,7 @@
+ if (vptr->mii_status & VELOCITY_LINK_FAIL) {
+ VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: failed to detect cable link\n", vptr->dev->name);
+ } else if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
+- VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link auto-negotiation", vptr->dev->name);
++ VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link autonegation", vptr->dev->name);
+
+ if (vptr->mii_status & VELOCITY_SPEED_1000)
+ VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps");
+@@ -1765,17 +1707,48 @@
+ }
+
+ /**
++ * velocity_update_hw_mibs - fetch MIB counters from chip
++ * @vptr: velocity to update
++ *
++ * The velocity hardware keeps certain counters in the hardware
++ * side. We need to read these when the user asks for statistics
++ * or when they overflow (causing an interrupt). The read of the
++ * statistic clears it, so we keep running master counters in user
++ * space.
++ */
++static void velocity_update_hw_mibs(struct velocity_info *vptr)
++{
++ int i;
++
++ /* Toggle flush to update MIB SRAM from fast counters */
++ BYTE_REG_BITS_ON(MIBCR_MIBFLSH, &(vptr->mac_regs->MIBCR));
++ while (BYTE_REG_BITS_IS_ON(MIBCR_MIBFLSH, &(vptr->mac_regs->MIBCR)));
++
++ /* Toggle MIBINI to begin MIB SRAM read out. Datasheet says always reads as
++ zero, so no point polling for it to return to zero after setting */
++ BYTE_REG_BITS_ON(MIBCR_MPTRINI, &(vptr->mac_regs->MIBCR));
++
++ for (i=0; i < HW_MIB_SIZE; ++i) {
++ /* Read MIB, preserving both index and count */
++ u32 mib = readl(&(vptr->mac_regs->MIBData));
++ int index = (mib & 0xff000000) >> 24;
++ u32 count = mib & 0x00ffffff;
++ vptr->mib_counter[index] += count;
++ }
++}
++
++/**
+ * velocity_error - handle error from controller
+ * @vptr: velocity
+ * @status: card status
+ *
+ * Process an error report from the hardware and attempt to recover
+- * the card itself. At the moment we cannot recover from some
++ * the card itself. At the moment we cannot recover from some
+ * theoretically impossible errors but this could be fixed using
+ * the pci_device_failed logic to bounce the hardware
+ *
+ */
+-
++
+ static void velocity_error(struct velocity_info *vptr, int status)
+ {
+
+@@ -1786,7 +1759,7 @@
+ BYTE_REG_BITS_ON(TXESR_TDSTR, ®s->TXESR);
+ writew(TRDCSR_RUN, ®s->TDCSRClr);
+ netif_stop_queue(vptr->dev);
+-
++
+ /* FIXME: port over the pci_device_failed code and use it
+ here */
+ }
+@@ -1799,7 +1772,7 @@
+ vptr->mii_status = check_connection_type(regs);
+
+ /*
+- * If it is a 3119, disable frame bursting in
++ * If it is a 3119, disable frame bursting in
+ * halfduplex mode and enable it in fullduplex
+ * mode
+ */
+@@ -1832,13 +1805,15 @@
+ }
+
+ velocity_print_link_status(vptr);
++
++ mac_set_dma_length(vptr);
+ enable_flow_control_ability(vptr);
+
+ /*
+- * Re-enable auto-polling because SRCI will disable
++ * Re-enable auto-polling because SRCI will disable
+ * auto-polling
+ */
+-
++
+ enable_mii_autopoll(regs);
+
+ if (vptr->mii_status & VELOCITY_LINK_FAIL)
+@@ -1846,9 +1821,11 @@
+ else
+ netif_wake_queue(vptr->dev);
+
+- };
++ }
++
+ if (status & ISR_MIBFI)
+ velocity_update_hw_mibs(vptr);
++
+ if (status & ISR_LSTEI)
+ mac_rx_queue_wake(vptr->mac_regs);
+ }
+@@ -1858,29 +1835,35 @@
+ * @vptr: velocity
+ * @tdinfo: buffer
+ *
+- * Release an transmit buffer. If the buffer was preallocated then
++ * Release a transmit buffer. If the buffer was preallocated then
+ * recycle it, if not then unmap the buffer.
+ */
+-
+ static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *tdinfo)
+ {
+ struct sk_buff *skb = tdinfo->skb;
+ int i;
+
+- /*
+- * Don't unmap the pre-allocated tx_bufs
+- */
+- if (tdinfo->skb_dma && (tdinfo->skb_dma[0] != tdinfo->buf_dma)) {
++ /* Don't unmap the pre-allocated tx_bufs */
++ if (tdinfo->skb_dma[0] && (tdinfo->skb_dma[0] != tdinfo->buf_dma)) {
++ if (tdinfo->nskb_dma == 1) {
++ /* Either no fragments originally, or was linearized because too
++ many fragments */
++ pci_unmap_single(vptr->pdev, tdinfo->skb_dma[0], skb->len, PCI_DMA_TODEVICE);
++ tdinfo->skb_dma[0] = 0;
++ } else {
++ /* Unmap the head buffer */
++ pci_unmap_single(vptr->pdev, tdinfo->skb_dma[0], skb_headlen(skb), PCI_DMA_TODEVICE);
++ tdinfo->skb_dma[0] = 0;
+
+- for (i = 0; i < tdinfo->nskb_dma; i++) {
+-#ifdef VELOCITY_ZERO_COPY_SUPPORT
+- pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], td->tdesc1.len, PCI_DMA_TODEVICE);
+-#else
+- pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], skb->len, PCI_DMA_TODEVICE);
+-#endif
+- tdinfo->skb_dma[i] = 0;
+- }
++ /* Unmap the fragment buffers */
++ for (i=0; i < tdinfo->nskb_dma-1; ++i) {
++ pci_unmap_page(vptr->pdev, tdinfo->skb_dma[i+1],
++ skb_shinfo(skb)->frags[i].size, PCI_DMA_TODEVICE);
++ tdinfo->skb_dma[i+1] = 0;
++ }
++ }
+ }
++
+ dev_kfree_skb_irq(skb);
+ tdinfo->skb = NULL;
+ }
+@@ -1895,12 +1878,14 @@
+ * All the ring allocation and set up is done on open for this
+ * adapter to minimise memory usage when inactive
+ */
+-
++
+ static int velocity_open(struct net_device *dev)
+ {
+ struct velocity_info *vptr = netdev_priv(dev);
+ int ret;
+
++ vptr->rx_buf_sz = dev->mtu + NET_IP_ALIGN + EXTRA_RX_SKB_SPACE;
++
+ ret = velocity_init_rings(vptr);
+ if (ret < 0)
+ goto out;
+@@ -1912,13 +1897,13 @@
+ ret = velocity_init_td_ring(vptr);
+ if (ret < 0)
+ goto err_free_rd_ring;
+-
+- /* Ensure chip is running */
++
++ /* Ensure chip is running */
+ pci_set_power_state(vptr->pdev, PCI_D0);
+-
++
+ velocity_init_registers(vptr, VELOCITY_INIT_COLD);
+
+- ret = request_irq(vptr->pdev->irq, &velocity_intr, IRQF_SHARED,
++ ret = request_irq(vptr->pdev->irq, &velocity_intr, SA_SHIRQ,
+ dev->name, dev);
+ if (ret < 0) {
+ /* Power down the chip */
+@@ -1941,7 +1926,7 @@
+ goto out;
+ }
+
+-/**
++/**
+ * velocity_change_mtu - MTU change callback
+ * @dev: network device
+ * @new_mtu: desired MTU
+@@ -1950,7 +1935,7 @@
+ * this interface. It gets called on a change by the network layer.
+ * Return zero for success or negative posix error code.
+ */
+-
++
+ static int velocity_change_mtu(struct net_device *dev, int new_mtu)
+ {
+ struct velocity_info *vptr = netdev_priv(dev);
+@@ -1959,16 +1944,11 @@
+ int ret = 0;
+
+ if ((new_mtu < VELOCITY_MIN_MTU) || new_mtu > (VELOCITY_MAX_MTU)) {
+- VELOCITY_PRT(MSG_LEVEL_ERR, KERN_NOTICE "%s: Invalid MTU.\n",
++ VELOCITY_PRT(MSG_LEVEL_ERR, KERN_NOTICE "%s: Invalid MTU.\n",
+ vptr->dev->name);
+ return -EINVAL;
+ }
+
+- if (!netif_running(dev)) {
+- dev->mtu = new_mtu;
+- return 0;
+- }
+-
+ if (new_mtu != oldmtu) {
+ spin_lock_irqsave(&vptr->lock, flags);
+
+@@ -1978,7 +1958,7 @@
+ velocity_free_td_ring(vptr);
+ velocity_free_rd_ring(vptr);
+
+- dev->mtu = new_mtu;
++ dev->mtu = new_mtu + NET_IP_ALIGN + EXTRA_RX_SKB_SPACE;
+
+ ret = velocity_init_rd_ring(vptr);
+ if (ret < 0)
+@@ -2006,7 +1986,7 @@
+ * Shuts down the internal operations of the velocity and
+ * disables interrupts, autopolling, transmit and receive
+ */
+-
++
+ static void velocity_shutdown(struct velocity_info *vptr)
+ {
+ struct mac_regs __iomem * regs = vptr->mac_regs;
+@@ -2037,10 +2017,10 @@
+ velocity_get_ip(vptr);
+ if (dev->irq != 0)
+ free_irq(dev->irq, dev);
+-
++
+ /* Power down the chip */
+ pci_set_power_state(vptr->pdev, PCI_D3hot);
+-
++
+ /* Free the resources */
+ velocity_free_td_ring(vptr);
+ velocity_free_rd_ring(vptr);
+@@ -2058,7 +2038,7 @@
+ * Called by the networ layer to request a packet is queued to
+ * the velocity. Returns zero on success.
+ */
+-
++
+ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+ struct velocity_info *vptr = netdev_priv(dev);
+@@ -2067,16 +2047,22 @@
+ struct velocity_td_info *tdinfo;
+ unsigned long flags;
+ int index;
+-
+- int pktlen = skb->len;
+-
++ int pktlen;
++printk("Tx");
+ #ifdef VELOCITY_ZERO_COPY_SUPPORT
+- if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) {
+- kfree_skb(skb);
+- return 0;
++ if (skb_shinfo(skb)->nr_frags > MAX_HW_FRAGMENTS) {
++//printk("Too many fragments (%d), linearizing\n", skb_shinfo(skb)->nr_frags);
++ if (__skb_linearize(skb, GFP_ATOMIC)) {
++//printk("Linearization failed, dropping Tx packet\n");
++ kfree_skb(skb);
++ return 0;
++ }
+ }
+ #endif
+
++ // Get packet length after any linearization has occured
++ pktlen = skb->len;
++
+ spin_lock_irqsave(&vptr->lock, flags);
+
+ index = vptr->td_curr[qnum];
+@@ -2088,19 +2074,28 @@
+ td_ptr->td_buf[0].queue = 0;
+
+ /*
+- * Pad short frames.
++ * Pad short frames.
+ */
+ if (pktlen < ETH_ZLEN) {
+- /* Cannot occur until ZC support */
++ int pad_required = ETH_ZLEN - skb->len;
++printk("Padding short Tx frame\n");
+ pktlen = ETH_ZLEN;
+- skb_copy_from_linear_data(skb, tdinfo->buf, skb->len);
+- memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
+ tdinfo->skb = skb;
+- tdinfo->skb_dma[0] = tdinfo->buf_dma;
++
++ if (skb_tailroom(skb) >= pad_required) {
++//printk("Using short frame\n");
++ tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, pktlen, PCI_DMA_TODEVICE);
++ } else {
++//printk("Copying short frame\n");
++ memcpy(tdinfo->buf, skb->data, skb->len);
++ memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
++ tdinfo->skb_dma[0] = tdinfo->buf_dma;
++ }
++
+ td_ptr->tdesc0.pktsize = pktlen;
+ td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
+ td_ptr->td_buf[0].pa_high = 0;
+- td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize;
++ td_ptr->td_buf[0].bufsize = pktlen;
+ tdinfo->nskb_dma = 1;
+ td_ptr->tdesc1.CMDZ = 2;
+ } else
+@@ -2108,41 +2103,46 @@
+ if (skb_shinfo(skb)->nr_frags > 0) {
+ int nfrags = skb_shinfo(skb)->nr_frags;
+ tdinfo->skb = skb;
+- if (nfrags > 6) {
+- skb_copy_from_linear_data(skb, tdinfo->buf, skb->len);
+- tdinfo->skb_dma[0] = tdinfo->buf_dma;
+- td_ptr->tdesc0.pktsize =
++ td_ptr->tdesc0.pktsize = pktlen;
++
++ if (nfrags > MAX_HW_FRAGMENTS) {
++//printk("Using linearized skb\n");
++ /* SKB has already been linearized above, so use direct from skb */
++ tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, pktlen, PCI_DMA_TODEVICE);
+ td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
+ td_ptr->td_buf[0].pa_high = 0;
+- td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize;
++ td_ptr->td_buf[0].bufsize = pktlen;
+ tdinfo->nskb_dma = 1;
+ td_ptr->tdesc1.CMDZ = 2;
+ } else {
+ int i = 0;
+- tdinfo->nskb_dma = 0;
+- tdinfo->skb_dma[i] = pci_map_single(vptr->pdev, skb->data, skb->len - skb->data_len, PCI_DMA_TODEVICE);
+
+- td_ptr->tdesc0.pktsize = pktlen;
++ tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, skb_headlen(skb), PCI_DMA_TODEVICE);
+
+- /* FIXME: support 48bit DMA later */
+- td_ptr->td_buf[i].pa_low = cpu_to_le32(tdinfo->skb_dma);
+- td_ptr->td_buf[i].pa_high = 0;
+- td_ptr->td_buf[i].bufsize = skb->len->skb->data_len;
++ td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
++ td_ptr->td_buf[0].pa_high = 0;
++ td_ptr->td_buf[0].bufsize = skb_headlen(skb);
+
+- for (i = 0; i < nfrags; i++) {
++ for (i=0; i < nfrags; ++i) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+- void *addr = ((void *) page_address(frag->page + frag->page_offset));
+
+- tdinfo->skb_dma[i + 1] = pci_map_single(vptr->pdev, addr, frag->size, PCI_DMA_TODEVICE);
++ tdinfo->skb_dma[i+1] = pci_map_page(vptr->pdev, frag->page, frag->page_offset, frag->size, PCI_DMA_TODEVICE);
+
+- td_ptr->td_buf[i + 1].pa_low = cpu_to_le32(tdinfo->skb_dma[i + 1]);
+- td_ptr->td_buf[i + 1].pa_high = 0;
+- td_ptr->td_buf[i + 1].bufsize = frag->size;
++ td_ptr->td_buf[i+1].pa_low = cpu_to_le32(tdinfo->skb_dma[i+1]);
++ td_ptr->td_buf[i+1].pa_high = 0;
++ td_ptr->td_buf[i+1].bufsize = frag->size;
+ }
+- tdinfo->nskb_dma = i - 1;
+- td_ptr->tdesc1.CMDZ = i;
+- }
+
++ tdinfo->nskb_dma = nfrags+1;
++ td_ptr->tdesc1.CMDZ = nfrags+2;
++
++//printk("Num frags = %d\n", nfrags);
++//printk("skb: 0x%08lx:0x%08x, %d\n", (unsigned long)skb->data, tdinfo->skb_dma[0], skb_headlen(skb));
++//for (i=0; i < nfrags; ++i) {
++// skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
++// printk("frag: 0x%08lx:0x%08x, %d\n", (unsigned long)page_address(frag->page) + frag->page_offset, tdinfo->skb_dma[i+1], frag->size);
++//}
++ }
+ } else
+ #endif
+ {
+@@ -2155,13 +2155,18 @@
+ td_ptr->tdesc0.pktsize = pktlen;
+ td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
+ td_ptr->td_buf[0].pa_high = 0;
+- td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize;
++ td_ptr->td_buf[0].bufsize = pktlen;
+ tdinfo->nskb_dma = 1;
+ td_ptr->tdesc1.CMDZ = 2;
++printk("0x%08x:%u\n", td_ptr->td_buf[0].pa_low, td_ptr->td_buf[0].bufsize);
++printk("TdInd0=0x%04hx\n", readw(&vptr->mac_regs->TDIdx[0]));
++printk("TdInd1=0x%04hx\n", readw(&vptr->mac_regs->TDIdx[1]));
++printk("TdInd2=0x%04hx\n", readw(&vptr->mac_regs->TDIdx[2]));
++printk("TdInd3=0x%04hx\n", readw(&vptr->mac_regs->TDIdx[3]));
+ }
+
+- if (vptr->vlgrp && vlan_tx_tag_present(skb)) {
+- td_ptr->tdesc1.pqinf.VID = vlan_tx_tag_get(skb);
++ if (vptr->flags & VELOCITY_FLAGS_TAGGING) {
++ td_ptr->tdesc1.pqinf.VID = (vptr->options.vid & 0xfff);
+ td_ptr->tdesc1.pqinf.priority = 0;
+ td_ptr->tdesc1.pqinf.CFI = 0;
+ td_ptr->tdesc1.TCR |= TCR0_VETAG;
+@@ -2170,21 +2175,23 @@
+ /*
+ * Handle hardware checksum
+ */
+- if ((vptr->flags & VELOCITY_FLAGS_TX_CSUM)
+- && (skb->ip_summed == CHECKSUM_PARTIAL)) {
+- const struct iphdr *ip = ip_hdr(skb);
++ if ((vptr->flags & VELOCITY_FLAGS_TX_CSUM) &&
++ (skb->ip_summed == CHECKSUM_HW)) {
++ struct iphdr *ip = skb->nh.iph;
++
+ if (ip->protocol == IPPROTO_TCP)
+ td_ptr->tdesc1.TCR |= TCR0_TCPCK;
+ else if (ip->protocol == IPPROTO_UDP)
+ td_ptr->tdesc1.TCR |= (TCR0_UDPCK);
++
+ td_ptr->tdesc1.TCR |= TCR0_IPCK;
+ }
+ {
+-
+ int prev = index - 1;
+
+ if (prev < 0)
+ prev = vptr->options.numtx - 1;
++
+ td_ptr->tdesc0.owner = OWNED_BY_NIC;
+ vptr->td_used[qnum]++;
+ vptr->td_curr[qnum] = (index + 1) % vptr->options.numtx;
+@@ -2196,8 +2203,10 @@
+ td_ptr->td_buf[0].queue = 1;
+ mac_tx_queue_wake(vptr->mac_regs, qnum);
+ }
++
+ dev->trans_start = jiffies;
+ spin_unlock_irqrestore(&vptr->lock, flags);
++printk("xT\n");
+ return 0;
+ }
+
+@@ -2205,57 +2214,55 @@
+ * velocity_intr - interrupt callback
+ * @irq: interrupt number
+ * @dev_instance: interrupting device
++ * @pt_regs: CPU register state at interrupt
+ *
+ * Called whenever an interrupt is generated by the velocity
+ * adapter IRQ line. We may not be the source of the interrupt
+ * and need to identify initially if we are, and if not exit as
+ * efficiently as possible.
+ */
+-
+-static int velocity_intr(int irq, void *dev_instance)
++
++static int velocity_intr(int irq, void *dev_instance, struct pt_regs *regs)
+ {
+ struct net_device *dev = dev_instance;
+ struct velocity_info *vptr = netdev_priv(dev);
+ u32 isr_status;
+ int max_count = 0;
+
+-
++printk("I");
+ spin_lock(&vptr->lock);
+ isr_status = mac_read_isr(vptr->mac_regs);
++printk("0x%08x ", isr_status);
+
+- /* Not us ? */
+- if (isr_status == 0) {
++ if (!isr_status) {
+ spin_unlock(&vptr->lock);
++printk("N ");
+ return IRQ_NONE;
+ }
+
+ mac_disable_int(vptr->mac_regs);
+
+- /*
+- * Keep processing the ISR until we have completed
+- * processing and the isr_status becomes zero
+- */
+-
+- while (isr_status != 0) {
++ /* Process all pending interrupts */
++ while (isr_status) {
++ /* Ack all pending interrupt sources */
+ mac_write_isr(vptr->mac_regs, isr_status);
+- if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI)))
+- velocity_error(vptr, isr_status);
+- if (isr_status & (ISR_PRXI | ISR_PPRXI))
++
++ velocity_error(vptr, isr_status);
++ if (isr_status & (ISR_PRXI | ISR_PPRXI)) {
++printk("R");
+ max_count += velocity_rx_srv(vptr, isr_status);
+- if (isr_status & (ISR_PTXI | ISR_PPTXI))
++ }
++ if (isr_status & (ISR_PTXI | ISR_PPTXI)) {
++printk("T");
+ max_count += velocity_tx_srv(vptr, isr_status);
+- isr_status = mac_read_isr(vptr->mac_regs);
+- if (max_count > vptr->options.int_works)
+- {
+- printk(KERN_WARNING "%s: excessive work at interrupt.\n",
+- dev->name);
+- max_count = 0;
+ }
++ isr_status = mac_read_isr(vptr->mac_regs);
+ }
++
+ spin_unlock(&vptr->lock);
++printk("i");
+ mac_enable_int(vptr->mac_regs);
+ return IRQ_HANDLED;
+-
+ }
+
+
+@@ -2267,41 +2274,70 @@
+ * for a velocity adapter. Reload the CAMs with the new address
+ * filter ruleset.
+ */
++static void clear_all_multicast(struct velocity_info *vptr)
++{
++ struct mac_regs __iomem * regs = vptr->mac_regs;
++
++ /* Do not allow any multicast packets through the multicast hash table */
++ writel(0x0, ®s->MARCAM[0]);
++ writel(0x0, ®s->MARCAM[4]);
++}
++
++static void set_all_multicast(struct velocity_info *vptr)
++{
++ struct mac_regs __iomem * regs = vptr->mac_regs;
++
++ /* Allow all multicast packets through the multicast hash table */
++ writel(0xffffffff, ®s->MARCAM[0]);
++ writel(0xffffffff, ®s->MARCAM[4]);
++}
+
+ static void velocity_set_multi(struct net_device *dev)
+ {
+ struct velocity_info *vptr = netdev_priv(dev);
+ struct mac_regs __iomem * regs = vptr->mac_regs;
+- u8 rx_mode;
+- int i;
+ struct dev_mc_list *mclist;
++ int i;
++ u8 rx_mode = RCR_AB; /* Always enable broadcast packet reception */
+
+- if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
+- writel(0xffffffff, ®s->MARCAM[0]);
+- writel(0xffffffff, ®s->MARCAM[4]);
+- rx_mode = (RCR_AM | RCR_AB | RCR_PROM);
+- } else if ((dev->mc_count > vptr->multicast_limit)
+- || (dev->flags & IFF_ALLMULTI)) {
+- writel(0xffffffff, ®s->MARCAM[0]);
+- writel(0xffffffff, ®s->MARCAM[4]);
+- rx_mode = (RCR_AM | RCR_AB);
+- } else {
+- int offset = MCAM_SIZE - vptr->multicast_limit;
+- mac_get_cam_mask(regs, vptr->mCAMmask);
++ /* Clear out the multicast hash table */
++ clear_all_multicast(vptr);
+
++ /* Disable all multicast CAM entries */
++ memset(vptr->mCAMmask, 0, MCAM_SIZE / 8);
++ mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM);
++
++ if (dev->flags & IFF_PROMISC) {
++ /* Enable promiscuous mode */
++ printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
++
++ set_all_multicast(vptr);
++ rx_mode |= (RCR_PROM | RCR_AM);
++ } else if ((dev->mc_count > MCAM_SIZE) ||
++ (dev->flags & IFF_ALLMULTI)) {
++ /* ALL_MULTI or too many entries for perfect filtering, so allow all
++ * multicast packets through hash table */
++ set_all_multicast(vptr);
++ rx_mode |= RCR_AM;
++ } else {
++ /* Write a CAM entry for each multicast address */
+ for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) {
+- mac_set_cam(regs, i + offset, mclist->dmi_addr);
+- vptr->mCAMmask[(offset + i) / 8] |= 1 << ((offset + i) & 7);
++ mac_set_cam(regs, i, mclist->dmi_addr, VELOCITY_MULTICAST_CAM);
++ vptr->mCAMmask[i / 8] |= 1 << (i & 7);
+ }
+
+- mac_set_cam_mask(regs, vptr->mCAMmask);
+- rx_mode = (RCR_AM | RCR_AB);
++ /* Enable those multicast CAM entries just written */
++ mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM);
++
++ /* Enable multicast perfect matching */
++ rx_mode |= (RCR_AM | RCR_AP);
+ }
++
++ /* Allow large packets if indicated by MTU */
+ if (dev->mtu > 1500)
+ rx_mode |= RCR_AL;
+
+- BYTE_REG_BITS_ON(rx_mode, ®s->RCR);
+-
++ BYTE_REG_BITS_SET(rx_mode, RCR_AM | RCR_AB | RCR_PROM | RCR_AL | RCR_AP, ®s->RCR);
+ }
+
+ /**
+@@ -2314,36 +2350,32 @@
+ * the hardware into the counters before letting the network
+ * layer display them.
+ */
+-
++
+ static struct net_device_stats *velocity_get_stats(struct net_device *dev)
+ {
+- struct velocity_info *vptr = netdev_priv(dev);
+-
+- /* If the hardware is down, don't touch MII */
+- if(!netif_running(dev))
+- return &vptr->stats;
+-
+- spin_lock_irq(&vptr->lock);
+- velocity_update_hw_mibs(vptr);
+- spin_unlock_irq(&vptr->lock);
++ struct velocity_info *vptr = dev->priv;
+
+- vptr->stats.rx_packets = vptr->mib_counter[HW_MIB_ifRxAllPkts];
+- vptr->stats.rx_errors = vptr->mib_counter[HW_MIB_ifRxErrorPkts];
+- vptr->stats.rx_length_errors = vptr->mib_counter[HW_MIB_ifInRangeLengthErrors];
++#if 0
++ /* Only access the MIBs if the hardware is up */
++ if (netif_running(dev)) {
++ int i;
+
+-// unsigned long rx_dropped; /* no space in linux buffers */
+- vptr->stats.collisions = vptr->mib_counter[HW_MIB_ifTxEtherCollisions];
+- /* detailed rx_errors: */
+-// unsigned long rx_length_errors;
+-// unsigned long rx_over_errors; /* receiver ring buff overflow */
+- vptr->stats.rx_crc_errors = vptr->mib_counter[HW_MIB_ifRxPktCRCE];
+-// unsigned long rx_frame_errors; /* recv'd frame alignment error */
+-// unsigned long rx_fifo_errors; /* recv'r fifo overrun */
+-// unsigned long rx_missed_errors; /* receiver missed packet */
++ /* Transfer from fast counters to MIB SRAM, locking against
++ simulatanous access by ISR due to MIB high threshold being
++ exceeded */
++ spin_lock_irq(&vptr->lock);
++ velocity_update_hw_mibs(vptr);
++ spin_unlock_irq(&vptr->lock);
+
+- /* detailed tx_errors */
+-// unsigned long tx_fifo_errors;
++ /* Print MIB statistics */
++ printk("MIBs:\n");
++ for (i=0; i < HW_MIB_SIZE; ++i) {
++ printk("%02d: %08d\n", i, vptr->mib_counter[i]);
++ }
++ }
++#endif
+
++ /* Return only the statistics gathered by the driver, not MIBs */
+ return &vptr->stats;
+ }
+
+@@ -2357,7 +2389,7 @@
+ * Called when the user issues an ioctl request to the network
+ * device in question. The velocity interface supports MII.
+ */
+-
++
+ static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+ {
+ struct velocity_info *vptr = netdev_priv(dev);
+@@ -2365,10 +2397,10 @@
+
+ /* If we are asked for information and the device is power
+ saving then we need to bring the device back up to talk to it */
+-
++
+ if (!netif_running(dev))
+ pci_set_power_state(vptr->pdev, PCI_D0);
+-
++
+ switch (cmd) {
+ case SIOCGMIIPHY: /* Get address of MII PHY in use. */
+ case SIOCGMIIREG: /* Read MII PHY register. */
+@@ -2381,8 +2413,8 @@
+ }
+ if (!netif_running(dev))
+ pci_set_power_state(vptr->pdev, PCI_D3hot);
+-
+-
++
++
+ return ret;
+ }
+
+@@ -2390,7 +2422,7 @@
+ * Definition for our device driver. The PCI layer interface
+ * uses this to handle all our card discover and plugging
+ */
+-
++
+ static struct pci_driver velocity_driver = {
+ .name = VELOCITY_NAME,
+ .id_table = velocity_id_table,
+@@ -2410,13 +2442,13 @@
+ * the probe functions for each velocity adapter installed
+ * in the system.
+ */
+-
++
+ static int __init velocity_init_module(void)
+ {
+ int ret;
+
+ velocity_register_notifier();
+- ret = pci_register_driver(&velocity_driver);
++ ret = pci_module_init(&velocity_driver);
+ if (ret < 0)
+ velocity_unregister_notifier();
+ return ret;
+@@ -2426,11 +2458,11 @@
+ * velocity_cleanup - module unload
+ *
+ * When the velocity hardware is unloaded this function is called.
+- * It will clean up the notifiers and the unregister the PCI
++ * It will clean up the notifiers and the unregister the PCI
+ * driver interface for this hardware. This in turn cleans up
+ * all discovered interfaces before returning from the function
+ */
+-
++
+ static void __exit velocity_cleanup_module(void)
+ {
+ velocity_unregister_notifier();
+@@ -2444,8 +2476,8 @@
+ /*
+ * MII access , media link mode setting functions
+ */
+-
+-
++
++
+ /**
+ * mii_init - set up MII
+ * @vptr: velocity adapter
+@@ -2453,7 +2485,7 @@
+ *
+ * Set up the PHY for the current link state.
+ */
+-
++
+ static void mii_init(struct velocity_info *vptr, u32 mii_status)
+ {
+ u16 BMCR;
+@@ -2466,7 +2498,7 @@
+ MII_REG_BITS_OFF((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
+ /*
+ * Turn on ECHODIS bit in NWay-forced full mode and turn it
+- * off it in NWay-forced half mode for NWay-forced v.s.
++ * off it in NWay-forced half mode for NWay-forced v.s.
+ * legacy-forced issue.
+ */
+ if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
+@@ -2486,7 +2518,7 @@
+ MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
+ /*
+ * Turn on ECHODIS bit in NWay-forced full mode and turn it
+- * off it in NWay-forced half mode for NWay-forced v.s.
++ * off it in NWay-forced half mode for NWay-forced v.s.
+ * legacy-forced issue
+ */
+ if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
+@@ -2498,11 +2530,11 @@
+ case PHYID_MARVELL_1000:
+ case PHYID_MARVELL_1000S:
+ /*
+- * Assert CRS on Transmit
++ * Assert CRS on Transmit
+ */
+ MII_REG_BITS_ON(PSCR_ACRSTX, MII_REG_PSCR, vptr->mac_regs);
+ /*
+- * Reset to hardware default
++ * Reset to hardware default
+ */
+ MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
+ break;
+@@ -2522,7 +2554,7 @@
+ *
+ * Turn off the autopoll and wait for it to disable on the chip
+ */
+-
++
+ static void safe_disable_mii_autopoll(struct mac_regs __iomem * regs)
+ {
+ u16 ww;
+@@ -2576,7 +2608,7 @@
+ * Perform a single read of an MII 16bit register. Returns zero
+ * on success or -ETIMEDOUT if the PHY did not respond.
+ */
+-
++
+ static int velocity_mii_read(struct mac_regs __iomem *regs, u8 index, u16 *data)
+ {
+ u16 ww;
+@@ -2612,7 +2644,7 @@
+ * Perform a single write to an MII 16bit register. Returns zero
+ * on success or -ETIMEDOUT if the PHY did not respond.
+ */
+-
++
+ static int velocity_mii_write(struct mac_regs __iomem *regs, u8 mii_addr, u16 data)
+ {
+ u16 ww;
+@@ -2651,7 +2683,7 @@
+ * mii_status accordingly. The requested link state information
+ * is also returned.
+ */
+-
++
+ static u32 velocity_get_opt_media_mode(struct velocity_info *vptr)
+ {
+ u32 status = 0;
+@@ -2683,7 +2715,7 @@
+ *
+ * Enable autonegotation on this interface
+ */
+-
++
+ static void mii_set_auto_on(struct velocity_info *vptr)
+ {
+ if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs))
+@@ -2707,7 +2739,7 @@
+ * Set up the flow control on this interface according to
+ * the supplied user/eeprom options.
+ */
+-
++
+ static void set_mii_flow_control(struct velocity_info *vptr)
+ {
+ /*Enable or Disable PAUSE in ANAR */
+@@ -2744,7 +2776,7 @@
+ * PHY and also velocity hardware setup accordingly. In particular
+ * we need to set up CD polling and frame bursting.
+ */
+-
++
+ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status)
+ {
+ u32 curr_status;
+@@ -2854,7 +2886,7 @@
+ * Check the current MII status and determine the link status
+ * accordingly
+ */
+-
++
+ static u32 mii_check_media_mode(struct mac_regs __iomem * regs)
+ {
+ u32 status = 0;
+@@ -2986,14 +3018,14 @@
+ * Called before an ethtool operation. We need to make sure the
+ * chip is out of D3 state before we poke at it.
+ */
+-
++
+ static int velocity_ethtool_up(struct net_device *dev)
+ {
+ struct velocity_info *vptr = netdev_priv(dev);
+ if (!netif_running(dev))
+ pci_set_power_state(vptr->pdev, PCI_D0);
+ return 0;
+-}
++}
+
+ /**
+ * velocity_ethtool_down - post hook for ethtool
+@@ -3002,7 +3034,7 @@
+ * Called after an ethtool operation. Restore the chip back to D3
+ * state if it isn't running.
+ */
+-
++
+ static void velocity_ethtool_down(struct net_device *dev)
+ {
+ struct velocity_info *vptr = netdev_priv(dev);
+@@ -3040,7 +3072,21 @@
+ cmd->duplex = DUPLEX_FULL;
+ else
+ cmd->duplex = DUPLEX_HALF;
+-
++
++#if 0
++{
++int i;
++unsigned char __iomem *ptr = (unsigned char __iomem *)regs;
++printk("Regs:\n");
++printk("0x00:\t");
++for (i=0; i <= MAC_REG_BYTEMSK3_3; ++i) {
++ printk("0x%02x\t", readb(&(ptr[i])));
++ if (!((i+1) % 8)) {
++ printk("\n0x%02x:\t", i+1);
++ }
++}
++}
++#endif
+ return 0;
+ }
+
+@@ -3050,7 +3096,7 @@
+ u32 curr_status;
+ u32 new_status = 0;
+ int ret = 0;
+-
++
+ curr_status = check_connection_type(vptr->mac_regs);
+ curr_status &= (~VELOCITY_LINK_FAIL);
+
+@@ -3061,8 +3107,10 @@
+
+ if ((new_status & VELOCITY_AUTONEG_ENABLE) && (new_status != (curr_status | VELOCITY_AUTONEG_ENABLE)))
+ ret = -EINVAL;
+- else
++ else {
+ velocity_set_media_mode(vptr, new_status);
++ mac_set_dma_length(vptr);
++ }
+
+ return ret;
+ }
+@@ -3139,7 +3187,7 @@
+ msglevel = value;
+ }
+
+-static const struct ethtool_ops velocity_ethtool_ops = {
++static struct ethtool_ops velocity_ethtool_ops = {
+ .get_settings = velocity_get_settings,
+ .set_settings = velocity_set_settings,
+ .get_drvinfo = velocity_get_drvinfo,
+@@ -3162,7 +3210,7 @@
+ * are used by tools like kudzu to interrogate the link state of the
+ * hardware
+ */
+-
++
+ static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+ {
+ struct velocity_info *vptr = netdev_priv(dev);
+@@ -3170,7 +3218,7 @@
+ unsigned long flags;
+ struct mii_ioctl_data *miidata = if_mii(ifr);
+ int err;
+-
++
+ switch (cmd) {
+ case SIOCGMIIPHY:
+ miidata->phy_id = readb(®s->MIIADR) & 0x1f;
+@@ -3197,11 +3245,36 @@
+ return 0;
+ }
+
++static void hw_set_mac_address(struct velocity_info *vptr, unsigned char* p)
++{
++ struct mac_regs __iomem * regs = vptr->mac_regs;
++
++ int i;
++ for (i = 0; i < 6; i++) {
++ writeb(p[i], &(regs->PAR[i]));
++ }
++}
++
++static int set_mac_address(struct net_device *dev, void *p)
++{
++ struct sockaddr *addr = p;
++ struct velocity_info *vptr = dev->priv;
++
++ if (!is_valid_ether_addr(addr->sa_data)) {
++ return -EADDRNOTAVAIL;
++ }
++
++ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
++ hw_set_mac_address(vptr, addr->sa_data);
++
++ return 0;
++}
++
+ #ifdef CONFIG_PM
+
+ /**
+ * velocity_save_context - save registers
+- * @vptr: velocity
++ * @vptr: velocity
+ * @context: buffer for stored context
+ *
+ * Retrieve the current configuration from the velocity hardware
+@@ -3209,7 +3282,7 @@
+ * restore functions. This allows us to save things we need across
+ * power down states
+ */
+-
++
+ static void velocity_save_context(struct velocity_info *vptr, struct velocity_context * context)
+ {
+ struct mac_regs __iomem * regs = vptr->mac_regs;
+@@ -3229,13 +3302,13 @@
+
+ /**
+ * velocity_restore_context - restore registers
+- * @vptr: velocity
++ * @vptr: velocity
+ * @context: buffer for stored context
+ *
+- * Reload the register configuration from the velocity context
++ * Reload the register configuration from the velocity context
+ * created by velocity_save_context.
+ */
+-
++
+ static void velocity_restore_context(struct velocity_info *vptr, struct velocity_context *context)
+ {
+ struct mac_regs __iomem * regs = vptr->mac_regs;
+@@ -3301,7 +3374,7 @@
+ }
+ /* Finally, invert the result once to get the correct data */
+ crc = ~crc;
+- return bitrev32(crc) >> 16;
++ return bitreverse(crc) >> 16;
+ }
+
+ /**
+@@ -3461,8 +3534,6 @@
+ return 0;
+ }
+
+-#ifdef CONFIG_INET
+-
+ static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr)
+ {
+ struct in_ifaddr *ifa = (struct in_ifaddr *) ptr;
+@@ -3483,6 +3554,4 @@
+ }
+ return NOTIFY_DONE;
+ }
+-
+-#endif
+ #endif
+diff -Nurd linux-2.6.24/drivers/net/via-velocity.h linux-2.6.24-oxe810/drivers/net/via-velocity.h
+--- linux-2.6.24/drivers/net/via-velocity.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/via-velocity.h 2008-06-11 17:50:11.000000000 +0200
+@@ -25,8 +25,6 @@
+ #ifndef VELOCITY_H
+ #define VELOCITY_H
+
+-#define VELOCITY_TX_CSUM_SUPPORT
+-
+ #define VELOCITY_NAME "via-velocity"
+ #define VELOCITY_FULL_DRV_NAM "VIA Networking Velocity Family Gigabit Ethernet Adapter Driver"
+ #define VELOCITY_VERSION "1.14"
+@@ -35,6 +33,8 @@
+
+ #define PKT_BUF_SZ 1540
+
++#define PKT_BUF_SZ ETH_ZLEN
++
+ #define MAX_UNITS 8
+ #define OPTION_DEFAULT { [0 ... MAX_UNITS-1] = -1}
+
+@@ -716,6 +716,8 @@
+ /*
+ * Bits in the CFGA register
+ */
++#define CFGA_PHYLEDS1 0x20
++#define CFGA_PHYLEDS0 0x10
+
+ #define CFGA_PMHCTG 0x08
+ #define CFGA_GPIO1PD 0x04
+@@ -766,6 +768,7 @@
+ #define DCFG_XMRM 0x4000
+ #define DCFG_XMRL 0x2000
+ #define DCFG_PERDIS 0x1000
++#define DCFG_MRDPL 0x0800
+ #define DCFG_MRWAIT 0x0400
+ #define DCFG_MWWAIT 0x0200
+ #define DCFG_LATMEN 0x0100
+@@ -1173,7 +1176,7 @@
+
+ struct velocity_info_tbl {
+ enum chip_type chip_id;
+- const char *name;
++ char *name;
+ int txqueue;
+ u32 flags;
+ };
+@@ -1194,8 +1197,12 @@
+ #define mac_disable_int(regs) writel(CR0_GINTMSK1,&((regs)->CR0Clr))
+ #define mac_enable_int(regs) writel(CR0_GINTMSK1,&((regs)->CR0Set))
+
+-#define mac_set_dma_length(regs, n) {\
+- BYTE_REG_BITS_SET((n),0x07,&((regs)->DCFG));\
++#define mac_hw_mibs_read(regs, MIBs) {\
++ int i;\
++ BYTE_REG_BITS_ON(MIBCR_MPTRINI,&((regs)->MIBCR));\
++ for (i=0;i<HW_MIB_SIZE;i++) {\
++ (MIBs)[i]=readl(&((regs)->MIBData));\
++ }\
+ }
+
+ #define mac_set_rx_thresh(regs, n) {\
+@@ -1218,17 +1225,184 @@
+ writew(TRDCSR_WAK<<(n*4),&((regs)->TDCSRSet));\
+ }
+
+-static inline void mac_eeprom_reload(struct mac_regs __iomem * regs) {
+- int i=0;
++enum velocity_cam_type {
++ VELOCITY_VLAN_ID_CAM = 0,
++ VELOCITY_MULTICAST_CAM
++};
+
+- BYTE_REG_BITS_ON(EECSR_RELOAD,&(regs->EECSR));
+- do {
+- udelay(10);
+- if (i++>0x1000)
+- break;
+- } while (BYTE_REG_BITS_IS_ON(EECSR_RELOAD,&(regs->EECSR)));
++/**
++ * mac_get_cam_mask - Read a CAM mask
++ * @regs: register block for this velocity
++ * @mask: buffer to store mask
++ * @cam_type: CAM to fetch
++ *
++ * Fetch the mask bits of the selected CAM and store them into the
++ * provided mask buffer.
++ */
++
++static inline void mac_get_cam_mask(struct mac_regs __iomem * regs, u8 * mask, enum velocity_cam_type cam_type)
++{
++ int i;
++ /* Select CAM mask */
++ BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
++
++ if (cam_type == VELOCITY_VLAN_ID_CAM)
++ writeb(CAMADDR_VCAMSL, ®s->CAMADDR);
++ else
++ writeb(0, ®s->CAMADDR);
++
++ /* read mask */
++ for (i = 0; i < 8; i++)
++ *mask++ = readb(&(regs->MARCAM[i]));
++
++ /* disable CAMEN */
++ writeb(0, ®s->CAMADDR);
++
++ /* Select mar */
++ BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
++
++}
++
++/**
++ * mac_set_cam_mask - Set a CAM mask
++ * @regs: register block for this velocity
++ * @mask: CAM mask to load
++ * @cam_type: CAM to store
++ *
++ * Store a new mask into a CAM
++ */
++
++static inline void mac_set_cam_mask(struct mac_regs __iomem * regs, u8 * mask, enum velocity_cam_type cam_type)
++{
++ int i;
++ /* Select CAM mask */
++ BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
++
++ if (cam_type == VELOCITY_VLAN_ID_CAM)
++ writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL, ®s->CAMADDR);
++ else
++ writeb(CAMADDR_CAMEN, ®s->CAMADDR);
++
++ for (i = 0; i < 8; i++) {
++ writeb(*mask++, &(regs->MARCAM[i]));
++ }
++ /* disable CAMEN */
++ writeb(0, ®s->CAMADDR);
++
++ /* Select mar */
++ BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
+ }
+
++/**
++ * mac_set_cam - set CAM data
++ * @regs: register block of this velocity
++ * @idx: Cam index
++ * @addr: 2 or 6 bytes of CAM data
++ * @cam_type: CAM to load
++ *
++ * Load an address or vlan tag into a CAM
++ */
++
++static inline void mac_set_cam(struct mac_regs __iomem * regs, int idx, u8 *addr, enum velocity_cam_type cam_type)
++{
++ int i;
++
++ /* Select CAM mask */
++ BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
++
++ idx &= (64 - 1);
++
++ if (cam_type == VELOCITY_VLAN_ID_CAM)
++ writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, ®s->CAMADDR);
++ else
++ writeb(CAMADDR_CAMEN | idx, ®s->CAMADDR);
++
++ if (cam_type == VELOCITY_VLAN_ID_CAM)
++ writew(*((u16 *) addr), ®s->MARCAM[0]);
++ else {
++ for (i = 0; i < 6; i++) {
++ writeb(*addr++, &(regs->MARCAM[i]));
++ }
++ }
++ BYTE_REG_BITS_ON(CAMCR_CAMWR, ®s->CAMCR);
++
++ udelay(10);
++
++ writeb(0, ®s->CAMADDR);
++
++ /* Select mar */
++ BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
++}
++
++/**
++ * mac_get_cam - fetch CAM data
++ * @regs: register block of this velocity
++ * @idx: Cam index
++ * @addr: buffer to hold up to 6 bytes of CAM data
++ * @cam_type: CAM to load
++ *
++ * Load an address or vlan tag from a CAM into the buffer provided by
++ * the caller. VLAN tags are 2 bytes the address cam entries are 6.
++ */
++
++static inline void mac_get_cam(struct mac_regs __iomem * regs, int idx, u8 *addr, enum velocity_cam_type cam_type)
++{
++ int i;
++
++ /* Select CAM mask */
++ BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
++
++ idx &= (64 - 1);
++
++ if (cam_type == VELOCITY_VLAN_ID_CAM)
++ writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, ®s->CAMADDR);
++ else
++ writeb(CAMADDR_CAMEN | idx, ®s->CAMADDR);
++
++ BYTE_REG_BITS_ON(CAMCR_CAMRD, ®s->CAMCR);
++
++ udelay(10);
++
++ if (cam_type == VELOCITY_VLAN_ID_CAM)
++ *((u16 *) addr) = readw(&(regs->MARCAM[0]));
++ else
++ for (i = 0; i < 6; i++, addr++)
++ *((u8 *) addr) = readb(&(regs->MARCAM[i]));
++
++ writeb(0, ®s->CAMADDR);
++
++ /* Select mar */
++ BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR);
++}
++
++/**
++ * mac_wol_reset - reset WOL after exiting low power
++ * @regs: register block of this velocity
++ *
++ * Called after we drop out of wake on lan mode in order to
++ * reset the Wake on lan features. This function doesn't restore
++ * the rest of the logic from the result of sleep/wakeup
++ */
++
++static inline void mac_wol_reset(struct mac_regs __iomem * regs)
++{
++
++ /* Turn off SWPTAG right after leaving power mode */
++ BYTE_REG_BITS_OFF(STICKHW_SWPTAG, ®s->STICKHW);
++ /* clear sticky bits */
++ BYTE_REG_BITS_OFF((STICKHW_DS1 | STICKHW_DS0), ®s->STICKHW);
++
++ BYTE_REG_BITS_OFF(CHIPGCR_FCGMII, ®s->CHIPGCR);
++ BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, ®s->CHIPGCR);
++ /* disable force PME-enable */
++ writeb(WOLCFG_PMEOVR, ®s->WOLCFGClr);
++ /* disable power-event config bit */
++ writew(0xFFFF, ®s->WOLCRClr);
++ /* clear power status */
++ writew(0xFFFF, ®s->WOLSRClr);
++}
++
++
+ /*
+ * Header for WOL definitions. Used to compute hashes
+ */
+@@ -1515,8 +1689,9 @@
+ int numrx; /* Number of RX descriptors */
+ int numtx; /* Number of TX descriptors */
+ enum speed_opt spd_dpx; /* Media link mode */
+-
+- int DMA_length; /* DMA length */
++ int vid; /* vlan id */
++ int DMA_length_100M; /* DMA length at 100Mb/s */
++ int DMA_length_1000M; /* DMA length at 1Gb/s */
+ int rx_thresh; /* RX_THRESH */
+ int flow_cntl;
+ int wol_opts; /* Wake on lan options */
+@@ -1541,7 +1716,6 @@
+ dma_addr_t tx_bufs_dma;
+ u8 *tx_bufs;
+
+- struct vlan_group *vlgrp;
+ u8 ip_addr[4];
+ enum chip_type chip_id;
+
+@@ -1578,7 +1752,6 @@
+ int rx_buf_sz;
+ u32 mii_status;
+ u32 phy_id;
+- int multicast_limit;
+
+ u8 vCAMmask[(VCAM_SIZE / 8)];
+ u8 mCAMmask[(MCAM_SIZE / 8)];
+@@ -1623,32 +1796,6 @@
+ }
+
+ /**
+- * velocity_update_hw_mibs - fetch MIB counters from chip
+- * @vptr: velocity to update
+- *
+- * The velocity hardware keeps certain counters in the hardware
+- * side. We need to read these when the user asks for statistics
+- * or when they overflow (causing an interrupt). The read of the
+- * statistic clears it, so we keep running master counters in user
+- * space.
+- */
+-
+-static inline void velocity_update_hw_mibs(struct velocity_info *vptr)
+-{
+- u32 tmp;
+- int i;
+- BYTE_REG_BITS_ON(MIBCR_MIBFLSH, &(vptr->mac_regs->MIBCR));
+-
+- while (BYTE_REG_BITS_IS_ON(MIBCR_MIBFLSH, &(vptr->mac_regs->MIBCR)));
+-
+- BYTE_REG_BITS_ON(MIBCR_MPTRINI, &(vptr->mac_regs->MIBCR));
+- for (i = 0; i < HW_MIB_SIZE; i++) {
+- tmp = readl(&(vptr->mac_regs->MIBData)) & 0x00FFFFFFUL;
+- vptr->mib_counter[i] += tmp;
+- }
+-}
+-
+-/**
+ * init_flow_control_register - set up flow control
+ * @vptr: velocity to configure
+ *
+diff -Nurd linux-2.6.24/drivers/net/wireless/b43/dma.c linux-2.6.24-oxe810/drivers/net/wireless/b43/dma.c
+--- linux-2.6.24/drivers/net/wireless/b43/dma.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/wireless/b43/dma.c 2008-06-11 17:49:58.000000000 +0200
+@@ -165,7 +165,7 @@
+ addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK);
+ addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK)
+ >> SSB_DMA_TRANSLATION_SHIFT;
+- addrhi |= ssb_dma_translation(ring->dev->dev);
++ addrhi |= (ssb_dma_translation(ring->dev->dev) << 1);
+ if (slot == ring->nr_slots - 1)
+ ctl0 |= B43_DMA64_DCTL0_DTABLEEND;
+ if (start)
+@@ -426,9 +426,21 @@
+ static int alloc_ringmemory(struct b43_dmaring *ring)
+ {
+ struct device *dev = ring->dev->dev->dev;
++ gfp_t flags = GFP_KERNEL;
+
++ /* The specs call for 4K buffers for 30- and 32-bit DMA with 4K
++ * alignment and 8K buffers for 64-bit DMA with 8K alignment. Testing
++ * has shown that 4K is sufficient for the latter as long as the buffer
++ * does not cross an 8K boundary.
++ *
++ * For unknown reasons - possibly a hardware error - the BCM4311 rev
++ * 02, which uses 64-bit DMA, needs the ring buffer in very low memory,
++ * which accounts for the GFP_DMA flag below.
++ */
++ if (ring->dma64)
++ flags |= GFP_DMA;
+ ring->descbase = dma_alloc_coherent(dev, B43_DMA_RINGMEMSIZE,
+- &(ring->dmabase), GFP_KERNEL);
++ &(ring->dmabase), flags);
+ if (!ring->descbase) {
+ b43err(ring->dev->wl, "DMA ringmemory allocation failed\n");
+ return -ENOMEM;
+@@ -483,7 +495,7 @@
+ return 0;
+ }
+
+-/* Reset the RX DMA channel */
++/* Reset the TX DMA channel */
+ int b43_dmacontroller_tx_reset(struct b43_wldev *dev, u16 mmio_base, int dma64)
+ {
+ int i;
+@@ -647,7 +659,7 @@
+ b43_dma_write(ring, B43_DMA64_TXRINGHI,
+ ((ringbase >> 32) &
+ ~SSB_DMA_TRANSLATION_MASK)
+- | trans);
++ | (trans << 1));
+ } else {
+ u32 ringbase = (u32) (ring->dmabase);
+
+@@ -680,8 +692,9 @@
+ b43_dma_write(ring, B43_DMA64_RXRINGHI,
+ ((ringbase >> 32) &
+ ~SSB_DMA_TRANSLATION_MASK)
+- | trans);
+- b43_dma_write(ring, B43_DMA64_RXINDEX, 200);
++ | (trans << 1));
++ b43_dma_write(ring, B43_DMA64_RXINDEX, ring->nr_slots *
++ sizeof(struct b43_dmadesc64));
+ } else {
+ u32 ringbase = (u32) (ring->dmabase);
+
+@@ -695,11 +708,12 @@
+ b43_dma_write(ring, B43_DMA32_RXRING,
+ (ringbase & ~SSB_DMA_TRANSLATION_MASK)
+ | trans);
+- b43_dma_write(ring, B43_DMA32_RXINDEX, 200);
++ b43_dma_write(ring, B43_DMA32_RXINDEX, ring->nr_slots *
++ sizeof(struct b43_dmadesc32));
+ }
+ }
+
+- out:
++out:
+ return err;
+ }
+
+@@ -1106,7 +1120,7 @@
+ {
+ const struct b43_dma_ops *ops = ring->ops;
+ u8 *header;
+- int slot;
++ int slot, old_top_slot, old_used_slots;
+ int err;
+ struct b43_dmadesc_generic *desc;
+ struct b43_dmadesc_meta *meta;
+@@ -1116,20 +1130,31 @@
+ #define SLOTS_PER_PACKET 2
+ B43_WARN_ON(skb_shinfo(skb)->nr_frags);
+
++ old_top_slot = ring->current_slot;
++ old_used_slots = ring->used_slots;
++
+ /* Get a slot for the header. */
+ slot = request_slot(ring);
+ desc = ops->idx2desc(ring, slot, &meta_hdr);
+ memset(meta_hdr, 0, sizeof(*meta_hdr));
+
+ header = &(ring->txhdr_cache[slot * sizeof(struct b43_txhdr_fw4)]);
+- b43_generate_txhdr(ring->dev, header,
++ err = b43_generate_txhdr(ring->dev, header,
+ skb->data, skb->len, ctl,
+ generate_cookie(ring, slot));
++ if (unlikely(err)) {
++ ring->current_slot = old_top_slot;
++ ring->used_slots = old_used_slots;
++ return err;
++ }
+
+ meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header,
+ sizeof(struct b43_txhdr_fw4), 1);
+- if (dma_mapping_error(meta_hdr->dmaaddr))
++ if (dma_mapping_error(meta_hdr->dmaaddr)) {
++ ring->current_slot = old_top_slot;
++ ring->used_slots = old_used_slots;
+ return -EIO;
++ }
+ ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr,
+ sizeof(struct b43_txhdr_fw4), 1, 0, 0);
+
+@@ -1147,6 +1172,8 @@
+ if (dma_mapping_error(meta->dmaaddr)) {
+ bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
+ if (!bounce_skb) {
++ ring->current_slot = old_top_slot;
++ ring->used_slots = old_used_slots;
+ err = -ENOMEM;
+ goto out_unmap_hdr;
+ }
+@@ -1157,6 +1184,8 @@
+ meta->skb = skb;
+ meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
+ if (dma_mapping_error(meta->dmaaddr)) {
++ ring->current_slot = old_top_slot;
++ ring->used_slots = old_used_slots;
+ err = -EIO;
+ goto out_free_bounce;
+ }
+@@ -1219,6 +1248,13 @@
+ B43_WARN_ON(ring->stopped);
+
+ err = dma_tx_fragment(ring, skb, ctl);
++ if (unlikely(err == -ENOKEY)) {
++ /* Drop this packet, as we don't have the encryption key
++ * anymore and must not transmit it unencrypted. */
++ dev_kfree_skb_any(skb);
++ err = 0;
++ goto out_unlock;
++ }
+ if (unlikely(err)) {
+ b43err(dev->wl, "DMA tx mapping failure\n");
+ goto out_unlock;
+diff -Nurd linux-2.6.24/drivers/net/wireless/b43/main.c linux-2.6.24-oxe810/drivers/net/wireless/b43/main.c
+--- linux-2.6.24/drivers/net/wireless/b43/main.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/wireless/b43/main.c 2008-06-11 17:49:58.000000000 +0200
+@@ -101,6 +101,7 @@
+ SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 7),
+ SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 9),
+ SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10),
++ SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13),
+ SSB_DEVTABLE_END
+ };
+
+@@ -1800,6 +1801,18 @@
+ err = -EOPNOTSUPP;
+ goto out;
+ }
++ if (fwrev > 351) {
++ b43err(dev->wl, "YOUR FIRMWARE IS TOO NEW. Please downgrade your "
++ "firmware.\n");
++ b43err(dev->wl, "Use this firmware tarball: "
++ "http://downloads.openwrt.org/sources/broadcom-wl-4.80.53.0.tar.bz2\n");
++ b43err(dev->wl, "Use this b43-fwcutter tarball: "
++ "http://bu3sch.de/b43/fwcutter/b43-fwcutter-009.tar.bz2\n");
++ b43err(dev->wl, "Read, understand and _do_ what this message says, please.\n");
++ b43_write32(dev, B43_MMIO_MACCTL, 0);
++ err = -EOPNOTSUPP;
++ goto out;
++ }
+ b43dbg(dev->wl, "Loading firmware version %u.%u "
+ "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
+ fwrev, fwpatch,
+@@ -3067,7 +3080,7 @@
+ unsupported = 1;
+ break;
+ case B43_PHYTYPE_G:
+- if (phy_rev > 8)
++ if (phy_rev > 9)
+ unsupported = 1;
+ break;
+ default:
+@@ -3395,8 +3408,6 @@
+ b43_bluetooth_coext_enable(dev);
+
+ ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */
+- memset(wl->bssid, 0, ETH_ALEN);
+- memset(wl->mac_addr, 0, ETH_ALEN);
+ b43_upload_card_macaddress(dev);
+ b43_security_init(dev);
+ b43_rng_init(wl);
+@@ -3493,6 +3504,13 @@
+ int did_init = 0;
+ int err = 0;
+
++ /* Kill all old instance specific information to make sure
++ * the card won't use it in the short timeframe between start
++ * and mac80211 reconfiguring it. */
++ memset(wl->bssid, 0, ETH_ALEN);
++ memset(wl->mac_addr, 0, ETH_ALEN);
++ wl->filter_flags = 0;
++
+ /* First register RFkill.
+ * LEDs that are registered later depend on it. */
+ b43_rfkill_init(dev);
+diff -Nurd linux-2.6.24/drivers/net/wireless/b43/xmit.c linux-2.6.24-oxe810/drivers/net/wireless/b43/xmit.c
+--- linux-2.6.24/drivers/net/wireless/b43/xmit.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/wireless/b43/xmit.c 2008-06-11 17:49:58.000000000 +0200
+@@ -177,7 +177,7 @@
+ return 0;
+ }
+
+-static void generate_txhdr_fw4(struct b43_wldev *dev,
++static int generate_txhdr_fw4(struct b43_wldev *dev,
+ struct b43_txhdr_fw4 *txhdr,
+ const unsigned char *fragment_data,
+ unsigned int fragment_len,
+@@ -235,7 +235,15 @@
+
+ B43_WARN_ON(key_idx >= dev->max_nr_keys);
+ key = &(dev->key[key_idx]);
+- B43_WARN_ON(!key->keyconf);
++
++ if (unlikely(!key->keyconf)) {
++ /* This key is invalid. This might only happen
++ * in a short timeframe after machine resume before
++ * we were able to reconfigure keys.
++ * Drop this packet completely. Do not transmit it
++ * unencrypted to avoid leaking information. */
++ return -ENOKEY;
++ }
+
+ /* Hardware appends ICV. */
+ plcp_fragment_len += txctl->icv_len;
+@@ -352,16 +360,18 @@
+ txhdr->mac_ctl = cpu_to_le32(mac_ctl);
+ txhdr->phy_ctl = cpu_to_le16(phy_ctl);
+ txhdr->extra_ft = extra_ft;
++
++ return 0;
+ }
+
+-void b43_generate_txhdr(struct b43_wldev *dev,
++int b43_generate_txhdr(struct b43_wldev *dev,
+ u8 * txhdr,
+ const unsigned char *fragment_data,
+ unsigned int fragment_len,
+ const struct ieee80211_tx_control *txctl, u16 cookie)
+ {
+- generate_txhdr_fw4(dev, (struct b43_txhdr_fw4 *)txhdr,
+- fragment_data, fragment_len, txctl, cookie);
++ return generate_txhdr_fw4(dev, (struct b43_txhdr_fw4 *)txhdr,
++ fragment_data, fragment_len, txctl, cookie);
+ }
+
+ static s8 b43_rssi_postprocess(struct b43_wldev *dev,
+diff -Nurd linux-2.6.24/drivers/net/wireless/b43/xmit.h linux-2.6.24-oxe810/drivers/net/wireless/b43/xmit.h
+--- linux-2.6.24/drivers/net/wireless/b43/xmit.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/wireless/b43/xmit.h 2008-06-11 17:49:58.000000000 +0200
+@@ -82,7 +82,7 @@
+ #define B43_TX4_PHY_ANT1 0x0100 /* Use antenna 1 */
+ #define B43_TX4_PHY_ANTLAST 0x0300 /* Use last used antenna */
+
+-void b43_generate_txhdr(struct b43_wldev *dev,
++int b43_generate_txhdr(struct b43_wldev *dev,
+ u8 * txhdr,
+ const unsigned char *fragment_data,
+ unsigned int fragment_len,
+diff -Nurd linux-2.6.24/drivers/net/wireless/b43legacy/dma.c linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/dma.c
+--- linux-2.6.24/drivers/net/wireless/b43legacy/dma.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/dma.c 2008-06-11 17:49:57.000000000 +0200
+@@ -1164,7 +1164,7 @@
+ {
+ const struct b43legacy_dma_ops *ops = ring->ops;
+ u8 *header;
+- int slot;
++ int slot, old_top_slot, old_used_slots;
+ int err;
+ struct b43legacy_dmadesc_generic *desc;
+ struct b43legacy_dmadesc_meta *meta;
+@@ -1174,6 +1174,9 @@
+ #define SLOTS_PER_PACKET 2
+ B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags != 0);
+
++ old_top_slot = ring->current_slot;
++ old_used_slots = ring->used_slots;
++
+ /* Get a slot for the header. */
+ slot = request_slot(ring);
+ desc = ops->idx2desc(ring, slot, &meta_hdr);
+@@ -1181,9 +1184,14 @@
+
+ header = &(ring->txhdr_cache[slot * sizeof(
+ struct b43legacy_txhdr_fw3)]);
+- b43legacy_generate_txhdr(ring->dev, header,
++ err = b43legacy_generate_txhdr(ring->dev, header,
+ skb->data, skb->len, ctl,
+ generate_cookie(ring, slot));
++ if (unlikely(err)) {
++ ring->current_slot = old_top_slot;
++ ring->used_slots = old_used_slots;
++ return err;
++ }
+
+ meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header,
+ sizeof(struct b43legacy_txhdr_fw3), 1);
+@@ -1206,6 +1214,8 @@
+ if (dma_mapping_error(meta->dmaaddr)) {
+ bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
+ if (!bounce_skb) {
++ ring->current_slot = old_top_slot;
++ ring->used_slots = old_used_slots;
+ err = -ENOMEM;
+ goto out_unmap_hdr;
+ }
+@@ -1216,6 +1226,8 @@
+ meta->skb = skb;
+ meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
+ if (dma_mapping_error(meta->dmaaddr)) {
++ ring->current_slot = old_top_slot;
++ ring->used_slots = old_used_slots;
+ err = -EIO;
+ goto out_free_bounce;
+ }
+@@ -1282,6 +1294,13 @@
+ B43legacy_BUG_ON(ring->stopped);
+
+ err = dma_tx_fragment(ring, skb, ctl);
++ if (unlikely(err == -ENOKEY)) {
++ /* Drop this packet, as we don't have the encryption key
++ * anymore and must not transmit it unencrypted. */
++ dev_kfree_skb_any(skb);
++ err = 0;
++ goto out_unlock;
++ }
+ if (unlikely(err)) {
+ b43legacyerr(dev->wl, "DMA tx mapping failure\n");
+ goto out_unlock;
+diff -Nurd linux-2.6.24/drivers/net/wireless/b43legacy/main.c linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/main.c
+--- linux-2.6.24/drivers/net/wireless/b43legacy/main.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/main.c 2008-06-11 17:49:57.000000000 +0200
+@@ -3215,8 +3215,6 @@
+ b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, 0x0414, 0x01F4);
+
+ ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */
+- memset(wl->bssid, 0, ETH_ALEN);
+- memset(wl->mac_addr, 0, ETH_ALEN);
+ b43legacy_upload_card_macaddress(dev);
+ b43legacy_security_init(dev);
+ b43legacy_rng_init(wl);
+@@ -3311,6 +3309,13 @@
+ int did_init = 0;
+ int err = 0;
+
++ /* Kill all old instance specific information to make sure
++ * the card won't use it in the short timeframe between start
++ * and mac80211 reconfiguring it. */
++ memset(wl->bssid, 0, ETH_ALEN);
++ memset(wl->mac_addr, 0, ETH_ALEN);
++ wl->filter_flags = 0;
++
+ mutex_lock(&wl->mutex);
+
+ if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) {
+diff -Nurd linux-2.6.24/drivers/net/wireless/b43legacy/pio.c linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/pio.c
+--- linux-2.6.24/drivers/net/wireless/b43legacy/pio.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/pio.c 2008-06-11 17:49:57.000000000 +0200
+@@ -181,7 +181,7 @@
+ struct b43legacy_txhdr_fw3 txhdr_fw3;
+ };
+
+-static void pio_tx_write_fragment(struct b43legacy_pioqueue *queue,
++static int pio_tx_write_fragment(struct b43legacy_pioqueue *queue,
+ struct sk_buff *skb,
+ struct b43legacy_pio_txpacket *packet,
+ size_t txhdr_size)
+@@ -189,14 +189,17 @@
+ union txhdr_union txhdr_data;
+ u8 *txhdr = NULL;
+ unsigned int octets;
++ int err;
+
+ txhdr = (u8 *)(&txhdr_data.txhdr_fw3);
+
+ B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags != 0);
+- b43legacy_generate_txhdr(queue->dev,
++ err = b43legacy_generate_txhdr(queue->dev,
+ txhdr, skb->data, skb->len,
+ &packet->txstat.control,
+ generate_cookie(queue, packet));
++ if (err)
++ return err;
+
+ tx_start(queue);
+ octets = skb->len + txhdr_size;
+@@ -204,6 +207,8 @@
+ octets--;
+ tx_data(queue, txhdr, (u8 *)skb->data, octets);
+ tx_complete(queue, skb);
++
++ return 0;
+ }
+
+ static void free_txpacket(struct b43legacy_pio_txpacket *packet,
+@@ -226,6 +231,7 @@
+ struct b43legacy_pioqueue *queue = packet->queue;
+ struct sk_buff *skb = packet->skb;
+ u16 octets;
++ int err;
+
+ octets = (u16)skb->len + sizeof(struct b43legacy_txhdr_fw3);
+ if (queue->tx_devq_size < octets) {
+@@ -247,8 +253,14 @@
+ if (queue->tx_devq_used + octets > queue->tx_devq_size)
+ return -EBUSY;
+ /* Now poke the device. */
+- pio_tx_write_fragment(queue, skb, packet,
++ err = pio_tx_write_fragment(queue, skb, packet,
+ sizeof(struct b43legacy_txhdr_fw3));
++ if (unlikely(err == -ENOKEY)) {
++ /* Drop this packet, as we don't have the encryption key
++ * anymore and must not transmit it unencrypted. */
++ free_txpacket(packet, 1);
++ return 0;
++ }
+
+ /* Account for the packet size.
+ * (We must not overflow the device TX queue)
+@@ -486,6 +498,9 @@
+ queue = parse_cookie(dev, status->cookie, &packet);
+ B43legacy_WARN_ON(!queue);
+
++ if (!packet->skb)
++ return;
++
+ queue->tx_devq_packets--;
+ queue->tx_devq_used -= (packet->skb->len +
+ sizeof(struct b43legacy_txhdr_fw3));
+diff -Nurd linux-2.6.24/drivers/net/wireless/b43legacy/xmit.c linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/xmit.c
+--- linux-2.6.24/drivers/net/wireless/b43legacy/xmit.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/xmit.c 2008-06-11 17:49:57.000000000 +0200
+@@ -181,7 +181,7 @@
+ return 0;
+ }
+
+-static void generate_txhdr_fw3(struct b43legacy_wldev *dev,
++static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
+ struct b43legacy_txhdr_fw3 *txhdr,
+ const unsigned char *fragment_data,
+ unsigned int fragment_len,
+@@ -252,6 +252,13 @@
+ iv_len = min((size_t)txctl->iv_len,
+ ARRAY_SIZE(txhdr->iv));
+ memcpy(txhdr->iv, ((u8 *)wlhdr) + wlhdr_len, iv_len);
++ } else {
++ /* This key is invalid. This might only happen
++ * in a short timeframe after machine resume before
++ * we were able to reconfigure keys.
++ * Drop this packet completely. Do not transmit it
++ * unencrypted to avoid leaking information. */
++ return -ENOKEY;
+ }
+ }
+ b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *)
+@@ -344,16 +351,18 @@
+ /* Apply the bitfields */
+ txhdr->mac_ctl = cpu_to_le32(mac_ctl);
+ txhdr->phy_ctl = cpu_to_le16(phy_ctl);
++
++ return 0;
+ }
+
+-void b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
++int b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
+ u8 *txhdr,
+ const unsigned char *fragment_data,
+ unsigned int fragment_len,
+ const struct ieee80211_tx_control *txctl,
+ u16 cookie)
+ {
+- generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr,
++ return generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr,
+ fragment_data, fragment_len,
+ txctl, cookie);
+ }
+diff -Nurd linux-2.6.24/drivers/net/wireless/b43legacy/xmit.h linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/xmit.h
+--- linux-2.6.24/drivers/net/wireless/b43legacy/xmit.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/net/wireless/b43legacy/xmit.h 2008-06-11 17:49:57.000000000 +0200
+@@ -76,7 +76,7 @@
+
+
+
+-void b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
++int b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
+ u8 *txhdr,
+ const unsigned char *fragment_data,
+ unsigned int fragment_len,
+diff -Nurd linux-2.6.24/drivers/pci/hotplug/fakephp.c linux-2.6.24-oxe810/drivers/pci/hotplug/fakephp.c
+--- linux-2.6.24/drivers/pci/hotplug/fakephp.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/pci/hotplug/fakephp.c 2008-06-11 17:49:28.000000000 +0200
+@@ -39,6 +39,7 @@
+ #include <linux/init.h>
+ #include <linux/string.h>
+ #include <linux/slab.h>
++#include <linux/workqueue.h>
+ #include "../pci.h"
+
+ #if !defined(MODULE)
+@@ -63,10 +64,16 @@
+ struct list_head node;
+ struct hotplug_slot *slot;
+ struct pci_dev *dev;
++ struct work_struct remove_work;
++ unsigned long removed;
+ };
+
+ static int debug;
+ static LIST_HEAD(slot_list);
++static struct workqueue_struct *dummyphp_wq;
++
++static void pci_rescan_worker(struct work_struct *work);
++static DECLARE_WORK(pci_rescan_work, pci_rescan_worker);
+
+ static int enable_slot (struct hotplug_slot *slot);
+ static int disable_slot (struct hotplug_slot *slot);
+@@ -109,7 +116,7 @@
+ slot->name = &dev->dev.bus_id[0];
+ dbg("slot->name = %s\n", slot->name);
+
+- dslot = kmalloc(sizeof(struct dummy_slot), GFP_KERNEL);
++ dslot = kzalloc(sizeof(struct dummy_slot), GFP_KERNEL);
+ if (!dslot)
+ goto error_info;
+
+@@ -164,6 +171,14 @@
+ err("Problem unregistering a slot %s\n", dslot->slot->name);
+ }
+
++/* called from the single-threaded workqueue handler to remove a slot */
++static void remove_slot_worker(struct work_struct *work)
++{
++ struct dummy_slot *dslot =
++ container_of(work, struct dummy_slot, remove_work);
++ remove_slot(dslot);
++}
++
+ /**
+ * pci_rescan_slot - Rescan slot
+ * @temp: Device template. Should be set: bus and devfn.
+@@ -267,11 +282,17 @@
+ pci_rescan_buses(&pci_root_buses);
+ }
+
++/* called from the single-threaded workqueue handler to rescan all pci buses */
++static void pci_rescan_worker(struct work_struct *work)
++{
++ pci_rescan();
++}
+
+ static int enable_slot(struct hotplug_slot *hotplug_slot)
+ {
+ /* mis-use enable_slot for rescanning of the pci bus */
+- pci_rescan();
++ cancel_work_sync(&pci_rescan_work);
++ queue_work(dummyphp_wq, &pci_rescan_work);
+ return -ENODEV;
+ }
+
+@@ -306,6 +327,10 @@
+ err("Can't remove PCI devices with other PCI devices behind it yet.\n");
+ return -ENODEV;
+ }
++ if (test_and_set_bit(0, &dslot->removed)) {
++ dbg("Slot already scheduled for removal\n");
++ return -ENODEV;
++ }
+ /* search for subfunctions and disable them first */
+ if (!(dslot->dev->devfn & 7)) {
+ for (func = 1; func < 8; func++) {
+@@ -328,8 +353,9 @@
+ /* remove the device from the pci core */
+ pci_remove_bus_device(dslot->dev);
+
+- /* blow away this sysfs entry and other parts. */
+- remove_slot(dslot);
++ /* queue work item to blow away this sysfs entry and other parts. */
++ INIT_WORK(&dslot->remove_work, remove_slot_worker);
++ queue_work(dummyphp_wq, &dslot->remove_work);
+
+ return 0;
+ }
+@@ -340,6 +366,7 @@
+ struct list_head *next;
+ struct dummy_slot *dslot;
+
++ destroy_workqueue(dummyphp_wq);
+ list_for_each_safe (tmp, next, &slot_list) {
+ dslot = list_entry (tmp, struct dummy_slot, node);
+ remove_slot(dslot);
+@@ -351,6 +378,10 @@
+ {
+ info(DRIVER_DESC "\n");
+
++ dummyphp_wq = create_singlethread_workqueue(MY_NAME);
++ if (!dummyphp_wq)
++ return -ENOMEM;
++
+ return pci_scan_buses();
+ }
+
+diff -Nurd linux-2.6.24/drivers/pci/probe.c linux-2.6.24-oxe810/drivers/pci/probe.c
+--- linux-2.6.24/drivers/pci/probe.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/pci/probe.c 2008-06-11 17:49:28.000000000 +0200
+@@ -991,8 +991,18 @@
+ for (func = 0; func < 8; func++, devfn++) {
+ struct pci_dev *dev;
+
+- dev = pci_scan_single_device(bus, devfn);
+- if (dev) {
++#ifdef CONFIG_PCI_OXNAS_CARDBUS
++ // printk(KERN_INFO "pci_scan_slot %u\n", PCI_SLOT(devfn) );
++ scan_all_fns = 1;
++ if ( PCI_SLOT(devfn) == 5 )
++ dev = pci_scan_single_device(bus, devfn);
++ else
++ dev = 0;
++#else /* ifndef CONFIG_OXNAS_CARDBUS */
++ dev = pci_scan_single_device(bus, devfn);
++#endif /* CONFIG_OXNAS_CARDBUS */
++
++ if (dev) {
+ nr++;
+
+ /*
+diff -Nurd linux-2.6.24/drivers/rtc/rtc-ds1307.c linux-2.6.24-oxe810/drivers/rtc/rtc-ds1307.c
+--- linux-2.6.24/drivers/rtc/rtc-ds1307.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/rtc/rtc-ds1307.c 2008-06-11 17:49:41.000000000 +0200
+@@ -17,7 +17,7 @@
+ #include <linux/rtc.h>
+ #include <linux/bcd.h>
+
+-
++#define ACCEPT_UNINITIALIZED_DEVICE_IN_PROBE
+
+ /* We can't determine type by probing, but if we expect pre-Linux code
+ * to have set the chip up as a clock (turning on the oscillator and
+@@ -445,6 +445,7 @@
+ break;
+ }
+
++#ifndef ACCEPT_UNINITIALIZED_DEVICE_IN_PROBE
+ tmp = ds1307->regs[DS1307_REG_SECS];
+ tmp = BCD2BIN(tmp & 0x7f);
+ if (tmp > 60)
+@@ -460,6 +461,7 @@
+ tmp = BCD2BIN(ds1307->regs[DS1307_REG_MONTH] & 0x1f);
+ if (tmp == 0 || tmp > 12)
+ goto exit_bad;
++#endif // !ACCEPT_UNINITIALIZED_DEVICE_IN_PROBE
+
+ tmp = ds1307->regs[DS1307_REG_HOUR];
+ switch (ds1307->type) {
+diff -Nurd linux-2.6.24/drivers/s390/char/defkeymap.c linux-2.6.24-oxe810/drivers/s390/char/defkeymap.c
+--- linux-2.6.24/drivers/s390/char/defkeymap.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/s390/char/defkeymap.c 2008-06-11 17:49:17.000000000 +0200
+@@ -151,8 +151,8 @@
+ };
+
+ struct kbdiacruc accent_table[MAX_DIACR] = {
+- {'^', 'c', '\003'}, {'^', 'd', '\004'},
+- {'^', 'z', '\032'}, {'^', '\012', '\000'},
++ {'^', 'c', 0003}, {'^', 'd', 0004},
++ {'^', 'z', 0032}, {'^', 0012, 0000},
+ };
+
+ unsigned int accent_table_size = 4;
+diff -Nurd linux-2.6.24/drivers/scsi/Kconfig linux-2.6.24-oxe810/drivers/scsi/Kconfig
+--- linux-2.6.24/drivers/scsi/Kconfig 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/scsi/Kconfig 2008-06-11 17:50:29.000000000 +0200
+@@ -556,6 +556,15 @@
+ To compile this driver as a module, choose M here: the
+ module will be called arcmsr (modprobe arcmsr).
+
++config SCSI_SATA_DISK_DETECTION_TENACITY
++ int "The number of attempts to detect a disk."
++ default 1
++ depends on SCSI_SATA
++ help
++ Sets the number of times taken to repeat a 700 ms process of detecting a disk. Some disks will not respond to detection until they have spun-up and they won't spin-up untill they receive some communication from the host.
++
++ If unsure, use 1.
++
+ config SCSI_ARCMSR_AER
+ bool "Enable PCI Error Recovery Capability in Areca Driver(ARCMSR)"
+ depends on SCSI_ARCMSR && PCIEAER
+diff -Nurd linux-2.6.24/drivers/scsi/advansys.c linux-2.6.24-oxe810/drivers/scsi/advansys.c
+--- linux-2.6.24/drivers/scsi/advansys.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/scsi/advansys.c 2008-06-11 17:50:28.000000000 +0200
+@@ -566,7 +566,7 @@
+ ASC_SCSI_BIT_ID_TYPE unit_not_ready;
+ ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
+ ASC_SCSI_BIT_ID_TYPE start_motor;
+- uchar overrun_buf[ASC_OVERRUN_BSIZE] __aligned(8);
++ uchar *overrun_buf;
+ dma_addr_t overrun_dma;
+ uchar scsi_reset_wait;
+ uchar chip_no;
+@@ -6439,7 +6439,7 @@
+ i += 2;
+ len += 2;
+ } else {
+- unsigned char off = buf[i] * 2;
++ unsigned int off = buf[i] * 2;
+ unsigned short word = (buf[off + 1] << 8) | buf[off];
+ AdvWriteWordAutoIncLram(iop_base, word);
+ len += 2;
+@@ -13833,6 +13833,12 @@
+ */
+ if (ASC_NARROW_BOARD(boardp)) {
+ ASC_DBG(2, "AscInitAsc1000Driver()\n");
++
++ asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL);
++ if (!asc_dvc_varp->overrun_buf) {
++ ret = -ENOMEM;
++ goto err_free_wide_mem;
++ }
+ warn_code = AscInitAsc1000Driver(asc_dvc_varp);
+
+ if (warn_code || asc_dvc_varp->err_code) {
+@@ -13840,8 +13846,10 @@
+ "warn 0x%x, error 0x%x\n",
+ asc_dvc_varp->init_state, warn_code,
+ asc_dvc_varp->err_code);
+- if (asc_dvc_varp->err_code)
++ if (asc_dvc_varp->err_code) {
+ ret = -ENODEV;
++ kfree(asc_dvc_varp->overrun_buf);
++ }
+ }
+ } else {
+ if (advansys_wide_init_chip(shost))
+@@ -13894,6 +13902,7 @@
+ dma_unmap_single(board->dev,
+ board->dvc_var.asc_dvc_var.overrun_dma,
+ ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
++ kfree(board->dvc_var.asc_dvc_var.overrun_buf);
+ } else {
+ iounmap(board->ioremap_addr);
+ advansys_wide_free_mem(board);
+diff -Nurd linux-2.6.24/drivers/scsi/aic94xx/aic94xx_scb.c linux-2.6.24-oxe810/drivers/scsi/aic94xx/aic94xx_scb.c
+--- linux-2.6.24/drivers/scsi/aic94xx/aic94xx_scb.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/scsi/aic94xx/aic94xx_scb.c 2008-06-11 17:50:27.000000000 +0200
+@@ -458,13 +458,19 @@
+ tc_abort = le16_to_cpu(tc_abort);
+
+ list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) {
+- struct sas_task *task = ascb->uldd_task;
++ struct sas_task *task = a->uldd_task;
+
+- if (task && a->tc_index == tc_abort) {
++ if (a->tc_index != tc_abort)
++ continue;
++
++ if (task) {
+ failed_dev = task->dev;
+ sas_task_abort(task);
+- break;
++ } else {
++ ASD_DPRINTK("R_T_A for non TASK scb 0x%x\n",
++ a->scb->header.opcode);
+ }
++ break;
+ }
+
+ if (!failed_dev) {
+@@ -478,7 +484,7 @@
+ * that the EH will wake up and do something.
+ */
+ list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) {
+- struct sas_task *task = ascb->uldd_task;
++ struct sas_task *task = a->uldd_task;
+
+ if (task &&
+ task->dev == failed_dev &&
+diff -Nurd linux-2.6.24/drivers/scsi/arcmsr/arcmsr_hba.c linux-2.6.24-oxe810/drivers/scsi/arcmsr/arcmsr_hba.c
+--- linux-2.6.24/drivers/scsi/arcmsr/arcmsr_hba.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/scsi/arcmsr/arcmsr_hba.c 2008-06-11 17:50:28.000000000 +0200
+@@ -1380,17 +1380,16 @@
+ switch(controlcode) {
+
+ case ARCMSR_MESSAGE_READ_RQBUFFER: {
+- unsigned long *ver_addr;
+- dma_addr_t buf_handle;
++ unsigned char *ver_addr;
+ uint8_t *pQbuffer, *ptmpQbuffer;
+ int32_t allxfer_len = 0;
+
+- ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle);
++ ver_addr = kmalloc(1032, GFP_ATOMIC);
+ if (!ver_addr) {
+ retvalue = ARCMSR_MESSAGE_FAIL;
+ goto message_out;
+ }
+- ptmpQbuffer = (uint8_t *) ver_addr;
++ ptmpQbuffer = ver_addr;
+ while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
+ && (allxfer_len < 1031)) {
+ pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
+@@ -1419,25 +1418,24 @@
+ }
+ arcmsr_iop_message_read(acb);
+ }
+- memcpy(pcmdmessagefld->messagedatabuffer, (uint8_t *)ver_addr, allxfer_len);
++ memcpy(pcmdmessagefld->messagedatabuffer, ver_addr, allxfer_len);
+ pcmdmessagefld->cmdmessage.Length = allxfer_len;
+ pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
+- pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle);
++ kfree(ver_addr);
+ }
+ break;
+
+ case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
+- unsigned long *ver_addr;
+- dma_addr_t buf_handle;
++ unsigned char *ver_addr;
+ int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
+ uint8_t *pQbuffer, *ptmpuserbuffer;
+
+- ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle);
++ ver_addr = kmalloc(1032, GFP_ATOMIC);
+ if (!ver_addr) {
+ retvalue = ARCMSR_MESSAGE_FAIL;
+ goto message_out;
+ }
+- ptmpuserbuffer = (uint8_t *)ver_addr;
++ ptmpuserbuffer = ver_addr;
+ user_len = pcmdmessagefld->cmdmessage.Length;
+ memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len);
+ wqbuf_lastindex = acb->wqbuf_lastindex;
+@@ -1483,7 +1481,7 @@
+ retvalue = ARCMSR_MESSAGE_FAIL;
+ }
+ }
+- pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle);
++ kfree(ver_addr);
+ }
+ break;
+
+diff -Nurd linux-2.6.24/drivers/scsi/gdth.c linux-2.6.24-oxe810/drivers/scsi/gdth.c
+--- linux-2.6.24/drivers/scsi/gdth.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/scsi/gdth.c 2008-06-11 17:50:29.000000000 +0200
+@@ -160,7 +160,7 @@
+ static void gdth_clear_events(void);
+
+ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
+- char *buffer, ushort count, int to_buffer);
++ char *buffer, ushort count);
+ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp);
+ static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive);
+
+@@ -183,7 +183,6 @@
+ unsigned int cmd, unsigned long arg);
+
+ static void gdth_flush(gdth_ha_str *ha);
+-static int gdth_halt(struct notifier_block *nb, ulong event, void *buf);
+ static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *));
+ static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp,
+ struct gdth_cmndinfo *cmndinfo);
+@@ -418,12 +417,6 @@
+ #include "gdth_proc.h"
+ #include "gdth_proc.c"
+
+-/* notifier block to get a notify on system shutdown/halt/reboot */
+-static struct notifier_block gdth_notifier = {
+- gdth_halt, NULL, 0
+-};
+-static int notifier_disabled = 0;
+-
+ static gdth_ha_str *gdth_find_ha(int hanum)
+ {
+ gdth_ha_str *ha;
+@@ -446,8 +439,8 @@
+ for (i=0; i<GDTH_MAXCMDS; ++i) {
+ if (ha->cmndinfo[i].index == 0) {
+ priv = &ha->cmndinfo[i];
+- priv->index = i+1;
+ memset(priv, 0, sizeof(*priv));
++ priv->index = i+1;
+ break;
+ }
+ }
+@@ -494,7 +487,6 @@
+ gdth_ha_str *ha = shost_priv(sdev->host);
+ Scsi_Cmnd *scp;
+ struct gdth_cmndinfo cmndinfo;
+- struct scatterlist one_sg;
+ DECLARE_COMPLETION_ONSTACK(wait);
+ int rval;
+
+@@ -508,13 +500,10 @@
+ /* use request field to save the ptr. to completion struct. */
+ scp->request = (struct request *)&wait;
+ scp->timeout_per_command = timeout*HZ;
+- sg_init_one(&one_sg, gdtcmd, sizeof(*gdtcmd));
+- gdth_set_sglist(scp, &one_sg);
+- gdth_set_sg_count(scp, 1);
+- gdth_set_bufflen(scp, sizeof(*gdtcmd));
+ scp->cmd_len = 12;
+ memcpy(scp->cmnd, cmnd, 12);
+ cmndinfo.priority = IOCTL_PRI;
++ cmndinfo.internal_cmd_str = gdtcmd;
+ cmndinfo.internal_command = 1;
+
+ TRACE(("__gdth_execute() cmd 0x%x\n", scp->cmnd[0]));
+@@ -2355,7 +2344,7 @@
+ * buffers, kmap_atomic() as needed.
+ */
+ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
+- char *buffer, ushort count, int to_buffer)
++ char *buffer, ushort count)
+ {
+ ushort cpcount,i, max_sg = gdth_sg_count(scp);
+ ushort cpsum,cpnow;
+@@ -2381,10 +2370,7 @@
+ }
+ local_irq_save(flags);
+ address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset;
+- if (to_buffer)
+- memcpy(buffer, address, cpnow);
+- else
+- memcpy(address, buffer, cpnow);
++ memcpy(address, buffer, cpnow);
+ flush_dcache_page(sg_page(sl));
+ kunmap_atomic(address, KM_BIO_SRC_IRQ);
+ local_irq_restore(flags);
+@@ -2438,7 +2424,7 @@
+ strcpy(inq.vendor,ha->oem_name);
+ sprintf(inq.product,"Host Drive #%02d",t);
+ strcpy(inq.revision," ");
+- gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data), 0);
++ gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data));
+ break;
+
+ case REQUEST_SENSE:
+@@ -2448,7 +2434,7 @@
+ sd.key = NO_SENSE;
+ sd.info = 0;
+ sd.add_length= 0;
+- gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data), 0);
++ gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data));
+ break;
+
+ case MODE_SENSE:
+@@ -2460,7 +2446,7 @@
+ mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16;
+ mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8;
+ mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff);
+- gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data), 0);
++ gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data));
+ break;
+
+ case READ_CAPACITY:
+@@ -2470,7 +2456,7 @@
+ else
+ rdc.last_block_no = cpu_to_be32(ha->hdr[t].size-1);
+ rdc.block_length = cpu_to_be32(SECTOR_SIZE);
+- gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data), 0);
++ gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data));
+ break;
+
+ case SERVICE_ACTION_IN:
+@@ -2482,7 +2468,7 @@
+ rdc16.last_block_no = cpu_to_be64(ha->hdr[t].size-1);
+ rdc16.block_length = cpu_to_be32(SECTOR_SIZE);
+ gdth_copy_internal_data(ha, scp, (char*)&rdc16,
+- sizeof(gdth_rdcap16_data), 0);
++ sizeof(gdth_rdcap16_data));
+ } else {
+ scp->result = DID_ABORT << 16;
+ }
+@@ -2852,6 +2838,7 @@
+ static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp)
+ {
+ register gdth_cmd_str *cmdp;
++ struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);
+ int cmd_index;
+
+ cmdp= ha->pccb;
+@@ -2860,7 +2847,7 @@
+ if (ha->type==GDT_EISA && ha->cmd_cnt>0)
+ return 0;
+
+- gdth_copy_internal_data(ha, scp, (char *)cmdp, sizeof(gdth_cmd_str), 1);
++ *cmdp = *cmndinfo->internal_cmd_str;
+ cmdp->RequestBuffer = scp;
+
+ /* search free command index */
+@@ -3793,6 +3780,8 @@
+ gdth_ha_str *ha;
+ ulong flags;
+
++ BUG_ON(list_empty(&gdth_instances));
++
+ ha = list_first_entry(&gdth_instances, gdth_ha_str, list);
+ spin_lock_irqsave(&ha->smp_lock, flags);
+
+@@ -4668,45 +4657,6 @@
+ }
+ }
+
+-/* shutdown routine */
+-static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
+-{
+- gdth_ha_str *ha;
+-#ifndef __alpha__
+- gdth_cmd_str gdtcmd;
+- char cmnd[MAX_COMMAND_SIZE];
+-#endif
+-
+- if (notifier_disabled)
+- return NOTIFY_OK;
+-
+- TRACE2(("gdth_halt() event %d\n",(int)event));
+- if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF)
+- return NOTIFY_DONE;
+-
+- notifier_disabled = 1;
+- printk("GDT-HA: Flushing all host drives .. ");
+- list_for_each_entry(ha, &gdth_instances, list) {
+- gdth_flush(ha);
+-
+-#ifndef __alpha__
+- /* controller reset */
+- memset(cmnd, 0xff, MAX_COMMAND_SIZE);
+- gdtcmd.BoardNode = LOCALBOARD;
+- gdtcmd.Service = CACHESERVICE;
+- gdtcmd.OpCode = GDT_RESET;
+- TRACE2(("gdth_halt(): reset controller %d\n", ha->hanum));
+- gdth_execute(ha->shost, &gdtcmd, cmnd, 10, NULL);
+-#endif
+- }
+- printk("Done.\n");
+-
+-#ifdef GDTH_STATISTICS
+- del_timer(&gdth_timer);
+-#endif
+- return NOTIFY_OK;
+-}
+-
+ /* configure lun */
+ static int gdth_slave_configure(struct scsi_device *sdev)
+ {
+@@ -4838,6 +4788,9 @@
+ if (error)
+ goto out_free_coal_stat;
+ list_add_tail(&ha->list, &gdth_instances);
++
++ scsi_scan_host(shp);
++
+ return 0;
+
+ out_free_coal_stat:
+@@ -4965,6 +4918,9 @@
+ if (error)
+ goto out_free_coal_stat;
+ list_add_tail(&ha->list, &gdth_instances);
++
++ scsi_scan_host(shp);
++
+ return 0;
+
+ out_free_ccb_phys:
+@@ -5102,6 +5058,9 @@
+ if (error)
+ goto out_free_coal_stat;
+ list_add_tail(&ha->list, &gdth_instances);
++
++ scsi_scan_host(shp);
++
+ return 0;
+
+ out_free_coal_stat:
+@@ -5132,13 +5091,13 @@
+
+ scsi_remove_host(shp);
+
++ gdth_flush(ha);
++
+ if (ha->sdev) {
+ scsi_free_host_dev(ha->sdev);
+ ha->sdev = NULL;
+ }
+
+- gdth_flush(ha);
+-
+ if (shp->irq)
+ free_irq(shp->irq,ha);
+
+@@ -5164,6 +5123,24 @@
+ scsi_host_put(shp);
+ }
+
++static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
++{
++ gdth_ha_str *ha;
++
++ TRACE2(("gdth_halt() event %d\n", (int)event));
++ if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF)
++ return NOTIFY_DONE;
++
++ list_for_each_entry(ha, &gdth_instances, list)
++ gdth_flush(ha);
++
++ return NOTIFY_OK;
++}
++
++static struct notifier_block gdth_notifier = {
++ gdth_halt, NULL, 0
++};
++
+ static int __init gdth_init(void)
+ {
+ if (disable) {
+@@ -5226,7 +5203,6 @@
+ add_timer(&gdth_timer);
+ #endif
+ major = register_chrdev(0,"gdth", &gdth_fops);
+- notifier_disabled = 0;
+ register_reboot_notifier(&gdth_notifier);
+ gdth_polling = FALSE;
+ return 0;
+@@ -5236,14 +5212,15 @@
+ {
+ gdth_ha_str *ha;
+
+- list_for_each_entry(ha, &gdth_instances, list)
+- gdth_remove_one(ha);
++ unregister_chrdev(major, "gdth");
++ unregister_reboot_notifier(&gdth_notifier);
+
+ #ifdef GDTH_STATISTICS
+- del_timer(&gdth_timer);
++ del_timer_sync(&gdth_timer);
+ #endif
+- unregister_chrdev(major,"gdth");
+- unregister_reboot_notifier(&gdth_notifier);
++
++ list_for_each_entry(ha, &gdth_instances, list)
++ gdth_remove_one(ha);
+ }
+
+ module_init(gdth_init);
+diff -Nurd linux-2.6.24/drivers/scsi/gdth.h linux-2.6.24-oxe810/drivers/scsi/gdth.h
+--- linux-2.6.24/drivers/scsi/gdth.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/scsi/gdth.h 2008-06-11 17:50:29.000000000 +0200
+@@ -915,6 +915,7 @@
+ struct gdth_cmndinfo { /* per-command private info */
+ int index;
+ int internal_command; /* don't call scsi_done */
++ gdth_cmd_str *internal_cmd_str; /* crier for internal messages*/
+ dma_addr_t sense_paddr; /* sense dma-addr */
+ unchar priority;
+ int timeout;
+diff -Nurd linux-2.6.24/drivers/scsi/gdth_proc.c linux-2.6.24-oxe810/drivers/scsi/gdth_proc.c
+--- linux-2.6.24/drivers/scsi/gdth_proc.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/scsi/gdth_proc.c 2008-06-11 17:50:29.000000000 +0200
+@@ -694,15 +694,13 @@
+ {
+ ulong flags;
+
+- spin_lock_irqsave(&ha->smp_lock, flags);
+-
+ if (buf == ha->pscratch) {
++ spin_lock_irqsave(&ha->smp_lock, flags);
+ ha->scratch_busy = FALSE;
++ spin_unlock_irqrestore(&ha->smp_lock, flags);
+ } else {
+ pci_free_consistent(ha->pdev, size, buf, paddr);
+ }
+-
+- spin_unlock_irqrestore(&ha->smp_lock, flags);
+ }
+
+ #ifdef GDTH_IOCTL_PROC
+diff -Nurd linux-2.6.24/drivers/scsi/ips.c linux-2.6.24-oxe810/drivers/scsi/ips.c
+--- linux-2.6.24/drivers/scsi/ips.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/scsi/ips.c 2008-06-11 17:50:29.000000000 +0200
+@@ -1580,7 +1580,7 @@
+ METHOD_TRACE("ips_make_passthru", 1);
+
+ scsi_for_each_sg(SC, sg, scsi_sg_count(SC), i)
+- length += sg[i].length;
++ length += sg->length;
+
+ if (length < sizeof (ips_passthru_t)) {
+ /* wrong size */
+@@ -6842,13 +6842,10 @@
+ if (request_irq(ha->irq, do_ipsintr, IRQF_SHARED, ips_name, ha)) {
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "Unable to install interrupt handler\n");
+- scsi_host_put(sh);
+- return -1;
++ goto err_out_sh;
+ }
+
+ kfree(oldha);
+- ips_sh[index] = sh;
+- ips_ha[index] = ha;
+
+ /* Store away needed values for later use */
+ sh->io_port = ha->io_addr;
+@@ -6867,10 +6864,21 @@
+ sh->max_channel = ha->nbus - 1;
+ sh->can_queue = ha->max_cmds - 1;
+
+- scsi_add_host(sh, NULL);
++ if (scsi_add_host(sh, &ha->pcidev->dev))
++ goto err_out;
++
++ ips_sh[index] = sh;
++ ips_ha[index] = ha;
++
+ scsi_scan_host(sh);
+
+ return 0;
++
++err_out:
++ free_irq(ha->pcidev->irq, ha);
++err_out_sh:
++ scsi_host_put(sh);
++ return -1;
+ }
+
+ /*---------------------------------------------------------------------------*/
+diff -Nurd linux-2.6.24/drivers/scsi/scsi_lib.c linux-2.6.24-oxe810/drivers/scsi/scsi_lib.c
+--- linux-2.6.24/drivers/scsi/scsi_lib.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/scsi/scsi_lib.c 2008-06-11 17:50:29.000000000 +0200
+@@ -298,7 +298,6 @@
+ page = sg_page(sg);
+ off = sg->offset;
+ len = sg->length;
+- data_len += len;
+
+ while (len > 0 && data_len > 0) {
+ /*
+diff -Nurd linux-2.6.24/drivers/scsi/sd.c linux-2.6.24-oxe810/drivers/scsi/sd.c
+--- linux-2.6.24/drivers/scsi/sd.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/scsi/sd.c 2008-06-11 17:50:29.000000000 +0200
+@@ -907,6 +907,7 @@
+ unsigned int xfer_size = SCpnt->request_bufflen;
+ unsigned int good_bytes = result ? 0 : xfer_size;
+ u64 start_lba = SCpnt->request->sector;
++ u64 end_lba = SCpnt->request->sector + (xfer_size / 512);
+ u64 bad_lba;
+ struct scsi_sense_hdr sshdr;
+ int sense_valid = 0;
+@@ -945,26 +946,23 @@
+ goto out;
+ if (xfer_size <= SCpnt->device->sector_size)
+ goto out;
+- switch (SCpnt->device->sector_size) {
+- case 256:
++ if (SCpnt->device->sector_size < 512) {
++ /* only legitimate sector_size here is 256 */
+ start_lba <<= 1;
+- break;
+- case 512:
+- break;
+- case 1024:
+- start_lba >>= 1;
+- break;
+- case 2048:
+- start_lba >>= 2;
+- break;
+- case 4096:
+- start_lba >>= 3;
+- break;
+- default:
+- /* Print something here with limiting frequency. */
+- goto out;
+- break;
++ end_lba <<= 1;
++ } else {
++ /* be careful ... don't want any overflows */
++ u64 factor = SCpnt->device->sector_size / 512;
++ do_div(start_lba, factor);
++ do_div(end_lba, factor);
+ }
++
++ if (bad_lba < start_lba || bad_lba >= end_lba)
++ /* the bad lba was reported incorrectly, we have
++ * no idea where the error is
++ */
++ goto out;
++
+ /* This computation should always be done in terms of
+ * the resolution of the device's medium.
+ */
+diff -Nurd linux-2.6.24/drivers/serial/8250.c linux-2.6.24-oxe810/drivers/serial/8250.c
+--- linux-2.6.24/drivers/serial/8250.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/serial/8250.c 2008-06-11 17:48:56.000000000 +0200
+@@ -2153,7 +2153,37 @@
+ serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
+ }
+
+- serial_dl_write(up, quot);
++ if ((up->port.type == PORT_16550A) &&
++ (serial_in(up, UART_XON_CHAR) == 0x11) &&
++ (serial_in(up, UART_XOFF_CHAR) == 0x13))
++ {
++ /* We should now be dealing with an extended 16550A-type UART from
++ * the Oxsemi 0x800 */
++
++ /* Calculate values for DLM,DLL,DLF divisor registers from clock
++ * frequency in Hz and Baud rate in bits per second, and program them
++ * into the UART */
++ u32 tmp;
++ u8 lcr, dlm, dll, dlf;
++
++ tmp = port->uartclk / baud;
++ tmp = (tmp + 1) / 2;
++ dlm = tmp >> (8 + 3);
++ dll = (tmp >> 3) & 0xFF;
++ dlf = (tmp & 7) << 5;
++
++ lcr = serial_in(up, UART_LSR); /* Store LCR */
++
++ serial_outp(up, UART_LCR, 0x80); /* Enable access to DLM DLL */
++ serial_outp(up, UART_DLL, dll); /* LS of divisor */
++ serial_outp(up, UART_DLM, dlm); /* MS of divisor */
++ serial_outp(up, UART_DLF, dlf); /* Set non-standard fractional divisor */
++ serial_outp(up, UART_LCR, lcr); /* Restore LCR */
++
++ printk(KERN_INFO "Using fractional divider baud %d, clock %d dlf %02x\n", baud, port->uartclk, dlf);
++ } else {
++ serial_dl_write(up, quot);
++ }
+
+ /*
+ * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
+@@ -2519,7 +2549,11 @@
+ static int __init serial8250_console_setup(struct console *co, char *options)
+ {
+ struct uart_port *port;
+- int baud = 9600;
++#if defined (CONFIG_ARCH_OXNAS)
++ int baud = 115200;
++#else
++ int baud = 9600;
++#endif // defined (CONFIG_ARCH_OXNAS)
+ int bits = 8;
+ int parity = 'n';
+ int flow = 'n';
+diff -Nurd linux-2.6.24/drivers/spi/atmel_spi.c linux-2.6.24-oxe810/drivers/spi/atmel_spi.c
+--- linux-2.6.24/drivers/spi/atmel_spi.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/spi/atmel_spi.c 2008-06-11 17:49:13.000000000 +0200
+@@ -85,6 +85,16 @@
+ unsigned gpio = (unsigned) spi->controller_data;
+ unsigned active = spi->mode & SPI_CS_HIGH;
+ u32 mr;
++ int i;
++ u32 csr;
++ u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0;
++
++ /* Make sure clock polarity is correct */
++ for (i = 0; i < spi->master->num_chipselect; i++) {
++ csr = spi_readl(as, CSR0 + 4 * i);
++ if ((csr ^ cpol) & SPI_BIT(CPOL))
++ spi_writel(as, CSR0 + 4 * i, csr ^ SPI_BIT(CPOL));
++ }
+
+ mr = spi_readl(as, MR);
+ mr = SPI_BFINS(PCS, ~(1 << spi->chip_select), mr);
+diff -Nurd linux-2.6.24/drivers/spi/pxa2xx_spi.c linux-2.6.24-oxe810/drivers/spi/pxa2xx_spi.c
+--- linux-2.6.24/drivers/spi/pxa2xx_spi.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/spi/pxa2xx_spi.c 2008-06-11 17:49:13.000000000 +0200
+@@ -48,13 +48,19 @@
+ #define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
+ #define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0)
+
+-/* for testing SSCR1 changes that require SSP restart, basically
+- * everything except the service and interrupt enables */
+-#define SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_EBCEI | SSCR1_SCFR \
++/*
++ * for testing SSCR1 changes that require SSP restart, basically
++ * everything except the service and interrupt enables, the pxa270 developer
++ * manual says only SSCR1_SCFR, SSCR1_SPH, SSCR1_SPO need to be in this
++ * list, but the PXA255 dev man says all bits without really meaning the
++ * service and interrupt enables
++ */
++#define SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_SCFR \
+ | SSCR1_ECRA | SSCR1_ECRB | SSCR1_SCLKDIR \
+- | SSCR1_RWOT | SSCR1_TRAIL | SSCR1_PINTE \
+- | SSCR1_STRF | SSCR1_EFWR |SSCR1_RFT \
+- | SSCR1_TFT | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM)
++ | SSCR1_SFRMDIR | SSCR1_RWOT | SSCR1_TRAIL \
++ | SSCR1_IFS | SSCR1_STRF | SSCR1_EFWR \
++ | SSCR1_RFT | SSCR1_TFT | SSCR1_MWDS \
++ | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM)
+
+ #define DEFINE_SSP_REG(reg, off) \
+ static inline u32 read_##reg(void *p) { return __raw_readl(p + (off)); } \
+@@ -961,9 +967,6 @@
+ if (drv_data->ssp_type == PXA25x_SSP)
+ DCMD(drv_data->tx_channel) |= DCMD_ENDIRQEN;
+
+- /* Fix me, need to handle cs polarity */
+- drv_data->cs_control(PXA2XX_CS_ASSERT);
+-
+ /* Clear status and start DMA engine */
+ cr1 = chip->cr1 | dma_thresh | drv_data->dma_cr1;
+ write_SSSR(drv_data->clear_sr, reg);
+@@ -973,9 +976,6 @@
+ /* Ensure we have the correct interrupt handler */
+ drv_data->transfer_handler = interrupt_transfer;
+
+- /* Fix me, need to handle cs polarity */
+- drv_data->cs_control(PXA2XX_CS_ASSERT);
+-
+ /* Clear status */
+ cr1 = chip->cr1 | chip->threshold | drv_data->int_cr1;
+ write_SSSR(drv_data->clear_sr, reg);
+@@ -986,16 +986,29 @@
+ || (read_SSCR1(reg) & SSCR1_CHANGE_MASK) !=
+ (cr1 & SSCR1_CHANGE_MASK)) {
+
++ /* stop the SSP, and update the other bits */
+ write_SSCR0(cr0 & ~SSCR0_SSE, reg);
+ if (drv_data->ssp_type != PXA25x_SSP)
+ write_SSTO(chip->timeout, reg);
+- write_SSCR1(cr1, reg);
++ /* first set CR1 without interrupt and service enables */
++ write_SSCR1(cr1 & SSCR1_CHANGE_MASK, reg);
++ /* restart the SSP */
+ write_SSCR0(cr0, reg);
++
+ } else {
+ if (drv_data->ssp_type != PXA25x_SSP)
+ write_SSTO(chip->timeout, reg);
+- write_SSCR1(cr1, reg);
+ }
++
++ /* FIXME, need to handle cs polarity,
++ * this driver uses struct pxa2xx_spi_chip.cs_control to
++ * specify a CS handling function, and it ignores most
++ * struct spi_device.mode[s], including SPI_CS_HIGH */
++ drv_data->cs_control(PXA2XX_CS_ASSERT);
++
++ /* after chip select, release the data by enabling service
++ * requests and interrupts, without changing any mode bits */
++ write_SSCR1(cr1, reg);
+ }
+
+ static void pump_messages(struct work_struct *work)
+diff -Nurd linux-2.6.24/drivers/usb/Kconfig linux-2.6.24-oxe810/drivers/usb/Kconfig
+--- linux-2.6.24/drivers/usb/Kconfig 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/Kconfig 2008-06-11 17:50:19.000000000 +0200
+@@ -36,6 +36,7 @@
+ default y if ARCH_EP93XX
+ default y if ARCH_AT91
+ default y if ARCH_PNX4008
++ default y if ARCH_OXNAS
+ # PPC:
+ default y if STB03xxx
+ default y if PPC_MPC52xx
+@@ -49,6 +50,7 @@
+ boolean
+ default y if PPC_83xx
+ default y if SOC_AU1200
++ default y if ARCH_OXNAS
+ default PCI
+
+ # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
+diff -Nurd linux-2.6.24/drivers/usb/class/usblp.c linux-2.6.24-oxe810/drivers/usb/class/usblp.c
+--- linux-2.6.24/drivers/usb/class/usblp.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/class/usblp.c 2008-06-11 17:50:16.000000000 +0200
+@@ -428,6 +428,7 @@
+ usblp->rcomplete = 0;
+
+ if (handle_bidir(usblp) < 0) {
++ usb_autopm_put_interface(intf);
+ usblp->used = 0;
+ file->private_data = NULL;
+ retval = -EIO;
+diff -Nurd linux-2.6.24/drivers/usb/core/driver.c linux-2.6.24-oxe810/drivers/usb/core/driver.c
+--- linux-2.6.24/drivers/usb/core/driver.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/core/driver.c 2008-06-11 17:50:16.000000000 +0200
+@@ -534,8 +534,8 @@
+ id->driver_info is the way to create an entry that
+ indicates that the driver want to examine every
+ device and interface. */
+- for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
+- id->driver_info; id++) {
++ for (; id->idVendor || id->idProduct || id->bDeviceClass ||
++ id->bInterfaceClass || id->driver_info; id++) {
+ if (usb_match_one_id(interface, id))
+ return id;
+ }
+diff -Nurd linux-2.6.24/drivers/usb/core/hcd.h linux-2.6.24-oxe810/drivers/usb/core/hcd.h
+--- linux-2.6.24/drivers/usb/core/hcd.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/core/hcd.h 2008-06-11 17:50:16.000000000 +0200
+@@ -312,7 +312,9 @@
+ #define SetHubFeature (0x2000 | USB_REQ_SET_FEATURE)
+ #define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE)
+
+-
++#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
++#define ResetHubTT (0x2308)
++#endif
+ /*-------------------------------------------------------------------------*/
+
+ /*
+@@ -359,6 +361,11 @@
+
+ /*-------------------------------------------------------------------------*/
+
++extern int usb_register_root_hub (struct usb_device *usb_dev,
++ struct device *parent_dev);
++
++extern void usb_hcd_release (struct usb_bus *);
++
+ extern void usb_set_device_state(struct usb_device *udev,
+ enum usb_device_state new_state);
+
+diff -Nurd linux-2.6.24/drivers/usb/core/hub.c linux-2.6.24-oxe810/drivers/usb/core/hub.c
+--- linux-2.6.24/drivers/usb/core/hub.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/core/hub.c 2008-06-11 17:50:16.000000000 +0200
+@@ -2946,7 +2946,7 @@
+ if (len < le16_to_cpu(udev->config[index].desc.wTotalLength))
+ len = le16_to_cpu(udev->config[index].desc.wTotalLength);
+ }
+- buf = kmalloc (len, GFP_KERNEL);
++ buf = kmalloc(len, GFP_NOIO);
+ if (buf == NULL) {
+ dev_err(&udev->dev, "no mem to re-read configs after reset\n");
+ /* assume the worst */
+diff -Nurd linux-2.6.24/drivers/usb/gadget/fsl_usb2_udc.c linux-2.6.24-oxe810/drivers/usb/gadget/fsl_usb2_udc.c
+--- linux-2.6.24/drivers/usb/gadget/fsl_usb2_udc.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/gadget/fsl_usb2_udc.c 2008-06-11 17:50:17.000000000 +0200
+@@ -776,7 +776,7 @@
+ VDBG("%s, bad params\n", __FUNCTION__);
+ return -EINVAL;
+ }
+- if (!_ep || (!ep->desc && ep_index(ep))) {
++ if (unlikely(!_ep || !ep->desc)) {
+ VDBG("%s, bad ep\n", __FUNCTION__);
+ return -EINVAL;
+ }
+diff -Nurd linux-2.6.24/drivers/usb/host/Kconfig linux-2.6.24-oxe810/drivers/usb/host/Kconfig
+--- linux-2.6.24/drivers/usb/host/Kconfig 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/host/Kconfig 2008-06-11 17:50:19.000000000 +0200
+@@ -41,6 +41,7 @@
+ config USB_EHCI_ROOT_HUB_TT
+ bool "Root Hub Transaction Translators (EXPERIMENTAL)"
+ depends on USB_EHCI_HCD && EXPERIMENTAL
++ default y if ARCH_OXNAS
+ ---help---
+ Some EHCI chips have vendor-specific extensions to integrate
+ transaction translators, so that no OHCI or UHCI companion
+diff -Nurd linux-2.6.24/drivers/usb/host/Makefile linux-2.6.24-oxe810/drivers/usb/host/Makefile
+--- linux-2.6.24/drivers/usb/host/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/host/Makefile 2008-06-11 17:50:19.000000000 +0200
+@@ -3,7 +3,11 @@
+ #
+
+ ifeq ($(CONFIG_USB_DEBUG),y)
+- EXTRA_CFLAGS += -DDEBUG
++ EXTRA_CFLAGS += -DDEBUG
++endif
++
++ifeq ($(CONFIG_EHCI_VERBOSE_DEBUG),y)
++ EXTRA_CFLAGS += -DEHCI_VERBOSE_DEBUG
+ endif
+
+ obj-$(CONFIG_PCI) += pci-quirks.o
+@@ -16,4 +20,3 @@
+ obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o
+ obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o
+ obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o
+-
+diff -Nurd linux-2.6.24/drivers/usb/host/ehci-dbg.c linux-2.6.24-oxe810/drivers/usb/host/ehci-dbg.c
+--- linux-2.6.24/drivers/usb/host/ehci-dbg.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/host/ehci-dbg.c 2008-06-11 17:50:19.000000000 +0200
+@@ -28,11 +28,11 @@
+ dev_warn (ehci_to_hcd(ehci)->self.controller , fmt , ## args )
+
+ #ifdef EHCI_VERBOSE_DEBUG
+-# define vdbg dbg
+-# define ehci_vdbg ehci_dbg
++ #define vdbg dbg
++ #define ehci_vdbg ehci_dbg
+ #else
+-# define vdbg(fmt,args...) do { } while (0)
+-# define ehci_vdbg(ehci, fmt, args...) do { } while (0)
++ #define vdbg(fmt,args...) do { } while (0)
++ #define ehci_vdbg(ehci, fmt, args...) do { } while (0)
+ #endif
+
+ #ifdef DEBUG
+@@ -242,6 +242,10 @@
+ );
+ }
+
++#define PORT_SPD_HIGH (2 << 26)
++#define PORT_SPD_FULL (1 << 26)
++
++
+ static int
+ dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status)
+ {
+@@ -256,7 +260,7 @@
+ }
+
+ return scnprintf (buf, len,
+- "%s%sport %d status %06x%s%s sig=%s%s%s%s%s%s%s%s%s%s",
++ "%s%sport %d status %06x%s%s sig=%s %s%s%s%s%s%s%s%s%s %s",
+ label, label [0] ? " " : "", port, status,
+ (status & PORT_POWER) ? " POWER" : "",
+ (status & PORT_OWNER) ? " OWNER" : "",
+@@ -269,7 +273,9 @@
+ (status & PORT_PEC) ? " PEC" : "",
+ (status & PORT_PE) ? " PE" : "",
+ (status & PORT_CSC) ? " CSC" : "",
+- (status & PORT_CONNECT) ? " CONNECT" : "");
++ (status & PORT_CONNECT) ? " CONNECT" : "",
++ (status & PORT_SPD_HIGH) ? ((status & PORT_SPD_FULL) ? "??" : "HIGH" ) : (status & PORT_SPD_FULL) ? "LOW" : "FULL"
++ );
+ }
+
+ #else
+@@ -783,13 +789,38 @@
+ size -= temp;
+ next += temp;
+ #endif
+-
++#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
++ long unsigned tt_status =readl((u32)ehci->regs +TT_STATUS);
++ temp = scnprintf (next, size,
++ "tt status %08lx \n",
++ tt_status);
++ size -= temp;
++ next += temp;
++#endif
+ done:
+ spin_unlock_irqrestore (&ehci->lock, flags);
+
+ return PAGE_SIZE - size;
+ }
+ static CLASS_DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
++#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
++static ssize_t
++reset_tt (struct class_device *class_dev, const char *buf, size_t len)
++{
++ struct usb_bus *bus;
++ struct usb_hcd *hcd;
++ struct ehci_hcd *ehci;
++
++ bus = class_get_devdata(class_dev);
++ hcd = bus->hcpriv;
++ ehci = hcd_to_ehci (hcd);
++
++ *((u32 *) ((u32)ehci->regs +TT_STATUS)) = 2;
++ return len;
++}
++
++static CLASS_DEVICE_ATTR (tt_reset, S_IWUGO, NULL, reset_tt );
++#endif
+
+ static inline void create_debug_files (struct ehci_hcd *ehci)
+ {
+@@ -799,6 +830,9 @@
+ retval = class_device_create_file(cldev, &class_device_attr_async);
+ retval = class_device_create_file(cldev, &class_device_attr_periodic);
+ retval = class_device_create_file(cldev, &class_device_attr_registers);
++#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
++ class_device_create_file(cldev, &class_device_attr_tt_reset);
++#endif
+ }
+
+ static inline void remove_debug_files (struct ehci_hcd *ehci)
+@@ -808,6 +842,9 @@
+ class_device_remove_file(cldev, &class_device_attr_async);
+ class_device_remove_file(cldev, &class_device_attr_periodic);
+ class_device_remove_file(cldev, &class_device_attr_registers);
++#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
++ class_device_remove_file(cldev, &class_device_attr_tt_reset);
++#endif
+ }
+
+ #endif /* STUB_DEBUG_FILES */
+diff -Nurd linux-2.6.24/drivers/usb/host/ehci-hcd.c linux-2.6.24-oxe810/drivers/usb/host/ehci-hcd.c
+--- linux-2.6.24/drivers/usb/host/ehci-hcd.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/host/ehci-hcd.c 2008-06-11 17:50:19.000000000 +0200
+@@ -197,7 +197,7 @@
+ u32 __iomem *reg_ptr;
+ u32 tmp;
+
+- reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + USBMODE);
++ reg_ptr = (u32 __iomem *)&ehci->regs->usbmode;
+ tmp = ehci_readl(ehci, reg_ptr);
+ tmp |= USBMODE_CM_HC;
+ /* The default byte access to MMR space is LE after
+@@ -207,6 +207,20 @@
+ if (ehci_big_endian_mmio(ehci))
+ tmp |= USBMODE_BE;
+ ehci_writel(ehci, tmp, reg_ptr);
++
++#ifdef CONFIG_ARCH_OXNAS
++ reg_ptr = (u32 __iomem *)&ehci->regs->txfilltuning;
++ tmp = ehci_readl(ehci, reg_ptr);
++ tmp &= ~0x00ff0000;
++ tmp |= 0x00200000; /* set burst pre load count to 16 */
++ tmp |= 0x16; /* set sheduler overhead to 3 * 1.267us */
++ ehci_writel(ehci, tmp, reg_ptr);
++
++ reg_ptr = (u32 __iomem *)&ehci->regs->txttfilltuning;
++ tmp = readl (reg_ptr);
++ tmp |= 0x2; /* set sheduler overhead to 2 * 6.333us */
++ writel (tmp, reg_ptr);
++#endif // CONFIG_ARCH_OXNAS
+ }
+
+ /* reset a non-running (STS_HALT == 1) controller */
+@@ -225,9 +239,17 @@
+
+ if (retval)
+ return retval;
++ if (ehci->is_tdi_rh_tt)
++ tdi_reset(ehci); /* set TDI EHCI internal registers */
++#ifdef CONFIG_ARCH_OXNAS
++ command=readl(&ehci->regs->port_status[1]);
++ command |=0xc0000000; /* force use of serial PHY on 1st full speed port */
++ writel(command,&ehci->regs->port_status[1]);
+
+- if (ehci_is_TDI(ehci))
+- tdi_reset (ehci);
++ command=readl(&ehci->regs->port_status[2]);
++ command |=0xc0000000; /* force use of serial PHY on 2nd full speed port */
++ writel(command,&ehci->regs->port_status[2]);
++#endif // CONFIG_ARCH_OXNAS
+
+ return retval;
+ }
+@@ -939,10 +961,15 @@
+ MODULE_AUTHOR (DRIVER_AUTHOR);
+ MODULE_LICENSE ("GPL");
+
++#ifdef CONFIG_ARCH_OXNAS
++#include "ehci-oxnas.c"
++#define PLATFORM_DRIVER ehci_hcd_oxnas_driver
++#else // CONFIG_ARCH_OXNAS
+ #ifdef CONFIG_PCI
+ #include "ehci-pci.c"
+ #define PCI_DRIVER ehci_pci_driver
+-#endif
++#endif // CONFIG_PCI
++#endif // CONFIG_ARCH_OXNAS
+
+ #ifdef CONFIG_USB_EHCI_FSL
+ #include "ehci-fsl.c"
+diff -Nurd linux-2.6.24/drivers/usb/host/ehci-hub.c linux-2.6.24-oxe810/drivers/usb/host/ehci-hub.c
+--- linux-2.6.24/drivers/usb/host/ehci-hub.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/host/ehci-hub.c 2008-06-11 17:50:19.000000000 +0200
+@@ -769,6 +769,11 @@
+ dbg_port (ehci, "GetStatus", wIndex + 1, temp);
+ put_unaligned(cpu_to_le32 (status), (__le32 *) buf);
+ break;
++#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
++ case ResetHubTT :
++ *((u32 *) ((u32)ehci->regs +TT_STATUS)) = 2;
++ break;
++#endif
+ case SetHubFeature:
+ switch (wValue) {
+ case C_HUB_LOCAL_POWER:
+@@ -825,6 +830,23 @@
+ temp |= PORT_RESET;
+ temp &= ~PORT_PE;
+
++#if defined(CONFIG_USB_EHCI_ROOT_HUB_TT) & defined (CONFIG_ARCH_OXNAS) & 0
++ printk(KERN_ERR "port using status raw %lx\n",temp);
++ temp &= 0x0fffffffL; /* remove default data source */
++ if (temp & (1 << 27 ))
++ {
++ /* set the input to the UTMI input */
++ temp |= 0x20000000L;
++ printk(KERN_ERR "port using UTMI %d\n",wIndex);
++ }
++ else
++ {
++ /* set the input to the serial PHY input */
++ temp |= 0xE0000000L;
++ printk(KERN_ERR "port using serial PHY %d\n",wIndex);
++ }
++ writel(temp, &ehci->regs->port_status [wIndex]);
++#endif
+ /*
+ * caller must wait, then call GetPortStatus
+ * usb 2.0 spec says 50 ms resets on root
+diff -Nurd linux-2.6.24/drivers/usb/host/ehci-oxnas.c linux-2.6.24-oxe810/drivers/usb/host/ehci-oxnas.c
+--- linux-2.6.24/drivers/usb/host/ehci-oxnas.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/host/ehci-oxnas.c 2008-06-11 17:50:19.000000000 +0200
+@@ -0,0 +1,307 @@
++/*
++ * EHCI HCD (Host Controller Driver) for USB.
++ *
++ * (C) Copyright 2005 John Larkworthy <john.larkworthy@oxsemi.com>
++ *
++ * OXNAS Bus Glue
++ *
++ * Written by John Larkworthy
++ *
++ * This file is licenced under the GPL.
++ */
++
++#include <linux/platform_device.h>
++#include <asm/hardware.h>
++
++extern spinlock_t oxnas_gpio_spinlock;
++
++int usb_patch = 1;
++
++module_param(usb_patch, int, 1);
++MODULE_PARM_DESC (usb_patch, "use usb hw patch");
++
++/* called during probe() after chip reset completes */
++static int ehci_oxnas_setup(struct usb_hcd *hcd)
++{
++ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
++ int temp;
++ int retval;
++
++ ehci->caps = hcd->regs;
++ ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase));
++ dbg_hcs_params(ehci, "reset");
++ dbg_hcc_params(ehci, "reset");
++
++ /* cache this readonly data; minimize chip reads */
++ ehci->hcs_params = readl(&ehci->caps->hcs_params);
++
++ retval = ehci_halt(ehci);
++ if (retval)
++ return retval;
++
++ /* data structure init */
++ retval = ehci_init(hcd);
++ if (retval)
++ return retval;
++
++ if (ehci_is_TDI(ehci))
++ ehci_reset(ehci);
++
++ /* at least the Genesys GL880S needs fixup here */
++ temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params);
++ temp &= 0x0f;
++ if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) {
++ ehci_dbg(ehci, "bogus port configuration: "
++ "cc=%d x pcc=%d < ports=%d\n",
++ HCS_N_CC(ehci->hcs_params),
++ HCS_N_PCC(ehci->hcs_params),
++ HCS_N_PORTS(ehci->hcs_params));
++ }
++
++ ehci_port_power(ehci, 0);
++
++ return retval;
++}
++
++static const struct hc_driver ehci_oxnas_driver = {
++ .description = hcd_name,
++ .product_desc = "OXNAS EHCI Host Controller",
++ .hcd_priv_size = sizeof(struct ehci_hcd),
++
++ /*
++ * generic hardware linkage
++ */
++ .irq = ehci_irq,
++ .flags = HCD_MEMORY | HCD_USB2,
++
++ /*
++ * basic lifecycle operations
++ */
++ .reset = ehci_oxnas_setup,
++ .start = ehci_run,
++#ifdef CONFIG_PM
++ .suspend = ehci_suspend,
++ .resume = ehci_resume,
++#endif
++ .stop = ehci_stop,
++ .shutdown = ehci_shutdown,
++
++ /*
++ * managing i/o requests and associated device resources
++ */
++ .urb_enqueue = ehci_urb_enqueue,
++ .urb_dequeue = ehci_urb_dequeue,
++ .endpoint_disable = ehci_endpoint_disable,
++
++ /*
++ * scheduling support
++ */
++ .get_frame_number = ehci_get_frame,
++
++ /*
++ * root hub support
++ */
++ .hub_status_data = ehci_hub_status_data,
++ .hub_control = ehci_hub_control,
++ .bus_suspend = ehci_bus_suspend,
++ .bus_resume = ehci_bus_resume,
++};
++
++static int start_oxnas_usb_ehci(struct platform_device *dev)
++{
++ unsigned long flags;
++ unsigned long input_polarity = 0;
++ unsigned long output_polarity = 0;
++ unsigned long power_switch_mask = 0;
++ unsigned long power_monitor_mask = 0;
++ unsigned long power_lines_mask = 0;
++
++ if (usb_disabled())
++ return -ENODEV;
++
++ pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
++ hcd_name,
++ sizeof (struct ehci_qh), sizeof (struct ehci_qtd),
++ sizeof (struct ehci_itd), sizeof (struct ehci_sitd));
++
++#ifdef CONFIG_OXNAS_USB_PORTA_POWER_CONTROL
++ power_switch_mask |= (1UL << USBA_POWO_GPIO);
++ power_monitor_mask |= (1UL << USBA_OVERI_GPIO);
++#endif // CONFIG_OXNAS_USB_PORTA_POWER_CONTROL
++
++#ifdef CONFIG_OXNAS_USB_PORTB_POWER_CONTROL
++ power_switch_mask |= (1UL << USBB_POWO_GPIO);
++ power_monitor_mask |= (1UL << USBB_OVERI_GPIO);
++#endif // CONFIG_OXNAS_USB_PORTB_POWER_CONTROL
++
++#ifdef CONFIG_OXNAS_USB_PORTC_POWER_CONTROL
++ power_switch_mask |= (1UL << USBC_POWO_GPIO);
++ power_monitor_mask |= (1UL << USBC_OVERI_GPIO);
++#endif // CONFIG_OXNAS_USB_PORTC_POWER_CONTROL
++
++ power_lines_mask = power_switch_mask | power_monitor_mask;
++
++ // Configure USB power monitoring input and switch output GPIOs
++#ifdef CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE
++ input_polarity = ((1UL << SYS_CTRL_USBHSMPH_IP_POL_A_BIT) |
++ (1UL << SYS_CTRL_USBHSMPH_IP_POL_B_BIT) |
++ (1UL << SYS_CTRL_USBHSMPH_IP_POL_C_BIT));
++#endif // CONFIG_OXNAS_USB_OVERCURRENT_POLARITY_NEGATIVE
++
++#ifdef CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE
++ output_polarity = ((1UL << SYS_CTRL_USBHSMPH_OP_POL_A_BIT) |
++ (1UL << SYS_CTRL_USBHSMPH_OP_POL_B_BIT) |
++ (1UL << SYS_CTRL_USBHSMPH_OP_POL_C_BIT));
++#endif // CONFIG_OXNAS_USB_POWER_SWITCH_POLARITY_NEGATIVE
++
++ // Enable primary function on USB power monitor and switch lines
++ spin_lock_irqsave(&oxnas_gpio_spinlock, flags);
++ writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) | power_lines_mask, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
++ writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0) & ~power_lines_mask, SYS_CTRL_GPIO_SECSEL_CTRL_0);
++ writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0) & ~power_lines_mask, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
++ spin_unlock_irqrestore(&oxnas_gpio_spinlock, flags);
++
++ // Enable GPIO output on USB power switch output GPIOs
++ writel(power_switch_mask, GPIO_A_OUTPUT_ENABLE_SET);
++
++ // Enable GPIO input on USB power monitoring input GPIOs
++ writel(power_monitor_mask, GPIO_A_OUTPUT_ENABLE_CLEAR);
++
++ // Set the polarity of the USB power switch output and monitoring
++ // inputs in system control
++ if (usb_patch) {
++ writel(input_polarity | output_polarity| (1<<6) , SYS_CTRL_USBHSMPH_CTRL);
++ }
++ else {
++ writel(input_polarity | output_polarity, SYS_CTRL_USBHSMPH_CTRL);
++ }
++
++ // Ensure the USB block is properly reset
++ writel(1UL << SYS_CTRL_RSTEN_USBHS_BIT, SYS_CTRL_RSTEN_SET_CTRL);
++ writel(1UL << SYS_CTRL_RSTEN_USBHS_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
++ writel(1UL << SYS_CTRL_RSTEN_USBHSPHY_BIT, SYS_CTRL_RSTEN_SET_CTRL);
++ writel(1UL << SYS_CTRL_RSTEN_USBHSPHY_BIT, SYS_CTRL_RSTEN_CLR_CTRL);
++
++ // Force the high speed clock to be generated all the time, via serial
++ // programming of the USB HS PHY
++ writel((2UL << SYS_CTRL_USBHSPHY_TEST_ADD) |
++ (0xe0UL << SYS_CTRL_USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
++
++ writel((1UL << SYS_CTRL_USBHSPHY_TEST_CLK) |
++ (2UL << SYS_CTRL_USBHSPHY_TEST_ADD) |
++ (0xe0UL << SYS_CTRL_USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
++
++ writel((0xfUL << SYS_CTRL_USBHSPHY_TEST_ADD) |
++ (0xaaUL << SYS_CTRL_USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
++
++ writel((1UL << SYS_CTRL_USBHSPHY_TEST_CLK) |
++ (0xfUL << SYS_CTRL_USBHSPHY_TEST_ADD) |
++ (0xaaUL << SYS_CTRL_USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
++
++ // Enable the clock to the USB block
++ writel(1UL << SYS_CTRL_CKEN_USBHS_BIT, SYS_CTRL_CKEN_SET_CTRL);
++
++ // Ensure reset and clock operations are complete
++ wmb();
++
++ return 0;
++}
++
++static void stop_oxnas_usb_ehci(struct platform_device *dev)
++{
++ // put usb core into reset
++ writel(1UL << SYS_CTRL_RSTEN_USBHS_BIT, SYS_CTRL_RSTEN_SET_CTRL);
++
++ // Disable the clock to the USB block
++ writel(1UL << SYS_CTRL_CKEN_USBHS_BIT, SYS_CTRL_CKEN_CLR_CTRL);
++}
++
++/**
++ * usb_hcd_oxnas_probe - initialize OXNAS-based HCD
++ * Context: !in_interrupt()
++ *
++ * Allocates basic resources for this USB host controller.
++ *
++ */
++static int usb_hcd_oxnas_probe(const struct hc_driver *driver, struct platform_device *dev)
++{
++ int retval;
++ unsigned long ehci_id;
++ struct usb_hcd *hcd = 0;
++ struct ehci_hcd *ehci;
++
++ if (dev->num_resources != 2) {
++ pr_debug("wrong number of resources %d, expected %d", dev->num_resources, 2);
++ }
++
++ start_oxnas_usb_ehci(dev);
++
++ if (((ehci_id = readl(USB_BASE)) & 0x2f) != 0x05) {
++ pr_debug("wrong chip ID found %lx", ehci_id);
++ return -ENODEV;
++ }
++
++ hcd = usb_create_hcd(driver, &dev->dev, "usb");
++ if (!hcd) {
++ pr_debug("usb_create_hcd() failed");
++ retval = -ENOMEM;
++ }
++ hcd->regs = (void *)(USB_BASE + 0x100); /* adjust to point at cap length register */
++
++ printk(DRIVER_INFO "@%p Device ID register %lx\n", (void *)USB_BASE, *(unsigned long *)USB_BASE);
++
++ /* OXNAS device has a transaction translator */
++ ehci = hcd_to_ehci(hcd);
++ ehci->is_tdi_rh_tt = 1;
++
++ /* Finished initialisation and register */
++ if ((retval = usb_add_hcd(hcd, dev->resource[1].start, 0))) {
++ pr_debug("usb_add_hcd() failed");
++ stop_oxnas_usb_ehci(dev);
++ usb_put_hcd(hcd);
++ return retval;
++ }
++ return 0;
++}
++
++/**
++ * usb_hcd_oxnas_remove - shutdown processing for OXNAS-based HCD
++ * @dev: USB Host Controller being removed
++ * Context: !in_interrupt()
++ *
++ * Reverses the effect of usb_hcd_oxnas_probe(), first invoking
++ * the HCD's stop() method. It is always called from a thread
++ * context, normally "rmmod", "apmd", or something similar.
++ *
++ */
++static void usb_hcd_oxnas_remove(struct usb_hcd *hcd, struct platform_device *dev)
++{
++ usb_remove_hcd(hcd);
++ usb_put_hcd(hcd);
++ stop_oxnas_usb_ehci(dev);
++}
++
++static int ehci_hcd_oxnas_drv_probe(struct platform_device *dev)
++{
++ if (usb_disabled())
++ return -ENODEV;
++
++ return usb_hcd_oxnas_probe(&ehci_oxnas_driver, dev);
++}
++
++static int ehci_hcd_oxnas_drv_remove(struct platform_device *dev)
++{
++ usb_hcd_oxnas_remove(platform_get_drvdata(dev), dev);
++ return 0;
++}
++
++MODULE_ALIAS("oxnas-ehci");
++
++static struct platform_driver ehci_hcd_oxnas_driver = {
++ .probe = ehci_hcd_oxnas_drv_probe,
++ .remove = ehci_hcd_oxnas_drv_remove,
++ .shutdown = usb_hcd_platform_shutdown,
++ .driver = {
++ .name = "oxnas-ehci",
++ },
++};
+diff -Nurd linux-2.6.24/drivers/usb/host/ehci-q.c linux-2.6.24-oxe810/drivers/usb/host/ehci-q.c
+--- linux-2.6.24/drivers/usb/host/ehci-q.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/host/ehci-q.c 2008-06-11 17:50:19.000000000 +0200
+@@ -315,10 +315,10 @@
+ if (likely (last->urb != urb)) {
+ ehci_urb_done(ehci, last->urb, last_status);
+ count++;
++ last_status = -EINPROGRESS;
+ }
+ ehci_qtd_free (ehci, last);
+ last = NULL;
+- last_status = -EINPROGRESS;
+ }
+
+ /* ignore urbs submitted during completions we reported */
+diff -Nurd linux-2.6.24/drivers/usb/host/ehci-sched.c linux-2.6.24-oxe810/drivers/usb/host/ehci-sched.c
+--- linux-2.6.24/drivers/usb/host/ehci-sched.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/host/ehci-sched.c 2008-06-11 17:50:19.000000000 +0200
+@@ -2109,6 +2109,7 @@
+ {
+ unsigned frame, clock, now_uframe, mod;
+ unsigned modified;
++ u8 uncompleted_td = 0;
+
+ mod = ehci->periodic_size << 3;
+
+@@ -2188,8 +2189,10 @@
+ q = *q_p;
+ break;
+ }
+- if (uf != 8)
++ if (uf != 8){
++ uncompleted_td = 1;
+ break;
++ }
+
+ /* this one's ready ... HC won't cache the
+ * pointer for much longer, if at all.
+@@ -2214,6 +2217,7 @@
+ *q_p = q.sitd->sitd_next;
+ *hw_p = q.sitd->hw_next;
+ type = Q_NEXT_TYPE(ehci, q.sitd->hw_next);
++ uncompleted_td = 1;
+ wmb();
+ modified = sitd_complete (ehci, q.sitd);
+ q = *q_p;
+@@ -2239,6 +2243,12 @@
+ // don't exceed periodic_size msec (default 1.024 sec).
+
+ // FIXME: likewise assumes HC doesn't halt mid-scan
++
++ /* We must stat the next scan cycle at the first
++ * uncompleted TD so that TDs are not lost.
++ */
++ if ((!uncompleted_td) && (ehci_to_hcd(ehci)->state == HC_STATE_RUNNING))
++ ehci->next_uframe = now_uframe;
+
+ if (now_uframe == clock) {
+ unsigned now;
+diff -Nurd linux-2.6.24/drivers/usb/host/ehci.h linux-2.6.24-oxe810/drivers/usb/host/ehci.h
+--- linux-2.6.24/drivers/usb/host/ehci.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/host/ehci.h 2008-06-11 17:50:19.000000000 +0200
+@@ -262,14 +262,22 @@
+ /* ASYNCLISTADDR: offset 0x18 */
+ u32 async_next; /* address of next async queue head */
+
+- u32 reserved [9];
++ u32 ttctrl;
++ u32 burstsize;
++ u32 txfilltuning;
++ u32 txttfilltuning;
++ u32 reserved_1;
++ u32 ulpi_viewport;
++ u32 reserved_2;
++ u32 endpknack;
++ u32 endptnalek;
+
+ /* CONFIGFLAG: offset 0x40 */
+ u32 configured_flag;
+ #define FLAG_CF (1<<0) /* true: we'll support "high speed" */
+
+ /* PORTSC: offset 0x44 */
+- u32 port_status [0]; /* up to N_PORTS */
++ u32 port_status [8]; /* up to N_PORTS, max 8 */
+ /* 31:23 reserved */
+ #define PORT_WKOC_E (1<<22) /* wake on overcurrent (enable) */
+ #define PORT_WKDISC_E (1<<21) /* wake on disconnect (enable) */
+@@ -294,14 +302,22 @@
+ #define PORT_CSC (1<<1) /* connect status change */
+ #define PORT_CONNECT (1<<0) /* device connected */
+ #define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC)
+-} __attribute__ ((packed));
+
+-#define USBMODE 0x68 /* USB Device mode */
++ u32 otgsc;
++ u32 usbmode;
+ #define USBMODE_SDIS (1<<3) /* Stream disable */
+-#define USBMODE_BE (1<<2) /* BE/LE endianness select */
++#define USBMODE_BE (1<<2) /* BE/LE endianness select */
+ #define USBMODE_CM_HC (3<<0) /* host controller mode */
+ #define USBMODE_CM_IDLE (0<<0) /* idle state */
+
++ u32 endptsetupstack;
++ u32 endptprime;
++ u32 endptflush;
++ u32 endptstat;
++ u32 endptcomplete;
++ u32 endptctrl[8];
++} __attribute__ ((packed));
++
+ /* Appendix C, Debug port ... intended for use with special "debug devices"
+ * that can help if there's no serial console. (nonstandard enumeration.)
+ */
+@@ -682,6 +698,11 @@
+ }
+ return (1<<USB_PORT_FEAT_HIGHSPEED);
+ }
++#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
++/* TDI transaction translator status register and busy bit */
++#define TT_BUSY 0x1
++#define TT_STATUS (0x15c-0x140)
++#endif
+
+ #else
+
+diff -Nurd linux-2.6.24/drivers/usb/misc/usbtest.c linux-2.6.24-oxe810/drivers/usb/misc/usbtest.c
+--- linux-2.6.24/drivers/usb/misc/usbtest.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/misc/usbtest.c 2008-06-11 17:50:18.000000000 +0200
+@@ -993,6 +993,7 @@
+
+ u->context = &context;
+ u->complete = ctrl_complete;
++ u->transfer_flags |= URB_NO_SETUP_DMA_MAP;
+ }
+
+ /* queue the urbs */
+@@ -1151,6 +1152,7 @@
+ dbg ("ep %02x couldn't get halt status, %d", ep, retval);
+ return retval;
+ }
++ le16_to_cpus(&status);
+ if (status != 1) {
+ dbg ("ep %02x bogus status: %04x != 1", ep, status);
+ return -EINVAL;
+@@ -1207,7 +1209,7 @@
+ int retval = 0;
+ struct urb *urb;
+
+- urb = simple_alloc_urb (testdev_to_usbdev (dev), 0, 512);
++ urb = simple_alloc_urb (testdev_to_usbdev (dev), 0, 256);
+ if (urb == NULL)
+ return -ENOMEM;
+
+@@ -2100,6 +2102,10 @@
+ /* EZ-USB devices which download firmware to replace (or in our
+ * case augment) the default device implementation.
+ */
++ /* generic EZ-USB FX controller */
++ { USB_DEVICE (0x0547, 0x2131),
++ .driver_info = (unsigned long) &ez1_info,
++ },
+
+ /* generic EZ-USB FX controller */
+ { USB_DEVICE (0x0547, 0x2235),
+diff -Nurd linux-2.6.24/drivers/usb/serial/cp2101.c linux-2.6.24-oxe810/drivers/usb/serial/cp2101.c
+--- linux-2.6.24/drivers/usb/serial/cp2101.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/serial/cp2101.c 2008-06-11 17:50:15.000000000 +0200
+@@ -59,6 +59,7 @@
+ { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */
+ { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
+ { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */
++ { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */
+ { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */
+ { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */
+ { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */
+@@ -76,8 +77,13 @@
+ { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
+ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
+ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
++ { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
++ { USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */
++ { USB_DEVICE(0x10C4, 0xF003) }, /* Elan Digital Systems USBpulse100 */
++ { USB_DEVICE(0x10C4, 0xF004) }, /* Elan Digital Systems USBcount50 */
+ { USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */
+ { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
++ { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */
+ { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
+ { } /* Terminating Entry */
+ };
+diff -Nurd linux-2.6.24/drivers/usb/serial/ftdi_sio.c linux-2.6.24-oxe810/drivers/usb/serial/ftdi_sio.c
+--- linux-2.6.24/drivers/usb/serial/ftdi_sio.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/serial/ftdi_sio.c 2008-06-11 17:50:15.000000000 +0200
+@@ -310,6 +310,7 @@
+ };
+
+ static int ftdi_olimex_probe (struct usb_serial *serial);
++static int ftdi_mtxorb_hack_setup (struct usb_serial *serial);
+ static void ftdi_USB_UIRT_setup (struct ftdi_private *priv);
+ static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv);
+
+@@ -317,6 +318,10 @@
+ .probe = ftdi_olimex_probe,
+ };
+
++static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = {
++ .probe = ftdi_mtxorb_hack_setup,
++};
++
+ static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
+ .port_probe = ftdi_USB_UIRT_setup,
+ };
+@@ -379,6 +384,8 @@
+ { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
++ { USB_DEVICE(MTXORB_VK_VID, MTXORB_VK_PID),
++ .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
+ { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) },
+@@ -471,30 +478,29 @@
+ { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) },
+ /*
+- * These will probably use user-space drivers. Uncomment them if
+- * you need them or use the user-specified vendor/product module
+- * parameters (see ftdi_sio.h for the numbers). Make a fuss if
+- * you think the driver should recognize any of them by default.
++ * Due to many user requests for multiple ELV devices we enable
++ * them by default.
+ */
+- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) }, */
+- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) }, */
+- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) }, */
+- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UDF77_PID) }, */
+- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UIO88_PID) }, */
+- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UAD8_PID) }, */
+- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_UDA7_PID) }, */
+- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_USI2_PID) }, */
+- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_T1100_PID) }, */
+- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCD200_PID) }, */
+- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_ULA200_PID) }, */
+- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_CSI8_PID) }, */
+- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1000DL_PID) }, */
+- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, */
+- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) }, */
+- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, */
+- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, */
+- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, */
+- /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, */
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_UDF77_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_UIO88_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_UAD8_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_UDA7_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_USI2_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_T1100_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_PCD200_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_ULA200_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_CSI8_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1000DL_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) },
+ { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) },
+ { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },
+ { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) },
+@@ -545,6 +551,7 @@
+ { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HRC_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16IC_PID) },
+ { USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) },
+ { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) },
+ { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) },
+@@ -569,6 +576,7 @@
+ { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
+ { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) },
+ { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_olimex_quirk },
+ { }, /* Optional parameter entry */
+@@ -1299,6 +1307,23 @@
+ }
+
+ return 0;
++}
++
++/*
++ * The Matrix Orbital VK204-25-USB has an invalid IN endpoint.
++ * We have to correct it if we want to read from it.
++ */
++static int ftdi_mtxorb_hack_setup(struct usb_serial *serial)
++{
++ struct usb_host_endpoint *ep = serial->dev->ep_in[1];
++ struct usb_endpoint_descriptor *ep_desc = &ep->desc;
++
++ if (ep->enabled && ep_desc->wMaxPacketSize == 0) {
++ ep_desc->wMaxPacketSize = 0x40;
++ info("Fixing invalid wMaxPacketSize on read pipe");
++ }
++
++ return 0;
+ }
+
+ /* ftdi_shutdown is called from usbserial:usb_serial_disconnect
+diff -Nurd linux-2.6.24/drivers/usb/serial/ftdi_sio.h linux-2.6.24-oxe810/drivers/usb/serial/ftdi_sio.h
+--- linux-2.6.24/drivers/usb/serial/ftdi_sio.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/serial/ftdi_sio.h 2008-06-11 17:50:15.000000000 +0200
+@@ -98,6 +98,13 @@
+ #define FTDI_MTXORB_5_PID 0xFA05 /* Matrix Orbital Product Id */
+ #define FTDI_MTXORB_6_PID 0xFA06 /* Matrix Orbital Product Id */
+
++/*
++ * The following are the values for the Matrix Orbital VK204-25-USB
++ * display, which use the FT232RL.
++ */
++#define MTXORB_VK_VID 0x1b3d
++#define MTXORB_VK_PID 0x0158
++
+ /* Interbiometrics USB I/O Board */
+ /* Developed for Interbiometrics by Rudolf Gugler */
+ #define INTERBIOMETRICS_VID 0x1209
+@@ -245,6 +252,7 @@
+ #define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */
+ #define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */
+ #define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */
++#define FTDI_ELV_EM1010PC_PID 0xE0EF /* Engery monitor EM 1010 PC */
+
+ /*
+ * Definitions for ID TECH (www.idt-net.com) devices
+@@ -278,6 +286,7 @@
+ #define FTDI_ATIK_ATK16C_PID 0xDF32 /* ATIK ATK-16C Colour Camera */
+ #define FTDI_ATIK_ATK16HR_PID 0xDF31 /* ATIK ATK-16HR Grayscale Camera */
+ #define FTDI_ATIK_ATK16HRC_PID 0xDF33 /* ATIK ATK-16HRC Colour Camera */
++#define FTDI_ATIK_ATK16IC_PID 0xDF35 /* ATIK ATK-16IC Grayscale Camera */
+
+ /*
+ * Protego product ids
+@@ -534,6 +543,8 @@
+ #define OLIMEX_VID 0x15BA
+ #define OLIMEX_ARM_USB_OCD_PID 0x0003
+
++/* www.elsterelectricity.com Elster Unicom III Optical Probe */
++#define FTDI_ELSTER_UNICOM_PID 0xE700 /* Product Id */
+
+ /*
+ * The Mobility Lab (TML)
+diff -Nurd linux-2.6.24/drivers/usb/serial/keyspan.c linux-2.6.24-oxe810/drivers/usb/serial/keyspan.c
+--- linux-2.6.24/drivers/usb/serial/keyspan.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/serial/keyspan.c 2008-06-11 17:50:15.000000000 +0200
+@@ -838,7 +838,7 @@
+
+ port = (struct usb_serial_port *) urb->context;
+ tty = port->tty;
+- if (urb->actual_length) {
++ if (tty && urb->actual_length) {
+ /* 0x80 bit is error flag */
+ if ((data[0] & 0x80) == 0) {
+ /* no error on any byte */
+diff -Nurd linux-2.6.24/drivers/usb/serial/kobil_sct.c linux-2.6.24-oxe810/drivers/usb/serial/kobil_sct.c
+--- linux-2.6.24/drivers/usb/serial/kobil_sct.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/serial/kobil_sct.c 2008-06-11 17:50:15.000000000 +0200
+@@ -114,6 +114,7 @@
+ .usb_driver = &kobil_driver,
+ .id_table = id_table,
+ .num_interrupt_in = NUM_DONT_CARE,
++ .num_interrupt_out = NUM_DONT_CARE,
+ .num_bulk_in = 0,
+ .num_bulk_out = 0,
+ .num_ports = 1,
+diff -Nurd linux-2.6.24/drivers/usb/serial/option.c linux-2.6.24-oxe810/drivers/usb/serial/option.c
+--- linux-2.6.24/drivers/usb/serial/option.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/serial/option.c 2008-06-11 17:50:15.000000000 +0200
+@@ -180,6 +180,7 @@
+ { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */
+ { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */
+ { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */
++ { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */
+ { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */
+ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },
+ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
+diff -Nurd linux-2.6.24/drivers/usb/serial/pl2303.c linux-2.6.24-oxe810/drivers/usb/serial/pl2303.c
+--- linux-2.6.24/drivers/usb/serial/pl2303.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/serial/pl2303.c 2008-06-11 17:50:15.000000000 +0200
+@@ -65,6 +65,7 @@
+ { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID_2080) },
+ { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) },
+ { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) },
++ { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
+ { USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) },
+ { USB_DEVICE(RADIOSHACK_VENDOR_ID, RADIOSHACK_PRODUCT_ID) },
+ { USB_DEVICE(DCU10_VENDOR_ID, DCU10_PRODUCT_ID) },
+@@ -84,9 +85,10 @@
+ { USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) },
+ { USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) },
+ { USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) },
+- { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ID) },
+ { USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) },
+ { USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) },
++ { USB_DEVICE(HL340_VENDOR_ID, HL340_PRODUCT_ID) },
++ { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },
+ { } /* Terminating entry */
+ };
+
+diff -Nurd linux-2.6.24/drivers/usb/serial/pl2303.h linux-2.6.24-oxe810/drivers/usb/serial/pl2303.h
+--- linux-2.6.24/drivers/usb/serial/pl2303.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/serial/pl2303.h 2008-06-11 17:50:15.000000000 +0200
+@@ -35,6 +35,7 @@
+
+ #define RATOC_VENDOR_ID 0x0584
+ #define RATOC_PRODUCT_ID 0xb000
++#define RATOC_PRODUCT_ID_USB60F 0xb020
+
+ #define TRIPP_VENDOR_ID 0x2478
+ #define TRIPP_PRODUCT_ID 0x2008
+@@ -96,10 +97,6 @@
+ #define ALCOR_VENDOR_ID 0x058F
+ #define ALCOR_PRODUCT_ID 0x9720
+
+-/* Huawei E620 UMTS/HSDPA card (ID: 12d1:1001) */
+-#define HUAWEI_VENDOR_ID 0x12d1
+-#define HUAWEI_PRODUCT_ID 0x1001
+-
+ /* Willcom WS002IN Data Driver (by NetIndex Inc.) */
+ #define WS002IN_VENDOR_ID 0x11f6
+ #define WS002IN_PRODUCT_ID 0x2001
+@@ -107,3 +104,11 @@
+ /* Corega CG-USBRS232R Serial Adapter */
+ #define COREGA_VENDOR_ID 0x07aa
+ #define COREGA_PRODUCT_ID 0x002a
++
++/* HL HL-340 (ID: 4348:5523) */
++#define HL340_VENDOR_ID 0x4348
++#define HL340_PRODUCT_ID 0x5523
++
++/* Y.C. Cable U.S.A., Inc - USB to RS-232 */
++#define YCCABLE_VENDOR_ID 0x05ad
++#define YCCABLE_PRODUCT_ID 0x0fba
+diff -Nurd linux-2.6.24/drivers/usb/serial/sierra.c linux-2.6.24-oxe810/drivers/usb/serial/sierra.c
+--- linux-2.6.24/drivers/usb/serial/sierra.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/serial/sierra.c 2008-06-11 17:50:15.000000000 +0200
+@@ -104,6 +104,7 @@
+ { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
+ { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
+ { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */
++ { USB_DEVICE(0x1199, 0x0023) }, /* Sierra Wireless AirCard */
+
+ { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
+ { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
+@@ -117,9 +118,15 @@
+ { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */
+ { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */
+ { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */
++ { USB_DEVICE(0x1199, 0x6855) }, /* Sierra Wireless AirCard 880 U */
++ { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */
++
++ { USB_DEVICE(0x1199, 0x6468) }, /* Sierra Wireless MP3G - EVDO */
++ { USB_DEVICE(0x1199, 0x6469) }, /* Sierra Wireless MP3G - UMTS/HSPA */
+
+ { USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */
+ { USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */
++ { USB_DEVICE(0x05C6, 0x6613), .driver_info = DEVICE_1_PORT }, /* Onda H600/ZTE MF330 */
+
+ { USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER},
+ { }
+@@ -129,6 +136,7 @@
+ static struct usb_device_id id_table_1port [] = {
+ { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
+ { USB_DEVICE(0x0F3D, 0x0112) }, /* AirPrime/Sierra PC 5220 */
++ { USB_DEVICE(0x05C6, 0x6613) }, /* Onda H600/ZTE MF330 */
+ { }
+ };
+
+@@ -142,6 +150,7 @@
+ { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
+ { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
+ { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U*/
++ { USB_DEVICE(0x1199, 0x0023) }, /* Sierra Wireless AirCard */
+
+ { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
+ { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
+@@ -155,6 +164,10 @@
+ { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */
+ { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880E */
+ { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881E */
++ { USB_DEVICE(0x1199, 0x6855) }, /* Sierra Wireless AirCard 880 U */
++ { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881U */
++ { USB_DEVICE(0x1199, 0x6468) }, /* Sierra Wireless MP3G - EVDO */
++ { USB_DEVICE(0x1199, 0x6469) }, /* Sierra Wireless MP3G - UMTS/HSPA */
+ { }
+ };
+
+diff -Nurd linux-2.6.24/drivers/usb/storage/protocol.c linux-2.6.24-oxe810/drivers/usb/storage/protocol.c
+--- linux-2.6.24/drivers/usb/storage/protocol.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/storage/protocol.c 2008-06-11 17:50:16.000000000 +0200
+@@ -194,7 +194,7 @@
+ * and the starting offset within the page, and update
+ * the *offset and *index values for the next loop. */
+ cnt = 0;
+- while (cnt < buflen) {
++ while (cnt < buflen && sg) {
+ struct page *page = sg_page(sg) +
+ ((sg->offset + *offset) >> PAGE_SHIFT);
+ unsigned int poff =
+@@ -249,7 +249,8 @@
+ unsigned int offset = 0;
+ struct scatterlist *sg = NULL;
+
+- usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
++ buflen = min(buflen, srb->request_bufflen);
++ buflen = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
+ TO_XFER_BUF);
+ if (buflen < srb->request_bufflen)
+ srb->resid = srb->request_bufflen - buflen;
+diff -Nurd linux-2.6.24/drivers/usb/storage/unusual_devs.h linux-2.6.24-oxe810/drivers/usb/storage/unusual_devs.h
+--- linux-2.6.24/drivers/usb/storage/unusual_devs.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/drivers/usb/storage/unusual_devs.h 2008-06-11 17:50:16.000000000 +0200
+@@ -86,6 +86,14 @@
+ US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
+ #endif
+
++/* Reported by Grant Grundler <grundler@parisc-linux.org>
++ * HP r707 camera in "Disk" mode with 2.00.23 or 2.00.24 firmware.
++ */
++UNUSUAL_DEV( 0x03f0, 0x4002, 0x0001, 0x0001,
++ "HP",
++ "PhotoSmart R707",
++ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY),
++
+ /* Reported by Sebastian Kapfer <sebastian_kapfer@gmx.net>
+ * and Olaf Hering <olh@suse.de> (different bcd's, same vendor/product)
+ * for USB floppies that need the SINGLE_LUN enforcement.
+diff -Nurd linux-2.6.24/fs/adfs/file.c linux-2.6.24-oxe810/fs/adfs/file.c
+--- linux-2.6.24/fs/adfs/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/adfs/file.c 2008-06-11 17:47:02.000000000 +0200
+@@ -33,6 +33,7 @@
+ .fsync = file_fsync,
+ .write = do_sync_write,
+ .aio_write = generic_file_aio_write,
++ .sendfile = generic_file_sendfile,
+ .splice_read = generic_file_splice_read,
+ };
+
+diff -Nurd linux-2.6.24/fs/affs/file.c linux-2.6.24-oxe810/fs/affs/file.c
+--- linux-2.6.24/fs/affs/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/affs/file.c 2008-06-11 17:46:52.000000000 +0200
+@@ -35,6 +35,7 @@
+ .open = affs_file_open,
+ .release = affs_file_release,
+ .fsync = file_fsync,
++ .sendfile = generic_file_sendfile,
+ .splice_read = generic_file_splice_read,
+ };
+
+diff -Nurd linux-2.6.24/fs/afs/file.c linux-2.6.24-oxe810/fs/afs/file.c
+--- linux-2.6.24/fs/afs/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/afs/file.c 2008-06-11 17:46:51.000000000 +0200
+@@ -32,6 +32,7 @@
+ .aio_read = generic_file_aio_read,
+ .aio_write = afs_file_write,
+ .mmap = generic_file_readonly_mmap,
++ .sendfile = generic_file_sendfile,
+ .splice_read = generic_file_splice_read,
+ .fsync = afs_fsync,
+ .lock = afs_lock,
+diff -Nurd linux-2.6.24/fs/aio.c linux-2.6.24-oxe810/fs/aio.c
+--- linux-2.6.24/fs/aio.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/aio.c 2008-06-11 17:47:10.000000000 +0200
+@@ -997,6 +997,14 @@
+ /* everything turned out well, dispose of the aiocb. */
+ ret = __aio_put_req(ctx, iocb);
+
++ /*
++ * We have to order our ring_info tail store above and test
++ * of the wait list below outside the wait lock. This is
++ * like in wake_up_bit() where clearing a bit has to be
++ * ordered with the unlocked test.
++ */
++ smp_mb();
++
+ if (waitqueue_active(&ctx->wait))
+ wake_up(&ctx->wait);
+
+diff -Nurd linux-2.6.24/fs/bio.c linux-2.6.24-oxe810/fs/bio.c
+--- linux-2.6.24/fs/bio.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/bio.c 2008-06-11 17:47:10.000000000 +0200
+@@ -133,6 +133,7 @@
+ memset(bio, 0, sizeof(*bio));
+ bio->bi_flags = 1 << BIO_UPTODATE;
+ atomic_set(&bio->bi_cnt, 1);
++ bio->bi_raid = 0;
+ }
+
+ /**
+@@ -260,6 +261,7 @@
+ bio->bi_vcnt = bio_src->bi_vcnt;
+ bio->bi_size = bio_src->bi_size;
+ bio->bi_idx = bio_src->bi_idx;
++ bio->bi_raid = bio_src->bi_raid;
+ bio_phys_segments(q, bio);
+ bio_hw_segments(q, bio);
+ }
+diff -Nurd linux-2.6.24/fs/coda/file.c linux-2.6.24-oxe810/fs/coda/file.c
+--- linux-2.6.24/fs/coda/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/coda/file.c 2008-06-11 17:47:09.000000000 +0200
+@@ -238,6 +238,7 @@
+ .open = coda_open,
+ .release = coda_release,
+ .fsync = coda_fsync,
++ .sendfile = coda_file_sendfile,
+ .splice_read = coda_file_splice_read,
+ };
+
+diff -Nurd linux-2.6.24/fs/ecryptfs/file.c linux-2.6.24-oxe810/fs/ecryptfs/file.c
+--- linux-2.6.24/fs/ecryptfs/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/ecryptfs/file.c 2008-06-11 17:46:59.000000000 +0200
+@@ -292,6 +292,7 @@
+ .release = ecryptfs_release,
+ .fsync = ecryptfs_fsync,
+ .fasync = ecryptfs_fasync,
++ .sendfile = ecryptfs_sendfile,
+ .splice_read = generic_file_splice_read,
+ };
+
+@@ -309,6 +310,7 @@
+ .release = ecryptfs_release,
+ .fsync = ecryptfs_fsync,
+ .fasync = ecryptfs_fasync,
++ .sendfile = ecryptfs_sendfile,
+ .splice_read = generic_file_splice_read,
+ };
+
+diff -Nurd linux-2.6.24/fs/ecryptfs/mmap.c linux-2.6.24-oxe810/fs/ecryptfs/mmap.c
+--- linux-2.6.24/fs/ecryptfs/mmap.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/ecryptfs/mmap.c 2008-06-11 17:46:59.000000000 +0200
+@@ -263,52 +263,102 @@
+ return 0;
+ }
+
+-/* This function must zero any hole we create */
++/**
++ * ecryptfs_prepare_write
++ * @file: The eCryptfs file
++ * @page: The eCryptfs page
++ * @from: The start byte from which we will write
++ * @to: The end byte to which we will write
++ *
++ * This function must zero any hole we create
++ *
++ * Returns zero on success; non-zero otherwise
++ */
+ static int ecryptfs_prepare_write(struct file *file, struct page *page,
+ unsigned from, unsigned to)
+ {
+- int rc = 0;
+ loff_t prev_page_end_size;
++ int rc = 0;
+
+ if (!PageUptodate(page)) {
+- rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
+- PAGE_CACHE_SIZE,
+- page->mapping->host);
+- if (rc) {
+- printk(KERN_ERR "%s: Error attemping to read lower "
+- "page segment; rc = [%d]\n", __FUNCTION__, rc);
+- ClearPageUptodate(page);
+- goto out;
+- } else
++ struct ecryptfs_crypt_stat *crypt_stat =
++ &ecryptfs_inode_to_private(
++ file->f_path.dentry->d_inode)->crypt_stat;
++
++ if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)
++ || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) {
++ rc = ecryptfs_read_lower_page_segment(
++ page, page->index, 0, PAGE_CACHE_SIZE,
++ page->mapping->host);
++ if (rc) {
++ printk(KERN_ERR "%s: Error attemping to read "
++ "lower page segment; rc = [%d]\n",
++ __FUNCTION__, rc);
++ ClearPageUptodate(page);
++ goto out;
++ } else
++ SetPageUptodate(page);
++ } else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) {
++ if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) {
++ rc = ecryptfs_copy_up_encrypted_with_header(
++ page, crypt_stat);
++ if (rc) {
++ printk(KERN_ERR "%s: Error attempting "
++ "to copy the encrypted content "
++ "from the lower file whilst "
++ "inserting the metadata from "
++ "the xattr into the header; rc "
++ "= [%d]\n", __FUNCTION__, rc);
++ ClearPageUptodate(page);
++ goto out;
++ }
++ SetPageUptodate(page);
++ } else {
++ rc = ecryptfs_read_lower_page_segment(
++ page, page->index, 0, PAGE_CACHE_SIZE,
++ page->mapping->host);
++ if (rc) {
++ printk(KERN_ERR "%s: Error reading "
++ "page; rc = [%d]\n",
++ __FUNCTION__, rc);
++ ClearPageUptodate(page);
++ goto out;
++ }
++ SetPageUptodate(page);
++ }
++ } else {
++ rc = ecryptfs_decrypt_page(page);
++ if (rc) {
++ printk(KERN_ERR "%s: Error decrypting page "
++ "at index [%ld]; rc = [%d]\n",
++ __FUNCTION__, page->index, rc);
++ ClearPageUptodate(page);
++ goto out;
++ }
+ SetPageUptodate(page);
++ }
+ }
+-
+ prev_page_end_size = ((loff_t)page->index << PAGE_CACHE_SHIFT);
+-
+- /*
+- * If creating a page or more of holes, zero them out via truncate.
+- * Note, this will increase i_size.
+- */
++ /* If creating a page or more of holes, zero them out via truncate.
++ * Note, this will increase i_size. */
+ if (page->index != 0) {
+ if (prev_page_end_size > i_size_read(page->mapping->host)) {
+ rc = ecryptfs_truncate(file->f_path.dentry,
+ prev_page_end_size);
+ if (rc) {
+- printk(KERN_ERR "Error on attempt to "
++ printk(KERN_ERR "%s: Error on attempt to "
+ "truncate to (higher) offset [%lld];"
+- " rc = [%d]\n", prev_page_end_size, rc);
++ " rc = [%d]\n", __FUNCTION__,
++ prev_page_end_size, rc);
+ goto out;
+ }
+ }
+ }
+- /*
+- * Writing to a new page, and creating a small hole from start of page?
+- * Zero it out.
+- */
+- if ((i_size_read(page->mapping->host) == prev_page_end_size) &&
+- (from != 0)) {
++ /* Writing to a new page, and creating a small hole from start
++ * of page? Zero it out. */
++ if ((i_size_read(page->mapping->host) == prev_page_end_size)
++ && (from != 0))
+ zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0);
+- }
+ out:
+ return rc;
+ }
+diff -Nurd linux-2.6.24/fs/eventpoll.c linux-2.6.24-oxe810/fs/eventpoll.c
+--- linux-2.6.24/fs/eventpoll.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/eventpoll.c 2008-06-11 17:47:10.000000000 +0200
+@@ -353,7 +353,7 @@
+ spin_unlock_irqrestore(&psw->lock, flags);
+
+ /* Do really wake up now */
+- wake_up(wq);
++ wake_up_nested(wq, 1 + wake_nests);
+
+ /* Remove the current task from the list */
+ spin_lock_irqsave(&psw->lock, flags);
+diff -Nurd linux-2.6.24/fs/ext2/file.c linux-2.6.24-oxe810/fs/ext2/file.c
+--- linux-2.6.24/fs/ext2/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/ext2/file.c 2008-06-11 17:47:06.000000000 +0200
+@@ -56,6 +56,7 @@
+ .open = generic_file_open,
+ .release = ext2_release_file,
+ .fsync = ext2_sync_file,
++ .sendfile = generic_file_sendfile,
+ .splice_read = generic_file_splice_read,
+ .splice_write = generic_file_splice_write,
+ };
+@@ -73,6 +74,7 @@
+ .open = generic_file_open,
+ .release = ext2_release_file,
+ .fsync = ext2_sync_file,
++ .sendfile = xip_file_sendfile,
+ };
+ #endif
+
+diff -Nurd linux-2.6.24/fs/ext3/file.c linux-2.6.24-oxe810/fs/ext3/file.c
+--- linux-2.6.24/fs/ext3/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/ext3/file.c 2008-06-11 17:47:06.000000000 +0200
+@@ -120,6 +120,7 @@
+ .open = generic_file_open,
+ .release = ext3_release_file,
+ .fsync = ext3_sync_file,
++ .sendfile = generic_file_sendfile,
+ .splice_read = generic_file_splice_read,
+ .splice_write = generic_file_splice_write,
+ };
+diff -Nurd linux-2.6.24/fs/ext3/ialloc.c linux-2.6.24-oxe810/fs/ext3/ialloc.c
+--- linux-2.6.24/fs/ext3/ialloc.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/ext3/ialloc.c 2008-06-11 17:47:06.000000000 +0200
+@@ -543,7 +543,16 @@
+ percpu_counter_inc(&sbi->s_dirs_counter);
+ sb->s_dirt = 1;
+
++#ifdef CONFIG_OXNAS_SUID_INHERIT
++ if (dir->i_mode & S_ISUID) {
++ inode->i_uid = dir->i_uid;
++ if (S_ISDIR(mode))
++ mode |= S_ISUID;
++ } else
++#else // CONFIG_OXNAS_SUID_INHERIT
+ inode->i_uid = current->fsuid;
++#endif // CONFIG_OXNAS_SUID_INHERIT
++
+ if (test_opt (sb, GRPID))
+ inode->i_gid = dir->i_gid;
+ else if (dir->i_mode & S_ISGID) {
+diff -Nurd linux-2.6.24/fs/ext4/file.c linux-2.6.24-oxe810/fs/ext4/file.c
+--- linux-2.6.24/fs/ext4/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/ext4/file.c 2008-06-11 17:47:07.000000000 +0200
+@@ -120,7 +120,8 @@
+ .open = generic_file_open,
+ .release = ext4_release_file,
+ .fsync = ext4_sync_file,
+- .splice_read = generic_file_splice_read,
++ .sendfile = generic_file_sendfile,
++ .splice_read = generic_file_splice_read,
+ .splice_write = generic_file_splice_write,
+ };
+
+diff -Nurd linux-2.6.24/fs/fat/file.c linux-2.6.24-oxe810/fs/fat/file.c
+--- linux-2.6.24/fs/fat/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/fat/file.c 2008-06-11 17:47:05.000000000 +0200
+@@ -134,6 +134,7 @@
+ .release = fat_file_release,
+ .ioctl = fat_generic_ioctl,
+ .fsync = file_fsync,
++ .sendfile = generic_file_sendfile,
+ .splice_read = generic_file_splice_read,
+ };
+
+diff -Nurd linux-2.6.24/fs/fuse/dir.c linux-2.6.24-oxe810/fs/fuse/dir.c
+--- linux-2.6.24/fs/fuse/dir.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/fuse/dir.c 2008-06-11 17:47:00.000000000 +0200
+@@ -905,7 +905,7 @@
+ }
+
+ if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
+- int err = generic_permission(inode, mask, NULL);
++ err = generic_permission(inode, mask, NULL);
+
+ /* If permission is denied, try to refresh file
+ attributes. This is also needed, because the root
+diff -Nurd linux-2.6.24/fs/fuse/file.c linux-2.6.24-oxe810/fs/fuse/file.c
+--- linux-2.6.24/fs/fuse/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/fuse/file.c 2008-06-11 17:47:00.000000000 +0200
+@@ -920,6 +920,7 @@
+ .fsync = fuse_fsync,
+ .lock = fuse_file_lock,
+ .flock = fuse_file_flock,
++ .sendfile = generic_file_sendfile,
+ .splice_read = generic_file_splice_read,
+ };
+
+diff -Nurd linux-2.6.24/fs/gfs2/ops_file.c linux-2.6.24-oxe810/fs/gfs2/ops_file.c
+--- linux-2.6.24/fs/gfs2/ops_file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/gfs2/ops_file.c 2008-06-11 17:47:09.000000000 +0200
+@@ -662,6 +662,7 @@
+ .release = gfs2_close,
+ .fsync = gfs2_fsync,
+ .lock = gfs2_lock,
++ .sendfile = generic_file_sendfile,
+ .flock = gfs2_flock,
+ .splice_read = generic_file_splice_read,
+ .splice_write = generic_file_splice_write,
+diff -Nurd linux-2.6.24/fs/hpfs/file.c linux-2.6.24-oxe810/fs/hpfs/file.c
+--- linux-2.6.24/fs/hpfs/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/hpfs/file.c 2008-06-11 17:46:57.000000000 +0200
+@@ -137,6 +137,7 @@
+ .mmap = generic_file_mmap,
+ .release = hpfs_file_release,
+ .fsync = hpfs_file_fsync,
++ .sendfile = generic_file_sendfile,
+ .splice_read = generic_file_splice_read,
+ };
+
+diff -Nurd linux-2.6.24/fs/inotify_user.c linux-2.6.24-oxe810/fs/inotify_user.c
+--- linux-2.6.24/fs/inotify_user.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/inotify_user.c 2008-06-11 17:47:10.000000000 +0200
+@@ -269,7 +269,7 @@
+ /* we can safely put the watch as we don't reference it while
+ * generating the event
+ */
+- if (mask & IN_IGNORED || mask & IN_ONESHOT)
++ if (mask & IN_IGNORED || w->mask & IN_ONESHOT)
+ put_inotify_watch(w); /* final put */
+
+ /* coalescing: drop this event if it is a dupe of the previous */
+diff -Nurd linux-2.6.24/fs/isofs/compress.c linux-2.6.24-oxe810/fs/isofs/compress.c
+--- linux-2.6.24/fs/isofs/compress.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/isofs/compress.c 2008-06-11 17:46:52.000000000 +0200
+@@ -72,6 +72,17 @@
+ offset = index & ~zisofs_block_page_mask;
+ blockindex = offset >> zisofs_block_page_shift;
+ maxpage = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
++
++ /*
++ * If this page is wholly outside i_size we just return zero;
++ * do_generic_file_read() will handle this for us
++ */
++ if (page->index >= maxpage) {
++ SetPageUptodate(page);
++ unlock_page(page);
++ return 0;
++ }
++
+ maxpage = min(zisofs_block_pages, maxpage-offset);
+
+ for ( i = 0 ; i < maxpage ; i++, offset++ ) {
+diff -Nurd linux-2.6.24/fs/jbd/recovery.c linux-2.6.24-oxe810/fs/jbd/recovery.c
+--- linux-2.6.24/fs/jbd/recovery.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/jbd/recovery.c 2008-06-11 17:47:07.000000000 +0200
+@@ -478,7 +478,7 @@
+ memcpy(nbh->b_data, obh->b_data,
+ journal->j_blocksize);
+ if (flags & JFS_FLAG_ESCAPE) {
+- *((__be32 *)bh->b_data) =
++ *((__be32 *)nbh->b_data) =
+ cpu_to_be32(JFS_MAGIC_NUMBER);
+ }
+
+diff -Nurd linux-2.6.24/fs/jbd2/recovery.c linux-2.6.24-oxe810/fs/jbd2/recovery.c
+--- linux-2.6.24/fs/jbd2/recovery.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/jbd2/recovery.c 2008-06-11 17:46:49.000000000 +0200
+@@ -488,7 +488,7 @@
+ memcpy(nbh->b_data, obh->b_data,
+ journal->j_blocksize);
+ if (flags & JBD2_FLAG_ESCAPE) {
+- *((__be32 *)bh->b_data) =
++ *((__be32 *)nbh->b_data) =
+ cpu_to_be32(JBD2_MAGIC_NUMBER);
+ }
+
+diff -Nurd linux-2.6.24/fs/jffs2/file.c linux-2.6.24-oxe810/fs/jffs2/file.c
+--- linux-2.6.24/fs/jffs2/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/jffs2/file.c 2008-06-11 17:47:10.000000000 +0200
+@@ -49,7 +49,8 @@
+ .ioctl = jffs2_ioctl,
+ .mmap = generic_file_readonly_mmap,
+ .fsync = jffs2_fsync,
+- .splice_read = generic_file_splice_read,
++ .sendfile = generic_file_sendfile
++ .splice_read = generic_file_splice_read,
+ };
+
+ /* jffs2_file_inode_operations */
+diff -Nurd linux-2.6.24/fs/jfs/file.c linux-2.6.24-oxe810/fs/jfs/file.c
+--- linux-2.6.24/fs/jfs/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/jfs/file.c 2008-06-11 17:46:58.000000000 +0200
+@@ -108,6 +108,7 @@
+ .aio_read = generic_file_aio_read,
+ .aio_write = generic_file_aio_write,
+ .mmap = generic_file_mmap,
++ .sendfile = generic_file_sendfile,
+ .splice_read = generic_file_splice_read,
+ .splice_write = generic_file_splice_write,
+ .fsync = jfs_fsync,
+diff -Nurd linux-2.6.24/fs/minix/file.c linux-2.6.24-oxe810/fs/minix/file.c
+--- linux-2.6.24/fs/minix/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/minix/file.c 2008-06-11 17:47:00.000000000 +0200
+@@ -23,6 +23,7 @@
+ .aio_write = generic_file_aio_write,
+ .mmap = generic_file_mmap,
+ .fsync = minix_sync_file,
++ .sendfile = generic_file_sendfile,
+ .splice_read = generic_file_splice_read,
+ };
+
+diff -Nurd linux-2.6.24/fs/ncpfs/mmap.c linux-2.6.24-oxe810/fs/ncpfs/mmap.c
+--- linux-2.6.24/fs/ncpfs/mmap.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/ncpfs/mmap.c 2008-06-11 17:47:09.000000000 +0200
+@@ -50,10 +50,6 @@
+ pos = vmf->pgoff << PAGE_SHIFT;
+
+ count = PAGE_SIZE;
+- if ((unsigned long)vmf->virtual_address + PAGE_SIZE > area->vm_end) {
+- WARN_ON(1); /* shouldn't happen? */
+- count = area->vm_end - (unsigned long)vmf->virtual_address;
+- }
+ /* what we can read in one go */
+ bufsize = NCP_SERVER(inode)->buffer_size;
+
+diff -Nurd linux-2.6.24/fs/nfs/write.c linux-2.6.24-oxe810/fs/nfs/write.c
+--- linux-2.6.24/fs/nfs/write.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/nfs/write.c 2008-06-11 17:46:59.000000000 +0200
+@@ -701,6 +701,17 @@
+ }
+
+ /*
++ * If the page cache is marked as unsafe or invalid, then we can't rely on
++ * the PageUptodate() flag. In this case, we will need to turn off
++ * write optimisations that depend on the page contents being correct.
++ */
++static int nfs_write_pageuptodate(struct page *page, struct inode *inode)
++{
++ return PageUptodate(page) &&
++ !(NFS_I(inode)->cache_validity & (NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA));
++}
++
++/*
+ * Update and possibly write a cached page of an NFS file.
+ *
+ * XXX: Keep an eye on generic_file_read to make sure it doesn't do bad
+@@ -721,10 +732,13 @@
+ (long long)(page_offset(page) +offset));
+
+ /* If we're not using byte range locks, and we know the page
+- * is entirely in cache, it may be more efficient to avoid
+- * fragmenting write requests.
++ * is up to date, it may be more efficient to extend the write
++ * to cover the entire page in order to avoid fragmentation
++ * inefficiencies.
+ */
+- if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) {
++ if (nfs_write_pageuptodate(page, inode) &&
++ inode->i_flock == NULL &&
++ !(file->f_mode & O_SYNC)) {
+ count = max(count + offset, nfs_page_length(page));
+ offset = 0;
+ }
+diff -Nurd linux-2.6.24/fs/nfsd/nfsfh.c linux-2.6.24-oxe810/fs/nfsd/nfsfh.c
+--- linux-2.6.24/fs/nfsd/nfsfh.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/nfsd/nfsfh.c 2008-06-11 17:47:05.000000000 +0200
+@@ -231,6 +231,7 @@
+ fhp->fh_dentry = dentry;
+ fhp->fh_export = exp;
+ nfsd_nr_verified++;
++ cache_get(&exp->h);
+ } else {
+ /*
+ * just rechecking permissions
+@@ -240,6 +241,7 @@
+ dprintk("nfsd: fh_verify - just checking\n");
+ dentry = fhp->fh_dentry;
+ exp = fhp->fh_export;
++ cache_get(&exp->h);
+ /*
+ * Set user creds for this exportpoint; necessary even
+ * in the "just checking" case because this may be a
+@@ -251,8 +253,6 @@
+ if (error)
+ goto out;
+ }
+- cache_get(&exp->h);
+-
+
+ error = nfsd_mode_check(rqstp, dentry->d_inode->i_mode, type);
+ if (error)
+diff -Nurd linux-2.6.24/fs/ntfs/file.c linux-2.6.24-oxe810/fs/ntfs/file.c
+--- linux-2.6.24/fs/ntfs/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/ntfs/file.c 2008-06-11 17:47:01.000000000 +0200
+@@ -2274,16 +2274,11 @@
+ mounted filesystem. */
+ .mmap = generic_file_mmap, /* Mmap file. */
+ .open = ntfs_file_open, /* Open file. */
+- .splice_read = generic_file_splice_read /* Zero-copy data send with
++ .sendfile = generic_file_sendfile, /* Zero-copy data send with
+ the data source being on
+ the ntfs partition. We do
+ not need to care about the
+ data destination. */
+- /*.sendpage = ,*/ /* Zero-copy data send with
+- the data destination being
+- on the ntfs partition. We
+- do not need to care about
+- the data source. */
+ };
+
+ const struct inode_operations ntfs_file_inode_ops = {
+diff -Nurd linux-2.6.24/fs/ocfs2/file.c linux-2.6.24-oxe810/fs/ocfs2/file.c
+--- linux-2.6.24/fs/ocfs2/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/ocfs2/file.c 2008-06-11 17:46:56.000000000 +0200
+@@ -2206,6 +2206,7 @@
+ const struct file_operations ocfs2_fops = {
+ .read = do_sync_read,
+ .write = do_sync_write,
++ .sendfile = generic_file_sendfile,
+ .mmap = ocfs2_mmap,
+ .fsync = ocfs2_sync_file,
+ .release = ocfs2_file_release,
+diff -Nurd linux-2.6.24/fs/qnx4/file.c linux-2.6.24-oxe810/fs/qnx4/file.c
+--- linux-2.6.24/fs/qnx4/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/qnx4/file.c 2008-06-11 17:46:56.000000000 +0200
+@@ -25,6 +25,7 @@
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
+ .mmap = generic_file_mmap,
++ .sendfile = generic_file_sendfile,
+ .splice_read = generic_file_splice_read,
+ #ifdef CONFIG_QNX4FS_RW
+ .write = do_sync_write,
+diff -Nurd linux-2.6.24/fs/read_write.c linux-2.6.24-oxe810/fs/read_write.c
+--- linux-2.6.24/fs/read_write.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/read_write.c 2008-06-11 17:47:10.000000000 +0200
+@@ -26,7 +26,8 @@
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
+ .mmap = generic_file_readonly_mmap,
+- .splice_read = generic_file_splice_read,
++ //.splice_read = generic_file_splice_read,
++ .sendfile = generic_file_sendfile,
+ };
+
+ EXPORT_SYMBOL(generic_ro_fops);
+@@ -709,7 +710,7 @@
+ struct inode * in_inode, * out_inode;
+ loff_t pos;
+ ssize_t retval;
+- int fput_needed_in, fput_needed_out, fl;
++ int fput_needed_in, fput_needed_out;
+
+ /*
+ * Get input file, and verify that it is ok..
+@@ -724,7 +725,7 @@
+ in_inode = in_file->f_path.dentry->d_inode;
+ if (!in_inode)
+ goto fput_in;
+- if (!in_file->f_op || !in_file->f_op->splice_read)
++ if (!in_file->f_op || !in_file->f_op->sendfile)
+ goto fput_in;
+ retval = -ESPIPE;
+ if (!ppos)
+@@ -777,7 +778,6 @@
+ count = max - pos;
+ }
+
+- fl = 0;
+ #if 0
+ /*
+ * We need to debate whether we can enable this or not. The
+@@ -788,7 +788,7 @@
+ if (in_file->f_flags & O_NONBLOCK)
+ fl = SPLICE_F_NONBLOCK;
+ #endif
+- retval = do_splice_direct(in_file, ppos, out_file, count, fl);
++ retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file);
+
+ if (retval > 0) {
+ add_rchar(current, retval);
+diff -Nurd linux-2.6.24/fs/reiserfs/file.c linux-2.6.24-oxe810/fs/reiserfs/file.c
+--- linux-2.6.24/fs/reiserfs/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/reiserfs/file.c 2008-06-11 17:46:50.000000000 +0200
+@@ -292,6 +292,7 @@
+ .open = generic_file_open,
+ .release = reiserfs_file_release,
+ .fsync = reiserfs_sync_file,
++ .sendfile = generic_file_sendfile,
+ .aio_read = generic_file_aio_read,
+ .aio_write = generic_file_aio_write,
+ .splice_read = generic_file_splice_read,
+diff -Nurd linux-2.6.24/fs/smbfs/file.c linux-2.6.24-oxe810/fs/smbfs/file.c
+--- linux-2.6.24/fs/smbfs/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/smbfs/file.c 2008-06-11 17:47:00.000000000 +0200
+@@ -283,6 +283,27 @@
+ return status;
+ }
+
++static ssize_t
++smb_file_sendfile(struct file *file, loff_t *ppos,
++ size_t count, read_actor_t actor, void *target)
++{
++ struct dentry *dentry = file->f_path.dentry;
++ ssize_t status;
++
++ VERBOSE("file %s/%s, pos=%Ld, count=%d\n",
++ DENTRY_PATH(dentry), *ppos, count);
++
++ status = smb_revalidate_inode(dentry);
++ if (status) {
++ PARANOIA("%s/%s validation failed, error=%Zd\n",
++ DENTRY_PATH(dentry), status);
++ goto out;
++ }
++ status = generic_file_sendfile(file, ppos, count, actor, target);
++out:
++ return status;
++}
++
+ /*
+ * This does the "real" work of the write. The generic routine has
+ * allocated the page, locked it, done all the page alignment stuff
+@@ -434,6 +455,7 @@
+ .open = smb_file_open,
+ .release = smb_file_release,
+ .fsync = smb_fsync,
++ .sendfile = smb_file_sendfile,
+ .splice_read = smb_file_splice_read,
+ };
+
+diff -Nurd linux-2.6.24/fs/splice.c linux-2.6.24-oxe810/fs/splice.c
+--- linux-2.6.24/fs/splice.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/splice.c 2008-06-11 17:47:10.000000000 +0200
+@@ -1184,6 +1184,9 @@
+ {
+ int partial;
+
++ if (!access_ok(VERIFY_READ, src, n))
++ return -EFAULT;
++
+ pagefault_disable();
+ partial = __copy_from_user_inatomic(dst, src, n);
+ pagefault_enable();
+@@ -1236,7 +1239,7 @@
+ if (unlikely(!len))
+ break;
+ error = -EFAULT;
+- if (unlikely(!base))
++ if (!access_ok(VERIFY_READ, base, len))
+ break;
+
+ /*
+@@ -1391,6 +1394,11 @@
+ error = -EFAULT;
+ break;
+ }
++
++ if (unlikely(!access_ok(VERIFY_WRITE, base, len))) {
++ error = -EFAULT;
++ break;
++ }
+
+ sd.len = 0;
+ sd.total_len = len;
+diff -Nurd linux-2.6.24/fs/sysv/file.c linux-2.6.24-oxe810/fs/sysv/file.c
+--- linux-2.6.24/fs/sysv/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/sysv/file.c 2008-06-11 17:47:00.000000000 +0200
+@@ -27,6 +27,7 @@
+ .aio_write = generic_file_aio_write,
+ .mmap = generic_file_mmap,
+ .fsync = sysv_sync_file,
++ .sendfile = generic_file_sendfile,
+ .splice_read = generic_file_splice_read,
+ };
+
+diff -Nurd linux-2.6.24/fs/udf/file.c linux-2.6.24-oxe810/fs/udf/file.c
+--- linux-2.6.24/fs/udf/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/udf/file.c 2008-06-11 17:47:10.000000000 +0200
+@@ -246,6 +246,8 @@
+ .aio_write = udf_file_aio_write,
+ .release = udf_release_file,
+ .fsync = udf_fsync_file,
++ .sendfile = generic_file_sendfile,
++ .sendfile = generic_file_sendfile,
+ .splice_read = generic_file_splice_read,
+ };
+
+diff -Nurd linux-2.6.24/fs/ufs/file.c linux-2.6.24-oxe810/fs/ufs/file.c
+--- linux-2.6.24/fs/ufs/file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/ufs/file.c 2008-06-11 17:46:54.000000000 +0200
+@@ -63,5 +63,6 @@
+ .mmap = generic_file_mmap,
+ .open = generic_file_open,
+ .fsync = ufs_sync_file,
++ .sendfile = generic_file_sendfile,
+ .splice_read = generic_file_splice_read,
+ };
+diff -Nurd linux-2.6.24/fs/ufs/util.h linux-2.6.24-oxe810/fs/ufs/util.h
+--- linux-2.6.24/fs/ufs/util.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/ufs/util.h 2008-06-11 17:46:54.000000000 +0200
+@@ -58,7 +58,7 @@
+ {
+ switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
+ case UFS_ST_SUNOS:
+- if (fs32_to_cpu(sb, usb3->fs_postblformat == UFS_42POSTBLFMT)) {
++ if (fs32_to_cpu(sb, usb3->fs_postblformat) == UFS_42POSTBLFMT) {
+ usb1->fs_u0.fs_sun.fs_state = cpu_to_fs32(sb, value);
+ break;
+ }
+diff -Nurd linux-2.6.24/fs/xfs/Makefile-linux-2.6 linux-2.6.24-oxe810/fs/xfs/Makefile-linux-2.6
+--- linux-2.6.24/fs/xfs/Makefile-linux-2.6 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/Makefile-linux-2.6 2008-06-11 17:46:48.000000000 +0200
+@@ -15,13 +15,20 @@
+ # along with this program; if not, write the Free Software Foundation,
+ # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ #
++CONFIG_XFS_DEBUG := n
++CONFIG_XFS_TRACE := n
+
+ EXTRA_CFLAGS += -Ifs/xfs -Ifs/xfs/linux-2.6 -funsigned-char
+
+ XFS_LINUX := linux-2.6
+
++ifeq ($(CONFIG_XFS_TRACE),y)
++ EXTRA_CFLAGS += -DCONFIG_XFS_TRACE
++endif
++
+ ifeq ($(CONFIG_XFS_DEBUG),y)
+ EXTRA_CFLAGS += -g
++ EXTRA_CFLAGS += -DCONFIG_XFS_DEBUG
+ endif
+
+ obj-$(CONFIG_XFS_FS) += xfs.o
+diff -Nurd linux-2.6.24/fs/xfs/linux-2.6/xfs_buf.c linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_buf.c
+--- linux-2.6.24/fs/xfs/linux-2.6/xfs_buf.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_buf.c 2008-06-11 17:46:46.000000000 +0200
+@@ -330,20 +330,26 @@
+
+ ASSERT(list_empty(&bp->b_hash_list));
+
+- if (bp->b_flags & (_XBF_PAGE_CACHE|_XBF_PAGES)) {
++ if (bp->b_flags & _XBF_PAGE_CACHE) {
+ uint i;
+
+ if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1))
+ free_address(bp->b_addr - bp->b_offset);
+
+ for (i = 0; i < bp->b_page_count; i++) {
+- struct page *page = bp->b_pages[i];
+-
+- if (bp->b_flags & _XBF_PAGE_CACHE)
+- ASSERT(!PagePrivate(page));
++ struct page *page = bp->b_pages[i];
++ ASSERT(!PagePrivate(page));
+ page_cache_release(page);
+ }
+ _xfs_buf_free_pages(bp);
++ } else if (bp->b_flags & _XBF_KMEM_ALLOC) {
++ /*
++ * XXX(hch): bp->b_count_desired might be incorrect (see
++ * xfs_buf_associate_memory for details), but fortunately
++ * the Linux version of kmem_free ignores the len argument..
++ */
++ kmem_free(bp->b_addr, bp->b_count_desired);
++ _xfs_buf_free_pages(bp);
+ }
+
+ xfs_buf_deallocate(bp);
+@@ -766,44 +772,46 @@
+ size_t len,
+ xfs_buftarg_t *target)
+ {
+- unsigned long page_count = PAGE_ALIGN(len) >> PAGE_SHIFT;
+- int error, i;
++ size_t malloc_len = len;
+ xfs_buf_t *bp;
++ void *data;
++ int error;
+
+ bp = xfs_buf_allocate(0);
+ if (unlikely(bp == NULL))
+ goto fail;
+ _xfs_buf_initialize(bp, target, 0, len, 0);
+
+- error = _xfs_buf_get_pages(bp, page_count, 0);
+- if (error)
++ try_again:
++ data = kmem_alloc(malloc_len, KM_SLEEP | KM_MAYFAIL | KM_LARGE);
++ if (unlikely(data == NULL))
+ goto fail_free_buf;
+
+- for (i = 0; i < page_count; i++) {
+- bp->b_pages[i] = alloc_page(GFP_KERNEL);
+- if (!bp->b_pages[i])
+- goto fail_free_mem;
++ /* check whether alignment matches.. */
++ if ((__psunsigned_t)data !=
++ ((__psunsigned_t)data & ~target->bt_smask)) {
++ /* .. else double the size and try again */
++ kmem_free(data, malloc_len);
++ malloc_len <<= 1;
++ goto try_again;
+ }
+- bp->b_flags |= _XBF_PAGES;
+
+- error = _xfs_buf_map_pages(bp, XBF_MAPPED);
+- if (unlikely(error)) {
+- printk(KERN_WARNING "%s: failed to map pages\n",
+- __FUNCTION__);
++ /* Clear the memory contents */
++ memset(data, 0, malloc_len);
++
++ error = xfs_buf_associate_memory(bp, data, len);
++ if (error)
+ goto fail_free_mem;
+- }
++ bp->b_flags |= _XBF_KMEM_ALLOC;
+
+ xfs_buf_unlock(bp);
+
+- XB_TRACE(bp, "no_daddr", len);
++ XB_TRACE(bp, "no_daddr", data);
+ return bp;
+-
+ fail_free_mem:
+- while (--i >= 0)
+- __free_page(bp->b_pages[i]);
+- _xfs_buf_free_pages(bp);
++ kmem_free(data, malloc_len);
+ fail_free_buf:
+- xfs_buf_deallocate(bp);
++ xfs_buf_free(bp);
+ fail:
+ return NULL;
+ }
+diff -Nurd linux-2.6.24/fs/xfs/linux-2.6/xfs_buf.h linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_buf.h
+--- linux-2.6.24/fs/xfs/linux-2.6/xfs_buf.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_buf.h 2008-06-11 17:46:46.000000000 +0200
+@@ -63,7 +63,7 @@
+
+ /* flags used only internally */
+ _XBF_PAGE_CACHE = (1 << 17),/* backed by pagecache */
+- _XBF_PAGES = (1 << 18), /* backed by refcounted pages */
++ _XBF_KMEM_ALLOC = (1 << 18),/* backed by kmem_alloc() */
+ _XBF_RUN_QUEUES = (1 << 19),/* run block device task queue */
+ _XBF_DELWRI_Q = (1 << 21), /* buffer on delwri queue */
+ } xfs_buf_flags_t;
+diff -Nurd linux-2.6.24/fs/xfs/linux-2.6/xfs_file.c linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_file.c
+--- linux-2.6.24/fs/xfs/linux-2.6/xfs_file.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_file.c 2008-06-11 17:46:46.000000000 +0200
+@@ -122,6 +122,28 @@
+ }
+
+ STATIC ssize_t
++xfs_file_sendfile(
++ struct file *filp,
++ loff_t *pos,
++ size_t count,
++ read_actor_t actor,
++ void *target)
++{
++ return xfs_sendfile(XFS_I(filp->f_path.dentry->d_inode), filp, pos, 0, count, actor, target);
++}
++
++STATIC ssize_t
++xfs_file_sendfile_invis(
++ struct file *filp,
++ loff_t *pos,
++ size_t count,
++ read_actor_t actor,
++ void *target)
++{
++ return xfs_sendfile(XFS_I(filp->f_path.dentry->d_inode), filp, pos, IO_INVIS, count, actor, target);
++}
++
++STATIC ssize_t
+ xfs_file_splice_read(
+ struct file *infilp,
+ loff_t *ppos,
+@@ -350,8 +372,8 @@
+
+ size = buf.used;
+ de = (struct hack_dirent *)buf.dirent;
+- curr_offset = de->offset /* & 0x7fffffff */;
+ while (size > 0) {
++ curr_offset = de->offset /* & 0x7fffffff */;
+ if (filldir(dirent, de->name, de->namlen,
+ curr_offset & 0x7fffffff,
+ de->ino, de->d_type)) {
+@@ -362,7 +384,6 @@
+ sizeof(u64));
+ size -= reclen;
+ de = (struct hack_dirent *)((char *)de + reclen);
+- curr_offset = de->offset /* & 0x7fffffff */;
+ }
+ }
+
+@@ -502,8 +523,11 @@
+ .llseek = generic_file_llseek,
+ .read = do_sync_read,
+ .write = do_sync_write,
++// .readv = xfs_file_readv,
++// .writev = xfs_file_writev,
+ .aio_read = xfs_file_aio_read,
+ .aio_write = xfs_file_aio_write,
++ .sendfile = xfs_file_sendfile,
+ .splice_read = xfs_file_splice_read,
+ .splice_write = xfs_file_splice_write,
+ .unlocked_ioctl = xfs_file_ioctl,
+@@ -525,6 +549,7 @@
+ .write = do_sync_write,
+ .aio_read = xfs_file_aio_read_invis,
+ .aio_write = xfs_file_aio_write_invis,
++ .sendfile = xfs_file_sendfile_invis,
+ .splice_read = xfs_file_splice_read_invis,
+ .splice_write = xfs_file_splice_write_invis,
+ .unlocked_ioctl = xfs_file_ioctl_invis,
+diff -Nurd linux-2.6.24/fs/xfs/linux-2.6/xfs_lrw.c linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_lrw.c
+--- linux-2.6.24/fs/xfs/linux-2.6/xfs_lrw.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/linux-2.6/xfs_lrw.c 2008-06-11 17:46:46.000000000 +0200
+@@ -271,6 +271,48 @@
+ }
+
+ ssize_t
++xfs_sendfile(
++ xfs_inode_t *ip,
++ struct file *filp,
++ loff_t *offset,
++ int ioflags,
++ size_t count,
++ read_actor_t actor,
++ void *target)
++{
++ bhv_vnode_t *vp = XFS_ITOV(ip);
++ xfs_mount_t *mp = ip->i_mount;
++ ssize_t ret;
++
++ XFS_STATS_INC(xs_read_calls);
++ if (XFS_FORCED_SHUTDOWN(mp))
++ return -EIO;
++
++ xfs_ilock(ip, XFS_IOLOCK_SHARED);
++
++ if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
++ (!(ioflags & IO_INVIS))) {
++ bhv_vrwlock_t locktype = VRWLOCK_READ;
++ int error;
++
++ error = XFS_SEND_DATA(mp, DM_EVENT_READ, vp,*offset, count,
++ FILP_DELAY_FLAG(filp), &locktype);
++ if (error) {
++ xfs_iunlock(ip, XFS_IOLOCK_SHARED);
++ return -error;
++ }
++ }
++ xfs_rw_enter_trace(XFS_SENDFILE_ENTER, &ip->i_iocore,
++ (void *)(unsigned long)target, count, *offset, ioflags);
++ ret = generic_file_sendfile(filp, offset, count, actor, target);
++ if (ret > 0)
++ XFS_STATS_ADD(xs_read_bytes, ret);
++
++ xfs_iunlock(ip, XFS_IOLOCK_SHARED);
++ return ret;
++}
++
++ssize_t
+ xfs_splice_read(
+ xfs_inode_t *ip,
+ struct file *infilp,
+diff -Nurd linux-2.6.24/fs/xfs/xfs_alloc.c linux-2.6.24-oxe810/fs/xfs/xfs_alloc.c
+--- linux-2.6.24/fs/xfs/xfs_alloc.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_alloc.c 2008-06-11 17:46:48.000000000 +0200
+@@ -592,7 +592,7 @@
+ if (!(args->wasfromfl)) {
+
+ agf = XFS_BUF_TO_AGF(args->agbp);
+- be32_add(&agf->agf_freeblks, -(args->len));
++ be32_add_cpu(&agf->agf_freeblks, -(args->len));
+ xfs_trans_agblocks_delta(args->tp,
+ -((long)(args->len)));
+ args->pag->pagf_freeblks -= args->len;
+@@ -1720,7 +1720,7 @@
+
+ agf = XFS_BUF_TO_AGF(agbp);
+ pag = &mp->m_perag[agno];
+- be32_add(&agf->agf_freeblks, len);
++ be32_add_cpu(&agf->agf_freeblks, len);
+ xfs_trans_agblocks_delta(tp, len);
+ pag->pagf_freeblks += len;
+ XFS_WANT_CORRUPTED_GOTO(
+@@ -2008,18 +2008,18 @@
+ * Get the block number and update the data structures.
+ */
+ bno = be32_to_cpu(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)]);
+- be32_add(&agf->agf_flfirst, 1);
++ be32_add_cpu(&agf->agf_flfirst, 1);
+ xfs_trans_brelse(tp, agflbp);
+ if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp))
+ agf->agf_flfirst = 0;
+ pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)];
+- be32_add(&agf->agf_flcount, -1);
++ be32_add_cpu(&agf->agf_flcount, -1);
+ xfs_trans_agflist_delta(tp, -1);
+ pag->pagf_flcount--;
+
+ logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT;
+ if (btreeblk) {
+- be32_add(&agf->agf_btreeblks, 1);
++ be32_add_cpu(&agf->agf_btreeblks, 1);
+ pag->pagf_btreeblks++;
+ logflags |= XFS_AGF_BTREEBLKS;
+ }
+@@ -2117,17 +2117,17 @@
+ be32_to_cpu(agf->agf_seqno), &agflbp)))
+ return error;
+ agfl = XFS_BUF_TO_AGFL(agflbp);
+- be32_add(&agf->agf_fllast, 1);
++ be32_add_cpu(&agf->agf_fllast, 1);
+ if (be32_to_cpu(agf->agf_fllast) == XFS_AGFL_SIZE(mp))
+ agf->agf_fllast = 0;
+ pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)];
+- be32_add(&agf->agf_flcount, 1);
++ be32_add_cpu(&agf->agf_flcount, 1);
+ xfs_trans_agflist_delta(tp, 1);
+ pag->pagf_flcount++;
+
+ logflags = XFS_AGF_FLLAST | XFS_AGF_FLCOUNT;
+ if (btreeblk) {
+- be32_add(&agf->agf_btreeblks, -1);
++ be32_add_cpu(&agf->agf_btreeblks, -1);
+ pag->pagf_btreeblks--;
+ logflags |= XFS_AGF_BTREEBLKS;
+ }
+diff -Nurd linux-2.6.24/fs/xfs/xfs_alloc_btree.c linux-2.6.24-oxe810/fs/xfs/xfs_alloc_btree.c
+--- linux-2.6.24/fs/xfs/xfs_alloc_btree.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_alloc_btree.c 2008-06-11 17:46:48.000000000 +0200
+@@ -221,7 +221,7 @@
+ */
+ bno = be32_to_cpu(agf->agf_roots[cur->bc_btnum]);
+ agf->agf_roots[cur->bc_btnum] = *lpp;
+- be32_add(&agf->agf_levels[cur->bc_btnum], -1);
++ be32_add_cpu(&agf->agf_levels[cur->bc_btnum], -1);
+ mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_levels[cur->bc_btnum]--;
+ /*
+ * Put this buffer/block on the ag's freelist.
+@@ -1256,9 +1256,9 @@
+ /*
+ * Bump and log left's numrecs, decrement and log right's numrecs.
+ */
+- be16_add(&left->bb_numrecs, 1);
++ be16_add_cpu(&left->bb_numrecs, 1);
+ xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
+- be16_add(&right->bb_numrecs, -1);
++ be16_add_cpu(&right->bb_numrecs, -1);
+ xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
+ /*
+ * Slide the contents of right down one entry.
+@@ -1346,7 +1346,7 @@
+
+ agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
+ agf->agf_roots[cur->bc_btnum] = cpu_to_be32(nbno);
+- be32_add(&agf->agf_levels[cur->bc_btnum], 1);
++ be32_add_cpu(&agf->agf_levels[cur->bc_btnum], 1);
+ seqno = be32_to_cpu(agf->agf_seqno);
+ mp->m_perag[seqno].pagf_levels[cur->bc_btnum]++;
+ xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
+@@ -1558,9 +1558,9 @@
+ /*
+ * Decrement and log left's numrecs, bump and log right's numrecs.
+ */
+- be16_add(&left->bb_numrecs, -1);
++ be16_add_cpu(&left->bb_numrecs, -1);
+ xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
+- be16_add(&right->bb_numrecs, 1);
++ be16_add_cpu(&right->bb_numrecs, 1);
+ xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
+ /*
+ * Using a temporary cursor, update the parent key values of the
+@@ -1643,7 +1643,7 @@
+ */
+ if ((be16_to_cpu(left->bb_numrecs) & 1) &&
+ cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
+- be16_add(&right->bb_numrecs, 1);
++ be16_add_cpu(&right->bb_numrecs, 1);
+ i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
+ /*
+ * For non-leaf blocks, copy keys and addresses over to the new block.
+@@ -1689,7 +1689,7 @@
+ * Adjust numrecs, sibling pointers.
+ */
+ lbno = XFS_DADDR_TO_AGBNO(cur->bc_mp, XFS_BUF_ADDR(lbp));
+- be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
++ be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
+ right->bb_rightsib = left->bb_rightsib;
+ left->bb_rightsib = cpu_to_be32(rbno);
+ right->bb_leftsib = cpu_to_be32(lbno);
+diff -Nurd linux-2.6.24/fs/xfs/xfs_attr_leaf.c linux-2.6.24-oxe810/fs/xfs/xfs_attr_leaf.c
+--- linux-2.6.24/fs/xfs/xfs_attr_leaf.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_attr_leaf.c 2008-06-11 17:46:48.000000000 +0200
+@@ -319,7 +319,7 @@
+ memcpy(sfe->nameval, args->name, args->namelen);
+ memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen);
+ sf->hdr.count++;
+- be16_add(&sf->hdr.totsize, size);
++ be16_add_cpu(&sf->hdr.totsize, size);
+ xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
+
+ xfs_sbversion_add_attr2(mp, args->trans);
+@@ -365,7 +365,7 @@
+ if (end != totsize)
+ memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end);
+ sf->hdr.count--;
+- be16_add(&sf->hdr.totsize, -size);
++ be16_add_cpu(&sf->hdr.totsize, -size);
+
+ /*
+ * Fix up the start offset of the attribute fork
+@@ -1135,7 +1135,7 @@
+ xfs_da_log_buf(args->trans, bp,
+ XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry)));
+ }
+- be16_add(&hdr->count, 1);
++ be16_add_cpu(&hdr->count, 1);
+
+ /*
+ * Allocate space for the new string (at the end of the run).
+@@ -1149,7 +1149,7 @@
+ mp->m_sb.sb_blocksize, NULL));
+ ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp));
+ ASSERT((be16_to_cpu(map->size) & 0x3) == 0);
+- be16_add(&map->size,
++ be16_add_cpu(&map->size,
+ -xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
+ mp->m_sb.sb_blocksize, &tmp));
+ entry->nameidx = cpu_to_be16(be16_to_cpu(map->base) +
+@@ -1216,12 +1216,12 @@
+ map = &hdr->freemap[0];
+ for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; map++, i++) {
+ if (be16_to_cpu(map->base) == tmp) {
+- be16_add(&map->base, sizeof(xfs_attr_leaf_entry_t));
+- be16_add(&map->size,
++ be16_add_cpu(&map->base, sizeof(xfs_attr_leaf_entry_t));
++ be16_add_cpu(&map->size,
+ -((int)sizeof(xfs_attr_leaf_entry_t)));
+ }
+ }
+- be16_add(&hdr->usedbytes, xfs_attr_leaf_entsize(leaf, args->index));
++ be16_add_cpu(&hdr->usedbytes, xfs_attr_leaf_entsize(leaf, args->index));
+ xfs_da_log_buf(args->trans, bp,
+ XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr)));
+ return(0);
+@@ -1729,9 +1729,9 @@
+ ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp));
+ ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp));
+ if (be16_to_cpu(map->base) == tablesize) {
+- be16_add(&map->base,
++ be16_add_cpu(&map->base,
+ -((int)sizeof(xfs_attr_leaf_entry_t)));
+- be16_add(&map->size, sizeof(xfs_attr_leaf_entry_t));
++ be16_add_cpu(&map->size, sizeof(xfs_attr_leaf_entry_t));
+ }
+
+ if ((be16_to_cpu(map->base) + be16_to_cpu(map->size))
+@@ -1753,19 +1753,19 @@
+ if ((before >= 0) || (after >= 0)) {
+ if ((before >= 0) && (after >= 0)) {
+ map = &hdr->freemap[before];
+- be16_add(&map->size, entsize);
+- be16_add(&map->size,
++ be16_add_cpu(&map->size, entsize);
++ be16_add_cpu(&map->size,
+ be16_to_cpu(hdr->freemap[after].size));
+ hdr->freemap[after].base = 0;
+ hdr->freemap[after].size = 0;
+ } else if (before >= 0) {
+ map = &hdr->freemap[before];
+- be16_add(&map->size, entsize);
++ be16_add_cpu(&map->size, entsize);
+ } else {
+ map = &hdr->freemap[after];
+ /* both on-disk, don't endian flip twice */
+ map->base = entry->nameidx;
+- be16_add(&map->size, entsize);
++ be16_add_cpu(&map->size, entsize);
+ }
+ } else {
+ /*
+@@ -1790,7 +1790,7 @@
+ * Compress the remaining entries and zero out the removed stuff.
+ */
+ memset(XFS_ATTR_LEAF_NAME(leaf, args->index), 0, entsize);
+- be16_add(&hdr->usedbytes, -entsize);
++ be16_add_cpu(&hdr->usedbytes, -entsize);
+ xfs_da_log_buf(args->trans, bp,
+ XFS_DA_LOGRANGE(leaf, XFS_ATTR_LEAF_NAME(leaf, args->index),
+ entsize));
+@@ -1798,7 +1798,7 @@
+ tmp = (be16_to_cpu(hdr->count) - args->index)
+ * sizeof(xfs_attr_leaf_entry_t);
+ memmove((char *)entry, (char *)(entry+1), tmp);
+- be16_add(&hdr->count, -1);
++ be16_add_cpu(&hdr->count, -1);
+ xfs_da_log_buf(args->trans, bp,
+ XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry)));
+ entry = &leaf->entries[be16_to_cpu(hdr->count)];
+@@ -2184,15 +2184,15 @@
+ */
+ if (entry_s->flags & XFS_ATTR_INCOMPLETE) { /* skip partials? */
+ memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp);
+- be16_add(&hdr_s->usedbytes, -tmp);
+- be16_add(&hdr_s->count, -1);
++ be16_add_cpu(&hdr_s->usedbytes, -tmp);
++ be16_add_cpu(&hdr_s->count, -1);
+ entry_d--; /* to compensate for ++ in loop hdr */
+ desti--;
+ if ((start_s + i) < offset)
+ result++; /* insertion index adjustment */
+ } else {
+ #endif /* GROT */
+- be16_add(&hdr_d->firstused, -tmp);
++ be16_add_cpu(&hdr_d->firstused, -tmp);
+ /* both on-disk, don't endian flip twice */
+ entry_d->hashval = entry_s->hashval;
+ /* both on-disk, don't endian flip twice */
+@@ -2205,10 +2205,10 @@
+ ASSERT(be16_to_cpu(entry_s->nameidx) + tmp
+ <= XFS_LBSIZE(mp));
+ memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp);
+- be16_add(&hdr_s->usedbytes, -tmp);
+- be16_add(&hdr_d->usedbytes, tmp);
+- be16_add(&hdr_s->count, -1);
+- be16_add(&hdr_d->count, 1);
++ be16_add_cpu(&hdr_s->usedbytes, -tmp);
++ be16_add_cpu(&hdr_d->usedbytes, tmp);
++ be16_add_cpu(&hdr_s->count, -1);
++ be16_add_cpu(&hdr_d->count, 1);
+ tmp = be16_to_cpu(hdr_d->count)
+ * sizeof(xfs_attr_leaf_entry_t)
+ + sizeof(xfs_attr_leaf_hdr_t);
+@@ -2249,7 +2249,7 @@
+ * Fill in the freemap information
+ */
+ hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t));
+- be16_add(&hdr_d->freemap[0].base, be16_to_cpu(hdr_d->count) *
++ be16_add_cpu(&hdr_d->freemap[0].base, be16_to_cpu(hdr_d->count) *
+ sizeof(xfs_attr_leaf_entry_t));
+ hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused)
+ - be16_to_cpu(hdr_d->freemap[0].base));
+diff -Nurd linux-2.6.24/fs/xfs/xfs_bmap_btree.c linux-2.6.24-oxe810/fs/xfs/xfs_bmap_btree.c
+--- linux-2.6.24/fs/xfs/xfs_bmap_btree.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_bmap_btree.c 2008-06-11 17:46:48.000000000 +0200
+@@ -631,7 +631,7 @@
+ memcpy(lrp, rrp, numrrecs * sizeof(*lrp));
+ xfs_bmbt_log_recs(cur, lbp, numlrecs + 1, numlrecs + numrrecs);
+ }
+- be16_add(&left->bb_numrecs, numrrecs);
++ be16_add_cpu(&left->bb_numrecs, numrrecs);
+ left->bb_rightsib = right->bb_rightsib;
+ xfs_bmbt_log_block(cur, lbp, XFS_BB_RIGHTSIB | XFS_BB_NUMRECS);
+ if (be64_to_cpu(left->bb_rightsib) != NULLDFSBNO) {
+@@ -924,7 +924,7 @@
+ xfs_iroot_realloc(ip, i, cur->bc_private.b.whichfork);
+ block = ifp->if_broot;
+ }
+- be16_add(&block->bb_numrecs, i);
++ be16_add_cpu(&block->bb_numrecs, i);
+ ASSERT(block->bb_numrecs == cblock->bb_numrecs);
+ kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
+ ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur);
+@@ -947,7 +947,7 @@
+ XFS_TRANS_DQ_BCOUNT, -1L);
+ xfs_trans_binval(cur->bc_tp, cbp);
+ cur->bc_bufs[level - 1] = NULL;
+- be16_add(&block->bb_level, -1);
++ be16_add_cpu(&block->bb_level, -1);
+ xfs_trans_log_inode(cur->bc_tp, ip,
+ XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
+ cur->bc_nlevels--;
+@@ -1401,9 +1401,9 @@
+ key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp));
+ rkp = &key;
+ }
+- be16_add(&left->bb_numrecs, -1);
++ be16_add_cpu(&left->bb_numrecs, -1);
+ xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS);
+- be16_add(&right->bb_numrecs, 1);
++ be16_add_cpu(&right->bb_numrecs, 1);
+ #ifdef DEBUG
+ if (level > 0)
+ xfs_btree_check_key(XFS_BTNUM_BMAP, rkp, rkp + 1);
+@@ -1535,7 +1535,7 @@
+ right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2);
+ if ((be16_to_cpu(left->bb_numrecs) & 1) &&
+ cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
+- be16_add(&right->bb_numrecs, 1);
++ be16_add_cpu(&right->bb_numrecs, 1);
+ i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
+ if (level > 0) {
+ lkp = XFS_BMAP_KEY_IADDR(left, i, cur);
+@@ -1562,7 +1562,7 @@
+ xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
+ *startoff = xfs_bmbt_disk_get_startoff(rrp);
+ }
+- be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
++ be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
+ right->bb_rightsib = left->bb_rightsib;
+ left->bb_rightsib = cpu_to_be64(args.fsbno);
+ right->bb_leftsib = cpu_to_be64(lbno);
+@@ -2241,7 +2241,7 @@
+ bp = xfs_btree_get_bufl(args.mp, cur->bc_tp, args.fsbno, 0);
+ cblock = XFS_BUF_TO_BMBT_BLOCK(bp);
+ *cblock = *block;
+- be16_add(&block->bb_level, 1);
++ be16_add_cpu(&block->bb_level, 1);
+ block->bb_numrecs = cpu_to_be16(1);
+ cur->bc_nlevels++;
+ cur->bc_ptrs[level + 1] = 1;
+diff -Nurd linux-2.6.24/fs/xfs/xfs_da_btree.c linux-2.6.24-oxe810/fs/xfs/xfs_da_btree.c
+--- linux-2.6.24/fs/xfs/xfs_da_btree.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_da_btree.c 2008-06-11 17:46:48.000000000 +0200
+@@ -511,12 +511,12 @@
+ * Move the req'd B-tree elements from high in node1 to
+ * low in node2.
+ */
+- be16_add(&node2->hdr.count, count);
++ be16_add_cpu(&node2->hdr.count, count);
+ tmp = count * (uint)sizeof(xfs_da_node_entry_t);
+ btree_s = &node1->btree[be16_to_cpu(node1->hdr.count) - count];
+ btree_d = &node2->btree[0];
+ memcpy(btree_d, btree_s, tmp);
+- be16_add(&node1->hdr.count, -count);
++ be16_add_cpu(&node1->hdr.count, -count);
+ } else {
+ /*
+ * Move the req'd B-tree elements from low in node2 to
+@@ -527,7 +527,7 @@
+ btree_s = &node2->btree[0];
+ btree_d = &node1->btree[be16_to_cpu(node1->hdr.count)];
+ memcpy(btree_d, btree_s, tmp);
+- be16_add(&node1->hdr.count, count);
++ be16_add_cpu(&node1->hdr.count, count);
+ xfs_da_log_buf(tp, blk1->bp,
+ XFS_DA_LOGRANGE(node1, btree_d, tmp));
+
+@@ -539,7 +539,7 @@
+ btree_s = &node2->btree[count];
+ btree_d = &node2->btree[0];
+ memmove(btree_d, btree_s, tmp);
+- be16_add(&node2->hdr.count, -count);
++ be16_add_cpu(&node2->hdr.count, -count);
+ }
+
+ /*
+@@ -604,7 +604,7 @@
+ btree->before = cpu_to_be32(newblk->blkno);
+ xfs_da_log_buf(state->args->trans, oldblk->bp,
+ XFS_DA_LOGRANGE(node, btree, tmp + sizeof(*btree)));
+- be16_add(&node->hdr.count, 1);
++ be16_add_cpu(&node->hdr.count, 1);
+ xfs_da_log_buf(state->args->trans, oldblk->bp,
+ XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr)));
+
+@@ -959,7 +959,7 @@
+ memset((char *)btree, 0, sizeof(xfs_da_node_entry_t));
+ xfs_da_log_buf(state->args->trans, drop_blk->bp,
+ XFS_DA_LOGRANGE(node, btree, sizeof(*btree)));
+- be16_add(&node->hdr.count, -1);
++ be16_add_cpu(&node->hdr.count, -1);
+ xfs_da_log_buf(state->args->trans, drop_blk->bp,
+ XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr)));
+
+@@ -1018,7 +1018,7 @@
+ */
+ tmp = be16_to_cpu(drop_node->hdr.count) * (uint)sizeof(xfs_da_node_entry_t);
+ memcpy(btree, &drop_node->btree[0], tmp);
+- be16_add(&save_node->hdr.count, be16_to_cpu(drop_node->hdr.count));
++ be16_add_cpu(&save_node->hdr.count, be16_to_cpu(drop_node->hdr.count));
+
+ xfs_da_log_buf(tp, save_blk->bp,
+ XFS_DA_LOGRANGE(save_node, &save_node->hdr,
+diff -Nurd linux-2.6.24/fs/xfs/xfs_dir2_block.c linux-2.6.24-oxe810/fs/xfs/xfs_dir2_block.c
+--- linux-2.6.24/fs/xfs/xfs_dir2_block.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_dir2_block.c 2008-06-11 17:46:48.000000000 +0200
+@@ -271,7 +271,7 @@
+ }
+ lfloglow = toidx + 1 - (be32_to_cpu(btp->stale) - 1);
+ lfloghigh -= be32_to_cpu(btp->stale) - 1;
+- be32_add(&btp->count, -(be32_to_cpu(btp->stale) - 1));
++ be32_add_cpu(&btp->count, -(be32_to_cpu(btp->stale) - 1));
+ xfs_dir2_data_make_free(tp, bp,
+ (xfs_dir2_data_aoff_t)((char *)blp - (char *)block),
+ (xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)),
+@@ -326,7 +326,7 @@
+ /*
+ * Update the tail (entry count).
+ */
+- be32_add(&btp->count, 1);
++ be32_add_cpu(&btp->count, 1);
+ /*
+ * If we now need to rebuild the bestfree map, do so.
+ * This needs to happen before the next call to use_free.
+@@ -387,7 +387,7 @@
+ lfloglow = MIN(mid, lfloglow);
+ lfloghigh = MAX(highstale, lfloghigh);
+ }
+- be32_add(&btp->stale, -1);
++ be32_add_cpu(&btp->stale, -1);
+ }
+ /*
+ * Point to the new data entry.
+@@ -767,7 +767,7 @@
+ /*
+ * Fix up the block tail.
+ */
+- be32_add(&btp->stale, 1);
++ be32_add_cpu(&btp->stale, 1);
+ xfs_dir2_block_log_tail(tp, bp);
+ /*
+ * Remove the leaf entry by marking it stale.
+diff -Nurd linux-2.6.24/fs/xfs/xfs_dir2_data.c linux-2.6.24-oxe810/fs/xfs/xfs_dir2_data.c
+--- linux-2.6.24/fs/xfs/xfs_dir2_data.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_dir2_data.c 2008-06-11 17:46:48.000000000 +0200
+@@ -587,7 +587,7 @@
+ /*
+ * Fix up the new big freespace.
+ */
+- be16_add(&prevdup->length, len + be16_to_cpu(postdup->length));
++ be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length));
+ *xfs_dir2_data_unused_tag_p(prevdup) =
+ cpu_to_be16((char *)prevdup - (char *)d);
+ xfs_dir2_data_log_unused(tp, bp, prevdup);
+@@ -621,7 +621,7 @@
+ */
+ else if (prevdup) {
+ dfp = xfs_dir2_data_freefind(d, prevdup);
+- be16_add(&prevdup->length, len);
++ be16_add_cpu(&prevdup->length, len);
+ *xfs_dir2_data_unused_tag_p(prevdup) =
+ cpu_to_be16((char *)prevdup - (char *)d);
+ xfs_dir2_data_log_unused(tp, bp, prevdup);
+diff -Nurd linux-2.6.24/fs/xfs/xfs_dir2_leaf.c linux-2.6.24-oxe810/fs/xfs/xfs_dir2_leaf.c
+--- linux-2.6.24/fs/xfs/xfs_dir2_leaf.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_dir2_leaf.c 2008-06-11 17:46:48.000000000 +0200
+@@ -359,7 +359,7 @@
+ bestsp--;
+ memmove(&bestsp[0], &bestsp[1],
+ be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0]));
+- be32_add(<p->bestcount, 1);
++ be32_add_cpu(<p->bestcount, 1);
+ xfs_dir2_leaf_log_tail(tp, lbp);
+ xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
+ }
+@@ -445,7 +445,7 @@
+ */
+ lfloglow = index;
+ lfloghigh = be16_to_cpu(leaf->hdr.count);
+- be16_add(&leaf->hdr.count, 1);
++ be16_add_cpu(&leaf->hdr.count, 1);
+ }
+ /*
+ * There are stale entries.
+@@ -523,7 +523,7 @@
+ lfloglow = MIN(index, lfloglow);
+ lfloghigh = MAX(highstale, lfloghigh);
+ }
+- be16_add(&leaf->hdr.stale, -1);
++ be16_add_cpu(&leaf->hdr.stale, -1);
+ }
+ /*
+ * Fill in the new leaf entry.
+@@ -626,7 +626,7 @@
+ * Update and log the header, log the leaf entries.
+ */
+ ASSERT(be16_to_cpu(leaf->hdr.stale) == from - to);
+- be16_add(&leaf->hdr.count, -(be16_to_cpu(leaf->hdr.stale)));
++ be16_add_cpu(&leaf->hdr.count, -(be16_to_cpu(leaf->hdr.stale)));
+ leaf->hdr.stale = 0;
+ xfs_dir2_leaf_log_header(args->trans, bp);
+ if (loglow != -1)
+@@ -728,7 +728,7 @@
+ /*
+ * Adjust the leaf header values.
+ */
+- be16_add(&leaf->hdr.count, -(from - to));
++ be16_add_cpu(&leaf->hdr.count, -(from - to));
+ leaf->hdr.stale = cpu_to_be16(1);
+ /*
+ * Remember the low/high stale value only in the "right"
+@@ -1470,7 +1470,7 @@
+ /*
+ * We just mark the leaf entry stale by putting a null in it.
+ */
+- be16_add(&leaf->hdr.stale, 1);
++ be16_add_cpu(&leaf->hdr.stale, 1);
+ xfs_dir2_leaf_log_header(tp, lbp);
+ lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
+ xfs_dir2_leaf_log_ents(tp, lbp, index, index);
+@@ -1531,7 +1531,7 @@
+ */
+ memmove(&bestsp[db - i], bestsp,
+ (be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp));
+- be32_add(<p->bestcount, -(db - i));
++ be32_add_cpu(<p->bestcount, -(db - i));
+ xfs_dir2_leaf_log_tail(tp, lbp);
+ xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
+ } else
+@@ -1712,7 +1712,7 @@
+ * Eliminate the last bests entry from the table.
+ */
+ bestsp = xfs_dir2_leaf_bests_p(ltp);
+- be32_add(<p->bestcount, -1);
++ be32_add_cpu(<p->bestcount, -1);
+ memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp));
+ xfs_dir2_leaf_log_tail(tp, lbp);
+ xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
+diff -Nurd linux-2.6.24/fs/xfs/xfs_dir2_node.c linux-2.6.24-oxe810/fs/xfs/xfs_dir2_node.c
+--- linux-2.6.24/fs/xfs/xfs_dir2_node.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_dir2_node.c 2008-06-11 17:46:48.000000000 +0200
+@@ -254,7 +254,7 @@
+ (be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep));
+ lfloglow = index;
+ lfloghigh = be16_to_cpu(leaf->hdr.count);
+- be16_add(&leaf->hdr.count, 1);
++ be16_add_cpu(&leaf->hdr.count, 1);
+ }
+ /*
+ * There are stale entries. We'll use one for the new entry.
+@@ -322,7 +322,7 @@
+ lfloglow = MIN(index, lfloglow);
+ lfloghigh = MAX(highstale, lfloghigh);
+ }
+- be16_add(&leaf->hdr.stale, -1);
++ be16_add_cpu(&leaf->hdr.stale, -1);
+ }
+ /*
+ * Insert the new entry, log everything.
+@@ -697,10 +697,10 @@
+ /*
+ * Update the headers and log them.
+ */
+- be16_add(&leaf_s->hdr.count, -(count));
+- be16_add(&leaf_s->hdr.stale, -(stale));
+- be16_add(&leaf_d->hdr.count, count);
+- be16_add(&leaf_d->hdr.stale, stale);
++ be16_add_cpu(&leaf_s->hdr.count, -(count));
++ be16_add_cpu(&leaf_s->hdr.stale, -(stale));
++ be16_add_cpu(&leaf_d->hdr.count, count);
++ be16_add_cpu(&leaf_d->hdr.stale, stale);
+ xfs_dir2_leaf_log_header(tp, bp_s);
+ xfs_dir2_leaf_log_header(tp, bp_d);
+ xfs_dir2_leafn_check(args->dp, bp_s);
+@@ -885,7 +885,7 @@
+ * Kill the leaf entry by marking it stale.
+ * Log the leaf block changes.
+ */
+- be16_add(&leaf->hdr.stale, 1);
++ be16_add_cpu(&leaf->hdr.stale, 1);
+ xfs_dir2_leaf_log_header(tp, bp);
+ lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
+ xfs_dir2_leaf_log_ents(tp, bp, index, index);
+@@ -971,7 +971,7 @@
+ /*
+ * One less used entry in the free table.
+ */
+- be32_add(&free->hdr.nused, -1);
++ be32_add_cpu(&free->hdr.nused, -1);
+ xfs_dir2_free_log_header(tp, fbp);
+ /*
+ * If this was the last entry in the table, we can
+@@ -1642,7 +1642,7 @@
+ * (this should always be true) then update the header.
+ */
+ if (be16_to_cpu(free->bests[findex]) == NULLDATAOFF) {
+- be32_add(&free->hdr.nused, 1);
++ be32_add_cpu(&free->hdr.nused, 1);
+ xfs_dir2_free_log_header(tp, fbp);
+ }
+ /*
+diff -Nurd linux-2.6.24/fs/xfs/xfs_fsops.c linux-2.6.24-oxe810/fs/xfs/xfs_fsops.c
+--- linux-2.6.24/fs/xfs/xfs_fsops.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_fsops.c 2008-06-11 17:46:48.000000000 +0200
+@@ -318,7 +318,7 @@
+ }
+ ASSERT(bp);
+ agi = XFS_BUF_TO_AGI(bp);
+- be32_add(&agi->agi_length, new);
++ be32_add_cpu(&agi->agi_length, new);
+ ASSERT(nagcount == oagcount ||
+ be32_to_cpu(agi->agi_length) == mp->m_sb.sb_agblocks);
+ xfs_ialloc_log_agi(tp, bp, XFS_AGI_LENGTH);
+@@ -331,7 +331,7 @@
+ }
+ ASSERT(bp);
+ agf = XFS_BUF_TO_AGF(bp);
+- be32_add(&agf->agf_length, new);
++ be32_add_cpu(&agf->agf_length, new);
+ ASSERT(be32_to_cpu(agf->agf_length) ==
+ be32_to_cpu(agi->agi_length));
+ xfs_alloc_log_agf(tp, bp, XFS_AGF_LENGTH);
+diff -Nurd linux-2.6.24/fs/xfs/xfs_ialloc.c linux-2.6.24-oxe810/fs/xfs/xfs_ialloc.c
+--- linux-2.6.24/fs/xfs/xfs_ialloc.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_ialloc.c 2008-06-11 17:46:48.000000000 +0200
+@@ -301,8 +301,8 @@
+ }
+ xfs_trans_inode_alloc_buf(tp, fbuf);
+ }
+- be32_add(&agi->agi_count, newlen);
+- be32_add(&agi->agi_freecount, newlen);
++ be32_add_cpu(&agi->agi_count, newlen);
++ be32_add_cpu(&agi->agi_freecount, newlen);
+ agno = be32_to_cpu(agi->agi_seqno);
+ down_read(&args.mp->m_peraglock);
+ args.mp->m_perag[agno].pagi_freecount += newlen;
+@@ -885,7 +885,7 @@
+ if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount,
+ rec.ir_free)))
+ goto error0;
+- be32_add(&agi->agi_freecount, -1);
++ be32_add_cpu(&agi->agi_freecount, -1);
+ xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
+ down_read(&mp->m_peraglock);
+ mp->m_perag[tagno].pagi_freecount--;
+@@ -1065,8 +1065,8 @@
+ * to be freed when the transaction is committed.
+ */
+ ilen = XFS_IALLOC_INODES(mp);
+- be32_add(&agi->agi_count, -ilen);
+- be32_add(&agi->agi_freecount, -(ilen - 1));
++ be32_add_cpu(&agi->agi_count, -ilen);
++ be32_add_cpu(&agi->agi_freecount, -(ilen - 1));
+ xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT);
+ down_read(&mp->m_peraglock);
+ mp->m_perag[agno].pagi_freecount -= ilen - 1;
+@@ -1095,7 +1095,7 @@
+ /*
+ * Change the inode free counts and log the ag/sb changes.
+ */
+- be32_add(&agi->agi_freecount, 1);
++ be32_add_cpu(&agi->agi_freecount, 1);
+ xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
+ down_read(&mp->m_peraglock);
+ mp->m_perag[agno].pagi_freecount++;
+diff -Nurd linux-2.6.24/fs/xfs/xfs_ialloc_btree.c linux-2.6.24-oxe810/fs/xfs/xfs_ialloc_btree.c
+--- linux-2.6.24/fs/xfs/xfs_ialloc_btree.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_ialloc_btree.c 2008-06-11 17:46:48.000000000 +0200
+@@ -189,7 +189,7 @@
+ */
+ bno = be32_to_cpu(agi->agi_root);
+ agi->agi_root = *pp;
+- be32_add(&agi->agi_level, -1);
++ be32_add_cpu(&agi->agi_level, -1);
+ /*
+ * Free the block.
+ */
+@@ -1132,7 +1132,7 @@
+ /*
+ * Bump and log left's numrecs, decrement and log right's numrecs.
+ */
+- be16_add(&left->bb_numrecs, 1);
++ be16_add_cpu(&left->bb_numrecs, 1);
+ xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
+ #ifdef DEBUG
+ if (level > 0)
+@@ -1140,7 +1140,7 @@
+ else
+ xfs_btree_check_rec(cur->bc_btnum, lrp - 1, lrp);
+ #endif
+- be16_add(&right->bb_numrecs, -1);
++ be16_add_cpu(&right->bb_numrecs, -1);
+ xfs_inobt_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
+ /*
+ * Slide the contents of right down one entry.
+@@ -1232,7 +1232,7 @@
+ * Set the root data in the a.g. inode structure.
+ */
+ agi->agi_root = cpu_to_be32(args.agbno);
+- be32_add(&agi->agi_level, 1);
++ be32_add_cpu(&agi->agi_level, 1);
+ xfs_ialloc_log_agi(args.tp, cur->bc_private.i.agbp,
+ XFS_AGI_ROOT | XFS_AGI_LEVEL);
+ /*
+@@ -1426,9 +1426,9 @@
+ /*
+ * Decrement and log left's numrecs, bump and log right's numrecs.
+ */
+- be16_add(&left->bb_numrecs, -1);
++ be16_add_cpu(&left->bb_numrecs, -1);
+ xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
+- be16_add(&right->bb_numrecs, 1);
++ be16_add_cpu(&right->bb_numrecs, 1);
+ #ifdef DEBUG
+ if (level > 0)
+ xfs_btree_check_key(cur->bc_btnum, rkp, rkp + 1);
+@@ -1529,7 +1529,7 @@
+ */
+ if ((be16_to_cpu(left->bb_numrecs) & 1) &&
+ cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
+- be16_add(&right->bb_numrecs, 1);
++ be16_add_cpu(&right->bb_numrecs, 1);
+ i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
+ /*
+ * For non-leaf blocks, copy keys and addresses over to the new block.
+@@ -1565,7 +1565,7 @@
+ * Find the left block number by looking in the buffer.
+ * Adjust numrecs, sibling pointers.
+ */
+- be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
++ be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
+ right->bb_rightsib = left->bb_rightsib;
+ left->bb_rightsib = cpu_to_be32(args.agbno);
+ right->bb_leftsib = cpu_to_be32(lbno);
+diff -Nurd linux-2.6.24/fs/xfs/xfs_inode.c linux-2.6.24-oxe810/fs/xfs/xfs_inode.c
+--- linux-2.6.24/fs/xfs/xfs_inode.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_inode.c 2008-06-11 17:46:48.000000000 +0200
+@@ -1158,6 +1158,16 @@
+ if ((prid != 0) && (ip->i_d.di_version == XFS_DINODE_VERSION_1))
+ xfs_bump_ino_vers2(tp, ip);
+
++#ifdef CONFIG_OXNAS_SUID_INHERIT
++ /* Modification to propagate SUID down directory hierarchy */
++ if (pip && XFS_INHERIT_UID(pip)) {
++ ip->i_d.di_uid = pip->i_d.di_uid;
++ if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) {
++ ip->i_d.di_mode |= S_ISUID;
++ }
++ }
++#endif // CONFIG_OXNAS_SUID_INHERIT
++
+ if (pip && XFS_INHERIT_GID(pip)) {
+ ip->i_d.di_gid = pip->i_d.di_gid;
+ if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) {
+diff -Nurd linux-2.6.24/fs/xfs/xfs_inode.h linux-2.6.24-oxe810/fs/xfs/xfs_inode.h
+--- linux-2.6.24/fs/xfs/xfs_inode.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_inode.h 2008-06-11 17:46:48.000000000 +0200
+@@ -495,6 +495,11 @@
+ #define XFS_INHERIT_GID(pip) \
+ (((pip)->i_mount->m_flags & XFS_MOUNT_GRPID) || \
+ ((pip)->i_d.di_mode & S_ISGID))
++#ifdef CONFIG_OXNAS_SUID_INHERIT
++/* Modification to propagate SUID down directory hierarchy */
++#define XFS_INHERIT_UID(pip) \
++ ((pip)->i_d.di_mode & S_ISUID)
++#endif // CONFIG_OXNAS_SUID_INHERIT
+
+ /*
+ * Flags for xfs_iget()
+diff -Nurd linux-2.6.24/fs/xfs/xfs_log.c linux-2.6.24-oxe810/fs/xfs/xfs_log.c
+--- linux-2.6.24/fs/xfs/xfs_log.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_log.c 2008-06-11 17:46:48.000000000 +0200
+@@ -399,10 +399,10 @@
+ {
+ xlog_t *log = mp->m_log;
+ xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl;
+- int abortflg, spl;
++ int abortflg;
+
+ cb->cb_next = NULL;
+- spl = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+ abortflg = (iclog->ic_state & XLOG_STATE_IOERROR);
+ if (!abortflg) {
+ ASSERT_ALWAYS((iclog->ic_state == XLOG_STATE_ACTIVE) ||
+@@ -411,7 +411,7 @@
+ *(iclog->ic_callback_tail) = cb;
+ iclog->ic_callback_tail = &(cb->cb_next);
+ }
+- LOG_UNLOCK(log, spl);
++ spin_unlock(&log->l_icloglock);
+ return abortflg;
+ } /* xfs_log_notify */
+
+@@ -503,6 +503,8 @@
+ xfs_daddr_t blk_offset,
+ int num_bblks)
+ {
++ int error;
++
+ if (!(mp->m_flags & XFS_MOUNT_NORECOVERY))
+ cmn_err(CE_NOTE, "XFS mounting filesystem %s", mp->m_fsname);
+ else {
+@@ -519,7 +521,7 @@
+ * just worked.
+ */
+ if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
+- int error, readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
++ int readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
+
+ if (readonly)
+ mp->m_flags &= ~XFS_MOUNT_RDONLY;
+@@ -530,8 +532,8 @@
+ mp->m_flags |= XFS_MOUNT_RDONLY;
+ if (error) {
+ cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error);
+- xlog_dealloc_log(mp->m_log);
+- return error;
++
++ goto error;
+ }
+ }
+
+@@ -540,6 +542,9 @@
+
+ /* End mounting message in xfs_log_mount_finish */
+ return 0;
++error:
++ xfs_log_unmount_dealloc(mp);
++ return error;
+ } /* xfs_log_mount */
+
+ /*
+@@ -606,7 +611,6 @@
+ xfs_log_ticket_t tic = NULL;
+ xfs_lsn_t lsn;
+ int error;
+- SPLDECL(s);
+
+ /* the data section must be 32 bit size aligned */
+ struct {
+@@ -659,24 +663,24 @@
+ }
+
+
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+ iclog = log->l_iclog;
+ iclog->ic_refcnt++;
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ xlog_state_want_sync(log, iclog);
+ (void) xlog_state_release_iclog(log, iclog);
+
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+ if (!(iclog->ic_state == XLOG_STATE_ACTIVE ||
+ iclog->ic_state == XLOG_STATE_DIRTY)) {
+ if (!XLOG_FORCED_SHUTDOWN(log)) {
+ sv_wait(&iclog->ic_forcesema, PMEM,
+ &log->l_icloglock, s);
+ } else {
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ }
+ } else {
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ }
+ if (tic) {
+ xlog_trace_loggrant(log, tic, "unmount rec");
+@@ -697,15 +701,15 @@
+ * a file system that went into forced_shutdown as
+ * the result of an unmount..
+ */
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+ iclog = log->l_iclog;
+ iclog->ic_refcnt++;
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+
+ xlog_state_want_sync(log, iclog);
+ (void) xlog_state_release_iclog(log, iclog);
+
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+
+ if ( ! ( iclog->ic_state == XLOG_STATE_ACTIVE
+ || iclog->ic_state == XLOG_STATE_DIRTY
+@@ -714,7 +718,7 @@
+ sv_wait(&iclog->ic_forcesema, PMEM,
+ &log->l_icloglock, s);
+ } else {
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ }
+ }
+
+@@ -723,6 +727,9 @@
+
+ /*
+ * Deallocate log structures for unmount/relocation.
++ *
++ * We need to stop the aild from running before we destroy
++ * and deallocate the log as the aild references the log.
+ */
+ void
+ xfs_log_unmount_dealloc(xfs_mount_t *mp)
+@@ -762,20 +769,18 @@
+ xlog_ticket_t *tic;
+ xlog_t *log = mp->m_log;
+ int need_bytes, free_bytes, cycle, bytes;
+- SPLDECL(s);
+
+ if (XLOG_FORCED_SHUTDOWN(log))
+ return;
+- ASSERT(!XFS_FORCED_SHUTDOWN(mp));
+
+ if (tail_lsn == 0) {
+ /* needed since sync_lsn is 64 bits */
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+ tail_lsn = log->l_last_sync_lsn;
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ }
+
+- s = GRANT_LOCK(log);
++ spin_lock(&log->l_grant_lock);
+
+ /* Also an invalid lsn. 1 implies that we aren't passing in a valid
+ * tail_lsn.
+@@ -824,7 +829,7 @@
+ tic = tic->t_next;
+ } while (tic != log->l_reserve_headq);
+ }
+- GRANT_UNLOCK(log, s);
++ spin_unlock(&log->l_grant_lock);
+ } /* xfs_log_move_tail */
+
+ /*
+@@ -836,14 +841,13 @@
+ int
+ xfs_log_need_covered(xfs_mount_t *mp)
+ {
+- SPLDECL(s);
+ int needed = 0, gen;
+ xlog_t *log = mp->m_log;
+
+ if (!xfs_fs_writable(mp))
+ return 0;
+
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+ if (((log->l_covered_state == XLOG_STATE_COVER_NEED) ||
+ (log->l_covered_state == XLOG_STATE_COVER_NEED2))
+ && !xfs_trans_first_ail(mp, &gen)
+@@ -856,7 +860,7 @@
+ }
+ needed = 1;
+ }
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ return needed;
+ }
+
+@@ -881,17 +885,16 @@
+ xlog_assign_tail_lsn(xfs_mount_t *mp)
+ {
+ xfs_lsn_t tail_lsn;
+- SPLDECL(s);
+ xlog_t *log = mp->m_log;
+
+ tail_lsn = xfs_trans_tail_ail(mp);
+- s = GRANT_LOCK(log);
++ spin_lock(&log->l_grant_lock);
+ if (tail_lsn != 0) {
+ log->l_tail_lsn = tail_lsn;
+ } else {
+ tail_lsn = log->l_tail_lsn = log->l_last_sync_lsn;
+ }
+- GRANT_UNLOCK(log, s);
++ spin_unlock(&log->l_grant_lock);
+
+ return tail_lsn;
+ } /* xlog_assign_tail_lsn */
+@@ -911,7 +914,7 @@
+ * the tail. The details of this case are described below, but the end
+ * result is that we return the size of the log as the amount of space left.
+ */
+-int
++STATIC int
+ xlog_space_left(xlog_t *log, int cycle, int bytes)
+ {
+ int free_bytes;
+@@ -1165,7 +1168,7 @@
+ log->l_flags |= XLOG_ACTIVE_RECOVERY;
+
+ log->l_prev_block = -1;
+- ASSIGN_ANY_LSN_HOST(log->l_tail_lsn, 1, 0);
++ log->l_tail_lsn = xlog_assign_lsn(1, 0);
+ /* log->l_tail_lsn = 0x100000000LL; cycle = 1; current block = 0 */
+ log->l_last_sync_lsn = log->l_tail_lsn;
+ log->l_curr_cycle = 1; /* 0 is bad since this is initial value */
+@@ -1193,8 +1196,8 @@
+ ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
+ log->l_xbuf = bp;
+
+- spinlock_init(&log->l_icloglock, "iclog");
+- spinlock_init(&log->l_grant_lock, "grhead_iclog");
++ spin_lock_init(&log->l_icloglock);
++ spin_lock_init(&log->l_grant_lock);
+ initnsema(&log->l_flushsema, 0, "ic-flush");
+ xlog_state_ticket_alloc(log); /* wait until after icloglock inited */
+
+@@ -1231,12 +1234,12 @@
+
+ head = &iclog->ic_header;
+ memset(head, 0, sizeof(xlog_rec_header_t));
+- INT_SET(head->h_magicno, ARCH_CONVERT, XLOG_HEADER_MAGIC_NUM);
+- INT_SET(head->h_version, ARCH_CONVERT,
++ head->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM);
++ head->h_version = cpu_to_be32(
+ XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? 2 : 1);
+- INT_SET(head->h_size, ARCH_CONVERT, log->l_iclog_size);
++ head->h_size = cpu_to_be32(log->l_iclog_size);
+ /* new fields */
+- INT_SET(head->h_fmt, ARCH_CONVERT, XLOG_FMT);
++ head->h_fmt = cpu_to_be32(XLOG_FMT);
+ memcpy(&head->h_fs_uuid, &mp->m_sb.sb_uuid, sizeof(uuid_t));
+
+
+@@ -1293,7 +1296,7 @@
+ * pushes on an lsn which is further along in the log once we reach the high
+ * water mark. In this manner, we would be creating a low water mark.
+ */
+-void
++STATIC void
+ xlog_grant_push_ail(xfs_mount_t *mp,
+ int need_bytes)
+ {
+@@ -1305,11 +1308,10 @@
+ int threshold_block; /* block in lsn we'd like to be at */
+ int threshold_cycle; /* lsn cycle we'd like to be at */
+ int free_threshold;
+- SPLDECL(s);
+
+ ASSERT(BTOBB(need_bytes) < log->l_logBBsize);
+
+- s = GRANT_LOCK(log);
++ spin_lock(&log->l_grant_lock);
+ free_bytes = xlog_space_left(log,
+ log->l_grant_reserve_cycle,
+ log->l_grant_reserve_bytes);
+@@ -1331,8 +1333,7 @@
+ threshold_block -= log->l_logBBsize;
+ threshold_cycle += 1;
+ }
+- ASSIGN_ANY_LSN_HOST(threshold_lsn, threshold_cycle,
+- threshold_block);
++ threshold_lsn = xlog_assign_lsn(threshold_cycle, threshold_block);
+
+ /* Don't pass in an lsn greater than the lsn of the last
+ * log record known to be on disk.
+@@ -1340,7 +1341,7 @@
+ if (XFS_LSN_CMP(threshold_lsn, log->l_last_sync_lsn) > 0)
+ threshold_lsn = log->l_last_sync_lsn;
+ }
+- GRANT_UNLOCK(log, s);
++ spin_unlock(&log->l_grant_lock);
+
+ /*
+ * Get the transaction layer to kick the dirty buffers out to
+@@ -1378,19 +1379,18 @@
+ * is added immediately before calling bwrite().
+ */
+
+-int
++STATIC int
+ xlog_sync(xlog_t *log,
+ xlog_in_core_t *iclog)
+ {
+ xfs_caddr_t dptr; /* pointer to byte sized element */
+ xfs_buf_t *bp;
+- int i, ops;
++ int i;
+ uint count; /* byte count of bwrite */
+ uint count_init; /* initial count before roundup */
+ int roundoff; /* roundoff to BB or stripe */
+ int split = 0; /* split write into two regions */
+ int error;
+- SPLDECL(s);
+ int v2 = XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb);
+
+ XFS_STATS_INC(xs_log_writes);
+@@ -1415,30 +1415,24 @@
+ roundoff < BBTOB(1)));
+
+ /* move grant heads by roundoff in sync */
+- s = GRANT_LOCK(log);
++ spin_lock(&log->l_grant_lock);
+ xlog_grant_add_space(log, roundoff);
+- GRANT_UNLOCK(log, s);
++ spin_unlock(&log->l_grant_lock);
+
+ /* put cycle number in every block */
+ xlog_pack_data(log, iclog, roundoff);
+
+ /* real byte length */
+ if (v2) {
+- INT_SET(iclog->ic_header.h_len,
+- ARCH_CONVERT,
+- iclog->ic_offset + roundoff);
++ iclog->ic_header.h_len = cpu_to_be32(iclog->ic_offset + roundoff);
+ } else {
+- INT_SET(iclog->ic_header.h_len, ARCH_CONVERT, iclog->ic_offset);
++ iclog->ic_header.h_len = cpu_to_be32(iclog->ic_offset);
+ }
+
+- /* put ops count in correct order */
+- ops = iclog->ic_header.h_num_logops;
+- INT_SET(iclog->ic_header.h_num_logops, ARCH_CONVERT, ops);
+-
+ bp = iclog->ic_bp;
+ ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) == (unsigned long)1);
+ XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2);
+- XFS_BUF_SET_ADDR(bp, BLOCK_LSN(INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT)));
++ XFS_BUF_SET_ADDR(bp, BLOCK_LSN(be64_to_cpu(iclog->ic_header.h_lsn)));
+
+ XFS_STATS_ADD(xs_log_blocks, BTOBB(count));
+
+@@ -1450,11 +1444,13 @@
+ } else {
+ iclog->ic_bwritecnt = 1;
+ }
++
+ XFS_BUF_SET_COUNT(bp, count);
+ XFS_BUF_SET_FSPRIVATE(bp, iclog); /* save for later */
+ XFS_BUF_ZEROFLAGS(bp);
+ XFS_BUF_BUSY(bp);
+ XFS_BUF_ASYNC(bp);
++
+ /*
+ * Do an ordered write for the log block.
+ * Its unnecessary to flush the first split block in the log wrap case.
+@@ -1480,6 +1476,7 @@
+ XFS_BUF_ADDR(bp));
+ return error;
+ }
++
+ if (split) {
+ bp = iclog->ic_log->l_xbuf;
+ ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) ==
+@@ -1501,10 +1498,10 @@
+ * a new cycle. Watch out for the header magic number
+ * case, though.
+ */
+- for (i=0; i<split; i += BBSIZE) {
+- INT_MOD(*(uint *)dptr, ARCH_CONVERT, +1);
+- if (INT_GET(*(uint *)dptr, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM)
+- INT_MOD(*(uint *)dptr, ARCH_CONVERT, +1);
++ for (i = 0; i < split; i += BBSIZE) {
++ be32_add_cpu((__be32 *)dptr, 1);
++ if (be32_to_cpu(*(__be32 *)dptr) == XLOG_HEADER_MAGIC_NUM)
++ be32_add_cpu((__be32 *)dptr, 1);
+ dptr += BBSIZE;
+ }
+
+@@ -1520,6 +1517,7 @@
+ return error;
+ }
+ }
++
+ return 0;
+ } /* xlog_sync */
+
+@@ -1527,7 +1525,7 @@
+ /*
+ * Deallocate a log structure
+ */
+-void
++STATIC void
+ xlog_dealloc_log(xlog_t *log)
+ {
+ xlog_in_core_t *iclog, *next_iclog;
+@@ -1592,14 +1590,12 @@
+ int record_cnt,
+ int copy_bytes)
+ {
+- SPLDECL(s);
+-
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+
+- iclog->ic_header.h_num_logops += record_cnt;
++ be32_add_cpu(&iclog->ic_header.h_num_logops, record_cnt);
+ iclog->ic_offset += copy_bytes;
+
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ } /* xlog_state_finish_copy */
+
+
+@@ -1752,7 +1748,7 @@
+ * we don't update ic_offset until the end when we know exactly how many
+ * bytes have been written out.
+ */
+-int
++STATIC int
+ xlog_write(xfs_mount_t * mp,
+ xfs_log_iovec_t reg[],
+ int nentries,
+@@ -1823,7 +1819,7 @@
+
+ /* start_lsn is the first lsn written to. That's all we need. */
+ if (! *start_lsn)
+- *start_lsn = INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT);
++ *start_lsn = be64_to_cpu(iclog->ic_header.h_lsn);
+
+ /* This loop writes out as many regions as can fit in the amount
+ * of space which was allocated by xlog_state_get_iclog_space().
+@@ -1839,7 +1835,7 @@
+ */
+ if (ticket->t_flags & XLOG_TIC_INITED) {
+ logop_head = (xlog_op_header_t *)ptr;
+- INT_SET(logop_head->oh_tid, ARCH_CONVERT, ticket->t_tid);
++ logop_head->oh_tid = cpu_to_be32(ticket->t_tid);
+ logop_head->oh_clientid = ticket->t_clientid;
+ logop_head->oh_len = 0;
+ logop_head->oh_flags = XLOG_START_TRANS;
+@@ -1853,7 +1849,7 @@
+
+ /* Copy log operation header directly into data section */
+ logop_head = (xlog_op_header_t *)ptr;
+- INT_SET(logop_head->oh_tid, ARCH_CONVERT, ticket->t_tid);
++ logop_head->oh_tid = cpu_to_be32(ticket->t_tid);
+ logop_head->oh_clientid = ticket->t_clientid;
+ logop_head->oh_res2 = 0;
+
+@@ -1888,13 +1884,14 @@
+
+ copy_off = partial_copy_len;
+ if (need_copy <= iclog->ic_size - log_offset) { /*complete write */
+- INT_SET(logop_head->oh_len, ARCH_CONVERT, copy_len = need_copy);
++ copy_len = need_copy;
++ logop_head->oh_len = cpu_to_be32(copy_len);
+ if (partial_copy)
+ logop_head->oh_flags|= (XLOG_END_TRANS|XLOG_WAS_CONT_TRANS);
+ partial_copy_len = partial_copy = 0;
+ } else { /* partial write */
+ copy_len = iclog->ic_size - log_offset;
+- INT_SET(logop_head->oh_len, ARCH_CONVERT, copy_len);
++ logop_head->oh_len = cpu_to_be32(copy_len);
+ logop_head->oh_flags |= XLOG_CONTINUE_TRANS;
+ if (partial_copy)
+ logop_head->oh_flags |= XLOG_WAS_CONT_TRANS;
+@@ -1992,7 +1989,8 @@
+ * We don't need to cover the dummy.
+ */
+ if (!changed &&
+- (INT_GET(iclog->ic_header.h_num_logops, ARCH_CONVERT) == XLOG_COVER_OPS)) {
++ (be32_to_cpu(iclog->ic_header.h_num_logops) ==
++ XLOG_COVER_OPS)) {
+ changed = 1;
+ } else {
+ /*
+@@ -2060,7 +2058,7 @@
+ lowest_lsn = 0;
+ do {
+ if (!(lsn_log->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_DIRTY))) {
+- lsn = INT_GET(lsn_log->ic_header.h_lsn, ARCH_CONVERT);
++ lsn = be64_to_cpu(lsn_log->ic_header.h_lsn);
+ if ((lsn && !lowest_lsn) ||
+ (XFS_LSN_CMP(lsn, lowest_lsn) < 0)) {
+ lowest_lsn = lsn;
+@@ -2089,9 +2087,8 @@
+ int funcdidcallbacks; /* flag: function did callbacks */
+ int repeats; /* for issuing console warnings if
+ * looping too many times */
+- SPLDECL(s);
+
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+ first_iclog = iclog = log->l_iclog;
+ ioerrors = 0;
+ funcdidcallbacks = 0;
+@@ -2162,11 +2159,9 @@
+ */
+
+ lowest_lsn = xlog_get_lowest_lsn(log);
+- if (lowest_lsn && (
+- XFS_LSN_CMP(
+- lowest_lsn,
+- INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT)
+- )<0)) {
++ if (lowest_lsn &&
++ XFS_LSN_CMP(lowest_lsn,
++ be64_to_cpu(iclog->ic_header.h_lsn)) < 0) {
+ iclog = iclog->ic_next;
+ continue; /* Leave this iclog for
+ * another thread */
+@@ -2174,19 +2169,18 @@
+
+ iclog->ic_state = XLOG_STATE_CALLBACK;
+
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+
+ /* l_last_sync_lsn field protected by
+ * GRANT_LOCK. Don't worry about iclog's lsn.
+ * No one else can be here except us.
+ */
+- s = GRANT_LOCK(log);
+- ASSERT(XFS_LSN_CMP(
+- log->l_last_sync_lsn,
+- INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT)
+- )<=0);
+- log->l_last_sync_lsn = INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT);
+- GRANT_UNLOCK(log, s);
++ spin_lock(&log->l_grant_lock);
++ ASSERT(XFS_LSN_CMP(log->l_last_sync_lsn,
++ be64_to_cpu(iclog->ic_header.h_lsn)) <= 0);
++ log->l_last_sync_lsn =
++ be64_to_cpu(iclog->ic_header.h_lsn);
++ spin_unlock(&log->l_grant_lock);
+
+ /*
+ * Keep processing entries in the callback list
+@@ -2195,7 +2189,7 @@
+ * empty and change the state to DIRTY so that
+ * we don't miss any more callbacks being added.
+ */
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+ } else {
+ ioerrors++;
+ }
+@@ -2204,14 +2198,14 @@
+ while (cb) {
+ iclog->ic_callback_tail = &(iclog->ic_callback);
+ iclog->ic_callback = NULL;
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+
+ /* perform callbacks in the order given */
+ for (; cb; cb = cb_next) {
+ cb_next = cb->cb_next;
+ cb->cb_func(cb->cb_arg, aborted);
+ }
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+ cb = iclog->ic_callback;
+ }
+
+@@ -2276,7 +2270,7 @@
+ flushcnt = log->l_flushcnt;
+ log->l_flushcnt = 0;
+ }
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ while (flushcnt--)
+ vsema(&log->l_flushsema);
+ } /* xlog_state_do_callback */
+@@ -2296,15 +2290,14 @@
+ * global state machine log lock. Assume that the calls to cvsema won't
+ * take a long time. At least we know it won't sleep.
+ */
+-void
++STATIC void
+ xlog_state_done_syncing(
+ xlog_in_core_t *iclog,
+ int aborted)
+ {
+ xlog_t *log = iclog->ic_log;
+- SPLDECL(s);
+
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+
+ ASSERT(iclog->ic_state == XLOG_STATE_SYNCING ||
+ iclog->ic_state == XLOG_STATE_IOERROR);
+@@ -2320,7 +2313,7 @@
+ */
+ if (iclog->ic_state != XLOG_STATE_IOERROR) {
+ if (--iclog->ic_bwritecnt == 1) {
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ return;
+ }
+ iclog->ic_state = XLOG_STATE_DONE_SYNC;
+@@ -2332,7 +2325,7 @@
+ * I/O, the others get to wait for the result.
+ */
+ sv_broadcast(&iclog->ic_writesema);
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ xlog_state_do_callback(log, aborted, iclog); /* also cleans log */
+ } /* xlog_state_done_syncing */
+
+@@ -2357,7 +2350,7 @@
+ * needs to be incremented, depending on the amount of data which
+ * is copied.
+ */
+-int
++STATIC int
+ xlog_state_get_iclog_space(xlog_t *log,
+ int len,
+ xlog_in_core_t **iclogp,
+@@ -2365,23 +2358,22 @@
+ int *continued_write,
+ int *logoffsetp)
+ {
+- SPLDECL(s);
+ int log_offset;
+ xlog_rec_header_t *head;
+ xlog_in_core_t *iclog;
+ int error;
+
+ restart:
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+ if (XLOG_FORCED_SHUTDOWN(log)) {
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ return XFS_ERROR(EIO);
+ }
+
+ iclog = log->l_iclog;
+ if (! (iclog->ic_state == XLOG_STATE_ACTIVE)) {
+ log->l_flushcnt++;
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ xlog_trace_iclog(iclog, XLOG_TRACE_SLEEP_FLUSH);
+ XFS_STATS_INC(xs_log_noiclogs);
+ /* Ensure that log writes happen */
+@@ -2404,8 +2396,9 @@
+ xlog_tic_add_region(ticket,
+ log->l_iclog_hsize,
+ XLOG_REG_TYPE_LRHEADER);
+- INT_SET(head->h_cycle, ARCH_CONVERT, log->l_curr_cycle);
+- ASSIGN_LSN(head->h_lsn, log);
++ head->h_cycle = cpu_to_be32(log->l_curr_cycle);
++ head->h_lsn = cpu_to_be64(
++ xlog_assign_lsn(log->l_curr_cycle, log->l_curr_block));
+ ASSERT(log->l_curr_block >= 0);
+ }
+
+@@ -2423,12 +2416,12 @@
+
+ /* If I'm the only one writing to this iclog, sync it to disk */
+ if (iclog->ic_refcnt == 1) {
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ if ((error = xlog_state_release_iclog(log, iclog)))
+ return error;
+ } else {
+ iclog->ic_refcnt--;
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ }
+ goto restart;
+ }
+@@ -2449,7 +2442,7 @@
+ *iclogp = iclog;
+
+ ASSERT(iclog->ic_offset <= iclog->ic_size);
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+
+ *logoffsetp = log_offset;
+ return 0;
+@@ -2467,7 +2460,6 @@
+ {
+ int free_bytes;
+ int need_bytes;
+- SPLDECL(s);
+ #ifdef DEBUG
+ xfs_lsn_t tail_lsn;
+ #endif
+@@ -2479,7 +2471,7 @@
+ #endif
+
+ /* Is there space or do we need to sleep? */
+- s = GRANT_LOCK(log);
++ spin_lock(&log->l_grant_lock);
+ xlog_trace_loggrant(log, tic, "xlog_grant_log_space: enter");
+
+ /* something is already sleeping; insert new transaction at end */
+@@ -2502,7 +2494,7 @@
+ */
+ xlog_trace_loggrant(log, tic,
+ "xlog_grant_log_space: wake 1");
+- s = GRANT_LOCK(log);
++ spin_lock(&log->l_grant_lock);
+ }
+ if (tic->t_flags & XFS_LOG_PERM_RESERV)
+ need_bytes = tic->t_unit_res*tic->t_ocnt;
+@@ -2524,14 +2516,14 @@
+ sv_wait(&tic->t_sema, PINOD|PLTWAIT, &log->l_grant_lock, s);
+
+ if (XLOG_FORCED_SHUTDOWN(log)) {
+- s = GRANT_LOCK(log);
++ spin_lock(&log->l_grant_lock);
+ goto error_return;
+ }
+
+ xlog_trace_loggrant(log, tic,
+ "xlog_grant_log_space: wake 2");
+ xlog_grant_push_ail(log->l_mp, need_bytes);
+- s = GRANT_LOCK(log);
++ spin_lock(&log->l_grant_lock);
+ goto redo;
+ } else if (tic->t_flags & XLOG_TIC_IN_Q)
+ xlog_del_ticketq(&log->l_reserve_headq, tic);
+@@ -2553,7 +2545,7 @@
+ #endif
+ xlog_trace_loggrant(log, tic, "xlog_grant_log_space: exit");
+ xlog_verify_grant_head(log, 1);
+- GRANT_UNLOCK(log, s);
++ spin_unlock(&log->l_grant_lock);
+ return 0;
+
+ error_return:
+@@ -2567,7 +2559,7 @@
+ */
+ tic->t_curr_res = 0;
+ tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */
+- GRANT_UNLOCK(log, s);
++ spin_unlock(&log->l_grant_lock);
+ return XFS_ERROR(EIO);
+ } /* xlog_grant_log_space */
+
+@@ -2581,7 +2573,6 @@
+ xlog_regrant_write_log_space(xlog_t *log,
+ xlog_ticket_t *tic)
+ {
+- SPLDECL(s);
+ int free_bytes, need_bytes;
+ xlog_ticket_t *ntic;
+ #ifdef DEBUG
+@@ -2599,7 +2590,7 @@
+ panic("regrant Recovery problem");
+ #endif
+
+- s = GRANT_LOCK(log);
++ spin_lock(&log->l_grant_lock);
+ xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: enter");
+
+ if (XLOG_FORCED_SHUTDOWN(log))
+@@ -2638,14 +2629,14 @@
+ /* If we're shutting down, this tic is already
+ * off the queue */
+ if (XLOG_FORCED_SHUTDOWN(log)) {
+- s = GRANT_LOCK(log);
++ spin_lock(&log->l_grant_lock);
+ goto error_return;
+ }
+
+ xlog_trace_loggrant(log, tic,
+ "xlog_regrant_write_log_space: wake 1");
+ xlog_grant_push_ail(log->l_mp, tic->t_unit_res);
+- s = GRANT_LOCK(log);
++ spin_lock(&log->l_grant_lock);
+ }
+ }
+
+@@ -2665,14 +2656,14 @@
+
+ /* If we're shutting down, this tic is already off the queue */
+ if (XLOG_FORCED_SHUTDOWN(log)) {
+- s = GRANT_LOCK(log);
++ spin_lock(&log->l_grant_lock);
+ goto error_return;
+ }
+
+ xlog_trace_loggrant(log, tic,
+ "xlog_regrant_write_log_space: wake 2");
+ xlog_grant_push_ail(log->l_mp, need_bytes);
+- s = GRANT_LOCK(log);
++ spin_lock(&log->l_grant_lock);
+ goto redo;
+ } else if (tic->t_flags & XLOG_TIC_IN_Q)
+ xlog_del_ticketq(&log->l_write_headq, tic);
+@@ -2689,7 +2680,7 @@
+
+ xlog_trace_loggrant(log, tic, "xlog_regrant_write_log_space: exit");
+ xlog_verify_grant_head(log, 1);
+- GRANT_UNLOCK(log, s);
++ spin_unlock(&log->l_grant_lock);
+ return 0;
+
+
+@@ -2704,7 +2695,7 @@
+ */
+ tic->t_curr_res = 0;
+ tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */
+- GRANT_UNLOCK(log, s);
++ spin_unlock(&log->l_grant_lock);
+ return XFS_ERROR(EIO);
+ } /* xlog_regrant_write_log_space */
+
+@@ -2720,14 +2711,12 @@
+ xlog_regrant_reserve_log_space(xlog_t *log,
+ xlog_ticket_t *ticket)
+ {
+- SPLDECL(s);
+-
+ xlog_trace_loggrant(log, ticket,
+ "xlog_regrant_reserve_log_space: enter");
+ if (ticket->t_cnt > 0)
+ ticket->t_cnt--;
+
+- s = GRANT_LOCK(log);
++ spin_lock(&log->l_grant_lock);
+ xlog_grant_sub_space(log, ticket->t_curr_res);
+ ticket->t_curr_res = ticket->t_unit_res;
+ xlog_tic_reset_res(ticket);
+@@ -2737,7 +2726,7 @@
+
+ /* just return if we still have some of the pre-reserved space */
+ if (ticket->t_cnt > 0) {
+- GRANT_UNLOCK(log, s);
++ spin_unlock(&log->l_grant_lock);
+ return;
+ }
+
+@@ -2745,7 +2734,7 @@
+ xlog_trace_loggrant(log, ticket,
+ "xlog_regrant_reserve_log_space: exit");
+ xlog_verify_grant_head(log, 0);
+- GRANT_UNLOCK(log, s);
++ spin_unlock(&log->l_grant_lock);
+ ticket->t_curr_res = ticket->t_unit_res;
+ xlog_tic_reset_res(ticket);
+ } /* xlog_regrant_reserve_log_space */
+@@ -2769,12 +2758,10 @@
+ xlog_ungrant_log_space(xlog_t *log,
+ xlog_ticket_t *ticket)
+ {
+- SPLDECL(s);
+-
+ if (ticket->t_cnt > 0)
+ ticket->t_cnt--;
+
+- s = GRANT_LOCK(log);
++ spin_lock(&log->l_grant_lock);
+ xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: enter");
+
+ xlog_grant_sub_space(log, ticket->t_curr_res);
+@@ -2791,7 +2778,7 @@
+
+ xlog_trace_loggrant(log, ticket, "xlog_ungrant_log_space: exit");
+ xlog_verify_grant_head(log, 1);
+- GRANT_UNLOCK(log, s);
++ spin_unlock(&log->l_grant_lock);
+ xfs_log_move_tail(log->l_mp, 1);
+ } /* xlog_ungrant_log_space */
+
+@@ -2799,15 +2786,13 @@
+ /*
+ * Atomically put back used ticket.
+ */
+-void
++STATIC void
+ xlog_state_put_ticket(xlog_t *log,
+ xlog_ticket_t *tic)
+ {
+- unsigned long s;
+-
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+ xlog_ticket_put(log, tic);
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ } /* xlog_state_put_ticket */
+
+ /*
+@@ -2819,19 +2804,18 @@
+ *
+ *
+ */
+-int
++STATIC int
+ xlog_state_release_iclog(xlog_t *log,
+ xlog_in_core_t *iclog)
+ {
+- SPLDECL(s);
+ int sync = 0; /* do we sync? */
+
+ xlog_assign_tail_lsn(log->l_mp);
+
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+
+ if (iclog->ic_state & XLOG_STATE_IOERROR) {
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ return XFS_ERROR(EIO);
+ }
+
+@@ -2843,12 +2827,12 @@
+ iclog->ic_state == XLOG_STATE_WANT_SYNC) {
+ sync++;
+ iclog->ic_state = XLOG_STATE_SYNCING;
+- INT_SET(iclog->ic_header.h_tail_lsn, ARCH_CONVERT, log->l_tail_lsn);
++ iclog->ic_header.h_tail_lsn = cpu_to_be64(log->l_tail_lsn);
+ xlog_verify_tail_lsn(log, iclog, log->l_tail_lsn);
+ /* cycle incremented when incrementing curr_block */
+ }
+
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+
+ /*
+ * We let the log lock go, so it's possible that we hit a log I/O
+@@ -2860,6 +2844,7 @@
+ if (sync) {
+ return xlog_sync(log, iclog);
+ }
++
+ return 0;
+
+ } /* xlog_state_release_iclog */
+@@ -2881,7 +2866,7 @@
+ if (!eventual_size)
+ eventual_size = iclog->ic_offset;
+ iclog->ic_state = XLOG_STATE_WANT_SYNC;
+- INT_SET(iclog->ic_header.h_prev_block, ARCH_CONVERT, log->l_prev_block);
++ iclog->ic_header.h_prev_block = cpu_to_be32(log->l_prev_block);
+ log->l_prev_block = log->l_curr_block;
+ log->l_prev_cycle = log->l_curr_cycle;
+
+@@ -2939,13 +2924,12 @@
+ {
+ xlog_in_core_t *iclog;
+ xfs_lsn_t lsn;
+- SPLDECL(s);
+
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+
+ iclog = log->l_iclog;
+ if (iclog->ic_state & XLOG_STATE_IOERROR) {
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ return XFS_ERROR(EIO);
+ }
+
+@@ -2978,15 +2962,15 @@
+ * the previous sync.
+ */
+ iclog->ic_refcnt++;
+- lsn = INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT);
++ lsn = be64_to_cpu(iclog->ic_header.h_lsn);
+ xlog_state_switch_iclogs(log, iclog, 0);
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+
+ if (xlog_state_release_iclog(log, iclog))
+ return XFS_ERROR(EIO);
+ *log_flushed = 1;
+- s = LOG_LOCK(log);
+- if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) == lsn &&
++ spin_lock(&log->l_icloglock);
++ if (be64_to_cpu(iclog->ic_header.h_lsn) == lsn &&
+ iclog->ic_state != XLOG_STATE_DIRTY)
+ goto maybe_sleep;
+ else
+@@ -3016,7 +3000,7 @@
+ * sleep was disturbed by a bad news.
+ */
+ if (iclog->ic_state & XLOG_STATE_IOERROR) {
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ return XFS_ERROR(EIO);
+ }
+ XFS_STATS_INC(xs_log_force_sleep);
+@@ -3033,7 +3017,7 @@
+ } else {
+
+ no_sleep:
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ }
+ return 0;
+ } /* xlog_state_sync_all */
+@@ -3051,7 +3035,7 @@
+ * If filesystem activity goes to zero, the iclog will get flushed only by
+ * bdflush().
+ */
+-int
++STATIC int
+ xlog_state_sync(xlog_t *log,
+ xfs_lsn_t lsn,
+ uint flags,
+@@ -3059,26 +3043,24 @@
+ {
+ xlog_in_core_t *iclog;
+ int already_slept = 0;
+- SPLDECL(s);
+-
+
+ try_again:
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+ iclog = log->l_iclog;
+
+ if (iclog->ic_state & XLOG_STATE_IOERROR) {
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ return XFS_ERROR(EIO);
+ }
+
+ do {
+- if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) != lsn) {
+- iclog = iclog->ic_next;
+- continue;
++ if (be64_to_cpu(iclog->ic_header.h_lsn) != lsn) {
++ iclog = iclog->ic_next;
++ continue;
+ }
+
+ if (iclog->ic_state == XLOG_STATE_DIRTY) {
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ return 0;
+ }
+
+@@ -3113,11 +3095,11 @@
+ } else {
+ iclog->ic_refcnt++;
+ xlog_state_switch_iclogs(log, iclog, 0);
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ if (xlog_state_release_iclog(log, iclog))
+ return XFS_ERROR(EIO);
+ *log_flushed = 1;
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+ }
+ }
+
+@@ -3129,7 +3111,7 @@
+ * gotten a log write error.
+ */
+ if (iclog->ic_state & XLOG_STATE_IOERROR) {
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ return XFS_ERROR(EIO);
+ }
+ XFS_STATS_INC(xs_log_force_sleep);
+@@ -3143,13 +3125,13 @@
+ return XFS_ERROR(EIO);
+ *log_flushed = 1;
+ } else { /* just return */
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ }
+ return 0;
+
+ } while (iclog != log->l_iclog);
+
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ return 0;
+ } /* xlog_state_sync */
+
+@@ -3158,12 +3140,10 @@
+ * Called when we want to mark the current iclog as being ready to sync to
+ * disk.
+ */
+-void
++STATIC void
+ xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog)
+ {
+- SPLDECL(s);
+-
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+
+ if (iclog->ic_state == XLOG_STATE_ACTIVE) {
+ xlog_state_switch_iclogs(log, iclog, 0);
+@@ -3172,7 +3152,7 @@
+ (XLOG_STATE_WANT_SYNC|XLOG_STATE_IOERROR));
+ }
+
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ } /* xlog_state_want_sync */
+
+
+@@ -3194,7 +3174,6 @@
+ xlog_ticket_t *next;
+ xfs_caddr_t buf;
+ uint i = (NBPP / sizeof(xlog_ticket_t)) - 2;
+- SPLDECL(s);
+
+ /*
+ * The kmem_zalloc may sleep, so we shouldn't be holding the
+@@ -3202,7 +3181,7 @@
+ */
+ buf = (xfs_caddr_t) kmem_zalloc(NBPP, KM_SLEEP);
+
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+
+ /* Attach 1st ticket to Q, so we can keep track of allocated memory */
+ t_list = (xlog_ticket_t *)buf;
+@@ -3231,7 +3210,7 @@
+ }
+ t_list->t_next = NULL;
+ log->l_tail = t_list;
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ } /* xlog_state_ticket_alloc */
+
+
+@@ -3273,7 +3252,7 @@
+ /*
+ * Grab ticket off freelist or allocation some more
+ */
+-xlog_ticket_t *
++STATIC xlog_ticket_t *
+ xlog_ticket_get(xlog_t *log,
+ int unit_bytes,
+ int cnt,
+@@ -3282,15 +3261,14 @@
+ {
+ xlog_ticket_t *tic;
+ uint num_headers;
+- SPLDECL(s);
+
+ alloc:
+ if (log->l_freelist == NULL)
+ xlog_state_ticket_alloc(log); /* potentially sleep */
+
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+ if (log->l_freelist == NULL) {
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ goto alloc;
+ }
+ tic = log->l_freelist;
+@@ -3298,7 +3276,7 @@
+ if (log->l_freelist == NULL)
+ log->l_tail = NULL;
+ log->l_ticket_cnt--;
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+
+ /*
+ * Permanent reservations have up to 'cnt'-1 active log operations
+@@ -3476,7 +3454,7 @@
+ SPLDECL(s);
+
+ /* check validity of iclog pointers */
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+ icptr = log->l_iclog;
+ for (i=0; i < log->l_iclog_bufs; i++) {
+ if (icptr == NULL)
+@@ -3485,21 +3463,21 @@
+ }
+ if (icptr != log->l_iclog)
+ xlog_panic("xlog_verify_iclog: corrupt iclog ring");
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+
+ /* check log magic numbers */
+- ptr = (xfs_caddr_t) &(iclog->ic_header);
+- if (INT_GET(*(uint *)ptr, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM)
++ if (be32_to_cpu(iclog->ic_header.h_magicno) != XLOG_HEADER_MAGIC_NUM)
+ xlog_panic("xlog_verify_iclog: invalid magic num");
+
++ ptr = (xfs_caddr_t) &(iclog->ic_header);
+ for (ptr += BBSIZE; ptr < ((xfs_caddr_t)&(iclog->ic_header))+count;
+ ptr += BBSIZE) {
+- if (INT_GET(*(uint *)ptr, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM)
++ if (be32_to_cpu(*(__be32 *)ptr) == XLOG_HEADER_MAGIC_NUM)
+ xlog_panic("xlog_verify_iclog: unexpected magic num");
+ }
+
+ /* check fields */
+- len = INT_GET(iclog->ic_header.h_num_logops, ARCH_CONVERT);
++ len = be32_to_cpu(iclog->ic_header.h_num_logops);
+ ptr = iclog->ic_datap;
+ base_ptr = ptr;
+ ophead = (xlog_op_header_t *)ptr;
+@@ -3517,9 +3495,11 @@
+ if (idx >= (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) {
+ j = idx / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+ k = idx % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+- clientid = GET_CLIENT_ID(xhdr[j].hic_xheader.xh_cycle_data[k], ARCH_CONVERT);
++ clientid = xlog_get_client_id(
++ xhdr[j].hic_xheader.xh_cycle_data[k]);
+ } else {
+- clientid = GET_CLIENT_ID(iclog->ic_header.h_cycle_data[idx], ARCH_CONVERT);
++ clientid = xlog_get_client_id(
++ iclog->ic_header.h_cycle_data[idx]);
+ }
+ }
+ if (clientid != XFS_TRANSACTION && clientid != XFS_LOG)
+@@ -3531,16 +3511,16 @@
+ field_offset = (__psint_t)
+ ((xfs_caddr_t)&(ophead->oh_len) - base_ptr);
+ if (syncing == B_FALSE || (field_offset & 0x1ff)) {
+- op_len = INT_GET(ophead->oh_len, ARCH_CONVERT);
++ op_len = be32_to_cpu(ophead->oh_len);
+ } else {
+ idx = BTOBBT((__psint_t)&ophead->oh_len -
+ (__psint_t)iclog->ic_datap);
+ if (idx >= (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) {
+ j = idx / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+ k = idx % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+- op_len = INT_GET(xhdr[j].hic_xheader.xh_cycle_data[k], ARCH_CONVERT);
++ op_len = be32_to_cpu(xhdr[j].hic_xheader.xh_cycle_data[k]);
+ } else {
+- op_len = INT_GET(iclog->ic_header.h_cycle_data[idx], ARCH_CONVERT);
++ op_len = be32_to_cpu(iclog->ic_header.h_cycle_data[idx]);
+ }
+ }
+ ptr += sizeof(xlog_op_header_t) + op_len;
+@@ -3597,8 +3577,6 @@
+ xlog_t *log;
+ int retval;
+ int dummy;
+- SPLDECL(s);
+- SPLDECL(s2);
+
+ log = mp->m_log;
+
+@@ -3627,8 +3605,8 @@
+ * before we mark the filesystem SHUTDOWN and wake
+ * everybody up to tell the bad news.
+ */
+- s = GRANT_LOCK(log);
+- s2 = LOG_LOCK(log);
++ spin_lock(&log->l_grant_lock);
++ spin_lock(&log->l_icloglock);
+ mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN;
+ XFS_BUF_DONE(mp->m_sb_bp);
+ /*
+@@ -3644,7 +3622,7 @@
+ */
+ if (logerror)
+ retval = xlog_state_ioerror(log);
+- LOG_UNLOCK(log, s2);
++ spin_unlock(&log->l_icloglock);
+
+ /*
+ * We don't want anybody waiting for log reservations
+@@ -3667,7 +3645,7 @@
+ tic = tic->t_next;
+ } while (tic != log->l_write_headq);
+ }
+- GRANT_UNLOCK(log, s);
++ spin_unlock(&log->l_grant_lock);
+
+ if (! (log->l_iclog->ic_state & XLOG_STATE_IOERROR)) {
+ ASSERT(!logerror);
+@@ -3676,9 +3654,9 @@
+ * log down completely.
+ */
+ xlog_state_sync_all(log, XFS_LOG_FORCE|XFS_LOG_SYNC, &dummy);
+- s2 = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+ retval = xlog_state_ioerror(log);
+- LOG_UNLOCK(log, s2);
++ spin_unlock(&log->l_icloglock);
+ }
+ /*
+ * Wake up everybody waiting on xfs_log_force.
+@@ -3691,13 +3669,13 @@
+ {
+ xlog_in_core_t *iclog;
+
+- s = LOG_LOCK(log);
++ spin_lock(&log->l_icloglock);
+ iclog = log->l_iclog;
+ do {
+ ASSERT(iclog->ic_callback == 0);
+ iclog = iclog->ic_next;
+ } while (iclog != log->l_iclog);
+- LOG_UNLOCK(log, s);
++ spin_unlock(&log->l_icloglock);
+ }
+ #endif
+ /* return non-zero if log IOERROR transition had already happened */
+diff -Nurd linux-2.6.24/fs/xfs/xfs_log.h linux-2.6.24-oxe810/fs/xfs/xfs_log.h
+--- linux-2.6.24/fs/xfs/xfs_log.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_log.h 2008-06-11 17:46:48.000000000 +0200
+@@ -23,7 +23,7 @@
+ #define CYCLE_LSN(lsn) ((uint)((lsn)>>32))
+ #define BLOCK_LSN(lsn) ((uint)(lsn))
+ /* this is used in a spot where we might otherwise double-endian-flip */
+-#define CYCLE_LSN_DISK(lsn) (((uint *)&(lsn))[0])
++#define CYCLE_LSN_DISK(lsn) (((__be32 *)&(lsn))[0])
+
+ #ifdef __KERNEL__
+ /*
+diff -Nurd linux-2.6.24/fs/xfs/xfs_log_priv.h linux-2.6.24-oxe810/fs/xfs/xfs_log_priv.h
+--- linux-2.6.24/fs/xfs/xfs_log_priv.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_log_priv.h 2008-06-11 17:46:48.000000000 +0200
+@@ -55,29 +55,19 @@
+ BTOBB(XLOG_MAX_ICLOGS << (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? \
+ XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT))
+
+-/*
+- * set lsns
+- */
+-
+-#define ASSIGN_ANY_LSN_HOST(lsn,cycle,block) \
+- { \
+- (lsn) = ((xfs_lsn_t)(cycle)<<32)|(block); \
+- }
+-#define ASSIGN_ANY_LSN_DISK(lsn,cycle,block) \
+- { \
+- INT_SET(((uint *)&(lsn))[0], ARCH_CONVERT, (cycle)); \
+- INT_SET(((uint *)&(lsn))[1], ARCH_CONVERT, (block)); \
+- }
+-#define ASSIGN_LSN(lsn,log) \
+- ASSIGN_ANY_LSN_DISK(lsn,(log)->l_curr_cycle,(log)->l_curr_block);
+
+-#define XLOG_SET(f,b) (((f) & (b)) == (b))
++static inline xfs_lsn_t xlog_assign_lsn(uint cycle, uint block)
++{
++ return ((xfs_lsn_t)cycle << 32) | block;
++}
+
+-#define GET_CYCLE(ptr, arch) \
+- (INT_GET(*(uint *)(ptr), arch) == XLOG_HEADER_MAGIC_NUM ? \
+- INT_GET(*((uint *)(ptr)+1), arch) : \
+- INT_GET(*(uint *)(ptr), arch) \
+- )
++static inline uint xlog_get_cycle(char *ptr)
++{
++ if (be32_to_cpu(*(__be32 *)ptr) == XLOG_HEADER_MAGIC_NUM)
++ return be32_to_cpu(*((__be32 *)ptr + 1));
++ else
++ return be32_to_cpu(*(__be32 *)ptr);
++}
+
+ #define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1)
+
+@@ -97,18 +87,15 @@
+ * this has endian issues, of course.
+ */
+
+-#ifndef XFS_NATIVE_HOST
+-#define GET_CLIENT_ID(i,arch) \
+- ((i) & 0xff)
+-#else
+-#define GET_CLIENT_ID(i,arch) \
+- ((i) >> 24)
+-#endif
++static inline uint xlog_get_client_id(__be32 i)
++{
++ return be32_to_cpu(i) >> 24;
++}
+
+-#define GRANT_LOCK(log) mutex_spinlock(&(log)->l_grant_lock)
+-#define GRANT_UNLOCK(log, s) mutex_spinunlock(&(log)->l_grant_lock, s)
+-#define LOG_LOCK(log) mutex_spinlock(&(log)->l_icloglock)
+-#define LOG_UNLOCK(log, s) mutex_spinunlock(&(log)->l_icloglock, s)
++//#define GRANT_LOCK(log) mutex_spinlock(&(log)->l_grant_lock)
++//#define GRANT_UNLOCK(log, s) mutex_spinunlock(&(log)->l_grant_lock, s)
++//#define LOG_LOCK(log) mutex_spinlock(&(log)->l_icloglock)
++//#define LOG_UNLOCK(log, s) mutex_spinunlock(&(log)->l_icloglock, s)
+
+ #define xlog_panic(args...) cmn_err(CE_PANIC, ## args)
+ #define xlog_exit(args...) cmn_err(CE_PANIC, ## args)
+@@ -285,11 +272,11 @@
+
+
+ typedef struct xlog_op_header {
+- xlog_tid_t oh_tid; /* transaction id of operation : 4 b */
+- int oh_len; /* bytes in data region : 4 b */
+- __uint8_t oh_clientid; /* who sent me this : 1 b */
+- __uint8_t oh_flags; /* : 1 b */
+- ushort oh_res2; /* 32 bit align : 2 b */
++ __be32 oh_tid; /* transaction id of operation : 4 b */
++ __be32 oh_len; /* bytes in data region : 4 b */
++ __u8 oh_clientid; /* who sent me this : 1 b */
++ __u8 oh_flags; /* : 1 b */
++ __u16 oh_res2; /* 32 bit align : 2 b */
+ } xlog_op_header_t;
+
+
+@@ -307,25 +294,25 @@
+ #endif
+
+ typedef struct xlog_rec_header {
+- uint h_magicno; /* log record (LR) identifier : 4 */
+- uint h_cycle; /* write cycle of log : 4 */
+- int h_version; /* LR version : 4 */
+- int h_len; /* len in bytes; should be 64-bit aligned: 4 */
+- xfs_lsn_t h_lsn; /* lsn of this LR : 8 */
+- xfs_lsn_t h_tail_lsn; /* lsn of 1st LR w/ buffers not committed: 8 */
+- uint h_chksum; /* may not be used; non-zero if used : 4 */
+- int h_prev_block; /* block number to previous LR : 4 */
+- int h_num_logops; /* number of log operations in this LR : 4 */
+- uint h_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE];
++ __be32 h_magicno; /* log record (LR) identifier : 4 */
++ __be32 h_cycle; /* write cycle of log : 4 */
++ __be32 h_version; /* LR version : 4 */
++ __be32 h_len; /* len in bytes; should be 64-bit aligned: 4 */
++ __be64 h_lsn; /* lsn of this LR : 8 */
++ __be64 h_tail_lsn; /* lsn of 1st LR w/ buffers not committed: 8 */
++ __be32 h_chksum; /* may not be used; non-zero if used : 4 */
++ __be32 h_prev_block; /* block number to previous LR : 4 */
++ __be32 h_num_logops; /* number of log operations in this LR : 4 */
++ __be32 h_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE];
+ /* new fields */
+- int h_fmt; /* format of log record : 4 */
+- uuid_t h_fs_uuid; /* uuid of FS : 16 */
+- int h_size; /* iclog size : 4 */
++ __be32 h_fmt; /* format of log record : 4 */
++ uuid_t h_fs_uuid; /* uuid of FS : 16 */
++ __be32 h_size; /* iclog size : 4 */
+ } xlog_rec_header_t;
+
+ typedef struct xlog_rec_ext_header {
+- uint xh_cycle; /* write cycle of log : 4 */
+- uint xh_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /* : 256 */
++ __be32 xh_cycle; /* write cycle of log : 4 */
++ __be32 xh_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; /* : 256 */
+ } xlog_rec_ext_header_t;
+
+ #ifdef __KERNEL__
+@@ -464,12 +451,12 @@
+
+ #define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR)
+
+-
+ /* common routines */
+ extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp);
+ extern int xlog_find_tail(xlog_t *log,
+ xfs_daddr_t *head_blk,
+ xfs_daddr_t *tail_blk);
++
+ extern int xlog_recover(xlog_t *log);
+ extern int xlog_recover_finish(xlog_t *log, int mfsi_flags);
+ extern void xlog_pack_data(xlog_t *log, xlog_in_core_t *iclog, int);
+diff -Nurd linux-2.6.24/fs/xfs/xfs_log_recover.c linux-2.6.24-oxe810/fs/xfs/xfs_log_recover.c
+--- linux-2.6.24/fs/xfs/xfs_log_recover.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_log_recover.c 2008-06-11 17:46:48.000000000 +0200
+@@ -198,7 +198,7 @@
+ cmn_err(CE_DEBUG, " log : uuid = ");
+ for (b = 0; b < 16; b++)
+ cmn_err(CE_DEBUG, "%02x",((uchar_t *)&head->h_fs_uuid)[b]);
+- cmn_err(CE_DEBUG, ", fmt = %d\n", INT_GET(head->h_fmt, ARCH_CONVERT));
++ cmn_err(CE_DEBUG, ", fmt = %d\n", be32_to_cpu(head->h_fmt));
+ }
+ #else
+ #define xlog_header_check_dump(mp, head)
+@@ -212,14 +212,14 @@
+ xfs_mount_t *mp,
+ xlog_rec_header_t *head)
+ {
+- ASSERT(INT_GET(head->h_magicno, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM);
++ ASSERT(be32_to_cpu(head->h_magicno) == XLOG_HEADER_MAGIC_NUM);
+
+ /*
+ * IRIX doesn't write the h_fmt field and leaves it zeroed
+ * (XLOG_FMT_UNKNOWN). This stops us from trying to recover
+ * a dirty log created in IRIX.
+ */
+- if (unlikely(INT_GET(head->h_fmt, ARCH_CONVERT) != XLOG_FMT)) {
++ if (unlikely(be32_to_cpu(head->h_fmt) != XLOG_FMT)) {
+ xlog_warn(
+ "XFS: dirty log written in incompatible format - can't recover");
+ xlog_header_check_dump(mp, head);
+@@ -245,7 +245,7 @@
+ xfs_mount_t *mp,
+ xlog_rec_header_t *head)
+ {
+- ASSERT(INT_GET(head->h_magicno, ARCH_CONVERT) == XLOG_HEADER_MAGIC_NUM);
++ ASSERT(be32_to_cpu(head->h_magicno) == XLOG_HEADER_MAGIC_NUM);
+
+ if (uuid_is_nil(&head->h_fs_uuid)) {
+ /*
+@@ -311,7 +311,7 @@
+ if ((error = xlog_bread(log, mid_blk, 1, bp)))
+ return error;
+ offset = xlog_align(log, mid_blk, 1, bp);
+- mid_cycle = GET_CYCLE(offset, ARCH_CONVERT);
++ mid_cycle = xlog_get_cycle(offset);
+ if (mid_cycle == cycle) {
+ *last_blk = mid_blk;
+ /* last_half_cycle == mid_cycle */
+@@ -371,7 +371,7 @@
+
+ buf = xlog_align(log, i, bcount, bp);
+ for (j = 0; j < bcount; j++) {
+- cycle = GET_CYCLE(buf, ARCH_CONVERT);
++ cycle = xlog_get_cycle(buf);
+ if (cycle == stop_on_cycle_no) {
+ *new_blk = i+j;
+ goto out;
+@@ -447,8 +447,7 @@
+
+ head = (xlog_rec_header_t *)offset;
+
+- if (XLOG_HEADER_MAGIC_NUM ==
+- INT_GET(head->h_magicno, ARCH_CONVERT))
++ if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(head->h_magicno))
+ break;
+
+ if (!smallmem)
+@@ -480,7 +479,7 @@
+ * record do we update last_blk.
+ */
+ if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
+- uint h_size = INT_GET(head->h_size, ARCH_CONVERT);
++ uint h_size = be32_to_cpu(head->h_size);
+
+ xhdrs = h_size / XLOG_HEADER_CYCLE_SIZE;
+ if (h_size % XLOG_HEADER_CYCLE_SIZE)
+@@ -489,8 +488,8 @@
+ xhdrs = 1;
+ }
+
+- if (*last_blk - i + extra_bblks
+- != BTOBB(INT_GET(head->h_len, ARCH_CONVERT)) + xhdrs)
++ if (*last_blk - i + extra_bblks !=
++ BTOBB(be32_to_cpu(head->h_len)) + xhdrs)
+ *last_blk = i;
+
+ out:
+@@ -550,13 +549,13 @@
+ if ((error = xlog_bread(log, 0, 1, bp)))
+ goto bp_err;
+ offset = xlog_align(log, 0, 1, bp);
+- first_half_cycle = GET_CYCLE(offset, ARCH_CONVERT);
++ first_half_cycle = xlog_get_cycle(offset);
+
+ last_blk = head_blk = log_bbnum - 1; /* get cycle # of last block */
+ if ((error = xlog_bread(log, last_blk, 1, bp)))
+ goto bp_err;
+ offset = xlog_align(log, last_blk, 1, bp);
+- last_half_cycle = GET_CYCLE(offset, ARCH_CONVERT);
++ last_half_cycle = xlog_get_cycle(offset);
+ ASSERT(last_half_cycle != 0);
+
+ /*
+@@ -799,21 +798,27 @@
+ * Find previous log record
+ */
+ if ((error = xlog_find_head(log, head_blk)))
++ {
++ xlog_warn("XFS: xlog_find_tail: couldn't find previous log record \n");
+ return error;
++ }
+
+ bp = xlog_get_bp(log, 1);
+ if (!bp)
++ {
++ xlog_warn("XFS: xlog_find_tail: ENOMEM \n");
+ return ENOMEM;
++ }
+ if (*head_blk == 0) { /* special case */
+ if ((error = xlog_bread(log, 0, 1, bp)))
+ goto bread_err;
+ offset = xlog_align(log, 0, 1, bp);
+- if (GET_CYCLE(offset, ARCH_CONVERT) == 0) {
++ if (xlog_get_cycle(offset) == 0) {
+ *tail_blk = 0;
+ /* leave all other log inited values alone */
+ goto exit;
+ }
+- }
++ }
+
+ /*
+ * Search backwards looking for log record header block
+@@ -823,8 +828,7 @@
+ if ((error = xlog_bread(log, i, 1, bp)))
+ goto bread_err;
+ offset = xlog_align(log, i, 1, bp);
+- if (XLOG_HEADER_MAGIC_NUM ==
+- INT_GET(*(uint *)offset, ARCH_CONVERT)) {
++ if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(*(__be32 *)offset)) {
+ found = 1;
+ break;
+ }
+@@ -841,7 +845,7 @@
+ goto bread_err;
+ offset = xlog_align(log, i, 1, bp);
+ if (XLOG_HEADER_MAGIC_NUM ==
+- INT_GET(*(uint*)offset, ARCH_CONVERT)) {
++ be32_to_cpu(*(__be32 *)offset)) {
+ found = 2;
+ break;
+ }
+@@ -855,7 +859,7 @@
+
+ /* find blk_no of tail of log */
+ rhead = (xlog_rec_header_t *)offset;
+- *tail_blk = BLOCK_LSN(INT_GET(rhead->h_tail_lsn, ARCH_CONVERT));
++ *tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn));
+
+ /*
+ * Reset log values according to the state of the log when we
+@@ -869,11 +873,11 @@
+ */
+ log->l_prev_block = i;
+ log->l_curr_block = (int)*head_blk;
+- log->l_curr_cycle = INT_GET(rhead->h_cycle, ARCH_CONVERT);
++ log->l_curr_cycle = be32_to_cpu(rhead->h_cycle);
+ if (found == 2)
+ log->l_curr_cycle++;
+- log->l_tail_lsn = INT_GET(rhead->h_tail_lsn, ARCH_CONVERT);
+- log->l_last_sync_lsn = INT_GET(rhead->h_lsn, ARCH_CONVERT);
++ log->l_tail_lsn = be64_to_cpu(rhead->h_tail_lsn);
++ log->l_last_sync_lsn = be64_to_cpu(rhead->h_lsn);
+ log->l_grant_reserve_cycle = log->l_curr_cycle;
+ log->l_grant_reserve_bytes = BBTOB(log->l_curr_block);
+ log->l_grant_write_cycle = log->l_curr_cycle;
+@@ -891,8 +895,8 @@
+ * unmount record rather than the block after it.
+ */
+ if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
+- int h_size = INT_GET(rhead->h_size, ARCH_CONVERT);
+- int h_version = INT_GET(rhead->h_version, ARCH_CONVERT);
++ int h_size = be32_to_cpu(rhead->h_size);
++ int h_version = be32_to_cpu(rhead->h_version);
+
+ if ((h_version & XLOG_VERSION_2) &&
+ (h_size > XLOG_HEADER_CYCLE_SIZE)) {
+@@ -905,11 +909,12 @@
+ } else {
+ hblks = 1;
+ }
++
+ after_umount_blk = (i + hblks + (int)
+- BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT))) % log->l_logBBsize;
++ BTOBB(be32_to_cpu(rhead->h_len))) % log->l_logBBsize;
+ tail_lsn = log->l_tail_lsn;
+ if (*head_blk == after_umount_blk &&
+- INT_GET(rhead->h_num_logops, ARCH_CONVERT) == 1) {
++ be32_to_cpu(rhead->h_num_logops) == 1) {
+ umount_data_blk = (i + hblks) % log->l_logBBsize;
+ if ((error = xlog_bread(log, umount_data_blk, 1, bp))) {
+ goto bread_err;
+@@ -922,10 +927,12 @@
+ * log records will point recovery to after the
+ * current unmount record.
+ */
+- ASSIGN_ANY_LSN_HOST(log->l_tail_lsn, log->l_curr_cycle,
+- after_umount_blk);
+- ASSIGN_ANY_LSN_HOST(log->l_last_sync_lsn, log->l_curr_cycle,
+- after_umount_blk);
++ log->l_tail_lsn =
++ xlog_assign_lsn(log->l_curr_cycle,
++ after_umount_blk);
++ log->l_last_sync_lsn =
++ xlog_assign_lsn(log->l_curr_cycle,
++ after_umount_blk);
+ *tail_blk = after_umount_blk;
+
+ /*
+@@ -986,7 +993,7 @@
+ * -1 => use *blk_no as the first block of the log
+ * >0 => error has occurred
+ */
+-int
++STATIC int
+ xlog_find_zeroed(
+ xlog_t *log,
+ xfs_daddr_t *blk_no)
+@@ -1007,7 +1014,7 @@
+ if ((error = xlog_bread(log, 0, 1, bp)))
+ goto bp_err;
+ offset = xlog_align(log, 0, 1, bp);
+- first_cycle = GET_CYCLE(offset, ARCH_CONVERT);
++ first_cycle = xlog_get_cycle(offset);
+ if (first_cycle == 0) { /* completely zeroed log */
+ *blk_no = 0;
+ xlog_put_bp(bp);
+@@ -1018,7 +1025,7 @@
+ if ((error = xlog_bread(log, log_bbnum-1, 1, bp)))
+ goto bp_err;
+ offset = xlog_align(log, log_bbnum-1, 1, bp);
+- last_cycle = GET_CYCLE(offset, ARCH_CONVERT);
++ last_cycle = xlog_get_cycle(offset);
+ if (last_cycle != 0) { /* log completely written to */
+ xlog_put_bp(bp);
+ return 0;
+@@ -1098,13 +1105,13 @@
+ xlog_rec_header_t *recp = (xlog_rec_header_t *)buf;
+
+ memset(buf, 0, BBSIZE);
+- INT_SET(recp->h_magicno, ARCH_CONVERT, XLOG_HEADER_MAGIC_NUM);
+- INT_SET(recp->h_cycle, ARCH_CONVERT, cycle);
+- INT_SET(recp->h_version, ARCH_CONVERT,
++ recp->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM);
++ recp->h_cycle = cpu_to_be32(cycle);
++ recp->h_version = cpu_to_be32(
+ XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? 2 : 1);
+- ASSIGN_ANY_LSN_DISK(recp->h_lsn, cycle, block);
+- ASSIGN_ANY_LSN_DISK(recp->h_tail_lsn, tail_cycle, tail_block);
+- INT_SET(recp->h_fmt, ARCH_CONVERT, XLOG_FMT);
++ recp->h_lsn = cpu_to_be64(xlog_assign_lsn(cycle, block));
++ recp->h_tail_lsn = cpu_to_be64(xlog_assign_lsn(tail_cycle, tail_block));
++ recp->h_fmt = cpu_to_be32(XLOG_FMT);
+ memcpy(&recp->h_fs_uuid, &log->l_mp->m_sb.sb_uuid, sizeof(uuid_t));
+ }
+
+@@ -1214,6 +1221,11 @@
+ head_cycle = log->l_curr_cycle;
+ head_block = log->l_curr_block;
+
++ /* Temp fix - to ensure that the tail cycle and tail blocks both are never 0
++ */
++ if ((tail_cycle == 0) && (tail_block == 0))
++ tail_cycle = head_cycle;
++
+ /*
+ * Figure out the distance between the new head of the log
+ * and the tail. We want to write over any blocks beyond the
+@@ -1231,6 +1243,8 @@
+ if (unlikely(head_block < tail_block || head_block >= log->l_logBBsize)) {
+ XFS_ERROR_REPORT("xlog_clear_stale_blocks(1)",
+ XFS_ERRLEVEL_LOW, log->l_mp);
++ printk(KERN_INFO "XFS: head_blk %d tail_blk %d head_cycle %d tail_cycle %d \n",\
++ head_block, tail_block, head_cycle, tail_cycle);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+ tail_distance = tail_block + (log->l_logBBsize - head_block);
+@@ -1243,6 +1257,8 @@
+ if (unlikely(head_block >= tail_block || head_cycle != (tail_cycle + 1))){
+ XFS_ERROR_REPORT("xlog_clear_stale_blocks(2)",
+ XFS_ERRLEVEL_LOW, log->l_mp);
++ printk(KERN_INFO "XFS: head_blk %d tail_blk %d head_cycle %d tail_cycle %d \n",\
++ head_block, tail_block, head_cycle, tail_cycle);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+ tail_distance = tail_block - head_block;
+@@ -2211,7 +2227,7 @@
+ * overlap with future reads of those inodes.
+ */
+ if (XFS_DINODE_MAGIC ==
+- INT_GET(*((__uint16_t *)(xfs_buf_offset(bp, 0))), ARCH_CONVERT) &&
++ be16_to_cpu(*((__be16 *)xfs_buf_offset(bp, 0))) &&
+ (XFS_BUF_COUNT(bp) != MAX(log->l_mp->m_sb.sb_blocksize,
+ (__uint32_t)XFS_INODE_CLUSTER_SIZE(log->l_mp)))) {
+ XFS_BUF_STALE(bp);
+@@ -2581,8 +2597,7 @@
+ /*
+ * This type of quotas was turned off, so ignore this record.
+ */
+- type = INT_GET(recddq->d_flags, ARCH_CONVERT) &
+- (XFS_DQ_USER | XFS_DQ_PROJ | XFS_DQ_GROUP);
++ type = recddq->d_flags & (XFS_DQ_USER | XFS_DQ_PROJ | XFS_DQ_GROUP);
+ ASSERT(type);
+ if (log->l_quotaoffs_flag & type)
+ return (0);
+@@ -2736,21 +2751,13 @@
+ * AIL lock.
+ */
+ xfs_trans_delete_ail(mp, lip, s);
+- break;
++ xfs_efi_item_free(efip);
++ return;
+ }
+ }
+ lip = xfs_trans_next_ail(mp, lip, &gen, NULL);
+ }
+-
+- /*
+- * If we found it, then free it up. If it wasn't there, it
+- * must have been overwritten in the log. Oh well.
+- */
+- if (lip != NULL) {
+- xfs_efi_item_free(efip);
+- } else {
+- AIL_UNLOCK(mp, s);
+- }
++ AIL_UNLOCK(mp, s);
+ }
+
+ /*
+@@ -2897,8 +2904,8 @@
+ unsigned long hash;
+ uint flags;
+
+- lp = dp + INT_GET(rhead->h_len, ARCH_CONVERT);
+- num_logops = INT_GET(rhead->h_num_logops, ARCH_CONVERT);
++ lp = dp + be32_to_cpu(rhead->h_len);
++ num_logops = be32_to_cpu(rhead->h_num_logops);
+
+ /* check the log format matches our own - else we can't recover */
+ if (xlog_header_check_recover(log->l_mp, rhead))
+@@ -2912,18 +2919,28 @@
+ ohead->oh_clientid != XFS_LOG) {
+ xlog_warn(
+ "XFS: xlog_recover_process_data: bad clientid");
++ printk(KERN_INFO "Ticket ID - %d\n", ohead->oh_tid);
++ printk(KERN_INFO "Bytes in Data Region - %d\n", ohead->oh_len);
++ printk(KERN_INFO "Client ID - %d\n", ohead->oh_clientid);
++ printk(KERN_INFO "Flags - %d\n", ohead->oh_flags);
++ printk(KERN_INFO "Unused - %d\n", ohead->oh_res2);
+ ASSERT(0);
+ return (XFS_ERROR(EIO));
+ }
+- tid = INT_GET(ohead->oh_tid, ARCH_CONVERT);
++ tid = be32_to_cpu(ohead->oh_tid);
+ hash = XLOG_RHASH(tid);
+ trans = xlog_recover_find_tid(rhash[hash], tid);
+ if (trans == NULL) { /* not found; add new tid */
+ if (ohead->oh_flags & XLOG_START_TRANS)
+ xlog_recover_new_tid(&rhash[hash], tid,
+- INT_GET(rhead->h_lsn, ARCH_CONVERT));
++ be64_to_cpu(rhead->h_lsn));
+ } else {
+- ASSERT(dp+INT_GET(ohead->oh_len, ARCH_CONVERT) <= lp);
++ if (dp + be32_to_cpu(ohead->oh_len) > lp) {
++ xlog_warn(
++ "XFS: xlog_recover_process_data: bad length");
++ WARN_ON(1);
++ return (XFS_ERROR(EIO));
++ }
+ flags = ohead->oh_flags & ~XLOG_END_TRANS;
+ if (flags & XLOG_WAS_CONT_TRANS)
+ flags &= ~XLOG_CONTINUE_TRANS;
+@@ -2937,8 +2954,7 @@
+ break;
+ case XLOG_WAS_CONT_TRANS:
+ error = xlog_recover_add_to_cont_trans(trans,
+- dp, INT_GET(ohead->oh_len,
+- ARCH_CONVERT));
++ dp, be32_to_cpu(ohead->oh_len));
+ break;
+ case XLOG_START_TRANS:
+ xlog_warn(
+@@ -2949,8 +2965,7 @@
+ case 0:
+ case XLOG_CONTINUE_TRANS:
+ error = xlog_recover_add_to_trans(trans,
+- dp, INT_GET(ohead->oh_len,
+- ARCH_CONVERT));
++ dp, be32_to_cpu(ohead->oh_len));
+ break;
+ default:
+ xlog_warn(
+@@ -2962,7 +2977,7 @@
+ if (error)
+ return error;
+ }
+- dp += INT_GET(ohead->oh_len, ARCH_CONVERT);
++ dp += be32_to_cpu(ohead->oh_len);
+ num_logops--;
+ }
+ return 0;
+@@ -3315,16 +3330,16 @@
+ int size)
+ {
+ int i;
+- uint *up;
++ __be32 *up;
+ uint chksum = 0;
+
+- up = (uint *)iclog->ic_datap;
++ up = (__be32 *)iclog->ic_datap;
+ /* divide length by 4 to get # words */
+ for (i = 0; i < (size >> 2); i++) {
+- chksum ^= INT_GET(*up, ARCH_CONVERT);
++ chksum ^= be32_to_cpu(*up);
+ up++;
+ }
+- INT_SET(iclog->ic_header.h_chksum, ARCH_CONVERT, chksum);
++ iclog->ic_header.h_chksum = cpu_to_be32(chksum);
+ }
+ #else
+ #define xlog_pack_data_checksum(log, iclog, size)
+@@ -3341,7 +3356,7 @@
+ {
+ int i, j, k;
+ int size = iclog->ic_offset + roundoff;
+- uint cycle_lsn;
++ __be32 cycle_lsn;
+ xfs_caddr_t dp;
+ xlog_in_core_2_t *xhdr;
+
+@@ -3352,8 +3367,8 @@
+ dp = iclog->ic_datap;
+ for (i = 0; i < BTOBB(size) &&
+ i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) {
+- iclog->ic_header.h_cycle_data[i] = *(uint *)dp;
+- *(uint *)dp = cycle_lsn;
++ iclog->ic_header.h_cycle_data[i] = *(__be32 *)dp;
++ *(__be32 *)dp = cycle_lsn;
+ dp += BBSIZE;
+ }
+
+@@ -3362,8 +3377,8 @@
+ for ( ; i < BTOBB(size); i++) {
+ j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+ k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+- xhdr[j].hic_xheader.xh_cycle_data[k] = *(uint *)dp;
+- *(uint *)dp = cycle_lsn;
++ xhdr[j].hic_xheader.xh_cycle_data[k] = *(__be32 *)dp;
++ *(__be32 *)dp = cycle_lsn;
+ dp += BBSIZE;
+ }
+
+@@ -3380,21 +3395,21 @@
+ xfs_caddr_t dp,
+ xlog_t *log)
+ {
+- uint *up = (uint *)dp;
++ __be32 *up = (__be32 *)dp;
+ uint chksum = 0;
+ int i;
+
+ /* divide length by 4 to get # words */
+- for (i=0; i < INT_GET(rhead->h_len, ARCH_CONVERT) >> 2; i++) {
+- chksum ^= INT_GET(*up, ARCH_CONVERT);
++ for (i=0; i < be32_to_cpu(rhead->h_len) >> 2; i++) {
++ chksum ^= be32_to_cpu(*up);
+ up++;
+ }
+- if (chksum != INT_GET(rhead->h_chksum, ARCH_CONVERT)) {
++ if (chksum != be32_to_cpu(rhead->h_chksum)) {
+ if (rhead->h_chksum ||
+ ((log->l_flags & XLOG_CHKSUM_MISMATCH) == 0)) {
+ cmn_err(CE_DEBUG,
+ "XFS: LogR chksum mismatch: was (0x%x) is (0x%x)\n",
+- INT_GET(rhead->h_chksum, ARCH_CONVERT), chksum);
++ be32_to_cpu(rhead->h_chksum), chksum);
+ cmn_err(CE_DEBUG,
+ "XFS: Disregard message if filesystem was created with non-DEBUG kernel");
+ if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
+@@ -3418,18 +3433,18 @@
+ int i, j, k;
+ xlog_in_core_2_t *xhdr;
+
+- for (i = 0; i < BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)) &&
++ for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) &&
+ i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) {
+- *(uint *)dp = *(uint *)&rhead->h_cycle_data[i];
++ *(__be32 *)dp = *(__be32 *)&rhead->h_cycle_data[i];
+ dp += BBSIZE;
+ }
+
+ if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
+ xhdr = (xlog_in_core_2_t *)rhead;
+- for ( ; i < BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); i++) {
++ for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) {
+ j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+ k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
+- *(uint *)dp = xhdr[j].hic_xheader.xh_cycle_data[k];
++ *(__be32 *)dp = xhdr[j].hic_xheader.xh_cycle_data[k];
+ dp += BBSIZE;
+ }
+ }
+@@ -3445,24 +3460,21 @@
+ {
+ int hlen;
+
+- if (unlikely(
+- (INT_GET(rhead->h_magicno, ARCH_CONVERT) !=
+- XLOG_HEADER_MAGIC_NUM))) {
++ if (unlikely(be32_to_cpu(rhead->h_magicno) != XLOG_HEADER_MAGIC_NUM)) {
+ XFS_ERROR_REPORT("xlog_valid_rec_header(1)",
+ XFS_ERRLEVEL_LOW, log->l_mp);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+ if (unlikely(
+ (!rhead->h_version ||
+- (INT_GET(rhead->h_version, ARCH_CONVERT) &
+- (~XLOG_VERSION_OKBITS)) != 0))) {
++ (be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS))))) {
+ xlog_warn("XFS: %s: unrecognised log version (%d).",
+- __FUNCTION__, INT_GET(rhead->h_version, ARCH_CONVERT));
++ __FUNCTION__, be32_to_cpu(rhead->h_version));
+ return XFS_ERROR(EIO);
+ }
+
+ /* LR body must have data or it wouldn't have been written */
+- hlen = INT_GET(rhead->h_len, ARCH_CONVERT);
++ hlen = be32_to_cpu(rhead->h_len);
+ if (unlikely( hlen <= 0 || hlen > INT_MAX )) {
+ XFS_ERROR_REPORT("xlog_valid_rec_header(2)",
+ XFS_ERRLEVEL_LOW, log->l_mp);
+@@ -3522,9 +3534,8 @@
+ error = xlog_valid_rec_header(log, rhead, tail_blk);
+ if (error)
+ goto bread_err1;
+- h_size = INT_GET(rhead->h_size, ARCH_CONVERT);
+- if ((INT_GET(rhead->h_version, ARCH_CONVERT)
+- & XLOG_VERSION_2) &&
++ h_size = be32_to_cpu(rhead->h_size);
++ if ((be32_to_cpu(rhead->h_version) & XLOG_VERSION_2) &&
+ (h_size > XLOG_HEADER_CYCLE_SIZE)) {
+ hblks = h_size / XLOG_HEADER_CYCLE_SIZE;
+ if (h_size % XLOG_HEADER_CYCLE_SIZE)
+@@ -3561,7 +3572,7 @@
+ goto bread_err2;
+
+ /* blocks in data section */
+- bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT));
++ bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
+ error = xlog_bread(log, blk_no + hblks, bblks, dbp);
+ if (error)
+ goto bread_err2;
+@@ -3636,7 +3647,7 @@
+ if (error)
+ goto bread_err2;
+
+- bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT));
++ bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
+ blk_no += hblks;
+
+ /* Read in data for log record */
+@@ -3707,7 +3718,7 @@
+ error = xlog_valid_rec_header(log, rhead, blk_no);
+ if (error)
+ goto bread_err2;
+- bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT));
++ bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
+ if ((error = xlog_bread(log, blk_no+hblks, bblks, dbp)))
+ goto bread_err2;
+ offset = xlog_align(log, blk_no+hblks, bblks, dbp);
+@@ -3878,7 +3889,12 @@
+
+ /* find the tail of the log */
+ if ((error = xlog_find_tail(log, &head_blk, &tail_blk)))
++ {
++ cmn_err(CE_NOTE, "Log head - 0x%llx Log Tail - 0x%llx \n",\
++ (unsigned long long)head_blk, \
++ (unsigned long long)tail_blk);
+ return error;
++ }
+
+ if (tail_blk != head_blk) {
+ /* There used to be a comment here:
+diff -Nurd linux-2.6.24/fs/xfs/xfs_trans.c linux-2.6.24-oxe810/fs/xfs/xfs_trans.c
+--- linux-2.6.24/fs/xfs/xfs_trans.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_trans.c 2008-06-11 17:46:48.000000000 +0200
+@@ -567,26 +567,26 @@
+ */
+ if (!xfs_sb_version_haslazysbcount(&(tp->t_mountp->m_sb))) {
+ if (tp->t_icount_delta)
+- be64_add(&sbp->sb_icount, tp->t_icount_delta);
++ be64_add_cpu(&sbp->sb_icount, tp->t_icount_delta);
+ if (tp->t_ifree_delta)
+- be64_add(&sbp->sb_ifree, tp->t_ifree_delta);
++ be64_add_cpu(&sbp->sb_ifree, tp->t_ifree_delta);
+ if (tp->t_fdblocks_delta)
+- be64_add(&sbp->sb_fdblocks, tp->t_fdblocks_delta);
++ be64_add_cpu(&sbp->sb_fdblocks, tp->t_fdblocks_delta);
+ if (tp->t_res_fdblocks_delta)
+- be64_add(&sbp->sb_fdblocks, tp->t_res_fdblocks_delta);
++ be64_add_cpu(&sbp->sb_fdblocks, tp->t_res_fdblocks_delta);
+ }
+
+ if (tp->t_frextents_delta)
+- be64_add(&sbp->sb_frextents, tp->t_frextents_delta);
++ be64_add_cpu(&sbp->sb_frextents, tp->t_frextents_delta);
+ if (tp->t_res_frextents_delta)
+- be64_add(&sbp->sb_frextents, tp->t_res_frextents_delta);
++ be64_add_cpu(&sbp->sb_frextents, tp->t_res_frextents_delta);
+
+ if (tp->t_dblocks_delta) {
+- be64_add(&sbp->sb_dblocks, tp->t_dblocks_delta);
++ be64_add_cpu(&sbp->sb_dblocks, tp->t_dblocks_delta);
+ whole = 1;
+ }
+ if (tp->t_agcount_delta) {
+- be32_add(&sbp->sb_agcount, tp->t_agcount_delta);
++ be32_add_cpu(&sbp->sb_agcount, tp->t_agcount_delta);
+ whole = 1;
+ }
+ if (tp->t_imaxpct_delta) {
+@@ -594,19 +594,19 @@
+ whole = 1;
+ }
+ if (tp->t_rextsize_delta) {
+- be32_add(&sbp->sb_rextsize, tp->t_rextsize_delta);
++ be32_add_cpu(&sbp->sb_rextsize, tp->t_rextsize_delta);
+ whole = 1;
+ }
+ if (tp->t_rbmblocks_delta) {
+- be32_add(&sbp->sb_rbmblocks, tp->t_rbmblocks_delta);
++ be32_add_cpu(&sbp->sb_rbmblocks, tp->t_rbmblocks_delta);
+ whole = 1;
+ }
+ if (tp->t_rblocks_delta) {
+- be64_add(&sbp->sb_rblocks, tp->t_rblocks_delta);
++ be64_add_cpu(&sbp->sb_rblocks, tp->t_rblocks_delta);
+ whole = 1;
+ }
+ if (tp->t_rextents_delta) {
+- be64_add(&sbp->sb_rextents, tp->t_rextents_delta);
++ be64_add_cpu(&sbp->sb_rextents, tp->t_rextents_delta);
+ whole = 1;
+ }
+ if (tp->t_rextslog_delta) {
+diff -Nurd linux-2.6.24/fs/xfs/xfs_vnodeops.c linux-2.6.24-oxe810/fs/xfs/xfs_vnodeops.c
+--- linux-2.6.24/fs/xfs/xfs_vnodeops.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/fs/xfs/xfs_vnodeops.c 2008-06-11 17:46:48.000000000 +0200
+@@ -3558,11 +3558,11 @@
+ if (iip && iip->ili_last_lsn) {
+ xlog_t *log = mp->m_log;
+ xfs_lsn_t sync_lsn;
+- int s, log_flags = XFS_LOG_FORCE;
++ int log_flags = XFS_LOG_FORCE;
+
+- s = GRANT_LOCK(log);
++ spin_lock(&log->l_grant_lock);
+ sync_lsn = log->l_last_sync_lsn;
+- GRANT_UNLOCK(log, s);
++ spin_unlock(&log->l_grant_lock);
+
+ if ((XFS_LSN_CMP(iip->ili_last_lsn, sync_lsn) > 0)) {
+ if (flags & FLUSH_SYNC)
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/GPIO_PST_FunctionEnables.inc linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/GPIO_PST_FunctionEnables.inc
+--- linux-2.6.24/include/asm-arm/arch-oxnas/GPIO_PST_FunctionEnables.inc 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/GPIO_PST_FunctionEnables.inc 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,91 @@
++/**
++ * -- GPIO Function Enable Mappings --
++ * Auto Generated by asic/chips/nas/root.user/docs/specs/map2CInlude
++ */
++// GPIO Primary Function Enables
++#define PRIMARY_FUNCTION_ENABLE_SYSPCI_GNT_N0 (0) // As Output
++#define PRIMARY_FUNCTION_ENABLE_SYSPCI_GNT_N1 (1) // As Output
++#define PRIMARY_FUNCTION_ENABLE_SYSPCI_GNT_N2 (2) // As Output
++#define PRIMARY_FUNCTION_ENABLE_SYSPCI_GNT_N3 (3) // As Output
++#define PRIMARY_FUNCTION_ENABLE_SYSPCI_REQ_N0 (4) // As Input
++#define PRIMARY_FUNCTION_ENABLE_SYSPCI_REQ_N1 (5) // As Input
++#define PRIMARY_FUNCTION_ENABLE_SYSPCI_REQ_N2 (6) // As Input
++#define PRIMARY_FUNCTION_ENABLE_SYSPCI_REQ_N3 (7) // As Input
++#define PRIMARY_FUNCTION_ENABLE_PCI_CKO (8) // As Output
++#define PRIMARY_FUNCTION_ENABLE_STATIC_OE_N (12) // As Output
++#define PRIMARY_FUNCTION_ENABLE_STATIC_ADDR21 (13) // As Output
++#define PRIMARY_FUNCTION_ENABLE_STATIC_ADDR20 (14) // As Output
++#define PRIMARY_FUNCTION_ENABLE_STATIC_ADDR19 (15) // As Output
++#define PRIMARY_FUNCTION_ENABLE_STATIC_ADDR18 (16) // As Output
++#define PRIMARY_FUNCTION_ENABLE_STATIC_ADDR17 (17) // As Output
++#define PRIMARY_FUNCTION_ENABLE_STATIC_ADDR16 (18) // As Output
++#define PRIMARY_FUNCTION_ENABLE_STATIC_CS_N0 (19) // As Output
++#define PRIMARY_FUNCTION_ENABLE_STATIC_CS_N1 (20) // As Output
++#define PRIMARY_FUNCTION_ENABLE_STATIC_WE_N0 (21) // As Output
++#define PRIMARY_FUNCTION_ENABLE_STATIC_WE_N1 (22) // As Output
++#define PRIMARY_FUNCTION_ENABLE_USBA_PWRO (23) // As Output
++#define PRIMARY_FUNCTION_ENABLE_USBA_OVERI (24) // As Input
++#define PRIMARY_FUNCTION_ENABLE_USBB_PWRO (25) // As Output
++#define PRIMARY_FUNCTION_ENABLE_USBB_OVERI (26) // As Input
++#define PRIMARY_FUNCTION_ENABLE_USBC_PWRO (27) // As Output
++#define PRIMARY_FUNCTION_ENABLE_USBC_OVERI (28) // As Input
++#define PRIMARY_FUNCTION_ENABLE_FAN_TEMP (29) // Is Bidirectional
++#define PRIMARY_FUNCTION_ENABLE_FAN_TACHO (30) // As Input
++#define PRIMARY_FUNCTION_ENABLE_FAN_PWM0 (31) // As Output
++#define PRIMARY_FUNCTION_ENABLE_FAN_PWM1 (32) // As Output
++#define PRIMARY_FUNCTION_ENABLE_IBIW_D (33) // Is Bidirectional
++#define PRIMARY_FUNCTION_ENABLE_IBIW_LED (34) // As Output
++// GPIO Secondary Function Enables
++#define SECONDARY_FUNCTION_ENABLE_SYSPCI_REQ_OUT_N (0) // As Output
++#define SECONDARY_FUNCTION_ENABLE_SYSPCI_GNT_IN_N (1) // As Input
++#define SECONDARY_FUNCTION_ENABLE_PCI_IDSEL (2) // As Input
++#define SECONDARY_FUNCTION_ENABLE_IRRX_IN (3) // As Input
++#define SECONDARY_FUNCTION_ENABLE_FAN_PWM3 (5) // As Output
++#define SECONDARY_FUNCTION_ENABLE_AUDIO_TX_BITCK (6) // As Input
++#define SECONDARY_FUNCTION_ENABLE_AUDIO_TXLRCK (7) // As Input
++#define SECONDARY_FUNCTION_ENABLE_FAN_PWM2 (8) // As Output
++#define SECONDARY_FUNCTION_ENABLE_USB_CKO (10) // As Output
++#define SECONDARY_FUNCTION_ENABLE_PCI_CCLKRUN_N (12) // Is Bidirectional
++#define SECONDARY_FUNCTION_ENABLE_PCI_LOCK_N (13) // As Input
++#define SECONDARY_FUNCTION_ENABLE_PCI_PERR_N (14) // Is Bidirectional
++#define SECONDARY_FUNCTION_ENABLE_PCI_SERR_N (15) // As Output
++#define SECONDARY_FUNCTION_ENABLE_MEM_DLLTGL (16) // As Output
++#define SECONDARY_FUNCTION_ENABLE_SATA_OBS_RBC0 (17) // As Output
++#define SECONDARY_FUNCTION_ENABLE_PCI_CINT_N (18) // As Output
++#define SECONDARY_FUNCTION_ENABLE_PCI_CSTSCHG_N (19) // As Output
++#define SECONDARY_FUNCTION_ENABLE_PCI_CKO (23) // As Output
++#define SECONDARY_FUNCTION_ENABLE_AUDIO_TXD0 (25) // As Output
++#define SECONDARY_FUNCTION_ENABLE_AUDIO_RXD0 (26) // As Input
++#define SECONDARY_FUNCTION_ENABLE_AUDIO_RXLRCK (27) // As Input
++#define SECONDARY_FUNCTION_ENABLE_AUDIO_RX_BITCK (28) // As Input
++#define SECONDARY_FUNCTION_ENABLE_AUDIO_TXD2 (29) // As Output
++#define SECONDARY_FUNCTION_ENABLE_AUDIO_RXD2 (30) // As Input
++#define SECONDARY_FUNCTION_ENABLE_AUDIO_TXD3 (31) // As Output
++#define SECONDARY_FUNCTION_ENABLE_AUDIO_RXD3 (32) // As Input
++#define SECONDARY_FUNCTION_ENABLE_AUDIO_RXD1 (33) // As Input
++#define SECONDARY_FUNCTION_ENABLE_AUDIO_TXD1 (34) // As Output
++// GPIO Tertiary Function Enables
++#define TERTIARY_FUNCTION_ENABLE_UART3_RI_N (0) // As Input
++#define TERTIARY_FUNCTION_ENABLE_UART3_CD_N (1) // As Input
++#define TERTIARY_FUNCTION_ENABLE_UART3_CTS_N (2) // As Input
++#define TERTIARY_FUNCTION_ENABLE_UART3_DSR_N (3) // As Input
++#define TERTIARY_FUNCTION_ENABLE_UART3_DTR_N (4) // As Output
++#define TERTIARY_FUNCTION_ENABLE_UART3_RTS_N (5) // As Output
++#define TERTIARY_FUNCTION_ENABLE_UART3_SIN (6) // As Input
++#define TERTIARY_FUNCTION_ENABLE_UART3_SOUT (7) // As Output
++#define TERTIARY_FUNCTION_ENABLE_UART2_DSR_N (8) // As Input
++#define TERTIARY_FUNCTION_ENABLE_UART2_RTS_N (9) // As Output
++#define TERTIARY_FUNCTION_ENABLE_UART2_SOUT (20) // As Output
++#define TERTIARY_FUNCTION_ENABLE_UART2_SIN (22) // As Input
++#define TERTIARY_FUNCTION_ENABLE_UART2_RI_N (23) // As Input
++#define TERTIARY_FUNCTION_ENABLE_UART2_CD_N (24) // As Input
++#define TERTIARY_FUNCTION_ENABLE_UART2_DTR_N (25) // As Output
++#define TERTIARY_FUNCTION_ENABLE_UART2_CTS_N (26) // As Input
++#define TERTIARY_FUNCTION_ENABLE_UART1_RTS_N (27) // As Output
++#define TERTIARY_FUNCTION_ENABLE_UART1_CTS_N (28) // As Input
++#define TERTIARY_FUNCTION_ENABLE_UART1_DSR_N (29) // As Input
++#define TERTIARY_FUNCTION_ENABLE_UART1_CD_N (30) // As Input
++#define TERTIARY_FUNCTION_ENABLE_UART1_SOUT (31) // As Output
++#define TERTIARY_FUNCTION_ENABLE_UART1_SIN (32) // As Input
++#define TERTIARY_FUNCTION_ENABLE_UART1_RI_N (33) // As Input
++#define TERTIARY_FUNCTION_ENABLE_UART1_DTR_N (34) // As Output
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/ahb_mon.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/ahb_mon.h
+--- linux-2.6.24/include/asm-arm/arch-oxnas/ahb_mon.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/ahb_mon.h 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,27 @@
++/* linux/include/asm-arm/arch-oxnas/ahb_mon.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.
++ */
++#ifdef CONFIG_OXNAS_AHB_MON
++
++#if !defined(__AHB_MON_H__)
++#define __AHB_MON_H__
++
++extern void init_ahb_monitors(
++ AHB_MON_HWRITE_T ahb_mon_hwrite,
++ unsigned hburst_mask,
++ unsigned hburst_match,
++ unsigned hprot_mask,
++ unsigned hprot_match);
++extern void restart_ahb_monitors(void);
++extern void read_ahb_monitors(void);
++#else // CONFIG_OXNAS_AHB_MON
++#define init_ahb_monitors(a, b, c, d, e) {}
++#define restart_ahb_monitors(x) {}
++#define read_ahb_monitors(x) {}
++
++#endif // #if !defined(__AHB_MON_H__)
++#endif // CONFIG_OXNAS_AHB_MON
++
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/cipher.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/cipher.h
+--- linux-2.6.24/include/asm-arm/arch-oxnas/cipher.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/cipher.h 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,139 @@
++/*
++ * linux/include/asm-arm/arch-oxnas/cipher.h
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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
++ *
++ * Register locations in the cipher core
++ *
++ */
++
++#ifndef __ASM_ARCH_CIPHER_H
++#define __ASM_ARCH_CIPHER_H
++
++#define OX800DPE_CTL_DIRECTION_ENC 0x002
++#define OX800DPE_CTL_PRIMARY_IS_KEY3 0x004
++#define OX800DPE_CTL_ENCRYPT_KEY 0x010
++#define OX800DPE_CTL_ABORT 0x040
++#define OX800DPE_CTL_MODE_ECB_AES 0x000
++#define OX800DPE_CTL_MODE_LRW_AES 0x080
++#define OX800DPE_CTL_MODE_CBC_AES 0x100
++
++
++#define OX800DPE_STAT_IDLE 0x1
++#define OX800DPE_STAT_RX_SPACE 0x4
++#define OX800DPE_STAT_TX_NOTEMPTY 0x8
++
++
++#define OX800DPE_KEYSIZE 16
++typedef volatile u32 oxnas_cipher_key_t[4];
++
++#define OX800DPE_CONTROL ((DPE_REGS_BASE) + 0x00)
++#define OX800DPE_STATUS ((DPE_REGS_BASE) + 0x04)
++#define OX800DPE_KEY00 ((DPE_REGS_BASE) + 0x10)
++#define OX800DPE_KEY01 ((DPE_REGS_BASE) + 0x14)
++#define OX800DPE_KEY02 ((DPE_REGS_BASE) + 0x18)
++#define OX800DPE_KEY03 ((DPE_REGS_BASE) + 0x1c)
++#define OX800DPE_KEY10 ((DPE_REGS_BASE) + 0x20)
++#define OX800DPE_KEY11 ((DPE_REGS_BASE) + 0x24)
++#define OX800DPE_KEY12 ((DPE_REGS_BASE) + 0x28)
++#define OX800DPE_KEY13 ((DPE_REGS_BASE) + 0x2c)
++#define OX800DPE_KEY20 ((DPE_REGS_BASE) + 0x30)
++#define OX800DPE_KEY21 ((DPE_REGS_BASE) + 0x34)
++#define OX800DPE_KEY22 ((DPE_REGS_BASE) + 0x38)
++#define OX800DPE_KEY23 ((DPE_REGS_BASE) + 0x3c)
++#define OX800DPE_DATA_IN0 ((DPE_REGS_BASE) + 0x40)
++#define OX800DPE_DATA_IN1 ((DPE_REGS_BASE) + 0x44)
++#define OX800DPE_DATA_IN2 ((DPE_REGS_BASE) + 0x48)
++#define OX800DPE_DATA_IN3 ((DPE_REGS_BASE) + 0x4c)
++#define OX800DPE_DATA_OUT0 ((DPE_REGS_BASE) + 0x50)
++#define OX800DPE_DATA_OUT1 ((DPE_REGS_BASE) + 0x54)
++#define OX800DPE_DATA_OUT2 ((DPE_REGS_BASE) + 0x58)
++#define OX800DPE_DATA_OUT3 ((DPE_REGS_BASE) + 0x5c)
++#define OX800DPE_DATA_LRW0 ((DPE_REGS_BASE) + 0x60)
++#define OX800DPE_DATA_LRW1 ((DPE_REGS_BASE) + 0x64)
++#define OX800DPE_DATA_CBC0 ((DPE_REGS_BASE) + 0x68)
++#define OX800DPE_DATA_CBC1 ((DPE_REGS_BASE) + 0x6c)
++
++
++#define OX800IBW_STAT_AUTHENTICATED 0x10
++
++#define OX800IBW_CONTROL ((IBW_REGS_BASE) + 0x00)
++#define OX800IBW_STATUS ((IBW_REGS_BASE) + 0x04)
++#define OX800IBW_SERIAL_LO ((IBW_REGS_BASE) + 0x08)
++#define OX800IBW_SERIAL_HI ((IBW_REGS_BASE) + 0x0C)
++
++
++// IBIW Control register bits
++
++#define OX800IBW_CTRL_LOAD_AES_KEY 0x00100
++#define OX800IBW_CTRL_BUFF_WR_SRC 0x00200
++#define OX800IBW_CTRL_CRC_WR_SRC 0x00400
++#define OX800IBW_CTRL_RESET 0x00800
++#define OX800IBW_CTRL_WR 0x01000
++#define OX800IBW_CTRL_RD 0x02000
++#define OX800IBW_CTRL_RX_INIT 0x04000
++#define OX800IBW_CTRL_TX_INIT 0x08000
++#define OX800IBW_CTRL_DONE 0x10000
++#define OX800IBW_CTRL_ENABLE 0x20000
++
++
++// IBIW Status register bits
++
++#define OX800IBW_STATUS_PRESENT 0x0001
++#define OX800IBW_STATUS_ARRIVAL 0x0002
++#define OX800IBW_STATUS_DEPARTURE 0x0004
++#define OX800IBW_STATUS_HOLDOFF 0x0008
++#define OX800IBW_STATUS_CRC_OK 0x0010
++#define OX800IBW_STATUS_SERIAL_MATCH 0x0020
++#define OX800IBW_STATUS_KEY_MATCH 0x0040
++#define OX800IBW_STATUS_VALID_KEY 0x0080
++#define OX800IBW_STATUS_AUTHENTICATED 0x0100
++#define OX800IBW_STATUS_RD_ENABLED 0x0200
++
++/*The number of storage fields in a DS1991 iButton */
++#define DS1991_IBUTTON_FIELDS 4
++#define DS1991_PASSWORD_SIZE 8
++#define DS1991_ID_SIZE 8
++#define DS1991_DATA_SIZE 48
++#define DS1991_PLAINTEXT_SIZE 64
++
++/* DS1991 COMMANDS */
++#define DS1991_WRITE_SCRATCHPAD 0x96
++#define DS1991_READ_SCRATCHPAD 0x69
++#define DS1991_COPY_SCRATCHPAD 0x3c
++#define DS1991_READ_SUBKEY 0x66
++#define DS1991_WRITE_SUBKEY 0x99
++#define DS1991_WRITE_PASSWORD 0x5a
++
++/* prototype */
++struct scatterlist;
++
++int ox800_aeslrw_encrypt( struct scatterlist* in,
++ struct scatterlist* out,
++ unsigned int length,
++ u8 iv[],
++ u8 cipher_key[],
++ u8 tweak_key[]);
++
++int ox800_aeslrw_decrypt( struct scatterlist* in,
++ struct scatterlist* out,
++ unsigned int length,
++ u8 iv[],
++ u8 cipher_key[],
++ u8 tweak_key[]);
++
++#endif
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/debug-macro.S linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/debug-macro.S
+--- linux-2.6.24/include/asm-arm/arch-oxnas/debug-macro.S 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/debug-macro.S 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,47 @@
++/* linux/include/asm-arm/arch-oxnas/debug-macro.S
++ *
++ * Debugging macro include header
++ *
++ * Copyright (C) 2005 B.H.Clarke
++ *
++ * 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 <asm/arch/hardware.h>
++
++ .macro addruart,rx
++ mrc p15, 0, \rx, c1, c0
++ tst \rx, #1 @ MMU enabled?
++#ifdef CONFIG_ARCH_OXNAS_UART1
++ ldreq \rx, =UART_1_BASE_PA @ physical base address
++ ldrne \rx, =UART_1_BASE @ virtual address
++#elif CONFIG_ARCH_OXNAS_UART2
++ ldreq \rx, =UART_2_BASE_PA @ physical base address
++ ldrne \rx, =UART_2_BASE @ virtual address
++#elif CONFIG_ARCH_OXNAS_UART3
++ ldreq \rx, =UART_3_BASE_PA @ physical base address
++ ldrne \rx, =UART_3_BASE @ virtual address
++#else
++ ldreq \rx, =UART_4_BASE_PA @ physical base address
++ ldrne \rx, =UART_4_BASE @ virtual address
++#endif
++ .endm
++
++ .macro senduart,rd,rx @ Load byte into Tx holding register
++ strb \rd, [\rx, #0] @ THR
++ .endm
++
++ .macro waituart,rd,rx @ Wait until there is space in the TX FIFO
++1001: ldrb \rd, [\rx, #5] @ LSR
++ tst \rd, #1 << 5 @ THR empty
++ beq 1001b
++ .endm
++
++ .macro busyuart,rd,rx @ Wait until the TX is idle
++#1001: ldrb \rd, [\rx, #5] @ LSR
++# tst \rd, #1 << 6 @ THR and Tx FIFO empty
++# beq 1001b
++ .endm
++
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/desc_alloc.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/desc_alloc.h
+--- linux-2.6.24/include/asm-arm/arch-oxnas/desc_alloc.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/desc_alloc.h 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,62 @@
++/*
++ * linux/include/asm-arm/arch-oxnas/dma.h
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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
++ *
++ *
++ * Here we partition the available internal SRAM between the GMAC and generic
++ * DMA descriptors. This requires defining the gmac_dma_desc_t structure here,
++ * rather than in its more natural position within gmac.h
++ */
++#if !defined(__DESC_ALLOC_H__)
++#define __DESC_ALLOC_H__
++
++#include <asm/arch/hardware.h>
++
++// GMAC DMA in-memory descriptor structures
++typedef struct gmac_dma_desc
++{
++ /** The encoded status field of the GMAC descriptor */
++ u32 status;
++ /** The encoded length field of GMAC descriptor */
++ u32 length;
++ /** Buffer 1 pointer field of GMAC descriptor */
++ u32 buffer1;
++ /** Buffer 2 pointer or next descriptor pointer field of GMAC descriptor */
++ u32 buffer2;
++} __attribute ((aligned(4),packed)) gmac_dma_desc_t;
++
++#define NUM_GMAC_DMA_DESCRIPTORS CONFIG_ARCH_OXNAS_NUM_GMAC_DESCRIPTORS
++
++#define GMAC_DESC_ALLOC_START (SRAM_BASE)
++#define GMAC_DESC_ALLOC_START_PA (DESCRIPTORS_BASE_PA)
++/** Must be modified to track gmac_dma_desc_t definition above */
++#define GMAC_DESC_ALLOC_SIZE ((NUM_GMAC_DMA_DESCRIPTORS) * (4*4))
++
++#if ((GMAC_DESC_ALLOC_SIZE) > (DESCRIPTORS_SIZE))
++#error "Too many GMAC descriptors - descriptor SRAM allocation exceeded"
++#endif
++
++#define DMA_DESC_ALLOC_START ((GMAC_DESC_ALLOC_START) + (GMAC_DESC_ALLOC_SIZE))
++#define DMA_DESC_ALLOC_START_PA ((GMAC_DESC_ALLOC_START_PA) + (GMAC_DESC_ALLOC_SIZE))
++#define DMA_DESC_ALLOC_SIZE ((DESCRIPTORS_SIZE) - (GMAC_DESC_ALLOC_SIZE))
++
++#define descriptors_virt_to_phys(x) ((x) - (SRAM_BASE) + (DESCRIPTORS_BASE_PA))
++#define descriptors_phys_to_virt(x) ((x) - (DESCRIPTORS_BASE_PA) + (SRAM_BASE))
++
++#endif // #if !defined(__DESC_ALLOC_H__)
++
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/dma.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/dma.h
+--- linux-2.6.24/include/asm-arm/arch-oxnas/dma.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/dma.h 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,299 @@
++/*
++ * linux/include/asm-arm/arch-oxnas/dma.h
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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
++ *
++ *
++ * We have a generic DMAC that is a two port, memory to memory design, supporting
++ * multiple channels, each of which can transfer between any pair of memory
++ * regions. This DMAC architecture does not sit well with the std. ARM DMA
++ * architecture, thus we define a custom way of acquiring and operating on the
++ * available channels of the DMAC
++ */
++
++#ifndef __ASM_ARCH_DMA_H
++#define __ASM_ARCH_DMA_H
++
++#include <asm/scatterlist.h>
++#include <asm/semaphore.h>
++#include <linux/ata.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++
++/* All memory DMAable */
++#define MAX_DMA_ADDRESS (~0UL)
++
++/* Do not want to use the std. ARM DMA architecure */
++#define MAX_DMA_CHANNELS 0
++
++#define MAX_OXNAS_DMA_CHANNELS 5
++
++#define MAX_OXNAS_DMA_TRANSFER_LENGTH ((1 << 21) - 1)
++
++#ifdef CONFIG_OXNAS_VERSION_0X800
++// Need to set this (unused) high order address bit in the start address of DMA
++// transfers in order for checksum calculation to be performed
++#define OXNAS_DMA_CSUM_ENABLE_ADR_BIT 28
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++//#define OXNAS_DMA_TEST
++//#define OXNAS_DMA_TEST_ITERATIONS 1
++//#define OXNAS_DMA_SG_TEST
++//#define OXNAS_DMA_SG_TEST_2
++//#define OXNAS_DMA_SG_TEST_ITERATIONS 1
++//#define OXNAS_DMA_SG_TEST2_ITERATIONS 1
++//#define OXNAS_DMA_SG_TEST_DUMP_BUFFERS
++//#define OXNAS_DMA_SG_TEST_DUMP_DESCRIPTORS
++//#define OXNAS_DMA_TEST_AFTER_SG_ITERATIONS 0
++//#define OXNAS_DMA_OVERALL_TEST_LOOPS 1
++
++// All other error codes are generated by the SG engine - refer to its
++// documentation for details
++typedef enum oxnas_dma_callback_status {
++ OXNAS_DMA_ERROR_CODE_NONE
++} oxnas_dma_callback_status_t;
++
++typedef enum oxnas_dma_mode {
++ OXNAS_DMA_MODE_FIXED,
++ OXNAS_DMA_MODE_INC
++} oxnas_dma_mode_t;
++
++typedef enum oxnas_dma_direction {
++ OXNAS_DMA_TO_DEVICE,
++ OXNAS_DMA_FROM_DEVICE
++} oxnas_dma_direction_t;
++
++struct oxnas_dma_channel;
++typedef struct oxnas_dma_channel oxnas_dma_channel_t;
++
++#define OXNAS_DMA_CHANNEL_NUL ((oxnas_dma_channel_t*)0)
++
++typedef void* oxnas_callback_arg_t;
++
++#define OXNAS_DMA_CALLBACK_ARG_NUL ((oxnas_callback_arg_t)0)
++
++typedef void (*oxnas_dma_callback_t)(oxnas_dma_channel_t*, oxnas_callback_arg_t, oxnas_dma_callback_status_t, u16 checksum, int interrupt_count);
++
++#define OXNAS_DMA_CALLBACK_NUL ((oxnas_dma_callback_t)0)
++
++typedef enum oxnas_dma_eot_type {
++ OXNAS_DMA_EOT_NONE,
++ OXNAS_DMA_EOT_ALL,
++ OXNAS_DMA_EOT_FINAL
++} oxnas_dma_eot_type_t;
++
++// Will be exchanged with SG DMA controller
++typedef struct oxnas_dma_sg_entry {
++ dma_addr_t addr_; // The physical address of the buffer described by this descriptor
++ unsigned long length_; // The length of the buffer described by this descriptor
++ dma_addr_t p_next_; // The physical address of the next descriptor
++ struct oxnas_dma_sg_entry *v_next_; // The virtual address of the next descriptor
++ dma_addr_t paddr_; // The physical address of this descriptor
++ struct oxnas_dma_sg_entry *next_; // To allow insertion into single-linked list
++} __attribute ((aligned(4),packed)) oxnas_dma_sg_entry_t;
++
++// Will be exchanged with SG DMA controller
++typedef struct oxnas_dma_sg_info {
++ unsigned long qualifer_;
++ unsigned long control_;
++ dma_addr_t p_srcEntries_; // The physical address of the first source SG descriptor
++ dma_addr_t p_dstEntries_; // The physical address of the first destination SG descriptor
++ oxnas_dma_sg_entry_t *v_srcEntries_; // The virtual address of the first source SG descriptor
++ oxnas_dma_sg_entry_t *v_dstEntries_; // The virtual address of the first destination SG descriptor
++} __attribute ((aligned(4),packed)) oxnas_dma_sg_info_t;
++
++struct oxnas_dma_channel {
++ unsigned channel_number_;
++ oxnas_dma_callback_t notification_callback_;
++ oxnas_callback_arg_t notification_arg_;
++ dma_addr_t p_sg_info_; // Physical address of sg_info structure
++ oxnas_dma_sg_info_t *v_sg_info_; // Virtual address of sg_info structure
++ oxnas_dma_callback_status_t error_code_;
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ int checksumming_;
++ u16 checksum_;
++#endif // CONFIG_OXNAS_VERSION_0X800
++ unsigned rps_interrupt_;
++ struct oxnas_dma_channel *next_;
++ struct semaphore default_semaphore_;
++ atomic_t interrupt_count_;
++ atomic_t active_count_;
++ int auto_sg_entries_;
++};
++
++typedef struct oxnas_dma_controller {
++ oxnas_dma_channel_t channels_[MAX_OXNAS_DMA_CHANNELS];
++ unsigned numberOfChannels_;
++ int version_;
++ atomic_t run_bh_;
++ spinlock_t spinlock_;
++ struct tasklet_struct tasklet_;
++ dma_addr_t p_sg_infos_; // Physical address of the array of sg_info structures
++ oxnas_dma_sg_info_t *v_sg_infos_; // Virtual address of the array of sg_info structures
++ struct semaphore csum_engine_sem_;
++ spinlock_t alloc_spinlock_; // Sync. for SG management
++ spinlock_t channel_alloc_spinlock_; // Sync. for channel management
++ oxnas_dma_sg_entry_t *sg_entry_head_; // Pointer to head of free list for oxnas_dma_sg_entry_t objects
++ struct semaphore sg_entry_sem_;
++ unsigned sg_entry_available_;
++ oxnas_dma_channel_t *channel_head_;
++ struct semaphore channel_sem_;
++} oxnas_dma_controller_t;
++
++typedef struct oxnas_dma_device_settings {
++ unsigned long address_;
++ unsigned fifo_size_; // Chained transfers must take account of FIFO offset at end of previous transfer
++ unsigned char dreq_;
++ unsigned read_eot_policy_:2;
++ unsigned write_eot_policy_:2;
++ unsigned bus_:1;
++ unsigned width_:2;
++ unsigned transfer_mode_:1;
++ unsigned address_mode_:1;
++ unsigned address_really_fixed_:1;
++} oxnas_dma_device_settings_t;
++
++/* Pre-defined settings for known DMA devices */
++extern oxnas_dma_device_settings_t oxnas_pata_dma_settings;
++extern oxnas_dma_device_settings_t oxnas_sata_dma_settings;
++extern oxnas_dma_device_settings_t oxnas_dpe_rx_dma_settings;
++extern oxnas_dma_device_settings_t oxnas_dpe_tx_dma_settings;
++
++extern void oxnas_dma_init(void);
++
++extern void oxnas_dma_shutdown(void);
++
++extern oxnas_dma_channel_t* oxnas_dma_request(int block);
++
++extern void oxnas_dma_free(oxnas_dma_channel_t*);
++
++extern int oxnas_dma_is_active(oxnas_dma_channel_t*);
++
++extern int oxnas_dma_raw_isactive(oxnas_dma_channel_t*);
++
++extern int oxnas_dma_raw_sg_isactive(oxnas_dma_channel_t*);
++
++extern int oxnas_dma_get_raw_direction(oxnas_dma_channel_t*);
++
++/**
++ * @param do_checksum An int indicating that the checksum engine is required
++ * and causing the OXNAS_DMA_CSUM_ENABLE_ADR_BIT to be set
++ * automatically in the passed src and dst start addresses
++ * @return An int which is zero on success. Non-zero will returned if the length
++ * exceeds that allowed by the hardware
++ */
++extern int oxnas_dma_set(
++ oxnas_dma_channel_t *channel,
++ unsigned char *src_adr, // Physical address
++ unsigned long length,
++ unsigned char *dst_adr, // Physical address
++ oxnas_dma_mode_t src_mode,
++ oxnas_dma_mode_t dst_mode,
++ int do_checksum,
++ int paused);
++
++/**
++ * @return An int which is zero on success. Non-zero will returned if the length
++ * exceeds that allowed by the hardware
++ */
++extern int oxnas_dma_device_set(
++ oxnas_dma_channel_t *channel,
++ oxnas_dma_direction_t direction,
++ unsigned char *mem_adr, // Physical address
++ unsigned long length,
++ oxnas_dma_device_settings_t *device_settings,
++ oxnas_dma_mode_t mem_mode,
++ int paused);
++
++/**
++ * @return An int which is zero on success. Non-zero will returned if the length
++ * exceeds that allowed by the hardware
++ */
++extern int oxnas_dma_device_pair_set(
++ oxnas_dma_channel_t *channel,
++ unsigned long length,
++ oxnas_dma_device_settings_t *src_device_settings,
++ oxnas_dma_device_settings_t *dst_device_settings,
++ int paused);
++
++/**
++ * @param do_checksum An int indicating that the checksum engine is required
++ * for this SG transfer. For the individual SG transfer
++ * components to contribute to the checksum result, their
++ * start addresses contained within the scatterlist
++ * structures must have the OXNAS_DMA_CSUM_ENABLE_ADR_BIT
++ * bit set
++ *
++ * NB This function does not have an error return value, but if it is passed
++ * a transfer segment longer than the maximum allowed by the hardware, that
++ * entry will be zeroed in the SG descriptor list and a kernel warning
++ * message generated
++ */
++extern int oxnas_dma_set_sg(
++ oxnas_dma_channel_t* channel,
++ struct scatterlist* src_sg,
++ unsigned src_sg_count,
++ struct scatterlist* dst_sg,
++ unsigned dst_sg_count,
++ oxnas_dma_mode_t src_mode,
++ oxnas_dma_mode_t dst_mode,
++ int do_checksum,
++ int in_atomic);
++
++/**
++ * NB This function does not have an error return value, but if it is passed
++ * a transfer segment longer than the maximum allowed by the hardware, that
++ * entry will be zeroed in the SG descriptor list and a kernel warning
++ * message generated
++ */
++extern int oxnas_dma_device_set_sg(
++ oxnas_dma_channel_t* channel,
++ oxnas_dma_direction_t direction,
++ struct scatterlist* mem_sg,
++ unsigned mem_sg_count,
++ oxnas_dma_device_settings_t* device_settings,
++ oxnas_dma_mode_t mem_mode,
++ int in_atomic);
++
++extern int oxnas_dma_device_set_prd(
++ oxnas_dma_channel_t *channel,
++ oxnas_dma_direction_t direction,
++ struct ata_prd *prd,
++ oxnas_dma_device_settings_t *device_settings,
++ oxnas_dma_mode_t mem_mode,
++ oxnas_dma_sg_entry_t *sg_entries);
++
++/**
++ * The callback function should complete quickly and must not sleep
++ */
++extern void oxnas_dma_set_callback(
++ oxnas_dma_channel_t*,
++ oxnas_dma_callback_t callback,
++ oxnas_callback_arg_t callback_arg);
++
++extern void oxnas_dma_abort(oxnas_dma_channel_t*, int in_atomic);
++
++extern void oxnas_dma_start(oxnas_dma_channel_t*);
++
++extern void oxnas_dma_dump_registers(void);
++
++extern void oxnas_dma_dump_registers_single(int channel_number);
++
++extern int oxnas_dma_alloc_sg_entries(oxnas_dma_sg_entry_t** entries, unsigned required, int in_atomic);
++
++extern void oxnas_dma_free_sg_entries(oxnas_dma_sg_entry_t* entries);
++#endif // __ASM_ARCH_DMA_H
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/entry-macro.S linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/entry-macro.S
+--- linux-2.6.24/include/asm-arm/arch-oxnas/entry-macro.S 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/entry-macro.S 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,40 @@
++/*
++ * include/asm-arm/arch-oxnas/entry-macro.S
++ *
++ * Low-level IRQ helper macros for Integrator platforms
++ *
++ * 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 <asm/arch/irqs.h>
++#include <asm/arch/hardware.h>
++
++ .macro disable_fiq
++ .endm
++
++ .macro get_irqnr_preamble, base, tmp
++ .endm
++
++ .macro arch_ret_to_user, tmp1, tmp2
++ .endm
++
++ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
++ ldr \irqstat, =RPS_IRQ_STATUS
++ ldr \irqstat, [\irqstat, #0]
++
++ mov \irqnr, #0
++1001:
++ tst \irqstat, #1
++ bne 1002f
++ add \irqnr, \irqnr, #1
++ mov \irqstat, \irqstat, lsr #1
++ cmp \irqnr, #NR_IRQS
++ bcc 1001b
++
++1002:
++ .endm
++
++ .macro irq_prio_table
++ .endm
++
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/hardware.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/hardware.h
+--- linux-2.6.24/include/asm-arm/arch-oxnas/hardware.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/hardware.h 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,760 @@
++/* linux/include/asm-arm/arch-oxnas/hardware.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.
++ */
++
++#ifndef __ASM_ARCH_HARDWARE_H
++#define __ASM_ARCH_HARDWARE_H
++
++#include <asm/page.h>
++#include <asm/memory.h>
++#include <asm/sizes.h>
++#include <asm/arch/vmalloc.h>
++#include <asm/arch/timex.h>
++
++// The base of virtual address mappings for hardware cores starts directly after
++// the end of the vmalloc mapping region
++#define OXNAS_HW_PA_TO_VA(x) (VMALLOC_END + (x))
++
++// Virtual address mapping of hardware cores
++#define APB_BRIDGE_A_BASE OXNAS_HW_PA_TO_VA(0)
++#define STATIC_CONTROL_BASE OXNAS_HW_PA_TO_VA(0x1000000)
++#define CORE_MODULE_BASE OXNAS_HW_PA_TO_VA(0x2000000)
++#define EXTERNAL_UART_BASE OXNAS_HW_PA_TO_VA(0x3000000)
++#define EXTERNAL_UART_2_BASE OXNAS_HW_PA_TO_VA(0x3800000)
++
++/* 16 Mbyte address range on AMBA bus */
++#define APB_BRIDGE_BASE_MASK 0x00FFFFFF
++
++#define APB_BRIDGE_B_BASE OXNAS_HW_PA_TO_VA(0x04000000)
++#define SATA_DATA_BASE OXNAS_HW_PA_TO_VA(0x05000000)
++#define DPE_BASE OXNAS_HW_PA_TO_VA(0x06000000)
++#define USB_BASE OXNAS_HW_PA_TO_VA(0x07000000)
++#define MAC_BASE OXNAS_HW_PA_TO_VA(0x08000000)
++#define PCI_CSRS_BASE OXNAS_HW_PA_TO_VA(0x0A000000)
++#define STATIC_CS0_BASE OXNAS_HW_PA_TO_VA(0x0B000000)
++#define STATIC_CS1_BASE OXNAS_HW_PA_TO_VA(0x0C000000)
++#define STATIC_CS2_BASE OXNAS_HW_PA_TO_VA(0x0D000000)
++#define ROM_BASE OXNAS_HW_PA_TO_VA(0x0E000000)
++#define SDRAM_CTRL_BASE OXNAS_HW_PA_TO_VA(0x0F000000)
++#define LEON_IMAGE_BASE OXNAS_HW_PA_TO_VA(0x10000000)
++#define SRAM_BASE OXNAS_HW_PA_TO_VA(0x11000000)
++
++#ifdef CONFIG_SUPPORT_LEON
++#define LEON_IMAGE_SIZE (CONFIG_LEON_PAGES * PAGE_SIZE)
++#define LEON_IMAGE_BASE_PA (((SRAM_END) + 1) - (LEON_IMAGE_SIZE))
++#else // CONFIG_SUPPORT_LEON
++#define LEON_IMAGE_SIZE 0
++#define LEON_IMAGE_BASE_PA 0
++#endif // CONFIG_SUPPORT_LEON
++
++#if (LEON_IMAGE_BASE_PA >= SRAM_PA) && (LEON_IMAGE_BASE_PA <= SRAM_END)
++#define LEON_IMAGE_IN_SRAM
++#endif
++
++#define DESCRIPTORS_SIZE (CONFIG_DESCRIPTORS_PAGES * PAGE_SIZE)
++
++#ifdef CONFIG_DESCRIPTORS_PAGES
++#if (CONFIG_DESCRIPTORS_PAGES > CONFIG_SRAM_NUM_PAGES)
++#error "Too many descriptor pages defined - greater than total SRAM pages"
++#endif
++#endif // CONFIG_DESCRIPTORS_PAGES
++
++#define DESCRIPTORS_BASE_PA (SRAM_PA)
++#define DESCRIPTORS_END_PA (SRAM_PA + DESCRIPTORS_SIZE)
++
++#ifdef LEON_IMAGE_IN_SRAM
++#if (DESCRIPTORS_END_PA > LEON_IMAGE_BASE_PA)
++#error "Overlapping LEON and Descriptor areas in SRAM"
++#endif
++#endif
++
++#define CORE_MODULE_BASE_PA 0x10000000
++
++#define ROM_BASE_PA 0x40000000
++#define USB_BASE_PA 0x40200000
++#define MAC_BASE_PA 0x40400000
++#define PCI_CSRS_BASE_PA 0x40600000
++#define PCI_BASE_PA 0x40800000
++
++#define STATIC_CS0_BASE_PA 0x41000000
++#define STATIC_CS1_BASE_PA 0x41400000
++#define STATIC_CS2_BASE_PA 0x41800000
++#define STATIC_CONTROL_BASE_PA 0x41C00000
++
++#define SATA_DATA_BASE_PA 0x42000000
++#define DPE_BASE_PA 0x43000000
++#define APB_BRIDGE_A_BASE_PA 0x44000000
++#define APB_BRIDGE_B_BASE_PA 0x45000000
++
++#define UART_1_BASE_PA (APB_BRIDGE_A_BASE_PA + 0x200000)
++#define UART_2_BASE_PA (APB_BRIDGE_A_BASE_PA + 0x300000)
++#define UART_3_BASE_PA (APB_BRIDGE_A_BASE_PA + 0x900000)
++#define UART_4_BASE_PA (APB_BRIDGE_A_BASE_PA + 0xA00000)
++
++#define GPIO_A_BASE APB_BRIDGE_A_BASE
++#define GPIO_B_BASE (APB_BRIDGE_A_BASE + 0x100000)
++#define UART_1_BASE (APB_BRIDGE_A_BASE + 0x200000)
++#define UART_2_BASE (APB_BRIDGE_A_BASE + 0x300000)
++#define UART_3_BASE (APB_BRIDGE_A_BASE + 0x900000)
++#define UART_4_BASE (APB_BRIDGE_A_BASE + 0xA00000)
++#define I2C_BASE (APB_BRIDGE_A_BASE + 0x400000)
++#define I2S_BASE (APB_BRIDGE_A_BASE + 0x500000)
++#define FAN_MON_BASE (APB_BRIDGE_A_BASE + 0x600000)
++#define PWM_BASE (APB_BRIDGE_A_BASE + 0x700000)
++#define IRRX_BASE (APB_BRIDGE_A_BASE + 0x800000)
++
++#define SYS_CONTROL_BASE APB_BRIDGE_B_BASE
++#define CLOCK_CONTROL_BASE (APB_BRIDGE_B_BASE + 0x100000)
++#define RTC_BASE (APB_BRIDGE_B_BASE + 0x200000)
++#define RPS_BASE (APB_BRIDGE_B_BASE + 0x300000)
++#define COPRO_RPS_BASE (APB_BRIDGE_B_BASE + 0x400000)
++#define AHB_MON_BASE (APB_BRIDGE_B_BASE + 0x500000)
++#define DMA_BASE (APB_BRIDGE_B_BASE + 0x600000)
++#define DPE_REGS_BASE (APB_BRIDGE_B_BASE + 0x700000)
++#define IBW_REGS_BASE (APB_BRIDGE_B_BASE + 0x780000)
++#define DDR_REGS_BASE (APB_BRIDGE_B_BASE + 0x800000)
++
++#ifdef CONFIG_OXNAS_VERSION_0X800
++#define SATA0_REGS_BASE (APB_BRIDGE_B_BASE + 0x900000)
++#define SATA0_LINK_REGS_BASE (APB_BRIDGE_B_BASE + 0x940000)
++#define SATA1_REGS_BASE (APB_BRIDGE_B_BASE + 0x980000)
++#define SATA1_LINK_REGS_BASE (APB_BRIDGE_B_BASE + 0x9C0000)
++#elif CONFIG_OXNAS_VERSION_0X810
++#define SATA_REG_BASE (APB_BRIDGE_B_BASE + 0x900000)
++#define SATA0_REGS_BASE (SATA_REG_BASE)
++#define SATA1_REGS_BASE (SATA_REG_BASE + 0x10000)
++#define SATACORE_REGS_BASE (SATA_REG_BASE + 0xe0000)
++#define SATARAID_REGS_BASE (SATA_REG_BASE + 0xf0000)
++#endif // CONFIG_OXNAS_VERSION_0X8xx
++
++#define DMA_CHECKSUM_BASE (APB_BRIDGE_B_BASE + 0xA00000)
++#define COPRO_REGS_BASE (APB_BRIDGE_B_BASE + 0xB00000)
++#define DMA_SG_BASE (APB_BRIDGE_B_BASE + 0xC00000)
++
++/* Interrupt Controller registers */
++#define RPS_IC_BASE RPS_BASE
++#define RPS_IRQ_STATUS (RPS_IC_BASE)
++#define RPS_IRQ_RAW_STATUS (RPS_IC_BASE + 0x04)
++#define RPS_IRQ_ENABLE (RPS_IC_BASE + 0x08)
++#define RPS_IRQ_DISABLE (RPS_IC_BASE + 0x0C)
++#define RPS_IRQ_SOFT (RPS_IC_BASE + 0x10)
++
++/* FIQ registers */
++#define RPS_FIQ_BASE (RPS_IC_BASE + 0x100)
++#define RPS_FIQ_STATUS (RPS_FIQ_BASE + 0x00)
++#define RPS_FIQ_RAW_STATUS (RPS_FIQ_BASE + 0x04)
++#define RPS_FIQ_ENABLE (RPS_FIQ_BASE + 0x08)
++#define RPS_FIQ_DISABLE (RPS_FIQ_BASE + 0x0C)
++
++/* Timer registers */
++#define RPS_TIMER_BASE (RPS_BASE + 0x200)
++#define RPS_TIMER1_BASE (RPS_TIMER_BASE)
++#define RPS_TIMER2_BASE (RPS_TIMER_BASE + 0x20)
++
++#define TIMER1_LOAD (RPS_TIMER1_BASE + 0x0)
++#define TIMER1_VALUE (RPS_TIMER1_BASE + 0x4)
++#define TIMER1_CONTROL (RPS_TIMER1_BASE + 0x8)
++#define TIMER1_CLEAR (RPS_TIMER1_BASE + 0xc)
++
++#define TIMER2_LOAD (RPS_TIMER2_BASE + 0x0)
++#define TIMER2_VALUE (RPS_TIMER2_BASE + 0x4)
++#define TIMER2_CONTROL (RPS_TIMER2_BASE + 0x8)
++#define TIMER2_CLEAR (RPS_TIMER2_BASE + 0xc)
++
++#define TIMER_MODE_BIT 6
++#define TIMER_MODE_FREE_RUNNING 0
++#define TIMER_MODE_PERIODIC 1
++#define TIMER_ENABLE_BIT 7
++#define TIMER_ENABLE_DISABLE 0
++#define TIMER_ENABLE_ENABLE 1
++
++/* System clock frequencies */
++#ifdef CONFIG_ARCH_OXNAS_FPGA
++/* FPGA CPU clock is entirely independent of rest of SoC */
++#define NOMINAL_ARMCLK (CONFIG_OXNAS_CORE_CLK)
++#else // CONFIG_ARCH_OXNAS_FPGA
++/* ASIC CPU clock is derived from SoC master clock */
++#define NOMINAL_ARMCLK (CONFIG_NOMINAL_PLL400_FREQ / 2)
++#endif // CONFIG_ARCH_OXNAS_FPGA
++
++#define NOMINAL_SYSCLK (CONFIG_NOMINAL_PLL400_FREQ / 4)
++#define NOMINAL_PCICLK 33000000
++
++#ifdef CONFIG_ARCH_OXNAS_FPGA
++/* FPGA has no PCI clock divider */
++#define PCI_CLOCK_DIVIDER 1
++#else // CONFIG_ARCH_OXNAS_FPGA
++/* ASIC PCI divider divides CONFIG_NOMINAL_PLL400_FREQ by 2(n + 1) to get 33MHz */
++#define PCI_CLOCK_DIVIDER (((CONFIG_NOMINAL_PLL400_FREQ) / (2 * NOMINAL_PCICLK)) - 1)
++#endif //CONFIG_ARCH_OXNAS_FPGA
++
++/* RPS timer setup */
++#define TIMER_1_MODE TIMER_MODE_PERIODIC
++#define TIMER_2_PRESCALE_ENUM TIMER_PRESCALE_256
++#define TIMER_2_MODE TIMER_MODE_FREE_RUNNING
++
++/* Useful macros for dealing with sub timer-interrupt intervals - preserve
++ * as much precision as possible without using floating point and minimising
++ * runtime CPU requirement */
++#define TIMER_1_LOAD_VALUE ((CLOCK_TICK_RATE) / HZ)
++#define TICKS_TO_US_SCALING 1024
++#define TICKS_TO_US_FACTOR (((2 * TICKS_TO_US_SCALING * 1000000) + CLOCK_TICK_RATE) / (2 * CLOCK_TICK_RATE))
++#define TICKS_TO_US(ticks) ((((ticks) * TICKS_TO_US_FACTOR * 2) + TICKS_TO_US_SCALING) / (2 * TICKS_TO_US_SCALING))
++
++/* Remap and pause */
++#define RPS_REMAP_AND_PAUSE (RPS_BASE + 0x300)
++
++/* GPIO */
++#define GPIO_0 (0x00)
++#define GPIO_1 (0x01)
++#define GPIO_2 (0x02)
++#define GPIO_3 (0x03)
++#define GPIO_4 (0x04)
++#define GPIO_5 (0x05)
++#define GPIO_6 (0x06)
++#define GPIO_7 (0x07)
++#define GPIO_8 (0x08)
++#define GPIO_9 (0x09)
++#define GPIO_10 (0x0a)
++#define GPIO_11 (0x0b)
++#define GPIO_12 (0x0c)
++#define GPIO_13 (0x0d)
++#define GPIO_14 (0x0e)
++#define GPIO_15 (0x0f)
++#define GPIO_16 (0x10)
++#define GPIO_17 (0x11)
++#define GPIO_18 (0x12)
++#define GPIO_19 (0x13)
++#define GPIO_20 (0x14)
++#define GPIO_21 (0x15)
++#define GPIO_22 (0x16)
++#define GPIO_23 (0x17)
++#define GPIO_24 (0x18)
++#define GPIO_25 (0x19)
++#define GPIO_26 (0x1a)
++#define GPIO_27 (0x1b)
++#define GPIO_28 (0x1c)
++#define GPIO_29 (0x1d)
++#define GPIO_30 (0x1e)
++#define GPIO_31 (0x1f)
++#define GPIO_32 (0x00)
++#define GPIO_33 (0x01)
++#define GPIO_34 (0x02)
++
++/* Symbols for functions mapped onto GPIO lines */
++#ifdef CONFIG_ARCH_OXNAS_FPGA
++#define PCI_GPIO_INTA_PLANAR 8
++#define PCI_GPIO_INTA_MINIPCI 9
++#else // CONFIG_ARCH_OXNAS_FPGA
++#ifdef CONFIG_OXNAS_VERSION_0X800
++#define PCI_GPIO_INTA_PLANAR 3
++#define PCI_GPIO_INTA_MINIPCI 9
++#elif CONFIG_OXNAS_VERSION_0X810
++#define PCI_GPIO_INTA_PLANAR 3
++#define PCI_GPIO_INTA_MINIPCI 9
++#endif // CONFIG_OXNAS_VERSION_0X8xx
++#endif // CONFIG_ARCH_OXNAS_FPGA
++
++#define PCI_GPIO_CLKO_0 8
++#define PCI_GPIO_CLKO_1 9
++#define PCI_GPIO_CLKO_2 10
++#define PCI_GPIO_CLKO_3 11
++#define PCI_GPIO_CLKO_4 23
++
++#define PCI_GNT_N0 0
++#define PCI_GNT_N1 1
++#define PCI_GNT_N2 2
++#define PCI_GNT_N3 3
++#define PCI_REQ_N0 4
++#define PCI_REQ_N1 5
++#define PCI_REQ_N2 6
++#define PCI_REQ_N3 7
++
++#define IBW_GPIO_DATA (GPIO_33)
++
++#define USBA_POWO_GPIO 23
++#define USBA_OVERI_GPIO 24
++#define USBB_POWO_GPIO 25
++#define USBB_OVERI_GPIO 26
++#define USBC_POWO_GPIO 27
++#define USBC_OVERI_GPIO 28
++
++/* RPS GPIO registers */
++#define RPS_GPIO_BASE GPIO_1_BASE /*(RPS_BASE + 0x3C0) ??????? */
++
++/* GPIO A registers */
++#define GPIO_A_DATA GPIO_A_BASE
++#define GPIO_A_OUTPUT_ENABLE (GPIO_A_BASE + 0x0004)
++#define GPIO_A_INTERRUPT_ENABLE (GPIO_A_BASE + 0x0008)
++#define GPIO_A_INTERRUPT_EVENT (GPIO_A_BASE + 0x000C)
++#define GPIO_A_OUTPUT_VALUE (GPIO_A_BASE + 0x0010)
++#define GPIO_A_OUTPUT_SET (GPIO_A_BASE + 0x0014)
++#define GPIO_A_OUTPUT_CLEAR (GPIO_A_BASE + 0x0018)
++#define GPIO_A_OUTPUT_ENABLE_SET (GPIO_A_BASE + 0x001C)
++#define GPIO_A_OUTPUT_ENABLE_CLEAR (GPIO_A_BASE + 0x0020)
++#define GPIO_A_INPUT_DEBOUNCE_ENABLE (GPIO_A_BASE + 0x0024)
++#define GPIO_A_RISING_EDGE_ACTIVE_HIGH_ENABLE (GPIO_A_BASE + 0x0028)
++#define GPIO_A_FALLING_EDGE_ACTIVE_LOW_ENABLE (GPIO_A_BASE + 0x002C)
++#define GPIO_A_RISING_EDGE_DETECT (GPIO_A_BASE + 0x0030)
++#define GPIO_A_FALLING_EDGE_DETECT (GPIO_A_BASE + 0x0034)
++#define GPIO_A_LEVEL_INTERRUPT_ENABLE (GPIO_A_BASE + 0x0038)
++#define GPIO_A_INTERRUPT_STATUS_REGISTER (GPIO_A_BASE + 0x003C)
++
++/* GPIO B registers */
++#define GPIO_B_DATA GPIO_B_BASE
++#define GPIO_B_OUTPUT_ENABLE (GPIO_B_BASE + 0x0004)
++#define GPIO_B_INTERRUPT_ENABLE (GPIO_B_BASE + 0x0008)
++#define GPIO_B_INTERRUPT_EVENT (GPIO_B_BASE + 0x000C)
++#define GPIO_B_OUTPUT_VALUE (GPIO_B_BASE + 0x0010)
++#define GPIO_B_OUTPUT_SET (GPIO_B_BASE + 0x0014)
++#define GPIO_B_OUTPUT_CLEAR (GPIO_B_BASE + 0x0018)
++#define GPIO_B_OUTPUT_ENABLE_SET (GPIO_B_BASE + 0x001C)
++#define GPIO_B_OUTPUT_ENABLE_CLEAR (GPIO_B_BASE + 0x0020)
++#define GPIO_B_INPUT_DEBOUNCE_ENABLE (GPIO_B_BASE + 0x0024)
++#define GPIO_B_RISING_EDGE_ACTIVE_HIGH_ENABLE (GPIO_B_BASE + 0x0028)
++#define GPIO_B_FALLING_EDGE_ACTIVE_LOW_ENABLE (GPIO_B_BASE + 0x002C)
++#define GPIO_B_RISING_EDGE_DETECT (GPIO_B_BASE + 0x0030)
++#define GPIO_B_FALLING_EDGE_DETECT (GPIO_B_BASE + 0x0034)
++#define GPIO_B_LEVEL_INTERRUPT_ENABLE (GPIO_B_BASE + 0x0038)
++#define GPIO_B_INTERRUPT_STATUS_REGISTER (GPIO_B_BASE + 0x003C)
++
++/* CoProcessor RPS GPIO registers */
++#define COPRO_GPIO_A_BASE (COPRO_RPS_BASE + 0x3C0)
++#define COPRO_GPIO_A_DATA COPRO_GPIO_A_BASE
++#define COPRO_GPIO_A_OUTPUT_ENABLE (COPRO_GPIO_A_BASE + 0x04)
++#define COPRO_GPIO_A_INTERRUPT_MASK (COPRO_GPIO_A_BASE + 0x08)
++#define COPRO_GPIO_A_INTERRUPT_EVENT (COPRO_GPIO_A_BASE + 0x0C)
++
++/* Static bus registers */
++#define STATIC_CONTROL_VERSION (STATIC_CONTROL_BASE + 0x0)
++#define STATIC_CONTROL_BANK0 (STATIC_CONTROL_BASE + 0x4)
++#define STATIC_CONTROL_BANK1 (STATIC_CONTROL_BASE + 0x8)
++#define STATIC_CONTROL_BANK2 (STATIC_CONTROL_BASE + 0xC)
++
++/* System Control registers */
++#define SYS_CTRL_USB11_CTRL (SYS_CONTROL_BASE + 0x00)
++#define SYS_CTRL_PCI_CTRL0 (SYS_CONTROL_BASE + 0x04)
++#define SYS_CTRL_PCI_CTRL1 (SYS_CONTROL_BASE + 0x08)
++#define SYS_CTRL_GPIO_PRIMSEL_CTRL_0 (SYS_CONTROL_BASE + 0x0C)
++#define SYS_CTRL_GPIO_PRIMSEL_CTRL_1 (SYS_CONTROL_BASE + 0x10)
++#define SYS_CTRL_GPIO_SECSEL_CTRL_0 (SYS_CONTROL_BASE + 0x14)
++#define SYS_CTRL_GPIO_SECSEL_CTRL_1 (SYS_CONTROL_BASE + 0x18)
++#define SYS_CTRL_GPIO_TERTSEL_CTRL_0 (SYS_CONTROL_BASE + 0x8C)
++#define SYS_CTRL_GPIO_TERTSEL_CTRL_1 (SYS_CONTROL_BASE + 0x90)
++#define SYS_CTRL_USB11_STAT (SYS_CONTROL_BASE + 0x1c)
++#define SYS_CTRL_PCI_STAT (SYS_CONTROL_BASE + 0x20)
++#define SYS_CTRL_CKEN_CTRL (SYS_CONTROL_BASE + 0x24)
++#define SYS_CTRL_RSTEN_CTRL (SYS_CONTROL_BASE + 0x28)
++#define SYS_CTRL_CKEN_SET_CTRL (SYS_CONTROL_BASE + 0x2C)
++#define SYS_CTRL_CKEN_CLR_CTRL (SYS_CONTROL_BASE + 0x30)
++#define SYS_CTRL_RSTEN_SET_CTRL (SYS_CONTROL_BASE + 0x34)
++#define SYS_CTRL_RSTEN_CLR_CTRL (SYS_CONTROL_BASE + 0x38)
++#define SYS_CTRL_USBHSMPH_CTRL (SYS_CONTROL_BASE + 0x40)
++#define SYS_CTRL_USBHSMPH_STAT (SYS_CONTROL_BASE + 0x44)
++#define SYS_CTRL_PLLSYS_CTRL (SYS_CONTROL_BASE + 0x48)
++#define SYS_CTRL_SEMA_STAT (SYS_CONTROL_BASE + 0x4C)
++#define SYS_CTRL_SEMA_SET_CTRL (SYS_CONTROL_BASE + 0x50)
++#define SYS_CTRL_SEMA_CLR_CTRL (SYS_CONTROL_BASE + 0x54)
++#define SYS_CTRL_SEMA_MASKA_CTRL (SYS_CONTROL_BASE + 0x58)
++#define SYS_CTRL_SEMA_MASKB_CTRL (SYS_CONTROL_BASE + 0x5C)
++#define SYS_CTRL_SEMA_MASKC_CTRL (SYS_CONTROL_BASE + 0x60)
++#define SYS_CTRL_CKCTRL_CTRL (SYS_CONTROL_BASE + 0x64)
++#define SYS_CTRL_COPRO_CTRL (SYS_CONTROL_BASE + 0x68)
++#define SYS_CTRL_PLLSYS_KEY_CTRL (SYS_CONTROL_BASE + 0x6C)
++#define SYS_CTRL_GMAC_CTRL (SYS_CONTROL_BASE + 0x78)
++#define SYS_CTRL_USBHSPHY_CTRL (SYS_CONTROL_BASE + 0x84)
++#define SYS_CTRL_UART_CTRL (SYS_CONTROL_BASE + 0x94)
++#define SYS_CTRL_GPIO_PWMSEL_CTRL_0 (SYS_CONTROL_BASE + 0x9C)
++#define SYS_CTRL_GPIO_PWMSEL_CTRL_1 (SYS_CONTROL_BASE + 0xA0)
++#define SYSCTRL_GPIO_MONSEL_CTRL_0 (SYS_CONTROL_BASE + 0xA4)
++#define SYSCTRL_GPIO_MONSEL_CTRL_1 (SYS_CONTROL_BASE + 0xA8)
++#define SYSCTRL_GPIO_PULLUP_CTRL_0 (SYS_CONTROL_BASE + 0xAC)
++#define SYSCTRL_GPIO_PULLUP_CTRL_1 (SYS_CONTROL_BASE + 0xB0)
++#define SYSCTRL_GPIO_ODRIVEHI_CTRL_0 (SYS_CONTROL_BASE + 0xB4)
++#define SYSCTRL_GPIO_ODRIVEHI_CTRL_1 (SYS_CONTROL_BASE + 0xB8)
++#define SYSCTRL_GPIO_ODRIVELO_CTRL_0 (SYS_CONTROL_BASE + 0xBC)
++#define SYSCTRL_GPIO_ODRIVELO_CTRL_1 (SYS_CONTROL_BASE + 0xC0)
++
++
++/* System control register field definitions */
++#define SYSCTL_CB_CIS_OFFSET_0 SYS_CTRL_PCI_CTRL0
++
++#define SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO5 19
++#define SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO4 18
++#define SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO3 17
++#define SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO2 16
++#define SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO1 15
++#define SYSCTL_PCI_CTRL1_PULL_UP_ENABLE_GPIO0 14
++#define SYSCTL_PCI_CTRL1_ENPU 13
++#define SYSCTL_PCI_CTRL1_ENCB 12
++#define SYSCTL_PCI_CTRL1_SYSPCI_STATIC_REQ 11
++#define SYSCTL_PCI_CTRL1_SS_HOST_E 10
++#define SYSCTL_PCI_CTRL1_SYSPCI_PAKING_ENABLE 9
++#define SYSCTL_PCI_CTRL1_SYSPCI_PAKING_MASTE 7
++#define SYSCTL_PCI_CTRL1_SS_CADBUS_E 6
++#define SYSCTL_PCI_CTRL1_SS_MINIPCI_ 5
++#define SYSCTL_PCI_CTRL1_SS_INT_MASK_0 4
++#define SYSCTL_PCI_CTRL1_INT_STATUS_0 3
++#define SYSCTL_PCI_CTRL1_APP_EQUIES_NOM_CLK 2
++#define SYSCTL_PCI_CTRL1_APP_CBUS_INT_N 1
++#define SYSCTL_PCI_CTRL1_APP_CSTSCHG_N 0
++
++#define SYSCTL_PCI_STAT_SYSPCI_CLKCHG_EQ 3
++#define SYSCTL_PCI_STAT_SYSPCI_STATIC_GNT 2
++#define SYSCTL_PCI_STAT_INT_DISABLE_0 1
++#define SYSCTL_PCI_STAT_CLK_CHANGED 0
++
++#define SYS_CTRL_CKEN_COPRO_BIT 0
++#define SYS_CTRL_CKEN_DMA_BIT 1
++#define SYS_CTRL_CKEN_DPE_BIT 2
++#define SYS_CTRL_CKEN_DDR_BIT 3
++#define SYS_CTRL_CKEN_SATA_BIT 4
++#define SYS_CTRL_CKEN_I2S_BIT 5
++#define SYS_CTRL_CKEN_USBHS_BIT 6
++#define SYS_CTRL_CKEN_MAC_BIT 7
++#define SYS_CTRL_CKEN_PCI_BIT 8
++#define SYS_CTRL_CKEN_STATIC_BIT 9
++
++#define SYS_CTRL_RSTEN_ARM_BIT 0
++#define SYS_CTRL_RSTEN_COPRO_BIT 1
++#define SYS_CTRL_RSTEN_USBHS_BIT 4
++#define SYS_CTRL_RSTEN_USBHSPHY_BIT 5
++#define SYS_CTRL_RSTEN_MAC_BIT 6
++#define SYS_CTRL_RSTEN_PCI_BIT 7
++#define SYS_CTRL_RSTEN_DMA_BIT 8
++#define SYS_CTRL_RSTEN_DPE_BIT 9
++#define SYS_CTRL_RSTEN_DDR_BIT 10
++
++#ifdef CONFIG_OXNAS_VERSION_0X800
++ #define SYS_CTRL_RSTEN_SATA_BIT 11
++ #define SYS_CTRL_RSTEN_SATA_PHY_BIT 12
++#elif CONFIG_OXNAS_VERSION_0X810
++ #define SYS_CTRL_RSTEN_SATA_BIT 11
++ #define SYS_CTRL_RSTEN_SATA_LINK_BIT 12
++ #define SYS_CTRL_RSTEN_SATA_PHY_BIT 13
++#endif
++
++#define SYS_CTRL_RSTEN_STATIC_BIT 15
++#define SYS_CTRL_RSTEN_GPIO_BIT 16
++#define SYS_CTRL_RSTEN_UART1_BIT 17
++#define SYS_CTRL_RSTEN_UART2_BIT 18
++#define SYS_CTRL_RSTEN_MISC_BIT 19
++#define SYS_CTRL_RSTEN_I2S_BIT 20
++#define SYS_CTRL_RSTEN_AHB_MON_BIT 21
++#define SYS_CTRL_RSTEN_UART3_BIT 22
++#define SYS_CTRL_RSTEN_UART4_BIT 23
++#define SYS_CTRL_RSTEN_SGDMA_BIT 24
++#define SYS_CTRL_RSTEN_BUS_BIT 31
++
++#define SYS_CTRL_USBHSMPH_IP_POL_A_BIT 0
++#define SYS_CTRL_USBHSMPH_IP_POL_B_BIT 1
++#define SYS_CTRL_USBHSMPH_IP_POL_C_BIT 2
++#define SYS_CTRL_USBHSMPH_OP_POL_A_BIT 3
++#define SYS_CTRL_USBHSMPH_OP_POL_B_BIT 4
++#define SYS_CTRL_USBHSMPH_OP_POL_C_BIT 5
++
++#define SYS_CTRL_GMAC_RGMII 2
++#define SYS_CTRL_GMAC_SIMPLE_MAX 1
++#define SYS_CTRL_GMAC_CKEN_GTX 0
++
++#define SYS_CTRL_CKCTRL_CTRL_PCIDIV_BIT 0
++#define SYS_CTRL_CKCTRL_CTRL_PCIDIV_NUM_BITS 4
++
++#define SYS_CTRL_USBHSPHY_SUSPENDM_MANUAL_ENABLE 16
++#define SYS_CTRL_USBHSPHY_SUSPENDM_MANUAL_STATE 15
++#define SYS_CTRL_USBHSPHY_ATE_ESET 14
++#define SYS_CTRL_USBHSPHY_TEST_DIN 6
++#define SYS_CTRL_USBHSPHY_TEST_ADD 2
++#define SYS_CTRL_USBHSPHY_TEST_DOUT_SEL 1
++#define SYS_CTRL_USBHSPHY_TEST_CLK 0
++
++#define SYS_CTRL_UART2_DEQ_EN 0
++#define SYS_CTRL_UART3_DEQ_EN 1
++#define SYS_CTRL_UART3_IQ_EN 2
++#define SYS_CTRL_UART4_IQ_EN 3
++#define SYS_CTRL_UART4_NOT_PCI_MODE 4
++
++/* DDR core registers */
++#define DDR_CFG_REG (DDR_REGS_BASE + 0x00)
++#define DDR_BLKEN_REG (DDR_REGS_BASE + 0x04)
++#define DDR_STAT_REG (DDR_REGS_BASE + 0x08)
++#define DDR_CMD_REG (DDR_REGS_BASE + 0x0C)
++#define DDR_AHB_REG (DDR_REGS_BASE + 0x10)
++#define DDR_DLL_REG (DDR_REGS_BASE + 0x14)
++#define DDR_MON_REG (DDR_REGS_BASE + 0x18)
++#define DDR_DIAG_REG (DDR_REGS_BASE + 0x1C)
++#define DDR_DIAG2_REG (DDR_REGS_BASE + 0x20)
++#define DDR_IOC_REG (DDR_REGS_BASE + 0x24)
++#define DDR_ARB_REG (DDR_REGS_BASE + 0x28)
++#define DDR_AHB2_REG (DDR_REGS_BASE + 0x2C)
++#define DDR_BUSY_REG (DDR_REGS_BASE + 0x30)
++#define DDR_TIMING0_REG (DDR_REGS_BASE + 0x34)
++#define DDR_TIMING1_REG (DDR_REGS_BASE + 0x38)
++#define DDR_TIMING2_REG (DDR_REGS_BASE + 0x3C)
++#define DDR_AHB3_REG (DDR_REGS_BASE + 0x40)
++#define DDR_AHB4_REG (DDR_REGS_BASE + 0x44)
++#define DDR_PHY0_REG (DDR_REGS_BASE + 0x48)
++#define DDR_PHY1_REG (DDR_REGS_BASE + 0x4C)
++#define DDR_PHY2_REG (DDR_REGS_BASE + 0x50)
++#define DDR_PHY3_REG (DDR_REGS_BASE + 0x54)
++
++/* DDR core register field definitions */
++#define DDR_BLKEN_CLIENTS_BIT 0
++#define DDR_BLKEN_CLIENTS_NUM_BITS 16
++#define DDR_BLKEN_DDR_BIT 31
++
++#define DDR_AHB_FLUSH_RCACHE_BIT 0
++#define DDR_AHB_FLUSH_RCACHE_NUM_BITS 16
++
++#define DDR_AHB_FLUSH_RCACHE_ARMD_BIT 0
++#define DDR_AHB_FLUSH_RCACHE_ARMI_BIT 1
++#define DDR_AHB_FLUSH_RCACHE_COPRO_BIT 2
++#define DDR_AHB_FLUSH_RCACHE_DMAA_BIT 3
++#define DDR_AHB_FLUSH_RCACHE_DMAB_BIT 4
++#define DDR_AHB_FLUSH_RCACHE_PCI_BIT 5
++#define DDR_AHB_FLUSH_RCACHE_GMAC_BIT 6
++#define DDR_AHB_FLUSH_RCACHE_USB_BIT 7
++
++#define DDR_AHB_NO_RCACHE_BIT 16
++#define DDR_AHB_NO_RCACHE_NUM_BITS 16
++
++#define DDR_AHB_NO_RCACHE_ARMD_BIT 16
++#define DDR_AHB_NO_RCACHE_ARMI_BIT 17
++#define DDR_AHB_NO_RCACHE_COPRO_BIT 18
++#define DDR_AHB_NO_RCACHE_DMAA_BIT 19
++#define DDR_AHB_NO_RCACHE_DMAB_BIT 20
++#define DDR_AHB_NO_RCACHE_PCI_BIT 21
++#define DDR_AHB_NO_RCACHE_GMAC_BIT 22
++#define DDR_AHB_NO_RCACHE_USB_BIT 23
++
++#define DDR_MON_CLIENT_BIT 0
++#define DDR_MON_ALL_BIT 4
++
++#define DDR_DIAG_HOLDOFFS_BIT 20
++#define DDR_DIAG_HOLDOFFS_NUM_BITS 12
++#define DDR_DIAG_WRITES_BIT 10
++#define DDR_DIAG_WRITES_NUM_BITS 10
++#define DDR_DIAG_READS_BIT 0
++#define DDR_DIAG_READS_NUM_BITS 10
++
++#define DDR_DIAG2_DIRCHANGES_BIT 0
++#define DDR_DIAG2_DIRCHANGES_NUM_BITS 10
++
++#define DDR_ARB_DATDIR_NCH_BIT 0
++#define DDR_ARB_DATDIR_EN_BIT 1
++#define DDR_ARB_REQAGE_EN_BIT 2
++#define DDR_ARB_LRUBANK_EN_BIT 3
++#define DDR_ARB_MIDBUF_BIT 4
++
++#define DDR_AHB2_IGNORE_HPROT_BIT 0
++#define DDR_AHB2_IGNORE_HPROT_NUM_BITS 16
++
++#define DDR_AHB2_IGNORE_HPROT_ARMD_BIT 0
++#define DDR_AHB2_IGNORE_HPROT_ARMI_BIT 1
++#define DDR_AHB2_IGNORE_HPROT_COPRO_BIT 2
++#define DDR_AHB2_IGNORE_HPROT_DMAA_BIT 3
++#define DDR_AHB2_IGNORE_HPROT_DMAB_BIT 4
++#define DDR_AHB2_IGNORE_HPROT_PCI_BIT 5
++#define DDR_AHB2_IGNORE_HPROT_GMAC_BIT 6
++#define DDR_AHB2_IGNORE_HPROT_USB_BIT 7
++
++#define DDR_AHB2_IGNORE_WRAP_BIT 16
++#define DDR_AHB2_IGNORE_WRAP_NUM_BITS 16
++
++#define DDR_AHB2_IGNORE_WRAP_ARMD_BIT 16
++#define DDR_AHB2_IGNORE_WRAP_ARMI_BIT 17
++#define DDR_AHB2_IGNORE_WRAP_COPRO_BIT 18
++#define DDR_AHB2_IGNORE_WRAP_DMAA_BIT 19
++#define DDR_AHB2_IGNORE_WRAP_DMAB_BIT 20
++#define DDR_AHB2_IGNORE_WRAP_PCI_BIT 21
++#define DDR_AHB2_IGNORE_WRAP_GMAC_BIT 22
++#define DDR_AHB2_IGNORE_WRAP_US_BIT 23
++
++#define DDR_AHB3_DIS_BURST_BIT 0
++#define DDR_AHB3_DIS_BURST_NUM_BITS 16
++
++#define DDR_AHB3_DIS_BURST_ARMD_BIT 0
++#define DDR_AHB3_DIS_BURST_ARMI_BIT 1
++#define DDR_AHB3_DIS_BURST_COPRO_BIT 2
++#define DDR_AHB3_DIS_BURST_DMAA_BIT 3
++#define DDR_AHB3_DIS_BURST_DMAB_BIT 4
++#define DDR_AHB3_DIS_BURST_PCI_BIT 5
++#define DDR_AHB3_DIS_BURST_GMAC_BIT 6
++#define DDR_AHB3_DIS_BURST_USB_BIT 7
++
++#define DDR_AHB3_DIS_NONCACHE_BIT 16
++#define DDR_AHB3_DIS_NONCACHE_NUM_BITS 16
++
++#define DDR_AHB3_DIS_NONCACHE_ARMD_BIT 16
++#define DDR_AHB3_DIS_NONCACHE_ARMI_BIT 17
++#define DDR_AHB3_DIS_NONCACHE_COPRO_BIT 18
++#define DDR_AHB3_DIS_NONCACHE_DMAA_BIT 19
++#define DDR_AHB3_DIS_NONCACHE_DMAB_BIT 20
++#define DDR_AHB3_DIS_NONCACHE_PCI_BIT 21
++#define DDR_AHB3_DIS_NONCACHE_GMAC_BIT 22
++#define DDR_AHB3_DIS_NONCACHE_USB_BIT 23
++
++#define DDR_AHB4_EN_TIMEOUT_BIT 0
++#define DDR_AHB4_EN_TIMEOUT_NUM_BITS 16
++
++#define DDR_AHB4_EN_TIMEOUT_ARMD_BIT 0
++#define DDR_AHB4_EN_TIMEOUT_ARMI_BIT 1
++#define DDR_AHB4_EN_TIMEOUT_COPRO_BIT 2
++#define DDR_AHB4_EN_TIMEOUT_DMAA_BIT 3
++#define DDR_AHB4_EN_TIMEOUT_DMAB_BIT 4
++#define DDR_AHB4_EN_TIMEOUT_PCI_BIT 5
++#define DDR_AHB4_EN_TIMEOUT_GMAC_BIT 6
++#define DDR_AHB4_EN_TIMEOUT_USB_BIT 7
++
++#define DDR_AHB4_EN_WRBEHIND_BIT 16
++#define DDR_AHB4_EN_WRBEHIND_NUM_BITS 16
++
++#define DDR_AHB4_EN_WRBEHIND_ARMD_BIT 16
++#define DDR_AHB4_EN_WRBEHIND_ARMI_BIT 17
++#define DDR_AHB4_EN_WRBEHIND_COPRO_BIT 18
++#define DDR_AHB4_EN_WRBEHIND_DMAA_BIT 19
++#define DDR_AHB4_EN_WRBEHIND_DMAB_BIT 20
++#define DDR_AHB4_EN_WRBEHIND_PCI_BIT 21
++#define DDR_AHB4_EN_WRBEHIND_GMAC_BIT 22
++#define DDR_AHB4_EN_WRBEHIND_USB_BIT 23
++
++/* AHB monitor base addresses */
++#define AHB_MON_ARM_D (AHB_MON_BASE + 0x00000)
++#define AHB_MON_ARM_I (AHB_MON_BASE + 0x10000)
++#define AHB_MON_DMA_A (AHB_MON_BASE + 0x20000)
++#define AHB_MON_DMA_B (AHB_MON_BASE + 0x30000)
++#define AHB_MON_LEON (AHB_MON_BASE + 0x40000)
++#define AHB_MON_USB (AHB_MON_BASE + 0x50000)
++#define AHB_MON_MAC (AHB_MON_BASE + 0x60000)
++#define AHB_MON_PCI (AHB_MON_BASE + 0x70000)
++
++/* AHB write monitor registers */
++#define AHB_MON_MODE_REG_OFFSET 0x00
++#define AHB_MON_HWRITE_REG_OFFSET 0x04
++#define AHB_MON_HADDR_LOW_REG_OFFSET 0x08
++#define AHB_MON_HADDR_HIGH_REG_OFFSET 0x0C
++#define AHB_MON_HBURST_REG_OFFSET 0x10
++#define AHB_MON_HPROT_REG_OFFSET 0x14
++
++/* AHB monitor write register field definitions */
++#define AHB_MON_MODE_MODE_BIT 0
++#define AHB_MON_MODE_MODE_NUM_BITS 2
++#define AHB_MON_HWRITE_COUNT_BIT 0
++#define AHB_MON_HWRITE_COUNT_NUM_BITS 2
++#define AHB_MON_HBURST_MASK_BIT 0
++#define AHB_MON_HBURST_MASK_NUM_BITS 3
++#define AHB_MON_HBURST_MATCH_BIT 4
++#define AHB_MON_HBURST_MATCH_NUM_BITS 3
++#define AHB_MON_HPROT_MASK_BIT 0
++#define AHB_MON_HPROT_MASK_NUM_BITS 4
++#define AHB_MON_HPROT_MATCH_BIT 4
++#define AHB_MON_HPROT_MATCH_NUM_BITS 4
++
++#ifndef __ASSEMBLY__
++typedef enum AHB_MON_MODES {
++ AHB_MON_MODE_IDLE,
++ AHB_MON_MODE_ACTIVE,
++ AHB_MON_MODE_RESET
++} AHB_MON_MODES_T;
++
++typedef enum AHB_MON_HWRITE {
++ AHB_MON_HWRITE_INACTIVE,
++ AHB_MON_HWRITE_WRITES,
++ AHB_MON_HWRITE_READS,
++ AHB_MON_HWRITE_READS_AND_WRITES
++} AHB_MON_HWRITE_T;
++
++typedef enum AHB_MON_HBURST {
++ AHB_MON_HBURST_SINGLE,
++ AHB_MON_HBURST_INCR,
++ AHB_MON_HBURST_WRAP4,
++ AHB_MON_HBURST_INCR4,
++ AHB_MON_HBURST_WRAP8,
++ AHB_MON_HBURST_INCR8,
++ AHB_MON_HBURST_WRAP16,
++ AHB_MON_HBURST_INCR16
++} AHB_MON_HBURST_T;
++#endif // __ASSEMBLY__
++
++/* AHB read monitor registers */
++#define AHB_MON_CYCLES_REG_OFFSET 0x00
++#define AHB_MON_TRANSFERS_REG_OFFSET 0x04
++#define AHB_MON_WAITS_REG_OFFSET 0x08
++
++#define STATIC_BUS1_CONTROL_VALUE 0x04010484 /* 200nS rd/wr cycles to allow DMAing to SMC91x on static bus */
++
++/* PCI bus definitions */
++#define pcibios_assign_all_busses() 1
++#define PCIBIOS_MIN_IO 0x1000 /* used for memory alignememnt guesstimate */
++#define PCIBIOS_MIN_MEM 0x00100000 /* used for memory alignememnt guesstimate */
++
++/* PCI bus commands - see pci spec */
++#define PCI_BUS_CMD_INTERRUPT_ACKNOWLEDGE 0x00
++#define PCI_BUS_CMD_SPECIAL_CYCLE 0x01
++#define PCI_BUS_CMD_IO_READ 0x02
++#define PCI_BUS_CMD_IO_WRITE 0x03
++/*#define PCI_BUS_RESERVED 0x04 */
++/*#define PCI_BUS_RESERVED 0x05 */
++#define PCI_BUS_CMD_MEMORY_READ 0x06
++#define PCI_BUS_CMD_MEMORY_WRITE 0x07
++/*#define PCI_BUS_RESERVED 0x08 */
++/*#define PCI_BUS_RESERVED 0x09 */
++#define PCI_BUS_CMD_CONFIGURATION_READ 0x0a
++#define PCI_BUS_CMD_CONFIGURATION_WRITE 0x0b
++#define PCI_BUS_CMD_MEMORY_READ_MULTIPLE 0x0c
++#define PCI_BUS_CMD_DUAL_ADDRESS_CYCLE 0x0d
++#define PCI_BUS_CMD_MEMORY_READ_LINE 0x0e
++#define PCI_BUS_CMD_MEMORY_WRITE_AND_INVALIDATE 0x0f
++
++/* synopsis PCI core register set */
++#define PCI_CORE_REG_START PCI_CSRS_BASE
++#define PCI_CRP_CMD_AND_ADDR PCI_CORE_REG_START
++#define PCI_CRP_WRITE_DATA (PCI_CRP_CMD_AND_ADDR + 4)
++#define PCI_CRP_READ_DATA (PCI_CRP_WRITE_DATA + 4)
++#define PCI_CONFIG_IO_CYCLE_ADDR (PCI_CRP_READ_DATA + 4)
++#define PCI_CONFIG_IO_BYTE_CMD (PCI_CONFIG_IO_CYCLE_ADDR + 4)
++#define PCI_CONFIG_IO_WRITE_DATA (PCI_CONFIG_IO_BYTE_CMD + 4)
++#define PCI_CONFIG_IO_READ_DATA (PCI_CONFIG_IO_WRITE_DATA + 4)
++#define PCI_ERROR_MSG (PCI_CONFIG_IO_READ_DATA + 4)
++#define PCI_TRANS_ERROR_START_ADDR (PCI_ERROR_MSG + 4)
++#define PCI_AHB_ERROR_LSB (PCI_TRANS_ERROR_START_ADDR + 4)
++#define PCI_AHB_ERROR_START_ADDR (PCI_AHB_ERROR_LSB + 4)
++#define PCI_FLUSH_FIFO_ON_ERR (PCI_AHB_ERROR_START_ADDR + 4)
++#define PCI_TAR_ID (PCI_FLUSH_FIFO_ON_ERR + 4)
++#define PCI_MAS_ID_IN (PCI_TAR_ID + 4)
++#define PCI_CORE_REG_END (PCI_MAS_ID_IN + 4)
++
++/* register bit offsets */
++#define PCI_CRP_ADDRESS_START 0
++#define PCI_CRP_ADDRESS_END 10
++#define PCI_CRP_CMD_START 16
++#define PCI_CRP_CMD_END 19
++#define PCI_CRP_BYTE_ENABLES_START 20
++#define PCI_CRP_BYTE_ENABLES_END 23
++
++#define PCI_CONFIG_IO_CMD_START 0
++#define PCI_CONFIG_IO_CMD_END 3
++#define PCI_CONFIG_IO_BYTE_ENABLES_START 4
++#define PCI_CONFIG_IO_BYTE_ENABLES_END 7
++
++#define PCI_ERR_MESSAGE_START 0
++#define PCI_ERR_MESSAGE_END 1
++
++#define PCI_AHB_ERR_BIT 0
++
++#define PCI_FLUSH_FIFO_ON_ERR_BIT 0
++
++#define PCI_TAR_ID_START 0
++#define PCI_TAR_ID_END 2
++
++#define PCI_MAS_ID_IN_START 0
++#define PCI_MAS_ID_IN_END 2
++
++/* PWM register definitions */
++#define PWM_DATA_REGISTER_BASE (PWM_BASE)
++#define PWM_CLOCK_REGISTER (PWM_BASE+0X400)
++
++#endif // __ASM_ARCH_HARDWARE_H
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/i2s.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/i2s.h
+--- linux-2.6.24/include/asm-arm/arch-oxnas/i2s.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/i2s.h 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,1023 @@
++/*
++ * linux/include/asm-arm/arch-oxnas/i2s.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.
++ */
++
++#ifndef __ASM_ARM_ARCH_I2S_H
++#define __ASM_ARM_ARCH_I2S_H
++
++#include "hardware.h"
++
++/* Routines ----------------------------------------------------------------- */
++/* -------------------------------------------------------------------------- */
++/* -------------------------------------------------------------------------- */
++/* -------------------------------------------------------------------------- */
++
++extern void DumpI2SRegisters(void);
++
++
++
++/* Registers ---------------------------------------------------------------- */
++/* -------------------------------------------------------------------------- */
++/* -------------------------------------------------------------------------- */
++/* -------------------------------------------------------------------------- */
++
++
++#define TX_CONTROL (0x0000 + I2S_BASE)
++#define TX_SETUP (0x0004 + I2S_BASE)
++#define TX_SETUP1 (0x0008 + I2S_BASE)
++#define TX_STATUS (0x000C + I2S_BASE)
++#define RX_CONTROL (0x0010 + I2S_BASE)
++#define RX_SETUP (0x0014 + I2S_BASE)
++#define RX_SETUP1 (0x0018 + I2S_BASE)
++#define RX_STATUS (0x001C + I2S_BASE)
++#define TX_DEBUG (0x0020 + I2S_BASE)
++#define TX_DEBUG2 (0x0024 + I2S_BASE)
++#define TX_DEBUG3 (0x0028 + I2S_BASE)
++#define RX_DEBUG_ (0x0030 + I2S_BASE)
++#define RX_DEBUG2 (0x0034 + I2S_BASE)
++#define RX_DEBUG3 (0x0038 + I2S_BASE)
++#define TX_BUFFER_LEVEL (0x0040 + I2S_BASE)
++#define TX_BUFFER_INTERRUPT_LEVEL (0x0048 + I2S_BASE)
++#define RX_BUFFER_LEVEL (0x0050 + I2S_BASE)
++#define RX_BUFFER_INTERRUPT_LEVEL (0x0058 + I2S_BASE)
++#define RX_SPDIF_DEBUG (0x0070 + I2S_BASE)
++#define RX_SPDIF_DEBUG2 (0x0074 + I2S_BASE)
++#define INTERRUPT_CONTROL_STATUS (0x0080 + I2S_BASE)
++#define INTERRUPT_MASK (0x0084 + I2S_BASE)
++#define VERSION (0x008C + I2S_BASE)
++#define TX_DATA_IN_FORMAT (0x0100 + I2S_BASE)
++#define TX_CHANNELS_ENABLE (0x0104 + I2S_BASE)
++#define TX_WRITES_TO (0x0108 + I2S_BASE)
++#define RX_DATA_OUT_FORMAT (0x0200 + I2S_BASE)
++#define RX_CHANNELS_ENABLE (0x0204 + I2S_BASE)
++#define RX_READS_FROM (0x0208 + I2S_BASE)
++#define TX_CPU_DATA_WRITES_ALT (0x04FF + I2S_BASE)
++#define RX_CPU_DATA_READS_ALT (0x08FF + I2S_BASE)
++#define TX_CPU_DATA_WRITES (0x1FFF + I2S_BASE)
++#define RX_CPU_DATA_READS (0x2FFF + I2S_BASE)
++
++
++
++/* TX_CONTROL ------------ */
++#define TX_CONTROL_ENABLE 0
++ /**
++ * 0 - Audio transmit is disabled
++ * 1 - Audio transmit is enabled.
++ */
++#define TX_CONTROL_FLUSH 1
++ /**
++ * 0 - Normal Operation
++ * 1 - Flush TX buffer
++ */
++#define TX_CONTROL_MUTE 2
++ /**
++ * 0 - Normal Operation
++ * 1 - Muted operation
++ */
++#define TX_CONTROL_TRICK 3
++ /**
++ * (UNTESTED FEATURE)
++ * 0 - Trickplay features disabled
++ * 1 - Trickplay features enabled
++ */
++#define TX_CONTROL_SPEED 4
++ /**
++ * (UNTESTED FEATURE)
++ * 00 - Quarter speed playback - DOESN\92T WORK
++ * 01 - Half speed playback - DOESN\92T WORK
++ * 10 - Double speed playback
++ * 11 - Quadruple speed playback.
++ */
++ #define QUARTER_SPEED_PLAYBACK 0x00
++ #define HALF_SPEED_PLAYBACK 0x01
++ #define DOUBLE_SPEED_PLAYBACK 0x02
++ #define QUADRUPLE_SPEED_PLAYBACK 0x03
++#define TX_CONTROL_ABORT_DMA 6
++ /**
++ * Write a 1 to abort any outstanding DMAs (self-clearing)
++ */
++#define TX_CONTROL_AHB_ENABLE 8
++ /**
++ * 0 - AHB disabled (APB only)
++ * 1 - AHB enabled (APB disabled for data plane)
++ */
++#define TX_CONTROL_QUAD_BURSTS 9
++ /**
++ * 0 - DMA transfers up to Single Quads
++ * 1 - DMA transfers up to Bursts of 4 Quads
++ */
++
++
++/* TX_SETUP ------------ */
++/**
++ * In order for the changes made to the fields in bold to propagate to the Tx
++ * audio clock domain, a write must be performed to TX_SETUP1 And the TX_CLK
++ * must be running.
++ */
++
++#define TX_SETUP_FORMAT 0
++ /**
++ * 00 - True/Early-I2S (standard format)
++ * 01 - Late-I2S
++ * 10 - MP3 Valid
++ * 11 - MP3 Start
++ */
++ #define TRUE_I2S 0x00
++ #define LATE_I2S 0x01
++ #define MP3_VALID 0x02
++ #define MP3_START 0x03
++#define TX_SETUP_MODE 2
++ /**
++ * 0 - Slave
++ * 1 - Master
++ */
++ #define I2S_SLAVE 0x00
++ #define I2S_MASTER 0x01
++#define TX_SETUP_FLOW_INVERT 3
++ /**
++ * 0 - Flow Control is active high
++ * (ie. Audio core is held off when TX_FLOW_CONTROL=\921\92)
++ * 1 - Flow Control is active low
++ * (ie. Audio core is held off when TX_FLOW_CONTROL=\920\92)
++ */
++ #define FLOW_CONTROL_ACTIVE_HIGH 0
++ #define FLOW_CONTROL_ACTIVE_LOW 1
++#define TX_SETUP_POS_EDGE 4
++ /**
++ * 0 - Data is output on the negative edge of the TX Audio clock
++ * 1 - Data is output on the positive edge of the TX Audio clock
++ */
++#define TX_SETUP_CLOCK_STOP 5
++ /**
++ * 0 - Audio TX clock should not be stopped during flow control hold off
++ * 1 - Audio TX clock should be stopped during flow control hold off
++ */
++#define TX_SETUP_SPLIT_QUAD 6
++ /**
++ * 0 - No splitting
++ * 1 - Split quadlet into two 16 bit samples - NOT VALID FOR S/PDIF
++ */
++#define TX_SETUP_INSPECT_WORD_CLOCK 7
++ /**
++ * Used when recovering from underrun. This bit is set to look for either
++ * a high or low word clock before the hardware carries on as normal.
++ */
++#define TX_SETUP_SPDIF_EN 8
++ /**
++ * 0 - No SPDIF on Channel 0 (disables biphase coding on output)
++ * 1 - SPDIF on Channel 0 (enables the biphase coding even when Tx disabled)
++ */
++
++
++/* TX_SETUP1 ------------ */
++#define TX_SETUP1_INPUT 0
++ /**
++ * 00 - Twos Compliment (pass-thru)
++ * 01 - Offset Binary
++ * 10 - Sign Magnitude
++ * 11 - Reserved
++ */
++ #define TWOS_COMPLIMENT 0x00
++ #define OFFSET_BINARY 0x01
++ #define SIGN_MAGNITUDE 0x02
++ #define RESERVED 0x03
++#define TX_SETUP1_REVERSE 2
++ /**
++ * 0 - Normal operation
++ * 1 - Reverse Stereo - DOES NOT WORK FOR NON- SPLIT_QUAD/MP3
++ */
++#define TX_SETUP1_INVERT 3
++ /**
++ * 0 - Normal operation
++ * 1 - Inverted word clock
++ */
++#define TX_SETUP1_BIG_ENDIAN 4
++ /**
++ * 0 - System data is in little endian format
++ * 1 - System data is in big endian format
++ */
++#define TX_SETUP1_QUAD_ENDIAN 5
++ /**
++ * 0 - System data is 16 bit.
++ * 1 - System data is 32 bit
++ */
++#define TX_SETUP1_QUAD_SAMPLES 6
++ /**
++ * 0 - I2S Master word clock uses 16 bit samples - NOT VALID FOR S/PDIF
++ * 1 - I2S Master word clock uses 32 bit samples
++ */
++#define TX_SETUP1_FLOW_CONTROL 7
++ /**
++ * 0 - No flow control (MP3 only)
++ * 1 - Flow control (MP3 only)
++ */
++
++/* TX_STATUS ------------ */
++#define TX_STATUS_UNDERRUN 0
++ /**
++ * 0 - Underrun has not occurred.
++ * 1 - Underrun has occurred. (Note that this bit must be written to with
++ * a \911\92 to clear)
++ */
++#define TX_STATUS_OVERRUN 1
++ /**
++ * 0 - Overrun has not occurred.
++ * 1 - Overrun has occurred. (Note that this bit must be written to with
++ * a \911\92 to clear)
++ */
++#define TX_STATUS_FIFO_UNDERRUN 2
++
++ /**
++ * 0 - FIFO Underrun has not occurred.
++ * 1 - FIFO Underrun has occurred. (Note that this bit must be written to
++ * with a \911\92 to clear)
++ */
++#define TX_STATUS_FIFO_OVERRUN 3
++ /**
++ * 0 - FIFO Overrun has not occurred.
++ * 1 - FIFO Overrun has occurred. (Note that this bit must be written to
++ * with a \911\92 to clear)
++ */
++#define TX_STATUS_HW_READ 8
++ /**
++ * 0 - H/W Read of FIFO has not occurred.
++ * 1 - H/W Read of FIFO has occurred. (Note that this bit must be written
++ * to with a \911\92 to clear)
++ */
++#define TX_STATUS_BUFFER_LEVEL_MET 9
++ /**
++ * 0 - Fill level of FIFO does not match BUFFER_INTERRUPT_LEVEL.
++ * 1 - Fill level of FIFO matches BUFFER_INTERRUPT_LEVEL
++ */
++
++
++/* RX_CONTROL ------------ */
++#define RX_CONTROL_ENABLE 0
++ /**
++ * 0 - Audio receive is disabled
++ * 1 - Audio receive is enabled.
++ */
++#define RX_CONTROL_FLUSH 1
++ /**
++ * 0 - Normal Operation
++ * 1 - Flush RX buffer
++ */
++#define RX_CONTROL_MUTE 2
++ /**
++ * 0 - Normal Operation
++ * 1 - Muted operation
++ */
++#define RX_CONTROL_TRICK 3
++ /**
++ * (UNTESTED FEATURE)
++ * 0 - Trickplay features disabled
++ * 1 - Trickplay features enabled
++ */
++#define RX_CONTROL_SPEED 4
++ /**
++ * (UNTESTED FEATURE)
++ * 00 - Quarter speed playback - DOESN\92T WORK
++ * 01 - Half speed playback - DOESN\92T WORK
++ * 10 - Double speed playback
++ * 11 - Quadruple speed playback.
++ */
++#define RX_CONTROL_ABORT_DMA 6
++ /**
++ * Write a 1 to abort any outstanding DMAs (self-clearing)
++ */
++#define RX_CONTROL_AHB_ENABLE 8
++ /**
++ * 0 - AHB disabled (APB only)
++ * 1 - AHB enabled (APB disabled for data plane)
++ */
++#define RX_CONTROL_QUAD_BURSTS 9
++ /**
++ * 0 - DMA transfers up to Single Quads
++ * 1 - DMA transfers up to Bursts of 4 Quads
++ */
++
++
++/* RX_SETUP ------------ */
++/**
++ * In order for the changes made to the fields in bold to propagate to the Rx
++ * audio clock domain, a write must be performed to RX_SETUP1 And the RX_CLK
++ * must be running.
++ */
++
++#define RX_SETUP_FORMAT 0
++ /**
++ * 00 - True/Early-I2S (standard format)
++ * 01 - Late-I2S
++ * 10 - MP3 Valid
++ * 11 - MP3 Start
++ */
++#define RX_SETUP_MODE 2
++ /**
++ * 0 - Slave
++ * 1 - Master - NOT VALID FOR S/PDIF
++ */
++#define RX_SETUP_POS_EDGE 4
++ /**
++ * 0 - Data is output on the negative edge of the RX Audio clock
++ * 1 - Data is output on the positive edge of the RX Audio clock
++ */
++#define RX_SETUP_COMBINE_QUAD 6
++ /**
++ * 0 - No combining
++ * 1 - Combine two 16 bit samples into single quadlet - NOT VALID FOR S/PDIF
++ */
++#define RX_SETUP_INSPECT_WORD_CLOCK 7
++ /**
++ * Used when recovering from overrun. This bit is set to look for either
++ * a high or low word clock before the hardware carries on as normal.
++ */
++#define RX_SETUP_SPDIF_EN 8
++ /**
++ * 0 - No SPDIF on Channel 0 (disables biphase decoding and clk recovery on input)
++ * 1 - SPDIF on Channel 0 (enables the biphase decoding and clk recovery even when Rx disabled)
++ */
++#define RX_SETUP_SPDIF_DEBUG_EN 9
++ /**
++ * Provides direct control over RX_SPDIF_OE Output signal
++ */
++
++
++/* RX_SETUP1 ------------ */
++#define RX_SETUP1_INPUT 0
++ /**
++ * 00 - Twos Compliment (pass-thru)
++ * 01 - Offset Binary
++ * 10 - Sign Magnitude
++ * 11 - Reserved
++ */
++#define RX_SETUP1_REVERSE 2
++ /**
++ * 0 - Normal operation
++ * 1 - Reverse Stereo - DOES NOT WORK FOR NON- SPLIT_QUAD/MP3
++ */
++#define RX_SETUP1_INVERT 3
++ /**
++ * 0 - Normal operation
++ * 1 - Inverted word clock
++ */
++#define RX_SETUP1_BIG_ENDIAN 4
++ /**
++ * 0 - System data is in little endian format
++ * 1 - System data is in big endian format
++ */
++#define RX_SETUP1_QUAD_ENDIAN 5
++ /**
++ * 0 - System data is 16 bit.
++ * 1 - System data is 32 bit
++ */
++#define RX_SETUP1_QUAD_SAMPLES 6
++ /**
++ * 0 - I2S Master word clock uses 16 bit samples - NOT VALID FOR S/PDIF
++ * 1 - I2S Master word clock uses 32 bit samples
++ */
++
++
++/* RX_STATUS ------------ */
++#define RX_STATUS_UNDERRUN 0
++ /**
++ * 0 - Underrun has not occurred.
++ * 1 - Underrun has occurred. (Note that this bit must be written to with
++ * a \911\92 to clear)
++ */
++#define RX_STATUS_OVERRUN 1
++ /**
++ * 0 - Overrun has not occurred.
++ * 1 - Overrun has occurred. (Note that this bit must be written to with
++ * a \911\92 to clear)
++ */
++#define RX_STATUS_FIFO_UNDERRUN 2
++ /**
++ * 0 - FIFO Underrun has not occurred.
++ * 1 - FIFO Underrun has occurred. (Note that this bit must be written to
++ * with a \911\92 to clear)
++ */
++#define RX_STATUS_FIFO_OVERRUN 3
++ /**
++ * 0 - FIFO Overrun has not occurred.
++ * 1 - FIFO Overrun has occurred. (Note that this bit must be written to
++ * with a \911\92 to clear)
++ */
++#define RX_STATUS_SPDIF_PARITY_ERROR 4
++ /**
++ * 0 - Rx S/PDIF Parity Error has not occurred.
++ * 1 - Rx S/PDIF Parity Error has occurred. (Note that this bit must be
++ * written to with a \911\92 to clear)
++ */
++#define RX_STATUS_SPDIF_PREAMBLE_ERROR 5
++ /**
++ * 0 - Rx S/PDIF Preamble Error has not occurred.
++ * 1 - Rx S/PDIF Preamble Error has occurred. (Note that this bit must be
++ * written to with a \911\92 to clear)
++ */
++#define RX_STATUS_SPDIF_FRAMING_ERROR 6
++ /**
++ * 0 - Rx S/PDIF Framing Error has not occurred.
++ * 1 - Rx S/PDIF Framing Error has occurred. (Note that this bit must be
++ * written to with a \911\92 to clear)
++ */
++#define RX_STATUS_SPDIF_LOCK_EVENT 7
++ /**
++ * 0 - Rx S/PDIF Lock status has not changed.
++ * 1 - Rx S/PDIF Lock status has changed. (Note that this bit must be
++ * written to with a \911\92 to clear)
++ */
++#define RX_STATUS_HW_WRITE 8
++ /**
++ * 0 - H/W Write of FIFO has not occurred.
++ * 1 - H/W Write of FIFO has occurred. (Note that this bit must be written
++ * to with a \911\92 to clear)
++ */
++#define RX_STATUS_BUFFER_LEVEL_MET 9
++ /**
++ * 0 - Fill level of FIFO does not match BUFFER_INTERRUPT_LEVEL.
++ * 1 - Fill level of FIFO matches BUFFER_INTERRUPT_LEVEL
++ */
++#define RX_STATUS_SPDIF_LOCK 10
++ /**
++ * 0 - Rx S/PDIF timing is not locked.
++ * 1 - Rx S/PDIF timing is locked.
++ */
++
++
++/* TX_DEBUG ------------ */
++#define TX_DEBUG_TX_DMA_STATE 0
++ /**
++ * 00 - START
++ * 01 - IDLE
++ * 10 - BURST
++ * 11 - NON_ALIGNED
++ */
++#define TX_DEBUG_WRITE_OFFSET 4
++ /**
++ * Write Offset Determines the alignment of the writes
++ * (0=quad aligned; 1/3=bytes aligned; 2 doublet aligned)
++ */
++#define TX_DEBUG_TX_DREQ 31
++ /**
++ * Set if DMA request for Tx is set
++ */
++
++
++/* TX_DEBUG2 ------------ */
++#define TX_DEBUG2_TX_CTRL_STATE 0
++ /**
++ * 000 - WAITING
++ * 001 - WAITING_HALF
++ * 010 - Invalid
++ * 011 - WAIT_LEFT
++ * 100 - READ_FIFO
++ * 101 - WAIT_TILL_DATA_TAKEN
++ * 11x - Invalid
++ */
++#define TX_DEBUG2_FIFO_READER_2ND_STAGE 3
++ /**
++ * 0 - First stage (L) of FIFO read
++ * 1 - Second stage (R) of FIFO read
++ */
++#define TX_DEBUG2_FIFO_READER_CHANNEL 4
++ /**
++ * Current channel being read from FIFO
++ */
++#define TX_DEBUG2_NUM_WRITES 8
++ /**
++ * Number of writes to be performed every interrupt
++ */
++#define TX_DEBUG2_SAFE_TO_UPDATE_REGS 12
++ /**
++ * 0 - Changes to registers will be deferred
++ * 1 - Changes to registers will be immediate
++ */
++#define TX_DEBUG2_WR_DMARQ 13
++ /**
++ * 0 - No writes being requested
++ * 1 - Writes being requested (=DMA DREQ when using APB)
++ */
++#define TX_DEBUG2_FIFO_READ_ADDRESS 16
++ /**
++ * 19 - 16 Current read pointer of FIFO
++ */
++#define TX_DEBUG2_FIFO_WRITE_ADDRESS 24
++ /**
++ * 27 - 24 Current write pointer of FIFO
++ */
++#define TX_DEBUG2_WORD_CLK 31
++ /**
++ * State of internal safe TX_WORD_CLK
++ */
++
++
++/* TX_DEBUG3 ------------ */
++/**
++ * This register is a read back of status directly from the TX_CLK domain.
++ * For this reason it may be unstable during operation. Several back-to-back
++ * reads might need to be made to get an accurate reflection of the status
++ * during operation.
++ */
++
++#define TX_DEBUG3_TX_STATE 0
++ /**
++ * 000 - DISABLED
++ * 001 - WAITING
++ * 010 - WAIT_FOR_8
++ * 011 - SAMPLE_8
++ * 100 - WAIT_FOR_LEFT
++ * 101 - SAMPLE_LEFT
++ * 110 - WAIT_FOR_RIGHT
++ * 111 - SAMPLE_RIGHT
++ */
++#define TX_DEBUG3_TX_IN_RESET 31
++ /**
++ * 0 - Tx domain is out of reset
++ * 1 - Tx domain is in reset
++ */
++
++
++
++/* RX_DEBUG ------------ */
++#define RX_DEBUG_RX_DMA_STATE 0
++ /**
++ * 00 - START
++ * 01 - IDLE
++ * 10 - BURST
++ * 11 - NON_ALIGNED
++ */
++#define RX_DEBUG_READ_OFFSET 4
++ /**
++ * 5 - 4 Determines the alignment of the reads
++ * (0=quad aligned; 1/3=bytes aligned; 2 doublet aligned)
++ */
++#define RX_DEBUG_RX_DREQ 31
++ /**
++ * Set if DMA request for Rx is set
++ */
++
++
++/* RX_DEBUG2 ------------ */
++#define RX_DEBUG2_RX_CTRL_STATE 0
++ /**
++ * 000 - WAITING
++ * 001 - WAITING_HALF
++ * 01x - Invalid
++ * 100 - WRITE_FIFO
++ * 101 - WAIT_TILL_DATA_PUT
++ * 11x - Invalid
++ */
++#define RX_DEBUG2_FIFO_WRITER_2ND_STAGE 3
++ /**
++ * 0 - First stage (L) of FIFO write
++ * 1 - Second stage (R) of FIFO write
++ */
++#define RX_DEBUG2_FIFO_WRITER_CHANNEL 4
++ /**
++ * 7 - 4 Current channel being written to FIFO
++ */
++#define RX_DEBUG2_NUM_READS 8
++ /**
++ * 11 - 8 Number of reads to be performed every interrupt
++ */
++#define RX_DEBUG2_SAFE_TO_UPDATE_REGS 12
++ /**
++ * 0 - Changes to registers will be deferred
++ * 1 - Changes to registers will be immediate
++ */
++#define RX_DEBUG2_RD_DMARQ 13
++ /**
++ * 0 - No reads being requested
++ * 1 - Reads being requested (=DMA DREQ when using APB)
++ */
++#define RX_DEBUG2_FIFO_READ_ADDRESS 16
++ /**
++ * 19 - 16 Current read pointer of FIFO
++ */
++#define RX_DEBUG2_FIFO_WRITE_ADDRESS 24
++ /**
++ * 27 - 24 Current write pointer of FIFO
++ */
++#define RX_DEBUG2_WORD_CLK 31
++ /**
++ * State of internal safe RX_WORD_CLK
++ */
++
++
++/* RX_DEBUG3 ------------ */
++/**
++ * This register is a read back of status directly from the RX_CLK domain.
++ * For this reason it may be unstable during operation. Several back-to-back
++ * reads might need to be made to get an accurate reflection of the status
++ * during operation.
++ */
++
++#define RX_DEBUG3_RX_STATE 0
++ /**
++ * 000 - DISABLED
++ * 001 - WAITING
++ * 010 - WAIT_FOR_8
++ * 011 - SAMPLE_8
++ * 100 - WAIT_FOR_LEFT
++ * 101 - SAMPLE_LEFT
++ * 110 - WAIT_FOR_RIGHT
++ * 111 - SAMPLE_RIGHT
++ */
++#define RX_DEBUG3_RX_IN_RESET 31
++ /**
++ * 0 - Rx domain is out of reset
++ * 1 - Rx domain is in reset
++ */
++
++
++/**
++ * VERSION* ------------
++ * Refer to VERSION. ??
++ */
++
++
++/* TX_BUFFER_LEVEL ------------ */
++/**
++ * When this register is read it returns the current fill level of the buffer
++ * within the audio core, when a \911\92 is written to the lower bit, the buffer
++ * fill level, read and write pointers are all set to zero.
++ * FT - 0 Buffer Level Fill level of Tx buffer
++ */
++
++/**
++ * INTERRUPT_CONTROL* ------------
++ * Refer to INTERRUPT_CONTROL_STATUS. ??
++ */
++
++/* TX_BUFFER_INTERRUPT_LEVEL ------------ */
++/**
++ * FT - 0 Interrupt Level Programmable Buffer Level to initiate Interrupt
++ */
++
++
++/* RX_BUFFER_LEVEL ------------ */
++/**
++ * When this register is read it returns the current fill level of the buffer
++ * within the audio core, when a \911\92 is written to the lower bit, the buffer
++ * fill level, read and write pointers are all set to zero.
++ * FR - 0 Buffer Level Fill level of Rx buffer
++ */
++
++
++/* RX_BUFFER_INTERRUPT_LEVEL ------------ */
++/**
++ * FR - 0 Interrupt Level Programmable Buffer Level to initiate Interrupt
++ */
++
++
++/* RX_SPDIF_DEBUG ------------ */
++#define RX_SPDIF_DEBUG_MAX_PULSE 0
++ /**
++ * 7 - 0 Number of cycles of RX_SPDIF_OSAMP_CLK in maximum pulse width
++ * detected (=1.5x BIT_CLK)
++ */
++#define RX_SPDIF_DEBUG_MIN_PULSE 8
++ /**
++ * 15 - 8 Number of cycles of RX_SPDIF_OSAMP_CLK in minimum pulse width
++ * detected (=0.5x BIT_CLK)
++ */
++#define RX_SPDIF_DEBUG_VALID 16
++ /**
++ * 0 - Min Pulse is not valid (<2) for doing recovery
++ * 1 - Min Pulse is valid (?2) and recovery is possible
++ */
++#define RX_SPDIF_DEBUG_LOCK 17
++ /**
++ * 0 - Rx S/PDIF timing is not locked.
++ * 1 - Rx S/PDIF timing is locked.
++ */
++#define RX_SPDIF_DEBUG_NO_PULSE 18
++ /**
++ * 0 - Pulse detected
++ * 1 - Pulse detection has timed out
++ */
++#define RX_SPDIF_DEBUG_BLOCK_START 20
++ /**
++ * 0 - Current frame is not at start of block
++ * 1 - Current frame is at start of block
++ */
++#define RX_SPDIF_DEBUG_CHAN_A 21
++ /**
++ * 0 - Current subframe is B
++ * 1 - Current subframe is A
++ */
++
++
++/* RX_SPDIF_DEBUG2 ------------ */
++#define RX_SPDIF_DEBUG2_FRAME 0
++ /**
++ * 7 - 0 Current frame counter (0 to 191)
++ */
++#define RX_SPDIF_DEBUG2_BLOCK_SYNC 8
++ /**
++ * 0 - Not yet achieved block sync
++ * 1 - Block sync has been achieved (i.e. received a start of block)
++ */
++
++
++/* INTERRUPT_CONTROL_STATUS ------------ */
++#define INTERRUPT_CONTROL_STATUS_AUDIO_IRQ 0
++ /**
++ * ** BACKWARDS COMPATIBLE, DO NOT USE
++ * Set if the Audio Core Interrupt is set. Write \910\92 to clear
++ */
++#define INTERRUPT_CONTROL_STATUS_AUTO_CLEAR 2
++ /**
++ * 0 - Auto Clear disabled
++ * 1 - Auto clear of H/W read/write interrupt on next data write/read (Tx/Rx)
++ */
++#define INTERRUPT_CONTROL_STATUS_TX_IRQ 8
++ /**
++ * Set if the Audio Core Tx Interrupt is set
++ * Set to \911\92 to trigger a Normal Interrupt (TX_READ/RX_WRITE IRQ Enable
++ * must be set)
++ */
++#define INTERRUPT_CONTROL_STATUS_TX_ERR_IRQ 9
++ /**
++ * Set if the Audio Core Tx Error Interrupt is set
++ * Set to \911\92 to trigger an Error Interrupt (TX_URUN/RX_ORUN IRQ Enable
++ * must be set)
++ */
++#define INTERRUPT_CONTROL_STATUS_RX_IRQ 16
++ /**
++ * Set if the Audio Core Rx Interrupt is set
++ * Set to \911\92 to trigger a Normal Interrupt (RX_WRITE/TX_READ IRQ Enable
++ * must be set)
++ */
++#define INTERRUPT_CONTROL_STATUS_RX_ERR_IRQ 17
++ /**
++ * Set if the Audio Core Rx Error Interrupt is set
++ * Set to \911\92 to trigger an Error Interrupt (RX_ORUN/TX_URUN IRQ Enable must
++ * be set)
++ */
++
++
++/* INTERRUPT_MASK ------------ */
++#define INTERRUPT_MASK_TX_READ_IRQ_ENABLE 0
++ /**
++ * 0 - No Normal Interrupt generated by TX_READ
++ * 1 - Normal Interrupt generated by TX_READ
++ */
++#define INTERRUPT_MASK_TX_LEVEL_IRQ_ENABLE 1
++ /**
++ * 0 - No Normal Interrupt generated by TX_BUFFER_LEVEL
++ * 1 - Normal Interrupt generated by TX_BUFFER_LEVEL
++ */
++#define INTERRUPT_MASK_TX_ERROR_IRQ_ENABLE 2
++ /**
++ * 0 - No Normal Interrupt generated by TX_ERROR
++ * 1 - Normal Interrupt generated by TX_ERROR
++ */
++#define INTERRUPT_MASK_RX_WRITE_IRQ_ENABLE 8
++ /**
++ * 0 - No Normal Interrupt generated by RX_WRITE
++ * 1 - Normal Interrupt generated by RX_WRITE
++ */
++#define INTERRUPT_MASK_RX_LEVEL_IRQ_ENABLE 9
++ /**
++ * 0 - No Normal Interrupt generated by RX_BUFFER_LEVEL
++ * 1 - Normal Interrupt generated by RX_BUFFER_LEVEL
++ */
++#define INTERRUPT_MASK_RX_ERROR_IRQ_ENABLE 10
++ /**
++ * 0 - No Normal Interrupt generated by RX_ERROR
++ * 1 - Normal Interrupt generated by RX_ERROR
++ */
++#define INTERRUPT_MASK_TX_URUN_IRQ_ENABLE 16
++ /**
++ * 0 - No Error Interrupt generated by Tx Underrun
++ * 1 - Error Interrupt generated by Tx Underrun
++ */
++#define INTERRUPT_MASK_TX_ORUN_IRQ_ENABLE 17
++ /**
++ * 0 - No Error Interrupt generated by Tx Overrun
++ * 1 - Error Interrupt generated by Tx Overrun
++ */
++#define INTERRUPT_MASK_TX_FIFO_URUN_ERR_IRQ_ENABLE 18
++ /**
++ * 0 - No Error Interrupt generated by Tx FIFO Underrun
++ * 1 - Error Interrupt generated by Tx FIFO Underrun
++ */
++#define INTERRUPT_MASK_TX_FIFO_ORUN_ERR_IRQ_ENABLE 19
++ /**
++ * 0 - No Error Interrupt generated by Tx FIFO Overrun
++ * 1 - Error Interrupt generated by Tx FIFO Overrun
++ */
++#define INTERRUPT_MASK_RX_URUN_ERR_IRQ_ENABLE 24
++ /**
++ * 0 - No Error Interrupt generated by Rx Underrun
++ * 1 - Error Interrupt generated by Rx Underrun
++ */
++#define INTERRUPT_MASK_RX_ORUN_ERR_IRQ_ENABLE 25
++ /**
++ * 0 - No Error Interrupt generated by Rx Overrun
++ * 1 - Error Interrupt generated by Rx Overrun
++ */
++#define INTERRUPT_MASK_RX_FIFO_URUN_ERR_IRQ_ENABLE 26
++ /**
++ * 0 - No Error Interrupt generated by Rx FIFO Underrun
++ * 1 - Error Interrupt generated by Rx FIFO Underrun
++ */
++#define INTERRUPT_MASK_RX_FIFO_ORUN_ERR_IRQ_ENABLE 27
++ /**
++ * 0 - No Error Interrupt generated by Rx FIFO Overrun
++ * 1 - Error Interrupt generated by Rx FIFO Overrun
++ */
++#define INTERRUPT_MASK_SPDIF_RX_ERROR 28
++ /**
++ * 0 - No Error Interrupt generated by Rx S/PDIF Error (Parity/Preamble/Framing)
++ * 1 - Error Interrupt generated by Rx S/PDIF Error (Parity/Preamble/ Framing)
++ */
++#define INTERRUPT_MASK_SPDIF_RX_LOCK 29
++ /**
++ * 0 - No Error Interrupt generated by Rx S/PDIF Lock event
++ * 1 - Error Interrupt generated by Rx S/PDIF Lock event
++ */
++
++
++/* VERSION ------------ */
++/**
++ * Returns a 32 bit value that indicates the version and build options of the
++ * audio core being used. See the version list at the end of the document to
++ * find out how they translate.
++ */
++
++#define VERSION_NUMBER 0
++ /**
++ * 0 - 7 Version of the core
++ */
++#define VERSION_AUX_APB 12
++ /**
++ * AUX_APB build option
++ */
++#define VERSION_RX_SPDIF 13
++ /**
++ * RX_SPDIF build option
++ */
++#define VERSION_TX_SPDIF 14
++ /**
++ * TX_SPDIF build option
++ */
++#define VERSION_AHB_DMA 15
++ /**
++ * DMA_AHB build option
++ */
++#define VERSION_RX_FIFO_ADDR_BITS 19
++ /**
++ * 16 - 19 G_RX_FIFO_A_BITS generic
++ */
++#define VERSION_RX_CHANS 23
++ /**
++ * 20 - 23 G_RX_CHANNELS generic
++ */
++#define VERSION_TX_FIFO_ADDR_BITS 27
++ /**
++ * 24 - 27 G_TX_FIFO_A_BITS generic
++ */
++#define VERSION_TX_CHANS 31
++ /**
++ * 28 - 31 G_TX_CHANNELS generic
++ */
++
++
++
++/* TX_DATA_IN_FORMAT ------------ */
++#define TX_DATA_IN_FORMAT_SAMPLE_ORDER 0
++ /**
++ * 0 - Samples written in as left/right pairs
++ * 1 - All left channels written then all right
++ */
++#define TX_DATA_IN_FORMAT_24_BIT_SAMPLE 1
++ /**
++ * Set to \911\92 to indicate write contains 24 bit data (used in conjunction
++ * with following setting)
++ * ** NOT VALID FOR S/PDIF
++ */
++#define TX_DATA_IN_FORMAT_PAD_TOP_BYTE 2
++ /**
++ * 0 - Output data becomes WRITE_DATA(23 downto 0) & \9300000000\94
++ * 1 - Output data becomes \930000000\94 & WRITE_DATA(23 downto 0)
++ */
++#define TX_DATA_IN_FORMAT_WAIT_FOR_HALF 4
++ /**
++ * 0 - Hardware waits for full number of writes before progressing
++ * 1 - Hardware waits for half the number of writes before progressing
++ */
++
++
++/* TX_CHANNELS_ENABLE ------------ */
++/**
++ * If a channel is disabled, then no new data is presented to the data line of
++ * that I2S channel
++ * 0 - Tx Channel N disabled
++ * 1 - Tx Channel N enabled
++ */
++
++
++/* TX_WRITES_TO ------------ */
++/**
++ * Can be used in conjunction with the Tx Channel Enable, whereby if an output
++ * channel is disabled then software can select whether or not it still wishes
++ * to write to this channel or not, effectively reduces its number of writes
++ * per interrupt. If it chooses to still write to this location then the write
++ * data is effectively ignored.
++ * 0 - Tx Channel N not included in data
++ * 1 - Tx Channel N included in data
++ */
++
++
++/* RX_DATA_OUT_FORMAT ------------ */
++#define RX_DATA_OUT_FORMAT_SAMPLE_ORDER 0
++ /**
++ * 0 - Samples read in as left/right pairs
++ * 1 - All left channels read then all right
++ */
++#define RX_DATA_OUT_FORMAT_24_BIT_SAMPLE 1
++ /**
++ * Set to \911\92 to indicate read contains 24 bit data (used in conjunction
++ * with following setting)
++ * ** NOT VALID FOR S/PDIF
++ */
++#define RX_DATA_OUT_FORMAT_PAD_TOP_BYTE 2
++ /**
++ * 0 - Read data becomes RX_DATA(23 downto 0) & \9300000000\94
++ * 1 - Read data becomes \930000000\94 & RX_DATA(23 downto 0)
++ */
++#define RX_DATA_OUT_FORMAT_WAIT_FOR_HALF 4
++ /**
++ * 0 - Hardware waits for full number of reads before progressing
++ * 1 - Hardware waits for half the number of reads before progressing
++ */
++
++
++/* RX_CHANNELS_ENABLE ------------ */
++/**
++ * If a channel is disabled, then no new data is presented to the data line of
++ * that I2S channel
++ * 0 - Rx Channel N disabled
++ * 1 - Rx Channel N enabled
++ */
++
++
++/* RX_READS_FROM ------------ */
++/**
++ * Can be used in conjunction with the Rx Channel Enable, whereby if an input
++ * channel is disabled then software can select whether or not it still wishes
++ * to read from this channel or not, effectively reduces its number of reads
++ * per interrupt. If it chooses to still read from this location then the read
++ * data is invalid.
++ * 0 - Rx Channel N not included in data
++ * 1 - Rx Channel N included in data
++ */
++
++
++
++/* TX_CPU_DATA_WRITES_ALT ------------ */
++/**
++ * See TX_CPU_DATA_WRITES.
++ * This alternative address has been provided as it may be referenced within a
++ * 13 bit immediate address (which may have benefits when being accessed by a
++ * CPU with only a 13 bit immediate offset such as the LEON2 IU).
++ * 0x0400-0x04FF TX_CPU_DATA_WRITES_ALT
++ */
++
++
++/* RX_CPU_DATA_READS_ALT ------------ */
++/**
++ * See RX_CPU_DATA_READS. This alternative address has been provided as it may
++ * be referenced within a 13 bit immediate address (which may have benefits
++ * when being accessed by a CPU with only a 13 bit immediate offset such as the
++ * LEON2 IU).
++ * 0x0800-0x08FF RX_CPU_DATA_READS_ALT
++ */
++
++
++/* TX_CPU_DATA_WRITES ------------ */
++/**
++ * Any writes to this location writes a valid sample into the internal buffer
++ * of the audio core. All writes should be the full 32 bits.
++ * This address is WRITE ONLY - any reads will return the previous read value
++ * on the bus.
++ * 0x1000-0x1FFF TX_CPU_DATA_WRITES
++ */
++
++
++/* RX_CPU_DATA_READS ------------ */
++/**
++ * Any reads from this location read a valid sample from the internal buffer of
++ * the audio core. All reads should be the full 32 bits.
++ * This address is READ ONLY - any writes will be ignored.
++ * 0x2000-0x2FFF RX_CPU_DATA_READS
++ */
++
++#endif /* __ASM_ARM_ARCH_I2S_H */
++
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/io.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/io.h
+--- linux-2.6.24/include/asm-arm/arch-oxnas/io.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/io.h 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,17 @@
++/*
++ * linux/include/asm-arm/arch-oxnas/io.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.
++ */
++
++#ifndef __ASM_ARM_ARCH_IO_H
++#define __ASM_ARM_ARCH_IO_H
++
++#define IO_SPACE_LIMIT 0xffffffff
++
++#define __io(a) ((void __iomem*)(a))
++#define __mem_pci(a) (a)
++
++#endif //__ASM_ARM_ARCH_IO_H
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/irqs.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/irqs.h
+--- linux-2.6.24/include/asm-arm/arch-oxnas/irqs.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/irqs.h 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,42 @@
++/* linux/include/asm-arm/arch-oxnas/irqs.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.
++ */
++
++#ifndef __ASM_ARCH_IRQS_H
++#define __ASM_ARCH_IRQS_H
++
++#define FIQ_INTERRUPT 0
++#define SOFTWARE_INTERRUPT 1
++#define TIMER_1_INTERRUPT 4
++#define TIMER_2_INTERRUPT 5
++#define USB_FS_INTERRUPT 7
++#define MAC_INTERRUPT 8
++#define SEM_A_INTERRUPT 10
++#define SEM_B_INTERRUPT 11
++#define DMA_INTERRUPT_0 13
++#define DMA_INTERRUPT_1 14
++#define DMA_INTERRUPT_2 15
++#define DMA_INTERRUPT_3 16
++#define DPE_INTERRUPT 17
++#define SATA_1_INTERRUPT 18
++#define SATA_2_INTERRUPT 19
++#define DMA_INTERRUPT_4 20
++#define GPIO_1_INTERRUPT 21
++#define GPIO_2_INTERRUPT 22
++#define UART_1_INTERRUPT 23
++#define UART_2_INTERRUPT 24
++#define I2S_INTERRUPT 25
++#define SATA_1_ERROR 26
++#define SATA_2_ERROR 27
++#define I2C_INTERRUPT 28
++#define UART_3_INTERRUPT 29
++#define UART_4_INTERRUPT 30
++
++#define PCI_A_INTERRUPT GPIO_1_INTERRUPT
++
++#define NR_IRQS 32
++
++#endif // __ASM_ARCH_IRQ_H
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/leon-power-button-prog.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/leon-power-button-prog.h
+--- linux-2.6.24/include/asm-arm/arch-oxnas/leon-power-button-prog.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/leon-power-button-prog.h 2008-07-01 09:46:51.000000000 +0200
+@@ -0,0 +1,73 @@
++static const s8 leon_srec[] =
++"S01400006C656F6E2D706F7765722D627574746F6E1A\n"
++"S3159801E00081D820000326007881984000821020C08C\n"
++"S3159801E010818840008190000003116C008210601481\n"
++"S3159801E020213D4040A014200FE02040001D26007F8E\n"
++"S3159801E0309C13A3F0BC10000E8E1000008C100000EB\n"
++"S30D9801E0404000004501000000B3\n"
++"S3159801E110A7480000A8100001AA100002AC1000033D\n"
++"S3159801E120AE100004A14000009C10001E400000EAB9\n"
++"S3159801E13001000000818400008810001786100016DF\n"
++"S3159801E1408410001582100014818CC00081C440008F\n"
++"S3099801E15081CC80005F\n"
++"S3159801E1549C03BFB8FE23A020BE23BFB8DE23A02408\n"
++"S3159801E164E03BA028E43BA030E823A03803160076C8\n"
++"S3159801E17484102030821063FCC42840002511500075\n"
++"S3159801E18486103FFF8214A00CC62040008414A10C6B\n"
++"S3159801E1940316007FC6208000821063FC4000008924\n"
++"S3159801E1A4E600400090102000921020004000008E56\n"
++"S3159801E1B4941023E88210200083306008821060202E\n"
++"S3159801E1C4A21020FFA3346008A1480000A02C0011D6\n"
++"S3159801E1D4A0140001818C0000A0102010A414A0089A\n"
++"S3159801E1E4E0248000400000950100000009114000D8\n"
++"S3159801E1F49A11200CC203400082087FFEC223400074\n"
++"S3159801E20498112014C203000082087FFEC2230000DD\n"
++"S3159801E2148811208CC201000082087FFEC221000069\n"
++"S3159801E224C40340008408BFEFC4234000C20300001E\n"
++"S3159801E23482087FEFC2230000C40100008408BFEF5F\n"
++"S3159801E244C4210000073F7FFFC20340008610E3FF05\n"
++"S3159801E25482084003C2234000C40300008408800353\n"
++"S3159801E264C4230000C201000082084003C2210000B1\n"
++"S3159801E2741B1100008610200188136014C621000022\n"
++"S3159801E2848213601CC620400084136020E02080001D\n"
++"S3159801E29480A4E0000280003C030080008413601887\n"
++"S3159801E2A4C2208000071100008410E01C030080003E\n"
++"S3159801E2B4C2208000A8100003C2050000808860105F\n"
++"S3159801E2C40280000DA0102000C2050000808860100D\n"
++"S3159801E2D41280000925000009231100004000005E00\n"
++"S3159801E2E49014A310C20440008088601002BFFFFCFA\n"
++"S3159801E2F40100000023000009251100004000005682\n"
++"S3159801E30490146310C20480008088601012800021E2\n"
++"S3159801E31480A42031A004200180A4203104BFFFF8F1\n"
++"S3159801E324031100000500800080A4E0001280000516\n"
++"S3159801E3348210601403110000050080008210601891\n"
++"S3159801E344C420400023000009A01020634000004225\n"
++"S3159801E35490146310A0843FFF1CBFFFFD031600763B\n"
++"S3159801E364821063FC84102031C428400003110000F4\n"
++"S3159801E3748610200182106018C62040001080000083\n"
++"S3159801E38401000000C221000010BFFFC80711000058\n"
++"S3159801E39404BFFFCA0311000010BFFFE40500800003\n"
++"S3159801E3A49C07FFB8FE03A020DE03A024E01BA02847\n"
++"S3159801E3B4E41BA030E803A03881C3E0089C23BFB8C6\n"
++"S3159801E3C4051150008610A20882102044C220C0006C\n"
++"S3159801E3D48410A22882102088C220800081C3E00874\n"
++"S3159801E3E401000000932A601003000061821062A064\n"
++"S3159801E3F493326010925A4001952AA010030005F5AC\n"
++"S3159801E40482106384900A20FF9532A010905A0001D5\n"
++"S3159801E41493326006945AA320900200099532A00972\n"
++"S3159801E424031150009002000A82106200D020400025\n"
++"S3159801E43481C3E00801000000051150008410A20868\n"
++"S3159801E444C200800082106080C220800081C3E008E7\n"
++"S3159801E4540100000003041893821061D380520001CD\n"
++"S3159801E46491400000913220068810000682380008EF\n"
++"S3159801E47480A040041A80000D8401000882020004D9\n"
++"S3159801E484900060018210000680A0400486603FFFD8\n"
++"S3159801E49480A2000184603FFF8090C00212BFFFFAF8\n"
++"S3159801E4A401000000308000098210000680A0400215\n"
++"S3159801E4B41A800006010000008210000680A040021E\n"
++"S3159801E4C40ABFFFFA0100000081C3E00801000000B9\n"
++"S3159801E4D405115000C200800080A060000280000BE4\n"
++"S3159801E4E48610A20C80886010028000040100000046\n"
++"S3159801E4F4C020C0008C01A001C200800080A06000E9\n"
++"S3159801E50412BFFFFA8088601081C3E00801000000F9\n"
++"S7059801E00081\n";
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/leon-program.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/leon-program.h
+--- linux-2.6.24/include/asm-arm/arch-oxnas/leon-program.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/leon-program.h 2008-07-01 09:46:44.000000000 +0200
+@@ -0,0 +1,404 @@
++static const s8 leon_srec[] =
++"S00700006C656F6E4A\n"
++"S3159801E00081D820000326007881984000821020C08C\n"
++"S3159801E010818840008190000003116C008210601481\n"
++"S3159801E020213FC040A014200FE02040001D26007F0C\n"
++"S3159801E0309C13A3F0BC10000E8E1000008C100000EB\n"
++"S30D9801E0404000005A010000009E\n"
++"S3159801E050051150008410A208C200800082106080C9\n"
++"S3159801E060C220800081C3E00801000000051150001C\n"
++"S3159801E0708610A20882102044C220C0008410A228CB\n"
++"S3159801E08082102088C220800081C3E0080100000028\n"
++"S3159801E110A7480000A8100001AA100002AC1000033D\n"
++"S3159801E120AE100004A14000009C10001E4000007F24\n"
++"S3159801E13001000000818400008810001786100016DF\n"
++"S3159801E1408410001582100014818CC00081C440008F\n"
++"S3099801E15081CC80005F\n"
++"S3159801E154932A601003000061821062A093326010C2\n"
++"S3159801E164925A4001952AA010030005F582106384FA\n"
++"S3159801E174900A20FF9532A010905A000193326006B6\n"
++"S3159801E184945AA320900200099532A00903115000CC\n"
++"S3159801E1949002000A82106200D020400081C3E008F0\n"
++"S3159801E1A4010000009C03BFB8FE23A020BE23BFB87C\n"
++"S3159801E1B4DE23A024E03BA028E43BA030033D404065\n"
++"S3159801E1C48210600FA610200021116C00A01420144F\n"
++"S3159801E1D4C2240000400001BF2511500086103FFF5C\n"
++"S3159801E1E48214A00CC62040008414A10CC620800079\n"
++"S3159801E1F47FFFFF9E010000009010200092102000DE\n"
++"S3159801E2047FFFFFD4941023E8400001A30100000086\n"
++"S3159801E2148A1000130326007EC60061700926007EC3\n"
++"S3159801E224841061708211219CDA00A004C6206008CA\n"
++"S3159801E234C621219C400001D5DA206004A734E00860\n"
++"S3159801E244A614E020A21020FFA3346008A148000078\n"
++"S3159801E254A02C0011A0140013818C000082102010A8\n"
++"S3159801E264A414A008C224800084102400C424800025\n"
++"S3159801E27482102100C22480004000055C0100000040\n"
++"S3159801E2847FFFFF73010000008210000780A06000E1\n"
++"S3159801E29402BFFFFEA6100001308000071280000F0E\n"
++"S3159801E2A40100000082100007A690600002BFFFF7E4\n"
++"S3159801E2B4010000008E29C013808CE00202BFFFF88A\n"
++"S3159801E2C4808CE0014000020001000000808CE0018E\n"
++"S3159801E2D402BFFFF5010000004000025B0100000047\n"
++"S3159801E2E430BFFFF19C07FFB8FE03A020DE03A024EC\n"
++"S3159801E2F4E01BA028E41BA03081C3E0089C23BFB887\n"
++"S3159801E3049801E6949801E7A09801E7689801E724AB\n"
++"S3159801E3149801E6B49801E8589801E83C9801E7EC25\n"
++"S3159801E3249801E7C49C03BFA0FE23A020BE23BFA0E7\n"
++"S3159801E334DE23A024E03BA028E43BA030E83BA038A8\n"
++"S3159801E34403115000E400400080A4A0000280014A11\n"
++"S3159801E354808CA1000280004E808CA01007101004B6\n"
++"S3159801E364C400E014C200E01C88088001808920104A\n"
++"S3159801E3749A1020009810200002800003841020002F\n"
++"S3159801E3848410201080892080328000028410A08015\n"
++"S3159801E39480892040328000028410A04080A0A00089\n"
++"S3159801E3A40280000603000060C200E01C8228400235\n"
++"S3159801E3B4C220E01C03000060821100010500006080\n"
++"S3159801E3C4C220E014882900028143C000C2000000DB\n"
++"S3159801E3D480892401028000068089202882102002DF\n"
++"S3159801E3E48E11C00188093BFE808920280280000984\n"
++"S3159801E3F480892002821020028E11C001808920080A\n"
++"S3159801E40422800003981020019A1020018089200205\n"
++"S3159801E414128000060310100480A360000280007F16\n"
++"S3159801E42480A3200003101004C40060180700000894\n"
++"S3159801E43484108003C4206018821000058210400459\n"
++"S3159801E4448A100001091140008211204CC400400031\n"
++"S3159801E4548088A1001280000E808CA0100326007E6D\n"
++"S3159801E464C600617884100005C420C0008143C000A9\n"
++"S3159801E474C20000008410210086112050C420C000D7\n"
++"S3159801E484821020008A100001808CA0100280001C42\n"
++"S3159801E494808CA400031150008210620CC0204000A5\n"
++"S3159801E4A48C01A0018210000580A0600002800014EE\n"
++"S3159801E4B4808CA400091140008211204CC4004000AC\n"
++"S3159801E4C48088A1001280000E808CA4000326007E09\n"
++"S3159801E4D4C600617884100005C420C0008143C00039\n"
++"S3159801E4E4C20000008410210086112050C420C00067\n"
++"S3159801E4F4821020008A100001808CA40002800039C1\n"
++"S3159801E50403000400031140008410604CE600800067\n"
++"S3159801E51482106054840CE003C4204000808CE0018E\n"
++"S3159801E5240280002B808CE0022326007EAA07FFF442\n"
++"S3159801E534A007FFF0A807FFEC9A14619C96103FFF79\n"
++"S3159801E544C8036008108000051908000080A2E0003D\n"
++"S3159801E55402800011C4236008C601000080A0E0006F\n"
++"S3159801E564168000178088C00C028000418401200817\n"
++"S3159801E574C2036004C624000080A0800112BFFFF480\n"
++"S3159801E58488100002C803400080A2E00012BFFFF37E\n"
++"S3159801E594C8236008C807FFF080A1200818800024C2\n"
++"S3159801E5A40720000005260078832920028410A304F5\n"
++"S3159801E5B4C600800181C0C0000100000080A2E0006D\n"
++"S3159801E5C402BFFFF5C6240000808CE0020280000594\n"
++"S3159801E5D403000400821020018E11C0010300040077\n"
++"S3159801E5E4808C8001028000080311500003115800A1\n"
++"S3159801E5F482106090C0204000841020048E11C002BD\n"
++"S3159801E60403115000E400400080A4A00012BFFF52F9\n"
++"S3159801E614808CA1003080009802BFFF8803101004F3\n"
++"S3159801E624C020600430BFFF850720000086290003B7\n"
++"S3159801E6349A14619CC807FFF48143C000C200000084\n"
++"S3159801E644C40360088400A008C2036004C6210000BC\n"
++"S3159801E65480A0800102800004C204619C10BFFFB7A8\n"
++"S3159801E664C423600810BFFFB5C22360080507FFFFDE\n"
++"S3159801E6748410A3FF031000008408C0028208C00115\n"
++"S3159801E684C8254000C225000010BFFFC3C42400005A\n"
++"S3159801E6940326007EC40061A880A0A000028000061B\n"
++"S3159801E6A4C207FFEC400000E401000000C807FFF030\n"
++"S3159801E6B4C207FFEC0708000080A0600002BFFFDBD9\n"
++"S3159801E6C486110003C807FFF4032000008410200173\n"
++"S3159801E6D48628C001C42120049A14619C8143C000F0\n"
++"S3159801E6E4C2000000C62100008143C000C200000098\n"
++"S3159801E6F4C40360088800A00803114000C603600497\n"
++"S3159801E7040500004082106050C420400080A1000397\n"
++"S3159801E71402BFFFD5C204619C10BFFF88C823600855\n"
++"S3159801E724C807FFF4C601200405101004C200A01CF2\n"
++"S3159801E7349A284003C207FFECDA20A01C80A0600047\n"
++"S3159801E74402800013C607FFF0030800008610C00173\n"
++"S3159801E754052000008628C002DA21200410BFFFE0B4\n"
++"S3159801E7649A14619CC807FFF4C60120040510100485\n"
++"S3159801E774C200A01C9A104003C207FFECDA20A01C21\n"
++"S3159801E78480A0600012BFFFF1C607FFF003200000C6\n"
++"S3159801E7948628C00110BFFFA99A14619C400000AF56\n"
++"S3159801E7A401000000C207FFEC80A060000280000C03\n"
++"S3159801E7B4C607FFF00308000010BFFFC38610C00107\n"
++"S3159801E7C4821023D005101004C607FFECC220A014AA\n"
++"S3159801E7D480A0E00012BFFFF8C607FFF003200000EF\n"
++"S3159801E7E410BFFF948628C001C807FFF4C20120040C\n"
++"S3159801E7F480A060000280001D05101004C200A018B4\n"
++"S3159801E80482106002C220A018C207FFEC80A06000A3\n"
++"S3159801E81402BFFFDFC607FFF0030800008610C00198\n"
++"S3159801E82405200000821020018628C002C2212004F6\n"
++"S3159801E83410BFFFAB9A14619CC207FFF4D000600421\n"
++"S3159801E8444000003301000000C207FFEC10BFFFD857\n"
++"S3159801E85480A060004000001201000000C207FFEC8E\n"
++"S3159801E86410BFFFD380A06000C200A01810BFFFE6B6\n"
++"S3159801E87482087FFD9C07FFA0FE03A020DE03A02447\n"
++"S3159801E884E01BA028E41BA030E81BA03881C3E0084C\n"
++"S3159801E8949C23BFA081C3E008010000000326007EE3\n"
++"S3159801E8A40526007EC60061988410A17088102009F7\n"
++"S3159801E8B4C200C000C22080008600E00488813FFF20\n"
++"S3159801E8C41CBFFFFC8400A00481C3E008010000007A\n"
++"S3159801E8D49C03BFD0FE23A01CBE23BFD0DE23A02059\n"
++"S3159801E8E40316007F821063FCC60040000526007E4D\n"
++"S3159801E8F47FFFFFEBC620A1989C07FFD0FE03A01CBF\n"
++"S3159801E904DE03A02081C3E0089C23BFD00310100422\n"
++"S3159801E914C6006018050000088428C002C42060183F\n"
++"S3159801E9248610000105001C00C200E014808840028C\n"
++"S3159801E93412BFFFFE80A22000228000090310100056\n"
++"S3159801E94407101000C400C00003000020822880012B\n"
++"S3159801E954C220C0001080000703101004C4004000B0\n"
++"S3159801E9640700002084108003C422000103101004B8\n"
++"S3159801E974C40060180700000884108003C420601836\n"
++"S3159801E98481C3E008010000009C03BFD0FE23A01CAC\n"
++"S3159801E994BE23BFD0DE23A020E023A0240326007E35\n"
++"S3159801E9A4821061701B26007E1926007E841361C429\n"
++"S3159801E9B4C600600C881321B4D60060102126007E07\n"
++"S3159801E9C4D0006014C621200CC02361C4C020A010B5\n"
++"S3159801E9D4C62321B4D6212004C020A004C020A008AF\n"
++"S3159801E9E4C020A00CC6212008400003A9D02421B038\n"
++"S3159801E9F4D02421B0400003BA921020360326007E13\n"
++"S3159801EA04D02421B0C02061A88143C000C20000006F\n"
++"S3159801EA140526007EC020A1ACD00421B09C07FFD066\n"
++"S3159801EA24FE03A01CDE03A020E003A02481C3E00812\n"
++"S3159801EA349C23BFD00526007EC200A1AC80A06000AD\n"
++"S3159801EA441280000482102001C220A1AC8E11C0014B\n"
++"S3159801EA5481C3E008010000009C03BFD0FE23A01CDB\n"
++"S3159801EA64BE23BFD0DE23A0207FFFFFC8010000008C\n"
++"S3159801EA748810201807101004C20100030500000825\n"
++"S3159801EA8482104002C2210003841020010326007ECD\n"
++"S3159801EA94C42061A89C07FFD0FE03A01CDE03A02016\n"
++"S3159801EAA481C3E0089C23BFD0832A2010913060103B\n"
++"S3159801EAB4900A20FF83306018912A200881C3E008C0\n"
++"S3159801EAC4901040089C03BFD8DE23A008F43BA010FD\n"
++"S3159801EAD4F83BA0180326007E3926007E961061D845\n"
++"S3159801EAE4BA1721C43526007EF60061D89010200005\n"
++"S3159801EAF49810000B9210001DC402E008C202E00CA3\n"
++"S3159801EB0480A0800102800032D406A1ECC200800064\n"
++"S3159801EB1480A0600026800047D426A1ECDA03200859\n"
++"S3159801EB2484036010C203200480A080010280003F00\n"
++"S3159801EB348610000CC4232008C200E01080A060004F\n"
++"S3159801EB4432800002C020E010DE034000030000205A\n"
++"S3159801EB54808BC00102800024808BE200028000052C\n"
++"S3159801EB64808BEC00C202600882006001C2226008B0\n"
++"S3159801EB7402800005808BE100C202600C820060016C\n"
++"S3159801EB84C222600C0280000501000000C2026010D6\n"
++"S3159801EB9482006010C2226010C203600C80A06000DB\n"
++"S3159801EBA422800007C402E008C203600CD4206008DE\n"
++"S3159801EBB4C020600494100001C402E008C202E00C6B\n"
++"S3159801EBC480A0800112BFFFD290102001C202E010EA\n"
++"S3159801EBD480A0600012BFFFCE0100000010800015CE\n"
++"S3159801EBE4D426A1ECC8036004C60721C4820927FF69\n"
++"S3159801EBF48600C001051000008089000202BFFFE764\n"
++"S3159801EC04C62721C48333E003C4076004C60760108A\n"
++"S3159801EC14820860078600C0018400A001C4276004A5\n"
++"S3159801EC2410BFFFDEC627601010BFFFC4F623200865\n"
++"S3159801EC34DE03A008F41BA010F81BA01881C3E008F2\n"
++"S3159801EC449C23BFD89C03BF40FE23A020BE23BF406C\n"
++"S3159801EC54DE23A024E03BA028E43BA030E83BA0387F\n"
++"S3159801EC64EC3BA040F03BA048F43BA050F83BA0589D\n"
++"S3159801EC740526007EC200A1A880A0600002800173C7\n"
++"S3159801EC840726007EC200E1AC80A060001280017064\n"
++"S3159801EC94010000003326007EB41661B4C606A008A6\n"
++"S3159801ECA4C210E01A8328601083306010808860024D\n"
++"S3159801ECB41280016680886001028001648800E08C74\n"
++"S3159801ECC4C210E01A82106002C406A00480A1000250\n"
++"S3159801ECD4028001F9C230E01AC826A008AE90E00075\n"
++"S3159801ECE42280015B0726007EC215E01A808860049B\n"
++"S3159801ECF432800028F005E0102326007EC405E0043E\n"
++"S3159801ED04C205E008A21461D8A6208001A0100002C9\n"
++"S3159801ED14E405E00CA8102000B8100011B605E01C13\n"
++"S3159801ED24B005E0641B26007EFA036168AA100013F5\n"
++"S3159801ED34AC100012E6160000E406C000B0062002E4\n"
++"S3159801ED44B606E004A0240015C204601080A06000F1\n"
++"S3159801ED541280000701000000C404600CC200800000\n"
++"S3159801ED6480A06000168000A69A00A0108210000761\n"
++"S3159801ED748288600202BFFFFE010000008E29C0014D\n"
++"S3159801ED847FFFFF510100000010BFFFF1C20460101C\n"
++"S3159801ED94C20E0000C405E00CC427FFB08208600FB8\n"
++"S3159801EDA483286002C80E2009842600028400800103\n"
++"S3159801EDB4860920FF80A0E006BA060001028001C3F5\n"
++"S3159801EDC4C437FFF680A0E011228001BE8400A00812\n"
++"S3159801EDD480A12006C027FFEC028001A0C027FFE886\n"
++"S3159801EDE4C417FFF6DA15E018C215E0168528A0109F\n"
++"S3159801EDF4DA27FFE080A36000C227FFE41280000CA3\n"
++"S3159801EE04C427FFB40326007EC617FFF6C40061889B\n"
++"S3159801EE148728E0108400A00E8330E01084208001B6\n"
++"S3159801EE249A102001C427FFE0DA27FFE4C607FFB446\n"
++"S3159801EE34E205E004C205E0088530E0108224400129\n"
++"S3159801EE4482204002C427FFCCDA07FFB0840340022C\n"
++"S3159801EE54C227FFD0C427FFD47FFFFF14D0162004FE\n"
++"S3159801EE64912A2010C607FFB09132201082102000F3\n"
++"S3159801EE74C407FFE48608E003C027FFBCD037FFC662\n"
++"S3159801EE8480A04002C027FFDCC027FFD816800099CE\n"
++"S3159801EE94C627FFACDA07FFCCA224400DC207FFE0D0\n"
++"S3159801EEA480A4400104800003E227FFB8C227FFB873\n"
++"S3159801EEB4D017FFC6912A20107FFFFEFC91322010AD\n"
++"S3159801EEC4C407FFB8C617FFF68200800382007FF253\n"
++"S3159801EED483286010D03620047FFFFEF491306010A9\n"
++"S3159801EEE4DA17FFC6C20E20099A036001D0362002AA\n"
++"S3159801EEF480A0600602800110DA37FFC680A06011EF\n"
++"S3159801EF0402800145C207FFB8C407FFB8C036200A74\n"
++"S3159801EF14C427FFDCA41000020726007EE200E1EC78\n"
++"S3159801EF2480A460000280002D84102004C204600825\n"
++"S3159801EF34C220E1ECC207FFB49B306010E0044000A4\n"
++"S3159801EF44820C200382208001C607FFAC84208003AB\n"
++"S3159801EF5480A04002DA246004C607FFB0028000CF7D\n"
++"S3159801EF64881000101080000698102000C22900000D\n"
++"S3159801EF74980320018600E0018801200180A3000DF1\n"
++"S3159801EF842ABFFFFBC208C0002726007EA614E1D833\n"
++"S3159801EF94C204E01080A060001280000701000000FE\n"
++"S3159801EFA4C204E00CC400400080A0A0003680014C45\n"
++"S3159801EFB41B26007E821000078288600202BFFFFE2C\n"
++"S3159801EFC4010000008E29C0017FFFFEBF01000000E9\n"
++"S3159801EFD410BFFFF1C204E010821000078288600214\n"
++"S3159801EFE402BFFFFE010000008E29C0017FFFFEB615\n"
++"S3159801EFF40100000010BFFFCA0726007EC20720043D\n"
++"S3159801F0048810000280A34001028001E99810001C2F\n"
++"S3159801F014C20120048208401DC2212004C40120048F\n"
++"S3159801F0248408B800C4212004872D6010C2012004E5\n"
++"S3159801F0348730E01082104003C2212004EC21200875\n"
++"S3159801F044C021200CC6012004031800008228C0019F\n"
++"S3159801F054C4032008C2212004841B400280A0000214\n"
++"S3159801F064C60120040306000084603FFF8228C0017C\n"
++"S3159801F074DA23200CC4232010C221200480A4200062\n"
++"S3159801F0841280000780A52000C20120040510000003\n"
++"S3159801F09482104002C221200480A52000028001BE6C\n"
++"S3159801F0A4010000008143C000C20000000320000053\n"
++"S3159801F0B4C401000084108001C421000080A42000AA\n"
++"S3159801F0C412BFFF1CAA1000138143C000C20000009E\n"
++"S3159801F0D403200000C405000084108001C4250000A3\n"
++"S3159801F0E48143C000C200000005101004C020A0048A\n"
++"S3159801F0F40726007E1B00003FC400E1C49A1363FFF0\n"
++"S3159801F10480A0800D8810E1C4088000048210000252\n"
++"S3159801F1141B26007EC403616C82204002C220E1C48E\n"
++"S3159801F124C425E088C401200480A0A03F0880000378\n"
++"S3159801F134821000028410203F82204002C2212004BA\n"
++"S3159801F1448528A010C205E08882104002C225E0886D\n"
++"S3159801F154C401200880A0A007088000038210000239\n"
++"S3159801F1648410200782204002C22120088528A016EF\n"
++"S3159801F174C205E08882104002C225E088C401200CA9\n"
++"S3159801F18480A0A0070880000382100002841020073B\n"
++"S3159801F19482204002C221200C8528A019C205E08844\n"
++"S3159801F1A482104002C225E088C401201080A0A00FD5\n"
++"S3159801F1B408800003821000028410200F82204002E6\n"
++"S3159801F1C4C2212010C205E0888528A01C821040021D\n"
++"S3159801F1D4C225E0888143C000C20000000326007E50\n"
++"S3159801F1E4881061B4C215E01AC401200C82087FFC08\n"
++"S3159801F1F48400A08CC6012004C235E01A80A080033D\n"
++"S3159801F2042280008B0526007EC421200C8143C000F0\n"
++"S3159801F214C20000000311400005000080821060506E\n"
++"S3159801F224C42040001B26007EC60361A880A0E00086\n"
++"S3159801F234028000060526007EC200A1AC80A060006B\n"
++"S3159801F24422BFFE98C606A0080726007EC200E1AC36\n"
++"S3159801F25480A0600002800159051150008210A00C0B\n"
++"S3159801F2649A102400DA20400009101004C6012018C7\n"
++"S3159801F274030000088228C001C22120188410A0081E\n"
++"S3159801F28403114000DA2080000700010082106050C3\n"
++"S3159801F294C62040003080014980A0A0041280000A4B\n"
++"S3159801F2A4981020001080000C8423400C02BFFF376D\n"
++"S3159801F2B498032001C208C000C22900008600E00113\n"
++"S3159801F2C48801200180A300020ABFFFF980A3000DDB\n"
++"S3159801F2D48423400C8530A0028328A002822340010E\n"
++"S3159801F2E49A20400C1080000698102000C221000034\n"
++"S3159801F2F4980320018600E0048801200480A3000273\n"
++"S3159801F3042ABFFFFBC200C000108000069810200097\n"
++"S3159801F314C2290000980320018600E0018801200192\n"
++"S3159801F32480A3000D2ABFFFFBC208C00010BFFF18B7\n"
++"S3159801F3342726007E0300003FC807600482106300F5\n"
++"S3159801F344860900011B003FC0852920188209000DF2\n"
++"S3159801F3548728E0088410800383306008841080012C\n"
++"S3159801F3648931201888108004C407FFDC80A0A00086\n"
++"S3159801F37422800012DA07FFE80700003F880100029D\n"
++"S3159801F3848610E300840900038528A0088329201898\n"
++"S3159801F394821040028609000D053FC0008730E008B7\n"
++"S3159801F3A484090002821040038530A0188210400215\n"
++"S3159801F3B4C2276004DA07FFE880A1000D1A80001FAE\n"
++"S3159801F3C4C207FFE89023400490023FFF912A201038\n"
++"S3159801F3D47FFFFDB691322010D0376012C407FFEC37\n"
++"S3159801F3E480A0A00002BFFECAC407FFB8C607FFE4FF\n"
++"S3159801F3F48200FFFFDA07FFBC80A0400D32BFFEC52D\n"
++"S3159801F404C036200AC217600C8210610010BFFEBF75\n"
++"S3159801F414C237600C90006008912A20107FFFFDA3E3\n"
++"S3159801F4249132201010BFFEB9D0376004C200A1B43E\n"
++"S3159801F43410BFFF77C221200C80A0600002BFFFE9AC\n"
++"S3159801F444C407FFECC417600C033FFFC882288001E8\n"
++"S3159801F45410BFFFE3C237600CE217600C0300000883\n"
++"S3159801F464808C40010280000E0700003F7FFFFD8FCC\n"
++"S3159801F474D0176012A12A20107FFFFD8CD017600641\n"
++"S3159801F484912A2010A134201091322010A00400084A\n"
++"S3159801F494A0042001E027FFE80700003F8610E2FF59\n"
++"S3159801F4A4820C4003A20C6100C237600C10BFFE4D5A\n"
++"S3159801F4B4E227FFECC20661B410BFFE09C226A00872\n"
++"S3159801F4C410BFFE44C437FFF6C217600C833060023E\n"
++"S3159801F4D48208603C10BFFFFB84008001981361D8B1\n"
++"S3159801F4E4E803200C88052010C203200480A100019A\n"
++"S3159801F4F422800002C80361D8053FF001C2052004A1\n"
++"S3159801F5048410A3FF82084002C2252004C40520045E\n"
++"S3159801F5148408B800C4252004C607FFB4C20520048C\n"
++"S3159801F5248530E01082104002C2252004E025200887\n"
++"S3159801F534E225200CC205200405060000821040022B\n"
++"S3159801F544C2252004C605200403180000C403200814\n"
++"S3159801F5548228C00184190002C2252004DA07FFD83B\n"
++"S3159801F56480A00002C823200CC6052004852B6002BE\n"
++"S3159801F5748803400D030800008610C0019A603FFF76\n"
++"S3159801F5848400801788010017DA232010C6252004E1\n"
++"S3159801F594B800A01CB6012064C207FFD080A48001DC\n"
++"S3159801F5A406800076E207FFD4DA07FFD8C416C000AE\n"
++"S3159801F5B4C60700009A036001A0100001C427FFD072\n"
++"S3159801F5C4C627FFD4DA27FFD8B606E002B80720047F\n"
++"S3159801F5D42726007EA614E1D80726007E80A420005B\n"
++"S3159801F5E4AC1000130280003FEA00E168C204E010FF\n"
++"S3159801F5F480A060001280005501000000C404E00C4C\n"
++"S3159801F604C200800080A06000068000508810000225\n"
++"S3159801F6148400A010C205A00480A080010280005431\n"
++"S3159801F62486100016C200E0088218800180A00001A5\n"
++"S3159801F634C420E00C84603FFFC420E01080A427FF17\n"
++"S3159801F644188000039A1027FF9A100010C20120040B\n"
++"S3159801F65482084015C2212004C40120048408B800F4\n"
++"S3159801F664C4212004872B6010C20120048730E0103E\n"
++"S3159801F67482104003C2212004E2212008C021200CD3\n"
++"S3159801F684C20120040506000082104002C22120040A\n"
++"S3159801F694C40120040318000082288001C221200491\n"
++"S3159801F6A4A4A4800D1280000601000000C201200462\n"
++"S3159801F6B40510000082104002C22120048143C00033\n"
++"S3159801F6C4C200000003200000C401000084108001D8\n"
++"S3159801F6D4C4210000A0A4000D12BFFFC5A204400DC9\n"
++"S3159801F6E480A4A00012BFFFAEC207FFD08143C00019\n"
++"S3159801F6F4C200000003200000C405000084108001A4\n"
++"S3159801F704C42500008143C000C2000000C207FFBCA3\n"
++"S3159801F71482006001C227FFBC03101004C407FFCC02\n"
++"S3159801F724C0206004C607FFB884008003DA07FFBCCB\n"
++"S3159801F734C207FFE480A3400116BFFE6EC427FFCC1F\n"
++"S3159801F74410BFFDD5E205E0048210000782886002A5\n"
++"S3159801F75402BFFFFE010000008E29C0017FFFFCDA7B\n"
++"S3159801F7640100000010BFFFA3C204E0101B26007E0F\n"
++"S3159801F77410BFFFADC40361D8C207FFD082204012DF\n"
++"S3159801F78484044012C227FFD0A010001210BFFF9123\n"
++"S3159801F794C427FFD4C2012004050800008210400240\n"
++"S3159801F7A4C221200410BFFE46A81000040326007E39\n"
++"S3159801F7B410BFFE18DA0061D89C07FF40FE03A0200B\n"
++"S3159801F7C4DE03A024E01BA028E41BA030E81BA03884\n"
++"S3159801F7D4EC1BA040F01BA048F41BA050F81BA058A2\n"
++"S3159801F7E481C3E0089C23BF40031140008410200381\n"
++"S3159801F7F482106060C420400081C3E00801000000C3\n"
++"S3159801F8049C03BFF0DE23A0041F26007E84102000EB\n"
++"S3159801F814C603E1D8092000008328A004C020C001AA\n"
++"S3159801F8248200C001C8206004C02060088400A00139\n"
++"S3159801F834C020600C80A0A03404BFFFF98328A004DB\n"
++"S3159801F844C020E3508600E350C820E004C200E004D7\n"
++"S3159801F8540500800082104002C220E004C020E0081E\n"
++"S3159801F8648213E1D8C020E00CC02060108143C00007\n"
++"S3159801F874C200000003101004C403E1D8C420601028\n"
++"S3159801F884DE03A00481C3E0089C23BFF09C03BFD088\n"
++"S3159801F894FE23A01CBE23BFD0DE23A020E023A024F0\n"
++"S3159801F8A40326007EA01061D884022360D02061D8F3\n"
++"S3159801F8B4D024200CD02420087FFFFFD2C42420040E\n"
++"S3159801F8C4D00420049C07FFD0FE03A01CDE03A020CD\n"
++"S3159801F8D4E003A02481C3E0089C23BFD09C03BFF016\n"
++"S3159801F8E4DE23A0048202400982004009832860022B\n"
++"S3159801F8F4860200010526007E8600E0041926007E0C\n"
++"S3159801F9049A1020000326007ED020A1F4D22061F01B\n"
++"S3159801F9148608FFFC80A340091680000FC02321ECBA\n"
++"S3159801F9249E1020008810200084010008C621000832\n"
++"S3159801F934DE20A0089A036001C020A0048600E04A4C\n"
++"S3159801F9448801200C80A3400906BFFFF89E10000287\n"
++"S3159801F954C42321EC90100003DE03A00481C3E008BC\n"
++"S3099801F9649C23BFF092\n"
++"S30D9801F968FFC007FF0000FFFF35\n"
++"S7059801E00081\n";
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/leon.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/leon.h
+--- linux-2.6.24/include/asm-arm/arch-oxnas/leon.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/leon.h 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,36 @@
++/*
++ * linux/arch/arm/mach-oxnas/leon.h
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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
++ */
++#ifdef CONFIG_SUPPORT_LEON
++
++#if !defined(__LEON_H__)
++#define __LEON_H__
++
++/**
++ * Load the LEON's program image into the memory as defined by the s-records
++ * holding the LEON program image, and begin execution at the start address
++ * defined by the s-records
++ */
++extern void init_copro(const s8 *srec, unsigned long arg);
++
++extern void shutdown_copro(void);
++
++#endif // #if !defined(__LEON_H__)
++#endif // CONFIG_SUPPORT_LEON
++
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/memory.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/memory.h
+--- linux-2.6.24/include/asm-arm/arch-oxnas/memory.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/memory.h 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,107 @@
++/*
++ * linux/include/asm-arm/arch-oxnas/memory.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.
++ */
++
++#ifndef __ASM_ARCH_MEMORY_H
++#define __ASM_ARCH_MEMORY_H
++
++/* Max. size of each memory node */
++#ifdef CONFIG_OXNAS_VERSION_0X800
++#define NODE_MAX_MEM_SHIFT (26) /* 64MB*/
++#elif defined (CONFIG_OXNAS_VERSION_0X810)
++#define NODE_MAX_MEM_SHIFT (28) /* 256MB */
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++#ifdef CONFIG_OXNAS_VERSION_0X800
++#define MEM_MAP_ALIAS_SHIFT 28
++#elif defined (CONFIG_OXNAS_VERSION_0X810)
++#define MEM_MAP_ALIAS_SHIFT 30
++#endif // CONFIG_OXNAS_VERSION_0X800
++
++/* All current OXNAS versions have two memory nodes; SDRAM followed contiguously
++ * by SRAM */
++#define SDRAM_PA (0x48000000)
++#define SDRAM_SIZE (1UL << (NODE_MAX_MEM_SHIFT))
++#define SRAM_PA ((SDRAM_PA) + (SDRAM_SIZE))
++
++/* Only a portion of the SRAM may be available for the use of Linux */
++#define SRAM_SIZE (CONFIG_SRAM_NUM_PAGES * PAGE_SIZE)
++
++#define SDRAM_END (SDRAM_PA + SDRAM_SIZE - 1)
++#define SRAM_END (SRAM_PA + SRAM_SIZE - 1)
++
++#define PHYS_OFFSET SDRAM_PA
++#define PAGE_OFFSET 0xC0000000
++
++#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
++#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
++
++#define __virt_to_bus(x) __virt_to_phys(x)
++#define __bus_to_virt(x) __phys_to_virt(x)
++
++#ifdef CONFIG_DISCONTIGMEM
++/*
++ * Memory map aliased every 1GByte, i.e. top 2 bits are ignored.
++ *
++ * Currently (0X800) we have:
++ *
++ * Start of physical memory: 0x08000000
++ * 0x48000000 - alias
++ * 0x88000000 - alias
++ * 0xC8000000 - alias
++ *
++ * Node 0 SDRAM: 0x08000000 - 0x09FFFFFF 32MB populated
++ * : 0x48000000 - alias
++ * : 0x88000000 - alias
++ * : 0xC8000000 - alias
++ *
++ * Node 1 SRAM : 0x0C000000 - 0x00008000 32KB populated
++ * : 0x4C000000 - alias
++ * : 0x8C000000 - alias
++ * : 0xCC000000 - alias
++ *
++ * It will be assumed that no single memory node can be larger than
++ * (1 << NODE_MAX_MEM_SIZE) and that nodes will be contiguous, although
++ * individual nodes may not be fully populated
++ */
++
++/*
++ * Given a kernel address, find the home node of the underlying memory.
++ */
++#define KVADDR_TO_NID(addr) (((unsigned long)(addr) - PAGE_OFFSET) >> NODE_MAX_MEM_SHIFT)
++
++/*
++ * Given a page frame number, convert it to a node id.
++ */
++#define PFN_TO_NID(pfn) (((pfn) - PHYS_PFN_OFFSET) >> (NODE_MAX_MEM_SHIFT - PAGE_SHIFT))
++
++/*
++ * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
++ * and return the mem_map of that node.
++ */
++#define ADDR_TO_MAPBASE(kaddr) NODE_MEM_MAP(KVADDR_TO_NID(kaddr))
++
++/*
++ * Given a page frame number, find the owning node of the memory
++ * and return the mem_map of that node.
++ */
++#define PFN_TO_MAPBASE(pfn) NODE_MEM_MAP(PFN_TO_NID(pfn))
++
++/*
++ * Given a kaddr, LOCAL_MAP_NR finds the owning node of the memory
++ * and returns the index corresponding to the appropriate page in the
++ * node's mem_map.
++ */
++#define LOCAL_MAP_NR(addr) (((unsigned long)(addr) & ((1 << NODE_MAX_MEM_SHIFT) - 1)) >> PAGE_SHIFT)
++
++#else
++
++#define PFN_TO_NID(addr) (0)
++
++#endif
++
++#endif // __ASM_ARCH_MEMORY_H
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/ox810sata.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/ox810sata.h
+--- linux-2.6.24/include/asm-arm/arch-oxnas/ox810sata.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/ox810sata.h 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,162 @@
++/*
++ * linux/include/asm-arm/arch-oxnas/sata.h
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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
++ *
++ * Definitions for using the SATA core in the ox800
++ */
++
++#ifndef __ASM_ARCH_SATA_H__
++#define __ASM_ARCH_SATA_H__
++
++/* number of ports per interface */
++#define OX810SATA_MAX_PORTS 1
++
++
++/** sata host port register offsets */
++#define OX810SATA_ORB1 (0x00 / sizeof(u32))
++#define OX810SATA_ORB2 (0x04 / sizeof(u32))
++#define OX810SATA_ORB3 (0x08 / sizeof(u32))
++#define OX810SATA_ORB4 (0x0C / sizeof(u32))
++#define OX810SATA_ORB5 (0x10 / sizeof(u32))
++
++#define OX810SATA_MASTER_STATUS (0x10 / sizeof(u32))
++#define OX810SATA_FIS_CTRL (0x18 / sizeof(u32))
++#define OX810SATA_FIS_DATA (0x1C / sizeof(u32))
++
++#define OX810SATA_INT_STATUS (0x30 / sizeof(u32))
++#define OX810SATA_INT_CLEAR (0x30 / sizeof(u32))
++#define OX810SATA_INT_ENABLE (0x34 / sizeof(u32))
++#define OX810SATA_INT_DISABLE (0x38 / sizeof(u32))
++#define OX810SATA_VERSION (0x3C / sizeof(u32))
++#define OX810SATA_SATA_CONTROL (0x5C / sizeof(u32))
++#define OX810SATA_SATA_COMMAND (0x60 / sizeof(u32))
++#define OX810SATA_HID_FEATURES (0x64 / sizeof(u32))
++#define OX810SATA_PORT_CONTROL (0x68 / sizeof(u32))
++#define OX810SATA_DRIVE_CONTROL (0x6C / sizeof(u32))
++
++/** These registers allow access to the link layer registers
++that reside in a different clock domain to the processor bus */
++#define OX810SATA_LINK_DATA (0x70 / sizeof(u32))
++#define OX810SATA_LINK_RD_ADDR (0x74 / sizeof(u32))
++#define OX810SATA_LINK_WR_ADDR (0x78 / sizeof(u32))
++#define OX810SATA_LINK_CONTROL (0x7C / sizeof(u32))
++
++/** Backup registers contain a copy of the command sent to the disk */
++#define OX810SATA_BACKUP1 (0xB0 / sizeof(u32))
++#define OX810SATA_BACKUP2 (0xB4 / sizeof(u32))
++#define OX810SATA_BACKUP3 (0xB8 / sizeof(u32))
++#define OX810SATA_BACKUP4 (0xBC / sizeof(u32))
++
++/**
++ * commands to issue in the master status to tell it to move shadow
++ * registers to the actual device
++ */
++#define SATA_OPCODE_MASK 0x00000007
++#define CMD_WRITE_TO_ORB_REGS_NO_COMMAND 0x4
++#define CMD_WRITE_TO_ORB_REGS 0x2
++#define CMD_SYNC_ESCAPE 0x7
++#define CMD_CORE_BUSY (1 << 7)
++
++/** interrupt bits */
++#define OX810SATA_INT_END_OF_CMD (1 << 0)
++#define OX810SATA_INT_LINK_SERROR (1 << 1)
++#define OX810SATA_INT_ERROR (1 << 2)
++#define OX810SATA_INT_LINK_IRQ (1 << 3)
++#define OX810SATA_INT_REG_ACCESS_ERR (1 << 7)
++#define OX810SATA_INT_BIST_FIS (1 << 11)
++#define OX810SATA_INT_MASKABLE (OX810SATA_INT_END_OF_CMD |\
++ OX810SATA_INT_LINK_SERROR |\
++ OX810SATA_INT_ERROR |\
++ OX810SATA_INT_LINK_IRQ |\
++ OX810SATA_INT_REG_ACCESS_ERR |\
++ OX810SATA_INT_BIST_FIS )
++
++#define OX810SATA_INT_WANT (OX810SATA_INT_END_OF_CMD |\
++ OX810SATA_INT_LINK_SERROR |\
++ OX810SATA_INT_REG_ACCESS_ERR |\
++ OX810SATA_INT_ERROR )
++
++/** raw interrupt bits, unmaskable, but do not generate interrupts */
++#define OX810SATA_RAW_END_OF_CMD (OX810SATA_INT_END_OF_CMD << 16)
++#define OX810SATA_RAW_LINK_SERROR (OX810SATA_INT_LINK_SERROR << 16)
++#define OX810SATA_RAW_ERROR (OX810SATA_INT_ERROR << 16)
++#define OX810SATA_RAW_LINK_IRQ (OX810SATA_INT_LINK_IRQ << 16)
++#define OX810SATA_RAW_REG_ACCESS_ERR (OX810SATA_INT_REG_ACCESS_ERR << 16)
++#define OX810SATA_RAW_BIST_FIS (OX810SATA_INT_BIST_FIS << 16)
++
++/** SATA core register offsets */
++#define OX810SATA_DM_DEBUG1 ( SATACORE_REGS_BASE + 0x000 )
++#define OX810SATA_RAID_SET ( SATACORE_REGS_BASE + 0x004 )
++#define OX810SATA_DM_DEBUG2 ( SATACORE_REGS_BASE + 0x008 )
++#define OX810SATA_CORE_ISR ( SATACORE_REGS_BASE + 0x030 )
++#define OX810SATA_CORE_IES ( SATACORE_REGS_BASE + 0x034 )
++#define OX810SATA_CORE_IEC ( SATACORE_REGS_BASE + 0x038 )
++#define OX810SATA_DEVICE_CONTROL ( SATACORE_REGS_BASE + 0x068 )
++#define OX810SATA_EXCESS ( SATACORE_REGS_BASE + 0x06C )
++#define OX810SATA_IDLE_STATUS ( SATACORE_REGS_BASE + 0x07C )
++#define OX810SATA_RAID_CONTROL ( SATACORE_REGS_BASE + 0x090 )
++
++/** sata core control register bits */
++#define OX810SATA_SCTL_CLR_ERR (0x00003016)
++
++/* Interrupts direct from the ports */
++#define OX810SATA_NORMAL_INTS_WANTED (0x00000003)
++
++/* Interrupts from the RAID controller only */
++#define OX810SATA_RAID_INTS_WANTED (0x00008000)
++
++/* The bits in the OX810SATA_IDLE_STATUS that, when set indicate an idle core */
++#define OX810SATA_IDLE_CORES ((1 << 18) | (1 << 19))
++
++/** Device Control register bits */
++#define OX810SATA_DEVICE_CONTROL_ABORT (1 << 2)
++#define OX810SATA_DEVICE_CONTROL_PAD (1 << 3)
++#define OX810SATA_DEVICE_CONTROL_PADPAT (1 << 16)
++
++/** ORB4 register bits */
++#define OX810SATA_ORB4_SRST (1 << 26)
++
++/** standard HW raid flags */
++#define OXNASSATA_NOTRAID 3
++#define OXNASSATA_RAID1 1
++#define OXNASSATA_RAID0 0
++#define OXNASSATA_RAID_TWODISKS 3
++
++/**
++ * variables to write to the device control register to set the current device
++ * ie, master or slave
++ */
++#define OX810SATA_DR_CON_48 2
++#define OX810SATA_DR_CON_28 0
++
++/** A ficticious device id used for matching device and driver */
++#define OX810SATA_DEVICEID 0x00100002
++
++/** The different Oxsemi SATA core version numbers */
++#define OX810SATA_CORE_VERSION 0x1f2
++
++/** Occasionally we get interrupts, even though there is no outstanding command,
++these can be caused by dodgy SATA cables, this is a divider for reporting these
++interrupts */
++#define OX810SATA_NO_CMD_ERROR_RPT_COUNT 8
++
++extern int oxnassata_RAID_faults( void );
++extern int oxnassata_get_port_no(struct request_queue* );
++extern int oxnassata_LBA_schemes_compatible( void );
++
++#endif /* #if !defined(__ASM_ARCH_SATA_H__) */
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/sata.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/sata.h
+--- linux-2.6.24/include/asm-arm/arch-oxnas/sata.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/sata.h 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,181 @@
++/*
++ * linux/include/asm-arm/arch-oxnas/sata.h
++ *
++ * Copyright (C) 2005 Oxford Semiconductor Ltd
++ *
++ * 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
++ *
++ * Definitions for using the SATA core in the ox800
++ */
++
++#ifndef __ASM_ARCH_SATA_H__
++#define __ASM_ARCH_SATA_H__
++
++#include <linux/blkdev.h>
++
++/* number of ports per interface */
++#define OX800SATA_MAX_PORTS 1
++
++
++/** ata core register offsets */
++#define OX800SATA_ORB1 (0x00 / sizeof(u32))
++#define OX800SATA_ORB2 (0x04 / sizeof(u32))
++#define OX800SATA_ORB3 (0x08 / sizeof(u32))
++#define OX800SATA_ORB4 (0x0C / sizeof(u32))
++#define OX800SATA_ORB5 (0x10 / sizeof(u32))
++
++#define OX800SATA_MASTER_STATUS (0x10 / sizeof(u32))
++#define OX800SATA_DEVICE_CTRL (0x18 / sizeof(u32))
++#define OX800SATA_REG_ACCESS (0x2c / sizeof(u32))
++#define OX800SATA_INT_STATUS (0x30 / sizeof(u32))
++#define OX800SATA_INT_CLEAR (0x30 / sizeof(u32))
++#define OX800SATA_INT_ENABLE (0x34 / sizeof(u32))
++#define OX800SATA_INT_DISABLE (0x38 / sizeof(u32))
++#define OX800SATA_VERSION (0x3C / sizeof(u32))
++#define OX800SATA_SATA_CONTROL (0x5C / sizeof(u32))
++#define OX800SATA_SATA_COMMAND (0x60 / sizeof(u32))
++#define OX800SATA_DEVICE_SELECT (0x64 / sizeof(u32))
++#define OX800SATA_DEVICE_CONTROL (0x68 / sizeof(u32))
++#define OX800SATA_DRIVE_CONTROL (0x6C / sizeof(u32))
++
++/** ata core registers that only work on port 0 */
++#define OX800SATA_BURST_BUFFER (0x1C / sizeof(u32))
++#define OX800SATA_BURST_CONTROL (0x48 / sizeof(u32))
++#define OX800SATA_RAID_CONTROL (0x70 / sizeof(u32))
++
++
++
++
++/** These registers allow access to the link layer registers
++that reside in a different clock domain to the processor bus */
++#define OX800SATA_LINK_DATA (0x00000000)
++#define OX800SATA_LINK_RD_ADDR (0x00000001)
++#define OX800SATA_LINK_WR_ADDR (0x00000002)
++#define OX800SATA_LINK_CONTROL (0x00000003)
++
++/**
++ * commands to issue in the master status to tell it to move shhadow
++ * registers to the actual device
++ */
++#define OX800SATA_MASTER_STATUS_WRITEOP 6 | (1 << 31)
++#define OX800SATA_MASTER_STATUS_READOP 5 | (1 << 31) | (1 << 29)
++#define OX800SATA_MASTER_STATUS_ORBWRITEOP 1 | (1 << 31)
++#define OX800SATA_MASTER_STATUS_ORBWRITE_RUN 2 | (1 << 31) | (1 << 29)
++#define OX800SATA_MASTER_STATUS_READY 64
++#define OX800SATA_MASTER_STATUS_BUSY 128
++
++#define OX800SATA_ORB2_SECTORS_MASK (0x0000ffff)
++
++#define SATA_OPCODE_MASK 0x00000003
++#define CMD_WRITE_TO_ORB_REGS_NO_COMMAND 0x01
++#define CMD_WRITE_TO_ORB_REGS 0x02
++#define CMD_READ_ALL_REGISTERS 0x03
++#define CMD_READ_STATUS_REG 0x04
++#define CMD_CORE_BUSY (1 << 7)
++
++/** interrupt bits */
++#define OX800SATA_INT_END_OF_CMD (1 << 0)
++#define OX800SATA_INT_END_OF_DATA_CMD (1 << 1)
++#define OX800SATA_INT_ERROR (1 << 2)
++#define OX800SATA_INT_FIFO_EMPTY (1 << 3)
++#define OX800SATA_INT_FIFO_FULL (1 << 4)
++#define OX800SATA_INT_END_OF_TRANSF (1 << 5)
++#define OX800SATA_INT_MASKABLE (OX800SATA_INT_END_OF_CMD |\
++ OX800SATA_INT_END_OF_DATA_CMD |\
++ OX800SATA_INT_ERROR |\
++ OX800SATA_INT_FIFO_EMPTY |\
++ OX800SATA_INT_FIFO_FULL |\
++ OX800SATA_INT_END_OF_TRANSF )
++
++/** raw interrupt bits, unmaskable, but do not generate interrupts */
++#define OX800SATA_RAW_END_OF_CMD (1 << 8)
++#define OX800SATA_RAW_END_OF_DATA_CMD (1 << 9)
++#define OX800SATA_RAW_ERROR (1 << 10)
++#define OX800SATA_RAW_FIFO_EMPTY (1 << 11)
++#define OX800SATA_RAW_FIFO_FULL (1 << 12)
++#define OX800SATA_RAW_END_OF_TRANSF (1 << 13)
++
++/** burst buffer control bits */
++#define OX800SATA_BBC_FORCE_EOT (1 << 0)
++#define OX800SATA_BBC_DIRECTION (1 << 2)
++#define OX800SATA_BBC_FIFO_DIS (1 << 4)
++#define OX800SATA_BBC_DREQ_DIS (1 << 5)
++#define OX800SATA_BBC_DREQ (1 << 6)
++
++/** sata control register bits */
++#define OX800SATA_SCTL_RESET (1 << 0)
++#define OX800SATA_SCTL_ABORT (1 << 2)
++
++/** Device Control register bits */
++#define OX800SATA_DEVICE_CONTROL_ABORT (1 << 2)
++
++/** ORB4 register bits */
++#define OX800SATA_ORB4_SRST (1 << 26)
++
++/** SATA control transport state machine mask */
++#define OX800SATA_SATA_CONTROL_TRANS_MASK (0x0000001e)
++#define OX800SATA_TRANS_CHECKTYPE (0x00000008)
++#define OX800SATA_TRANS_PIOITRANS (0x00000018)
++#define OX800SATA_TRANS_PIOOTRANS (0x0000001C)
++
++/** RAID control bit definitions */
++#define OX800SATA_RAID_SPAN_EN (1 << 0)
++#define OX800SATA_RAID_STRI_EN (1 << 1)
++#define OX800SATA_RAID_STRI16 (1 << 2)
++#define OX800SATA_RAID_STRI32 (1 << 3)
++#define OX800SATA_RAID_STRI64 (1 << 4)
++#define OX800SATA_RAID_STRI128 (1 << 5)
++#define OX800SATA_RAID_STRI256 (1 << 6)
++#define OX800SATA_RAID_STRI512 (1 << 7)
++#define OX800SATA_RAID_STRI1M (1 << 8)
++#define OX800SATA_RAID_STRI2M (1 << 9)
++#define OX800SATA_RAID_STRI_TEST (1 << 10)
++#define OX800SATA_RAID_XSOFF2 (0 << 11)
++#define OX800SATA_RAID_XSOFF4 (1 << 11)
++#define OX800SATA_RAID_XSOFF6 (2 << 11)
++#define OX800SATA_RAID_XSOFF8 (3 << 11)
++#define OX800SATA_RAID_LOOP_BK (1 << 12)
++#define OX800SATA_RAID_MIR0 (0 << 13)
++#define OX800SATA_RAID_MIR1 (1 << 13)
++#define OX800SATA_RAID_MIRALT (2 << 13)
++#define OX800SATA_RAID_MIR_EN (1 << 16)
++#define OX800SATA_RAID_OVERLAP (1 << 23)
++
++/* standard HW raid flags */
++#define OXNASSATA_RAID1 (OX800SATA_RAID_MIR0 | OX800SATA_RAID_MIR_EN | OX800SATA_RAID_OVERLAP )
++#define OXNASSATA_RAID0 (OX800SATA_RAID_OVERLAP | OX800SATA_RAID_STRI_EN )
++/**
++ * variables to write to the device control register to set the current device
++ * ie, master or slave
++ */
++#define OX800SATA_DEVICE_CONTROL_MASTER 0
++#define OX800SATA_DEVICE_CONTROL_SLAVE 1
++
++/** A ficticious device id used for matching device and driver */
++#define OX800SATA_DEVICEID 0x00100001
++
++/** The different Oxsemi SATA core version numbers */
++#define OX800SATA_CORE_VERSION 0xf0
++
++/** Occasionally we get interrupts, even though there is no outstanding command,
++these can be caused by dodgy SATA cables, this is a divider for reporting these
++interrupts */
++#define OX800SATA_NO_CMD_ERROR_RPT_COUNT 8
++
++extern int oxnassata_RAID_faults( void );
++extern int oxnassata_get_port_no(struct request_queue* );
++extern int oxnassata_LBA_schemes_compatible( void );
++
++#endif /* #if !defined(__ASM_ARCH_SATA_H__) */
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/system.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/system.h
+--- linux-2.6.24/include/asm-arm/arch-oxnas/system.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/system.h 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,103 @@
++/* linux/include/asm-arm/arch-oxnas/system.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.
++ */
++
++#ifndef __ASM_ARCH_SYSTEM_H
++#define __ASM_ARCH_SYSTEM_H
++
++#include <asm/hardware.h>
++#include <asm/io.h>
++
++extern void sata_power_off(void);
++extern int oxnas_global_invert_leds;
++
++#if defined(CONFIG_LEON_POWER_BUTTON_MONITOR) || defined(CONFIG_LEON_POWER_BUTTON_MONITOR_MODULE)
++#include <asm/arch/leon.h>
++#include <asm/arch/leon-power-button-prog.h>
++#endif // CONFIG_LEON_POWER_BUTTON_MONITOR
++
++static inline void arch_idle(void)
++{
++ /*
++ * This should do all the clock switching
++ * and wait for interrupt tricks
++ */
++ cpu_do_idle();
++}
++
++static void disable_gmac(void)
++{
++ writel((1UL << SYS_CTRL_RSTEN_MAC_BIT), SYS_CTRL_RSTEN_SET_CTRL);
++ writel((1UL << SYS_CTRL_CKEN_MAC_BIT), SYS_CTRL_CKEN_CLR_CTRL);
++}
++
++static void arch_poweroff(void)
++{
++ disable_gmac();
++
++#if defined(CONFIG_LEON_POWER_BUTTON_MONITOR) || defined(CONFIG_LEON_POWER_BUTTON_MONITOR_MODULE)
++ // Load CoPro program and start it running
++ init_copro(leon_srec, oxnas_global_invert_leds);
++#endif // CONFIG_LEON_POWER_BUTTON_MONITOR
++
++ // Turn of power to SATA disk if possible
++ sata_power_off();
++}
++
++static void arch_reset(char mode)
++{
++ // Assert reset to cores as per power on defaults
++ writel((1UL << SYS_CTRL_RSTEN_COPRO_BIT) |
++ (1UL << SYS_CTRL_RSTEN_USBHS_BIT) |
++ (1UL << SYS_CTRL_RSTEN_USBHSPHY_BIT) |
++ (1UL << SYS_CTRL_RSTEN_MAC_BIT) |
++ (1UL << SYS_CTRL_RSTEN_PCI_BIT) |
++ (1UL << SYS_CTRL_RSTEN_DMA_BIT) |
++ (1UL << SYS_CTRL_RSTEN_DPE_BIT) |
++ (1UL << SYS_CTRL_RSTEN_SATA_BIT) |
++ (1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT) |
++ (1UL << SYS_CTRL_RSTEN_STATIC_BIT) |
++ (1UL << SYS_CTRL_RSTEN_UART1_BIT) |
++ (1UL << SYS_CTRL_RSTEN_UART2_BIT) |
++ (1UL << SYS_CTRL_RSTEN_MISC_BIT) |
++ (1UL << SYS_CTRL_RSTEN_I2S_BIT) |
++ (1UL << SYS_CTRL_RSTEN_AHB_MON_BIT) |
++ (1UL << SYS_CTRL_RSTEN_UART3_BIT) |
++ (1UL << SYS_CTRL_RSTEN_UART4_BIT) |
++ (1UL << SYS_CTRL_RSTEN_SGDMA_BIT), SYS_CTRL_RSTEN_SET_CTRL);
++
++ // Release reset to cores as per power on defaults
++ writel((1UL << SYS_CTRL_RSTEN_GPIO_BIT), SYS_CTRL_RSTEN_CLR_CTRL);
++
++ // Disable clocks to cores as per power-on defaults
++ writel((1UL << SYS_CTRL_CKEN_COPRO_BIT) |
++ (1UL << SYS_CTRL_CKEN_DMA_BIT) |
++ (1UL << SYS_CTRL_CKEN_DPE_BIT) |
++ (1UL << SYS_CTRL_CKEN_SATA_BIT) |
++ (1UL << SYS_CTRL_CKEN_I2S_BIT) |
++ (1UL << SYS_CTRL_CKEN_USBHS_BIT) |
++ (1UL << SYS_CTRL_CKEN_MAC_BIT) |
++ (1UL << SYS_CTRL_CKEN_STATIC_BIT), SYS_CTRL_CKEN_CLR_CTRL);
++
++ // Enable clocks to cores as per power-on defaults
++ writel((1UL << SYS_CTRL_CKEN_PCI_BIT), SYS_CTRL_CKEN_SET_CTRL);
++
++ // Set sys-control pin mux'ing as per power-on defaults
++ writel(0x800UL, SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
++ writel(0x0UL, SYS_CTRL_GPIO_PRIMSEL_CTRL_1);
++ writel(0x0UL, SYS_CTRL_GPIO_SECSEL_CTRL_0);
++ writel(0x0UL, SYS_CTRL_GPIO_SECSEL_CTRL_1);
++ writel(0x0UL, SYS_CTRL_GPIO_TERTSEL_CTRL_0);
++ writel(0x0UL, SYS_CTRL_GPIO_TERTSEL_CTRL_1);
++
++ // No need to save any state, as the ROM loader can determine whether reset
++ // is due to power cycling or programatic action, just hit the (self-
++ // clearing) CPU reset bit of the block reset register
++ writel(1UL << SYS_CTRL_RSTEN_ARM_BIT, SYS_CTRL_RSTEN_SET_CTRL);
++}
++
++#endif // __ASM_ARCH_SYSTEM_H
++
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/taco.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/taco.h
+--- linux-2.6.24/include/asm-arm/arch-oxnas/taco.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/taco.h 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,227 @@
++/*
++ * linux/include/asm-arm/arch-oxnas/tacho.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.
++ */
++
++#ifndef __ASM_ARM_ARCH_TACHO_H
++#define __ASM_ARM_ARCH_TACHO_H
++
++#include "hardware.h"
++
++/* Routines ----------------------------------------------------------------- */
++/* -------------------------------------------------------------------------- */
++/* -------------------------------------------------------------------------- */
++/* -------------------------------------------------------------------------- */
++
++/**
++ * DumpTachoRegisters is a debug function used to inspect hte tacho registers.
++ */
++extern void DumpTachoRegisters(void);
++
++
++/**
++ * GetTemperature will read the thermistor register and convert the value to
++ * kelvin.
++ * @return an int that represents the thermister temperature in Kelvin, or a
++ * negative value in the case of error.
++ */
++extern int GetTemperature(void);
++
++
++/**
++ * GetFanRPM will read the fan tacho register and convert the value to
++ * RPM.
++ * @return an int that represents the fan speed in RPM, or a
++ * negative value in the case of error.
++ */
++extern int GetFanRPM(void);
++
++#ifdef CONFIG_OXNAS_VERSION_0X810
++#define OXNAS_TACHO_Ox810
++#endif
++
++
++#ifndef OXNAS_TACHO_Ox810
++#define DEGREES_C_0 273
++#define TACHO_TARGET_THERM_FREQ_HZ 1000000
++#define TACHO_CORE_THERM_DIVIDER_VALUE (((NOMINAL_SYSCLK / TACHO_TARGET_THERM_FREQ_HZ) - 1))
++#endif /* OXNAS_TACHO_Ox810 */
++
++#define TACHO_TARGET_CORE_FREQ_HZ 128000
++#define TACHO_CORE_TACHO_DIVIDER_VALUE (((NOMINAL_SYSCLK / TACHO_TARGET_CORE_FREQ_HZ) - 1))
++
++#ifndef OXNAS_TACHO_Ox810
++#define TACHO_FAN_SPEED_DIVIDER (64)
++#endif /*OXNAS_TACHO_Ox810 */
++
++#define SECONDARY_FUNCTION_ENABLE_FAN_PWM2 8
++#define PRIMARY_FUNCTION_ENABLE_FAN_TEMP 29
++#define PRIMARY_FUNCTION_ENABLE_FAN_TACHO 30
++
++#ifdef OXNAS_TACHO_Ox810
++#define TEMP_TACHO_PULLUP_CTRL_VALUE 0x20000000
++#endif /* OXNAS_TACHO_Ox810 */
++
++
++// 256kHz with 50MHz pclk (reset value)
++#ifdef OXNAS_TACHO_Ox810
++#define PWM_CORE_CLK_DIVIDER_VALUE (130)
++#else /* OXNAS_TACHO_Ox810 */
++#define PWM_CORE_CLK_DIVIDER_VALUE (194)
++#endif /* OXNAS_TACHO_Ox810 */
++
++/* Registers ---------------------------------------------------------------- */
++/* -------------------------------------------------------------------------- */
++/* -------------------------------------------------------------------------- */
++/* -------------------------------------------------------------------------- */
++
++/* FAN Speed Counter ----------------------------------- */
++
++#ifdef OXNAS_TACHO_Ox810
++
++#define TACHO_FAN_SPEED_COUNTER (FAN_MON_BASE + 0x00)
++ // 31:17 - RO - Unused (0x00)
++ // 16 - R0 - Fan Count Valid - used in one shot mode
++ // 15:10 - R0 - Unused
++ // 9:0 - RO - Fan counter value. (See DD for conversion to rpm)
++ #define TACHO_FAN_SPEED_COUNTER_FAN_COUNT 0
++ #define TACHO_FAN_SPEED_COUNTER_COUNT_VALID 16
++
++#else /* OXNAS_TACHO_Ox810 */
++
++#define TACHO_FAN_SPEED_COUNTER (FAN_MON_BASE + 0x00)
++ // 31:10 - RO - Unused (0x00)
++ // 9:0 - RO - Fan counter value. (See DD for conversion to rpm)
++ #define TACHO_FAN_SPEED_COUNTER_FAN_COUNT 0
++
++#endif /* OXNAS_TACHO_Ox810 */
++
++ #define TACHO_FAN_SPEED_COUNTER_MASK 1023
++
++/* Thermistor RC Counter ------------------------------- */
++#define TACHO_THERMISTOR_RC_COUNTER (FAN_MON_BASE + 0x04)
++ // 31:10 - RO - Unused (0x00)
++ // 9:0 - RO - Thermistor counter value (See DD for conversion to temperature)
++ #define TACHO_THERMISTOR_RC_COUNTER_THERM_COUNT 0
++
++ #define TACHO_THERMISTOR_RC_COUNTER_MASK 1023
++
++
++/* Thermistor Control ---------------------------------- */
++#define TACHO_THERMISTOR_CONTROL (FAN_MON_BASE + 0x08)
++ // 31:2 - RO - Unused (0x00)
++ // 1:1 - R0 � THERM_COUNT value is valid
++ // 0:0 - RW - Set to 1 to enable thermistor PWM output
++ #define TACHO_THERMISTOR_CONTROL_THERM_VALID 1
++ #define TACHO_THERMISTOR_CONTROL_THERM_ENABLE 0
++
++
++/* Clock divider ---------------------------- */
++#define TACHO_CLOCK_DIVIDER (FAN_MON_BASE + 0x0C)
++ // 31:10 - RO - Unused (0x00)
++ // 0:9 - RW - set PWM effective clock frequency to a division of pclk (0x030C )
++ // 0000 � pclk divided by 1 (=pclk)
++ // 0001 - pclk divided by 2
++ // 0780 - ~128kHz with 100MHz pclk (reset value)
++ // 1023 - pclk divided by 1024
++ #define TACHO_CLOCK_DIVIDER_PWM_DIVIDER 0
++ #define TACHO_CLOCK_DIVIDER_MASK 1023
++
++
++/* New hardware registers added for 810 */
++#ifdef OXNAS_TACHO_Ox810
++
++/* Fan Speed Control ..........................*/
++#define TACHO_FAN_SPEED_CONTROL (FAN_MON_BASE + 0x10)
++ // 31:N+16 - R0 - Unused (0x0000)
++ // N+15:16 - RW - Select PWM which controls FAN speed
++ // 15:1 - Unused 0
++ // 0 - RW - Fan Count mode 0 - Continuous running mode 1 - One shot mode
++ #define TACHO_FAN_SPEED_CONTROL_PWM_ENABLE_BASE 16
++ #define TACHO_FAN_SPEED_CONTROL_PWM_USED 2
++ #define TACHO_FAN_SPEED_CONTROL_FAN_COUNT_MODE 0
++
++
++/* Fan One Shot Control .........................*/
++#define TACHO_FAN_ONE_SHOT_CONTROL (FAN_MON_BASE + 0x14)
++ // 31:1 - R - Unused
++ // 0 - W - Start One-shot - Tacho - Self Clearing bit
++ #define TACHO_FAN_ONE_SHOT_CONTROL_START 0
++
++
++#endif /* OXNAS_TACHO_Ox810 */
++
++/* PWM SECTION ------------------------------ */
++
++// 0x00 Channel 0 PWM data
++// 7:0 R/W 0x00
++// 31:8 Unused R 0x00000 Unused
++#define PWM_DATA_0 (PWM_BASE+0x00)
++ // value 0 � Output aways lo
++ // value 1 � hi for 1 clock, lo for 255
++ // . . .
++ // value 127 � 50:50 hi/lo
++ // . . .
++ // value 255 � hi for 255 clocks, lo for 1
++
++// 0x04 Channel 1 PWM data
++// 7:0 R/W 0x00
++// 31:8 Unused R 0x00000 Unused
++#define PWM_DATA_1 (PWM_BASE+0x04)
++ // value 0 � Output aways lo
++ // value 1 � hi for 1 clock, lo for 255
++ // . . .
++ // value 127 � 50:50 hi/lo
++ // . . .
++ // value 255 � hi for 255 clocks, lo for 1
++
++// 0x08 Channel 2 PWM data
++// 7:0 R/W 0x00
++// 31:8 Unused R 0x00000 Unused
++#define PWM_DATA_2 (PWM_BASE+0x08)
++ // value 0 � Output aways lo
++ // value 1 � hi for 1 clock, lo for 255
++ // . . .
++ // value 127 � 50:50 hi/lo
++ // . . .
++ // value 255 � hi for 255 clocks, lo for 1
++
++// 0x0C Channel 3 PWM data
++// 7:0 R/W 0x00
++// 31:8 Unused R 0x00000 Unused
++#define PWM_DATA_3 (PWM_BASE+0x0C)
++ // value 0 � Output aways lo
++ // value 1 � hi for 1 clock, lo for 255
++ // . . .
++ // value 127 � 50:50 hi/lo
++ // . . .
++ // value 255 � hi for 255 clocks, lo for 1
++
++#ifdef OXNAS_TACHO_Ox810
++//0x400 PWM Clock Divider
++// 15:0 R/W 0x00C2
++// 31:16 Unused R 0x0000 Unused
++#define PWM_CLOCK_DIVIDER (PWM_BASE+0x400)
++
++#else /* OXNAS_TACHO_Ox810 */
++
++// 0x10 PWM clock divider
++// 15:0 R/W 0x00C2
++// 31:16 Unused R 0x0000 Unused
++#define PWM_CLOCK_DIVIDER (PWM_BASE+0x10)
++ // set PWM effective clock frequency to a division of pclk
++ // value 0 � pclk divided by 1 (=pclk)
++ // value 1 � pclk divided by 2
++ // value 194 � 256kHz with 50MHz pclk (reset value)
++ // . . .
++ // value 65535 � pclk divided by 65536
++
++#endif /* OXNAS_TACHO_Ox810 */
++
++#endif // __ASM_ARM_ARCH_TACHO_H
++
++/* End oF File */
++
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/timex.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/timex.h
+--- linux-2.6.24/include/asm-arm/arch-oxnas/timex.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/timex.h 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,23 @@
++/* linux/include/asm-arm/arch-oxnas/timex.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.
++*/
++
++#ifndef __ASM_ARCH_TIMEX_H
++#define __ASM_ARCH_TIMEX_H
++
++#define TIMER_PRESCALE_BIT 2
++#define TIMER_PRESCALE_1 0
++#define TIMER_PRESCALE_16 1
++#define TIMER_PRESCALE_256 2
++
++#define TIMER_INPUT_CLOCK CONFIG_NOMINAL_RPSCLK_FREQ
++#define TIMER_1_PRESCALE_ENUM TIMER_PRESCALE_16
++#define TIMER_1_PRESCALE_VALUE (1 << (TIMER_1_PRESCALE_ENUM * 4))
++#define TIMER_1_PRESCALED_CLK (TIMER_INPUT_CLOCK / TIMER_1_PRESCALE_VALUE)
++
++#define CLOCK_TICK_RATE (TIMER_1_PRESCALED_CLK)
++
++#endif // __ASM_ARCH_TIMEX_H
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/uncompress.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/uncompress.h
+--- linux-2.6.24/include/asm-arm/arch-oxnas/uncompress.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/uncompress.h 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,43 @@
++/* linux/include/asm-arm/arch-oxnas0/uncompress.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.
++*/
++
++#ifndef __ASM_ARCH_UNCOMPRESS_H
++#define __ASM_ARCH_UNCOMPRESS_H
++
++#include <asm/arch/hardware.h>
++
++static inline void putc(int c)
++{
++#ifdef CONFIG_ARCH_OXNAS_UART1
++ static volatile unsigned char* uart = (volatile unsigned char*)UART_1_BASE_PA;
++#elif defined(CONFIG_ARCH_OXNAS_UART2)
++ static volatile unsigned char* uart = (volatile unsigned char*)UART_2_BASE_PA;
++#elif defined(CONFIG_ARCH_OXNAS_UART3)
++ static volatile unsigned char* uart = (volatile unsigned char*)UART_3_BASE_PA;
++#elif defined(CONFIG_ARCH_OXNAS_UART4)
++ static volatile unsigned char* uart = (volatile unsigned char*)UART_4_BASE_PA;
++#else
++#define NO_UART
++#endif
++
++#ifndef NO_UART
++ while (!(uart[5] & 0x20)) { /* LSR reg THR empty bit */
++ barrier();
++ }
++ uart[0] = c; /* THR register */
++#endif // NO_UART
++}
++
++static inline void flush(void)
++{
++}
++
++#define arch_decomp_setup()
++
++#define arch_decomp_wdog()
++
++#endif // __ASM_ARCH_UNCOMPRESS_H
+diff -Nurd linux-2.6.24/include/asm-arm/arch-oxnas/vmalloc.h linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/vmalloc.h
+--- linux-2.6.24/include/asm-arm/arch-oxnas/vmalloc.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-oxnas/vmalloc.h 2008-06-11 17:45:12.000000000 +0200
+@@ -0,0 +1,29 @@
++/* linux/include/asm-arm/arch-oxnas/vmalloc.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.
++ */
++
++#ifndef __ASM_ARCH_VMALLOC_H
++#define __ASM_ARCH_VMALLOC_H
++
++/*
++ * Just any arbitrary offset to the start of the vmalloc VM area: the
++ * current 8MB value just means that there will be a 8MB "hole" after the
++ * physical memory until the kernel virtual memory starts. That means that
++ * any out-of-bounds memory accesses will hopefully be caught.
++ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
++ * area for the same reason. ;)
++ */
++
++#define VMALLOC_OFFSET (8*1024*1024)
++/* Fix the VMALLOC start adr from the maximum possible SDRAM adr, so that
++ * it's possible to have Linux use only part of the available SDRAM without
++ * vmalloc/ioremap aliasing with the kernel mapping of the entire SDRAM */
++#define MAX_SDRAM_ADR (__phys_to_virt(SDRAM_PA) + (SDRAM_SIZE))
++#define VMALLOC_START (((unsigned long)MAX_SDRAM_ADR + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
++#define VMALLOC_VMADDR(x) ((unsigned long)(x))
++#define VMALLOC_END (0xE0000000)
++
++#endif // __ASM_ARCH_VMALLOC_H
+diff -Nurd linux-2.6.24/include/asm-arm/arch-pxa/pxa-regs.h linux-2.6.24-oxe810/include/asm-arm/arch-pxa/pxa-regs.h
+--- linux-2.6.24/include/asm-arm/arch-pxa/pxa-regs.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/arch-pxa/pxa-regs.h 2008-06-11 17:45:03.000000000 +0200
+@@ -1669,6 +1669,7 @@
+ #define SSCR1_RSRE (1 << 20) /* Receive Service Request Enable */
+ #define SSCR1_TINTE (1 << 19) /* Receiver Time-out Interrupt enable */
+ #define SSCR1_PINTE (1 << 18) /* Peripheral Trailing Byte Interupt Enable */
++#define SSCR1_IFS (1 << 16) /* Invert Frame Signal */
+ #define SSCR1_STRF (1 << 15) /* Select FIFO or EFWR */
+ #define SSCR1_EFWR (1 << 14) /* Enable FIFO Write/Read */
+
+diff -Nurd linux-2.6.24/include/asm-arm/assembler.h linux-2.6.24-oxe810/include/asm-arm/assembler.h
+--- linux-2.6.24/include/asm-arm/assembler.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/assembler.h 2008-06-11 17:45:14.000000000 +0200
+@@ -48,8 +48,10 @@
+
+ /*
+ * Data preload for architectures that support it
++ * OXNAS altered to >= 6 from >= 5 as 926 supports pld, but implements it as
++ * nop, so wastes instruction cycles to include pld support
+ */
+-#if __LINUX_ARM_ARCH__ >= 5
++#if __LINUX_ARM_ARCH__ >= 6
+ #define PLD(code...) code
+ #else
+ #define PLD(code...)
+diff -Nurd linux-2.6.24/include/asm-arm/io.h linux-2.6.24-oxe810/include/asm-arm/io.h
+--- linux-2.6.24/include/asm-arm/io.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/io.h 2008-06-11 17:45:14.000000000 +0200
+@@ -108,27 +108,24 @@
+ *
+ * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space.
+ */
+-#ifdef __io
+-#define outb(v,p) __raw_writeb(v,__io(p))
+-#define outw(v,p) __raw_writew((__force __u16) \
+- cpu_to_le16(v),__io(p))
+-#define outl(v,p) __raw_writel((__force __u32) \
+- cpu_to_le32(v),__io(p))
++extern unsigned int pciio_read( u32 addr, unsigned int size );
++extern void pciio_write(unsigned int data, u32 addr, unsigned int size );
+
+-#define inb(p) ({ __u8 __v = __raw_readb(__io(p)); __v; })
+-#define inw(p) ({ __u16 __v = le16_to_cpu((__force __le16) \
+- __raw_readw(__io(p))); __v; })
+-#define inl(p) ({ __u32 __v = le32_to_cpu((__force __le32) \
+- __raw_readl(__io(p))); __v; })
++extern void outb(unsigned char v, u32 p);
++extern void outw(unsigned short v, u32 p);
++extern void outl(unsigned long v, u32 p);
+
+-#define outsb(p,d,l) __raw_writesb(__io(p),d,l)
+-#define outsw(p,d,l) __raw_writesw(__io(p),d,l)
+-#define outsl(p,d,l) __raw_writesl(__io(p),d,l)
++extern unsigned char inb(u32 p);
++extern unsigned short inw(u32 p);
++extern unsigned long inl(u32 p);
+
+-#define insb(p,d,l) __raw_readsb(__io(p),d,l)
+-#define insw(p,d,l) __raw_readsw(__io(p),d,l)
+-#define insl(p,d,l) __raw_readsl(__io(p),d,l)
+-#endif
++extern void outsb(u32 p, unsigned char * from, u32 len);
++extern void outsw(u32 p, unsigned short * from, u32 len);
++extern void outsl(u32 p, unsigned long * from, u32 len);
++
++extern void insb(u32 p, unsigned char * to, u32 len);
++extern void insw(u32 p, unsigned short * to, u32 len);
++extern void insl(u32 p, unsigned long * to, u32 len);
+
+ #define outb_p(val,port) outb((val),(port))
+ #define outw_p(val,port) outw((val),(port))
+diff -Nurd linux-2.6.24/include/asm-arm/uaccess.h linux-2.6.24-oxe810/include/asm-arm/uaccess.h
+--- linux-2.6.24/include/asm-arm/uaccess.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/uaccess.h 2008-06-11 17:45:14.000000000 +0200
+@@ -383,9 +383,30 @@
+
+
+ #ifdef CONFIG_MMU
++#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
++extern unsigned long __must_check __copy_from_user_alt(void *to, const void __user *from, unsigned long n);
++static inline unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n)
++{
++ if (n >= CONFIG_OXNAS_INSTRUMENT_COPIES_THRESHOLD) printk("__copy_from_user() %lu bytes\n", n);
++ return __copy_from_user_alt(to, from , n);
++}
++extern unsigned long __must_check __copy_to_user_alt(void __user *to, const void *from, unsigned long n);
++static inline unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n)
++{
++ if (n >= CONFIG_OXNAS_INSTRUMENT_COPIES_THRESHOLD) printk("__copy_to_user() %lu bytes\n", n);
++ return __copy_to_user_alt(to, from , n);
++}
++extern unsigned long __must_check __clear_user_alt(void __user *addr, unsigned long n);
++static inline unsigned long __must_check __clear_user(void __user *addr, unsigned long n)
++{
++ if (n >= CONFIG_OXNAS_INSTRUMENT_COPIES_THRESHOLD) printk("__clear_user() %lu bytes\n", n);
++ return __clear_user_alt(addr, n);
++}
++#else // CONFIG_OXNAS_INSTRUMENT_COPIES
+ extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n);
+ extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n);
+ extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n);
++#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
+ #else
+ #define __copy_from_user(to,from,n) (memcpy(to, (void __force *)from, n), 0)
+ #define __copy_to_user(to,from,n) (memcpy((void __force *)to, from, n), 0)
+@@ -397,8 +418,15 @@
+
+ static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
++#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
++ if (n >= CONFIG_OXNAS_INSTRUMENT_COPIES_THRESHOLD) printk("copy_from_user() %lu bytes\n", n);
++#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
+ if (access_ok(VERIFY_READ, from, n))
++#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
++ n = __copy_from_user_alt(to, from, n);
++#else // CONFIG_OXNAS_INSTRUMENT_COPIES
+ n = __copy_from_user(to, from, n);
++#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
+ else /* security hole - plug it */
+ memzero(to, n);
+ return n;
+@@ -406,8 +434,15 @@
+
+ static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
++#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
++ if (n >= CONFIG_OXNAS_INSTRUMENT_COPIES_THRESHOLD) printk("copy_to_user() %lu bytes\n", n);
++#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
+ if (access_ok(VERIFY_WRITE, to, n))
++#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
++ n = __copy_to_user_alt(to, from, n);
++#else // CONFIG_OXNAS_INSTRUMENT_COPIES
+ n = __copy_to_user(to, from, n);
++#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
+ return n;
+ }
+
+@@ -416,8 +451,15 @@
+
+ static inline unsigned long __must_check clear_user(void __user *to, unsigned long n)
+ {
++#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
++ if (n >= CONFIG_OXNAS_INSTRUMENT_COPIES_THRESHOLD) printk("clear_user() %lu bytes\n", n);
++#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
+ if (access_ok(VERIFY_WRITE, to, n))
++#ifdef CONFIG_OXNAS_INSTRUMENT_COPIES
++ n = __clear_user_alt(to, n);
++#else // CONFIG_OXNAS_INSTRUMENT_COPIES
+ n = __clear_user(to, n);
++#endif // CONFIG_OXNAS_INSTRUMENT_COPIES
+ return n;
+ }
+
+diff -Nurd linux-2.6.24/include/asm-arm/unaligned.h linux-2.6.24-oxe810/include/asm-arm/unaligned.h
+--- linux-2.6.24/include/asm-arm/unaligned.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/unaligned.h 2008-06-11 17:45:14.000000000 +0200
+@@ -40,16 +40,16 @@
+ */
+
+ #define __get_unaligned_2_le(__p) \
+- (__p[0] | __p[1] << 8)
++ (unsigned int)(__p[0] | __p[1] << 8)
+
+ #define __get_unaligned_2_be(__p) \
+- (__p[0] << 8 | __p[1])
++ (unsigned int)(__p[0] << 8 | __p[1])
+
+ #define __get_unaligned_4_le(__p) \
+- (__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24)
++ (unsigned int)(__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24)
+
+ #define __get_unaligned_4_be(__p) \
+- (__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3])
++ (unsigned int)(__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3])
+
+ #define __get_unaligned_8_le(__p) \
+ ((unsigned long long)__get_unaligned_4_le((__p+4)) << 32 | \
+diff -Nurd linux-2.6.24/include/asm-arm/unistd.h linux-2.6.24-oxe810/include/asm-arm/unistd.h
+--- linux-2.6.24/include/asm-arm/unistd.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-arm/unistd.h 2008-06-11 17:45:14.000000000 +0200
+@@ -379,6 +379,7 @@
+ #define __NR_timerfd (__NR_SYSCALL_BASE+350)
+ #define __NR_eventfd (__NR_SYSCALL_BASE+351)
+ #define __NR_fallocate (__NR_SYSCALL_BASE+352)
++#define __NR_samba_reserve (__NR_SYSCALL_BASE+353)
+
+ /*
+ * The following SWIs are ARM private.
+diff -Nurd linux-2.6.24/include/asm-powerpc/pmac_feature.h linux-2.6.24-oxe810/include/asm-powerpc/pmac_feature.h
+--- linux-2.6.24/include/asm-powerpc/pmac_feature.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-powerpc/pmac_feature.h 2008-06-11 17:44:57.000000000 +0200
+@@ -392,6 +392,14 @@
+ #define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v)))
+ #define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v)))
+
++/* Uninorth variant:
++ *
++ * 0 = not uninorth
++ * 1 = U1.x or U2.x
++ * 3 = U3
++ * 4 = U4
++ */
++extern int pmac_get_uninorth_variant(void);
+
+ #endif /* __ASM_POWERPC_PMAC_FEATURE_H */
+ #endif /* __KERNEL__ */
+diff -Nurd linux-2.6.24/include/asm-x86/apic_32.h linux-2.6.24-oxe810/include/asm-x86/apic_32.h
+--- linux-2.6.24/include/asm-x86/apic_32.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-x86/apic_32.h 2008-06-11 17:44:30.000000000 +0200
+@@ -109,7 +109,7 @@
+ extern void setup_secondary_APIC_clock (void);
+ extern int APIC_init_uniprocessor (void);
+
+-extern void enable_NMI_through_LVT0 (void * dummy);
++extern void enable_NMI_through_LVT0(void);
+
+ #define ARCH_APICTIMER_STOPS_ON_C3 1
+
+diff -Nurd linux-2.6.24/include/asm-x86/futex_32.h linux-2.6.24-oxe810/include/asm-x86/futex_32.h
+--- linux-2.6.24/include/asm-x86/futex_32.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-x86/futex_32.h 2008-06-11 17:44:30.000000000 +0200
+@@ -28,7 +28,7 @@
+ "1: movl %2, %0\n\
+ movl %0, %3\n" \
+ insn "\n" \
+-"2: " LOCK_PREFIX "cmpxchgl %3, %2\n\
++"2: lock ; cmpxchgl %3, %2\n\
+ jnz 1b\n\
+ 3: .section .fixup,\"ax\"\n\
+ 4: mov %5, %1\n\
+@@ -68,7 +68,7 @@
+ #endif
+ switch (op) {
+ case FUTEX_OP_ADD:
+- __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret,
++ __futex_atomic_op1("lock ; xaddl %0, %2", ret,
+ oldval, uaddr, oparg);
+ break;
+ case FUTEX_OP_OR:
+@@ -111,7 +111,7 @@
+ return -EFAULT;
+
+ __asm__ __volatile__(
+- "1: " LOCK_PREFIX "cmpxchgl %3, %1 \n"
++ "1: lock ; cmpxchgl %3, %1 \n"
+
+ "2: .section .fixup, \"ax\" \n"
+ "3: mov %2, %0 \n"
+diff -Nurd linux-2.6.24/include/asm-x86/futex_64.h linux-2.6.24-oxe810/include/asm-x86/futex_64.h
+--- linux-2.6.24/include/asm-x86/futex_64.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-x86/futex_64.h 2008-06-11 17:44:30.000000000 +0200
+@@ -27,7 +27,7 @@
+ "1: movl %2, %0\n\
+ movl %0, %3\n" \
+ insn "\n" \
+-"2: " LOCK_PREFIX "cmpxchgl %3, %2\n\
++"2: lock ; cmpxchgl %3, %2\n\
+ jnz 1b\n\
+ 3: .section .fixup,\"ax\"\n\
+ 4: mov %5, %1\n\
+@@ -62,7 +62,7 @@
+ __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
+ break;
+ case FUTEX_OP_ADD:
+- __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval,
++ __futex_atomic_op1("lock ; xaddl %0, %2", ret, oldval,
+ uaddr, oparg);
+ break;
+ case FUTEX_OP_OR:
+@@ -101,7 +101,7 @@
+ return -EFAULT;
+
+ __asm__ __volatile__(
+- "1: " LOCK_PREFIX "cmpxchgl %3, %1 \n"
++ "1: lock ; cmpxchgl %3, %1 \n"
+
+ "2: .section .fixup, \"ax\" \n"
+ "3: mov %2, %0 \n"
+diff -Nurd linux-2.6.24/include/asm-x86/io_apic_64.h linux-2.6.24-oxe810/include/asm-x86/io_apic_64.h
+--- linux-2.6.24/include/asm-x86/io_apic_64.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-x86/io_apic_64.h 2008-06-11 17:44:30.000000000 +0200
+@@ -129,7 +129,7 @@
+
+ extern int sis_apic_bug; /* dummy */
+
+-void enable_NMI_through_LVT0 (void * dummy);
++void enable_NMI_through_LVT0(void);
+
+ extern spinlock_t i8259A_lock;
+
+diff -Nurd linux-2.6.24/include/asm-x86/processor_32.h linux-2.6.24-oxe810/include/asm-x86/processor_32.h
+--- linux-2.6.24/include/asm-x86/processor_32.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/asm-x86/processor_32.h 2008-06-11 17:44:30.000000000 +0200
+@@ -712,9 +712,10 @@
+ #define ASM_NOP6 K7_NOP6
+ #define ASM_NOP7 K7_NOP7
+ #define ASM_NOP8 K7_NOP8
+-#elif defined(CONFIG_M686) || defined(CONFIG_MPENTIUMII) || \
++#elif (defined(CONFIG_M686) || defined(CONFIG_MPENTIUMII) || \
+ defined(CONFIG_MPENTIUMIII) || defined(CONFIG_MPENTIUMM) || \
+- defined(CONFIG_MCORE2) || defined(CONFIG_PENTIUM4)
++ defined(CONFIG_MCORE2) || defined(CONFIG_PENTIUM4)) && \
++ !defined(CONFIG_X86_GENERIC)
+ #define ASM_NOP1 P6_NOP1
+ #define ASM_NOP2 P6_NOP2
+ #define ASM_NOP3 P6_NOP3
+diff -Nurd linux-2.6.24/include/linux/bio.h linux-2.6.24-oxe810/include/linux/bio.h
+--- linux-2.6.24/include/linux/bio.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/bio.h 2008-06-11 17:45:39.000000000 +0200
+@@ -114,6 +114,15 @@
+ void *bi_private;
+
+ bio_destructor_t *bi_destructor; /* destructor */
++
++ /*
++ * The raid settings for the bio, this should only be used by the oxsemi
++ * sata driver to control raid hardware and the request merging code in
++ * ll_rw_blk.c to prevent merging of requests to hwraid and non-hwraid
++ *partitions.
++ */
++ u32 bi_raid;
++
+ };
+
+ /*
+diff -Nurd linux-2.6.24/include/linux/byteorder/generic.h linux-2.6.24-oxe810/include/linux/byteorder/generic.h
+--- linux-2.6.24/include/linux/byteorder/generic.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/byteorder/generic.h 2008-06-11 17:45:26.000000000 +0200
+@@ -146,6 +146,36 @@
+ #define htons(x) ___htons(x)
+ #define ntohs(x) ___ntohs(x)
+
++static inline void le16_add_cpu(__le16 *var, u16 val)
++{
++ *var = cpu_to_le16(le16_to_cpu(*var) + val);
++}
++
++static inline void le32_add_cpu(__le32 *var, u32 val)
++{
++ *var = cpu_to_le32(le32_to_cpu(*var) + val);
++}
++
++static inline void le64_add_cpu(__le64 *var, u64 val)
++{
++ *var = cpu_to_le64(le64_to_cpu(*var) + val);
++}
++
++static inline void be16_add_cpu(__be16 *var, u16 val)
++{
++ *var = cpu_to_be16(be16_to_cpu(*var) + val);
++}
++
++static inline void be32_add_cpu(__be32 *var, u32 val)
++{
++ *var = cpu_to_be32(be32_to_cpu(*var) + val);
++}
++
++static inline void be64_add_cpu(__be64 *var, u64 val)
++{
++ *var = cpu_to_be64(be64_to_cpu(*var) + val);
++}
++
+ #endif /* KERNEL */
+
+ #endif /* _LINUX_BYTEORDER_GENERIC_H */
+diff -Nurd linux-2.6.24/include/linux/byteorder/swab.h linux-2.6.24-oxe810/include/linux/byteorder/swab.h
+--- linux-2.6.24/include/linux/byteorder/swab.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/byteorder/swab.h 2008-06-11 17:45:26.000000000 +0200
+@@ -61,26 +61,37 @@
+ * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
+ */
+
+-static __inline__ __attribute_const__ __u16 ___swab16(__u16 x)
+-{
+- return x<<8 | x>>8;
+-}
+-static __inline__ __attribute_const__ __u32 ___swab32(__u32 x)
+-{
+- return x<<24 | x>>24 |
+- (x & (__u32)0x0000ff00UL)<<8 |
+- (x & (__u32)0x00ff0000UL)>>8;
+-}
+-static __inline__ __attribute_const__ __u64 ___swab64(__u64 x)
+-{
+- return x<<56 | x>>56 |
+- (x & (__u64)0x000000000000ff00ULL)<<40 |
+- (x & (__u64)0x0000000000ff0000ULL)<<24 |
+- (x & (__u64)0x00000000ff000000ULL)<< 8 |
+- (x & (__u64)0x000000ff00000000ULL)>> 8 |
+- (x & (__u64)0x0000ff0000000000ULL)>>24 |
+- (x & (__u64)0x00ff000000000000ULL)>>40;
+-}
++#define ___swab16(x) \
++({ \
++ __u16 __x = (x); \
++ ((__u16)( \
++ (((__u16)(__x) & (__u16)0x00ffU) << 8) | \
++ (((__u16)(__x) & (__u16)0xff00U) >> 8) )); \
++})
++
++#define ___swab32(x) \
++({ \
++ __u32 __x = (x); \
++ ((__u32)( \
++ (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \
++ (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | \
++ (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | \
++ (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \
++})
++
++#define ___swab64(x) \
++({ \
++ __u64 __x = (x); \
++ ((__u64)( \
++ (__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \
++ (__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \
++ (__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \
++ (__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) | \
++ (__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) | \
++ (__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
++ (__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \
++ (__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56) )); \
++})
+
+ #define ___constant_swab16(x) \
+ ((__u16)( \
+@@ -103,6 +114,7 @@
+ (__u64)(((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \
+ (__u64)(((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56) ))
+
++
+ /*
+ * provide defaults when no architecture-specific optimization is detected
+ */
+diff -Nurd linux-2.6.24/include/linux/dmi.h linux-2.6.24-oxe810/include/linux/dmi.h
+--- linux-2.6.24/include/linux/dmi.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/dmi.h 2008-06-11 17:45:39.000000000 +0200
+@@ -79,7 +79,6 @@
+ extern int dmi_get_year(int field);
+ extern int dmi_name_in_vendors(const char *str);
+ extern int dmi_available;
+-extern char *dmi_get_slot(int slot);
+
+ #else
+
+@@ -90,7 +89,6 @@
+ static inline int dmi_get_year(int year) { return 0; }
+ static inline int dmi_name_in_vendors(const char *s) { return 0; }
+ #define dmi_available 0
+-static inline char *dmi_get_slot(int slot) { return NULL; }
+
+ #endif
+
+diff -Nurd linux-2.6.24/include/linux/fs.h linux-2.6.24-oxe810/include/linux/fs.h
+--- linux-2.6.24/include/linux/fs.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/fs.h 2008-06-11 17:45:39.000000000 +0200
+@@ -1147,7 +1147,7 @@
+ int error;
+ } read_descriptor_t;
+
+-typedef int (*read_actor_t)(read_descriptor_t *, struct page *, unsigned long, unsigned long);
++typedef int (*read_actor_t)(read_descriptor_t *, struct page **, unsigned long, unsigned long);
+
+ /* These macros are for out of kernel modules to test that
+ * the kernel supports the unlocked_ioctl and compat_ioctl
+@@ -1180,7 +1180,9 @@
+ int (*aio_fsync) (struct kiocb *, int datasync);
+ int (*fasync) (int, struct file *, int);
+ int (*lock) (struct file *, int, struct file_lock *);
++ ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *);
+ ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
++ ssize_t (*sendpages) (struct file *, struct page **, int, size_t, loff_t *, int);
+ unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
+ int (*check_flags)(int);
+ int (*dir_notify)(struct file *filp, unsigned long arg);
+@@ -1791,7 +1793,8 @@
+
+ extern int generic_file_mmap(struct file *, struct vm_area_struct *);
+ extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *);
+-extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
++extern int file_read_actor(read_descriptor_t * desc, struct page **page, unsigned long offset, unsigned long size);
++extern int file_send_actor(read_descriptor_t * desc, struct page **page, unsigned long offset, unsigned long size);
+ int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk);
+ extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t);
+ extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t);
+@@ -1803,12 +1806,14 @@
+ unsigned long, loff_t, loff_t *, size_t, ssize_t);
+ extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos);
+ extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos);
++extern ssize_t generic_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *);
+ extern void do_generic_mapping_read(struct address_space *mapping,
+ struct file_ra_state *, struct file *,
+ loff_t *, read_descriptor_t *, read_actor_t);
+ extern int generic_segment_checks(const struct iovec *iov,
+ unsigned long *nr_segs, size_t *count, int access_flags);
+
++
+ /* fs/splice.c */
+ extern ssize_t generic_file_splice_read(struct file *, loff_t *,
+ struct pipe_inode_info *, size_t, unsigned int);
+diff -Nurd linux-2.6.24/include/linux/futex.h linux-2.6.24-oxe810/include/linux/futex.h
+--- linux-2.6.24/include/linux/futex.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/futex.h 2008-06-11 17:45:38.000000000 +0200
+@@ -153,6 +153,7 @@
+ #ifdef CONFIG_FUTEX
+ extern void exit_robust_list(struct task_struct *curr);
+ extern void exit_pi_state_list(struct task_struct *curr);
++extern int futex_cmpxchg_enabled;
+ #else
+ static inline void exit_robust_list(struct task_struct *curr)
+ {
+diff -Nurd linux-2.6.24/include/linux/hrtimer.h linux-2.6.24-oxe810/include/linux/hrtimer.h
+--- linux-2.6.24/include/linux/hrtimer.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/hrtimer.h 2008-06-11 17:45:39.000000000 +0200
+@@ -300,7 +300,7 @@
+
+ /* Precise sleep: */
+ extern long hrtimer_nanosleep(struct timespec *rqtp,
+- struct timespec *rmtp,
++ struct timespec __user *rmtp,
+ const enum hrtimer_mode mode,
+ const clockid_t clockid);
+ extern long hrtimer_nanosleep_restart(struct restart_block *restart_block);
+diff -Nurd linux-2.6.24/include/linux/hugetlb.h linux-2.6.24-oxe810/include/linux/hugetlb.h
+--- linux-2.6.24/include/linux/hugetlb.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/hugetlb.h 2008-06-11 17:45:39.000000000 +0200
+@@ -17,6 +17,7 @@
+ }
+
+ int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *);
++int hugetlb_overcommit_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *);
+ int hugetlb_treat_movable_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *);
+ int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *);
+ int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int, int);
+diff -Nurd linux-2.6.24/include/linux/i2c-id.h linux-2.6.24-oxe810/include/linux/i2c-id.h
+--- linux-2.6.24/include/linux/i2c-id.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/i2c-id.h 2008-06-11 17:45:39.000000000 +0200
+@@ -203,6 +203,7 @@
+ #define I2C_HW_B_CX2341X 0x010020 /* Conexant CX2341X MPEG encoder cards */
+ #define I2C_HW_B_INTELFB 0x010021 /* intel framebuffer driver */
+ #define I2C_HW_B_CX23885 0x010022 /* conexant 23885 based tv cards (bus1) */
++#define I2C_HW_B_OXNAS 0x010023 /* Oxford Semiconductor OX800 */
+
+ /* --- PCF 8584 based algorithms */
+ #define I2C_HW_P_LP 0x020000 /* Parallel port interface */
+diff -Nurd linux-2.6.24/include/linux/irq.h linux-2.6.24-oxe810/include/linux/irq.h
+--- linux-2.6.24/include/linux/irq.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/irq.h 2008-06-11 17:45:39.000000000 +0200
+@@ -367,6 +367,9 @@
+ __set_irq_handler(irq, handle, 1, NULL);
+ }
+
++extern void set_irq_noprobe(unsigned int irq);
++extern void set_irq_probe(unsigned int irq);
++
+ /* Handle dynamic irq creation and destruction */
+ extern int create_irq(void);
+ extern void destroy_irq(unsigned int irq);
+diff -Nurd linux-2.6.24/include/linux/ktime.h linux-2.6.24-oxe810/include/linux/ktime.h
+--- linux-2.6.24/include/linux/ktime.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/ktime.h 2008-06-11 17:45:39.000000000 +0200
+@@ -310,6 +310,8 @@
+ return ktime_sub_ns(kt, usec * 1000);
+ }
+
++extern ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs);
++
+ /*
+ * The resolution of the clocks. The resolution value is returned in
+ * the clock_getres() system call to give application programmers an
+diff -Nurd linux-2.6.24/include/linux/leds.h linux-2.6.24-oxe810/include/linux/leds.h
+--- linux-2.6.24/include/linux/leds.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/leds.h 2008-06-11 17:45:38.000000000 +0200
+@@ -123,5 +123,11 @@
+ struct gpio_led *leds;
+ };
+
++/* Trigger specific functions */
++#ifdef CONFIG_WDC_LEDS_TRIGGER_SATA_DISK
++extern void wdc_ledtrig_sata_activity(void);
++#else
++#define wdc_ledtrig_sata_activity() do {} while(0)
++#endif
+
+ #endif /* __LINUX_LEDS_H_INCLUDED */
+diff -Nurd linux-2.6.24/include/linux/libata.h linux-2.6.24-oxe810/include/linux/libata.h
+--- linux-2.6.24/include/linux/libata.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/libata.h 2008-06-11 17:45:39.000000000 +0200
+@@ -238,7 +238,7 @@
+ /* various lengths of time */
+ ATA_TMOUT_BOOT = 30 * HZ, /* heuristic */
+ ATA_TMOUT_BOOT_QUICK = 7 * HZ, /* heuristic */
+- ATA_TMOUT_INTERNAL = 30 * HZ,
++ ATA_TMOUT_INTERNAL = 10 * HZ,
+ ATA_TMOUT_INTERNAL_QUICK = 5 * HZ,
+
+ /* FIXME: GoVault needs 2s but we can't afford that without
+@@ -662,7 +662,7 @@
+ };
+
+ struct ata_port_operations {
+- void (*dev_config) (struct ata_device *);
++ void (*dev_config) (struct ata_port *, struct ata_device *);
+
+ void (*set_piomode) (struct ata_port *, struct ata_device *);
+ void (*set_dmamode) (struct ata_port *, struct ata_device *);
+@@ -675,6 +675,7 @@
+ u8 (*check_status)(struct ata_port *ap);
+ u8 (*check_altstatus)(struct ata_port *ap);
+ void (*dev_select)(struct ata_port *ap, unsigned int device);
++ unsigned int (*dev_chk)(struct ata_port *ap, unsigned int device);
+
+ void (*phy_reset) (struct ata_port *ap); /* obsolete */
+ int (*set_mode) (struct ata_link *link, struct ata_device **r_failed_dev);
+@@ -689,6 +690,8 @@
+ void (*data_xfer) (struct ata_device *, unsigned char *, unsigned int, int);
+
+ int (*qc_defer) (struct ata_queued_cmd *qc);
++ struct ata_queued_cmd* (*qc_new)(struct ata_port *ap);
++ void (*qc_free)(struct ata_queued_cmd *qc);
+ void (*qc_prep) (struct ata_queued_cmd *qc);
+ unsigned int (*qc_issue) (struct ata_queued_cmd *qc);
+
+@@ -724,6 +727,7 @@
+
+ void (*bmdma_stop) (struct ata_queued_cmd *qc);
+ u8 (*bmdma_status) (struct ata_port *ap);
++ void (*pio_task)(struct work_struct *work);
+ };
+
+ struct ata_port_info {
+diff -Nurd linux-2.6.24/include/linux/mii.h linux-2.6.24-oxe810/include/linux/mii.h
+--- linux-2.6.24/include/linux/mii.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/mii.h 2008-06-11 17:45:39.000000000 +0200
+@@ -21,18 +21,18 @@
+ #define MII_EXPANSION 0x06 /* Expansion register */
+ #define MII_CTRL1000 0x09 /* 1000BASE-T control */
+ #define MII_STAT1000 0x0a /* 1000BASE-T status */
+-#define MII_ESTATUS 0x0f /* Extended Status */
+-#define MII_DCOUNTER 0x12 /* Disconnect counter */
+-#define MII_FCSCOUNTER 0x13 /* False carrier counter */
+-#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
+-#define MII_RERRCOUNTER 0x15 /* Receive error counter */
+-#define MII_SREVISION 0x16 /* Silicon revision */
+-#define MII_RESV1 0x17 /* Reserved... */
+-#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
+-#define MII_PHYADDR 0x19 /* PHY address */
+-#define MII_RESV2 0x1a /* Reserved... */
+-#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
+-#define MII_NCONFIG 0x1c /* Network interface config */
++#define MII_ESTATUS 0x0f /* Extended Status */
++//#define MII_DCOUNTER 0x12 /* Disconnect counter */
++//#define MII_FCSCOUNTER 0x13 /* False carrier counter */
++//#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
++//#define MII_RERRCOUNTER 0x15 /* Receive error counter */
++//#define MII_SREVISION 0x16 /* Silicon revision */
++//#define MII_RESV1 0x17 /* Reserved... */
++//#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
++//#define MII_PHYADDR 0x19 /* PHY address */
++//#define MII_RESV2 0x1a /* Reserved... */
++//#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
++//#define MII_NCONFIG 0x1c /* Network interface config */
+
+ /* Basic mode control register. */
+ #define BMCR_RESV 0x003f /* Unused... */
+@@ -121,9 +121,9 @@
+ #define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */
+
+ /* N-way test register. */
+-#define NWAYTEST_RESV1 0x00ff /* Unused... */
+-#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */
+-#define NWAYTEST_RESV2 0xfe00 /* Unused... */
++//#define NWAYTEST_RESV1 0x00ff /* Unused... */
++//#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */
++//#define NWAYTEST_RESV2 0xfe00 /* Unused... */
+
+ /* 1000BASE-T Control register */
+ #define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */
+@@ -157,7 +157,9 @@
+
+ unsigned int full_duplex : 1; /* is full duplex? */
+ unsigned int force_media : 1; /* is autoneg. disabled? */
+- unsigned int supports_gmii : 1; /* are GMII registers supported? */
++ unsigned int using_1000 : 1; /* the PHY is using 1000Mb rate */
++ unsigned int using_100 : 1; /* the PHY is using 100Mb rate */
++ unsigned int using_pause : 1; /* the PHY will generate pause frames */
+
+ struct net_device *dev;
+ int (*mdio_read) (struct net_device *dev, int phy_id, int location);
+@@ -170,9 +172,16 @@
+ extern int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
+ extern int mii_check_gmii_support(struct mii_if_info *mii);
+ extern void mii_check_link (struct mii_if_info *mii);
+-extern unsigned int mii_check_media (struct mii_if_info *mii,
+- unsigned int ok_to_print,
+- unsigned int init_media);
++extern unsigned int mii_check_media(struct mii_if_info *mii,
++ unsigned int ok_to_print,
++ unsigned int init_media);
++extern unsigned int mii_check_media_ex(struct mii_if_info *mii,
++ unsigned int ok_to_print,
++ unsigned int init_media,
++ int *has_gigabit_changed,
++ int *has_pause_changed,
++ void (*link_state_change_callback)(int link_state, void* arg),
++ void *link_state_change_arg);
+ extern int generic_mii_ioctl(struct mii_if_info *mii_if,
+ struct mii_ioctl_data *mii_data, int cmd,
+ unsigned int *duplex_changed);
+@@ -216,6 +225,23 @@
+ return ret;
+ }
+
++static inline unsigned int mii_nway_result_1000(unsigned int lpa_1000, unsigned int advertised_1000)
++{
++ int full_negotiated = (lpa_1000 & LPA_1000FULL) &&
++ (advertised_1000 & ADVERTISE_1000FULL);
++
++ int half_negotiated = (lpa_1000 & LPA_1000HALF) &&
++ (advertised_1000 & ADVERTISE_1000HALF);
++
++ if (full_negotiated) {
++ return LPA_1000FULL;
++ } else if (half_negotiated) {
++ return LPA_1000HALF;
++ } else {
++ return 0;
++ }
++}
++
+ /**
+ * mii_duplex
+ * @duplex_lock: Non-zero if duplex is locked at full
+diff -Nurd linux-2.6.24/include/linux/moduleparam.h linux-2.6.24-oxe810/include/linux/moduleparam.h
+--- linux-2.6.24/include/linux/moduleparam.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/moduleparam.h 2008-06-11 17:45:39.000000000 +0200
+@@ -62,6 +62,16 @@
+ void *elem;
+ };
+
++/* On alpha, ia64 and ppc64 relocations to global data cannot go into
++ read-only sections (which is part of respective UNIX ABI on these
++ platforms). So 'const' makes no sense and even causes compile failures
++ with some compilers. */
++#if defined(CONFIG_ALPHA) || defined(CONFIG_IA64) || defined(CONFIG_PPC64)
++#define __moduleparam_const
++#else
++#define __moduleparam_const const
++#endif
++
+ /* This is the fundamental function for registering boot/module
+ parameters. perm sets the visibility in sysfs: 000 means it's
+ not there, read bits mean it's readable, write bits mean it's
+@@ -71,7 +81,7 @@
+ static int __param_perm_check_##name __attribute__((unused)) = \
+ BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)); \
+ static const char __param_str_##name[] = prefix #name; \
+- static struct kernel_param const __param_##name \
++ static struct kernel_param __moduleparam_const __param_##name \
+ __attribute_used__ \
+ __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
+ = { __param_str_##name, perm, set, get, { arg } }
+diff -Nurd linux-2.6.24/include/linux/net.h linux-2.6.24-oxe810/include/linux/net.h
+--- linux-2.6.24/include/linux/net.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/net.h 2008-06-11 17:45:39.000000000 +0200
+@@ -172,6 +172,8 @@
+ struct vm_area_struct * vma);
+ ssize_t (*sendpage) (struct socket *sock, struct page *page,
+ int offset, size_t size, int flags);
++ ssize_t (*sendpages) (struct socket *sock, struct page **page,
++ int offset, size_t size, int flags);
+ };
+
+ struct net_proto_family {
+diff -Nurd linux-2.6.24/include/linux/raid/raid1.h linux-2.6.24-oxe810/include/linux/raid/raid1.h
+--- linux-2.6.24/include/linux/raid/raid1.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/raid/raid1.h 2008-06-11 17:45:26.000000000 +0200
+@@ -61,6 +61,10 @@
+
+ mempool_t *r1bio_pool;
+ mempool_t *r1buf_pool;
++
++ /** This contains flags that can be included with the BIOs generated by
++ writes to set the correct hardware RAID modes */
++ u32 hw_raid1_settings;
+ };
+
+ typedef struct r1_private_data_s conf_t;
+diff -Nurd linux-2.6.24/include/linux/serial_reg.h linux-2.6.24-oxe810/include/linux/serial_reg.h
+--- linux-2.6.24/include/linux/serial_reg.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/serial_reg.h 2008-06-11 17:45:39.000000000 +0200
+@@ -133,6 +133,15 @@
+
+ #define UART_SCR 7 /* I/O: Scratch Register */
+
++/* Oxsemi NAS UART extra registers */
++#define UART_DLF 0x09 /* Oxsemi 16550 fractional divider */
++#define UART_RX_FILL 0x0a
++#define UART_TX_SPACE 0x0b
++#define UART_WIDE_ACCESS 0x0c
++#define UART_XON_CHAR 0x10
++#define UART_XOFF_CHAR 0x11
++#define UART_DMA 0x12
++
+ /*
+ * DLAB=1
+ */
+diff -Nurd linux-2.6.24/include/linux/syscalls.h linux-2.6.24-oxe810/include/linux/syscalls.h
+--- linux-2.6.24/include/linux/syscalls.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/syscalls.h 2008-06-11 17:45:39.000000000 +0200
+@@ -611,6 +611,7 @@
+ const struct itimerspec __user *utmr);
+ asmlinkage long sys_eventfd(unsigned int count);
+ asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len);
++asmlinkage long sys_samba_reserve(int fd, void __user *info);
+
+ int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
+
+diff -Nurd linux-2.6.24/include/linux/trustees.h linux-2.6.24-oxe810/include/linux/trustees.h
+--- linux-2.6.24/include/linux/trustees.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/trustees.h 2008-06-11 17:45:39.000000000 +0200
+@@ -0,0 +1,108 @@
++/*
++ * Trustees ACL Project
++ *
++ * Copyright (c) 1999-2000 Vyacheslav Zavadsky
++ * Copyright (c) 2004 Andrew Ruder (aeruder@ksu.edu)
++ *
++ * 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, version 2.
++ *
++ * Structs, defines and function definitions intended for export
++ *
++ */
++
++#ifndef _LINUX_TRUSTEE_STRUCT_H
++
++#define _LINUX_TRUSTEE_STRUCT_H
++#include <linux/types.h>
++
++#define TRUSTEES_APIVERSION 2
++#define TRUSTEES_APIVERSION_STR "2"
++
++#define TRUSTEE_EXECUTE_BIT 0
++#define TRUSTEE_READ_BIT 1
++#define TRUSTEE_WRITE_BIT 2
++#define TRUSTEE_BROWSE_BIT 3
++#define TRUSTEE_READ_DIR_BIT 4
++#define TRUSTEE_USE_UNIX_BIT 5
++#define TRUSTEE_NUM_ACL_BITS (TRUSTEE_USE_UNIX_BIT+1)
++#define TRUSTEE_EXECUTE_MASK (1 << TRUSTEE_EXECUTE_BIT)
++#define TRUSTEE_READ_MASK (1 << TRUSTEE_READ_BIT)
++#define TRUSTEE_WRITE_MASK (1 << TRUSTEE_WRITE_BIT)
++#define TRUSTEE_BROWSE_MASK (1 << TRUSTEE_BROWSE_BIT)
++#define TRUSTEE_READ_DIR_MASK (1 << TRUSTEE_READ_DIR_BIT)
++#define TRUSTEE_USE_UNIX_MASK (1 << TRUSTEE_USE_UNIX_BIT)
++#define TRUSTEE_ACL_MASK ((1 << TRUSTEE_NUM_ACL_BITS)-1)
++
++#define TRUSTEE_ALLOW_DENY_BIT 7
++#define TRUSTEE_IS_GROUP_BIT 6
++#define TRUSTEE_CLEAR_SET_BIT 8
++#define TRUSTEE_ONE_LEVEL_BIT 9
++#define TRUSTEE_NOT_BIT 10
++#define TRUSTEE_ALL_BIT 11
++#define TRUSTEE_ALLOW_DENY_MASK (1 << TRUSTEE_ALLOW_DENY_BIT) /* set if deny */
++#define TRUSTEE_IS_GROUP_MASK (1 << TRUSTEE_IS_GROUP_BIT)
++#define TRUSTEE_CLEAR_SET_MASK (1 << TRUSTEE_CLEAR_SET_BIT) /* set if clear */
++#define TRUSTEE_ONE_LEVEL_MASK (1 << TRUSTEE_ONE_LEVEL_BIT)
++#define TRUSTEE_NOT_MASK (1 << TRUSTEE_NOT_BIT)
++#define TRUSTEE_ALL_MASK (1 << TRUSTEE_ALL_BIT)
++
++#define trustee_acl __u16
++#define trustee_default_acl TRUSTEE_USE_UNIX_MASK
++
++struct trustee_permission {
++ trustee_acl mask;
++ union {
++ __kernel_uid32_t uid;
++ __kernel_gid32_t gid;
++ } u;
++};
++
++#ifndef __KERNEL__
++#ifndef __user
++#define __user
++#endif
++#endif
++
++struct trustee_command {
++ unsigned command;
++ unsigned numargs;
++};
++
++/* Most arguments that any command will take */
++
++#define TRUSTEE_MAX_ARGS 6
++
++/* Starts a table
++ * No arguments
++ */
++#define TRUSTEE_COMMAND_TABLE_START 1
++
++/* Ends a table successfully.
++ * No arguments
++ */
++#define TRUSTEE_COMMAND_TABLE_STOP 2
++
++/* Adds a trustee
++ * Arguments:
++ * filename (char [])
++ * struct trustee_permission
++ * device-name (char [])
++ * device number (u32)
++ */
++#define TRUSTEE_COMMAND_ADD 3
++
++/* Removes all trustees
++ * No arguments
++ */
++#define TRUSTEE_COMMAND_REMOVE_ALL 2
++
++/* Makes a filesystem ignorecase
++ * Arguments:
++ * device-name (char [])
++ * device number (u32)
++ */
++#define TRUSTEE_COMMAND_MAKE_IC 5
++
++#endif /* _LINUX_TRUSTEE_STRUCT_H */
+diff -Nurd linux-2.6.24/include/linux/wait.h linux-2.6.24-oxe810/include/linux/wait.h
+--- linux-2.6.24/include/linux/wait.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/linux/wait.h 2008-06-11 17:45:39.000000000 +0200
+@@ -161,6 +161,22 @@
+ #define wake_up_locked(x) __wake_up_locked((x), TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE)
+ #define wake_up_interruptible_sync(x) __wake_up_sync((x),TASK_INTERRUPTIBLE, 1)
+
++#ifdef CONFIG_DEBUG_LOCK_ALLOC
++/*
++ * macro to avoid include hell
++ */
++#define wake_up_nested(x, s) \
++do { \
++ unsigned long flags; \
++ \
++ spin_lock_irqsave_nested(&(x)->lock, flags, (s)); \
++ wake_up_locked(x); \
++ spin_unlock_irqrestore(&(x)->lock, flags); \
++} while (0)
++#else
++#define wake_up_nested(x, s) wake_up(x)
++#endif
++
+ #define __wait_event(wq, condition) \
+ do { \
+ DEFINE_WAIT(__wait); \
+diff -Nurd linux-2.6.24/include/net/inet_sock.h linux-2.6.24-oxe810/include/net/inet_sock.h
+--- linux-2.6.24/include/net/inet_sock.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/net/inet_sock.h 2008-06-11 17:44:45.000000000 +0200
+@@ -175,7 +175,8 @@
+ static inline unsigned int inet_ehashfn(const __be32 laddr, const __u16 lport,
+ const __be32 faddr, const __be16 fport)
+ {
+- return jhash_2words((__force __u32) laddr ^ (__force __u32) faddr,
++ return jhash_3words((__force __u32) laddr,
++ (__force __u32) faddr,
+ ((__u32) lport) << 16 | (__force __u32)fport,
+ inet_ehash_secret);
+ }
+diff -Nurd linux-2.6.24/include/net/sock.h linux-2.6.24-oxe810/include/net/sock.h
+--- linux-2.6.24/include/net/sock.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/net/sock.h 2008-06-11 17:44:45.000000000 +0200
+@@ -549,6 +549,8 @@
+ int *addr_len);
+ int (*sendpage)(struct sock *sk, struct page *page,
+ int offset, size_t size, int flags);
++ int (*sendpages)(struct sock *sk, struct page **page,
++ int offset, size_t size, int flags);
+ int (*bind)(struct sock *sk,
+ struct sockaddr *uaddr, int addr_len);
+
+diff -Nurd linux-2.6.24/include/net/tcp.h linux-2.6.24-oxe810/include/net/tcp.h
+--- linux-2.6.24/include/net/tcp.h 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/include/net/tcp.h 2008-06-11 17:44:45.000000000 +0200
+@@ -285,6 +285,7 @@
+ extern int tcp_sendmsg(struct kiocb *iocb, struct socket *sock,
+ struct msghdr *msg, size_t size);
+ extern ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags);
++extern ssize_t tcp_sendpages(struct socket *sock, struct page **page, int offset, size_t size, int flags);
+
+ extern int tcp_ioctl(struct sock *sk,
+ int cmd,
+diff -Nurd linux-2.6.24/kernel/audit.c linux-2.6.24-oxe810/kernel/audit.c
+--- linux-2.6.24/kernel/audit.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/kernel/audit.c 2008-06-11 17:43:47.000000000 +0200
+@@ -1200,13 +1200,17 @@
+ static inline int audit_expand(struct audit_buffer *ab, int extra)
+ {
+ struct sk_buff *skb = ab->skb;
+- int ret = pskb_expand_head(skb, skb_headroom(skb), extra,
+- ab->gfp_mask);
++ int oldtail = skb_tailroom(skb);
++ int ret = pskb_expand_head(skb, 0, extra, ab->gfp_mask);
++ int newtail = skb_tailroom(skb);
++
+ if (ret < 0) {
+ audit_log_lost("out of memory in audit_expand");
+ return 0;
+ }
+- return skb_tailroom(skb);
++
++ skb->truesize += newtail - oldtail;
++ return newtail;
+ }
+
+ /*
+diff -Nurd linux-2.6.24/kernel/compat.c linux-2.6.24-oxe810/kernel/compat.c
+--- linux-2.6.24/kernel/compat.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/kernel/compat.c 2008-06-11 17:43:47.000000000 +0200
+@@ -40,10 +40,36 @@
+ __put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
+ }
+
++static long compat_nanosleep_restart(struct restart_block *restart)
++{
++ struct compat_timespec __user *rmtp;
++ struct timespec rmt;
++ mm_segment_t oldfs;
++ long ret;
++
++ rmtp = (struct compat_timespec __user *)(restart->arg1);
++ restart->arg1 = (unsigned long)&rmt;
++ oldfs = get_fs();
++ set_fs(KERNEL_DS);
++ ret = hrtimer_nanosleep_restart(restart);
++ set_fs(oldfs);
++
++ if (ret) {
++ restart->fn = compat_nanosleep_restart;
++ restart->arg1 = (unsigned long)rmtp;
++
++ if (rmtp && put_compat_timespec(&rmt, rmtp))
++ return -EFAULT;
++ }
++
++ return ret;
++}
++
+ asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp,
+ struct compat_timespec __user *rmtp)
+ {
+ struct timespec tu, rmt;
++ mm_segment_t oldfs;
+ long ret;
+
+ if (get_compat_timespec(&tu, rqtp))
+@@ -52,11 +78,21 @@
+ if (!timespec_valid(&tu))
+ return -EINVAL;
+
+- ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL,
+- CLOCK_MONOTONIC);
++ oldfs = get_fs();
++ set_fs(KERNEL_DS);
++ ret = hrtimer_nanosleep(&tu,
++ rmtp ? (struct timespec __user *)&rmt : NULL,
++ HRTIMER_MODE_REL, CLOCK_MONOTONIC);
++ set_fs(oldfs);
+
+- if (ret && rmtp) {
+- if (put_compat_timespec(&rmt, rmtp))
++ if (ret) {
++ struct restart_block *restart
++ = ¤t_thread_info()->restart_block;
++
++ restart->fn = compat_nanosleep_restart;
++ restart->arg1 = (unsigned long)rmtp;
++
++ if (rmtp && put_compat_timespec(&rmt, rmtp))
+ return -EFAULT;
+ }
+
+diff -Nurd linux-2.6.24/kernel/futex.c linux-2.6.24-oxe810/kernel/futex.c
+--- linux-2.6.24/kernel/futex.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/kernel/futex.c 2008-06-11 17:43:47.000000000 +0200
+@@ -60,6 +60,8 @@
+
+ #include "rtmutex_common.h"
+
++int __read_mostly futex_cmpxchg_enabled;
++
+ #define FUTEX_HASHBITS (CONFIG_BASE_SMALL ? 4 : 8)
+
+ /*
+@@ -466,6 +468,8 @@
+ struct futex_hash_bucket *hb;
+ union futex_key key;
+
++ if (!futex_cmpxchg_enabled)
++ return;
+ /*
+ * We are a ZOMBIE and nobody can enqueue itself on
+ * pi_state_list anymore, but we have to be careful
+@@ -1854,6 +1858,8 @@
+ sys_set_robust_list(struct robust_list_head __user *head,
+ size_t len)
+ {
++ if (!futex_cmpxchg_enabled)
++ return -ENOSYS;
+ /*
+ * The kernel knows only one size for now:
+ */
+@@ -1878,6 +1884,9 @@
+ struct robust_list_head __user *head;
+ unsigned long ret;
+
++ if (!futex_cmpxchg_enabled)
++ return -ENOSYS;
++
+ if (!pid)
+ head = current->robust_list;
+ else {
+@@ -1980,6 +1989,9 @@
+ unsigned long futex_offset;
+ int rc;
+
++ if (!futex_cmpxchg_enabled)
++ return;
++
+ /*
+ * Fetch the list head (which was registered earlier, via
+ * sys_set_robust_list()):
+@@ -2034,7 +2046,7 @@
+ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
+ u32 __user *uaddr2, u32 val2, u32 val3)
+ {
+- int ret;
++ int ret = -ENOSYS;
+ int cmd = op & FUTEX_CMD_MASK;
+ struct rw_semaphore *fshared = NULL;
+
+@@ -2062,13 +2074,16 @@
+ ret = futex_wake_op(uaddr, fshared, uaddr2, val, val2, val3);
+ break;
+ case FUTEX_LOCK_PI:
+- ret = futex_lock_pi(uaddr, fshared, val, timeout, 0);
++ if (futex_cmpxchg_enabled)
++ ret = futex_lock_pi(uaddr, fshared, val, timeout, 0);
+ break;
+ case FUTEX_UNLOCK_PI:
+- ret = futex_unlock_pi(uaddr, fshared);
++ if (futex_cmpxchg_enabled)
++ ret = futex_unlock_pi(uaddr, fshared);
+ break;
+ case FUTEX_TRYLOCK_PI:
+- ret = futex_lock_pi(uaddr, fshared, 0, timeout, 1);
++ if (futex_cmpxchg_enabled)
++ ret = futex_lock_pi(uaddr, fshared, 0, timeout, 1);
+ break;
+ default:
+ ret = -ENOSYS;
+@@ -2094,7 +2109,7 @@
+
+ t = timespec_to_ktime(ts);
+ if (cmd == FUTEX_WAIT)
+- t = ktime_add(ktime_get(), t);
++ t = ktime_add_safe(ktime_get(), t);
+ tp = &t;
+ }
+ /*
+@@ -2123,8 +2138,29 @@
+
+ static int __init init(void)
+ {
+- int i = register_filesystem(&futex_fs_type);
++ u32 curval;
++ int i;
++
++ /*
++ * This will fail and we want it. Some arch implementations do
++ * runtime detection of the futex_atomic_cmpxchg_inatomic()
++ * functionality. We want to know that before we call in any
++ * of the complex code paths. Also we want to prevent
++ * registration of robust lists in that case. NULL is
++ * guaranteed to fault and we get -EFAULT on functional
++ * implementation, the non functional ones will return
++ * -ENOSYS.
++ */
++ curval = cmpxchg_futex_value_locked(NULL, 0, 0);
++ if (curval == -EFAULT)
++ futex_cmpxchg_enabled = 1;
+
++ for (i = 0; i < ARRAY_SIZE(futex_queues); i++) {
++ plist_head_init(&futex_queues[i].chain, &futex_queues[i].lock);
++ spin_lock_init(&futex_queues[i].lock);
++ }
++
++ i = register_filesystem(&futex_fs_type);
+ if (i)
+ return i;
+
+@@ -2134,10 +2170,6 @@
+ return PTR_ERR(futex_mnt);
+ }
+
+- for (i = 0; i < ARRAY_SIZE(futex_queues); i++) {
+- plist_head_init(&futex_queues[i].chain, &futex_queues[i].lock);
+- spin_lock_init(&futex_queues[i].lock);
+- }
+ return 0;
+ }
+ __initcall(init);
+diff -Nurd linux-2.6.24/kernel/futex_compat.c linux-2.6.24-oxe810/kernel/futex_compat.c
+--- linux-2.6.24/kernel/futex_compat.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/kernel/futex_compat.c 2008-06-11 17:43:47.000000000 +0200
+@@ -54,6 +54,9 @@
+ compat_long_t futex_offset;
+ int rc;
+
++ if (!futex_cmpxchg_enabled)
++ return;
++
+ /*
+ * Fetch the list head (which was registered earlier, via
+ * sys_set_robust_list()):
+@@ -115,6 +118,9 @@
+ compat_sys_set_robust_list(struct compat_robust_list_head __user *head,
+ compat_size_t len)
+ {
++ if (!futex_cmpxchg_enabled)
++ return -ENOSYS;
++
+ if (unlikely(len != sizeof(*head)))
+ return -EINVAL;
+
+@@ -130,6 +136,9 @@
+ struct compat_robust_list_head __user *head;
+ unsigned long ret;
+
++ if (!futex_cmpxchg_enabled)
++ return -ENOSYS;
++
+ if (!pid)
+ head = current->compat_robust_list;
+ else {
+@@ -175,7 +184,7 @@
+
+ t = timespec_to_ktime(ts);
+ if (cmd == FUTEX_WAIT)
+- t = ktime_add(ktime_get(), t);
++ t = ktime_add_safe(ktime_get(), t);
+ tp = &t;
+ }
+ if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE)
+diff -Nurd linux-2.6.24/kernel/hrtimer.c linux-2.6.24-oxe810/kernel/hrtimer.c
+--- linux-2.6.24/kernel/hrtimer.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/kernel/hrtimer.c 2008-06-11 17:43:47.000000000 +0200
+@@ -325,6 +325,24 @@
+ }
+ #endif /* BITS_PER_LONG >= 64 */
+
++/*
++ * Add two ktime values and do a safety check for overflow:
++ */
++
++ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs)
++{
++ ktime_t res = ktime_add(lhs, rhs);
++
++ /*
++ * We use KTIME_SEC_MAX here, the maximum timeout which we can
++ * return to user space in a timespec:
++ */
++ if (res.tv64 < 0 || res.tv64 < lhs.tv64 || res.tv64 < rhs.tv64)
++ res = ktime_set(KTIME_SEC_MAX, 0);
++
++ return res;
++}
++
+ /* High resolution timer related functions */
+ #ifdef CONFIG_HIGH_RES_TIMERS
+
+@@ -409,6 +427,8 @@
+ ktime_t expires = ktime_sub(timer->expires, base->offset);
+ int res;
+
++ WARN_ON_ONCE(timer->expires.tv64 < 0);
++
+ /*
+ * When the callback is running, we do not reprogram the clock event
+ * device. The timer callback is either running on a different CPU or
+@@ -419,6 +439,15 @@
+ if (hrtimer_callback_running(timer))
+ return 0;
+
++ /*
++ * CLOCK_REALTIME timer might be requested with an absolute
++ * expiry time which is less than base->offset. Nothing wrong
++ * about that, just avoid to call into the tick code, which
++ * has now objections against negative expiry values.
++ */
++ if (expires.tv64 < 0)
++ return -ETIME;
++
+ if (expires.tv64 >= expires_next->tv64)
+ return 0;
+
+@@ -682,13 +711,7 @@
+ */
+ orun++;
+ }
+- timer->expires = ktime_add(timer->expires, interval);
+- /*
+- * Make sure, that the result did not wrap with a very large
+- * interval.
+- */
+- if (timer->expires.tv64 < 0)
+- timer->expires = ktime_set(KTIME_SEC_MAX, 0);
++ timer->expires = ktime_add_safe(timer->expires, interval);
+
+ return orun;
+ }
+@@ -839,7 +862,7 @@
+ new_base = switch_hrtimer_base(timer, base);
+
+ if (mode == HRTIMER_MODE_REL) {
+- tim = ktime_add(tim, new_base->get_time());
++ tim = ktime_add_safe(tim, new_base->get_time());
+ /*
+ * CONFIG_TIME_LOW_RES is a temporary way for architectures
+ * to signal that they simply return xtime in
+@@ -848,16 +871,8 @@
+ * timeouts. This will go away with the GTOD framework.
+ */
+ #ifdef CONFIG_TIME_LOW_RES
+- tim = ktime_add(tim, base->resolution);
++ tim = ktime_add_safe(tim, base->resolution);
+ #endif
+- /*
+- * Careful here: User space might have asked for a
+- * very long sleep, so the add above might result in a
+- * negative number, which enqueues the timer in front
+- * of the queue.
+- */
+- if (tim.tv64 < 0)
+- tim.tv64 = KTIME_MAX;
+ }
+ timer->expires = tim;
+
+@@ -1291,11 +1306,26 @@
+ return t->task == NULL;
+ }
+
++static int update_rmtp(struct hrtimer *timer, struct timespec __user *rmtp)
++{
++ struct timespec rmt;
++ ktime_t rem;
++
++ rem = ktime_sub(timer->expires, timer->base->get_time());
++ if (rem.tv64 <= 0)
++ return 0;
++ rmt = ktime_to_timespec(rem);
++
++ if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
++ return -EFAULT;
++
++ return 1;
++}
++
+ long __sched hrtimer_nanosleep_restart(struct restart_block *restart)
+ {
+ struct hrtimer_sleeper t;
+- struct timespec *rmtp;
+- ktime_t time;
++ struct timespec __user *rmtp;
+
+ restart->fn = do_no_restart_syscall;
+
+@@ -1305,12 +1335,11 @@
+ if (do_nanosleep(&t, HRTIMER_MODE_ABS))
+ return 0;
+
+- rmtp = (struct timespec *)restart->arg1;
++ rmtp = (struct timespec __user *)restart->arg1;
+ if (rmtp) {
+- time = ktime_sub(t.timer.expires, t.timer.base->get_time());
+- if (time.tv64 <= 0)
+- return 0;
+- *rmtp = ktime_to_timespec(time);
++ int ret = update_rmtp(&t.timer, rmtp);
++ if (ret <= 0)
++ return ret;
+ }
+
+ restart->fn = hrtimer_nanosleep_restart;
+@@ -1319,12 +1348,11 @@
+ return -ERESTART_RESTARTBLOCK;
+ }
+
+-long hrtimer_nanosleep(struct timespec *rqtp, struct timespec *rmtp,
++long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
+ const enum hrtimer_mode mode, const clockid_t clockid)
+ {
+ struct restart_block *restart;
+ struct hrtimer_sleeper t;
+- ktime_t rem;
+
+ hrtimer_init(&t.timer, clockid, mode);
+ t.timer.expires = timespec_to_ktime(*rqtp);
+@@ -1336,10 +1364,9 @@
+ return -ERESTARTNOHAND;
+
+ if (rmtp) {
+- rem = ktime_sub(t.timer.expires, t.timer.base->get_time());
+- if (rem.tv64 <= 0)
+- return 0;
+- *rmtp = ktime_to_timespec(rem);
++ int ret = update_rmtp(&t.timer, rmtp);
++ if (ret <= 0)
++ return ret;
+ }
+
+ restart = ¤t_thread_info()->restart_block;
+@@ -1355,8 +1382,7 @@
+ asmlinkage long
+ sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp)
+ {
+- struct timespec tu, rmt;
+- int ret;
++ struct timespec tu;
+
+ if (copy_from_user(&tu, rqtp, sizeof(tu)))
+ return -EFAULT;
+@@ -1364,15 +1390,7 @@
+ if (!timespec_valid(&tu))
+ return -EINVAL;
+
+- ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL,
+- CLOCK_MONOTONIC);
+-
+- if (ret && rmtp) {
+- if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
+- return -EFAULT;
+- }
+-
+- return ret;
++ return hrtimer_nanosleep(&tu, rmtp, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
+ }
+
+ /*
+diff -Nurd linux-2.6.24/kernel/irq/chip.c linux-2.6.24-oxe810/kernel/irq/chip.c
+--- linux-2.6.24/kernel/irq/chip.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/kernel/irq/chip.c 2008-06-11 17:43:44.000000000 +0200
+@@ -246,6 +246,17 @@
+ }
+
+ /*
++ * default shutdown function
++ */
++static void default_shutdown(unsigned int irq)
++{
++ struct irq_desc *desc = irq_desc + irq;
++
++ desc->chip->mask(irq);
++ desc->status |= IRQ_MASKED;
++}
++
++/*
+ * Fixup enable/disable function pointers
+ */
+ void irq_chip_set_defaults(struct irq_chip *chip)
+@@ -256,8 +267,15 @@
+ chip->disable = default_disable;
+ if (!chip->startup)
+ chip->startup = default_startup;
++ /*
++ * We use chip->disable, when the user provided its own. When
++ * we have default_disable set for chip->disable, then we need
++ * to use default_shutdown, otherwise the irq line is not
++ * disabled on free_irq():
++ */
+ if (!chip->shutdown)
+- chip->shutdown = chip->disable;
++ chip->shutdown = chip->disable != default_disable ?
++ chip->disable : default_shutdown;
+ if (!chip->name)
+ chip->name = chip->typename;
+ if (!chip->end)
+@@ -589,3 +607,39 @@
+ set_irq_chip(irq, chip);
+ __set_irq_handler(irq, handle, 0, name);
+ }
++
++void __init set_irq_noprobe(unsigned int irq)
++{
++ struct irq_desc *desc;
++ unsigned long flags;
++
++ if (irq >= NR_IRQS) {
++ printk(KERN_ERR "Trying to mark IRQ%d non-probeable\n", irq);
++
++ return;
++ }
++
++ desc = irq_desc + irq;
++
++ spin_lock_irqsave(&desc->lock, flags);
++ desc->status |= IRQ_NOPROBE;
++ spin_unlock_irqrestore(&desc->lock, flags);
++}
++
++void __init set_irq_probe(unsigned int irq)
++{
++ struct irq_desc *desc;
++ unsigned long flags;
++
++ if (irq >= NR_IRQS) {
++ printk(KERN_ERR "Trying to mark IRQ%d probeable\n", irq);
++
++ return;
++ }
++
++ desc = irq_desc + irq;
++
++ spin_lock_irqsave(&desc->lock, flags);
++ desc->status &= ~IRQ_NOPROBE;
++ spin_unlock_irqrestore(&desc->lock, flags);
++}
+diff -Nurd linux-2.6.24/kernel/posix-timers.c linux-2.6.24-oxe810/kernel/posix-timers.c
+--- linux-2.6.24/kernel/posix-timers.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/kernel/posix-timers.c 2008-06-11 17:43:47.000000000 +0200
+@@ -766,9 +766,11 @@
+ /* SIGEV_NONE timers are not queued ! See common_timer_get */
+ if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) {
+ /* Setup correct expiry time for relative timers */
+- if (mode == HRTIMER_MODE_REL)
+- timer->expires = ktime_add(timer->expires,
+- timer->base->get_time());
++ if (mode == HRTIMER_MODE_REL) {
++ timer->expires =
++ ktime_add_safe(timer->expires,
++ timer->base->get_time());
++ }
+ return 0;
+ }
+
+@@ -981,20 +983,9 @@
+ static int common_nsleep(const clockid_t which_clock, int flags,
+ struct timespec *tsave, struct timespec __user *rmtp)
+ {
+- struct timespec rmt;
+- int ret;
+-
+- ret = hrtimer_nanosleep(tsave, rmtp ? &rmt : NULL,
+- flags & TIMER_ABSTIME ?
+- HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
+- which_clock);
+-
+- if (ret && rmtp) {
+- if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
+- return -EFAULT;
+- }
+-
+- return ret;
++ return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ?
++ HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
++ which_clock);
+ }
+
+ asmlinkage long
+diff -Nurd linux-2.6.24/kernel/printk.c linux-2.6.24-oxe810/kernel/printk.c
+--- linux-2.6.24/kernel/printk.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/kernel/printk.c 2008-06-11 17:43:47.000000000 +0200
+@@ -625,6 +625,11 @@
+ return r;
+ }
+
++#if defined(CONFIG_DEBUG_LL) && defined(CONFIG_OXNAS_EARLY_PRINTK)
++/* Declare the printascii function that is specific to ARM platforms */
++extern void printascii(const char *);
++#endif
++
+ /* cpu currently holding logbuf_lock */
+ static volatile unsigned int printk_cpu = UINT_MAX;
+
+@@ -653,6 +658,11 @@
+ /* Emit the output into the temporary buffer */
+ printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args);
+
++#if defined(CONFIG_DEBUG_LL) && defined(CONFIG_OXNAS_EARLY_PRINTK)
++ /* Send output down the early UART */
++ printascii(printk_buf);
++#endif
++
+ /*
+ * Copy the output into log_buf. If the caller didn't provide
+ * appropriate log level tags, we insert them here
+diff -Nurd linux-2.6.24/kernel/relay.c linux-2.6.24-oxe810/kernel/relay.c
+--- linux-2.6.24/kernel/relay.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/kernel/relay.c 2008-06-11 17:43:47.000000000 +0200
+@@ -92,6 +92,7 @@
+ return -EINVAL;
+
+ vma->vm_ops = &relay_file_mmap_ops;
++ vma->vm_flags |= VM_DONTEXPAND;
+ vma->vm_private_data = buf;
+ buf->chan->cb->buf_mapped(buf, filp);
+
+@@ -1071,7 +1072,7 @@
+ unsigned int flags,
+ int *nonpad_ret)
+ {
+- unsigned int pidx, poff, total_len, subbuf_pages, ret;
++ unsigned int pidx, poff, total_len, subbuf_pages, nr_pages, ret;
+ struct rchan_buf *rbuf = in->private_data;
+ unsigned int subbuf_size = rbuf->chan->subbuf_size;
+ uint64_t pos = (uint64_t) *ppos;
+@@ -1102,8 +1103,9 @@
+ subbuf_pages = rbuf->chan->alloc_size >> PAGE_SHIFT;
+ pidx = (read_start / PAGE_SIZE) % subbuf_pages;
+ poff = read_start & ~PAGE_MASK;
++ nr_pages = min_t(unsigned int, subbuf_pages, PIPE_BUFFERS);
+
+- for (total_len = 0; spd.nr_pages < subbuf_pages; spd.nr_pages++) {
++ for (total_len = 0; spd.nr_pages < nr_pages; spd.nr_pages++) {
+ unsigned int this_len, this_end, private;
+ unsigned int cur_pos = read_start + total_len;
+
+diff -Nurd linux-2.6.24/kernel/sched.c linux-2.6.24-oxe810/kernel/sched.c
+--- linux-2.6.24/kernel/sched.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/kernel/sched.c 2008-06-11 17:43:47.000000000 +0200
+@@ -4028,11 +4028,10 @@
+ oldprio = p->prio;
+ on_rq = p->se.on_rq;
+ running = task_current(rq, p);
+- if (on_rq) {
++ if (on_rq)
+ dequeue_task(rq, p, 0);
+- if (running)
+- p->sched_class->put_prev_task(rq, p);
+- }
++ if (running)
++ p->sched_class->put_prev_task(rq, p);
+
+ if (rt_prio(prio))
+ p->sched_class = &rt_sched_class;
+@@ -4041,9 +4040,9 @@
+
+ p->prio = prio;
+
++ if (running)
++ p->sched_class->set_curr_task(rq);
+ if (on_rq) {
+- if (running)
+- p->sched_class->set_curr_task(rq);
+ enqueue_task(rq, p, 0);
+ /*
+ * Reschedule if we are currently running on this runqueue and
+@@ -4339,18 +4338,17 @@
+ update_rq_clock(rq);
+ on_rq = p->se.on_rq;
+ running = task_current(rq, p);
+- if (on_rq) {
++ if (on_rq)
+ deactivate_task(rq, p, 0);
+- if (running)
+- p->sched_class->put_prev_task(rq, p);
+- }
++ if (running)
++ p->sched_class->put_prev_task(rq, p);
+
+ oldprio = p->prio;
+ __setscheduler(rq, p, policy, param->sched_priority);
+
++ if (running)
++ p->sched_class->set_curr_task(rq);
+ if (on_rq) {
+- if (running)
+- p->sched_class->set_curr_task(rq);
+ activate_task(rq, p, 0);
+ /*
+ * Reschedule if we are currently running on this runqueue and
+@@ -7110,19 +7108,17 @@
+ running = task_current(rq, tsk);
+ on_rq = tsk->se.on_rq;
+
+- if (on_rq) {
++ if (on_rq)
+ dequeue_task(rq, tsk, 0);
+- if (unlikely(running))
+- tsk->sched_class->put_prev_task(rq, tsk);
+- }
++ if (unlikely(running))
++ tsk->sched_class->put_prev_task(rq, tsk);
+
+ set_task_cfs_rq(tsk, task_cpu(tsk));
+
+- if (on_rq) {
+- if (unlikely(running))
+- tsk->sched_class->set_curr_task(rq);
++ if (unlikely(running))
++ tsk->sched_class->set_curr_task(rq);
++ if (on_rq)
+ enqueue_task(rq, tsk, 0);
+- }
+
+ done:
+ task_rq_unlock(rq, &flags);
+diff -Nurd linux-2.6.24/kernel/sched_fair.c linux-2.6.24-oxe810/kernel/sched_fair.c
+--- linux-2.6.24/kernel/sched_fair.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/kernel/sched_fair.c 2008-06-11 17:43:47.000000000 +0200
+@@ -511,7 +511,7 @@
+
+ if (!initial) {
+ /* sleeps upto a single latency don't count. */
+- if (sched_feat(NEW_FAIR_SLEEPERS) && entity_is_task(se))
++ if (sched_feat(NEW_FAIR_SLEEPERS))
+ vruntime -= sysctl_sched_latency;
+
+ /* ensure we never gain time by being placed backwards. */
+@@ -867,7 +867,11 @@
+ }
+
+ gran = sysctl_sched_wakeup_granularity;
+- if (unlikely(se->load.weight != NICE_0_LOAD))
++ /*
++ * More easily preempt - nice tasks, while not making
++ * it harder for + nice tasks.
++ */
++ if (unlikely(se->load.weight > NICE_0_LOAD))
+ gran = calc_delta_fair(gran, &se->load);
+
+ if (pse->vruntime + gran < se->vruntime)
+diff -Nurd linux-2.6.24/kernel/softirq.c linux-2.6.24-oxe810/kernel/softirq.c
+--- linux-2.6.24/kernel/softirq.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/kernel/softirq.c 2008-06-11 17:43:47.000000000 +0200
+@@ -72,7 +72,7 @@
+ {
+ unsigned long flags;
+
+- WARN_ON_ONCE(in_irq());
++ //WARN_ON_ONCE(in_irq());
+
+ raw_local_irq_save(flags);
+ add_preempt_count(SOFTIRQ_OFFSET);
+@@ -134,9 +134,9 @@
+ #ifdef CONFIG_TRACE_IRQFLAGS
+ unsigned long flags;
+
+- WARN_ON_ONCE(in_irq());
++ //WARN_ON_ONCE(in_irq());
+ #endif
+- WARN_ON_ONCE(irqs_disabled());
++ //WARN_ON_ONCE(irqs_disabled());
+
+ #ifdef CONFIG_TRACE_IRQFLAGS
+ local_irq_save(flags);
+diff -Nurd linux-2.6.24/kernel/sysctl.c linux-2.6.24-oxe810/kernel/sysctl.c
+--- linux-2.6.24/kernel/sysctl.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/kernel/sysctl.c 2008-06-11 17:43:47.000000000 +0200
+@@ -306,7 +306,7 @@
+ .procname = "sched_nr_migrate",
+ .data = &sysctl_sched_nr_migrate,
+ .maxlen = sizeof(unsigned int),
+- .mode = 644,
++ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ #endif
+@@ -910,7 +910,7 @@
+ .data = &nr_overcommit_huge_pages,
+ .maxlen = sizeof(nr_overcommit_huge_pages),
+ .mode = 0644,
+- .proc_handler = &proc_doulongvec_minmax,
++ .proc_handler = &hugetlb_overcommit_handler,
+ },
+ #endif
+ {
+diff -Nurd linux-2.6.24/mm/filemap.c linux-2.6.24-oxe810/mm/filemap.c
+--- linux-2.6.24/mm/filemap.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/mm/filemap.c 2008-06-11 17:47:28.000000000 +0200
+@@ -884,12 +884,31 @@
+ unsigned int prev_offset;
+ int error;
+
+- index = *ppos >> PAGE_CACHE_SHIFT;
++ // Page table mod's
++#define MAX_QUEUED_PAGES (65536/PAGE_CACHE_SIZE)
++ // Create the page table
++ struct page* page_table[MAX_QUEUED_PAGES];
++ pgoff_t start_index;
++ unsigned long loop_offset;
++ unsigned long transfer_count;
++ unsigned long start_desc_count;
++ unsigned long index_count;
++ unsigned long desc_remaining;
++
++
++ index = *ppos >> PAGE_CACHE_SHIFT;
+ prev_index = ra->prev_pos >> PAGE_CACHE_SHIFT;
+ prev_offset = ra->prev_pos & (PAGE_CACHE_SIZE-1);
+ last_index = (*ppos + desc->count + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT;
+ offset = *ppos & ~PAGE_CACHE_MASK;
+
++ // Page table mod's
++ start_index = index;
++ index_count = 0;
++ transfer_count = 0;
++ desc_remaining = desc->count;
++ loop_offset = offset;
++
+ for (;;) {
+ struct page *page;
+ pgoff_t end_index;
+@@ -935,12 +954,12 @@
+ nr = PAGE_CACHE_SIZE;
+ if (index == end_index) {
+ nr = ((isize - 1) & ~PAGE_CACHE_MASK) + 1;
+- if (nr <= offset) {
++ if (nr <= loop_offset) {
+ page_cache_release(page);
+ goto out;
+ }
+ }
+- nr = nr - offset;
++ nr = nr - loop_offset;
+
+ /* If users can be writing to this page using arbitrary
+ * virtual addresses, take care about potential aliasing
+@@ -953,30 +972,84 @@
+ * When a sequential read accesses a page several times,
+ * only mark it as accessed the first time.
+ */
+- if (prev_index != index || offset != prev_offset)
++ if (prev_index != index || loop_offset != prev_offset)
+ mark_page_accessed(page);
+ prev_index = index;
+
+ /*
+ * Ok, we have the page, and it's up-to-date, so
+- * now we can copy it to user space...
+- *
+- * The actor routine returns how many bytes were actually used..
+- * NOTE! This may not be the same as how much of a user buffer
+- * we filled up (we may be padding etc), so we can only update
+- * "pos" here (the actor routine has to update the user buffer
+- * pointers and the remaining count).
++ * now we can mark it for copy it to user space...
+ */
+- ret = actor(desc, page, offset, nr);
+- offset += ret;
+- index += offset >> PAGE_CACHE_SHIFT;
+- offset &= ~PAGE_CACHE_MASK;
+- prev_offset = offset;
++ page_table[index_count] = page;
+
+- page_cache_release(page);
+- if (ret == nr && desc->count)
+- continue;
+- goto out;
++ index_count++;
++
++ transfer_count += nr;
++
++ if (transfer_count >= desc->count) {
++ loop_offset += desc_remaining;
++ index += loop_offset >> PAGE_CACHE_SHIFT;
++ loop_offset &= ~PAGE_CACHE_MASK;
++ desc_remaining = 0;
++ } else {
++ loop_offset = 0;
++ index++;
++ desc_remaining -= nr;
++ }
++
++ prev_offset = loop_offset;
++ //ra.prev_offset = loop_offset;
++
++ /**
++ * Do we have enough data in the pages so far, or enough
++ * pages left, to satisfy the count specified in the descriptor ?
++ */
++ if ((transfer_count < desc->count) && (index <= end_index) && (index_count < MAX_QUEUED_PAGES)) {
++ continue;
++ }
++
++ /*
++ * The actor routine returns how many bytes were actually used..
++ * NOTE! This may not be the same as how much of a user buffer
++ * we filled up (we may be padding etc), so we can only update
++ * "pos" here (the actor routine has to update the user buffer
++ * pointers and the remaining count).
++ */
++
++ start_desc_count = desc->count;
++
++ ret = actor(desc, page_table, offset, transfer_count);
++
++ /*
++ * Some debug to test if our assumptions about the transfer length are correct
++ * We shouldn't see this message under normal execution
++ */
++
++ if ((start_desc_count != ret) && (transfer_count != ret)) {
++ printk("desc_count %#x, ret %#x, transfer_count %#x\n",start_desc_count,ret, transfer_count);
++ }
++
++ offset += ret;
++ index = start_index + (offset >> PAGE_CACHE_SHIFT);
++
++ offset &= ~PAGE_CACHE_MASK;
++ //ra.prev_offset = offset;
++
++ while (index_count) {
++ index_count--;
++ page_cache_release(page_table[index_count]);
++ }
++
++ if (ret == transfer_count && desc->count) {
++ // should probably think of what to do...
++ index_count = 0;
++ start_index = index;
++ transfer_count = 0;
++ loop_offset = offset;
++ desc_remaining = desc->count;
++ continue;
++ }
++ goto out;
+
+ page_not_up_to_date:
+ /* Get exclusive access to the page ... */
+@@ -1056,6 +1129,7 @@
+ goto readpage;
+ }
+
++
+ out:
+ ra->prev_pos = prev_index;
+ ra->prev_pos <<= PAGE_CACHE_SHIFT;
+@@ -1067,42 +1141,96 @@
+ }
+ EXPORT_SYMBOL(do_generic_mapping_read);
+
+-int file_read_actor(read_descriptor_t *desc, struct page *page,
++int file_read_actor(read_descriptor_t *desc, struct page **page,
+ unsigned long offset, unsigned long size)
+ {
+ char *kaddr;
+ unsigned long left, count = desc->count;
++ unsigned char* dst;
++ unsigned long ret_size;
++
+
+ if (size > count)
+ size = count;
+
++ ret_size = size;
++
++ dst = desc->arg.buf;
++
+ /*
+ * Faults on the destination of a read are common, so do it before
+ * taking the kmap.
+ */
+- if (!fault_in_pages_writeable(desc->arg.buf, size)) {
+- kaddr = kmap_atomic(page, KM_USER0);
+- left = __copy_to_user_inatomic(desc->arg.buf,
+- kaddr + offset, size);
+- kunmap_atomic(kaddr, KM_USER0);
+- if (left == 0)
+- goto success;
+- }
++ while (size) {
++ unsigned long psize = PAGE_CACHE_SIZE - offset;
++ struct page *page_it;
++
++ psize = PAGE_CACHE_SIZE - offset;
++ if (size <= psize) {
++ psize = size;
++ }
++
++ if (fault_in_pages_writeable(dst, psize))
++ break;
++
++ page_it = *page;
++
++ kaddr = kmap_atomic(page_it, KM_USER0);
++ left = __copy_to_user_inatomic(dst,
++ kaddr + offset, psize);
++ kunmap_atomic(kaddr, KM_USE R0);
++ if (left != 0)
++ break;
++
++ size -= psize;
++ page++;
++ offset += psize;
++ dst += psize;
++ offset &= (PAGE_CACHE_SIZE - 1);
++ }
++
++ if (size == 0)
++ goto success;
++
+
+ /* Do it the slow way */
+- kaddr = kmap(page);
+- left = __copy_to_user(desc->arg.buf, kaddr + offset, size);
+- kunmap(page);
+
+- if (left) {
+- size -= left;
+- desc->error = -EFAULT;
+- }
++
++ while (size) {
++ unsigned long psize;
++ struct page *page_it;
++
++ psize = PAGE_CACHE_SIZE - offset;
++ if (size <= psize) {
++ psize = size;
++ }
++
++
++ page_it = *page;
++
++ kaddr = kmap(page_it);
++
++ left = __copy_to_user(dst, kaddr + offset, psize);
++ kunmap(page_it);
++
++ if (left) {
++ size -= left;
++ desc->error = -EFAULT;
++ break;
++ }
++ page++;
++ offset += psize;
++ dst += psize;
++ offset &= (PAGE_CACHE_SIZE - 1);
++
++ size -= psize;
++ }
++
+ success:
+- desc->count = count - size;
+- desc->written += size;
+- desc->arg.buf += size;
+- return size;
++ desc->count = count - ret_size;
++ desc->written += ret_size;
++ desc->arg.buf += ret_size;
++ return ret_size;
+ }
+
+ /*
+@@ -1219,6 +1347,46 @@
+ }
+ EXPORT_SYMBOL(generic_file_aio_read);
+
++int file_send_actor(read_descriptor_t * desc, struct page **page, unsigned long offset, unsigned long size)
++{
++ ssize_t written;
++ unsigned long count = desc->count;
++ struct file *file = desc->arg.data;
++
++ if (size > count)
++ size = count;
++
++ written = file->f_op->sendpages(file, page, offset,
++ size, &file->f_pos, size<count);
++ if (written < 0) {
++ desc->error = written;
++ written = 0;
++ }
++ desc->count = count - written;
++ desc->written += written;
++ return written;
++}
++
++ssize_t generic_file_sendfile(struct file *in_file, loff_t *ppos,
++ size_t count, read_actor_t actor, void *target)
++{
++ read_descriptor_t desc;
++
++ if (!count)
++ return 0;
++
++ desc.written = 0;
++ desc.count = count;
++ desc.arg.data = target;
++ desc.error = 0;
++
++ do_generic_file_read(in_file, ppos, &desc, actor);
++ if (desc.written)
++ return desc.written;
++ return desc.error;
++}
++EXPORT_SYMBOL(generic_file_sendfile);
++
+ static ssize_t
+ do_readahead(struct address_space *mapping, struct file *filp,
+ pgoff_t index, unsigned long nr)
+@@ -1725,17 +1893,27 @@
+ }
+ EXPORT_SYMBOL(iov_iter_copy_from_user);
+
+-static void __iov_iter_advance_iov(struct iov_iter *i, size_t bytes)
++void iov_iter_advance(struct iov_iter *i, size_t bytes)
+ {
++ BUG_ON(i->count < bytes);
++
+ if (likely(i->nr_segs == 1)) {
+ i->iov_offset += bytes;
++ i->count -= bytes;
+ } else {
+ const struct iovec *iov = i->iov;
+ size_t base = i->iov_offset;
+
+- while (bytes) {
+- int copy = min(bytes, iov->iov_len - base);
++ /*
++ * The !iov->iov_len check ensures we skip over unlikely
++ * zero-length segments (without overruning the iovec).
++ */
++ while (bytes || unlikely(!iov->iov_len && i->count)) {
++ int copy;
+
++ copy = min(bytes, iov->iov_len - base);
++ BUG_ON(!i->count || i->count < copy);
++ i->count -= copy;
+ bytes -= copy;
+ base += copy;
+ if (iov->iov_len == base) {
+@@ -1747,14 +1925,6 @@
+ i->iov_offset = base;
+ }
+ }
+-
+-void iov_iter_advance(struct iov_iter *i, size_t bytes)
+-{
+- BUG_ON(i->count < bytes);
+-
+- __iov_iter_advance_iov(i, bytes);
+- i->count -= bytes;
+-}
+ EXPORT_SYMBOL(iov_iter_advance);
+
+ /*
+@@ -2251,6 +2421,7 @@
+
+ cond_resched();
+
++ iov_iter_advance(i, copied);
+ if (unlikely(copied == 0)) {
+ /*
+ * If we were unable to copy any data at all, we must
+@@ -2264,7 +2435,6 @@
+ iov_iter_single_seg_count(i));
+ goto again;
+ }
+- iov_iter_advance(i, copied);
+ pos += copied;
+ written += copied;
+
+diff -Nurd linux-2.6.24/mm/fremap.c linux-2.6.24-oxe810/mm/fremap.c
+--- linux-2.6.24/mm/fremap.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/mm/fremap.c 2008-06-11 17:47:28.000000000 +0200
+@@ -190,10 +190,13 @@
+ */
+ if (mapping_cap_account_dirty(mapping)) {
+ unsigned long addr;
++ struct file *file = vma->vm_file;
+
+ flags &= MAP_NONBLOCK;
+- addr = mmap_region(vma->vm_file, start, size,
++ get_file(file);
++ addr = mmap_region(file, start, size,
+ flags, vma->vm_flags, pgoff, 1);
++ fput(file);
+ if (IS_ERR_VALUE(addr)) {
+ err = addr;
+ } else {
+diff -Nurd linux-2.6.24/mm/hugetlb.c linux-2.6.24-oxe810/mm/hugetlb.c
+--- linux-2.6.24/mm/hugetlb.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/mm/hugetlb.c 2008-06-11 17:47:28.000000000 +0200
+@@ -119,6 +119,7 @@
+ struct address_space *mapping;
+
+ mapping = (struct address_space *) page_private(page);
++ set_page_private(page, 0);
+ BUG_ON(page_count(page));
+ INIT_LIST_HEAD(&page->lru);
+
+@@ -133,7 +134,6 @@
+ spin_unlock(&hugetlb_lock);
+ if (mapping)
+ hugetlb_put_quota(mapping, 1);
+- set_page_private(page, 0);
+ }
+
+ /*
+@@ -605,6 +605,16 @@
+ return 0;
+ }
+
++int hugetlb_overcommit_handler(struct ctl_table *table, int write,
++ struct file *file, void __user *buffer,
++ size_t *length, loff_t *ppos)
++{
++ spin_lock(&hugetlb_lock);
++ proc_doulongvec_minmax(table, write, file, buffer, length, ppos);
++ spin_unlock(&hugetlb_lock);
++ return 0;
++}
++
+ #endif /* CONFIG_SYSCTL */
+
+ int hugetlb_report_meminfo(char *buf)
+diff -Nurd linux-2.6.24/mm/memory.c linux-2.6.24-oxe810/mm/memory.c
+--- linux-2.6.24/mm/memory.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/mm/memory.c 2008-06-11 17:47:28.000000000 +0200
+@@ -980,6 +980,8 @@
+ int i;
+ unsigned int vm_flags;
+
++ if (len <= 0)
++ return 0;
+ /*
+ * Require read or write permissions.
+ * If 'force' is set, we only require the "MAY" flags.
+diff -Nurd linux-2.6.24/mm/mmap.c linux-2.6.24-oxe810/mm/mmap.c
+--- linux-2.6.24/mm/mmap.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/mm/mmap.c 2008-06-11 17:47:28.000000000 +0200
+@@ -2215,7 +2215,7 @@
+ vma->vm_start = addr;
+ vma->vm_end = addr + len;
+
+- vma->vm_flags = vm_flags | mm->def_flags;
++ vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+
+ vma->vm_ops = &special_mapping_vmops;
+diff -Nurd linux-2.6.24/mm/shmem.c linux-2.6.24-oxe810/mm/shmem.c
+--- linux-2.6.24/mm/shmem.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/mm/shmem.c 2008-06-11 17:47:28.000000000 +0200
+@@ -1681,7 +1681,7 @@
+ * "pos" here (the actor routine has to update the user buffer
+ * pointers and the remaining count).
+ */
+- ret = actor(desc, page, offset, nr);
++ ret = actor(desc, &page, offset, nr);
+ offset += ret;
+ index += offset >> PAGE_CACHE_SHIFT;
+ offset &= ~PAGE_CACHE_MASK;
+diff -Nurd linux-2.6.24/mm/slab.c linux-2.6.24-oxe810/mm/slab.c
+--- linux-2.6.24/mm/slab.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/mm/slab.c 2008-06-11 17:47:28.000000000 +0200
+@@ -304,11 +304,11 @@
+ /*
+ * Need this for bootstrapping a per node allocator.
+ */
+-#define NUM_INIT_LISTS (2 * MAX_NUMNODES + 1)
++#define NUM_INIT_LISTS (3 * MAX_NUMNODES)
+ struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
+ #define CACHE_CACHE 0
+-#define SIZE_AC 1
+-#define SIZE_L3 (1 + MAX_NUMNODES)
++#define SIZE_AC MAX_NUMNODES
++#define SIZE_L3 (2 * MAX_NUMNODES)
+
+ static int drain_freelist(struct kmem_cache *cache,
+ struct kmem_list3 *l3, int tofree);
+@@ -1410,6 +1410,22 @@
+ }
+
+ /*
++ * For setting up all the kmem_list3s for cache whose buffer_size is same as
++ * size of kmem_list3.
++ */
++static void __init set_up_list3s(struct kmem_cache *cachep, int index)
++{
++ int node;
++
++ for_each_online_node(node) {
++ cachep->nodelists[node] = &initkmem_list3[index + node];
++ cachep->nodelists[node]->next_reap = jiffies +
++ REAPTIMEOUT_LIST3 +
++ ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
++ }
++}
++
++/*
+ * Initialisation. Called after the page allocator have been initialised and
+ * before smp_init().
+ */
+@@ -1432,6 +1448,7 @@
+ if (i < MAX_NUMNODES)
+ cache_cache.nodelists[i] = NULL;
+ }
++ set_up_list3s(&cache_cache, CACHE_CACHE);
+
+ /*
+ * Fragmentation resistance on low memory - only use bigger
+@@ -1587,10 +1604,9 @@
+ {
+ int nid;
+
+- /* Replace the static kmem_list3 structures for the boot cpu */
+- init_list(&cache_cache, &initkmem_list3[CACHE_CACHE], node);
+-
+ for_each_online_node(nid) {
++ init_list(&cache_cache, &initkmem_list3[CACHE_CACHE], nid);
++
+ init_list(malloc_sizes[INDEX_AC].cs_cachep,
+ &initkmem_list3[SIZE_AC + nid], nid);
+
+@@ -1960,22 +1976,6 @@
+ }
+ }
+
+-/*
+- * For setting up all the kmem_list3s for cache whose buffer_size is same as
+- * size of kmem_list3.
+- */
+-static void __init set_up_list3s(struct kmem_cache *cachep, int index)
+-{
+- int node;
+-
+- for_each_online_node(node) {
+- cachep->nodelists[node] = &initkmem_list3[index + node];
+- cachep->nodelists[node]->next_reap = jiffies +
+- REAPTIMEOUT_LIST3 +
+- ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
+- }
+-}
+-
+ static void __kmem_cache_destroy(struct kmem_cache *cachep)
+ {
+ int i;
+@@ -2099,7 +2099,7 @@
+ g_cpucache_up = PARTIAL_L3;
+ } else {
+ int node;
+- for_each_node_state(node, N_NORMAL_MEMORY) {
++ for_each_online_node(node) {
+ cachep->nodelists[node] =
+ kmalloc_node(sizeof(struct kmem_list3),
+ GFP_KERNEL, node);
+@@ -2961,11 +2961,10 @@
+ struct array_cache *ac;
+ int node;
+
+- node = numa_node_id();
+-
++retry:
+ check_irq_off();
++ node = numa_node_id();
+ ac = cpu_cache_get(cachep);
+-retry:
+ batchcount = ac->batchcount;
+ if (!ac->touched && batchcount > BATCHREFILL_LIMIT) {
+ /*
+diff -Nurd linux-2.6.24/mm/slub.c linux-2.6.24-oxe810/mm/slub.c
+--- linux-2.6.24/mm/slub.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/mm/slub.c 2008-06-11 17:47:28.000000000 +0200
+@@ -2592,6 +2592,7 @@
+ void kfree(const void *x)
+ {
+ struct page *page;
++ void *object = (void *)x;
+
+ if (unlikely(ZERO_OR_NULL_PTR(x)))
+ return;
+@@ -2601,7 +2602,7 @@
+ put_page(page);
+ return;
+ }
+- slab_free(page->slab, page, (void *)x, __builtin_return_address(0));
++ slab_free(page->slab, page, object, __builtin_return_address(0));
+ }
+ EXPORT_SYMBOL(kfree);
+
+diff -Nurd linux-2.6.24/net/bluetooth/hci_sysfs.c linux-2.6.24-oxe810/net/bluetooth/hci_sysfs.c
+--- linux-2.6.24/net/bluetooth/hci_sysfs.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/bluetooth/hci_sysfs.c 2008-06-11 17:46:02.000000000 +0200
+@@ -12,6 +12,8 @@
+ #undef BT_DBG
+ #define BT_DBG(D...)
+ #endif
++static struct workqueue_struct *btaddconn;
++static struct workqueue_struct *btdelconn;
+
+ static inline char *typetostr(int type)
+ {
+@@ -279,6 +281,8 @@
+ struct hci_conn *conn = container_of(work, struct hci_conn, work);
+ int i;
+
++ flush_workqueue(btdelconn);
++
+ if (device_add(&conn->dev) < 0) {
+ BT_ERR("Failed to register connection device");
+ return;
+@@ -313,7 +317,7 @@
+
+ INIT_WORK(&conn->work, add_conn);
+
+- schedule_work(&conn->work);
++ queue_work(btaddconn, &conn->work);
+ }
+
+ static int __match_tty(struct device *dev, void *data)
+@@ -349,7 +353,7 @@
+
+ INIT_WORK(&conn->work, del_conn);
+
+- schedule_work(&conn->work);
++ queue_work(btdelconn, &conn->work);
+ }
+
+ int hci_register_sysfs(struct hci_dev *hdev)
+@@ -398,28 +402,54 @@
+ {
+ int err;
+
++ btaddconn = create_singlethread_workqueue("btaddconn");
++ if (!btaddconn) {
++ err = -ENOMEM;
++ goto out;
++ }
++
++ btdelconn = create_singlethread_workqueue("btdelconn");
++ if (!btdelconn) {
++ err = -ENOMEM;
++ goto out_del;
++ }
++
+ bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0);
+- if (IS_ERR(bt_platform))
+- return PTR_ERR(bt_platform);
++ if (IS_ERR(bt_platform)) {
++ err = PTR_ERR(bt_platform);
++ goto out_platform;
++ }
+
+ err = bus_register(&bt_bus);
+- if (err < 0) {
+- platform_device_unregister(bt_platform);
+- return err;
+- }
++ if (err < 0)
++ goto out_bus;
+
+ bt_class = class_create(THIS_MODULE, "bluetooth");
+ if (IS_ERR(bt_class)) {
+- bus_unregister(&bt_bus);
+- platform_device_unregister(bt_platform);
+- return PTR_ERR(bt_class);
++ err = PTR_ERR(bt_class);
++ goto out_class;
+ }
+
+ return 0;
++
++out_class:
++ bus_unregister(&bt_bus);
++out_bus:
++ platform_device_unregister(bt_platform);
++out_platform:
++ destroy_workqueue(btdelconn);
++out_del:
++ destroy_workqueue(btaddconn);
++out:
++ return err;
+ }
+
+ void bt_sysfs_cleanup(void)
+ {
++ destroy_workqueue(btaddconn);
++
++ destroy_workqueue(btdelconn);
++
+ class_destroy(bt_class);
+
+ bus_unregister(&bt_bus);
+diff -Nurd linux-2.6.24/net/bridge/netfilter/ebt_dnat.c linux-2.6.24-oxe810/net/bridge/netfilter/ebt_dnat.c
+--- linux-2.6.24/net/bridge/netfilter/ebt_dnat.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/bridge/netfilter/ebt_dnat.c 2008-06-11 17:46:12.000000000 +0200
+@@ -20,8 +20,8 @@
+ {
+ struct ebt_nat_info *info = (struct ebt_nat_info *)data;
+
+- if (skb_make_writable(skb, 0))
+- return NF_DROP;
++ if (!skb_make_writable(skb, 0))
++ return EBT_DROP;
+
+ memcpy(eth_hdr(skb)->h_dest, info->mac, ETH_ALEN);
+ return info->target;
+diff -Nurd linux-2.6.24/net/bridge/netfilter/ebt_redirect.c linux-2.6.24-oxe810/net/bridge/netfilter/ebt_redirect.c
+--- linux-2.6.24/net/bridge/netfilter/ebt_redirect.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/bridge/netfilter/ebt_redirect.c 2008-06-11 17:46:12.000000000 +0200
+@@ -21,8 +21,8 @@
+ {
+ struct ebt_redirect_info *info = (struct ebt_redirect_info *)data;
+
+- if (skb_make_writable(skb, 0))
+- return NF_DROP;
++ if (!skb_make_writable(skb, 0))
++ return EBT_DROP;
+
+ if (hooknr != NF_BR_BROUTING)
+ memcpy(eth_hdr(skb)->h_dest,
+diff -Nurd linux-2.6.24/net/bridge/netfilter/ebt_snat.c linux-2.6.24-oxe810/net/bridge/netfilter/ebt_snat.c
+--- linux-2.6.24/net/bridge/netfilter/ebt_snat.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/bridge/netfilter/ebt_snat.c 2008-06-11 17:46:12.000000000 +0200
+@@ -22,8 +22,8 @@
+ {
+ struct ebt_nat_info *info = (struct ebt_nat_info *) data;
+
+- if (skb_make_writable(skb, 0))
+- return NF_DROP;
++ if (!skb_make_writable(skb, 0))
++ return EBT_DROP;
+
+ memcpy(eth_hdr(skb)->h_source, info->mac, ETH_ALEN);
+ if (!(info->target & NAT_ARP_BIT) &&
+diff -Nurd linux-2.6.24/net/core/dev.c linux-2.6.24-oxe810/net/core/dev.c
+--- linux-2.6.24/net/core/dev.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/core/dev.c 2008-06-11 17:45:57.000000000 +0200
+@@ -1068,8 +1068,6 @@
+ */
+ call_netdevice_notifiers(NETDEV_GOING_DOWN, dev);
+
+- dev_deactivate(dev);
+-
+ clear_bit(__LINK_STATE_START, &dev->state);
+
+ /* Synchronize to scheduled poll. We cannot touch poll list,
+@@ -1080,6 +1078,8 @@
+ */
+ smp_mb__after_clear_bit(); /* Commit netif_running(). */
+
++ dev_deactivate(dev);
++
+ /*
+ * Call the device specific close. This cannot fail.
+ * Only if device is UP
+@@ -2906,7 +2906,7 @@
+ }
+ }
+
+- da = kmalloc(sizeof(*da), GFP_ATOMIC);
++ da = kzalloc(sizeof(*da), GFP_ATOMIC);
+ if (da == NULL)
+ return -ENOMEM;
+ memcpy(da->da_addr, addr, alen);
+diff -Nurd linux-2.6.24/net/ipv4/af_inet.c linux-2.6.24-oxe810/net/ipv4/af_inet.c
+--- linux-2.6.24/net/ipv4/af_inet.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/ipv4/af_inet.c 2008-06-11 17:46:09.000000000 +0200
+@@ -838,6 +838,7 @@
+ .recvmsg = sock_common_recvmsg,
+ .mmap = sock_no_mmap,
+ .sendpage = tcp_sendpage,
++ .sendpages = tcp_sendpages,
+ #ifdef CONFIG_COMPAT
+ .compat_setsockopt = compat_sock_common_setsockopt,
+ .compat_getsockopt = compat_sock_common_getsockopt,
+diff -Nurd linux-2.6.24/net/ipv4/fib_hash.c linux-2.6.24-oxe810/net/ipv4/fib_hash.c
+--- linux-2.6.24/net/ipv4/fib_hash.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/ipv4/fib_hash.c 2008-06-11 17:46:09.000000000 +0200
+@@ -434,19 +434,43 @@
+
+ if (fa && fa->fa_tos == tos &&
+ fa->fa_info->fib_priority == fi->fib_priority) {
+- struct fib_alias *fa_orig;
++ struct fib_alias *fa_first, *fa_match;
+
+ err = -EEXIST;
+ if (cfg->fc_nlflags & NLM_F_EXCL)
+ goto out;
+
++ /* We have 2 goals:
++ * 1. Find exact match for type, scope, fib_info to avoid
++ * duplicate routes
++ * 2. Find next 'fa' (or head), NLM_F_APPEND inserts before it
++ */
++ fa_match = NULL;
++ fa_first = fa;
++ fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
++ list_for_each_entry_continue(fa, &f->fn_alias, fa_list) {
++ if (fa->fa_tos != tos)
++ break;
++ if (fa->fa_info->fib_priority != fi->fib_priority)
++ break;
++ if (fa->fa_type == cfg->fc_type &&
++ fa->fa_scope == cfg->fc_scope &&
++ fa->fa_info == fi) {
++ fa_match = fa;
++ break;
++ }
++ }
++
+ if (cfg->fc_nlflags & NLM_F_REPLACE) {
+ struct fib_info *fi_drop;
+ u8 state;
+
+- if (fi->fib_treeref > 1)
++ fa = fa_first;
++ if (fa_match) {
++ if (fa == fa_match)
++ err = 0;
+ goto out;
+-
++ }
+ write_lock_bh(&fib_hash_lock);
+ fi_drop = fa->fa_info;
+ fa->fa_info = fi;
+@@ -469,20 +493,11 @@
+ * uses the same scope, type, and nexthop
+ * information.
+ */
+- fa_orig = fa;
+- fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
+- list_for_each_entry_continue(fa, &f->fn_alias, fa_list) {
+- if (fa->fa_tos != tos)
+- break;
+- if (fa->fa_info->fib_priority != fi->fib_priority)
+- break;
+- if (fa->fa_type == cfg->fc_type &&
+- fa->fa_scope == cfg->fc_scope &&
+- fa->fa_info == fi)
+- goto out;
+- }
++ if (fa_match)
++ goto out;
++
+ if (!(cfg->fc_nlflags & NLM_F_APPEND))
+- fa = fa_orig;
++ fa = fa_first;
+ }
+
+ err = -ENOENT;
+diff -Nurd linux-2.6.24/net/ipv4/fib_trie.c linux-2.6.24-oxe810/net/ipv4/fib_trie.c
+--- linux-2.6.24/net/ipv4/fib_trie.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/ipv4/fib_trie.c 2008-06-11 17:46:09.000000000 +0200
+@@ -1203,20 +1203,45 @@
+ * and we need to allocate a new one of those as well.
+ */
+
+- if (fa && fa->fa_info->fib_priority == fi->fib_priority) {
+- struct fib_alias *fa_orig;
++ if (fa && fa->fa_tos == tos &&
++ fa->fa_info->fib_priority == fi->fib_priority) {
++ struct fib_alias *fa_first, *fa_match;
+
+ err = -EEXIST;
+ if (cfg->fc_nlflags & NLM_F_EXCL)
+ goto out;
+
++ /* We have 2 goals:
++ * 1. Find exact match for type, scope, fib_info to avoid
++ * duplicate routes
++ * 2. Find next 'fa' (or head), NLM_F_APPEND inserts before it
++ */
++ fa_match = NULL;
++ fa_first = fa;
++ fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
++ list_for_each_entry_continue(fa, fa_head, fa_list) {
++ if (fa->fa_tos != tos)
++ break;
++ if (fa->fa_info->fib_priority != fi->fib_priority)
++ break;
++ if (fa->fa_type == cfg->fc_type &&
++ fa->fa_scope == cfg->fc_scope &&
++ fa->fa_info == fi) {
++ fa_match = fa;
++ break;
++ }
++ }
++
+ if (cfg->fc_nlflags & NLM_F_REPLACE) {
+ struct fib_info *fi_drop;
+ u8 state;
+
+- if (fi->fib_treeref > 1)
++ fa = fa_first;
++ if (fa_match) {
++ if (fa == fa_match)
++ err = 0;
+ goto out;
+-
++ }
+ err = -ENOBUFS;
+ new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
+ if (new_fa == NULL)
+@@ -1228,7 +1253,7 @@
+ new_fa->fa_type = cfg->fc_type;
+ new_fa->fa_scope = cfg->fc_scope;
+ state = fa->fa_state;
+- new_fa->fa_state &= ~FA_S_ACCESSED;
++ new_fa->fa_state = state & ~FA_S_ACCESSED;
+
+ list_replace_rcu(&fa->fa_list, &new_fa->fa_list);
+ alias_free_mem_rcu(fa);
+@@ -1245,20 +1270,11 @@
+ * uses the same scope, type, and nexthop
+ * information.
+ */
+- fa_orig = fa;
+- list_for_each_entry(fa, fa_orig->fa_list.prev, fa_list) {
+- if (fa->fa_tos != tos)
+- break;
+- if (fa->fa_info->fib_priority != fi->fib_priority)
+- break;
+- if (fa->fa_type == cfg->fc_type &&
+- fa->fa_scope == cfg->fc_scope &&
+- fa->fa_info == fi) {
+- goto out;
+- }
+- }
++ if (fa_match)
++ goto out;
++
+ if (!(cfg->fc_nlflags & NLM_F_APPEND))
+- fa = fa_orig;
++ fa = fa_first;
+ }
+ err = -ENOENT;
+ if (!(cfg->fc_nlflags & NLM_F_CREATE))
+@@ -1614,9 +1630,8 @@
+ pr_debug("Deleting %08x/%d tos=%d t=%p\n", key, plen, tos, t);
+
+ fa_to_delete = NULL;
+- fa_head = fa->fa_list.prev;
+-
+- list_for_each_entry(fa, fa_head, fa_list) {
++ fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
++ list_for_each_entry_continue(fa, fa_head, fa_list) {
+ struct fib_info *fi = fa->fa_info;
+
+ if (fa->fa_tos != tos)
+diff -Nurd linux-2.6.24/net/ipv4/inet_diag.c linux-2.6.24-oxe810/net/ipv4/inet_diag.c
+--- linux-2.6.24/net/ipv4/inet_diag.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/ipv4/inet_diag.c 2008-06-11 17:46:09.000000000 +0200
+@@ -259,8 +259,10 @@
+ const struct inet_diag_handler *handler;
+
+ handler = inet_diag_lock_handler(nlh->nlmsg_type);
+- if (!handler)
+- return -ENOENT;
++ if (IS_ERR(handler)) {
++ err = PTR_ERR(handler);
++ goto unlock;
++ }
+
+ hashinfo = handler->idiag_hashinfo;
+ err = -EINVAL;
+@@ -708,8 +710,8 @@
+ struct inet_hashinfo *hashinfo;
+
+ handler = inet_diag_lock_handler(cb->nlh->nlmsg_type);
+- if (!handler)
+- goto no_handler;
++ if (IS_ERR(handler))
++ goto unlock;
+
+ hashinfo = handler->idiag_hashinfo;
+
+@@ -838,7 +840,6 @@
+ cb->args[2] = num;
+ unlock:
+ inet_diag_unlock_handler(handler);
+-no_handler:
+ return skb->len;
+ }
+
+diff -Nurd linux-2.6.24/net/ipv4/ip_output.c linux-2.6.24-oxe810/net/ipv4/ip_output.c
+--- linux-2.6.24/net/ipv4/ip_output.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/ipv4/ip_output.c 2008-06-11 17:46:09.000000000 +0200
+@@ -462,6 +462,7 @@
+ if (skb_shinfo(skb)->frag_list) {
+ struct sk_buff *frag;
+ int first_len = skb_pagelen(skb);
++ int truesizes = 0;
+
+ if (first_len - hlen > mtu ||
+ ((first_len - hlen) & 7) ||
+@@ -485,7 +486,7 @@
+ sock_hold(skb->sk);
+ frag->sk = skb->sk;
+ frag->destructor = sock_wfree;
+- skb->truesize -= frag->truesize;
++ truesizes += frag->truesize;
+ }
+ }
+
+@@ -496,6 +497,7 @@
+ frag = skb_shinfo(skb)->frag_list;
+ skb_shinfo(skb)->frag_list = NULL;
+ skb->data_len = first_len - skb_headlen(skb);
++ skb->truesize -= truesizes;
+ skb->len = first_len;
+ iph->tot_len = htons(first_len);
+ iph->frag_off = htons(IP_MF);
+diff -Nurd linux-2.6.24/net/ipv4/ip_sockglue.c linux-2.6.24-oxe810/net/ipv4/ip_sockglue.c
+--- linux-2.6.24/net/ipv4/ip_sockglue.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/ipv4/ip_sockglue.c 2008-06-11 17:46:09.000000000 +0200
+@@ -514,11 +514,6 @@
+ val &= ~3;
+ val |= inet->tos & 3;
+ }
+- if (IPTOS_PREC(val) >= IPTOS_PREC_CRITIC_ECP &&
+- !capable(CAP_NET_ADMIN)) {
+- err = -EPERM;
+- break;
+- }
+ if (inet->tos != val) {
+ inet->tos = val;
+ sk->sk_priority = rt_tos2priority(val);
+diff -Nurd linux-2.6.24/net/ipv4/ipcomp.c linux-2.6.24-oxe810/net/ipv4/ipcomp.c
+--- linux-2.6.24/net/ipv4/ipcomp.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/ipv4/ipcomp.c 2008-06-11 17:46:09.000000000 +0200
+@@ -74,6 +74,7 @@
+
+ static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb)
+ {
++ int nexthdr;
+ int err = -ENOMEM;
+ struct ip_comp_hdr *ipch;
+
+@@ -84,13 +85,15 @@
+
+ /* Remove ipcomp header and decompress original payload */
+ ipch = (void *)skb->data;
++ nexthdr = ipch->nexthdr;
++
+ skb->transport_header = skb->network_header + sizeof(*ipch);
+ __skb_pull(skb, sizeof(*ipch));
+ err = ipcomp_decompress(x, skb);
+ if (err)
+ goto out;
+
+- err = ipch->nexthdr;
++ err = nexthdr;
+
+ out:
+ return err;
+@@ -105,8 +108,11 @@
+ const int cpu = get_cpu();
+ u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu);
+ struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu);
+- int err = crypto_comp_compress(tfm, start, plen, scratch, &dlen);
++ int err;
+
++ local_bh_disable();
++ err = crypto_comp_compress(tfm, start, plen, scratch, &dlen);
++ local_bh_enable();
+ if (err)
+ goto out;
+
+diff -Nurd linux-2.6.24/net/ipv4/ipconfig.c linux-2.6.24-oxe810/net/ipv4/ipconfig.c
+--- linux-2.6.24/net/ipv4/ipconfig.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/ipv4/ipconfig.c 2008-06-11 17:46:09.000000000 +0200
+@@ -739,9 +739,9 @@
+ printk("Unknown ARP type 0x%04x for device %s\n", dev->type, dev->name);
+ b->htype = dev->type; /* can cause undefined behavior */
+ }
++
++ /* server_ip and your_ip address are both already zero per RFC2131 */
+ b->hlen = dev->addr_len;
+- b->your_ip = NONE;
+- b->server_ip = NONE;
+ memcpy(b->hw_addr, dev->dev_addr, dev->addr_len);
+ b->secs = htons(jiffies_diff / HZ);
+ b->xid = d->xid;
+diff -Nurd linux-2.6.24/net/ipv4/netfilter/arpt_mangle.c linux-2.6.24-oxe810/net/ipv4/netfilter/arpt_mangle.c
+--- linux-2.6.24/net/ipv4/netfilter/arpt_mangle.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/ipv4/netfilter/arpt_mangle.c 2008-06-11 17:46:07.000000000 +0200
+@@ -19,7 +19,7 @@
+ unsigned char *arpptr;
+ int pln, hln;
+
+- if (skb_make_writable(skb, skb->len))
++ if (!skb_make_writable(skb, skb->len))
+ return NF_DROP;
+
+ arp = arp_hdr(skb);
+diff -Nurd linux-2.6.24/net/ipv4/netfilter/ip_queue.c linux-2.6.24-oxe810/net/ipv4/netfilter/ip_queue.c
+--- linux-2.6.24/net/ipv4/netfilter/ip_queue.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/ipv4/netfilter/ip_queue.c 2008-06-11 17:46:07.000000000 +0200
+@@ -336,8 +336,8 @@
+ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
+ {
+ int diff;
+- int err;
+ struct iphdr *user_iph = (struct iphdr *)v->payload;
++ struct sk_buff *nskb;
+
+ if (v->data_len < sizeof(*user_iph))
+ return 0;
+@@ -349,14 +349,16 @@
+ if (v->data_len > 0xFFFF)
+ return -EINVAL;
+ if (diff > skb_tailroom(e->skb)) {
+- err = pskb_expand_head(e->skb, 0,
++ nskb = skb_copy_expand(e->skb, 0,
+ diff - skb_tailroom(e->skb),
+ GFP_ATOMIC);
+- if (err) {
++ if (!nskb) {
+ printk(KERN_WARNING "ip_queue: error "
+- "in mangle, dropping packet: %d\n", -err);
+- return err;
++ "in mangle, dropping packet\n");
++ return -ENOMEM;
+ }
++ kfree_skb(e->skb);
++ e->skb = nskb;
+ }
+ skb_put(e->skb, diff);
+ }
+diff -Nurd linux-2.6.24/net/ipv4/sysctl_net_ipv4.c linux-2.6.24-oxe810/net/ipv4/sysctl_net_ipv4.c
+--- linux-2.6.24/net/ipv4/sysctl_net_ipv4.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/ipv4/sysctl_net_ipv4.c 2008-06-11 17:46:09.000000000 +0200
+@@ -248,7 +248,7 @@
+
+ tcp_get_available_congestion_control(tbl.data, tbl.maxlen);
+ ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen);
+- if (ret == 0 && newval && newlen)
++ if (ret == 1 && newval && newlen)
+ ret = tcp_set_allowed_congestion_control(tbl.data);
+ kfree(tbl.data);
+
+diff -Nurd linux-2.6.24/net/ipv4/tcp.c linux-2.6.24-oxe810/net/ipv4/tcp.c
+--- linux-2.6.24/net/ipv4/tcp.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/ipv4/tcp.c 2008-06-11 17:46:09.000000000 +0200
+@@ -269,6 +269,8 @@
+ #include <asm/uaccess.h>
+ #include <asm/ioctls.h>
+
++#include <linux/pagemap.h>
++
+ int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT;
+
+ DEFINE_SNMP_STAT(struct tcp_mib, tcp_statistics) __read_mostly;
+@@ -636,6 +638,48 @@
+ return res;
+ }
+
++ssize_t tcp_sendpages(struct socket *sock, struct page **page, int offset,
++ size_t size, int flags)
++{
++ ssize_t res;
++ struct sock *sk = sock->sk;
++
++#define TCP_ZC_CSUM_FLAGS (NETIF_F_IP_CSUM | NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
++
++ if (!(sk->sk_route_caps & NETIF_F_SG) ||
++ !(sk->sk_route_caps & TCP_ZC_CSUM_FLAGS)) {
++ // Iterate through each page
++ ssize_t ret = 0;
++
++ while (size) {
++ unsigned long psize = PAGE_CACHE_SIZE - offset;
++ struct page *page_it;
++
++ psize = PAGE_CACHE_SIZE - offset;
++ if (size <= psize) {
++ psize = size;
++ }
++ page_it = *page;
++ ret += sock_no_sendpage(sock, page_it, offset, psize, flags);
++ size -= psize;
++ page++;
++ offset += psize;
++ offset &= (PAGE_CACHE_SIZE - 1);
++ }
++ return ret;
++ }
++
++#undef TCP_ZC_CSUM_FLAGS
++
++ lock_sock(sk);
++ TCP_CHECK_TIMER(sk);
++ res = do_tcp_sendpages(sk, page, offset, size, flags);
++ TCP_CHECK_TIMER(sk);
++
++ release_sock(sk);
++ return res;
++}
++
+ #define TCP_PAGE(sk) (sk->sk_sndmsg_page)
+ #define TCP_OFF(sk) (sk->sk_sndmsg_off)
+
+diff -Nurd linux-2.6.24/net/ipv4/xfrm4_tunnel.c linux-2.6.24-oxe810/net/ipv4/xfrm4_tunnel.c
+--- linux-2.6.24/net/ipv4/xfrm4_tunnel.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/ipv4/xfrm4_tunnel.c 2008-06-11 17:46:09.000000000 +0200
+@@ -50,7 +50,7 @@
+
+ static int xfrm_tunnel_rcv(struct sk_buff *skb)
+ {
+- return xfrm4_rcv_spi(skb, IPPROTO_IP, ip_hdr(skb)->saddr);
++ return xfrm4_rcv_spi(skb, IPPROTO_IPIP, ip_hdr(skb)->saddr);
+ }
+
+ static int xfrm_tunnel_err(struct sk_buff *skb, u32 info)
+diff -Nurd linux-2.6.24/net/ipv6/ip6_output.c linux-2.6.24-oxe810/net/ipv6/ip6_output.c
+--- linux-2.6.24/net/ipv6/ip6_output.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/ipv6/ip6_output.c 2008-06-11 17:46:11.000000000 +0200
+@@ -593,7 +593,7 @@
+ * or if the skb it not generated by a local socket. (This last
+ * check should be redundant, but it's free.)
+ */
+- if (!np || np->pmtudisc >= IPV6_PMTUDISC_DO) {
++ if (!skb->local_df) {
+ skb->dev = skb->dst->dev;
+ icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
+ IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
+@@ -609,6 +609,7 @@
+
+ if (skb_shinfo(skb)->frag_list) {
+ int first_len = skb_pagelen(skb);
++ int truesizes = 0;
+
+ if (first_len - hlen > mtu ||
+ ((first_len - hlen) & 7) ||
+@@ -631,7 +632,7 @@
+ sock_hold(skb->sk);
+ frag->sk = skb->sk;
+ frag->destructor = sock_wfree;
+- skb->truesize -= frag->truesize;
++ truesizes += frag->truesize;
+ }
+ }
+
+@@ -662,6 +663,7 @@
+
+ first_len = skb_pagelen(skb);
+ skb->data_len = first_len - skb_headlen(skb);
++ skb->truesize -= truesizes;
+ skb->len = first_len;
+ ipv6_hdr(skb)->payload_len = htons(first_len -
+ sizeof(struct ipv6hdr));
+@@ -1387,6 +1389,10 @@
+ tmp_skb->sk = NULL;
+ }
+
++ /* Allow local fragmentation. */
++ if (np->pmtudisc < IPV6_PMTUDISC_DO)
++ skb->local_df = 1;
++
+ ipv6_addr_copy(final_dst, &fl->fl6_dst);
+ __skb_pull(skb, skb_network_header_len(skb));
+ if (opt && opt->opt_flen)
+diff -Nurd linux-2.6.24/net/ipv6/ip6_tunnel.c linux-2.6.24-oxe810/net/ipv6/ip6_tunnel.c
+--- linux-2.6.24/net/ipv6/ip6_tunnel.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/ipv6/ip6_tunnel.c 2008-06-11 17:46:11.000000000 +0200
+@@ -550,6 +550,7 @@
+ ip_rt_put(rt);
+ goto out;
+ }
++ skb2->dst = (struct dst_entry *)rt;
+ } else {
+ ip_rt_put(rt);
+ if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos,
+diff -Nurd linux-2.6.24/net/ipv6/ipcomp6.c linux-2.6.24-oxe810/net/ipv6/ipcomp6.c
+--- linux-2.6.24/net/ipv6/ipcomp6.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/ipv6/ipcomp6.c 2008-06-11 17:46:11.000000000 +0200
+@@ -64,6 +64,7 @@
+
+ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
+ {
++ int nexthdr;
+ int err = -ENOMEM;
+ struct ip_comp_hdr *ipch;
+ int plen, dlen;
+@@ -79,6 +80,8 @@
+
+ /* Remove ipcomp header and decompress original payload */
+ ipch = (void *)skb->data;
++ nexthdr = ipch->nexthdr;
++
+ skb->transport_header = skb->network_header + sizeof(*ipch);
+ __skb_pull(skb, sizeof(*ipch));
+
+@@ -108,7 +111,7 @@
+ skb->truesize += dlen - plen;
+ __skb_put(skb, dlen - plen);
+ skb_copy_to_linear_data(skb, scratch, dlen);
+- err = ipch->nexthdr;
++ err = nexthdr;
+
+ out_put_cpu:
+ put_cpu();
+@@ -143,7 +146,9 @@
+ scratch = *per_cpu_ptr(ipcomp6_scratches, cpu);
+ tfm = *per_cpu_ptr(ipcd->tfms, cpu);
+
++ local_bh_disable();
+ err = crypto_comp_compress(tfm, start, plen, scratch, &dlen);
++ local_bh_enable();
+ if (err || (dlen + sizeof(*ipch)) >= plen) {
+ put_cpu();
+ goto out_ok;
+diff -Nurd linux-2.6.24/net/ipv6/netfilter/ip6_queue.c linux-2.6.24-oxe810/net/ipv6/netfilter/ip6_queue.c
+--- linux-2.6.24/net/ipv6/netfilter/ip6_queue.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/ipv6/netfilter/ip6_queue.c 2008-06-11 17:46:10.000000000 +0200
+@@ -333,8 +333,8 @@
+ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
+ {
+ int diff;
+- int err;
+ struct ipv6hdr *user_iph = (struct ipv6hdr *)v->payload;
++ struct sk_buff *nskb;
+
+ if (v->data_len < sizeof(*user_iph))
+ return 0;
+@@ -346,14 +346,16 @@
+ if (v->data_len > 0xFFFF)
+ return -EINVAL;
+ if (diff > skb_tailroom(e->skb)) {
+- err = pskb_expand_head(e->skb, 0,
++ nskb = skb_copy_expand(e->skb, 0,
+ diff - skb_tailroom(e->skb),
+ GFP_ATOMIC);
+- if (err) {
++ if (!nskb) {
+ printk(KERN_WARNING "ip6_queue: OOM "
+ "in mangle, dropping packet\n");
+- return err;
++ return -ENOMEM;
+ }
++ kfree_skb(e->skb);
++ e->skb = nskb;
+ }
+ skb_put(e->skb, diff);
+ }
+diff -Nurd linux-2.6.24/net/ipv6/xfrm6_output.c linux-2.6.24-oxe810/net/ipv6/xfrm6_output.c
+--- linux-2.6.24/net/ipv6/xfrm6_output.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/ipv6/xfrm6_output.c 2008-06-11 17:46:11.000000000 +0200
+@@ -34,7 +34,7 @@
+ if (mtu < IPV6_MIN_MTU)
+ mtu = IPV6_MIN_MTU;
+
+- if (skb->len > mtu) {
++ if (!skb->local_df && skb->len > mtu) {
+ skb->dev = dst->dev;
+ icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
+ ret = -EMSGSIZE;
+diff -Nurd linux-2.6.24/net/netfilter/nf_conntrack_proto_tcp.c linux-2.6.24-oxe810/net/netfilter/nf_conntrack_proto_tcp.c
+--- linux-2.6.24/net/netfilter/nf_conntrack_proto_tcp.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/netfilter/nf_conntrack_proto_tcp.c 2008-06-11 17:46:00.000000000 +0200
+@@ -135,7 +135,7 @@
+ * CLOSE_WAIT: ACK seen (after FIN)
+ * LAST_ACK: FIN seen (after FIN)
+ * TIME_WAIT: last ACK seen
+- * CLOSE: closed connection
++ * CLOSE: closed connection (RST)
+ *
+ * LISTEN state is not used.
+ *
+@@ -834,8 +834,21 @@
+ case TCP_CONNTRACK_SYN_SENT:
+ if (old_state < TCP_CONNTRACK_TIME_WAIT)
+ break;
+- if ((conntrack->proto.tcp.seen[!dir].flags &
+- IP_CT_TCP_FLAG_CLOSE_INIT)
++ /* RFC 1122: "When a connection is closed actively,
++ * it MUST linger in TIME-WAIT state for a time 2xMSL
++ * (Maximum Segment Lifetime). However, it MAY accept
++ * a new SYN from the remote TCP to reopen the connection
++ * directly from TIME-WAIT state, if..."
++ * We ignore the conditions because we are in the
++ * TIME-WAIT state anyway.
++ *
++ * Handle aborted connections: we and the server
++ * think there is an existing connection but the client
++ * aborts it and starts a new one.
++ */
++ if (((conntrack->proto.tcp.seen[dir].flags
++ | conntrack->proto.tcp.seen[!dir].flags)
++ & IP_CT_TCP_FLAG_CLOSE_INIT)
+ || (conntrack->proto.tcp.last_dir == dir
+ && conntrack->proto.tcp.last_index == TCP_RST_SET)) {
+ /* Attempt to reopen a closed/aborted connection.
+@@ -848,18 +861,25 @@
+ }
+ /* Fall through */
+ case TCP_CONNTRACK_IGNORE:
+- /* Ignored packets:
++ /* Ignored packets:
++ *
++ * Our connection entry may be out of sync, so ignore
++ * packets which may signal the real connection between
++ * the client and the server.
+ *
+ * a) SYN in ORIGINAL
+ * b) SYN/ACK in REPLY
+ * c) ACK in reply direction after initial SYN in original.
++ *
++ * If the ignored packet is invalid, the receiver will send
++ * a RST we'll catch below.
+ */
+ if (index == TCP_SYNACK_SET
+ && conntrack->proto.tcp.last_index == TCP_SYN_SET
+ && conntrack->proto.tcp.last_dir != dir
+ && ntohl(th->ack_seq) ==
+ conntrack->proto.tcp.last_end) {
+- /* This SYN/ACK acknowledges a SYN that we earlier
++ /* b) This SYN/ACK acknowledges a SYN that we earlier
+ * ignored as invalid. This means that the client and
+ * the server are both in sync, while the firewall is
+ * not. We kill this session and block the SYN/ACK so
+@@ -884,7 +904,7 @@
+ write_unlock_bh(&tcp_lock);
+ if (LOG_INVALID(IPPROTO_TCP))
+ nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+- "nf_ct_tcp: invalid packed ignored ");
++ "nf_ct_tcp: invalid packet ignored ");
+ return NF_ACCEPT;
+ case TCP_CONNTRACK_MAX:
+ /* Invalid packet */
+@@ -938,8 +958,7 @@
+
+ conntrack->proto.tcp.state = new_state;
+ if (old_state != new_state
+- && (new_state == TCP_CONNTRACK_FIN_WAIT
+- || new_state == TCP_CONNTRACK_CLOSE))
++ && new_state == TCP_CONNTRACK_FIN_WAIT)
+ conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
+ timeout = conntrack->proto.tcp.retrans >= nf_ct_tcp_max_retrans
+ && *tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans
+diff -Nurd linux-2.6.24/net/netfilter/nfnetlink_log.c linux-2.6.24-oxe810/net/netfilter/nfnetlink_log.c
+--- linux-2.6.24/net/netfilter/nfnetlink_log.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/netfilter/nfnetlink_log.c 2008-06-11 17:46:00.000000000 +0200
+@@ -594,7 +594,7 @@
+ /* FIXME: do we want to make the size calculation conditional based on
+ * what is actually present? way more branches and checks, but more
+ * memory efficient... */
+- size = NLMSG_ALIGN(sizeof(struct nfgenmsg))
++ size = NLMSG_SPACE(sizeof(struct nfgenmsg))
+ + nla_total_size(sizeof(struct nfulnl_msg_packet_hdr))
+ + nla_total_size(sizeof(u_int32_t)) /* ifindex */
+ + nla_total_size(sizeof(u_int32_t)) /* ifindex */
+diff -Nurd linux-2.6.24/net/netfilter/nfnetlink_queue.c linux-2.6.24-oxe810/net/netfilter/nfnetlink_queue.c
+--- linux-2.6.24/net/netfilter/nfnetlink_queue.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/netfilter/nfnetlink_queue.c 2008-06-11 17:46:00.000000000 +0200
+@@ -353,7 +353,7 @@
+
+ QDEBUG("entered\n");
+
+- size = NLMSG_ALIGN(sizeof(struct nfgenmsg))
++ size = NLMSG_SPACE(sizeof(struct nfgenmsg))
+ + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr))
+ + nla_total_size(sizeof(u_int32_t)) /* ifindex */
+ + nla_total_size(sizeof(u_int32_t)) /* ifindex */
+@@ -616,8 +616,8 @@
+ static int
+ nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e)
+ {
++ struct sk_buff *nskb;
+ int diff;
+- int err;
+
+ diff = data_len - e->skb->len;
+ if (diff < 0) {
+@@ -627,14 +627,16 @@
+ if (data_len > 0xFFFF)
+ return -EINVAL;
+ if (diff > skb_tailroom(e->skb)) {
+- err = pskb_expand_head(e->skb, 0,
++ nskb = skb_copy_expand(e->skb, 0,
+ diff - skb_tailroom(e->skb),
+ GFP_ATOMIC);
+- if (err) {
++ if (!nskb) {
+ printk(KERN_WARNING "nf_queue: OOM "
+ "in mangle, dropping packet\n");
+- return err;
++ return -ENOMEM;
+ }
++ kfree_skb(e->skb);
++ e->skb = nskb;
+ }
+ skb_put(e->skb, diff);
+ }
+diff -Nurd linux-2.6.24/net/netfilter/xt_time.c linux-2.6.24-oxe810/net/netfilter/xt_time.c
+--- linux-2.6.24/net/netfilter/xt_time.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/netfilter/xt_time.c 2008-06-11 17:46:00.000000000 +0200
+@@ -95,8 +95,11 @@
+ */
+ r->dse = time / 86400;
+
+- /* 1970-01-01 (w=0) was a Thursday (4). */
+- r->weekday = (4 + r->dse) % 7;
++ /*
++ * 1970-01-01 (w=0) was a Thursday (4).
++ * -1 and +1 map Sunday properly onto 7.
++ */
++ r->weekday = (4 + r->dse - 1) % 7 + 1;
+ }
+
+ static void localtime_3(struct xtm *r, time_t time)
+diff -Nurd linux-2.6.24/net/sched/em_meta.c linux-2.6.24-oxe810/net/sched/em_meta.c
+--- linux-2.6.24/net/sched/em_meta.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/sched/em_meta.c 2008-06-11 17:45:56.000000000 +0200
+@@ -719,11 +719,13 @@
+
+ static inline void meta_delete(struct meta_match *meta)
+ {
+- struct meta_type_ops *ops = meta_type_ops(&meta->lvalue);
++ if (meta) {
++ struct meta_type_ops *ops = meta_type_ops(&meta->lvalue);
+
+- if (ops && ops->destroy) {
+- ops->destroy(&meta->lvalue);
+- ops->destroy(&meta->rvalue);
++ if (ops && ops->destroy) {
++ ops->destroy(&meta->lvalue);
++ ops->destroy(&meta->rvalue);
++ }
+ }
+
+ kfree(meta);
+diff -Nurd linux-2.6.24/net/sched/ematch.c linux-2.6.24-oxe810/net/sched/ematch.c
+--- linux-2.6.24/net/sched/ematch.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/sched/ematch.c 2008-06-11 17:45:56.000000000 +0200
+@@ -305,10 +305,9 @@
+ struct tcf_ematch_tree_hdr *tree_hdr;
+ struct tcf_ematch *em;
+
+- if (!rta) {
+- memset(tree, 0, sizeof(*tree));
++ memset(tree, 0, sizeof(*tree));
++ if (!rta)
+ return 0;
+- }
+
+ if (rtattr_parse_nested(tb, TCA_EMATCH_TREE_MAX, rta) < 0)
+ goto errout;
+diff -Nurd linux-2.6.24/net/socket.c linux-2.6.24-oxe810/net/socket.c
+--- linux-2.6.24/net/socket.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/net/socket.c 2008-06-11 17:46:19.000000000 +0200
+@@ -113,6 +113,9 @@
+ static ssize_t sock_sendpage(struct file *file, struct page *page,
+ int offset, size_t size, loff_t *ppos, int more);
+
++static ssize_t sock_sendpages(struct file *file, struct page **page,
++ int offset, size_t size, loff_t *ppos, int more);
++
+ /*
+ * Socket files have a set of 'special' operations as well as the generic file ones. These don't appear
+ * in the operation structures but are done directly via the socketcall() multiplexor.
+@@ -133,6 +136,7 @@
+ .release = sock_close,
+ .fasync = sock_fasync,
+ .sendpage = sock_sendpage,
++ .sendpages = sock_sendpages,
+ .splice_write = generic_splice_sendpage,
+ };
+
+@@ -691,6 +695,21 @@
+ return sock->ops->sendpage(sock, page, offset, size, flags);
+ }
+
++static ssize_t sock_sendpages(struct file *file, struct page **page,
++ int offset, size_t size, loff_t *ppos, int more)
++{
++ struct socket *sock;
++ int flags;
++
++ sock = file->private_data;
++
++ flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
++ if (more)
++ flags |= MSG_MORE;
++
++ return sock->ops->sendpages(sock, page, offset, size, flags);
++}
++
+ static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb,
+ struct sock_iocb *siocb)
+ {
+diff -Nurd linux-2.6.24/scripts/mod/file2alias.c linux-2.6.24-oxe810/scripts/mod/file2alias.c
+--- linux-2.6.24/scripts/mod/file2alias.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/scripts/mod/file2alias.c 2008-06-11 17:46:20.000000000 +0200
+@@ -155,7 +155,7 @@
+ * Some modules (visor) have empty slots as placeholder for
+ * run-time specification that results in catch-all alias
+ */
+- if (!(id->idVendor | id->bDeviceClass | id->bInterfaceClass))
++ if (!(id->idVendor | id->idProduct | id->bDeviceClass | id->bInterfaceClass))
+ return;
+
+ /* Convert numeric bcdDevice range into fnmatch-able pattern(s) */
+diff -Nurd linux-2.6.24/security/Kconfig linux-2.6.24-oxe810/security/Kconfig
+--- linux-2.6.24/security/Kconfig 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/security/Kconfig 2008-06-11 17:46:44.000000000 +0200
+@@ -103,6 +103,32 @@
+
+ If you are unsure how to answer this question, answer N.
+
++config SECURITY_TRUSTEES
++ bool "Linux Trustees ACLs"
++ depends on SECURITY
++ help
++ Implements a system similar to Netware ACLs. Trustees
++ allows a global configuration of recursive ACLs via a
++ centralized file. ACLs can be added to an entire
++ directory tree and masked out on subdirectories.
++
++ Trustees allows complex permissions to be enforced
++ system-wide without needing to touch every file or
++ maintain thousands of ugly POSIX ACLs. See
++ http://trustees.sourceforge.net for more information on
++ trustees and the associated user-space tools.
++
++ If you are unsure how to answer this question, answer N.
++
++config SECURITY_TRUSTEES_DEBUG
++ bool "Enable debugging code and messages"
++ depends on SECURITY_TRUSTEES
++ help
++ Turns on certain diagnostic messages and debugging code
++ in trustees.
++
++ If you are unsure how to answer this question, answer N.
++
+ source security/selinux/Kconfig
+
+ endmenu
+diff -Nurd linux-2.6.24/security/Makefile linux-2.6.24-oxe810/security/Makefile
+--- linux-2.6.24/security/Makefile 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/security/Makefile 2008-06-11 17:46:44.000000000 +0200
+@@ -12,6 +12,7 @@
+
+ # Object file lists
+ obj-$(CONFIG_SECURITY) += security.o dummy.o inode.o
++obj-$(CONFIG_SECURITY_TRUSTEES) += trustees/
+ # Must precede capability.o in order to stack properly.
+ obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
+ obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o
+diff -Nurd linux-2.6.24/security/commoncap.c linux-2.6.24-oxe810/security/commoncap.c
+--- linux-2.6.24/security/commoncap.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/security/commoncap.c 2008-06-11 17:46:44.000000000 +0200
+@@ -539,7 +539,7 @@
+ * allowed.
+ * We must preserve legacy signal behavior in this case.
+ */
+- if (p->euid == 0 && p->uid == current->uid)
++ if (p->uid == current->uid)
+ return 0;
+
+ /* sigcont is permitted within same session */
+diff -Nurd linux-2.6.24/security/selinux/ss/services.c linux-2.6.24-oxe810/security/selinux/ss/services.c
+--- linux-2.6.24/security/selinux/ss/services.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/security/selinux/ss/services.c 2008-06-11 17:46:43.000000000 +0200
+@@ -1744,6 +1744,9 @@
+ struct ocontext *c;
+ int rc = 0, cmp = 0;
+
++ while (path[0] == '/' && path[1] == '/')
++ path++;
++
+ POLICY_RDLOCK;
+
+ for (genfs = policydb.genfs; genfs; genfs = genfs->next) {
+@@ -2626,7 +2629,6 @@
+
+ netlbl_sid_to_secattr_failure:
+ POLICY_RDUNLOCK;
+- netlbl_secattr_destroy(secattr);
+ return rc;
+ }
+ #endif /* CONFIG_NETLABEL */
+diff -Nurd linux-2.6.24/security/trustees/Makefile linux-2.6.24-oxe810/security/trustees/Makefile
+--- linux-2.6.24/security/trustees/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/security/trustees/Makefile 2008-06-11 17:46:44.000000000 +0200
+@@ -0,0 +1,8 @@
++ifeq ($(CONFIG_SECURITY_TRUSTEES_DEBUG),y)
++ EXTRA_CFLAGS += -DTRUSTEES_DEBUG
++endif
++
++obj-$(CONFIG_SECURITY_TRUSTEES) := trustees.o
++trustees-objs := \
++ security.o fs.o \
++ init.o funcs.o ../commoncap.o
+diff -Nurd linux-2.6.24/security/trustees/fs.c linux-2.6.24-oxe810/security/trustees/fs.c
+--- linux-2.6.24/security/trustees/fs.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/security/trustees/fs.c 2008-06-11 17:46:44.000000000 +0200
+@@ -0,0 +1,273 @@
++/*
++ * Trustees ACL Project
++ *
++ * Copyright (c) 1999-2000 Vyacheslav Zavadsky
++ * Copyright (c) 2004 Andrew Ruder (aeruder@ksu.edu)
++ *
++ * 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, version 2.
++ *
++ * This code handles the virtual filesystem for trustees.
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/fs.h>
++#include <linux/vmalloc.h>
++#include <linux/security.h>
++#include <asm/atomic.h>
++#include <asm/uaccess.h>
++
++#include "internal.h"
++
++
++/* initialization code for the trustees filesystem */
++
++/* File operations
++ *
++ * this is all the code for handling the file operations done on the few files
++ * in the trustees filesystem
++ */
++static int trustees_open(struct inode *inode, struct file *filp);
++static ssize_t trustees_read_bogus(struct file *filp, char __user * buf,
++ size_t count, loff_t * offset);
++static ssize_t trustees_write_bogus(struct file *filp,
++ const char __user * buf, size_t count,
++ loff_t * offset);
++static ssize_t trustees_read_status(struct file *filp, char __user * buf,
++ size_t count, loff_t * offset);
++static ssize_t trustees_read_apiversion(struct file *filp, char __user * buf,
++ size_t count, loff_t * offset);
++static ssize_t trustees_write_trustees(struct file *filp,
++ const char __user * buf,
++ size_t count, loff_t * offset);
++static int trustees_open_trustees(struct inode *inode, struct file *file);
++static int trustees_release_trustees(struct inode *inode, struct file *file);
++
++/* Various structs
++ */
++
++static struct file_operations trustees_ops_apiversion = {
++ .open = trustees_open,
++ .read = trustees_read_apiversion,
++ .write = trustees_write_bogus,
++};
++
++static struct file_operations trustees_ops_status = {
++ .open = trustees_open,
++ .read = trustees_read_status,
++ .write = trustees_write_bogus
++};
++
++static struct file_operations trustees_ops_trustees = {
++ .open = trustees_open_trustees,
++ .read = trustees_read_bogus,
++ .write = trustees_write_trustees,
++ .release = trustees_release_trustees
++};
++
++static struct trustees_file_info {
++ const char *name;
++ struct file_operations *fops;
++ int mode;
++ struct dentry *dentry;
++} trustees_files[] = {
++ {.name = "device",
++ .fops = &trustees_ops_trustees,
++ .mode = S_IWUSR,
++ .dentry = 0
++ },
++ {.name = "status",
++ .fops = &trustees_ops_status,
++ .mode = S_IRUSR,
++ .dentry = 0
++ },
++ {.name = "apiversion",
++ .fops = &trustees_ops_apiversion,
++ .mode = S_IRUSR | S_IRGRP | S_IROTH,
++ .dentry = 0
++ },
++ {"", NULL, 0, 0}
++};
++
++struct trustee_command_reader {
++ struct trustee_command command;
++ unsigned curarg;
++ void *arg[TRUSTEE_MAX_ARGS];
++ size_t argsize[TRUSTEE_MAX_ARGS];
++};
++
++
++static struct dentry *toplevel = NULL;
++
++int trustees_init_fs(void)
++{
++ struct trustees_file_info *iter;
++ toplevel = securityfs_create_dir("trustees", NULL);
++ if (!toplevel) trustees_deinit_fs();
++ for (iter = trustees_files; iter->fops && toplevel; iter++) {
++ iter->dentry = securityfs_create_file(
++ iter->name, iter->mode, toplevel, NULL, iter->fops);
++ if (!iter->dentry) trustees_deinit_fs();
++ }
++ return !toplevel;
++}
++
++void trustees_deinit_fs(void)
++{
++ struct trustees_file_info *iter;
++ for (iter = trustees_files; iter->fops; iter++) {
++ securityfs_remove(iter->dentry);
++ iter->dentry = NULL;
++ }
++ securityfs_remove(toplevel);
++ toplevel = NULL;
++}
++
++/*
++ * They're opening the file...
++ */
++
++static int trustees_open(struct inode *inode, struct file *filp)
++{
++ return 0;
++}
++
++static int trustees_open_trustees(struct inode *inode, struct file *file)
++{
++ file->private_data = vmalloc(sizeof(struct trustee_command_reader));
++ if (!file->private_data)
++ return -ENOMEM;
++
++ memset(file->private_data, 0, sizeof(struct trustee_command_reader));
++
++ return 0;
++}
++
++static int trustees_release_trustees(struct inode *inode, struct file *file)
++{
++ vfree(file->private_data);
++ return 0;
++}
++
++/* Do a read on a bogus file. Just return nothing :) */
++static ssize_t trustees_read_bogus(struct file *filp, char __user * buf,
++ size_t count, loff_t * offset)
++{
++ return 0;
++}
++
++/* Similar way to handle writes. Just say we wrote the data and return */
++static ssize_t trustees_write_bogus(struct file *filp,
++ const char __user * buf, size_t count,
++ loff_t * offset)
++{
++ return count;
++}
++
++/* Function for handling reading of the status. */
++static ssize_t trustees_read_status(struct file *filp, char __user * buf,
++ size_t count, loff_t * offset)
++{
++ static const char msg[] = "Damnit, it works, OK?!\n";
++ unsigned long nocopy;
++
++ if (*offset >= (sizeof(msg) - 1)) {
++ return 0;
++ }
++
++ if (count > (sizeof(msg) - 1 - *offset)) {
++ count = sizeof(msg) - 1 - *offset;
++ }
++ nocopy = copy_to_user(buf, msg, count);
++ (*offset) += count;
++ (*offset) -= nocopy;
++
++ return count;
++}
++
++/* Function for handling reading of the apiversion. */
++static ssize_t trustees_read_apiversion(struct file *filp, char __user * buf,
++ size_t count, loff_t * offset)
++{
++ static const char msg[] = TRUSTEES_APIVERSION_STR "\n";
++ unsigned long nocopy;
++
++ if (*offset >= (sizeof(msg) - 1)) {
++ return 0;
++ }
++
++ if (count > (sizeof(msg) - 1 - *offset)) {
++ count = sizeof(msg) - 1 - *offset;
++ }
++ nocopy = copy_to_user(buf, msg, count);
++ (*offset) += count;
++ (*offset) -= nocopy;
++
++ return count;
++}
++
++/* Cleanup our reader (deallocate all the allocated memory) */
++static void cleanup_reader(struct trustee_command_reader *reader) {
++ int z;
++ if (!reader) {
++ TS_ERR_MSG("How does reader disappear on us?\n");
++ return;
++ }
++
++ for (z = reader->curarg - 1; z >= 0; z--) {
++ vfree(reader->arg[z]);
++ reader->argsize[z] = 0;
++ }
++ reader->command.command = 0;
++ reader->curarg = 0;
++}
++
++static ssize_t trustees_write_trustees(struct file *filp,
++ const char __user * buf,
++ size_t count, loff_t * offset)
++{
++ struct trustee_command_reader *reader = filp->private_data;
++
++ if (reader->command.command == 0) {
++ reader->curarg = 0;
++ if (count != sizeof(struct trustee_command)) {
++ return -EIO;
++ }
++ if (copy_from_user(&reader->command, buf, count)) {
++ reader->command.command = 0;
++ TS_ERR_MSG("copy_from_user failed on command\n");
++ return -EIO;
++ }
++ if (reader->command.numargs > TRUSTEE_MAX_ARGS) {
++ TS_ERR_MSG("Too many arguments specified for command %d\n",
++ reader->command.command);
++ return -EIO;
++ }
++ } else {
++ unsigned curarg = reader->curarg;
++ if (!(reader->arg[curarg] = vmalloc(count+1))) {
++ cleanup_reader(reader);
++ return -EIO;
++ }
++ reader->argsize[curarg] = count;
++ ((char *)reader->arg[curarg])[count] = '\0';
++ reader->curarg++;
++ if (copy_from_user(reader->arg[curarg], buf, count)) {
++ cleanup_reader(reader);
++ TS_ERR_MSG("copy_from_user failed on arg\n");
++ return -EIO;
++ }
++ }
++
++ if (reader->command.command && reader->curarg == reader->command.numargs) {
++ int ret = trustees_process_command(reader->command, reader->arg,
++ reader->argsize);
++ cleanup_reader(reader);
++ if (ret) return -EIO;
++ }
++
++ return count;
++}
+diff -Nurd linux-2.6.24/security/trustees/funcs.c linux-2.6.24-oxe810/security/trustees/funcs.c
+--- linux-2.6.24/security/trustees/funcs.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/security/trustees/funcs.c 2008-06-11 17:46:44.000000000 +0200
+@@ -0,0 +1,810 @@
++/*
++ * Trustees ACL Project
++ *
++ * Copyright (c) 1999-2000 Vyacheslav Zavadsky
++ * Copyright (c) 2004 Andrew Ruder (aeruder@ksu.edu)
++ *
++ * 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, version 2.
++ *
++ * This code contains the functions for handling the actual trustees data
++ * and returning the permissions for a given file, etc.
++ *
++ *
++ */
++
++#include <linux/fs.h>
++#include <linux/mount.h>
++#include <linux/dcache.h>
++#include <linux/string.h>
++#include <linux/mm.h>
++#include <linux/slab.h>
++#include <linux/smp_lock.h>
++#include <linux/poll.h>
++#include <linux/sched.h>
++#include <linux/limits.h>
++#include <linux/list.h>
++#include <linux/vmalloc.h>
++#include <linux/ctype.h>
++
++#include "internal.h"
++
++/*
++ * This is a hash of all the trustee_names currently added. These values
++ * are hashed on a combination of device/filename. Before reading/writing
++ * be sure to take care of the locking of trustee_hash_lock.
++ */
++rwlock_t trustee_hash_lock;
++static struct hlist_head *trustee_hash = NULL;
++
++/*
++ * This is the deepest level trustee. When calculating filenames, we can
++ * skip several of the levels in many case since we know it won't be any
++ * deeper than this.
++ *
++ * Kept up to date by calculate_deepest_level
++ *
++ * / => 0
++ * /test => 1
++ * /test/blah => 2
++ */
++static int deepest_level = 0;
++
++/*
++ * A list of filesystems that need to have their case
++ * ignored. This is protected by trustee_hash_lock.
++ */
++static LIST_HEAD(trustee_ic_list);
++
++
++/* The calling method needs to free the buffer created by this function
++ * This method returns the filename for a dentry. This is, of course,
++ * relative to the device. The filename can be truncated to be as deep as
++ * the deepest trustee. The depth returned in d will always be the true
++ * depth, however.
++ *
++ * Args:
++ * dentry: The dentry we are interested in.
++ * d: a pointer to the place where the depth can be stored.
++ * trunc: ok to truncate the name to the longest that needs to be figured out.
++ */
++
++#define FN_CHUNK_SIZE 64
++char *trustees_filename_for_dentry(struct dentry *dentry, int *d, int trunc)
++{
++ char *buffer = NULL, *tmpbuf = NULL;
++ int bufsize = FN_CHUNK_SIZE;
++ char c;
++ int i, j, k;
++ int depth = 0;
++ struct dentry *temp_dentry;
++
++ if (dentry->d_parent == NULL) {
++ TS_ERR_MSG("d_parent is null\n");
++ return NULL;
++ }
++
++ if (dentry->d_name.name == NULL) {
++ TS_ERR_MSG("name is null\n");
++ return NULL;
++ }
++
++ buffer = kmalloc(FN_CHUNK_SIZE, GFP_KERNEL);
++ if (!buffer) {
++ TS_ERR_MSG("could not allocate filename buffer\n");
++ return NULL;
++ }
++
++ buffer[0] = '/';
++ buffer[i = 1] = '\0';
++ for (temp_dentry = dentry; !IS_ROOT(temp_dentry); temp_dentry = temp_dentry->d_parent)
++ depth++;
++ if (d) *d = depth;
++ if (deepest_level <= 0) return buffer;
++
++ for (;;) {
++ if (IS_ROOT(dentry))
++ break;
++ if (depth-- > deepest_level) continue;
++
++ j = i + strlen(dentry->d_name.name);
++ if ((j + 2) > bufsize) { /* reallocate - won't fit */
++ bufsize = (((j + 2) / FN_CHUNK_SIZE) + 1) * FN_CHUNK_SIZE;
++ tmpbuf = kmalloc(bufsize, GFP_KERNEL);
++ if (!tmpbuf) {
++ kfree(buffer);
++ TS_ERR_MSG
++ ("Out of memory allocating tmpbuf\n");
++ return NULL;
++ }
++ memcpy(tmpbuf, buffer, i);
++ kfree(buffer);
++ buffer = tmpbuf;
++ }
++ /* Throw the name in there backward */
++ for (k = 0; dentry->d_name.name[k]; k++) {
++ buffer[j - 1 - k] = dentry->d_name.name[k];
++ }
++ i = j;
++ buffer[i++] = '/';
++ dentry = dentry->d_parent;
++ }
++ buffer[i] = 0;
++
++ /* buffer is backwards, reverse it */
++ for (j = 0; j < (i / 2); ++j) {
++ c = buffer[j];
++ buffer[j] = buffer[i - j - 1];
++ buffer[i - j - 1] = c;
++ }
++
++ return buffer;
++}
++
++/**
++ * Allocate memory using vmalloc and return a duplicate of the passed in string.
++ * Returns NULL if a problem occurs
++ */
++static char *vmalloc_strdup(const char *str, size_t len)
++{
++ char *r;
++
++ if (!str) return NULL;
++ len = strlen(str);
++ r = vmalloc(len + 1);
++ if (!r) return NULL;
++ memcpy(r, str, len + 1);
++
++ return r;
++}
++
++/*
++ * Add a filesystem as a ignored-case dev.
++ */
++static inline void add_ic_dev(u32 dev, char *devname)
++{
++ char *devname2;
++ struct trustee_ic *ic;
++ size_t dev_len;
++
++ dev_len = strlen(devname);
++
++ if (dev_len > PATH_MAX) {
++ TS_ERR_MSG("devname bad, add_ic_dev ignored.\n");
++ return;
++ }
++
++ if (!dev_len) {
++ TS_ERR_MSG("No devname specified in add_ic_dev.\n");
++ return;
++ }
++
++ devname2 = vmalloc_strdup(devname, dev_len);
++ if (!devname2) {
++ TS_ERR_MSG
++ ("Seems that we have ran out of memory adding ic dev!\n");
++ return;
++ }
++
++ ic = vmalloc(sizeof(struct trustee_ic));
++ if (!ic) {
++ TS_ERR_MSG
++ ("Seems that we ran out of memory allocating ic!\n");
++ return;
++ }
++
++ ic->dev = new_decode_dev(dev);
++ ic->devname = devname2;
++
++ write_lock(&trustee_hash_lock);
++ list_add(&ic->ic_list, &trustee_ic_list);
++ write_unlock(&trustee_hash_lock);
++}
++
++/*
++ * Remove all ignored-case filesystems.
++ */
++static inline void remove_ic_devs(void)
++{
++ struct trustee_ic *ic, *temp_ic;
++ struct list_head temp_ic_list;
++
++ INIT_LIST_HEAD(&temp_ic_list);
++ list_splice_init(&trustee_ic_list, &temp_ic_list);
++
++ list_for_each_entry_safe(ic, temp_ic, &temp_ic_list, ic_list) {
++ vfree(ic->devname);
++ vfree(ic);
++ }
++}
++
++/*
++ * This frees all the capsules in a trustee element.
++ */
++static inline void free_hash_element_list(struct trustee_hash_element *e)
++{
++ struct trustee_permission_capsule *capsule, *temp;
++
++ list_for_each_entry_safe(capsule, temp, &e->perm_list, perm_list) {
++ list_del(&capsule->perm_list);
++ vfree(capsule);
++ }
++}
++
++/*
++ * Free a trustee name. This frees the devname and the filename
++ */
++static inline void free_trustee_name(struct trustee_name *name)
++{
++ vfree(name->filename);
++ vfree(name->devname);
++}
++
++/*
++ * Frees the capsules, and the filenames for a trustee hash element.
++ * Also marks it as unused in the hash.
++ */
++static inline void free_hash_element(struct trustee_hash_element *e)
++{
++ free_hash_element_list(e);
++ free_trustee_name(&e->name);
++ vfree(e);
++}
++
++/**
++ * Copies from src to dest (duplicating the strings in the
++ * trustee_name structure. Returns zero for unsuccesful.
++ */
++static int copy_trustee_name(struct trustee_name *dst, struct trustee_name *src)
++{
++ *dst = *src;
++ if (dst->filename) {
++ dst->filename = vmalloc_strdup(src->filename, strlen(src->filename));
++ if (!dst->filename) {
++ TS_ERR_MSG("Ran out of memory duplicating src->filename\n");
++ return 0;
++ }
++ }
++
++ if (dst->devname) {
++ dst->devname = vmalloc_strdup(src->devname, strlen(src->devname));
++ if (!dst->devname) {
++ TS_ERR_MSG("Ran out of memory duplicating src->devname\n");
++ vfree(dst->filename);
++ return 0;
++ }
++ }
++
++ return 1;
++}
++
++
++/*
++ * hashing function researched by Karl Nelson <kenelson @ ece ucdavis edu>
++ * and is used in glib.
++ */
++static inline unsigned int hash_string(const char *s)
++{
++ unsigned int v = 0;
++
++ while (*s) {
++ v = (v << 5) - v + tolower(*s);
++ s++;
++ }
++
++ return v;
++}
++
++/*
++ * Return the hash for a device.
++ */
++static inline unsigned int hash_device(const char *name, dev_t device)
++{
++ if (MAJOR(device) == 0) {
++ return hash_string(name);
++ }
++
++ return new_encode_dev(device);
++}
++
++/*
++ * Return the hash for a file. This is a combination of the
++ * hash of the filename and the hash for the device.
++ */
++static inline unsigned int hash(const struct trustee_name *name)
++{
++ return hash_string(name->filename) ^
++ hash_device(name->devname, name->dev);
++}
++
++/*
++ * Return the slot in the trustees_hash where a trustee is located
++ */
++static inline unsigned int hash_slot(const struct trustee_name *name)
++{
++ return hash(name) % trustee_hash_size;
++}
++
++/*
++ * Compare two devices. Return 1 if they are equal otherwise return 0
++ */
++static inline int trustee_dev_cmp(dev_t dev1, dev_t dev2, char *devname1,
++ char *devname2)
++{
++ if ((MAJOR(dev1) == 0) && (MAJOR(dev2) == 0))
++ return (strcmp(devname1, devname2) == 0);
++ else if ((MAJOR(dev1) != 0) && (MAJOR(dev2) != 0))
++ return (dev1 == dev2);
++ return 0;
++}
++
++/*
++ * Compare two trustee_name's. Returns 1 if they are are equal
++ * otherwise return 0
++ */
++static inline int trustee_name_cmp(const struct trustee_name *n1,
++ const struct trustee_name *n2,
++ unsigned ignore_case)
++{
++ if (trustee_dev_cmp(n1->dev, n2->dev, n1->devname, n2->devname))
++ return ignore_case ?
++ (strnicmp(n1->filename, n2->filename, PATH_MAX) == 0) :
++ (strcmp(n1->filename, n2->filename) == 0);
++ return 0;
++}
++
++/*
++ * Calculate the deepest level.
++ */
++static inline void calculate_deepest_level(const struct trustee_name *name)
++{
++ char *fn = name->filename;
++ char *x;
++ int level = 0;
++
++ for (x = fn; *x; ++x) {
++ if (*x == '/')
++ ++level;
++ }
++
++ /* If it is the root, it should have
++ * a level of 0.
++ */
++ if (x == (fn + 1)) level = 0;
++
++ if (level > deepest_level) deepest_level = level;
++}
++
++/*
++ * Return the trustee element for a name.
++ * This should be called with a lock on the trustee_hash (which should
++ * not be released until you are done with the returned hash_element)!
++ */
++static struct trustee_hash_element *get_trustee_for_name(const struct trustee_name *name,
++ unsigned ignore_case)
++{
++ struct trustee_hash_element *item = NULL;
++ struct hlist_node *iter = NULL;
++
++ hlist_for_each_entry(item, iter, &trustee_hash[hash_slot(name)], hash_list) {
++ if (trustee_name_cmp(&item->name, name, ignore_case))
++ return item;
++ }
++
++ return NULL;
++}
++
++/**
++ * Add a new blank trustee to the hash.
++ *
++ * If this returns zero, then the adding failed and name should be freed
++ * (assuming must_copy is 0), otherwise assume we used its memory.
++ */
++static unsigned add_trustee(struct trustee_name *name, int must_copy) {
++ struct trustee_name newname;
++ struct trustee_name rootname;
++ unsigned is_root = 1;
++ unsigned r = 0;
++ struct trustee_hash_element *new;
++ struct trustee_hash_element *root;
++
++ if (!name->filename || !name->filename[0]) goto err0;
++
++ if (!copy_trustee_name(&rootname, name)) goto err0;
++ rootname.filename[1] = '\0';
++
++ if (strlen(name->filename) > 1 && strcmp(name->filename, "/")) {
++ add_trustee(&rootname, 1);
++ is_root = 0;
++ }
++
++ if (must_copy) {
++ if (!copy_trustee_name(&newname, name)) goto err1;
++ } else {
++ newname = *name;
++ }
++
++ new = vmalloc(sizeof(struct trustee_hash_element));
++ if (!new) goto err2;
++ new->name = newname;
++ INIT_HLIST_NODE(&new->hash_list);
++ INIT_LIST_HEAD(&new->perm_list);
++ INIT_LIST_HEAD(&new->device_list);
++
++ write_lock(&trustee_hash_lock);
++ if (get_trustee_for_name(&newname, 0)) goto err3;
++
++ if (is_root) {
++ root = NULL;
++ } else if (!(root = get_trustee_for_name(&rootname, 0))) {
++ TS_ERR_MSG("Root trustee disappeared on us!\n");
++ goto err3;
++ }
++ hlist_add_head(&new->hash_list, &trustee_hash[hash_slot(name)]);
++ if (!is_root) {
++ list_add_tail(&new->device_list, &root->device_list);
++ }
++ calculate_deepest_level(&newname);
++ TS_DEBUG_MSG("Created '%s' trustee\n", newname.filename);
++ r = 1;
++err3:
++ write_unlock(&trustee_hash_lock);
++ if (!r) vfree(new);
++err2:
++ if (must_copy && !r) free_trustee_name(&newname);
++err1:
++ free_trustee_name(&rootname);
++err0:
++ return r;
++}
++
++/**
++ * Add a permissions module to the trustee specified by name.
++ */
++static unsigned add_trustee_perm
++ (struct trustee_name *name, struct trustee_permission acl)
++{
++ struct trustee_hash_element *r = NULL;
++ struct trustee_permission_capsule *capsule;
++
++ capsule = vmalloc(sizeof(struct trustee_permission_capsule));
++ if (!capsule) {
++ TS_ERR_MSG
++ ("Can not allocate memory for trustee capsule\n");
++ return 0;
++ }
++ capsule->permission = acl;
++
++ write_lock(&trustee_hash_lock);
++ r = get_trustee_for_name(name, 0);
++
++ if (r) {
++ list_add_tail(&capsule->perm_list, &r->perm_list);
++ write_unlock(&trustee_hash_lock);
++ TS_DEBUG_MSG("Added permission capsule to '%s' trustee\n", name->filename);
++ return 1;
++ }
++ write_unlock(&trustee_hash_lock);
++ TS_ERR_MSG("trustee disappeared under us while trying to add perms\n");
++ vfree(capsule);
++
++ return 0;
++}
++
++/*
++ * Get the mask for a trustee name.
++ * This should be called with a lock on the trustee_hash (which should
++ * not be released until you are done with the returned hash_element)!
++ */
++static int get_trustee_mask_for_name(struct trustee_name *name,
++ int oldmask, int height,
++ struct trustee_hash_element **element,
++ unsigned ignore_case)
++{
++ struct trustee_hash_element *e;
++ int m;
++ struct trustee_permission_capsule *l;
++ int appl;
++ e = get_trustee_for_name(name, ignore_case);
++ if (!e) {
++ return oldmask;
++ }
++ list_for_each_entry(l, &e->perm_list, perm_list) {
++ if ((height < 0)
++ && (l->permission.mask & TRUSTEE_ONE_LEVEL_MASK))
++ continue;
++ if (element) {
++ *element = e;
++ element = NULL;
++ }
++ appl = ((!(l->permission.mask & TRUSTEE_IS_GROUP_MASK))
++ && (current->fsuid == l->permission.u.uid))
++ || (((l->permission.mask & TRUSTEE_IS_GROUP_MASK))
++ && (in_group_p(l->permission.u.gid)))
++ || (l->permission.mask & TRUSTEE_ALL_MASK);
++ if (l->permission.mask & TRUSTEE_NOT_MASK)
++ appl = !appl;
++
++ if (!appl)
++ continue;
++
++ m = l->permission.mask & TRUSTEE_ACL_MASK;
++
++ if (l->permission.mask & TRUSTEE_ALLOW_DENY_MASK)
++ m <<= TRUSTEE_NUM_ACL_BITS;
++
++ oldmask =
++ l->permission.
++ mask & TRUSTEE_CLEAR_SET_MASK ? (oldmask & (~m))
++ : (oldmask | m);
++ }
++
++ return oldmask;
++}
++
++/*
++ * Return non-zero if a trustee exists in a subpath.
++ *
++ * WARNING!
++ * This function requires that you lock/unlock the trustees_hash_lock
++ */
++int trustee_has_child(struct vfsmount *mnt, char *file_name)
++{
++ struct trustee_name trustee_name;
++ char tempchar;
++ unsigned ignore_case = 0;
++ struct trustee_hash_element *root;
++ size_t len;
++ struct trustee_ic *iter;
++ struct trustee_hash_element *r;
++
++ if (!file_name || !*file_name) return 0;
++
++ list_for_each_entry(iter, &trustee_ic_list, ic_list) {
++ if (trustee_dev_cmp
++ (iter->dev, trustee_name.dev, iter->devname,
++ trustee_name.devname)) {
++ ignore_case = 1;
++ break;
++ }
++ }
++
++ trustee_name.dev = mnt->mnt_sb->s_dev;
++ trustee_name.devname = mnt->mnt_devname;
++ trustee_name.filename = file_name;
++ tempchar = file_name[1];
++ file_name[1] = '\0';
++
++ root = get_trustee_for_name(&trustee_name, ignore_case);
++ if (!root) return 0;
++
++ file_name[1] = tempchar;
++
++ len = strlen(file_name);
++
++ list_for_each_entry(r, &root->device_list, device_list) {
++ size_t this_len = strlen(r->name.filename);
++ if (this_len <= len) continue;
++ if (!strncmp(file_name, r->name.filename, len) &&
++ r->name.filename[len] != '\0')
++ return 1;
++ }
++
++ return 0;
++}
++
++/*
++ * Return the mask for a file.
++ *
++ * WARNING!
++ * This function requires that you lock/unlock the trustees_hash_lock
++ */
++int trustee_perm(struct dentry *dentry, struct vfsmount *mnt,
++ char *file_name, int unix_ret, int depth, int is_dir,
++ struct trustee_hash_element **deepest)
++{
++ static char dbl_nul_slash[3] = { '/', '\0', '\0' };
++ int oldmask = trustee_default_acl;
++ int height = 0;
++ char *filecount;
++ char c;
++ struct trustee_name trustee_name;
++ struct trustee_ic *iter;
++ unsigned ignore_case = 0;
++
++ trustee_name.dev = mnt->mnt_sb->s_dev;
++ trustee_name.devname = mnt->mnt_devname;
++ trustee_name.filename = file_name;
++
++ list_for_each_entry(iter, &trustee_ic_list, ic_list) {
++ if (trustee_dev_cmp
++ (iter->dev, trustee_name.dev, iter->devname,
++ trustee_name.devname)) {
++ ignore_case = 1;
++ break;
++ }
++ }
++
++ if (deepest) *deepest = NULL;
++
++ filecount = file_name + 1;
++ /* Try to handle the unlikely case where the string will be '/'
++ * out here to simplify the logic inside the loop. We do this
++ * by giving it a string with two nul byte terminators so that it
++ * will gracefully (and safely) make it through the loop below.
++ */
++ if (*filecount == '\0') {
++ file_name = dbl_nul_slash;
++ filecount = file_name + 1;
++ }
++ do {
++ c = *filecount;
++ *filecount = 0;
++ oldmask =
++ get_trustee_mask_for_name(&trustee_name, oldmask,
++ height - depth + !is_dir,
++ deepest, ignore_case);
++ height++;
++ *filecount = c;
++ ++filecount;
++ while ((*filecount) && (*filecount != '/')) filecount++;
++
++ } while(*filecount);
++
++ return oldmask;
++}
++
++/* Clear out the hash of trustees and release the hash itself.
++ * Also gets rid of the ignore-case list
++ */
++static void trustees_clear_all(void)
++{
++ struct trustee_hash_element *item = NULL;
++ struct hlist_node *iter, *temp = NULL;
++ unsigned i;
++ write_lock(&trustee_hash_lock);
++
++ for (i = 0; i < trustee_hash_size; i++) {
++ hlist_for_each_entry_safe(item, iter, temp, &trustee_hash[i], hash_list) {
++ free_hash_element(item);
++ }
++ INIT_HLIST_HEAD(&trustee_hash[i]);
++ }
++
++ deepest_level = 0;
++
++ remove_ic_devs();
++
++ write_unlock(&trustee_hash_lock);
++}
++
++/*
++ * Initialize globals
++ */
++int trustees_funcs_init_globals(void)
++{
++ unsigned int iter;
++
++ if (trustee_hash_size <= 0)
++ return 1;
++
++ rwlock_init(&trustee_hash_lock);
++
++ trustee_hash = vmalloc(sizeof(*trustee_hash) * trustee_hash_size);
++ if (!trustee_hash)
++ return 1;
++
++ for (iter = 0; iter < trustee_hash_size; iter++)
++ INIT_HLIST_HEAD(trustee_hash + iter);
++
++ return 0;
++}
++
++/*
++ * Clear globals
++ */
++int trustees_funcs_cleanup_globals(void)
++{
++ trustees_clear_all();
++
++ vfree(trustee_hash);
++
++ return 0;
++}
++
++/*
++ * Prepare a trustee name from a passed in trustee name.
++ */
++static int prepare_trustee_name(u32 device, char *devname, char *filename, struct trustee_name *name)
++{
++ size_t devl, filel;
++ char *devb = NULL, *fileb = NULL;
++
++ if ((!name))
++ return 0;
++
++ filel = strlen(filename);
++ devl = strlen(devname);
++
++ if (devl > PATH_MAX) {
++ TS_ERR_MSG("device name bad, command ignored.\n");
++ return 0;
++ }
++ if (filel > PATH_MAX) {
++ TS_ERR_MSG("file name bad, command ignored.\n");
++ return 0;
++ }
++
++ devb = vmalloc_strdup(devname, devl);
++ if (!devb) {
++ TS_ERR_MSG("Couldn't allocate mem for devb.\n");
++ return 0;
++ }
++
++ fileb = vmalloc_strdup(filename, filel);
++ if (!fileb) {
++ TS_ERR_MSG("Couldn't allocate mem for fileb.\n");
++ return 0;
++ }
++
++ name->devname = devb;
++ name->filename = fileb;
++
++ name->dev = new_decode_dev(device);
++
++ return 1;
++}
++
++/*
++ * Process a user command
++ */
++extern int trustees_process_command(struct trustee_command command,
++ void **arg,
++ size_t *argsize)
++{
++ int r = -ENOSYS;
++ int must_free = 0;
++ struct trustee_name name;
++
++ if ((current->euid != 0) && !capable(CAP_SYS_ADMIN)) {
++ r = -EACCES;
++ return r;
++ }
++
++ switch (command.command) {
++ case TRUSTEE_COMMAND_MAKE_IC:
++ if (command.numargs != 2 ||
++ argsize[1] != sizeof(u32)) goto unlk;
++ add_ic_dev(*(u32 *)arg[1], arg[0]);
++ r = 0;
++ break;
++ case TRUSTEE_COMMAND_REMOVE_ALL:
++ if (command.numargs != 0) goto unlk;
++ trustees_clear_all();
++ r = 0;
++ break;
++ case TRUSTEE_COMMAND_ADD:
++ if (command.numargs != 4 ||
++ argsize[3] != sizeof(u32) ||
++ argsize[1] != sizeof(struct trustee_permission))
++ goto unlk;
++ if (!prepare_trustee_name(*(u32 *)arg[3], arg[2], arg[0], &name)) {
++ r = -ENOMEM;
++ goto unlk;
++ }
++ if (!add_trustee(&name, 0)) {
++ must_free = 1;
++ }
++ if (!add_trustee_perm(&name, *(struct trustee_permission *)arg[1]))
++ r = -ENOMEM;
++ else
++ r = 0;
++
++ if (must_free) free_trustee_name(&name);
++ break;
++ }
++ unlk:
++
++ return r;
++}
+diff -Nurd linux-2.6.24/security/trustees/init.c linux-2.6.24-oxe810/security/trustees/init.c
+--- linux-2.6.24/security/trustees/init.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/security/trustees/init.c 2008-06-11 17:46:44.000000000 +0200
+@@ -0,0 +1,57 @@
++/*
++ * Trustees ACL Project
++ *
++ * Copyright (c) 1999-2000 Vyacheslav Zavadsky
++ * Copyright (c) 2004 Andrew Ruder (aeruder@ksu.edu)
++ *
++ * 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, version 2.
++ *
++ * Module initialization and cleanup
++ *
++ * History:
++ * 2002-12-16 trustees 2.10 released by Vyacheslav Zavadsky
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/security.h>
++#include <linux/capability.h>
++
++#include "internal.h"
++
++unsigned int trustee_hash_size = 256;
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Trustees ACL System");
++MODULE_AUTHOR("Vyacheslav Zavadsky and Andrew E. Ruder <aeruder@ksu.edu>");
++MODULE_VERSION("2.11");
++
++MODULE_PARM_DESC(hash_size, "Trustees hash size");
++module_param_named(hash_size, trustee_hash_size, uint, 0444);
++
++
++static int __init trustees_init(void)
++{
++ if (trustees_funcs_init_globals() != 0) {
++ return -EINVAL;
++ }
++
++ if (trustees_init_fs() != 0) {
++ trustees_funcs_cleanup_globals();
++ return -EINVAL;
++ }
++
++ if (trustees_init_security() != 0) {
++ trustees_deinit_fs();
++ trustees_funcs_cleanup_globals();
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++fs_initcall(trustees_init);
+diff -Nurd linux-2.6.24/security/trustees/internal.h linux-2.6.24-oxe810/security/trustees/internal.h
+--- linux-2.6.24/security/trustees/internal.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/security/trustees/internal.h 2008-06-11 17:46:44.000000000 +0200
+@@ -0,0 +1,100 @@
++/*
++ * Trustees ACL Project
++ *
++ * Copyright (c) 1999-2000 Vyacheslav Zavadsky
++ * Copyright (c) 2004 Andrew Ruder (aeruder@ksu.edu)
++ *
++ * 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, version 2.
++ *
++ * Private methods and definitions used only within the module.
++ *
++ */
++
++#ifndef _LINUX_TRUSTEES_H
++#define _LINUX_TRUSTEES_H
++#include <linux/types.h>
++#include <linux/dcache.h>
++#include <linux/kdev_t.h>
++#include <linux/list.h>
++#include <linux/version.h>
++#include <linux/trustees.h>
++
++#define TRUSTEE_DEFAULT_MASK TRUSTEE_USE_UNIX_MASK
++
++struct trustee_ic {
++ dev_t dev;
++ char *devname; /* ONLY if MAJOR(dev)==0 */
++ struct list_head ic_list;
++};
++
++struct trustee_name {
++ dev_t dev;
++ char *filename;
++ char *devname; /* ONLY if MAJOR(dev)==0 */
++};
++
++struct trustee_permission_capsule {
++ struct list_head perm_list;
++ struct trustee_permission permission;
++};
++
++/* For the usage field */
++#define TRUSTEE_HASH_ELEMENT_USED 2
++#define TRUSTEE_HASH_ELEMENT_DELETED 1
++#define TRUSTEE_HASH_ELEMENT_NOTUSED 0
++
++struct trustee_hash_element {
++ struct trustee_name name;
++ struct list_head perm_list;
++ struct hlist_node hash_list;
++ struct list_head device_list;
++};
++
++extern char *trustees_filename_for_dentry(struct dentry *dentry, int *d, int trunc);
++
++extern int trustees_funcs_init_globals(void);
++extern int trustees_funcs_cleanup_globals(void);
++
++int trustee_has_child(struct vfsmount *mnt, char *file_name);
++int trustee_perm(struct dentry *dentry, struct vfsmount *mnt,
++ char *file_name, int unix_ret, int depth, int is_dir,
++ struct trustee_hash_element **deepest);
++
++extern int trustees_process_command(struct trustee_command command,
++ void **arg, size_t *argsize);
++
++extern unsigned int trustee_hash_size;
++extern rwlock_t trustee_hash_lock;
++
++#define TRUSTEE_INITIAL_NAME_BUFFER 256
++#define TRUSTEE_HASDEVNAME(TNAME) (MAJOR((TNAME).dev)==0)
++
++#define TS_ERR_MSG(...) printk(KERN_ERR "Trustees: " __VA_ARGS__)
++
++#ifdef TRUSTEES_DEBUG
++#define TS_DEBUG_MSG(...) printk(KERN_ERR "Trustees: " __VA_ARGS__)
++#else
++#define TS_DEBUG_MSG(...)
++#endif
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
++#define NAMESPACE_SEM(_ns) (namespace_sem)
++#else
++#define NAMESPACE_SEM(_ns) ((_ns)->sem)
++#endif
++
++/*
++ * Magic number!
++ *
++ * FIXME: Do I just make this up or is there some system for coming
++ * up with magic numbers?
++ */
++#define TRUSTEES_MAGIC 0x32236975
++
++int trustees_init_fs(void);
++void trustees_deinit_fs(void);
++
++int trustees_init_security(void);
++#endif /* _LINUX_TRUSTEES_H */
+diff -Nurd linux-2.6.24/security/trustees/security.c linux-2.6.24-oxe810/security/trustees/security.c
+--- linux-2.6.24/security/trustees/security.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24-oxe810/security/trustees/security.c 2008-06-11 17:46:44.000000000 +0200
+@@ -0,0 +1,423 @@
++/*
++ * Trustees ACL Project
++ *
++ * Copyright (c) 1999-2000 Vyacheslav Zavadsky
++ * Copyright (c) 2004 Andrew Ruder (aeruder@ksu.edu)
++ *
++ * 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, version 2.
++ *
++ * The security module (LSM API) component of the trustees system
++ *
++ * One quick note: generally security modules with the LSM are supposed
++ * to be solely restrictive modules. Unless the trustees module were to
++ * require that people set all files rwx by all, it could not function
++ * as it is meant to function as a solely restrictive module.
++ *
++ * To compensate, every process is given the capability CAP_DAC_OVERRIDE.
++ * In other words, every process is first given full rights to the filesystem.
++ * This is the only non-restricting portion of this module, since it -does-
++ * in fact give additional permissions. However, in the inode_permission hook,
++ * any rights the user should not have are taken away.
++ *
++ * Side effects: Posix ACLs or other filesystem-specific permissions are not
++ * honored. Trustees ACLs can (and do) take into account the standard unix
++ * permissions, but any permissions further than that are difficult, to say
++ * the least, to take into account. I, personally, do not find this to
++ * be a problem since if you are using Trustees ACLs, why also require the use
++ * of another ACL system?
++ */
++
++#include <linux/security.h>
++#include <linux/capability.h>
++#include <linux/mount.h>
++#include <linux/namei.h>
++#include <linux/fs.h>
++#include <linux/slab.h>
++#include <linux/smp_lock.h>
++#include <linux/nsproxy.h>
++#include <linux/mnt_namespace.h>
++
++#include "internal.h"
++
++static int trustees_capable(struct task_struct *tsk, int cap);
++static int trustees_inode_permission(struct inode *inode,
++ int mask, struct nameidata *nd);
++
++/* Checks if user has access to the inode due to root status
++ */
++static inline int has_root_perm(struct inode *inode, int mask)
++{
++ umode_t mode = inode->i_mode;
++
++ if (!(mask & MAY_EXEC) || (mode & S_IXUGO) || S_ISDIR(mode))
++ if (current->fsuid == 0)
++ return 0;
++
++ return -EACCES;
++}
++
++/* The logic for this was mostly stolen from vfs_permission. The security API
++ * doesn't give a good way to use the actual vfs_permission for this since our
++ * CAP_DAC_OVERRIDE causes it to always return 0. But if we didn't return
++ * CAP_DAC_OVERRIDE, we'd never get to handle permissions! Since we don't need
++ * to handle capabilities and dealing with ACLs with trustees loaded isn't an
++ * issue for me, the function ends up being pretty simple.
++ */
++
++static inline int has_unix_perm(struct inode *inode, int mask)
++{
++ umode_t mode = inode->i_mode;
++ mask &= ~MAY_APPEND;
++
++ if (current->fsuid == inode->i_uid)
++ mode >>= 6;
++ else if (in_group_p(inode->i_gid))
++ mode >>= 3;
++
++ if (((mode & mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == mask))
++ return 0;
++
++ return -EACCES;
++}
++
++/* Find a vfsmount given an inode */
++static inline struct vfsmount *find_inode_mnt(struct inode *inode,
++ struct nameidata *nd)
++{
++ struct mnt_namespace *ns = NULL;
++ struct vfsmount *mnt = NULL;
++
++ if (likely(nd))
++ return mntget(nd->mnt);
++
++ /* Okay, we need to find the vfsmount by looking
++ * at the namespace now.
++ */
++ task_lock(current);
++ if (current->nsproxy) {
++ ns = current->nsproxy->mnt_ns;
++ if (ns)
++ get_mnt_ns(ns);
++ }
++ task_unlock(current);
++
++ if (!ns) return NULL;
++
++ list_for_each_entry(mnt, &ns->list, mnt_list) {
++ if (mnt->mnt_sb == inode->i_sb) {
++ mntget(mnt);
++ goto out;
++ }
++ }
++
++ out:
++ put_mnt_ns(ns);
++
++ return mnt;
++}
++
++/* Find a dentry given an inode */
++static inline struct dentry *find_inode_dentry(struct inode *inode,
++ struct nameidata *nd)
++{
++ struct dentry *dentry;
++
++ if (likely(nd))
++ return dget(nd->dentry);
++
++ dentry = d_find_alias(inode);
++
++ return dentry;
++}
++
++/*
++ * Return 1 if they are under the same set of trustees
++ * otherwise return 0. In the case that we are handling
++ * a directory, we also check to see if there are subdirectories
++ * with trustees.
++ */
++static inline int have_same_trustees(struct dentry *old_dentry,
++ struct dentry *new_dentry)
++{
++ struct vfsmount *mnt;
++ char *old_file_name, *new_file_name;
++ int old_depth, new_depth;
++ struct trustee_hash_element *old_deep, *new_deep;
++ int is_dir;
++ int ret = 0;
++
++ mnt = find_inode_mnt(old_dentry->d_inode, NULL);
++ if (unlikely(!mnt)) {
++ TS_ERR_MSG("inode does not have a mnt!\n");
++ return 0;
++ }
++
++ old_file_name = trustees_filename_for_dentry(old_dentry, &old_depth, 1);
++ if (!old_file_name) {
++ TS_ERR_MSG("Couldn't allocate filename\n");
++ goto out_old_dentry;
++ }
++
++ new_file_name = trustees_filename_for_dentry(new_dentry, &new_depth, 1);
++ if (!new_file_name) {
++ TS_ERR_MSG("Couldn't allocate filename\n");
++ goto out_new_dentry;
++ }
++
++ is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
++
++ read_lock(&trustee_hash_lock);
++ trustee_perm(old_dentry, mnt, old_file_name, ret, old_depth, is_dir,
++ &old_deep);
++ trustee_perm(new_dentry, mnt, new_file_name, ret, new_depth, is_dir,
++ &new_deep);
++ if (old_deep == new_deep) {
++ ret = 1;
++ if (is_dir) {
++ if (trustee_has_child(mnt, old_file_name) ||
++ trustee_has_child(mnt, new_file_name)) ret = 0;
++ }
++ }
++ read_unlock(&trustee_hash_lock);
++
++ kfree(new_file_name);
++out_new_dentry:
++ kfree(old_file_name);
++out_old_dentry:
++ mntput(mnt);
++
++ return ret;
++}
++
++
++static int trustees_inode_rename(struct inode *old_dir,
++ struct dentry *old_dentry,
++ struct inode *new_dir,
++ struct dentry *new_dentry);
++static int trustees_inode_link(struct dentry *old_dentry,
++ struct inode *dir,
++ struct dentry *new_dentry);
++
++/* Structure where we fill in the various hooks we are implementing in this module
++ */
++struct security_operations trustees_security_ops = {
++ .capable = trustees_capable,
++ .inode_permission = trustees_inode_permission,
++ .inode_link = trustees_inode_link,
++ .inode_rename = trustees_inode_rename,
++
++ .ptrace = cap_ptrace,
++ .capget = cap_capget,
++ .capset_check = cap_capset_check,
++ .capset_set = cap_capset_set,
++ .settime = cap_settime,
++ .netlink_send = cap_netlink_send,
++ .netlink_recv = cap_netlink_recv,
++
++ .bprm_apply_creds = cap_bprm_apply_creds,
++ .bprm_set_security = cap_bprm_set_security,
++ .bprm_secureexec = cap_bprm_secureexec,
++
++ .inode_setxattr = cap_inode_setxattr,
++ .inode_removexattr = cap_inode_removexattr,
++
++ .task_post_setuid = cap_task_post_setuid,
++ .task_reparent_to_init = cap_task_reparent_to_init,
++
++ .syslog = cap_syslog,
++
++ .vm_enough_memory = cap_vm_enough_memory
++};
++
++#define ALL_MAYS (MAY_WRITE | MAY_EXEC | MAY_READ)
++/* Converts a trustee_mask to a normal unix mask
++ */
++static int inline trustee_mask_to_normal_mask(int mask, int isdir)
++{
++ int r = 0;
++ if ((mask & TRUSTEE_READ_MASK) && !isdir)
++ r |= MAY_READ;
++ if ((mask & TRUSTEE_READ_DIR_MASK) && isdir)
++ r |= MAY_READ;
++ if (mask & TRUSTEE_WRITE_MASK)
++ r |= MAY_WRITE;
++ if ((mask & TRUSTEE_BROWSE_MASK) && isdir)
++ r |= MAY_EXEC;
++ if ((mask & TRUSTEE_EXECUTE_MASK) && !isdir)
++ r |= MAY_EXEC;
++ return r;
++}
++
++/* This is the meat of the permissions checking. First it checks for root,
++ * otherwise it first checks for any errors finding the dentry/vfsmount for
++ * the inode, and then it looks up the dentry in the trustees hash.
++ */
++static int trustees_inode_permission(struct inode *inode,
++ int mask, struct nameidata *nd)
++{
++ struct dentry *dentry;
++ struct vfsmount *mnt;
++ char *file_name;
++ int is_dir;
++ int ret;
++ int depth;
++ int amask;
++ int dmask;
++ umode_t mode = inode->i_mode;
++
++ if (has_root_perm(inode, mask) == 0)
++ return 0;
++
++ ret = has_unix_perm(inode, mask);
++
++ mnt = find_inode_mnt(inode, nd);
++ if (unlikely(!mnt)) {
++ TS_ERR_MSG("inode does not have a mnt!\n");
++ return -EACCES; /* has_unix_perm(inode, mask); */
++ }
++
++ dentry = find_inode_dentry(inode, nd);
++ if (unlikely(!dentry)) {
++ /* Most of the time when this happens, it is the /
++ * If it is not, we need to dump as much information
++ * as possible on it and dump it to logs, because
++ * I'm really not sure how it happens.
++ */
++ if (inode == mnt->mnt_root->d_inode) {
++ dentry = dget(mnt->mnt_root);
++ } else {
++ /* I have seen this happen once but I did not have any
++ * way to see what caused it. I am gonna dump_stack
++ * until I have that happen again to see if the cause
++ * is something that I need to worry about.
++ */
++ dump_stack(); /* DEBUG FIXME */
++ TS_ERR_MSG("Inode number: %ld\n", inode->i_ino);
++ TS_ERR_MSG("dentry does not exist!\n");
++ goto out_mnt;
++ }
++ }
++ file_name = trustees_filename_for_dentry(dentry, &depth, 1);
++ if (!file_name) {
++ TS_ERR_MSG("Couldn't allocate filename\n");
++ ret = -EACCES;
++ goto out_dentry;
++ }
++
++ is_dir = S_ISDIR(inode->i_mode);
++
++ read_lock(&trustee_hash_lock);
++ amask = trustee_perm(dentry, mnt, file_name, ret, depth, is_dir,
++ (struct trustee_hash_element **)NULL);
++ read_unlock(&trustee_hash_lock);
++ dmask = amask >> TRUSTEE_NUM_ACL_BITS;
++
++ /* no permission if denied */
++ if (trustee_mask_to_normal_mask(dmask, is_dir) & mask & ALL_MAYS) {
++ ret = -EACCES;
++ goto out;
++ }
++ /* use unix perms */
++ if (!(dmask & TRUSTEE_USE_UNIX_MASK) &&
++ (amask & TRUSTEE_USE_UNIX_MASK) && (!ret))
++ goto out;
++
++ /* if the file isn't executable, then the trustees shouldn't
++ * make it executable
++ */
++ if ((mask & MAY_EXEC) && !(mode & S_IXOTH) &&
++ !((mode >> 3) & S_IXOTH) & !((mode >> 6) & S_IXOTH) &&
++ (!is_dir)) {
++ ret = -EACCES;
++ goto out;
++ }
++ /* Check trustees for permission
++ */
++ if ((trustee_mask_to_normal_mask(amask, is_dir) & mask & ALL_MAYS)
++ == mask) {
++ ret = 0;
++ goto out;
++ } else
++ ret = -EACCES;
++
++ out:
++ kfree(file_name);
++ out_dentry:
++ dput(dentry);
++ out_mnt:
++ mntput(mnt);
++
++ return ret;
++}
++
++/* We should only allow hard links under one of two conditions:
++ * 1. Its in the same trustee
++ * - if the two dentries are covered by the same trustee, there shouldn't
++ * be much of a problem with allowing the hardlink to occur.
++ * 2. fsuid = 0
++ */
++static int trustees_inode_link(struct dentry *old_dentry,
++ struct inode *dir,
++ struct dentry *new_dentry)
++{
++ if (current->fsuid == 0)
++ return 0;
++
++ if (have_same_trustees(old_dentry, new_dentry))
++ return 0;
++
++ return -EXDEV;
++}
++
++/* We have a few renames to protect against:
++ * 1. Any file or directory that is affected by different trustees at its
++ * old location than at its new location.
++ * 2. In the case of a directory, we should protect against moving a directory
++ * that has trustees set inside of it.
++ *
++ * In any case above, we return -EXDEV which signifies to the calling program that
++ * the files are on different devices, and assuming the program is written correctly
++ * it should then handle the situation by copying the files and removing the originals
++ * ( which will then use the trustees permissions as they are meant to be used )
++ */
++static int trustees_inode_rename(struct inode *old_dir,
++ struct dentry *old_dentry,
++ struct inode *new_dir,
++ struct dentry *new_dentry)
++{
++ if (current->fsuid == 0)
++ return 0;
++
++ if (have_same_trustees(old_dentry, new_dentry)) return 0;
++
++ return -EXDEV;
++}
++
++/* Return CAP_DAC_OVERRIDE on everything. We want to handle our own
++ * permissions (overriding those normally allowed by unix permissions)
++ */
++static int trustees_capable(struct task_struct *tsk, int cap)
++{
++ if (cap == CAP_DAC_OVERRIDE)
++ return 0;
++
++ return cap_capable(tsk, cap);
++}
++
++/* Register the security module
++ */
++int trustees_init_security(void)
++{
++ /* FIXME: add in secondary module register
++ * not worry about it now since I have better
++ * things to worry about. Comprende?
++ */
++ if (register_security(&trustees_security_ops)) {
++ TS_ERR_MSG("Could not register security component\n");
++ return -EINVAL;
++ }
++
++ return 0;
++}
+diff -Nurd linux-2.6.24/sound/oss/via82cxxx_audio.c linux-2.6.24-oxe810/sound/oss/via82cxxx_audio.c
+--- linux-2.6.24/sound/oss/via82cxxx_audio.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/sound/oss/via82cxxx_audio.c 2008-06-11 17:46:29.000000000 +0200
+@@ -2104,6 +2104,7 @@
+ {
+ struct via_info *card = vma->vm_private_data;
+ struct via_channel *chan = &card->ch_out;
++ unsigned long max_bufs;
+ struct page *dmapage;
+ unsigned long pgoff;
+ int rd, wr;
+@@ -2127,14 +2128,11 @@
+ rd = card->ch_in.is_mapped;
+ wr = card->ch_out.is_mapped;
+
+-#ifndef VIA_NDEBUG
+- {
+- unsigned long max_bufs = chan->frag_number;
+- if (rd && wr) max_bufs *= 2;
+- /* via_dsp_mmap() should ensure this */
+- assert (pgoff < max_bufs);
+- }
+-#endif
++ max_bufs = chan->frag_number;
++ if (rd && wr)
++ max_bufs *= 2;
++ if (pgoff >= max_bufs)
++ return NOPAGE_SIGBUS;
+
+ /* if full-duplex (read+write) and we have two sets of bufs,
+ * then the playback buffers come first, sez soundcard.c */
+diff -Nurd linux-2.6.24/sound/usb/usx2y/usX2Yhwdep.c linux-2.6.24-oxe810/sound/usb/usx2y/usX2Yhwdep.c
+--- linux-2.6.24/sound/usb/usx2y/usX2Yhwdep.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/sound/usb/usx2y/usX2Yhwdep.c 2008-06-11 17:46:26.000000000 +0200
+@@ -88,7 +88,7 @@
+ us428->us428ctls_sharedmem->CtlSnapShotLast = -2;
+ }
+ area->vm_ops = &us428ctls_vm_ops;
+- area->vm_flags |= VM_RESERVED;
++ area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
+ area->vm_private_data = hw->private_data;
+ return 0;
+ }
+diff -Nurd linux-2.6.24/sound/usb/usx2y/usx2yhwdeppcm.c linux-2.6.24-oxe810/sound/usb/usx2y/usx2yhwdeppcm.c
+--- linux-2.6.24/sound/usb/usx2y/usx2yhwdeppcm.c 2008-01-24 23:58:37.000000000 +0100
++++ linux-2.6.24-oxe810/sound/usb/usx2y/usx2yhwdeppcm.c 2008-06-11 17:46:26.000000000 +0200
+@@ -728,7 +728,7 @@
+ return -ENODEV;
+ }
+ area->vm_ops = &snd_usX2Y_hwdep_pcm_vm_ops;
+- area->vm_flags |= VM_RESERVED;
++ area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
+ area->vm_private_data = hw->private_data;
+ return 0;
+ }
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
SECTION = "kernel"
DESCRIPTION = "handhelds.org Linux kernel 2.6 for PocketPCs and other consumer handheld devices."
LICENSE = "GPL"
-PR = "r24"
+PR = "r25"
DEFAULT_PREFERENCE = "-1"
--- /dev/null
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.28-omap1
+# Wed Feb 4 12:40:38 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_OPROFILE_ARMV7=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+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_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=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_COMPAT_BRK is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LSF=y
+# 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=y
+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_CLASSIC_RCU=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_MSM is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+# CONFIG_ARCH_OMAP1 is not set
+# CONFIG_ARCH_OMAP2 is not set
+CONFIG_ARCH_OMAP3=y
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
+# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+CONFIG_OMAP_SMARTREFLEX=y
+# CONFIG_OMAP_SMARTREFLEX_TESTING is not set
+# CONFIG_OMAP_RESET_CLOCKS is not set
+CONFIG_OMAP_BOOT_TAG=y
+CONFIG_OMAP_BOOT_REASON=y
+# CONFIG_OMAP_COMPONENT_VERSION is not set
+# CONFIG_OMAP_GPIO_SWITCH is not set
+# CONFIG_OMAP_MUX is not set
+CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MMU_FWK is not set
+# CONFIG_OMAP_MBOX_FWK is not set
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_TICK_GPTIMER=1
+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_OMAP2_DSS=y
+CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y
+CONFIG_OMAP2_DSS_RFBI=y
+CONFIG_OMAP2_DSS_VENC=y
+CONFIG_OMAP2_DSS_SDI=y
+CONFIG_OMAP2_DSS_DSI=y
+CONFIG_OMAP2_DSS_USE_DSI_PLL=y
+# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set
+CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0
+CONFIG_ARCH_OMAP34XX=y
+CONFIG_ARCH_OMAP3430=y
+
+#
+# OMAP Board Type
+#
+# CONFIG_MACH_OMAP_LDP is not set
+# CONFIG_MACH_OMAP_3430SDP is not set
+# CONFIG_MACH_OMAP3EVM is not set
+# CONFIG_MACH_OMAP3_BEAGLE is not set
+CONFIG_MACH_OVERO=y
+# CONFIG_MACH_OMAP3_PANDORA is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_IFAR=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=128
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL 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_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_LEDS=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=" debug "
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+# CONFIG_ARM_ERRATUM_451034 is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+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_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+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=y
+# CONFIG_NET_KEY_MIGRATE 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=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# 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=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# 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=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE 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_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_NET_SCHED 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=y
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+# CONFIG_BT_HCIBTUSB is not set
+# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+# CONFIG_BT_HCIUART_LL is not set
+CONFIG_BT_HCIBCM203X=y
+CONFIG_BT_HCIBPA10X=y
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIBRF6150 is not set
+# CONFIG_BT_HCIH4P is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+CONFIG_CFG80211=y
+CONFIG_NL80211=y
+CONFIG_WIRELESS_OLD_REGULATORY=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_MAC80211=y
+
+#
+# Rate control algorithm selection
+#
+CONFIG_MAC80211_RC_PID=y
+# CONFIG_MAC80211_RC_MINSTREL is not set
+CONFIG_MAC80211_RC_DEFAULT_PID=y
+# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set
+CONFIG_MAC80211_RC_DEFAULT="pid"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_LEDS is not set
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+# 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=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
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# 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 is not set
+# CONFIG_MTD_JEDECPROBE 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_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS 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_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=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_GPIO is not set
+# CONFIG_MTD_NAND_OMAP2 is not set
+CONFIG_MTD_NAND_IDS=y
+# 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
+
+#
+# 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=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+# 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=16384
+# CONFIG_BLK_DEV_XIP is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# 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 is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# 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=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_DELAY=m
+# CONFIG_DM_UEVENT is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_MII=y
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_AX8817X=y
+CONFIG_USB_NET_CDCETHER=y
+CONFIG_USB_NET_DM9601=m
+# CONFIG_USB_NET_SMSC95XX is not set
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_KC2190=y
+CONFIG_USB_NET_ZAURUS=m
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# 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_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_TWL4030 is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM 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_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# 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_AT24 is not set
+# CONFIG_SENSORS_EEPROM 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_TPS65010 is not set
+CONFIG_TWL4030_MADC=m
+CONFIG_TWL4030_PWRBUTTON=y
+CONFIG_TWL4030_POWEROFF=y
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_TSL2563 is not set
+# CONFIG_LP5521 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_BITBANG is not set
+CONFIG_SPI_OMAP24XX=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_TSC210X is not set
+# CONFIG_SPI_TSC2301 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_DEBUG_GPIO=y
+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_TWL4030=y
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=m
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+# CONFIG_TWL4030_BCI_BATTERY is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 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_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 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_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_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_TSC210X is not set
+CONFIG_SENSORS_OMAP34XX=y
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_OMAP_WATCHDOG=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_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+CONFIG_TWL4030_CORE=y
+# CONFIG_TWL4030_POWER 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_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_DVB_CORE=m
+CONFIG_VIDEO_MEDIA=m
+
+#
+# Multimedia drivers
+#
+CONFIG_MEDIA_ATTACH=y
+CONFIG_MEDIA_TUNER=m
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=m
+CONFIG_MEDIA_TUNER_TDA8290=m
+CONFIG_MEDIA_TUNER_TDA9887=m
+CONFIG_MEDIA_TUNER_TEA5761=m
+CONFIG_MEDIA_TUNER_TEA5767=m
+CONFIG_MEDIA_TUNER_MT20XX=m
+CONFIG_MEDIA_TUNER_XC2028=m
+CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_DVB_CAPTURE_DRIVERS=y
+# CONFIG_TTPCI_EEPROM is not set
+
+#
+# Supported USB Adapters
+#
+# CONFIG_DVB_USB is not set
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+# CONFIG_DVB_SIANO_SMS1XXX is not set
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+# CONFIG_DVB_B2C2_FLEXCOP is not set
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+# CONFIG_DVB_FE_CUSTOMISE is not set
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_S5H1420=m
+# CONFIG_DVB_STV0288 is not set
+# CONFIG_DVB_STB6000 is not set
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_TDA10086=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_TUNER_ITD1000=m
+CONFIG_DVB_TDA826X=m
+CONFIG_DVB_TUA6100=m
+# CONFIG_DVB_CX24116 is not set
+# CONFIG_DVB_SI21XX is not set
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+# CONFIG_DVB_DRX397XD is not set
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+CONFIG_DVB_DIB7000M=m
+CONFIG_DVB_DIB7000P=m
+CONFIG_DVB_TDA10048=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_TDA10023=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+# CONFIG_DVB_OR51211 is not set
+# CONFIG_DVB_OR51132 is not set
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+CONFIG_DVB_S5H1409=m
+# CONFIG_DVB_AU8522 is not set
+# CONFIG_DVB_S5H1411 is not set
+
+#
+# Digital terrestrial only tuners/PLL
+#
+# CONFIG_DVB_PLL is not set
+# CONFIG_DVB_TUNER_DIB0070 is not set
+
+#
+# SEC control devices for DVB-S
+#
+CONFIG_DVB_LNBP21=m
+# CONFIG_DVB_ISL6405 is not set
+CONFIG_DVB_ISL6421=m
+# CONFIG_DVB_LGS8GL5 is not set
+
+#
+# Tools to develop new frontends
+#
+# CONFIG_DVB_DUMMY_FE is not set
+# CONFIG_DVB_AF9013 is not set
+# CONFIG_DAB 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_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=8
+CONFIG_FB_OMAP2=y
+CONFIG_FB_OMAP2_DEBUG=y
+# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set
+CONFIG_FB_OMAP2_NUM_FBS=3
+
+#
+# OMAP2/3 Display Device Drivers
+#
+CONFIG_PANEL_GENERIC=y
+# CONFIG_PANEL_SHARP_LS037V7DW01 is not set
+# CONFIG_PANEL_N800 is not set
+# CONFIG_CTRL_BLIZZARD is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+# CONFIG_LOGO is not set
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+# CONFIG_SND is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=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_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_EZKEY=y
+CONFIG_HID_GYRATION=y
+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_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 is not set
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+# 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
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_OMAP_EHCI_PHY_MODE=y
+# CONFIG_OMAP_EHCI_TLL_MODE is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_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
+
+#
+# OMAP 343x 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_GADGET_MUSB_HDRC is not set
+CONFIG_USB_MUSB_HDRC_HCD=y
+CONFIG_MUSB_PIO_ONLY=y
+# CONFIG_USB_MUSB_DEBUG is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_WDM=y
+# 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 information
+#
+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
+# 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=m
+# CONFIG_USB_EZUSB is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP2101 is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+# CONFIG_USB_BERRY_CHARGE is not set
+CONFIG_USB_LED=m
+# 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
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+# 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=m
+# CONFIG_USB_GADGET_DEBUG is not set
+# 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=y
+CONFIG_USB_OMAP=m
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_PXA27X 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_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_USB_CDC_COMPOSITE=m
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_ISP1301_OMAP is not set
+CONFIG_TWL4030_USB=y
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+CONFIG_SDIO_UART=y
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_OMAP_HS=y
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_OMAP_DEBUG is not set
+# CONFIG_LEDS_OMAP is not set
+# CONFIG_LEDS_OMAP_PWM is not set
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_PCA955X is not set
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGERS 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_TWL4030=y
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 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
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# 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_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+
+#
+# CBUS support
+#
+# CONFIG_CBUS is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+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_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# 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=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_FS_POSIX_ACL=y
+CONFIG_JFFS2_FS_SECURITY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+# CONFIG_CRAMFS 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=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+CONFIG_RPCSEC_GSS_KRB5=y
+# 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# 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=y
+# 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 is not set
+# 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=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# 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 is not set
+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_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+# 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_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_XOR_BLOCKS=m
+CONFIG_ASYNC_CORE=m
+CONFIG_ASYNC_MEMCPY=m
+CONFIG_ASYNC_XOR=m
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_TEST=m
+
+#
+# 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=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+# 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=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
--- /dev/null
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.28-omap1
+# Wed Feb 4 12:40:38 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_OPROFILE_ARMV7=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+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_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=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_COMPAT_BRK is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LSF=y
+# 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=y
+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_CLASSIC_RCU=y
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_MSM is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+# CONFIG_ARCH_OMAP1 is not set
+# CONFIG_ARCH_OMAP2 is not set
+CONFIG_ARCH_OMAP3=y
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
+# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+CONFIG_OMAP_SMARTREFLEX=y
+# CONFIG_OMAP_SMARTREFLEX_TESTING is not set
+# CONFIG_OMAP_RESET_CLOCKS is not set
+CONFIG_OMAP_BOOT_TAG=y
+CONFIG_OMAP_BOOT_REASON=y
+# CONFIG_OMAP_COMPONENT_VERSION is not set
+# CONFIG_OMAP_GPIO_SWITCH is not set
+# CONFIG_OMAP_MUX is not set
+CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MMU_FWK is not set
+# CONFIG_OMAP_MBOX_FWK is not set
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_TICK_GPTIMER=1
+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_OMAP2_DSS=y
+CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y
+CONFIG_OMAP2_DSS_RFBI=y
+CONFIG_OMAP2_DSS_VENC=y
+CONFIG_OMAP2_DSS_SDI=y
+CONFIG_OMAP2_DSS_DSI=y
+CONFIG_OMAP2_DSS_USE_DSI_PLL=y
+# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set
+CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0
+CONFIG_ARCH_OMAP34XX=y
+CONFIG_ARCH_OMAP3430=y
+
+#
+# OMAP Board Type
+#
+# CONFIG_MACH_OMAP_LDP is not set
+# CONFIG_MACH_OMAP_3430SDP is not set
+# CONFIG_MACH_OMAP3EVM is not set
+# CONFIG_MACH_OMAP3_BEAGLE is not set
+CONFIG_MACH_OVERO=y
+# CONFIG_MACH_OMAP3_PANDORA is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_IFAR=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=128
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL 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_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_LEDS=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=" debug "
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+# CONFIG_ARM_ERRATUM_451034 is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+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_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+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=y
+# CONFIG_NET_KEY_MIGRATE 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=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# 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=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# 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=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE 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_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_NET_SCHED 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=y
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+# CONFIG_BT_HCIBTUSB is not set
+# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+# CONFIG_BT_HCIUART_LL is not set
+CONFIG_BT_HCIBCM203X=y
+CONFIG_BT_HCIBPA10X=y
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIBRF6150 is not set
+# CONFIG_BT_HCIH4P is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+CONFIG_CFG80211=y
+CONFIG_NL80211=y
+CONFIG_WIRELESS_OLD_REGULATORY=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_MAC80211=y
+
+#
+# Rate control algorithm selection
+#
+CONFIG_MAC80211_RC_PID=y
+# CONFIG_MAC80211_RC_MINSTREL is not set
+CONFIG_MAC80211_RC_DEFAULT_PID=y
+# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set
+CONFIG_MAC80211_RC_DEFAULT="pid"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_LEDS is not set
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+# 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=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
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# 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 is not set
+# CONFIG_MTD_JEDECPROBE 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_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS 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_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=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_GPIO is not set
+# CONFIG_MTD_NAND_OMAP2 is not set
+CONFIG_MTD_NAND_IDS=y
+# 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
+
+#
+# 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=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+# 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=16384
+# CONFIG_BLK_DEV_XIP is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# 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 is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# 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=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_DELAY=m
+# CONFIG_DM_UEVENT is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_MII=y
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_AX8817X=y
+CONFIG_USB_NET_CDCETHER=y
+CONFIG_USB_NET_DM9601=m
+# CONFIG_USB_NET_SMSC95XX is not set
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_KC2190=y
+CONFIG_USB_NET_ZAURUS=m
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# 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_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_TWL4030 is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM 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_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# 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_AT24 is not set
+# CONFIG_SENSORS_EEPROM 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_TPS65010 is not set
+CONFIG_TWL4030_MADC=m
+CONFIG_TWL4030_PWRBUTTON=y
+CONFIG_TWL4030_POWEROFF=y
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_TSL2563 is not set
+# CONFIG_LP5521 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_BITBANG is not set
+CONFIG_SPI_OMAP24XX=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_TSC210X is not set
+# CONFIG_SPI_TSC2301 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_DEBUG_GPIO=y
+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_TWL4030=y
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=m
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+# CONFIG_TWL4030_BCI_BATTERY is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 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_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 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_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_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_TSC210X is not set
+CONFIG_SENSORS_OMAP34XX=y
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_OMAP_WATCHDOG=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_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+CONFIG_TWL4030_CORE=y
+# CONFIG_TWL4030_POWER 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_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_DVB_CORE=m
+CONFIG_VIDEO_MEDIA=m
+
+#
+# Multimedia drivers
+#
+CONFIG_MEDIA_ATTACH=y
+CONFIG_MEDIA_TUNER=m
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=m
+CONFIG_MEDIA_TUNER_TDA8290=m
+CONFIG_MEDIA_TUNER_TDA9887=m
+CONFIG_MEDIA_TUNER_TEA5761=m
+CONFIG_MEDIA_TUNER_TEA5767=m
+CONFIG_MEDIA_TUNER_MT20XX=m
+CONFIG_MEDIA_TUNER_XC2028=m
+CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_DVB_CAPTURE_DRIVERS=y
+# CONFIG_TTPCI_EEPROM is not set
+
+#
+# Supported USB Adapters
+#
+# CONFIG_DVB_USB is not set
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+# CONFIG_DVB_SIANO_SMS1XXX is not set
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+# CONFIG_DVB_B2C2_FLEXCOP is not set
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+# CONFIG_DVB_FE_CUSTOMISE is not set
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_S5H1420=m
+# CONFIG_DVB_STV0288 is not set
+# CONFIG_DVB_STB6000 is not set
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_TDA10086=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_TUNER_ITD1000=m
+CONFIG_DVB_TDA826X=m
+CONFIG_DVB_TUA6100=m
+# CONFIG_DVB_CX24116 is not set
+# CONFIG_DVB_SI21XX is not set
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+# CONFIG_DVB_DRX397XD is not set
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+CONFIG_DVB_DIB7000M=m
+CONFIG_DVB_DIB7000P=m
+CONFIG_DVB_TDA10048=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_TDA10023=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+# CONFIG_DVB_OR51211 is not set
+# CONFIG_DVB_OR51132 is not set
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+CONFIG_DVB_S5H1409=m
+# CONFIG_DVB_AU8522 is not set
+# CONFIG_DVB_S5H1411 is not set
+
+#
+# Digital terrestrial only tuners/PLL
+#
+# CONFIG_DVB_PLL is not set
+# CONFIG_DVB_TUNER_DIB0070 is not set
+
+#
+# SEC control devices for DVB-S
+#
+CONFIG_DVB_LNBP21=m
+# CONFIG_DVB_ISL6405 is not set
+CONFIG_DVB_ISL6421=m
+# CONFIG_DVB_LGS8GL5 is not set
+
+#
+# Tools to develop new frontends
+#
+# CONFIG_DVB_DUMMY_FE is not set
+# CONFIG_DVB_AF9013 is not set
+# CONFIG_DAB 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_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=8
+CONFIG_FB_OMAP2=y
+CONFIG_FB_OMAP2_DEBUG=y
+# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set
+CONFIG_FB_OMAP2_NUM_FBS=3
+
+#
+# OMAP2/3 Display Device Drivers
+#
+CONFIG_PANEL_GENERIC=y
+# CONFIG_PANEL_SHARP_LS037V7DW01 is not set
+# CONFIG_PANEL_N800 is not set
+# CONFIG_CTRL_BLIZZARD is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+# CONFIG_LOGO is not set
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+# CONFIG_SND is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=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_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_EZKEY=y
+CONFIG_HID_GYRATION=y
+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_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 is not set
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+# 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
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_OMAP_EHCI_PHY_MODE=y
+# CONFIG_OMAP_EHCI_TLL_MODE is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_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
+
+#
+# OMAP 343x 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_GADGET_MUSB_HDRC is not set
+CONFIG_USB_MUSB_HDRC_HCD=y
+CONFIG_MUSB_PIO_ONLY=y
+# CONFIG_USB_MUSB_DEBUG is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_WDM=y
+# 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 information
+#
+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
+# 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=m
+# CONFIG_USB_EZUSB is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP2101 is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+# CONFIG_USB_BERRY_CHARGE is not set
+CONFIG_USB_LED=m
+# 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
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+# 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=m
+# CONFIG_USB_GADGET_DEBUG is not set
+# 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=y
+CONFIG_USB_OMAP=m
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_PXA27X 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_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_USB_CDC_COMPOSITE=m
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_ISP1301_OMAP is not set
+CONFIG_TWL4030_USB=y
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+CONFIG_SDIO_UART=y
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_OMAP_HS=y
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_OMAP_DEBUG is not set
+# CONFIG_LEDS_OMAP is not set
+# CONFIG_LEDS_OMAP_PWM is not set
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_PCA955X is not set
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGERS 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_TWL4030=y
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 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
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# 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_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+
+#
+# CBUS support
+#
+# CONFIG_CBUS is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+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_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# 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=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_FS_POSIX_ACL=y
+CONFIG_JFFS2_FS_SECURITY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+# CONFIG_CRAMFS 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=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+CONFIG_RPCSEC_GSS_KRB5=y
+# 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# 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=y
+# 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 is not set
+# 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=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# 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 is not set
+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_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+# 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_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_XOR_BLOCKS=m
+CONFIG_ASYNC_CORE=m
+CONFIG_ASYNC_MEMCPY=m
+CONFIG_ASYNC_XOR=m
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_TEST=m
+
+#
+# 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=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+# 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=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
DESCRIPTION = "Linux kernel for OMAP processors"
KERNEL_IMAGETYPE = "uImage"
-COMPATIBLE_MACHINE = "omap5912osk|omap1710h3|omap2430sdp|omap2420h4|beagleboard|omap3evm|omap3-pandora"
+COMPATIBLE_MACHINE = "omap5912osk|omap1710h3|omap2430sdp|omap2420h4|beagleboard|omap3evm|omap3-pandora|overo"
DEFAULT_PREFERENCE = "-1"
DEFAULT_PREFERENCE_beagleboard = "1"
DESCRIPTION = "Linux kernel for OMAP processors"
KERNEL_IMAGETYPE = "uImage"
-COMPATIBLE_MACHINE = "omap5912osk|omap1710h3|omap2430sdp|omap2420h4|beagleboard|omap3evm|omap3-pandora"
+COMPATIBLE_MACHINE = "omap5912osk|omap1710h3|omap2430sdp|omap2420h4|beagleboard|omap3evm|omap3-pandora|overo"
DEFAULT_PREFERENCE = "-1"
DEFAULT_PREFERENCE_omap3evm = "1"
--- /dev/null
+From f94d3fbb605ad16d701525502fbad114a950197c Mon Sep 17 00:00:00 2001
+From: merge <null@invalid>
+Date: Mon, 19 Jan 2009 23:03:59 +0000
+Subject: [PATCH 1/8] MERGE-via-pending-tracking-hist-subject-usb-gadget-rndis-send-
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf-8
+Content-Transfer-Encoding: 8bit
+pending-tracking-hist top was subject-usb-gadget-rndis-send- / 3c29888770bfa8ce3a5e2ed590c3edb97ca4abaf ... parent commitmessage:
+From: Richard Röjfors <richard.rojfors@endian.se>
+Subject: USB: gadget rndis: send notifications
+
+X-Git-Tag: v2.6.28-rc6~2^2~2
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=ff3495052af48f7a2bf7961b131dc9e161dae19c;hp=9c264521a9f836541c122b00f505cfd60cc5bbb5
+
+USB: gadget rndis: send notifications
+
+It turns out that atomic_inc_return() returns the *new* value
+not the original one, so the logic in rndis_response_available()
+kept the first RNDIS response notification from getting out.
+This prevented interoperation with MS-Windows (but not Linux).
+
+Fix this to make RNDIS behave again.
+
+Signed-off-by: Richard Röjfors <richard.rojfors@endian.se>
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/usb/gadget/f_rndis.c | 3 +--
+ 1 files changed, 1 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
+index 659b3d9..428b599 100644
+--- a/drivers/usb/gadget/f_rndis.c
++++ b/drivers/usb/gadget/f_rndis.c
+@@ -172,7 +172,6 @@ static struct usb_interface_descriptor rndis_data_intf __initdata = {
+ .bDescriptorType = USB_DT_INTERFACE,
+
+ /* .bInterfaceNumber = DYNAMIC */
+- .bAlternateSetting = 1,
+ .bNumEndpoints = 2,
+ .bInterfaceClass = USB_CLASS_CDC_DATA,
+ .bInterfaceSubClass = 0,
+@@ -303,7 +302,7 @@ static void rndis_response_available(void *_rndis)
+ __le32 *data = req->buf;
+ int status;
+
+- if (atomic_inc_return(&rndis->notify_count))
++ if (atomic_inc_return(&rndis->notify_count) != 1)
+ return;
+
+ /* Send RNDIS RESPONSE_AVAILABLE notification; a
+--
+1.5.2.2
+
--- /dev/null
+From e4e155b8e3aeebb54b4295bce17ef5e85decd44d Mon Sep 17 00:00:00 2001
+From: merge <null@invalid>
+Date: Tue, 20 Jan 2009 10:40:16 +0000
+Subject: [PATCH 2/8] MERGE-via-pending-tracking-hist-subject-usb-gadget-fix-rndis-w
+pending-tracking-hist top was subject-usb-gadget-fix-rndis-w / 8a5ccc279cef316a16f921d7486f4a9efa234493 ... parent commitmessage:
+From: David Brownell <dbrownell@users.sourceforge.net>
+Subject: USB: gadget: fix rndis working at high speed
+
+X-Git-Tag: v2.6.28-rc9~8^2~7
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=7c12414955e9b44a3e33d54e578bf008caa4475d
+
+USB: gadget: fix rndis working at high speed
+
+Fix a bug specific to highspeed mode in the recently updated RNDIS
+support: it wasn't setting up the high speed notification endpoint,
+which prevented high speed RNDIS links from working.
+
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Tested-by: Anand Gadiyar <gadiyar@ti.com>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/usb/gadget/f_rndis.c | 4 ++++
+ 1 files changed, 4 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
+index 428b599..3a8bb53 100644
+--- a/drivers/usb/gadget/f_rndis.c
++++ b/drivers/usb/gadget/f_rndis.c
+@@ -651,6 +651,8 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
+ fs_in_desc.bEndpointAddress;
+ hs_out_desc.bEndpointAddress =
+ fs_out_desc.bEndpointAddress;
++ hs_notify_desc.bEndpointAddress =
++ fs_notify_desc.bEndpointAddress;
+
+ /* copy descriptors, and track endpoint copies */
+ f->hs_descriptors = usb_copy_descriptors(eth_hs_function);
+@@ -662,6 +664,8 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
+ f->hs_descriptors, &hs_in_desc);
+ rndis->hs.out = usb_find_endpoint(eth_hs_function,
+ f->hs_descriptors, &hs_out_desc);
++ rndis->hs.notify = usb_find_endpoint(eth_hs_function,
++ f->hs_descriptors, &hs_notify_desc);
+ }
+
+ rndis->port.open = rndis_open;
+--
+1.5.2.2
+
--- /dev/null
+From 72669a7c7637dba5f4f2ae4a8301cf9560f0a807 Mon Sep 17 00:00:00 2001
+From: Werner Almesberger <werner@openmoko.org>
+Date: Fri, 30 Jan 2009 08:07:27 +0000
+Subject: [PATCH 3/8] consider alrm->enable in pcf50633_rtc_set_alarm
+
+Backported to .28, original message below:
+
+Hi Balaji,
+
+Mickey mentioned to me that he had trouble with the RTC wakeup interrupt.
+I had a quick look at the problem and it seems that alrm->enable doesn't
+get propagated when setting the alarm time with RTC_WKALM_SET.
+
+Does something like my patch below look right ? We also don't handle
+alrm->pending, but I'm not sure if we have to.
+
+I tested this only very lightly since my current andy-tracking crashes
+in soc_suspend. If nobody else beats me to it, I'll have a look at it
+tomorrow.
+
+- Werner
+
+---------------------------------- cut here -----------------------------------
+
+According to Documentation/rtc.txt, RTC_WKALM_SET sets the alarm time
+and enables/disables the alarm. We implement RTC_WKALM_SET through
+pcf50633_rtc_set_alarm. The enabling/disabling part was missing.
+
+Signed-off-by: Werner Almesberger <werner@openmoko.org>
+Reported-by: Michael 'Mickey' Lauer <mickey@openmoko.org>
+---
+ drivers/rtc/rtc-pcf50633.c | 3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c
+index e1576d2..ddd6f89 100644
+--- a/drivers/rtc/rtc-pcf50633.c
++++ b/drivers/rtc/rtc-pcf50633.c
+@@ -221,8 +221,9 @@ static int pcf50633_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+ if (ret)
+ dev_err(dev, "Failed to write alarm time %d\n", ret);
+
+- if (!alarm_masked)
++ if (!alarm_masked || alrm->enabled)
+ pcf50633_irq_unmask(pcf, PCF50633_IRQ_ALARM);
++ pcf->rtc.alarm_enabled = alrm->enabled;
+
+ return 0;
+ }
+--
+1.5.2.2
+
--- /dev/null
+From 1fb682d2dfdaa19a50073fec6239f2bda9dbcc71 Mon Sep 17 00:00:00 2001
+From: Werner Almesberger <werner@openmoko.org>
+Date: Fri, 30 Jan 2009 14:37:40 +0000
+Subject: [PATCH 4/8] manage RTC alarm "pending" flag of PCF50633
+
+Backported to .28, original message below:
+
+This patch adds setting and clearing of the "pending" flag of the
+RTC alarm. The semantics follow the UEFI specification 2.2 available
+at http://www.uefi.org/specs/, i.e., the "pending" flag is cleared
+by disabling the alarm, but not by any other condition (such as the
+passing of time, a successful wakeup, or setting of a new alarm.)
+
+Signed-off-by: Werner Almesberger <werner@openmoko.org>
+---
+ drivers/rtc/rtc-pcf50633.c | 5 +++++
+ include/linux/mfd/pcf50633/rtc.h | 1 +
+ 2 files changed, 6 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c
+index ddd6f89..0fdadbd 100644
+--- a/drivers/rtc/rtc-pcf50633.c
++++ b/drivers/rtc/rtc-pcf50633.c
+@@ -185,6 +185,7 @@ static int pcf50633_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+ pcf = dev_get_drvdata(dev);
+
+ alrm->enabled = pcf->rtc.alarm_enabled;
++ alrm->pending = pcf->rtc.alarm_pending;
+
+ ret = pcf50633_read_block(pcf, PCF50633_REG_RTCSCA,
+ PCF50633_TI_EXTENT, &pcf_tm.time[0]);
+@@ -221,6 +222,9 @@ static int pcf50633_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+ if (ret)
+ dev_err(dev, "Failed to write alarm time %d\n", ret);
+
++ if (!alrm->enabled)
++ pcf->rtc.alarm_pending = 0;
++
+ if (!alarm_masked || alrm->enabled)
+ pcf50633_irq_unmask(pcf, PCF50633_IRQ_ALARM);
+ pcf->rtc.alarm_enabled = alrm->enabled;
+@@ -240,6 +244,7 @@ static void pcf50633_rtc_irq(struct pcf50633 *pcf, int irq, void *unused)
+ switch (irq) {
+ case PCF50633_IRQ_ALARM:
+ rtc_update_irq(pcf->rtc.rtc_dev, 1, RTC_AF | RTC_IRQF);
++ pcf->rtc.alarm_pending = 1;
+ break;
+ case PCF50633_IRQ_SECOND:
+ rtc_update_irq(pcf->rtc.rtc_dev, 1, RTC_PF | RTC_IRQF);
+diff --git a/include/linux/mfd/pcf50633/rtc.h b/include/linux/mfd/pcf50633/rtc.h
+index ce8ad8f..80cc6af 100644
+--- a/include/linux/mfd/pcf50633/rtc.h
++++ b/include/linux/mfd/pcf50633/rtc.h
+@@ -34,6 +34,7 @@
+ struct pcf50633_rtc {
+ int alarm_enabled;
+ int second_enabled;
++ int alarm_pending;
+
+ struct rtc_device *rtc_dev;
+ struct platform_device *pdev;
+--
+1.5.2.2
+
--- /dev/null
+From 8c787f1c57c3b09beece662faabfab419ae5c8d6 Mon Sep 17 00:00:00 2001
+From: Andy Green <andy@openmoko.com>
+Date: Wed, 28 Jan 2009 09:58:59 +0000
+Subject: [PATCH 5/8] debug-glamo-allow-slower-memory-bus.patch
+
+Signed-off-by: Andy Green <andy@openmoko.com>
+---
+ drivers/mfd/glamo/glamo-core.c | 34 +++++++++++++++++++++++++++++++++-
+ 1 files changed, 33 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c
+index b4595a8..e6253de 100644
+--- a/drivers/mfd/glamo/glamo-core.c
++++ b/drivers/mfd/glamo/glamo-core.c
+@@ -58,6 +58,25 @@
+
+ #define GLAMO_MEM_REFRESH_COUNT 0x100
+
++
++/*
++ * Glamo internal settings
++ *
++ * We run the memory interface from the faster PLLB on 2.6.28 kernels and
++ * above. Couple of GTA02 users report trouble with memory bus when they
++ * upgraded from 2.6.24. So this parameter allows reversion to 2.6.24
++ * scheme if their Glamo chip needs it.
++ *
++ * you can override the faster default on kernel commandline using
++ *
++ * glamo3362.slow_memory=1
++ *
++ * for example
++ */
++
++static int slow_memory = 0;
++module_param(slow_memory, int, 0644);
++
+ struct reg_range {
+ int start;
+ int count;
+@@ -786,6 +805,19 @@ int glamo_run_script(struct glamo_core *glamo, struct glamo_script *script,
+ while ((__reg_read(glamo, GLAMO_REG_PLL_GEN5) & 3) != 3)
+ ;
+ break;
++
++ /*
++ * couple of people reported artefacts with 2.6.28 changes, this
++ * allows reversion to 2.6.24 settings
++ */
++
++ case 0x200:
++ if (slow_memory)
++ __reg_write(glamo, script[i].reg, 0xef0);
++ else
++ __reg_write(glamo, script[i].reg, 0xe03);
++ break;
++
+ default:
+ __reg_write(glamo, script[i].reg, script[i].val);
+ break;
+@@ -848,7 +880,7 @@ static struct glamo_script glamo_init_script[] = {
+ * b7..b4 = 0 = no wait states on read or write
+ * b0 = 1 select PLL2 for Host interface, b1 = enable it
+ */
+- { 0x200, 0x0e03 },
++ { 0x200, 0x0e03 /* this is replaced by script parser */ },
+ { 0x202, 0x07ff },
+ { 0x212, 0x0000 },
+ { 0x214, 0x4000 },
+--
+1.5.2.2
+
--- /dev/null
+From d0bc6c5baae3a711f5039ea5440bafb37ebdfc24 Mon Sep 17 00:00:00 2001
+From: Balaji Rao <balajirrao@openmoko.org>
+Date: Wed, 28 Jan 2009 19:30:45 +0000
+Subject: [PATCH 6/8] Subject: fix_glamo_xrandr_bug.patch
+
+fix_glamo_xrandr_bug.patch
+
+This patch reintroduces the 2-cycle delay used when accessing glamo-fb
+registers. This seems to be required even when the corresponding
+registers in HOST_BUS are off.
+
+Signed-off-by: Balaji Rao <balajirrao@openmoko.org>
+---
+ drivers/mfd/glamo/glamo-fb.c | 10 ++++++++++
+ 1 files changed, 10 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/mfd/glamo/glamo-fb.c b/drivers/mfd/glamo/glamo-fb.c
+index 64fe464..91cf75b 100644
+--- a/drivers/mfd/glamo/glamo-fb.c
++++ b/drivers/mfd/glamo/glamo-fb.c
+@@ -86,12 +86,22 @@ static struct platform_device glamo_spi_dev = {
+ static int reg_read(struct glamofb_handle *glamo,
+ u_int16_t reg)
+ {
++ int i = 0;
++
++ for (i = 0; i != 2; i ++)
++ nop();
++
+ return readw(glamo->base + reg);
+ }
+
+ static void reg_write(struct glamofb_handle *glamo,
+ u_int16_t reg, u_int16_t val)
+ {
++ int i = 0;
++
++ for (i = 0; i != 2; i ++)
++ nop();
++
+ writew(val, glamo->base + reg);
+ }
+
+--
+1.5.2.2
+
--- /dev/null
+From 3192193f8a1a799783963aaf10119b39c3e8df24 Mon Sep 17 00:00:00 2001
+From: Balaji Rao <balajirrao@openmoko.org>
+Date: Thu, 29 Jan 2009 18:25:32 +0000
+Subject: [PATCH 7/8] Subject: glamo_fix_improper_xrandr_geometry_setting.patch
+
+glamo_fix_improper_xrandr_geometry_setting.patch
+
+Switching to xrandr -o 3 from xrandr -o 1 caused the screen to look crazy
+because of the way lcd geometry is set in glamo. This patch fixes it.
+
+Signed-off-by: Balaji Rao <balajirrao@openmoko.org>
+---
+ drivers/mfd/glamo/glamo-fb.c | 109 ++++++++++++++++++-----------------------
+ 1 files changed, 48 insertions(+), 61 deletions(-)
+
+diff --git a/drivers/mfd/glamo/glamo-fb.c b/drivers/mfd/glamo/glamo-fb.c
+index 91cf75b..16531fa 100644
+--- a/drivers/mfd/glamo/glamo-fb.c
++++ b/drivers/mfd/glamo/glamo-fb.c
+@@ -75,6 +75,7 @@ struct glamofb_handle {
+ int cursor_on;
+ u_int32_t pseudo_pal[16];
+ spinlock_t lock_cmd;
++ int angle; /* Current rotation angle */
+ };
+
+ /* 'sibling' spi device for lcm init */
+@@ -255,11 +256,6 @@ static void reg_set_bit_mask(struct glamofb_handle *glamo,
+ #define GLAMO_LCD_HV_RETR_DISP_START_MASK 0x03FF
+ #define GLAMO_LCD_HV_RETR_DISP_END_MASK 0x03FF
+
+-enum orientation {
+- ORIENTATION_PORTRAIT,
+- ORIENTATION_LANDSCAPE
+-};
+-
+
+ /* the caller has to enxure lock_cmd is held and we are in cmd mode */
+ static void __rotate_lcd(struct glamofb_handle *glamo, __u32 rotation)
+@@ -275,17 +271,22 @@ static void __rotate_lcd(struct glamofb_handle *glamo, __u32 rotation)
+ switch (rotation) {
+ case FB_ROTATE_UR:
+ glamo_rot = GLAMO_LCD_ROT_MODE_0;
++ glamo->angle = 0;
+ break;
+ case FB_ROTATE_CW:
+ glamo_rot = GLAMO_LCD_ROT_MODE_90;
++ glamo->angle = 90;
+ break;
+ case FB_ROTATE_UD:
+ glamo_rot = GLAMO_LCD_ROT_MODE_180;
++ glamo->angle = 180;
+ break;
+ case FB_ROTATE_CCW:
+ glamo_rot = GLAMO_LCD_ROT_MODE_270;
++ glamo->angle = 270;
+ break;
+ default:
++ glamo->angle = 0;
+ glamo_rot = GLAMO_LCD_ROT_MODE_0;
+ break;
+ }
+@@ -301,38 +302,12 @@ static void __rotate_lcd(struct glamofb_handle *glamo, __u32 rotation)
+ GLAMO_LCD_MODE1_ROTATE_EN : 0);
+ }
+
+-static enum orientation get_orientation(struct fb_var_screeninfo *var)
+-{
+- if (var->xres <= var->yres)
+- return ORIENTATION_PORTRAIT;
+-
+- return ORIENTATION_LANDSCAPE;
+-}
+-
+-static int will_orientation_change(struct fb_var_screeninfo *var)
+-{
+- enum orientation orient = get_orientation(var);
+-
+- switch (orient) {
+- case ORIENTATION_LANDSCAPE:
+- if (var->rotate == FB_ROTATE_UR ||
+- var->rotate == FB_ROTATE_UD)
+- return 1;
+- break;
+- case ORIENTATION_PORTRAIT:
+- if (var->rotate == FB_ROTATE_CW ||
+- var->rotate == FB_ROTATE_CCW)
+- return 1;
+- break;
+- }
+- return 0;
+-}
+-
+ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
+ struct fb_var_screeninfo *var)
+ {
+- int sync, bp, disp, fp, total, xres, yres, pitch, orientation_changing;
++ int sync, bp, disp, fp, total, pitch;
+ unsigned long flags;
++ int width, height;
+
+ if (!glamo || !var)
+ return;
+@@ -355,31 +330,52 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
+ GLAMO_ENGINE_LCD,
+ var->pixclock);
+
+- xres = var->xres;
+- yres = var->yres;
++ if (glamo->angle == 90 || glamo->angle == 270) {
++ /*
++ * But if we are going back to portrait mode from here,
++ * we get inverted values from Xglamo
++ */
++ if (!(var->rotate == FB_ROTATE_UR ||
++ var->rotate == FB_ROTATE_UD)) {
++ width = var->yres;
++ height = var->xres;
++ } else {
++ width = var->xres;
++ height = var->yres;
++ }
+
+- /* figure out if orientation is going to change */
+- orientation_changing = will_orientation_change(var);
++ } else {
++ width = var->xres;
++ height = var->yres;
++ }
+
+- /* adjust the pitch according to new orientation to come */
++ /* Portrait ? */
++ if (var->rotate == FB_ROTATE_UR || var->rotate == FB_ROTATE_UD) {
++ /* We don't need to set xres and yres in this particular case
++ * because Xglamo does it for us */
++ if (!(glamo->angle == 90 || glamo->angle == 270)) {
++ var->xres = width;var->yres = height;
++ }
+
+- if (orientation_changing) {
+- pitch = var->yres * var->bits_per_pixel / 8;
+- } else {
+- pitch = var->xres * var->bits_per_pixel / 8;
+- }
++ var->xres_virtual = width * 2;
++ var->yres_virtual = height;
++ pitch = width * var->bits_per_pixel / 8;
++ } else {
++ var->xres = height;
++ var->yres = width;
++ var->xres_virtual = height;
++ var->yres_virtual = width * 2;
++ pitch = height * var->bits_per_pixel / 8;
++ }
+
+- /*
+- * set the desired LCD geometry
+- */
+ reg_set_bit_mask(glamo,
+ GLAMO_REG_LCD_WIDTH,
+ GLAMO_LCD_WIDTH_MASK,
+- xres);
++ width);
+ reg_set_bit_mask(glamo,
+ GLAMO_REG_LCD_HEIGHT,
+ GLAMO_LCD_HEIGHT_MASK,
+- yres);
++ height);
+ reg_set_bit_mask(glamo,
+ GLAMO_REG_LCD_PITCH,
+ GLAMO_LCD_PITCH_MASK,
+@@ -388,22 +384,11 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
+ /* honour the rotation request */
+ __rotate_lcd(glamo, var->rotate);
+
+- /* update the reported geometry of the framebuffer. */
+- if (orientation_changing) {
+- var->xres_virtual = var->xres = yres;
+- var->xres_virtual *= 2;
+- var->yres_virtual = var->yres = xres;
+- } else {
+- var->xres_virtual = var->xres = xres;
+- var->yres_virtual = var->yres = yres;
+- var->yres_virtual *= 2;
+- }
+-
+ /* update scannout timings */
+ sync = 0;
+ bp = sync + var->hsync_len;
+ disp = bp + var->left_margin;
+- fp = disp + xres;
++ fp = disp + width;
+ total = fp + var->right_margin;
+
+ reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_TOTAL,
+@@ -420,7 +405,7 @@ static void glamofb_update_lcd_controller(struct glamofb_handle *glamo,
+ sync = 0;
+ bp = sync + var->vsync_len;
+ disp = bp + var->upper_margin;
+- fp = disp + yres;
++ fp = disp + height;
+ total = fp + var->lower_margin;
+
+ reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_TOTAL,
+@@ -836,6 +821,8 @@ static int __init glamofb_probe(struct platform_device *pdev)
+ glamofb->fb = fbinfo;
+ glamofb->dev = &pdev->dev;
+
++ glamofb->angle = 0;
++
+ strcpy(fbinfo->fix.id, "SMedia Glamo");
+
+ glamofb->reg = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+--
+1.5.2.2
+
--- /dev/null
+From 5e50f877f7ef2309a5318fc6ceed4903d1d80a64 Mon Sep 17 00:00:00 2001
+From: Nelson Castillo <arhuaco@freaks-unidos.net>
+Date: Thu, 29 Jan 2009 14:27:25 +0000
+Subject: [PATCH 8/8] Send pen-up events faster (side effect: improve illume keyboard responsiveness)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf-8
+Content-Transfer-Encoding: 8bit
+
+We were waiting 60ms before reporting a pen-up event to avoid
+jitter. Now we wait 8ms (actually 5 with HZ == 200).
+
+Thanks to Marco Trevisan for testing and pointing out that there was a
+problem that could be spotted with the illume keyboard.
+Note that I used the Terminal mode of the keyboard (no dictionary)
+for tests.
+
+I also used touch_test.py and the jitter doesn't seem to be an
+issue when drawing lines with the finger.
+
+Reported-by: Marco Trevisan (Treviño) <mail@3v1n0.net>
+Signed-off-by: Nelson Castillo <arhuaco@freaks-unidos.net>
+---
+ drivers/input/touchscreen/s3c2410_ts.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c
+index bc9b410..a37adc9 100644
+--- a/drivers/input/touchscreen/s3c2410_ts.c
++++ b/drivers/input/touchscreen/s3c2410_ts.c
+@@ -96,7 +96,7 @@ MODULE_LICENSE("GPL");
+
+ static char *s3c2410ts_name = "s3c2410 TouchScreen";
+
+-#define TS_RELEASE_TIMEOUT (HZ >> 4) /* ~ 60 milliseconds */
++#define TS_RELEASE_TIMEOUT (HZ >> 7 ? HZ >> 7 : 1) /* 8ms (5ms if HZ is 200) */
+ #define TS_EVENT_FIFO_SIZE (2 << 6) /* must be a power of 2 */
+
+ #define TS_STATE_STANDBY 0 /* initial state */
+--
+1.5.2.2
+
OEV = "oe1"
PV = "${KERNEL_RELEASE}-${OEV}+gitr${SRCREV}"
-PR = "r2"
+PR = "r3"
SRC_URI = "\
git://git.openmoko.org/git/kernel.git;protocol=git;branch=andy-tracking \
file://openwrt-ledtrig-netdev.patch;patch=1 \
+ file://0001-MERGE-via-pending-tracking-hist-subject-usb-gadget-r.patch;patch=1 \
+ file://0002-MERGE-via-pending-tracking-hist-subject-usb-gadget-f.patch;patch=1 \
+ file://0003-consider-alrm-enable-in-pcf50633_rtc_set_alarm.patch;patch=1 \
+ file://0004-manage-RTC-alarm-pending-flag-of-PCF50633.patch;patch=1 \
+ file://0005-debug-glamo-allow-slower-memory-bus.patch.patch;patch=1 \
+ file://0006-Subject-fix_glamo_xrandr_bug.patch.patch;patch=1 \
+ file://0007-Subject-glamo_fix_improper_xrandr_geometry_setting.patch;patch=1 \
+ file://0008-Send-pen-up-events-faster-side-effect-improve-illu.patch;patch=1 \
file://defconfig-oe.patch \
"
S = "${WORKDIR}/git"
OEV = "oe1"
PV = "${KERNEL_RELEASE}-${OEV}+gitr${SRCREV}"
-PR = "r2"
+PR = "r3"
SRC_URI = "\
git://git.openmoko.org/git/kernel.git;protocol=git;branch=andy-tracking \
S = "${WORKDIR}/git"
do_configure_prepend() {
- install -m 644 ./arch/arm/configs/gta02-packaging-defconfig ${WORKDIR}/defconfig-oe
+ install -m 644 ./arch/arm/configs/gta02_packaging_defconfig ${WORKDIR}/defconfig-oe
cat ${WORKDIR}/defconfig-oe.patch | patch -p0 -d ${WORKDIR}
}
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.24
-# Wed Jun 4 12:21:16 2008
+# Sun Feb 8 12:31:04 2009
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
# CONFIG_MACH_ARMCORE is not set
CONFIG_PXA_SHARPSL_25x=y
# CONFIG_PXA_SHARPSL_27x is not set
+# CONFIG_MACH_HTCUNIVERSAL is not set
# CONFIG_MACH_POODLE is not set
# CONFIG_MACH_CORGI is not set
# CONFIG_MACH_SHEPHERD is not set
# Wireless LAN
#
# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+CONFIG_WLAN_80211=y
+# CONFIG_PCMCIA_RAYCS is not set
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_USB=m
+CONFIG_LIBERTAS_CS=m
+CONFIG_LIBERTAS_SDIO=m
+# CONFIG_LIBERTAS_DEBUG is not set
+CONFIG_HERMES=m
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
+CONFIG_ATMEL=m
+CONFIG_PCMCIA_ATMEL=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_WL3501=m
+CONFIG_USB_ZD1201=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+# CONFIG_HOSTAP_FIRMWARE_NVRAM is not set
+CONFIG_HOSTAP_CS=m
#
# USB Network Adapters
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
-# CONFIG_SHARPSL_RC is not set
# CONFIG_KEYBOARD_ATKBD is not set
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_CORGI is not set
# CONFIG_KEYBOARD_SPITZ is not set
+# CONFIG_SHARPSL_RC is not set
CONFIG_KEYBOARD_TOSA=y
# CONFIG_KEYBOARD_TOSA_USE_EXT_KEYCODES is not set
CONFIG_KEYBOARD_GPIO=y
# CONFIG_MFD_TC6387XB is not set
CONFIG_MFD_TC6393XB=y
# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_ASIC3 is not set
+# CONFIG_HTC_ASIC3_DS1WM is not set
#
# Multimedia devices
module_autoload_leds-locomo_collie = "leds-locomo"
module_autoload_power_collie = "power"
-
-#package kernel cmdline
-PACKAGES_append += "kernel-cmdline"
-FILES_kernel-cmdline = "/boot/kernel-cmdline*"
-PKG_kernel-cmdline = "kernel-cmdline-${KERNEL_VERSION}"
-RRECOMMENDS_kernel-base += "kernel-cmdline"
-
-pkg_postinst_kernel-cmdline () {
- cd /boot; update-alternatives --install /boot/kernel-cmdline kernel-cmdline kernel-cmdline-${KERNEL_VERSION} ${KERNEL_PRIORITY} || true
-}
-
-pkg_postrm_kernel-cmdline () {
- cd /boot; update-alternatives --remove kernel-cmdline kernel-cmdline-${KERNEL_VERSION} || true
-}
-do_install_append () {
- echo "${CMDLINE_CON} ${CMDLINE_MEM} ${CMDLINE_ROTATE} ${CMDLINE_OTHER} ${CMDLINE_DEBUG}"> "${D}/boot/kernel-cmdline-${KERNEL_VERSION}"
-}
-
do_configure() {
rm -f ${S}/.config
yes '' | oe_runmake oldconfig
}
-#collie dosn't need to deploy kernel. The kernel is in the rootfs and
-# linux-kexecboot kernel is flashed
-do_deploy_collie() {
-}
# wlan-ng stuff need compiled kernel sources
do_rm_work() {
require linux-rp.inc
-PR = "r34"
+PR = "r35"
# Handy URLs
# git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git;protocol=git;tag=ef7d1b244fa6c94fb76d5f787b8629df64ea4046
require linux-rp.inc
-PR = "r20"
+PR = "r22"
DEFAULT_PREFERENCE = "-1"
DEFAULT_PREFERENCE_collie = "1"
require linux-rp.inc
-PR = "r5"
+PR = "r6"
DEFAULT_PREFERENCE = "-1"
DEFAULT_PREFERENCE_qemuarm = "1"
require linux-rp.inc
-PR = "r7"
+PR = "r8"
DEFAULT_PREFERENCE = "-1"
DEFAULT_PREFERENCE_qemuarm = "-1"
DEFAULT_PREFERENCE_atngw100 = "1"
DEFAULT_PREFERENCE_at32stk1000 = "1"
DEFAULT_PREFERENCE_ts72xx = "1"
-DEFAULT_PREFERENCE_oxe810 = "1"
+DEFAULT_PREFERENCE_oxnas = "1"
DEFAULT_PREFERENCE_cs-e9302 = "1"
-PR = "r18"
+PR = "r20"
SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-2.6.24.tar.bz2 \
http://kamikaze.waninkoko.info/patches/2.6.24/kamikaze1/broken-out/squashfs-lzma-2.6.24.patch;patch=1 \
file://ts72xx-use-cpld-reset.patch;patch=1 \
file://ts72xx-rs485.patch;patch=1"
-SRC_URI_append_oxe810 = " \
- file://oxe810.diff;patch=1 \
+SRC_URI_append_oxnas = " \
+ file://oxnas.diff;patch=1 \
+ file://oxnas-uart.patch;patch=1 \
"
CMDLINE_cm-x270 = "console=${CMX270_CONSOLE_SERIAL_PORT},38400 monitor=1 mem=64M mtdparts=physmap-flash.0:256k(boot)ro,0x180000(kernel),-(root);cm-x270-nand:64m(app),-(data) rdinit=/sbin/init root=mtd3 rootfstype=jffs2"
Exec=mumpot-cyclemap
Terminal=0
Type=Application
-Categories=Application;PIM;GTK
+Categories=X-PIM;GTK;Education;Science;Geography;
StartupNotify=True
Exec=mumpot-mapnik
Terminal=0
Type=Application
-Categories=Application;PIM;GTK
+Categories=X-PIM;GTK;Education;Science;Geography;
StartupNotify=True
Exec=mumpot-tah
Terminal=0
Type=Application
-Categories=Application;PIM;GTK
+Categories=X-PIM;GTK;Education;Science;Geography;
StartupNotify=True
+++ /dev/null
-DESCRIPTION = "A map-viewer, simple editor and routing application for OSM maps"
-HOMEPAGE = "http://wiki.openstreetmap.org/index.php/Mumpot"
-AUTHOR = "Andreas Kemnade"
-SECTION = "x11/applications"
-LICENSE = "GPLv2"
-DEPENDS = "gtk+ bluez-libs bzip2 libxml2 libpng jpeg"
-
-SRC_URI = "http://osm.andi.de1.cc/mumpot-${PV}.tar.gz \
- file://mumpot-tah.desktop \
- file://mumpot-mapnik.desktop"
-
-inherit autotools pkgconfig
-
-do_install_append() {
- install -d ${D}${datadir}/applications
- install -m 0644 ${WORKDIR}/mumpot-tah.desktop ${D}${datadir}/applications/mumpot-tah.desktop
- install -m 0644 ${WORKDIR}/mumpot-mapnik.desktop ${D}${datadir}/applications/mumpot-mapnik.desktop
-}
+++ /dev/null
-DESCRIPTION = "A map-viewer, simple editor and routing application for OSM maps"
-HOMEPAGE = "http://www.mumpot.org/"
-AUTHOR = "Andreas Kemnade"
-SECTION = "x11/applications"
-LICENSE = "GPLv3"
-DEPENDS = "gtk+ bluez-libs bzip2 libxml2 libpng jpeg"
-
-SRC_URI = "http://www.mumpot.org/download/mumpot-${PV}.tar.gz \
- file://mumpot-tah.desktop \
- file://mumpot-mapnik.desktop \
- file://mumpot-cyclemap.desktop"
-
-inherit autotools pkgconfig
-
-do_install_append() {
- install -d ${D}${datadir}/applications
- install -m 0644 ${WORKDIR}/mumpot-tah.desktop ${D}${datadir}/applications/mumpot-tah.desktop
- install -m 0644 ${WORKDIR}/mumpot-mapnik.desktop ${D}${datadir}/applications/mumpot-mapnik.desktop
- install -m 0644 ${WORKDIR}/mumpot-cyclemap.desktop ${D}${datadir}/applications/mumpot-cyclemap.desktop
-}
--- /dev/null
+DESCRIPTION = "A map-viewer, simple editor and routing application for OSM maps"
+HOMEPAGE = "http://www.mumpot.org/"
+AUTHOR = "Andreas Kemnade"
+SECTION = "x11/applications"
+LICENSE = "GPLv3"
+DEPENDS = "gtk+ bluez-libs bzip2 libxml2 libpng jpeg"
+
+SRC_URI = "http://www.mumpot.org/download/mumpot-${PV}.tar.gz \
+ file://mumpot-tah.desktop \
+ file://mumpot-mapnik.desktop \
+ file://mumpot-cyclemap.desktop"
+
+inherit autotools pkgconfig
+
+do_install_append() {
+ install -d ${D}${datadir}/applications
+ install -m 0644 ${WORKDIR}/mumpot-tah.desktop ${D}${datadir}/applications/mumpot-tah.desktop
+ install -m 0644 ${WORKDIR}/mumpot-mapnik.desktop ${D}${datadir}/applications/mumpot-mapnik.desktop
+ install -m 0644 ${WORKDIR}/mumpot-cyclemap.desktop ${D}${datadir}/applications/mumpot-cyclemap.desktop
+}
# Ethernet/RNDIS gadget (g_ether)
# ... or on host side, usbnet and random hwaddr
-auto usb0
+allow-hotplug usb0
iface usb0 inet static
address 192.168.0.202
netmask 255.255.255.0
# Ethernet/RNDIS gadget (g_ether)
# ... or on host side, usbnet and random hwaddr
-auto usb0
+allow-hotplug usb0
iface usb0 inet static
address 192.168.0.202
netmask 255.255.255.0
infrastructure for basic TCP/IP based networking."
SECTION = "base"
LICENSE = "GPL"
-PR = "r30"
+PR = "r31"
inherit update-rc.d
Name=numptyphysics
Comment=Physics Game
Note=Simulate Objects
-Exec=xrandr -o 3 && numptyphysics -geometry 640x480; xrandr -o 0
+Exec=numptyphysics
Icon=star.png
Type=Application
Categories=Games
HOMEPAGE = "http://numptyphysics.garage.maemo.org/"
SECTION = "x11/games"
PV = "0.2+svnr${SRCREV}"
+PR = "r1"
inherit autotools
--- /dev/null
+Index: RenderSystems/GLES/include/OgreGLESSupport.h
+===================================================================
+--- RenderSystems/GLES/include/OgreGLESSupport.h (revision 8310)
++++ RenderSystems/GLES/include/OgreGLESSupport.h (working copy)
+@@ -80,6 +80,11 @@
+ virtual void initialiseExtensions();
+ virtual bool checkExtension(const String& ext) const;
+
++ virtual unsigned int getDisplayMonitorCount() const
++ {
++ return 1;
++ }
++
+ virtual void start() = 0;
+ virtual void stop() = 0;
+
+Index: RenderSystems/GLES/include/OgreGLESRenderSystem.h
+===================================================================
+--- RenderSystems/GLES/include/OgreGLESRenderSystem.h (revision 8310)
++++ RenderSystems/GLES/include/OgreGLESRenderSystem.h (working copy)
+@@ -139,9 +139,11 @@
+ void _setTextureBorderColour(size_t stage, const ColourValue& colour);
+ void _setTextureMipmapBias(size_t unit, float bias);
+ void _setTextureMatrix(size_t stage, const Matrix4& xform);
+- void _setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor);
+- void _setSeparateSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha);
+- void _setAlphaRejectSettings(CompareFunction func, unsigned char value);
++ void _setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op );
++ void _setSeparateSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha, SceneBlendOperation op, SceneBlendOperation alphaOp );
++ void _setSceneBlendingOperation(SceneBlendOperation op);
++ void _setSeparateSceneBlendingOperation(SceneBlendOperation op, SceneBlendOperation alphaOp);
++ void _setAlphaRejectSettings(CompareFunction func, unsigned char value, bool alphaToCoverage);
+ void _setViewport(Viewport *vp);
+ void _beginFrame(void);
+ void _endFrame(void);
+@@ -195,6 +197,7 @@
+
+ GLESContext* _getMainContext() { return mMainContext; }
+ void _unregisterContext(GLESContext *context);
++ unsigned int getDisplayMonitorCount() const;
+ void _switchContext(GLESContext *context);
+ void _oneTimeContextInitialization();
+ void initialiseContext(RenderWindow* primary);
+Index: RenderSystems/GLES/include/OgreGLESDefaultHardwareBufferManager.h
+===================================================================
+--- RenderSystems/GLES/include/OgreGLESDefaultHardwareBufferManager.h (revision 8310)
++++ RenderSystems/GLES/include/OgreGLESDefaultHardwareBufferManager.h (working copy)
+@@ -110,6 +110,8 @@
+ HardwareIndexBufferSharedPtr
+ createIndexBuffer(HardwareIndexBuffer::IndexType itype, size_t numIndexes,
+ HardwareBuffer::Usage usage, bool useShadowBuffer = false);
++ // Create a render to vertex buffer
++ RenderToVertexBufferSharedPtr createRenderToVertexBuffer();
+ };
+ }
+
+Index: RenderSystems/GLES/src/OgreGLESRenderSystem.cpp
+===================================================================
+--- RenderSystems/GLES/src/OgreGLESRenderSystem.cpp (revision 8310)
++++ RenderSystems/GLES/src/OgreGLESRenderSystem.cpp (working copy)
+@@ -1182,7 +1182,8 @@
+ return GL_ONE;
+ }
+
+- void GLESRenderSystem::_setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor)
++
++ void GLESRenderSystem::_setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op )
+ {
+ GLint sourceBlend = getBlendMode(sourceFactor);
+ GLint destBlend = getBlendMode(destFactor);
+@@ -1199,17 +1200,19 @@
+ GL_CHECK_ERROR;
+ }
+ }
+-
+- void GLESRenderSystem::_setSeparateSceneBlending(SceneBlendFactor sourceFactor,
+- SceneBlendFactor destFactor,
+- SceneBlendFactor sourceFactorAlpha,
+- SceneBlendFactor destFactorAlpha)
++
++ void GLESRenderSystem::_setSeparateSceneBlending(
++ SceneBlendFactor sourceFactor, SceneBlendFactor destFactor,
++ SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha,
++ SceneBlendOperation op, SceneBlendOperation alphaOp )
+ {
+ // Not supported
+ }
+
+- void GLESRenderSystem::_setAlphaRejectSettings(CompareFunction func, unsigned char value)
++ void GLESRenderSystem::_setAlphaRejectSettings(CompareFunction func, unsigned char value, bool alphaToCoverage)
+ {
++ bool a2c = false;
++ static bool lasta2c = false;
+ if (func == CMPF_ALWAYS_PASS)
+ {
+ glDisable(GL_ALPHA_TEST);
+@@ -1222,6 +1225,15 @@
+ glAlphaFunc(convertCompareFunction(func), value / 255.0f);
+ GL_CHECK_ERROR;
+ }
++ if (a2c != lasta2c && getCapabilities()->hasCapability(RSC_ALPHA_TO_COVERAGE))
++ {
++ if (a2c)
++ glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
++ else
++ glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
++
++ lasta2c = a2c;
++ }
+ }
+
+ void GLESRenderSystem::_setViewport(Viewport *vp)
+@@ -2084,7 +2096,12 @@
+ {
+ // Not implemented
+ }
+-
++
++ unsigned int GLESRenderSystem::getDisplayMonitorCount() const
++ {
++ return mGLSupport->getDisplayMonitorCount();
++ }
++
+ void GLESRenderSystem::setClipPlanesImpl(const Ogre::PlaneList& clipPlanes)
+ {
+ // A note on GL user clipping:
+Index: RenderSystems/GLES/src/OgreGLESDefaultHardwareBufferManager.cpp
+===================================================================
+--- RenderSystems/GLES/src/OgreGLESDefaultHardwareBufferManager.cpp (revision 8310)
++++ RenderSystems/GLES/src/OgreGLESDefaultHardwareBufferManager.cpp (working copy)
+@@ -164,4 +164,12 @@
+ return HardwareIndexBufferSharedPtr(
+ new GLESDefaultHardwareIndexBuffer(itype, numIndexes, usage));
+ }
++
++ RenderToVertexBufferSharedPtr
++ GLESDefaultHardwareBufferManager::createRenderToVertexBuffer()
++ {
++ OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
++ "Cannot create RenderToVertexBuffer in GLESDefaultHardwareBufferManager",
++ "GLESDefaultHardwareBufferManager::createRenderToVertexBuffer");
++ }
+ }
+Index: RenderSystems/GLES/src/EGL/OgreEGLWindow.cpp
+===================================================================
+--- RenderSystems/GLES/src/EGL/OgreEGLWindow.cpp (revision 8310)
++++ RenderSystems/GLES/src/EGL/OgreEGLWindow.cpp (working copy)
+@@ -182,7 +182,7 @@
+
+ if ((opt = miscParams->find("parentWindowHandle")) != end)
+ {
+- std::vector<String> tokens = StringUtil::split(opt->second, " :");
++ StringVector tokens = StringUtil::split(opt->second, " :");
+
+ if (tokens.size() == 3)
+ {
+@@ -197,7 +197,7 @@
+ }
+ else if ((opt = miscParams->find("externalWindowHandle")) != end)
+ {
+- std::vector<String> tokens = StringUtil::split(opt->second, " :");
++ StringVector tokens = StringUtil::split(opt->second, " :");
+
+ LogManager::getSingleton().logMessage(
+ "EGLWindow::create: The externalWindowHandle parameter is deprecated.\n"
--- /dev/null
+LICENSE = "MIT"
+
+SRC_URI = "${SOURCEFORGE_MIRROR}/freeimage/FreeImage3110.zip"
+
+S = "${WORKDIR}/FreeImage/"
+
+do_configure() {
+ sed -i -e /^CC/d \
+ -e /^CXX\ /d \
+ -e /^AR/d \
+ -e /^INCDIR\ /d \
+ -e /^INSTALLDIR\ /d \
+ -e s:'-o root -g root'::g \
+ -e /ldconfig/d \
+ ${S}/Makefile.gnu
+}
+
+do_install() {
+ install -d ${D}${libdir}
+ install -d ${D}${includedir}
+ oe_runmake INSTALLDIR="${D}${libdir}" INCDIR="${D}${includedir}" install
+}
+
+do_stage() {
+ install -d ${STAGING_LIBDIR}
+ install -d ${STAGING_INCDIR}
+ oe_runmake INSTALLDIR="${STAGING_LIBDIR}" INCDIR="${STAGING_INCDIR}" install
+}
+
--- /dev/null
+DESCRIPTION = "OGRE (Object-Oriented Graphics Rendering Engine) is a scene-oriented, flexible 3D engine "
+LICENSE = "LGPL"
+DEPENDS = "zziplib boost freeimage freetype virtual/libx11 virtual/egl"
+
+SRCREV = "8310"
+PV = "1.6.1+svnr${SRCREV}"
+
+SRC_URI = "svn://ogre.svn.sourceforge.net/svnroot/ogre;module=trunk;proto=https \
+ file://ogre-egl-update.diff;patch=1;pnum=0 \
+ "
+
+inherit autotools_stage
+
+# This is the EGL version
+EXTRA_OECONF = " --with-allocator=std --enable-threading=no --disable-cg --enable-gles "
+
+S = "${WORKDIR}/trunk"
+
+
+EXTRA_OEMAKE = " ZZIPLIB_CFLAGS=\"${@base_conditional('SITEINFO_ENDIANESS', 'le', '-DOGRE_CONFIG_LITTLE_ENDIAN', '-DOGRE_CONFIG_BIG_ENDIAN', d)}\" "
+
+do_configure_prepend() {
+ sed -i -e /OGRE_DETECT_ENDIAN/d ${S}/configure.in
+}
+
+FILES_${PN}-dbg += "${libdir}/OGRE/.debug"
+FILES_${PN}-dev += "${libdir}/OGRE/*.la"
+FILES_${PN} += "${libdir}/OGRE/*.so"
+
--- /dev/null
+diff -urN pciutils-3.1.2.orig/lib/configure pciutils-3.1.2.new/lib/configure
+--- pciutils-3.1.2.orig/lib/configure 2009-01-30 14:06:25.000000000 +0100
++++ pciutils-3.1.2.new/lib/configure 2009-02-04 18:45:31.000000000 +0100
+@@ -14,11 +14,6 @@
+ fi
+ }
+
+-if [ -z "$VERSION" -o -z "$IDSDIR" ] ; then
+- echo >&2 "Please run the configure script from the top-level Makefile"
+- exit 1
+-fi
+-
+ echo_n "Configuring libpci for your system..."
+ if [ -z "$HOST" ] ; then
+ sys=`uname -s`
+@@ -44,8 +39,8 @@
+ [ -n "$RELEASE" ] && rel="${RELEASE}"
+ # CAVEAT: tr on Solaris is a bit weird and the extra [] is otherwise harmless.
+ host=`echo $HOST | sed -e 's/^\([^-]*\)-\([^-]*\)-\([^-]*\)-\([^-]*\)$/\1-\3/' -e 's/^\([^-]*\)-\([^-]*\)$/\1--\2/' | tr '[A-Z]' '[a-z]'`
+-cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+-sys=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
++sys=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
++cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+ echo " $host $rel $cpu $sys"
+
+ c=config.h
+diff -urN pciutils-3.1.2.orig/Makefile pciutils-3.1.2.new/Makefile
+--- pciutils-3.1.2.orig/Makefile 2009-02-01 17:49:22.000000000 +0100
++++ pciutils-3.1.2.new/Makefile 2009-02-04 13:32:50.000000000 +0100
+@@ -52,7 +52,8 @@
+
+ export
+
+-all: lib/$(PCILIB) lspci setpci example lspci.8 setpci.8 pcilib.7 update-pciids update-pciids.8 $(PCI_IDS)
++all: lib/$(PCILIB) lspci setpci example lspci.8 setpci.8 pcilib.7 update-pciids update-pciids.8 $(PCI_IDS) \
++ pcimodules pcimodules.8
+
+ lib/$(PCILIB): $(PCIINC) force
+ $(MAKE) -C lib all
+@@ -62,9 +63,11 @@
+ lib/config.h lib/config.mk:
+ cd lib && ./configure
+
++pcimodules: pcimodules.o common.o lib/$(PCILIB)
+ lspci: lspci.o ls-vpd.o ls-caps.o ls-ecaps.o ls-kernel.o ls-tree.o ls-map.o common.o lib/$(PCILIB)
+ setpci: setpci.o common.o lib/$(PCILIB)
+
++pcimodules.o: pcimodules.c pciutils.h
+ LSPCIINC=lspci.h pciutils.h $(PCIINC)
+ lspci.o: lspci.c $(LSPCIINC)
+ ls-vpd.o: ls-vpd.c $(LSPCIINC)
+@@ -101,10 +104,10 @@
+ install: all
+ # -c is ignored on Linux, but required on FreeBSD
+ $(DIRINSTALL) -m 755 $(DESTDIR)$(SBINDIR) $(DESTDIR)$(IDSDIR) $(DESTDIR)$(MANDIR)/man8 $(DESTDIR)$(MANDIR)/man7
+- $(INSTALL) -c -m 755 $(STRIP) lspci setpci $(DESTDIR)$(SBINDIR)
++ $(INSTALL) -c -m 755 $(STRIP) lspci setpci pcimodules $(DESTDIR)$(SBINDIR)
+ $(INSTALL) -c -m 755 update-pciids $(DESTDIR)$(SBINDIR)
+ $(INSTALL) -c -m 644 $(PCI_IDS) $(DESTDIR)$(IDSDIR)
+- $(INSTALL) -c -m 644 lspci.8 setpci.8 update-pciids.8 $(DESTDIR)$(MANDIR)/man8
++ $(INSTALL) -c -m 644 lspci.8 setpci.8 update-pciids.8 pcimodules.8 $(DESTDIR)$(MANDIR)/man8
+ $(INSTALL) -c -m 644 pcilib.7 $(DESTDIR)$(MANDIR)/man7
+ ifeq ($(SHARED),yes)
+ $(DIRINSTALL) -m 755 $(DESTDIR)$(LIBDIR)
+@@ -122,9 +125,10 @@
+ endif
+
+ uninstall: all
+- rm -f $(DESTDIR)$(SBINDIR)/lspci $(DESTDIR)$(SBINDIR)/setpci $(DESTDIR)$(SBINDIR)/update-pciids
++ rm -f $(DESTDIR)$(SBINDIR)/lspci $(DESTDIR)$(SBINDIR)/setpci $(DESTDIR)$(SBINDIR)/update-pciids $(DESTDIR)$(SBINDIR)/pcimodules
++
+ rm -f $(DESTDIR)$(IDSDIR)/$(PCI_IDS)
+- rm -f $(DESTDIR)$(MANDIR)/man8/lspci.8 $(DESTDIR)$(MANDIR)/man8/setpci.8 $(DESTDIR)$(MANDIR)/man8/update-pciids.8
++ rm -f $(DESTDIR)$(MANDIR)/man8/lspci.8 $(DESTDIR)$(MANDIR)/man8/setpci.8 $(DESTDIR)$(MANDIR)/man8/update-pciids.8 $(DESTDIR)$(MANDIR)/man8/pcimodules.8
+ rm -f $(DESTDIR)$(MANDIR)/man7/pcilib.7
+ ifeq ($(SHARED),yes)
+ rm -f $(DESTDIR)$(LIBDIR)/$(PCILIB) $(DESTDIR)$(LIBDIR)/$(LIBNAME).so$(ABI_VERSION)
+diff -urN pciutils-3.1.2.orig/pcimodules.c pciutils-3.1.2.new/pcimodules.c
+--- pciutils-3.1.2.orig/pcimodules.c 1970-01-01 01:00:00.000000000 +0100
++++ pciutils-3.1.2.new/pcimodules.c 2009-02-04 12:19:47.000000000 +0100
+@@ -0,0 +1,185 @@
++/*
++ * pcimodules: Load all kernel modules for PCI device currently
++ * plugged into any PCI slot.
++ *
++ * Copyright 2000 Yggdrasil Computing, Incorporated
++ * This file may be copied under the terms and conditions of version
++ * two of the GNU General Public License, as published by the Free
++ * Software Foundation (Cambridge, Massachusetts, USA).
++ *
++ * This file is based on pciutils/lib/example.c, which has the following
++ * authorship and copyright statement:
++ *
++ * Written by Martin Mares and put to public domain. You can do
++ * with it anything you want, but I don't give you any warranty.
++ */
++
++#include <stdlib.h>
++#include <stdio.h>
++#include <malloc.h>
++#include <string.h>
++#include <unistd.h>
++#include <sys/utsname.h>
++#include <sys/param.h>
++#include <sys/types.h>
++
++#define _GNU_SOURCE
++#include <getopt.h>
++
++#include "pciutils.h"
++
++#define MODDIR "/lib/modules"
++#define PCIMAP "modules.pcimap"
++
++#define LINELENGTH 8000
++
++#define DEVICE_ANY 0xffffffff
++#define VENDOR_ANY 0xffffffff
++
++#include "lib/pci.h"
++
++ const char program_name[] = "lspci";
++
++struct pcimap_entry {
++ unsigned int vendor, subsys_vendor, dev, subsys_dev, class, class_mask;
++ char *module;
++ struct pcimap_entry *next;
++};
++
++static struct pcimap_entry *pcimap_list = NULL;
++
++#define OPT_STRING "h"
++static struct option long_options[] = {
++ {"class", required_argument, NULL, 'c'},
++ {"classmask", required_argument, NULL, 'm'},
++ {"help", no_argument, NULL, 'h'},
++ { 0, 0, 0, 0}
++};
++
++static unsigned long desired_class;
++static unsigned long desired_classmask; /* Default is 0: accept all classes.*/
++
++void
++read_pcimap(void)
++{
++ struct utsname utsname;
++ char filename[MAXPATHLEN];
++ FILE *pcimap_file;
++ char line[LINELENGTH];
++ struct pcimap_entry *entry;
++ unsigned int driver_data;
++ char *prevmodule = "";
++ char module[LINELENGTH];
++
++ if (uname(&utsname) < 0) {
++ perror("uname");
++ exit(1);
++ }
++ sprintf(filename, "%s/%s/%s", MODDIR, utsname.release, PCIMAP);
++ if ((pcimap_file = fopen(filename, "r")) == NULL) {
++ perror(filename);
++ exit(1);
++ }
++
++ while(fgets(line, LINELENGTH, pcimap_file) != NULL) {
++ if (line[0] == '#')
++ continue;
++
++ entry = xmalloc(sizeof(struct pcimap_entry));
++
++ if (sscanf(line, "%s 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
++ module,
++ &entry->vendor, &entry->dev,
++ &entry->subsys_vendor, &entry->subsys_dev,
++ &entry->class, &entry->class_mask,
++ &driver_data) != 8) {
++ fprintf (stderr,
++ "modules.pcimap unparsable line: %s.\n", line);
++ free(entry);
++ continue;
++ }
++
++ /* Optimize memory allocation a bit, in case someday we
++ have Linux systems with ~100,000 modules. It also
++ allows us to just compare pointers to avoid trying
++ to load a module twice. */
++ if (strcmp(module, prevmodule) != 0) {
++ prevmodule = xmalloc(strlen(module)+1);
++ strcpy(prevmodule, module);
++ }
++ entry->module = prevmodule;
++ entry->next = pcimap_list;
++ pcimap_list = entry;
++ }
++ fclose(pcimap_file);
++}
++
++/* Return a filled in pci_access->dev tree, with the device classes
++ stored in dev->aux.
++*/
++static void
++match_pci_modules(void)
++{
++ struct pci_access *pacc;
++ struct pci_dev *dev;
++ unsigned int class, subsys_dev, subsys_vendor;
++ struct pcimap_entry *map;
++ const char *prevmodule = "";
++
++ pacc = pci_alloc(); /* Get the pci_access structure */
++ /* Set all options you want -- here we stick with the defaults */
++ pci_init(pacc); /* Initialize the PCI library */
++ pci_scan_bus(pacc); /* We want to get the list of devices */
++ for(dev=pacc->devices; dev; dev=dev->next) {
++ pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES);
++ class = (pci_read_word(dev, PCI_CLASS_DEVICE) << 8)
++ | pci_read_byte(dev, PCI_CLASS_PROG);
++ subsys_dev = pci_read_word(dev, PCI_SUBSYSTEM_ID);
++ subsys_vendor = pci_read_word(dev,PCI_SUBSYSTEM_VENDOR_ID);
++ for(map = pcimap_list; map != NULL; map = map->next) {
++ if (((map->class ^ class) & map->class_mask) == 0 &&
++ ((desired_class ^ class) & desired_classmask)==0 &&
++ (map->dev == DEVICE_ANY ||
++ map->dev == dev->device_id) &&
++ (map->vendor == VENDOR_ANY ||
++ map->vendor == dev->vendor_id) &&
++ (map->subsys_dev == DEVICE_ANY ||
++ map->subsys_dev == subsys_dev) &&
++ (map->subsys_vendor == VENDOR_ANY ||
++ map->subsys_vendor == subsys_vendor) &&
++ prevmodule != map->module) {
++ printf("%s\n", map->module);
++ prevmodule = map->module;
++ }
++ }
++
++ }
++ pci_cleanup(pacc);
++}
++
++int
++main (int argc, char **argv)
++{
++ int opt_index = 0;
++ int opt;
++
++ while ((opt = getopt_long(argc, argv, OPT_STRING, long_options,
++ &opt_index)) != -1) {
++ switch(opt) {
++ case 'c':
++ desired_class = strtol(optarg, NULL, 0);
++ break;
++ case 'm':
++ desired_classmask = strtol(optarg, NULL, 0);
++ break;
++ case 'h':
++ printf ("Usage: pcimodules [--help]\n"
++ " Lists kernel modules corresponding to PCI devices currently plugged"
++ " into the computer.\n");
++ }
++ }
++
++ read_pcimap();
++ match_pci_modules();
++ return 0;
++}
+diff -urN pciutils-3.1.2.orig/pcimodules.man pciutils-3.1.2.new/pcimodules.man
+--- pciutils-3.1.2.orig/pcimodules.man 1970-01-01 01:00:00.000000000 +0100
++++ pciutils-3.1.2.new/pcimodules.man 2009-02-04 12:19:53.000000000 +0100
+@@ -0,0 +1,92 @@
++.TH pcimodules 8 "@TODAY@" "@VERSION@" "Linux PCI Utilities"
++.IX pcimodules
++.SH NAME
++pcimodules \- List kernel driver modules available for all currently plugged
++in PCI devices
++.SH SYNOPSIS
++.B pcimodules
++.RB [ --class class_id ]
++.RB [ --classmask mask ]
++.RB [ --help ]
++.SH DESCRIPTION
++.B pcimodules
++lists all driver modules for all currently plugged in PCI devices.
++.B pcimodules
++should be run at boot time, and whenever a PCI device is "hot plugged"
++into the system. This can be done by the following Bourne shell syntax:
++.IP
++ for module in $(pcimodules) ; do
++.IP
++ modprobe -s -k "$module"
++.IP
++ done
++.PP
++When a PCI device is removed from the system, the Linux kernel will
++decrement a usage count on PCI driver module. If this count drops
++to zero (i.e., there are no PCI drivers), then the
++.B modprobe -r
++process that is normally configured to run from cron every few minutes
++will eventually remove the unneeded module.
++.PP
++The --class and --classmask arguments can be used to limit the search
++to certain classes of PCI devices. This is useful, for example, to
++generate a list of ethernet card drivers to be loaded when the kernel
++has indicated that it is trying to resolve an unknown network interface.
++.PP
++Modules are listed in the order in which the PCI devices are physically
++arranged so that the computer owner can arrange things like having scsi
++device 0 be on a controller that is not alphabetically the first scsi
++controller.
++.SH OPTIONS
++.TP
++.B --class class --classmask mask
++.PP
++--class and --classmask limit the search to PCI
++cards in particular classes. These arguments are always used together.
++The arguments to --class and --classmask
++can be given as hexadecimal numbers by prefixing a leading "0x".
++Note that the classes used by pcimodules are in "Linux" format,
++meaning the class value that you see with lspci would be shifted
++left eight bits, with the new low eight bits programming interface ID.
++An examples of how to use class and classmask is provided below.
++.B --help, -h
++Print a help message and exit.
++.SH EXAMPLES
++.TP
++pcimodules
++lists all modules corresponding to currently plugged in PCI devices.
++.TP
++pcimodules --class 0x200000 --classmask 0xffff00
++lists all modules corresponding to currently plugged in ethernet PCI devices.
++.SH FILES
++.TP
++.B /lib/modules/<kernel-version>/modules.pcimap
++This file is automatically generated by
++.B depmod,
++and used by
++.B pcimodules
++to determine which modules correspond to which PCI ID's.
++.TP
++.B /proc/bus/pci
++An interface to PCI bus configuration space provided by the post-2.1.82 Linux
++kernels. Contains per-bus subdirectories with per-card config space files and a
++.I devices
++file containing a list of all PCI devices.
++
++.SH SEE ALSO
++.BR lspci (8)
++
++.SH MAINTAINER
++The Linux PCI Utilities are maintained by Martin Mares <mj@suse.cz>.
++
++.SH AUTHOR
++.B pcimodules
++was written by Adam J. Richter <adam@yggdrasil.com>, based on public
++domain example code by Martin Mares <mj@suse.cz>.
++
++.SH COPYRIGHT
++.B pcimodules
++is copyright 2000, Yggdrasil Computing, Incorporated, and may
++be copied under the terms and conditions of version 2 of the GNU
++General Public License as published by the Free Software Foundation
++(Cambrige, Massachusetts, United States of America).
--- /dev/null
+DESCRIPTION = 'The PCI Utilities package contains a library for portable access \
+to PCI bus configuration space and several utilities based on this library.'
+DESCRIPTION_pciutils-ids = 'The list of PCI IDs for pciutils'
+SECTION = "console/utils"
+HOMEPAGE = "http://atrey.karlin.mff.cuni.cz/~mj/pciutils.shtml"
+LICENSE = "GPLv2"
+DEPENDS = "zlib"
+
+SRC_URI = "ftp://ftp.kernel.org/pub/software/utils/pciutils/pciutils-${PV}.tar.bz2 \
+ file://pciutils.patch;patch=1 "
+
+PARALLEL_MAKE = ""
+
+PR ="r2"
+
+EXTRA_OEMAKE += "'STRIP = '"
+export SHARED=yes
+
+do_configure () {
+ (cd lib && ./configure ${datadir} ${PV} ${TARGET_OS} 2.4.21 ${TARGET_ARCH})
+}
+
+export PREFIX = "${D}${prefix}"
+export SBINDIR = "${D}${sbindir}"
+export SHAREDIR = "${D}${datadir}"
+export MANDIR = "${D}${mandir}"
+
+do_install () {
+ oe_runmake install
+}
+
+do_install_append () {
+ install -d ${D}/${prefix}/share
+ install -m 6440 ${WORKDIR}/${PN}-${PV}/pci.ids ${D}/${prefix}/share
+
+ # The makefile does not install the development files:
+ # libpci.so pci.h header.h config.h types.h
+ install -d ${D}/${libdir}
+ install -d ${D}/${includedir}/pci
+
+ oe_libinstall -so -C lib libpci ${D}/${libdir}
+ install -m 0644 ${S}/lib/pci.h ${D}/${includedir}/pci/
+ install -m 0644 ${S}/lib/header.h ${D}/${includedir}/pci/
+ install -m 0644 ${S}/lib/config.h ${D}/${includedir}/pci/
+ install -m 0644 ${S}/lib/types.h ${D}/${includedir}/pci/
+}
+
+do_stage () {
+ oe_libinstall -so -C lib libpci ${STAGING_LIBDIR}
+ install -m 0755 -d ${STAGING_INCDIR}/pci
+ install -m 0644 ${S}/lib/pci.h ${STAGING_INCDIR}/pci/
+ install -m 0644 ${S}/lib/header.h ${STAGING_INCDIR}/pci/
+ install -m 0644 ${S}/lib/config.h ${STAGING_INCDIR}/pci/
+ install -m 0644 ${S}/lib/types.h ${STAGING_INCDIR}/pci/
+}
+
+
+PACKAGES =+ "pciutils-ids"
+FILES_pciutils-ids="${prefix}/share/pci.ids"
DESCRIPTION = "libGLES for the omap3"
LICENCE = "proprietary-binary"
+PROVIDES += "virtual/egl"
+
# Put "OMAP35x_Graphics_SDK_setuplinux_3_00_00_05.bin" in the same directory as this recipe
SRC_URI = "file://OMAP35x_Graphics_SDK_setuplinux_${SGXPV}.bin \
file://rc.pvr \
FILES_xserver-kdrive-powervrsgx = "${bindir}/Xsgx"
FILES_${PN}-tests = "${bindir}/*"
-PACKAGE_ARCH = "${MACHINE_ARCH}"
-
RRECOMMENDS_${PN} = "${PN}-tests \
omap3-sgx-modules"
${S}" | ${WORKDIR}/OMAP35x_Graphics_SDK_setuplinux_${SGXPV}.bin
}
-addtask accept_license after do_unpack before do_compile
+addtask accept_license after do_unpack before do_configure
-do_compile () {
- :
+do_compile() {
+ for sofile in $(find ${S} -name "lib*Open*.so") $(find ${S} -name "lib*srv*.so") $(find ${S} -name "lib*gl*.so") $(find ${S} -name "libpvr*.so") $(find ${S} -name "lib*GL*.so"); do
+ if [ "$(readlink -n ${sofile})" = "" ] ; then
+ mv $sofile ${sofile}.${IMGPV}
+ ln -sf $(basename ${sofile}.${IMGPV}) ${sofile}
+ fi
+ done
}
do_install () {
install -d ${D}${libdir}
- cp -pR ${BINLOCATION}/*.so* ${D}${libdir}
+ cp -pP ${BINLOCATION}/*.so* ${D}${libdir}
install -d ${D}${bindir}/
cp -pP ${BINLOCATION}/*_test ${D}${bindir}/
cp -pP ${BINLOCATION}/pvrsrvinit ${D}${bindir}/
cp -pP ${BINLOCATION}/xgles1test1 ${D}${bindir}/
- cp -pP ${BINLOCATION}/freedesktop/usr/X11R6_SGX/bin/Xsgx ${D}${bindir}/
+ cp -pP ${BINLOCATION}/freedesktop/kdrive/usr/X11R6_SGX/bin/Xsgx || true
+ cp -pP ${BINLOCATION}/freedesktop/usr/X11R6_SGX/bin/Xsgx ${D}${bindir}/ || true
install -d ${D}${includedir}
cp -pPR ${S}/GFX_Linux_SDK/OGLES2/SDKPackage/Builds/OGLES2/Include/* ${D}${includedir}/
+ cp -pPR ${S}/GFX_Linux_SDK/OGLES/SDKPackage/Builds/OGLES/Include/* ${D}${includedir}/
+ cp -pPR ${S}/GFX_Linux_SDK/OGLES/SDKPackage/Builds/OGLES/LinuxOMAP3/Include/GLES/* ${D}${includedir}/GLES/
+ cp -pPr ${S}/GFX_Linux_SDK/OGLES2/SDKPackage/Builds/OGLES2/LinuxOMAP3/Include/GLES/* ${D}${includedir}/GLES2/
install -d ${D}${sysconfdir}/init.d/
cp -pP ${WORKDIR}/rc.pvr ${D}${sysconfdir}/init.d/pvr-init
+
+ install -d ${D}${sysconfdir}
+ echo "[default]" > ${D}${sysconfdir}/powervr.ini
+ echo "WindowSystem=libpvrPVR2D_FRONTWSEGL.so" >> ${D}${sysconfdir}/powervr.ini
}
do_stage () {
install -d ${STAGING_INCDIR}
cp -pPR ${S}/GFX_Linux_SDK/OGLES2/SDKPackage/Builds/OGLES2/Include/* ${STAGING_INCDIR}/
+ cp -pPR ${S}/GFX_Linux_SDK/OGLES/SDKPackage/Builds/OGLES/Include/* ${STAGING_INCDIR}/
+ cp -pPR ${S}/GFX_Linux_SDK/OGLES/SDKPackage/Builds/OGLES/LinuxOMAP3/Include/GLES/* ${STAGING_INCDIR}/GLES/
+ cp -pPr ${S}/GFX_Linux_SDK/OGLES2/SDKPackage/Builds/OGLES2/LinuxOMAP3/Include/GLES/* ${STAGING_INCDIR}/GLES2/
}
pkg_postinst() {
#!/bin/sh
-rmmod bc_example
+#rmmod bc_example
rmmod omaplfb
rmmod pvrsrvkm
insmod $(busybox find /lib/modules/$(uname -r) -name "pvrsrvkm.ko")
-modprobe bc_example
+#modprobe bc_example
modprobe omaplfb
pvr_maj=`grep "pvrsrvkm$" /proc/devices | cut -b1,2,3`
# Not released yet
DEFAULT_PREFERENCE = "-1"
-PR = "r2"
+PR = "r3"
SGXPV = "3_00_00_05"
+IMGPV = "1.2.12.838"
# Quality control is really poor on these SDKs, so hack around the latest madness:
FILES_${PN} += "${libdir}/*.so"
FILES_${PN}-dev = "${includedir}"
-
--- /dev/null
+require libgles-omap3.inc
+
+# Not released yet
+DEFAULT_PREFERENCE = "-1"
+PR = "r5"
+
+SGXPV = "3_00_00_06"
+IMGPV = "1.3.13.1397"
+
+do_accept_license() {
+ export HOME="${WORKDIR}"
+ echo "Y
+q
+Y
+${S}" | ${WORKDIR}/OMAP35x_Graphics_SDK_setuplinux_${SGXPV}.bin
+}
+
+# Quality control is really poor on these SDKs, so hack around the latest madness:
+FILES_${PN} += "${libdir}/*.so"
+FILES_${PN}-dev = "${includedir}"
+
--- /dev/null
+SRC_URI = "http://divmod.org/trac/attachment/wiki/SoftwareReleases/${REALPN}-${PV}.tar.gz?format=raw"
+
+DEPENDS += "python-twisted-native"
+
+do_unpack2() {
+ cd ${WORKDIR}
+ tar zxvf ${REALPN}-${PV}.tar.gz?format=raw
+}
+
+addtask unpack2 after do_unpack before do_configure
+
+inherit distutils
+
+S = "${WORKDIR}/${REALPN}-${PV}"
+
+
+
DESCRIPTION = "Coherence is a DLNA/UPnP mediaserver + backends"
-SECTION = "python/devel"
+SECTION = "devel/python"
LICENSE = "MIT"
HOMEPAGE = "http://coherence.beebits.net/wiki"
-PR = "r0"
+PR = "r5"
inherit setuptools
S = "${WORKDIR}/Coherence-${PV}"
FILES_${PN} += "${datadir}"
+RDEPENDS_${PN} += "python-gst python-dbus python-configobj python-twisted python-twisted-core python-misc python-zopeinterface zope python-modules"
+
--- /dev/null
+DESCRIPTION = "Coherence is a DLNA/UPnP mediaserver + backends"
+SECTION = "devel/python"
+LICENSE = "MIT"
+HOMEPAGE = "http://coherence.beebits.net/wiki"
+
+PR = "r6"
+PV = "0.6.0+svnr${SRCREV}"
+
+inherit setuptools
+
+SRC_URI = "svn://coherence.beebits.net/svn/trunk;module=Coherence;proto=https"
+S = "${WORKDIR}/Coherence"
+
+FILES_${PN} += "${datadir}"
+RDEPENDS_${PN} += "python-twisted-pair python-divmodepsilon python-nevow python-gst python-dbus \
+ python-configobj python-twisted python-twisted-core python-misc python-zopeinterface \
+ zope python-modules python-pygobject python-gdata python-inotify"
+
+
--- /dev/null
+DESCRIPTION = "ConfigObj is a simple but powerful config file reader and writer"
+LICENSE = "BSD"
+
+SRC_URI = "http://pypi.python.org/packages/source/C/ConfigObj/configobj-${PV}.tar.gz"
+
+inherit distutils
+
+S = "${WORKDIR}/configobj-${PV}"
+
+
--- /dev/null
+DESCRIPTION = "A small utility package that depends on tools too recent for Twisted "
+LICENSE = "MIT"
+
+REALPN = "Epsilon"
+
+require divmod.inc
+
--- /dev/null
+DESCRIPTION = "Lightweight Python components for handling XML"
+SECTION = "devel/python"
+LICENSE = "Python"
+HOMEPAGE = "http://effbot.org/zone/element-index.htm"
+PR = "r0"
+
+inherit distutils
+
+SRC_URI = "http://effbot.org/media/downloads/elementtree-${PV}.zip"
+S = "${WORKDIR}/elementtree-${PV}"
+
+FILES_${PN} += "${datadir}"
+
+
--- /dev/null
+DESCRIPTION = "Google Data APIs Python Client Library"
+SECTION = "devel/python"
+LICENSE = "Apache"
+HOMEPAGE = "http://code.google.com/p/gdata-python-client/"
+PR = "r0"
+
+inherit distutils
+
+SRC_URI = "http://gdata-python-client.googlecode.com/files/gdata.py-${PV}.tar.gz"
+S = "${WORKDIR}/gdata.py-${PV}"
+
+FILES_${PN} += "${datadir}"
+
+RDEPENDS = "python-elementtree"
+
--- /dev/null
+DESCRIPTION = "Nevow is a web application construction kit written in Python"
+LICENSE = "MIT"
+
+REALPN = "Nevow"
+
+require divmod.inc
+
+FILES_${PN} += "${datadir}"
+DEPENDS += "python-twisted-native"
+
DESCRIPTION = "Python Bindings for the Cairo canvas library"
-SECTION = "python-devel"
+SECTION = "devel/python"
HOMEPAGE = "http://cairographics.org/pycairo"
LICENSE = "LGPL MPL"
DEPENDS = "cairo"
DESCRIPTION = "Python Bindings for the Cairo canvas library"
-SECTION = "python-devel"
+SECTION = "devel/python"
HOMEPAGE = "http://cairographics.org/pycairo"
LICENSE = "LGPL MPL"
# cairo >= 1.8.0
--- /dev/null
+require python-twisted_${PV}.bb
+
+RDEPENDS_${PN} = ""
+
+inherit native
+
+do_stage() {
+ distutils_stage_all
+}
--- /dev/null
+DESCRIPTION = "Twisted is an event-driven networking framework written in Python and licensed under the LGPL. \
+Twisted supports TCP, UDP, SSL/TLS, multicast, Unix sockets, a large number of protocols \
+(including HTTP, NNTP, IMAP, SSH, IRC, FTP, and others), and much more."
+HOMEPAGE = "http://www.twistedmatrix.com"
+SECTION = "console/network"
+PRIORITY = "optional"
+LICENSE = "LGPL"
+PR = "r1"
+
+SRC_URI = "http://tmrc.mit.edu/mirror/twisted/Twisted/8.2/Twisted-${PV}.tar.bz2 "
+S = "${WORKDIR}/Twisted-${PV}"
+
+inherit setuptools
+
+PACKAGES += "\
+ ${PN}-zsh \
+ ${PN}-test \
+ ${PN}-protocols \
+ ${PN}-bin \
+ ${PN}-conch \
+ ${PN}-lore \
+ ${PN}-mail \
+ ${PN}-names \
+ ${PN}-news \
+ ${PN}-runner \
+ ${PN}-web \
+ ${PN}-words \
+ ${PN}-flow \
+ ${PN}-pair \
+ ${PN}-core \
+"
+
+RDEPENDS = "python-core python-zopeinterface"
+RDEPENDS_${PN} += "\
+ ${PN}-bin \
+ ${PN}-conch \
+ ${PN}-lore \
+ ${PN}-mail \
+ ${PN}-names \
+ ${PN}-news \
+ ${PN}-runner \
+ ${PN}-web \
+ ${PN}-words \
+"
+
+ALLOW_EMPTY = "1"
+FILES_${PN} = ""
+
+FILES_${PN}-test = " \
+ ${libdir}/${PYTHON_DIR}/site-packages/twisted/test \
+"
+
+FILES_${PN}-protocols = " \
+ ${libdir}/${PYTHON_DIR}/site-packages/twisted/protocols/ \
+"
+
+FILES_${PN}-zsh = " \
+ ${libdir}/${PYTHON_DIR}/site-packages/twisted/python/zsh \
+ ${libdir}/${PYTHON_DIR}/site-packages/twisted/python/zshcomp.* \
+"
+
+FILES_${PN}-bin = " \
+ ${libdir}/${PYTHON_DIR}/site-packages/twisted/protocols/_c_urlarg.so \
+ ${libdir}/${PYTHON_DIR}/site-packages/twisted/spread/cBanana.so \
+"
+
+FILES_${PN}-conch = " \
+ ${bindir}/ckeygen \
+ ${bindir}/tkconch \
+ ${bindir}/conch \
+ ${bindir}/conchftp \
+ ${bindir}/cftp \
+ ${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/twisted_conch.py* \
+ ${libdir}/${PYTHON_DIR}/site-packages/twisted/conch \
+"
+
+FILES_${PN}-core = " \
+${bindir}/manhole \
+${bindir}/mktap \
+${bindir}/twistd \
+${bindir}/tap2deb \
+${bindir}/tap2rpm \
+${bindir}/tapconvert \
+${bindir}/tkmktap \
+${bindir}/trial \
+${bindir}/easy_install* \
+${bindir}/pyhtmlizer \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/*.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/__init__.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/notestplugin.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/testplugin.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/twisted_ftp.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/twisted_inet.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/twisted_manhole.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/twisted_portforward.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/twisted_socks.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/twisted_telnet.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/twisted_trial.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/dropin.cache \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/application \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/cred \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/enterprise \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/internet \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/manhole \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/manhole \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/persisted \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/protocols\
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python\
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/timeoutqueue.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/filepath.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/dxprofile.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/plugin.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/htmlizer.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/__init__.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/dispatch.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/hook.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/threadpool.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/otp.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/usage.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/roots.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/versions.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/urlpath.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/util.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/components.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/logfile.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/runtime.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/reflect.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/context.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/threadable.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/rebuild.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/failure.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/lockfile.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/formmethod.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/finalize.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/win32.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/dist.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/shortcut.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/zipstream.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/release.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/syslog.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/log.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/compat.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/zshcomp.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/procutils.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/text.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/_twisted_zsh_stub \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/scripts/ \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/spread/ \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/tap/ \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/trial/ \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/__init__.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/_version.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/copyright.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/im.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/*.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/python/*.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/*.py* \
+"
+
+FILES_${PN}-lore = " \
+${bindir}/bookify \
+${bindir}/lore \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/twisted_lore.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/lore \
+"
+
+FILES_${PN}-mail = " \
+${bindir}/mailmail \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/twisted_mail.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/mail \
+"
+
+FILES_${PN}-names = " \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/twisted_names.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/names \
+"
+
+FILES_${PN}-news = " \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/twisted_news.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/news \
+"
+
+FILES_${PN}-runner = " \
+${libdir}/site-packages/twisted/runner/portmap.so \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/runner\
+"
+
+FILES_${PN}-web = " \
+${bindir}/websetroot \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/twisted_web.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/web\
+"
+
+FILES_${PN}-words = " \
+${bindir}/im \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/twisted_words.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/words\
+"
+
+FILES_${PN}-flow = " \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/twisted_flow.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/flow \"
+
+FILES_${PN}-pair = " \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/plugins/twisted_pair.py* \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/pair \
+"
+
+FILES_${PN}-dbg += " \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/*/.debug \
+${libdir}/${PYTHON_DIR}/site-packages/twisted/*/*/.debug \
+"
DESCRIPTION = "The xappy python module is an easy-to-use interface to the Xapian search engine"
-SECTION = "python/devel"
+SECTION = "devel/python"
LICENSE = "GPLv2"
DEPENDS = "xapian-core"
PR = "ml0"
SECTION = "kernel/modules"
LICENSE = "GPL"
+PR = "r1"
+
SRC_URI = "http://homepages.tu-darmstadt.de/~p_larbig/wlan/${PN}-${PV}.tar.bz2"
inherit module
SECTION = "kernel/modules"
LICENSE = "GPL"
+PR = "r1"
+
SRC_URI = "http://homepages.tu-darmstadt.de/~p_larbig/wlan/${PN}-${PV}.tar.bz2"
inherit module
SECTION = "kernel/modules"
LICENSE = "GPL"
+PR = "r1"
+
SRC_URI = "${SOURCEFORGE_MIRROR}/rt2400/rt2570-${PV}.tar.gz"
inherit module
HOMEPAGE = "http://www.chumby.com"
SECTION = "kernel/modules"
LICENSE = "GPL"
-PR = "r2"
+PR = "r3"
SRC_URI="http://files.chumby.com/source/ironforge/build396/${PN}-${PV}.tar.gz"
DESCRIPTION = "Firmware for rt73 based USB wifi adaptors"
LICENSE = "unknown"
+PR = "r1"
+
SRC_URI = "http://www.ralinktech.com.tw/data/RT71W_Firmware_V${PV}.zip"
S = "${WORKDIR}/RT71W_Firmware_V${PV}"
HOMEPAGE = "http://homepages.tu-darmstadt.de/~p_larbig/wlan"
SECTION = "kernel/modules"
LICENSE = "GPL"
-PR = "r1"
+PR = "r2"
SRC_URI= "http://homepages.tu-darmstadt.de/~p_larbig/wlan/rt73-k2wrlz-1.0.0.tar.bz2"
inherit module
HOMEPAGE = "http://homepages.tu-darmstadt.de/~p_larbig/wlan"
SECTION = "kernel/modules"
LICENSE = "GPL"
-PR = "r1"
+PR = "r2"
SRC_URI="http://homepages.tu-darmstadt.de/~p_larbig/wlan/${PN}-${PV}.tar.bz2"
HOMEPAGE = "http://homepages.tu-darmstadt.de/~p_larbig/wlan"
SECTION = "kernel/modules"
LICENSE = "GPL"
-PR = "r0"
+PR = "r2"
SRC_URI="http://homepages.tu-darmstadt.de/~p_larbig/wlan/${PN}-${PV}.tar.bz2"
-LICENSE="GPL"
-SUMMARY="Receive a forwarded serial from serial-forward and provide a PTY"
+DESCRIPTION = "Receive a forwarded serial from serial-forward and provide a PTY"
+AUTHOR = "Holger 'Zecke' Freyther"
+LICENSE = "GPL"
+SECTION = "console/network"
+PV = "1.0.0+svnr${SRCREV}""
+PR = "r0"
-SRC_URI="svn://svn.openmoko.org/developers/zecke/;module=serial_forward;proto=http"
+SRC_URI = "svn://svn.openmoko.org/developers/zecke/;module=serial_forward;proto=http"
S = "${WORKDIR}/serial_forward"
inherit native
}
addtask deploy before do_package after do_install
-
-LICENSE="GPL"
-SUMMARY="Forward a serial using TCP/IP"
+DESCRIPTION = "Forward a serial using TCP/IP"
+AUTHOR = "Holger 'Zecke' Freyther'"
+LICENSE = "GPL"
+SECTION = "console/devel"
+PV = "1.0.0+svnr${SRCREV}"
+PR = "r0"
-SRC_URI="svn://svn.openmoko.org/developers/zecke/;module=serial_forward;proto=http"
-S="${WORKDIR}/serial_forward"
+SRC_URI = "svn://svn.openmoko.org/developers/zecke/;module=serial_forward;proto=http"
+S = "${WORKDIR}/serial_forward"
do_compile() {
cd ${S}
else
echo "sysconf_restore_conffiles: $file: timestamp copy failed (ignored)" >&2
fi
- elif test -h "$saved/file" -o -h "$ffsdir/$file"
+ elif test -h "$saved/$file" -o -h "$ffsdir/$file"
then
# new or old symbolic link
if test -h "$saved/$file" -a -h "$ffsdir/$file" &&
echo "$file"
echo "$file" >&3;;
diff) # need user input
- if sysconf_verify_link "$file" <>/dev/tty >&0 2>&0
+ if sysconf_verify_link "$file" </dev/tty >/dev/tty 2>&1
then
echo "$file"
echo "$file" >&3
echo "$file"
echo "$file" >&3;;
diff) # the files are different, get user input
- if sysconf_verify "$file" <>/dev/tty >&0 2>&0
+ if sysconf_verify "$file" </dev/tty >/dev/tty 2>&1
then
echo "$file"
echo "$file" >&3
elif test "$file" = "etc/.configured"
then
: # special handling
- elif test -h "$saved/file" -o -h "$ffsdir/$file"
+ elif test -h "$saved/$file" -o -h "$ffsdir/$file"
then
# new or old symbolic link
if test -h "$saved/$file" -a -h "$ffsdir/$file" &&
LICENSE = "GPL"
DEPENDS = "base-files devio"
RDEPENDS = "busybox devio"
-PR = "r8"
+PR = "r9"
SRC_URI = "file://boot/flash \
file://boot/disk \
DESCRIPTION = "Task for Beagleboard-demo-image"
-PR = "r6"
+PR = "r7"
inherit task
angstrom-gnome-icon-theme-enable \
openssh-scp openssh-ssh \
picodlp-control \
+ connman-gnome \
"
# Install all kernel modules
SECTION = "fso/base"
LICENSE = "MIT"
PV = "1.0"
-PR = "r6"
+PR = "r7"
inherit task
frameworkd \
# fso-apmd \
fso-gpsd \
-# fso-monitord \
+ fso-monitord \
connman \
connman-scripts \
connman-plugin-bluetooth \
# connman-plugin-dhclient \
# connman-plugin-dnsproxy \
- connman-plugin-ethernet \
+# connman-plugin-ethernet \
# connman-plugin-fake \
connman-plugin-loopback \
connman-plugin-pppd \
GLIBC_PKGS = "\
glibc \
glibc-dbg \
- glibc-dev \
+ virtual-libc-dev \
glibc-utils \
libsegfault \
glibc-thread-db \
+++ /dev/null
-diff -Nurd u-boot-1.1.2/board/oxnas/config.mk u-boot-1.1.2-oxe810/board/oxnas/config.mk
---- u-boot-1.1.2/board/oxnas/config.mk 1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/board/oxnas/config.mk 2008-06-11 17:55:18.000000000 +0200
-@@ -0,0 +1,26 @@
-+TEXT_BASE = 0x48d00000
-+CROSS_COMPILE = arm-linux-
-+
-+PLL400 ?= 733333333
-+RPSCLK ?= 25000000
-+
-+NAS_VERSION ?= 810
-+FPGA ?= 0
-+FPGA_ARM_CLK ?= 25000000
-+
-+PROBE_MEM_SIZE ?= 1
-+MEM_SIZE ?= 64 # Memory size in megabytes if probing is not enabled
-+MEM_ODT ?= 150
-+
-+USE_SATA ?= 1
-+USE_SATA_ENV ?= 1
-+USE_FLASH ?= 1
-+
-+LINUX_ROOT_RAIDED ?= 1
-+
-+USE_EXTERNAL_UART ?= 0
-+INTERNAL_UART ?= 2
-+
-+TEST_BRD ?= 0 # Only significant for OX800
-+
-+PLATFORM_CPPFLAGS += -DLINUX_ROOT_RAIDED=$(LINUX_ROOT_RAIDED) -DMEM_ODT=$(MEM_ODT) -DPROBE_MEM_SIZE=$(PROBE_MEM_SIZE) -DNAS_VERSION=$(NAS_VERSION) -DFPGA=$(FPGA) -DFPGA_ARM_CLK=$(FPGA_ARM_CLK) -DINTERNAL_UART=$(INTERNAL_UART) -DUSE_EXTERNAL_UART=$(USE_EXTERNAL_UART) -DMEM_SIZE=$(MEM_SIZE) -DPLL400=$(PLL400) -DRPSCLK=$(RPSCLK) -DTEST_BRD=$(TEST_BRD) -DUSE_SATA=$(USE_SATA) -DUSE_SATA_ENV=$(USE_SATA_ENV) -DUSE_FLASH=$(USE_FLASH)
-diff -Nurd u-boot-1.1.2/board/oxnas/eth.c u-boot-1.1.2-oxe810/board/oxnas/eth.c
---- u-boot-1.1.2/board/oxnas/eth.c 1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/board/oxnas/eth.c 2008-06-11 17:55:18.000000000 +0200
-@@ -0,0 +1,1666 @@
-+/*
-+ * (C) Copyright 2005
-+ * Oxford Semiconductor Ltd
-+ *
-+ * See file CREDITS for list of people who contributed to this
-+ * project.
-+ *
-+ * 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 <common.h>
-+#include <malloc.h>
-+#include <net.h>
-+#include <asm/barrier.h>
-+
-+//#define DEBUG_GMAC_INIT
-+
-+// The number of bytes wasted at the start of a received packet buffer in order
-+// to ensure the IP header will be aligned to a 32-bit boundary
-+static const int ETHER_FRAME_ALIGN_WASTAGE = 2;
-+static const int EXTRA_RX_SKB_SPACE = 32; // Otherwise GMAC spans over >1 skb
-+static const int ETHER_MTU = 1500;
-+
-+static const u32 MAC_BASE_OFFSET = 0x0000;
-+static const u32 DMA_BASE_OFFSET = 0x1000;
-+
-+static const int NUM_TX_DMA_DESCRIPTORS = 1;
-+static const int NUM_RX_DMA_DESCRIPTORS = 32;
-+
-+/* Generic MII registers. */
-+#define MII_BMCR 0x00 /* Basic mode control register */
-+#define MII_BMSR 0x01 /* Basic mode status register */
-+#define MII_PHYSID1 0x02 /* PHYS ID 1 */
-+#define MII_PHYSID2 0x03 /* PHYS ID 2 */
-+#define MII_ADVERTISE 0x04 /* Advertisement control reg */
-+#define MII_LPA 0x05 /* Link partner ability reg */
-+#define MII_EXPANSION 0x06 /* Expansion register */
-+#define MII_CTRL1000 0x09 /* 1000BASE-T control */
-+#define MII_STAT1000 0x0a /* 1000BASE-T status */
-+#define MII_ESTATUS 0x0f /* Extended Status */
-+
-+/* Basic mode control register. */
-+#define BMCR_RESV 0x003f /* Unused... */
-+#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */
-+#define BMCR_CTST 0x0080 /* Collision test */
-+#define BMCR_FULLDPLX 0x0100 /* Full duplex */
-+#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
-+#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */
-+#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */
-+#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
-+#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
-+#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
-+#define BMCR_RESET 0x8000 /* Reset the DP83840 */
-+
-+/* Basic mode status register. */
-+#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
-+#define BMSR_JCD 0x0002 /* Jabber detected */
-+#define BMSR_LSTATUS 0x0004 /* Link status */
-+#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
-+#define BMSR_RFAULT 0x0010 /* Remote fault detected */
-+#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
-+#define BMSR_RESV 0x00c0 /* Unused... */
-+#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */
-+#define BMSR_100FULL2 0x0200 /* Can do 100BASE-T2 HDX */
-+#define BMSR_100HALF2 0x0400 /* Can do 100BASE-T2 FDX */
-+#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
-+#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
-+#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
-+#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
-+#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
-+
-+/* 1000BASE-T Status register */
-+#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */
-+#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */
-+#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */
-+#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */
-+#define PHY_TYPE_NONE 0
-+#define PHY_TYPE_MICREL_KS8721BL 0x00221619
-+#define PHY_TYPE_VITESSE_VSC8201XVZ 0x000fc413
-+#define PHY_TYPE_REALTEK_RTL8211BGR 0x001cc912
-+#define PHY_TYPE_LSI_ET1011C 0x0282f013
-+
-+/* Specific PHY values */
-+#define VSC8201_MII_ACSR 0x1c // Vitesse VCS8201 gigabit PHY Auxillary Control and Status register
-+#define VSC8201_MII_ACSR_MDPPS_BIT 2 // Mode/Duplex Pin Priority Select
-+
-+#define ET1011C_MII_CONFIG 0x16
-+#define ET1011C_MII_CONFIG_IFMODESEL 0
-+#define ET1011C_MII_CONFIG_IFMODESEL_NUM_BITS 3
-+#define ET1011C_MII_CONFIG_SYSCLKEN 4
-+#define ET1011C_MII_CONFIG_TXCLKEN 5
-+#define ET1011C_MII_CONFIG_TBI_RATESEL 8
-+#define ET1011C_MII_CONFIG_CRS_TX_EN 15
-+
-+#define ET1011C_MII_CONFIG_IFMODESEL_GMII_MII 0
-+#define ET1011C_MII_CONFIG_IFMODESEL_TBI 1
-+#define ET1011C_MII_CONFIG_IFMODESEL_GMII_MII_GTX 2
-+
-+#define ET1011C_MII_LED2 0x1c
-+#define ET1011C_MII_LED2_LED_TXRX 12
-+#define ET1011C_MII_LED2_LED_NUM_BITS 4
-+
-+#define ET1011C_MII_LED2_LED_TXRX_ON 0xe
-+#define ET1011C_MII_LED2_LED_TXRX_ACTIVITY 0x7
-+
-+// Some typedefs to cope with std Linux types
-+typedef void sk_buff_t;
-+
-+// The in-memory descriptor structures
-+typedef struct gmac_dma_desc
-+{
-+ /** The encoded status field of the GMAC descriptor */
-+ u32 status;
-+ /** The encoded length field of GMAC descriptor */
-+ u32 length;
-+ /** Buffer 1 pointer field of GMAC descriptor */
-+ u32 buffer1;
-+ /** Buffer 2 pointer or next descriptor pointer field of GMAC descriptor */
-+ u32 buffer2;
-+ /** Not used for U-Boot */
-+ u32 skb;
-+} __attribute ((packed)) gmac_dma_desc_t;
-+
-+typedef struct gmac_desc_list_info
-+{
-+ gmac_dma_desc_t* base_ptr;
-+ int num_descriptors;
-+ int empty_count;
-+ int full_count;
-+ int r_index;
-+ int w_index;
-+} gmac_desc_list_info_t;
-+
-+// Private data structure for the GMAC driver
-+typedef struct gmac_priv
-+{
-+ /** Base address of GMAC MAC registers */
-+ u32 macBase;
-+ /** Base address of GMAC DMA registers */
-+ u32 dmaBase;
-+
-+ /** The number of descriptors in the gmac_dma_desc_t array holding both the
-+ * TX and RX descriptors. The TX descriptors reside at the start of the
-+ * array */
-+ unsigned total_num_descriptors;
-+
-+ /** The address of the start of the descriptor array */
-+ gmac_dma_desc_t *desc_base_addr;
-+
-+ /** Descriptor list management */
-+ gmac_desc_list_info_t tx_gmac_desc_list_info;
-+ gmac_desc_list_info_t rx_gmac_desc_list_info;
-+
-+ /** PHY info */
-+ u32 phy_type;
-+ u32 phy_addr;
-+ int phy_id;
-+ int link_is_1000M;
-+} gmac_priv_t;
-+
-+/**
-+ * MAC register indices
-+ */
-+typedef enum gmac_mac_regs {
-+ MAC_CONFIG_REG = 0,
-+ MAC_FRAME_FILTER_REG = 1,
-+ MAC_HASH_HIGH_REG = 2,
-+ MAC_HASH_LOW_REG = 3,
-+ MAC_GMII_ADR_REG = 4,
-+ MAC_GMII_DATA_REG = 5,
-+ MAC_FLOW_CNTL_REG = 6,
-+ MAC_VLAN_TAG_REG = 7,
-+ MAC_VERSION_REG = 8,
-+ MAC_ADR0_HIGH_REG = 16,
-+ MAC_ADR0_LOW_REG = 17,
-+ MAC_ADR1_HIGH_REG = 18,
-+ MAC_ADR1_LOW_REG = 19,
-+ MAC_ADR2_HIGH_REG = 20,
-+ MAC_ADR2_LOW_REG = 21,
-+ MAC_ADR3_HIGH_REG = 22,
-+ MAC_ADR3_LOW_REG = 23,
-+ MAC_ADR4_HIGH_REG = 24,
-+ MAC_ADR4_LOW_REG = 25,
-+ MAC_ADR5_HIGH_REG = 26,
-+ MAC_ADR5_LOW_REG = 27,
-+ MAC_ADR6_HIGH_REG = 28,
-+ MAC_ADR6_LOW_REG = 29,
-+ MAC_ADR7_HIGH_REG = 30,
-+ MAC_ADR7_LOW_REG = 31,
-+ MAC_ADR8_HIGH_REG = 32,
-+ MAC_ADR8_LOW_REG = 33,
-+ MAC_ADR9_HIGH_REG = 34,
-+ MAC_ADR9_LOW_REG = 35,
-+ MAC_ADR10_HIGH_REG = 36,
-+ MAC_ADR10_LOW_REG = 37,
-+ MAC_ADR11_HIGH_REG = 38,
-+ MAC_ADR11_LOW_REG = 39,
-+ MAC_ADR12_HIGH_REG = 40,
-+ MAC_ADR12_LOW_REG = 41,
-+ MAC_ADR13_HIGH_REG = 42,
-+ MAC_ADR13_LOW_REG = 43,
-+ MAC_ADR14_HIGH_REG = 44,
-+ MAC_ADR14_LOW_REG = 45,
-+ MAC_ADR15_HIGH_REG = 46,
-+ MAC_ADR15_LOW_REG = 47
-+} gmac_mac_regs_t;
-+
-+
-+/**
-+ * MAC register field definitions
-+ */
-+typedef enum gmac_config_reg {
-+ MAC_CONFIG_WD_BIT = 23,
-+ MAC_CONFIG_JD_BIT = 22,
-+ MAC_CONFIG_BE_BIT = 21,
-+ MAC_CONFIG_JE_BIT = 20,
-+ MAC_CONFIG_IFG_BIT = 17,
-+ MAC_CONFIG_PS_BIT = 15,
-+ MAC_CONFIG_DO_BIT = 13,
-+ MAC_CONFIG_LM_BIT = 12,
-+ MAC_CONFIG_DM_BIT = 11,
-+ MAC_CONFIG_IPC_BIT = 10,
-+ MAC_CONFIG_DR_BIT = 9,
-+ MAC_CONFIG_ACS_BIT = 7,
-+ MAC_CONFIG_BL_BIT = 5,
-+ MAC_CONFIG_DC_BIT = 4,
-+ MAC_CONFIG_TE_BIT = 3,
-+ MAC_CONFIG_RE_BIT = 2
-+} gmac_config_reg_t;
-+
-+#define MAC_CONFIG_IFG_NUM_BITS 3
-+#define MAC_CONFIG_BL_NUM_BITS 2
-+
-+typedef enum gmac_frame_filter_reg {
-+ MAC_FRAME_FILTER_RA_BIT = 31,
-+ MAC_FRAME_FILTER_SAF_BIT = 9,
-+ MAC_FRAME_FILTER_SAIF_BIT = 8,
-+ MAC_FRAME_FILTER_PCF_BIT = 6,
-+ MAC_FRAME_FILTER_DBF_BIT = 5,
-+ MAC_FRAME_FILTER_PM_BIT = 4,
-+ MAC_FRAME_FILTER_DAIF_BIT = 3,
-+ MAC_FRAME_FILTER_HMC_BIT = 2,
-+ MAC_FRAME_FILTER_HUC_BIT = 1,
-+ MAC_FRAME_FILTER_PR_BIT = 0
-+} gmac_frame_filter_reg_t;
-+
-+#define MAC_FRAME_FILTER_PCF_NUM_BITS 2
-+
-+typedef enum gmac_hash_table_high_reg {
-+ MAC_HASH_HIGH_HTH_BIT = 0
-+} gmac_hash_table_high_reg_t;
-+
-+typedef enum gmac_hash_table_low_reg {
-+ MAC_HASH_LOW_HTL_BIT = 0
-+} gmac_hash_table_low_reg_t;
-+
-+typedef enum gmac_gmii_address_reg {
-+ MAC_GMII_ADR_PA_BIT = 11,
-+ MAC_GMII_ADR_GR_BIT = 6,
-+ MAC_GMII_ADR_CR_BIT = 2,
-+ MAC_GMII_ADR_GW_BIT = 1,
-+ MAC_GMII_ADR_GB_BIT = 0
-+} gmac_gmii_address_reg_t;
-+
-+#define MAC_GMII_ADR_PA_NUM_BITS 5
-+#define MAC_GMII_ADR_GR_NUM_BITS 5
-+#define MAC_GMII_ADR_CR_NUM_BITS 3
-+
-+typedef enum gmac_gmii_data_reg {
-+ MAC_GMII_DATA_GD_BIT = 0
-+} gmac_gmii_data_reg_t;
-+
-+#define MAC_GMII_DATA_GD_NUM_BITS 16
-+
-+typedef enum gmac_flow_control_reg {
-+ MAC_FLOW_CNTL_PT_BIT = 16,
-+ MAC_FLOW_CNTL_PLT_BIT = 4,
-+ MAC_FLOW_CNTL_UP_BIT = 3,
-+ MAC_FLOW_CNTL_RFE_BIT = 2,
-+ MAC_FLOW_CNTL_TFE_BIT = 1,
-+ MAC_FLOW_CNTL_FCB_BPA_BIT = 0
-+} gmac_flow_control_reg_t;
-+
-+#define MAC_FLOW_CNTL_PT_NUM_BITS 16
-+#define MAC_FLOW_CNTL_PLT_NUM_BITS 2
-+
-+typedef enum gmac_vlan_tag_reg {
-+ MAC_VLAN_TAG_LV_BIT = 0
-+} gmac_vlan_tag_reg_t;
-+
-+#define MAC_VLAN_TAG_LV_NUM_BITS 16
-+
-+typedef enum gmac_version_reg {
-+ MAC_VERSION_UD_BIT = 8,
-+ MAC_VERSION_SD_BIT = 0
-+} gmac_version_reg_t;
-+
-+#define MAC_VERSION_UD_NUM_BITS 8
-+#define MAC_VERSION_SD_NUM_BITS 8
-+
-+typedef enum gmac_mac_adr_0_high_reg {
-+ MAC_ADR0_HIGH_MO_BIT = 31,
-+ MAC_ADR0_HIGH_A_BIT = 0
-+} gmac_mac_adr_0_high_reg_t;
-+
-+#define MAC_ADR0_HIGH_A_NUM_BITS 16
-+
-+typedef enum gmac_mac_adr_0_low_reg {
-+ MAC_ADR0_LOW_A_BIT = 0
-+} gmac_mac_adr_0_low_reg_t;
-+
-+typedef enum gmac_mac_adr_1_high_reg {
-+ MAC_ADR1_HIGH_AE_BIT = 31,
-+ MAC_ADR1_HIGH_SA_BIT = 30,
-+ MAC_ADR1_HIGH_MBC_BIT = 24,
-+ MAC_ADR1_HIGH_A_BIT = 0
-+} gmac_mac_adr_1_high_reg_t;
-+
-+#define MAC_ADR1_HIGH_MBC_NUM_BITS 6
-+#define MAC_ADR1_HIGH_A_NUM_BITS 16
-+
-+typedef enum gmac_mac_adr_1_low_reg {
-+ MAC_ADR1_LOW_A_BIT = 0
-+} gmac_mac_adr_1_low_reg_t;
-+
-+
-+/**
-+ * MMC register indices - registers accessed via the MAC accessor functions
-+ */
-+typedef enum gmac_mmc_regs {
-+ MMC_CONTROL_REG = 64,
-+ MMC_RX_INT_REG = 65,
-+ MMC_TX_INT_REG = 66,
-+ MMC_RX_MASK_REG = 67,
-+ MMC_TX_MASK_REG = 68
-+} gmac_mmc_regs_t;
-+
-+/**
-+ * DMA register indices
-+ */
-+typedef enum gmac_dma_regs {
-+ DMA_BUS_MODE_REG = 0,
-+ DMA_TX_POLL_REG = 1,
-+ DMA_RX_POLL_REG = 2,
-+ DMA_RX_DESC_ADR_REG = 3,
-+ DMA_TX_DESC_ADR_REG = 4,
-+ DMA_STATUS_REG = 5,
-+ DMA_OP_MODE_REG = 6,
-+ DMA_INT_ENABLE_REG = 7,
-+ DMA_MISSED_OVERFLOW_REG = 8,
-+ DMA_CUR_TX_DESC_REG = 18,
-+ DMA_CUR_RX_DESC_REG = 19,
-+ DMA_CUR_TX_ADR_REG = 20,
-+ DMA_CUR_RX_ADR_REG = 21
-+} gmac_dma_regs_t;
-+
-+/**
-+ * DMA register field definitions
-+ */
-+
-+typedef enum gmac_dma_bus_mode_reg {
-+ DMA_BUS_MODE_FB_BIT = 16,
-+ DMA_BUS_MODE_PR_BIT = 14,
-+ DMA_BUS_MODE_PBL_BIT = 8,
-+ DMA_BUS_MODE_DSL_BIT = 2,
-+ DMA_BUS_MODE_DA_BIT = 1,
-+ DMA_BUS_MODE_SWR_BIT = 0
-+} gmac_dma_bus_mode_reg_t;
-+
-+#define DMA_BUS_MODE_PR_NUM_BITS 2
-+#define DMA_BUS_MODE_PBL_NUM_BITS 6
-+#define DMA_BUS_MODE_DSL_NUM_BITS 5
-+
-+typedef enum gmac_dma_tx_poll_demand_reg {
-+ DMA_TX_POLL_TPD_BIT = 0
-+} gmac_dma_tx_poll_demand_reg_t;
-+
-+typedef enum gmac_dma_rx_poll_demand_reg {
-+ DMA_RX_POLL_RPD_BIT = 0
-+} gmac_dma_rx_poll_demand_reg_t;
-+
-+typedef enum gmac_dma_rx_desc_list_adr_reg {
-+ DMA_RX_DESC_ADR_SRL_BIT = 0
-+} gmac_dma_rx_desc_list_adr_reg_t;
-+
-+typedef enum gmac_dma_tx_desc_list_adr_reg {
-+ DMA_TX_DESC_ADR_STL_BIT = 0
-+} gmac_dma_tx_desc_list_adr_reg_t;
-+
-+typedef enum gmac_dma_status_reg {
-+ DMA_STATUS_GPI_BIT = 28,
-+ DMA_STATUS_GMI_BIT = 27,
-+ DMA_STATUS_GLI_BIT = 26,
-+ DMA_STATUS_EB_BIT = 23,
-+ DMA_STATUS_TS_BIT = 20,
-+ DMA_STATUS_RS_BIT = 17,
-+ DMA_STATUS_NIS_BIT = 16,
-+ DMA_STATUS_AIS_BIT = 15,
-+ DMA_STATUS_ERI_BIT = 14,
-+ DMA_STATUS_FBE_BIT = 13,
-+ DMA_STATUS_ETI_BIT = 10,
-+ DMA_STATUS_RWT_BIT = 9,
-+ DMA_STATUS_RPS_BIT = 8,
-+ DMA_STATUS_RU_BIT = 7,
-+ DMA_STATUS_RI_BIT = 6,
-+ DMA_STATUS_UNF_BIT = 5,
-+ DMA_STATUS_OVF_BIT = 4,
-+ DMA_STATUS_TJT_BIT = 3,
-+ DMA_STATUS_TU_BIT = 2,
-+ DMA_STATUS_TPS_BIT = 1,
-+ DMA_STATUS_TI_BIT = 0
-+} gmac_dma_status_reg_t;
-+
-+#define DMA_STATUS_EB_NUM_BITS 3
-+#define DMA_STATUS_TS_NUM_BITS 3
-+#define DMA_STATUS_RS_NUM_BITS 3
-+
-+typedef enum gmac_dma_op_mode_reg {
-+ DMA_OP_MODE_SF_BIT = 21,
-+ DMA_OP_MODE_FTF_BIT = 20,
-+ DMA_OP_MODE_TTC_BIT = 14,
-+ DMA_OP_MODE_ST_BIT = 13,
-+ DMA_OP_MODE_RFD_BIT = 11,
-+ DMA_OP_MODE_RFA_BIT = 9,
-+ DMA_OP_MODE_EFC_BIT = 8,
-+ DMA_OP_MODE_FEF_BIT = 7,
-+ DMA_OP_MODE_FUF_BIT = 6,
-+ DMA_OP_MODE_RTC_BIT = 3,
-+ DMA_OP_MODE_OSF_BIT = 2,
-+ DMA_OP_MODE_SR_BIT = 1
-+} gmac_dma_op_mode_reg_t;
-+
-+#define DMA_OP_MODE_TTC_NUM_BITS 3
-+#define DMA_OP_MODE_RFD_NUM_BITS 2
-+#define DMA_OP_MODE_RFA_NUM_BITS 2
-+#define DMA_OP_MODE_RTC_NUM_BITS 2
-+
-+typedef enum gmac_dma_intr_enable_reg {
-+ DMA_INT_ENABLE_NI_BIT = 16,
-+ DMA_INT_ENABLE_AI_BIT = 15,
-+ DMA_INT_ENABLE_ERE_BIT = 14,
-+ DMA_INT_ENABLE_FBE_BIT = 13,
-+ DMA_INT_ENABLE_ETE_BIT = 10,
-+ DMA_INT_ENABLE_RW_BIT = 9,
-+ DMA_INT_ENABLE_RS_BIT = 8,
-+ DMA_INT_ENABLE_RU_BIT = 7,
-+ DMA_INT_ENABLE_RI_BIT = 6,
-+ DMA_INT_ENABLE_UN_BIT = 5,
-+ DMA_INT_ENABLE_OV_BIT = 4,
-+ DMA_INT_ENABLE_TJ_BIT = 3,
-+ DMA_INT_ENABLE_TU_BIT = 2,
-+ DMA_INT_ENABLE_TS_BIT = 1,
-+ DMA_INT_ENABLE_TI_BIT = 0
-+} gmac_dma_intr_enable_reg_t;
-+
-+typedef enum gmac_dma_missed_overflow_reg {
-+ DMA_MISSED_OVERFLOW_OFOC_BIT = 28, // Overflow bit for FIFO Overflow Counter
-+ DMA_MISSED_OVERFLOW_AMFC_BIT = 17, // Application Missed Frames Count
-+ DMA_MISSED_OVERFLOW_OAMFO_BIT = 16, // Overflow bit for Application Missed Frames Count
-+ DMA_MISSED_OVERFLOW_CMFC_BIT = 0 // Controller Missed Frames Count
-+} gmac_dma_missed_overflow_reg_t;
-+
-+#define DMA_MISSED_OVERFLOW_OAMFO_NUM_BITS 11
-+#define DMA_MISSED_OVERFLOW_CMFC_NUM_BITS 16
-+
-+typedef enum gmac_dma_current_tx_desc_reg {
-+ DMA_CUR_TX_DESC_A_BIT = 0
-+} gmac_dma_current_tx_desc_reg_t;
-+
-+typedef enum gmac_dma_current_rx_desc_reg {
-+ DMA_CUR_RX_DESC_A_BIT = 0
-+} gmac_dma_current_rx_desc_reg_t;
-+
-+typedef enum gmac_dma_current_tx_adr_reg {
-+ DMA_CUR_TX_ADR_A_BIT = 0
-+} gmac_dma_current_tx_adr_reg_t;
-+
-+typedef enum gmac_dma_current_rx_adr_reg {
-+ DMA_CUR_RX_ADR_A_BIT = 0
-+} gmac_dma_current_rx_adr_reg_t;
-+
-+/**
-+ * Descriptor support
-+ */
-+/** Descriptor status word field definitions */
-+typedef enum desc_status {
-+ descOwnByDma = 0x80000000, /* descriptor is owned by DMA engine */
-+
-+ descFrameLengthMask = 0x3FFF0000, /* Receive descriptor frame length */
-+ descFrameLengthShift = 16,
-+
-+ descError = 0x00008000, /* Error summary bit - OR of the following bits: v */
-+
-+ descRxTruncated = 0x00004000, /* Rx - no more descriptors for receive frame E */
-+
-+ descRxLengthError = 0x00001000, /* Rx - frame size not matching with length field */
-+ descRxDamaged = 0x00000800, /* Rx - frame was damaged due to buffer overflow E */
-+ descRxFirst = 0x00000200, /* Rx - first descriptor of the frame */
-+ descRxLast = 0x00000100, /* Rx - last descriptor of the frame */
-+ descRxLongFrame = 0x00000080, /* Rx - frame is longer than 1518 bytes E */
-+ descRxCollision = 0x00000040, /* Rx - late collision occurred during reception E */
-+ descRxFrameEther = 0x00000020, /* Rx - Frame type - Ethernet, otherwise 802.3 */
-+ descRxWatchdog = 0x00000010, /* Rx - watchdog timer expired during reception E */
-+ descRxMiiError = 0x00000008, /* Rx - error reported by MII interface E */
-+ descRxDribbling = 0x00000004, /* Rx - frame contains noninteger multiple of 8 bits */
-+ descRxCrc = 0x00000002, /* Rx - CRC error E */
-+
-+ descTxTimeout = 0x00004000, /* Tx - Transmit jabber timeout E */
-+ descTxLostCarrier = 0x00000800, /* Tx - carrier lost during tramsmission E */
-+ descTxNoCarrier = 0x00000400, /* Tx - no carrier signal from the tranceiver E */
-+ descTxLateCollision = 0x00000200, /* Tx - transmission aborted due to collision E */
-+ descTxExcCollisions = 0x00000100, /* Tx - transmission aborted after 16 collisions E */
-+ descTxVLANFrame = 0x00000080, /* Tx - VLAN-type frame */
-+ descTxCollMask = 0x00000078, /* Tx - Collision count */
-+ descTxCollShift = 3,
-+ descTxExcDeferral = 0x00000004, /* Tx - excessive deferral E */
-+ descTxUnderflow = 0x00000002, /* Tx - late data arrival from the memory E */
-+ descTxDeferred = 0x00000001, /* Tx - frame transmision deferred */
-+} desc_status_t;
-+
-+/** Descriptor length word field definitions */
-+typedef enum desc_length {
-+ descTxIntEnable = 0x80000000, /* Tx - interrupt on completion */
-+ descTxLast = 0x40000000, /* Tx - Last segment of the frame */
-+ descTxFirst = 0x20000000, /* Tx - First segment of the frame */
-+ descTxDisableCrc = 0x04000000, /* Tx - Add CRC disabled (first segment only) */
-+
-+ descEndOfRing = 0x02000000, /* End of descriptors ring */
-+ descChain = 0x01000000, /* Second buffer address is chain address */
-+ descTxDisablePadd = 0x00800000, /* disable padding, added by - reyaz */
-+
-+ descSize2Mask = 0x003FF800, /* Buffer 2 size */
-+ descSize2Shift = 11,
-+ descSize1Mask = 0x000007FF, /* Buffer 1 size */
-+ descSize1Shift = 0,
-+} desc_length_t;
-+
-+typedef enum rx_desc_status {
-+ RX_DESC_STATUS_OWN_BIT = 31,
-+ RX_DESC_STATUS_AFM_BIT = 30,
-+ RX_DESC_STATUS_FL_BIT = 16,
-+ RX_DESC_STATUS_ES_BIT = 15,
-+ RX_DESC_STATUS_DE_BIT = 14,
-+ RX_DESC_STATUS_SAF_BIT = 13,
-+ RX_DESC_STATUS_LE_BIT = 12,
-+ RX_DESC_STATUS_OE_BIT = 11,
-+ RX_DESC_STATUS_IPC_BIT = 10,
-+ RX_DESC_STATUS_FS_BIT = 9,
-+ RX_DESC_STATUS_LS_BIT = 8,
-+ RX_DESC_STATUS_VLAN_BIT = 7,
-+ RX_DESC_STATUS_LC_BIT = 6,
-+ RX_DESC_STATUS_FT_BIT = 5,
-+ RX_DESC_STATUS_RWT_BIT = 4,
-+ RX_DESC_STATUS_RE_BIT = 3,
-+ RX_DESC_STATUS_DRE_BIT = 2,
-+ RX_DESC_STATUS_CE_BIT = 1,
-+ RX_DESC_STATUS_MAC_BIT = 0
-+} rx_desc_status_t;
-+
-+#define RX_DESC_STATUS_FL_NUM_BITS 14
-+
-+typedef enum rx_desc_length {
-+ RX_DESC_LENGTH_DIC_BIT = 31,
-+ RX_DESC_LENGTH_RER_BIT = 25,
-+ RX_DESC_LENGTH_RCH_BIT = 24,
-+ RX_DESC_LENGTH_RBS2_BIT = 11,
-+ RX_DESC_LENGTH_RBS1_BIT = 0,
-+} rx_desc_length_t;
-+
-+#define RX_DESC_LENGTH_RBS2_NUM_BITS 11
-+#define RX_DESC_LENGTH_RBS1_NUM_BITS 11
-+
-+typedef enum tx_desc_status {
-+ TX_DESC_STATUS_OWN_BIT = 31,
-+ TX_DESC_STATUS_ES_BIT = 15,
-+ TX_DESC_STATUS_JT_BIT = 14,
-+ TX_DESC_STATUS_FF_BIT = 13,
-+ TX_DESC_STATUS_LOC_BIT = 11,
-+ TX_DESC_STATUS_NC_BIT = 10,
-+ TX_DESC_STATUS_LC_BIT = 9,
-+ TX_DESC_STATUS_EC_BIT = 8,
-+ TX_DESC_STATUS_VF_BIT = 7,
-+ TX_DESC_STATUS_CC_BIT = 3,
-+ TX_DESC_STATUS_ED_BIT = 2,
-+ TX_DESC_STATUS_UF_BIT = 1,
-+ TX_DESC_STATUS_DB_BIT = 0
-+} tx_desc_status_t;
-+
-+#define TX_DESC_STATUS_CC_NUM_BITS 4
-+
-+typedef enum tx_desc_length {
-+ TX_DESC_LENGTH_IC_BIT = 31,
-+ TX_DESC_LENGTH_LS_BIT = 30,
-+ TX_DESC_LENGTH_FS_BIT = 29,
-+ TX_DESC_LENGTH_DC_BIT = 26,
-+ TX_DESC_LENGTH_TER_BIT = 25,
-+ TX_DESC_LENGTH_TCH_BIT = 24,
-+ TX_DESC_LENGTH_DP_BIT = 23,
-+ TX_DESC_LENGTH_TBS2_BIT = 11,
-+ TX_DESC_LENGTH_TBS1_BIT = 0
-+} tx_desc_length_t;
-+
-+#define TX_DESC_LENGTH_TBS2_NUM_BITS 11
-+#define TX_DESC_LENGTH_TBS1_NUM_BITS 11
-+
-+/** Return the number of descriptors available for the CPU to fill with new
-+ * packet info */
-+static inline int available_for_write(gmac_desc_list_info_t* desc_list)
-+{
-+ return desc_list->empty_count;
-+}
-+
-+/** Return non-zero if there is a descriptor available with a packet with which
-+ * the GMAC DMA has finished */
-+static inline int tx_available_for_read(gmac_desc_list_info_t* desc_list)
-+{
-+ return desc_list->full_count &&
-+ !((desc_list->base_ptr + desc_list->r_index)->status & (1UL << TX_DESC_STATUS_OWN_BIT));
-+}
-+
-+/** Return non-zero if there is a descriptor available with a packet with which
-+ * the GMAC DMA has finished */
-+static inline int rx_available_for_read(gmac_desc_list_info_t* desc_list)
-+{
-+ return desc_list->full_count &&
-+ !((desc_list->base_ptr + desc_list->r_index)->status & (1UL << RX_DESC_STATUS_OWN_BIT));
-+}
-+
-+/**
-+ * @param A u32 containing the status from a received frame's DMA descriptor
-+ * @return An int which is non-zero if a valid received frame is fully contained
-+ * within the descriptor from whence the status came
-+ */
-+static inline int is_rx_valid(u32 status)
-+{
-+ return !(status & descError) &&
-+ (status & descRxFirst) &&
-+ (status & descRxLast);
-+}
-+
-+static inline int is_rx_dribbling(u32 status)
-+{
-+ return status & descRxDribbling;
-+}
-+
-+static inline u32 get_rx_length(u32 status)
-+{
-+ return (status & descFrameLengthMask) >> descFrameLengthShift;
-+}
-+
-+static inline int is_rx_collision_error(u32 status)
-+{
-+ return status & (descRxDamaged | descRxCollision);
-+}
-+
-+static inline int is_rx_crc_error(u32 status)
-+{
-+ return status & descRxCrc;
-+}
-+
-+static inline int is_rx_frame_error(u32 status)
-+{
-+ return status & descRxDribbling;
-+}
-+
-+static inline int is_rx_length_error(u32 status)
-+{
-+ return status & descRxLengthError;
-+}
-+
-+static inline int is_rx_long_frame(u32 status)
-+{
-+ return status & descRxLongFrame;
-+}
-+
-+static inline int is_tx_valid(u32 status)
-+{
-+ return !(status & descError);
-+}
-+
-+static inline int is_tx_collision_error(u32 status)
-+{
-+ return (status & descTxCollMask) >> descTxCollShift;
-+}
-+
-+static inline int is_tx_aborted(u32 status)
-+{
-+ return status & (descTxLateCollision | descTxExcCollisions);
-+}
-+
-+static inline int is_tx_carrier_error(u32 status)
-+{
-+ return status & (descTxLostCarrier | descTxNoCarrier);
-+}
-+
-+/**
-+ * GMAC private metadata
-+ */
-+static gmac_priv_t priv_data;
-+static gmac_priv_t* priv = &priv_data;
-+
-+/**
-+ * Descriptor list management
-+ */
-+
-+static void init_rx_descriptor(
-+ gmac_dma_desc_t* desc,
-+ int end_of_ring,
-+ int disable_ioc)
-+{
-+ desc->status = 0;
-+ desc->length = 0;
-+ if (disable_ioc) {
-+ desc->length |= (1UL << RX_DESC_LENGTH_DIC_BIT);
-+ }
-+ if (end_of_ring) {
-+ desc->length |= (1UL << RX_DESC_LENGTH_RER_BIT);
-+ }
-+ desc->buffer1 = 0;
-+ desc->buffer2 = 0;
-+ desc->skb = 0;
-+}
-+
-+static void init_tx_descriptor(
-+ gmac_dma_desc_t* desc,
-+ int end_of_ring,
-+ int enable_ioc,
-+ int disable_crc,
-+ int disable_padding)
-+{
-+ desc->status = 0;
-+ desc->length = 0;
-+ if (enable_ioc) {
-+ desc->length |= (1UL << TX_DESC_LENGTH_IC_BIT);
-+ }
-+ if (disable_crc) {
-+ desc->length |= (1UL << TX_DESC_LENGTH_DC_BIT);
-+ }
-+ if (disable_padding) {
-+ desc->length |= (1UL << TX_DESC_LENGTH_DP_BIT);
-+ }
-+ if (end_of_ring) {
-+ desc->length |= (1UL << TX_DESC_LENGTH_TER_BIT);
-+ }
-+ desc->buffer1 = 0;
-+ desc->buffer2 = 0;
-+ desc->skb = 0;
-+}
-+
-+static void init_rx_desc_list(
-+ gmac_desc_list_info_t* desc_list,
-+ gmac_dma_desc_t* base_ptr,
-+ int num_descriptors)
-+{
-+ int i;
-+
-+ desc_list->base_ptr = base_ptr;
-+ desc_list->num_descriptors = num_descriptors;
-+ desc_list->empty_count = num_descriptors;
-+ desc_list->full_count = 0;
-+ desc_list->r_index = 0;
-+ desc_list->w_index = 0;
-+
-+ for (i=0; i < (num_descriptors - 1); i++) {
-+ init_rx_descriptor(base_ptr + i, 0, 0);
-+ }
-+ init_rx_descriptor(base_ptr + i, 1, 0);
-+}
-+
-+static void init_tx_desc_list(
-+ gmac_desc_list_info_t* desc_list,
-+ gmac_dma_desc_t* base_ptr,
-+ int num_descriptors)
-+{
-+ int i;
-+
-+ desc_list->base_ptr = base_ptr;
-+ desc_list->num_descriptors = num_descriptors;
-+ desc_list->empty_count = num_descriptors;
-+ desc_list->full_count = 0;
-+ desc_list->r_index = 0;
-+ desc_list->w_index = 0;
-+
-+ for (i=0; i < (num_descriptors - 1); i++) {
-+ init_tx_descriptor(base_ptr + i, 0, 1, 0, 0);
-+ }
-+ init_tx_descriptor(base_ptr + i, 1, 1, 0, 0);
-+}
-+
-+static void rx_take_ownership(gmac_desc_list_info_t* desc_list)
-+{
-+ int i;
-+ for (i=0; i < desc_list->num_descriptors; i++) {
-+ (desc_list->base_ptr + i)->status &= ~(1UL << RX_DESC_STATUS_OWN_BIT);
-+ }
-+}
-+
-+static void tx_take_ownership(gmac_desc_list_info_t* desc_list)
-+{
-+ int i;
-+ for (i=0; i < desc_list->num_descriptors; i++) {
-+ (desc_list->base_ptr + i)->status &= ~(1UL << TX_DESC_STATUS_OWN_BIT);
-+ }
-+}
-+
-+static int set_tx_descriptor(
-+ gmac_priv_t* priv,
-+ dma_addr_t dma_address,
-+ u32 length,
-+ sk_buff_t* skb)
-+{
-+ int index;
-+ gmac_dma_desc_t* tx;
-+
-+ // Are sufficicent descriptors available for writing by the CPU?
-+ if (!available_for_write(&priv->tx_gmac_desc_list_info)) {
-+ return -1;
-+ }
-+
-+ // Get the index of the next TX descriptor available for writing by the CPU
-+ index = priv->tx_gmac_desc_list_info.w_index;
-+
-+ // Get a pointer to the next TX descriptor available for writing by the CPU
-+ tx = priv->tx_gmac_desc_list_info.base_ptr + index;
-+
-+ // Initialise the TX descriptor length field for the passed single buffer,
-+ // without destroying any fields we wish to be persistent
-+
-+ // No chained second buffer
-+ tx->length &= ~(1UL << TX_DESC_LENGTH_TCH_BIT);
-+ // Single descriptor holds entire packet
-+ tx->length |= ((1UL << TX_DESC_LENGTH_LS_BIT) | (1UL << TX_DESC_LENGTH_FS_BIT));
-+ // Zero the second buffer length field
-+ tx->length &= ~(((1UL << TX_DESC_LENGTH_TBS2_NUM_BITS) - 1) << TX_DESC_LENGTH_TBS2_BIT);
-+ // Zero the first buffer length field
-+ tx->length &= ~(((1UL << TX_DESC_LENGTH_TBS1_NUM_BITS) - 1) << TX_DESC_LENGTH_TBS1_BIT);
-+ // Fill in the first buffer length
-+ tx->length |= (length << TX_DESC_LENGTH_TBS1_BIT);
-+
-+ // Initialise the first buffer pointer to the single passed buffer
-+ tx->buffer1 = dma_address;
-+
-+ // Remember the socket buffer associated with the single passed buffer
-+ tx->skb = (u32)skb;
-+
-+ // Update the index of the next descriptor available for writing by the CPU
-+ priv->tx_gmac_desc_list_info.w_index = (tx->length & (1UL << TX_DESC_LENGTH_TER_BIT)) ? 0 : index + 1;
-+
-+ // make sure all memory updates are complete before releasing the GMAC on the data.
-+ wmb();
-+
-+ // Hand TX descriptor to the GMAC DMA by setting the status bit.
-+ tx->status = (1UL << TX_DESC_STATUS_OWN_BIT);
-+
-+ // Account for the number of descriptors used to hold the new packet
-+ --priv->tx_gmac_desc_list_info.empty_count;
-+ ++priv->tx_gmac_desc_list_info.full_count;
-+
-+ return index;
-+}
-+
-+static int get_tx_descriptor(
-+ gmac_priv_t* priv,
-+ u32* status,
-+ dma_addr_t* dma_address,
-+ u32* length,
-+ sk_buff_t** skb)
-+{
-+ int index;
-+ gmac_dma_desc_t *tx;
-+
-+ // Is there at least one descriptor with which the GMAC DMA has finished?
-+ if (!tx_available_for_read(&priv->tx_gmac_desc_list_info)) {
-+ return -1;
-+ }
-+
-+ // Get the index of the descriptor released the longest time ago by the
-+ // GMAC DMA
-+ index = priv->tx_gmac_desc_list_info.r_index;
-+
-+ // Get a pointer to the descriptor released the longest time ago by the
-+ // GMAC DMA
-+ tx = priv->tx_gmac_desc_list_info.base_ptr + index;
-+
-+ // Extract the status field
-+ if (status) {
-+ *status = tx->status;
-+ }
-+
-+ // Extract the length field - only cope with the first buffer associated
-+ // with the descriptor
-+ if (length) {
-+ *length = (tx->length >> TX_DESC_LENGTH_TBS1_BIT) &
-+ ((1UL << TX_DESC_LENGTH_TBS1_NUM_BITS) - 1);
-+ }
-+
-+ // Extract the pointer to the buffer containing the packet - only cope with
-+ // the first buffer associated with the descriptor
-+ if (dma_address) {
-+ *dma_address = tx->buffer1;
-+ }
-+
-+ // Extract the pointer to the socket buffer associated with the packet
-+ if (skb) {
-+ *skb = (sk_buff_t*)(tx->skb);
-+ }
-+
-+ // Update the index of the next descriptor with which the GMAC DMA may have
-+ // finished
-+ priv->tx_gmac_desc_list_info.r_index = (tx->length & (1UL << TX_DESC_LENGTH_TER_BIT)) ? 0 : index + 1;
-+
-+ // Account for the number of descriptors freed to hold new packets
-+ ++priv->tx_gmac_desc_list_info.empty_count;
-+ --priv->tx_gmac_desc_list_info.full_count;
-+
-+ return index;
-+}
-+
-+int set_rx_descriptor(
-+ gmac_priv_t* priv,
-+ dma_addr_t dma_address,
-+ u32 length,
-+ sk_buff_t* skb)
-+{
-+ int index;
-+ gmac_dma_desc_t* rx;
-+ int num_descriptors_required;
-+
-+ // Currently only support using a single descriptor to describe each packet
-+ // queued with the GMAc DMA
-+ num_descriptors_required = 1;
-+
-+ // Are sufficicent descriptors available for writing by the CPU?
-+ if (available_for_write(&priv->rx_gmac_desc_list_info) < num_descriptors_required) {
-+ index = -1;
-+ } else {
-+ // Get the index of the next RX descriptor available for writing by the CPU
-+ index = priv->rx_gmac_desc_list_info.w_index;
-+
-+ // Get a pointer to the next RX descriptor available for writing by the CPU
-+ rx = priv->rx_gmac_desc_list_info.base_ptr + index;
-+
-+ // Initialise the RX descriptor length field for the passed single buffer,
-+ // without destroying any fields we wish to be persistent
-+
-+ // No chained second buffer
-+ rx->length &= ~(1UL << RX_DESC_LENGTH_RCH_BIT);
-+ // Zero the second buffer length field
-+ rx->length &= ~(((1UL << RX_DESC_LENGTH_RBS2_NUM_BITS) - 1) << RX_DESC_LENGTH_RBS2_BIT);
-+ // Zero the first buffer length field
-+ rx->length &= ~(((1UL << RX_DESC_LENGTH_RBS1_NUM_BITS) - 1) << RX_DESC_LENGTH_RBS1_BIT);
-+ // Fill in the first buffer length
-+ rx->length |= (length << RX_DESC_LENGTH_RBS1_BIT);
-+
-+ // Initialise the first buffer pointer to the single passed buffer
-+ rx->buffer1 = dma_address;
-+
-+ // Remember the socket buffer associated with the single passed buffer
-+ rx->skb = (u32)skb;
-+
-+ wmb();
-+
-+ // Initialise RX descriptor status to be owned by the GMAC DMA
-+ rx->status = (1UL << RX_DESC_STATUS_OWN_BIT);
-+
-+ // Update the index of the next descriptor available for writing by the CPU
-+ priv->rx_gmac_desc_list_info.w_index = (rx->length & (1UL << RX_DESC_LENGTH_RER_BIT)) ? 0 : index + 1;
-+
-+ // Account for the number of descriptors used to hold the new packet
-+ priv->rx_gmac_desc_list_info.empty_count -= num_descriptors_required;
-+ priv->rx_gmac_desc_list_info.full_count += num_descriptors_required;
-+ }
-+
-+ return index;
-+}
-+
-+int get_rx_descriptor(
-+ gmac_priv_t* priv,
-+ u32* status,
-+ dma_addr_t* dma_address,
-+ u32* length,
-+ sk_buff_t** skb)
-+{
-+ int index;
-+ gmac_dma_desc_t *rx;
-+ int num_descriptors_required;
-+
-+ // Is there at least one descriptor with which the GMAC DMA has finished?
-+ if (!rx_available_for_read(&priv->rx_gmac_desc_list_info)) {
-+ return -1;
-+ }
-+
-+ // Currently can only cope with packets entirely contained within a single
-+ // descriptor
-+ num_descriptors_required = 1;
-+
-+ // Get the index of the descriptor released the longest time ago by the
-+ // GMAC DMA
-+ index = priv->rx_gmac_desc_list_info.r_index;
-+
-+ // Get a pointer to the descriptor released the longest time ago by the
-+ // GMAC DMA
-+ rx = priv->rx_gmac_desc_list_info.base_ptr + index;
-+
-+ // Extract the status field
-+ if (status) {
-+ *status = rx->status;
-+ }
-+
-+ // Extract the length field - only cope with the first buffer associated
-+ // with the descriptor
-+ if (length) {
-+ *length = (rx->length >> RX_DESC_LENGTH_RBS1_BIT) &
-+ ((1UL << RX_DESC_LENGTH_RBS1_NUM_BITS) - 1);
-+ }
-+
-+ // Extract the pointer to the buffer containing the packet - only cope with
-+ // the first buffer associated with the descriptor
-+ if (dma_address) {
-+ *dma_address = rx->buffer1;
-+ }
-+
-+ // Extract the pointer to the socket buffer associated with the packet
-+ if (skb) {
-+ *skb = (sk_buff_t*)(rx->skb);
-+ }
-+
-+ wmb();
-+ // Update the index of the next descriptor with which the GMAC DMA may have
-+ // finished
-+ priv->rx_gmac_desc_list_info.r_index = (rx->length & (1UL << RX_DESC_LENGTH_RER_BIT)) ? 0 : index + 1;
-+
-+ // Account for the number of descriptors freed to hold new packets
-+ priv->rx_gmac_desc_list_info.empty_count += num_descriptors_required;
-+ priv->rx_gmac_desc_list_info.full_count -= num_descriptors_required;
-+
-+ return index;
-+}
-+
-+/**
-+ * GMAC register access functions
-+ */
-+
-+/**
-+ * MAC register access functions
-+ */
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the MAC register to access
-+ */
-+static inline u32 mac_reg_read(gmac_priv_t* priv, int reg_num)
-+{
-+ return *(volatile u32*)(priv->macBase + (reg_num << 2));
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the MAC register to access
-+ */
-+static inline void mac_reg_write(gmac_priv_t* priv, int reg_num, u32 value)
-+{
-+ *(volatile u32*)(priv->macBase + (reg_num << 2)) = value;
-+
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the MAC register to access
-+ * @param bits_to_clear A u32 specifying which bits of the specified register to
-+ * clear. A set bit in this parameter will cause the matching bit in the
-+ * register to be cleared
-+ */
-+static inline void mac_reg_clear_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_clear)
-+{
-+ mac_reg_write(priv, reg_num, mac_reg_read(priv, reg_num) & ~bits_to_clear);
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the MAC register to access
-+ * @param bits_to_set A u32 specifying which bits of the specified register to
-+ * set. A set bit in this parameter will cause the matching bit in the register
-+ * to be set
-+ */
-+static inline void mac_reg_set_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_set)
-+{
-+ mac_reg_write(priv, reg_num, mac_reg_read(priv, reg_num) | bits_to_set);
-+}
-+
-+
-+/**
-+ * DMA register access functions
-+ */
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the DMA register to access
-+ */
-+static inline u32 dma_reg_read(gmac_priv_t* priv, int reg_num)
-+{
-+ return *(volatile u32*)(priv->dmaBase + (reg_num << 2));
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the DMA register to access
-+ */
-+static inline void dma_reg_write(gmac_priv_t* priv, int reg_num, u32 value)
-+{
-+ *(volatile u32*)(priv->dmaBase + (reg_num << 2)) = value;
-+ wmb();
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the DMA register to access
-+ * @param bits_to_clear A u32 specifying which bits of the specified register to
-+ * clear. A set bit in this parameter will cause the matching bit in the
-+ * register to be cleared
-+ * @return An u32 containing the new value written to the register
-+ */
-+static inline u32 dma_reg_clear_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_clear)
-+{
-+ u32 new_value = dma_reg_read(priv, reg_num) & ~bits_to_clear;
-+ dma_reg_write(priv, reg_num, new_value);
-+ return new_value;
-+}
-+
-+/**
-+ * @param priv A gmac_priv_t* pointing to private device data
-+ * @param reg_num An int specifying the index of the DMA register to access
-+ * @param bits_to_set A u32 specifying which bits of the specified register to
-+ * set. A set bit in this parameter will cause the matching bit in the register
-+ * to be set
-+ * @return An u32 containing the new value written to the register
-+ */
-+static inline u32 dma_reg_set_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_set)
-+{
-+ u32 new_value = dma_reg_read(priv, reg_num) | bits_to_set;
-+ dma_reg_write(priv, reg_num, new_value);
-+ return new_value;
-+}
-+
-+static void eth_down(void)
-+{
-+ // Stop transmitter, take ownership of all tx descriptors
-+ dma_reg_clear_mask(priv, DMA_OP_MODE_REG, DMA_OP_MODE_ST_BIT);
-+ if (priv->desc_base_addr) {
-+ tx_take_ownership(&priv->tx_gmac_desc_list_info);
-+ }
-+
-+ // Stop receiver, take ownership of all rx descriptors
-+ dma_reg_clear_mask(priv, DMA_OP_MODE_REG, DMA_OP_MODE_SR_BIT);
-+ if (priv->desc_base_addr) {
-+ rx_take_ownership(&priv->rx_gmac_desc_list_info);
-+ }
-+
-+ // Free descriptor resources. The TX descriptor will not have a packet
-+ // buffer attached, as this is provided by the stack when transmission is
-+ // required and ownership is not retained by the descriptor, as the stack
-+ // waits for transmission to complete via polling
-+ if (priv->desc_base_addr) {
-+ // Free receive descriptors, accounting for buffer offset used to
-+ // ensure IP header alignment
-+ while (1) {
-+ dma_addr_t dma_address;
-+ if (get_rx_descriptor(priv, 0, &dma_address, 0, 0) < 0) {
-+ break;
-+ }
-+ free((void*)(dma_address - ETHER_FRAME_ALIGN_WASTAGE));
-+ }
-+
-+ // Free DMA descriptors' storage
-+ free(priv->desc_base_addr);
-+
-+ // Remember that we've freed the descriptors memory
-+ priv->desc_base_addr = 0;
-+ }
-+}
-+
-+/*
-+ * Reads a register from the MII Management serial interface
-+ */
-+int phy_read(int phyaddr, int phyreg)
-+{
-+ int data = 0;
-+ u32 addr = (phyaddr << MAC_GMII_ADR_PA_BIT) |
-+ (phyreg << MAC_GMII_ADR_GR_BIT) |
-+ (5 << MAC_GMII_ADR_CR_BIT) |
-+ (1UL << MAC_GMII_ADR_GB_BIT);
-+
-+ mac_reg_write(priv, MAC_GMII_ADR_REG, addr);
-+
-+ for (;;) {
-+ if (!(mac_reg_read(priv, MAC_GMII_ADR_REG) & (1UL << MAC_GMII_ADR_GB_BIT))) {
-+ // Successfully read from PHY
-+ data = mac_reg_read(priv, MAC_GMII_DATA_REG) & 0xFFFF;
-+ break;
-+ }
-+ }
-+
-+#ifdef DEBUG_GMAC_INIT
-+ printf("phy_read() phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", phyaddr, phyreg, data);
-+#endif // DEBUG_GMAC_INIT
-+
-+ return data;
-+}
-+
-+/*
-+ * Writes a register to the MII Management serial interface
-+ */
-+void phy_write(int phyaddr, int phyreg, int phydata)
-+{
-+ u32 addr = (phyaddr << MAC_GMII_ADR_PA_BIT) |
-+ (phyreg << MAC_GMII_ADR_GR_BIT) |
-+ (5 << MAC_GMII_ADR_CR_BIT) |
-+ (1UL << MAC_GMII_ADR_GW_BIT) |
-+ (1UL << MAC_GMII_ADR_GB_BIT);
-+
-+ mac_reg_write(priv, MAC_GMII_DATA_REG, phydata);
-+ mac_reg_write(priv, MAC_GMII_ADR_REG, addr);
-+
-+ for (;;) {
-+ if (!(mac_reg_read(priv, MAC_GMII_ADR_REG) & (1UL << MAC_GMII_ADR_GB_BIT))) {
-+ break;
-+ }
-+ }
-+
-+#ifdef DEBUG_GMAC_INIT
-+ printf("phy_write() phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", phyaddr, phyreg, phydata);
-+#endif // DEBUG_GMAC_INIT
-+}
-+
-+/*
-+ * Finds and reports the PHY address
-+ */
-+int phy_detect(void)
-+{
-+ int found = 0;
-+ int phyaddr;
-+
-+ // Scan all 32 PHY addresses if necessary
-+ priv->phy_type = 0;
-+ for (phyaddr = 1; phyaddr < 33; ++phyaddr) {
-+ unsigned int id1, id2;
-+
-+ // Read the PHY identifiers
-+ id1 = phy_read(phyaddr & 31, MII_PHYSID1);
-+ id2 = phy_read(phyaddr & 31, MII_PHYSID2);
-+
-+#ifdef DEBUG_GMAC_INIT
-+ printf("phy_detect() PHY adr = %u -> phy_id1=0x%x, phy_id2=0x%x\n", phyaddr, id1, id2);
-+#endif // DEBUG_GMAC_INIT
-+
-+ // Make sure it is a valid identifier
-+ if (id1 != 0x0000 && id1 != 0xffff && id1 != 0x8000 &&
-+ id2 != 0x0000 && id2 != 0xffff && id2 != 0x8000) {
-+#ifdef DEBUG_GMAC_INIT
-+ printf("phy_detect() Found PHY at address = %u\n", phyaddr);
-+#endif // DEBUG_GMAC_INIT
-+
-+ priv->phy_id = phyaddr & 31;
-+ priv->phy_type = id1 << 16 | id2;
-+ priv->phy_addr = phyaddr;
-+
-+ found = 1;
-+ break;
-+ }
-+ }
-+
-+ return found;
-+}
-+
-+void start_phy_reset(void)
-+{
-+ // Ask the PHY to reset
-+ phy_write(priv->phy_addr, MII_BMCR, BMCR_RESET);
-+}
-+
-+int is_phy_reset_complete(void)
-+{
-+ int complete = 0;
-+ int bmcr;
-+
-+ // Read back the status until it indicates reset, or we timeout
-+ bmcr = phy_read(priv->phy_addr, MII_BMCR);
-+ if (!(bmcr & BMCR_RESET)) {
-+ complete = 1;
-+ }
-+
-+ return complete;
-+}
-+
-+void set_phy_type_rgmii(void)
-+{
-+ // Use sysctrl to switch MAC link lines into either (G)MII or RGMII mode
-+ *(volatile u32*)SYS_CTRL_GMAC_CTRL |= (1UL << SYS_CTRL_GMAC_RGMII);
-+}
-+
-+void phy_initialise(void)
-+{
-+ switch (priv->phy_type) {
-+ case PHY_TYPE_VITESSE_VSC8201XVZ:
-+ {
-+ // Allow s/w to override mode/duplex pin settings
-+ u32 acsr = phy_read(priv->phy_id, VSC8201_MII_ACSR);
-+
-+ printf("PHY is Vitesse VSC8201XVZ\n");
-+ acsr |= (1UL << VSC8201_MII_ACSR_MDPPS_BIT);
-+ phy_write(priv->phy_id, VSC8201_MII_ACSR, acsr);
-+ }
-+ break;
-+ case PHY_TYPE_REALTEK_RTL8211BGR:
-+ printf("PHY is Realtek RTL8211BGR\n");
-+ set_phy_type_rgmii();
-+ break;
-+ case PHY_TYPE_LSI_ET1011C:
-+ {
-+ u32 phy_reg;
-+
-+ printf("PHY is LSI ET1011C\n");
-+
-+ // Configure clocks
-+ phy_reg = phy_read(priv->phy_id, ET1011C_MII_CONFIG);
-+ phy_reg &= ~(((1UL << ET1011C_MII_CONFIG_IFMODESEL_NUM_BITS) - 1) << ET1011C_MII_CONFIG_IFMODESEL);
-+ phy_reg |= (ET1011C_MII_CONFIG_IFMODESEL_GMII_MII << ET1011C_MII_CONFIG_IFMODESEL);
-+ phy_reg |= ((1UL << ET1011C_MII_CONFIG_SYSCLKEN) |
-+ (1UL << ET1011C_MII_CONFIG_TXCLKEN) |
-+ (1UL << ET1011C_MII_CONFIG_TBI_RATESEL) |
-+ (1UL << ET1011C_MII_CONFIG_CRS_TX_EN));
-+ phy_write(priv->phy_id, ET1011C_MII_CONFIG, phy_reg);
-+
-+ // Enable Tx/Rx LED
-+ phy_reg = phy_read(priv->phy_id, ET1011C_MII_LED2);
-+ phy_reg &= ~(((1UL << ET1011C_MII_LED2_LED_NUM_BITS) - 1) << ET1011C_MII_LED2_LED_TXRX);
-+ phy_reg |= (ET1011C_MII_LED2_LED_TXRX_ACTIVITY << ET1011C_MII_LED2_LED_TXRX);
-+ phy_write(priv->phy_id, ET1011C_MII_LED2, phy_reg);
-+ }
-+ break;
-+ }
-+}
-+
-+int detect_link_speed(void)
-+{
-+ u32 lpa2 = phy_read(priv->phy_id, MII_STAT1000);
-+
-+ if (((lpa2 & LPA_1000FULL)) ||
-+ ((lpa2 & LPA_1000HALF))) {
-+ priv->link_is_1000M = 1;
-+ } else {
-+ priv->link_is_1000M = 0;
-+ }
-+
-+ return 0;
-+}
-+
-+int is_autoneg_complete(void)
-+{
-+ return phy_read(priv->phy_addr, MII_BMSR) & BMSR_ANEGCOMPLETE;
-+}
-+
-+int is_link_ok(void)
-+{
-+ return phy_read(priv->phy_id, MII_BMSR) & BMSR_LSTATUS;
-+}
-+
-+int eth_init(bd_t *bd)
-+{
-+ u32 version;
-+ u32 reg_contents;
-+ u8 *mac_addr;
-+ int desc;
-+
-+ // Set hardware device base addresses
-+ priv->macBase = (MAC_BASE_PA + MAC_BASE_OFFSET);
-+ priv->dmaBase = (MAC_BASE_PA + DMA_BASE_OFFSET);
-+
-+#ifdef DEBUG_GMAC_INIT
-+ printf("eth_init(): About to reset MAC core\n");
-+#endif // DEBUG_GMAC_INIT
-+ // Ensure the MAC block is properly reset
-+ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_MAC_BIT);
-+ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_MAC_BIT);
-+
-+ // Enable the clock to the MAC block
-+ *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_MAC_BIT);
-+
-+ version = mac_reg_read(priv, MAC_VERSION_REG);
-+#ifdef DEBUG_GMAC_INIT
-+ printf("eth_init(): GMAC Synopsis version = 0x%x, vendor version = 0x%x\n", version & 0xff, (version >> 8) & 0xff);
-+#endif // DEBUG_GMAC_INIT
-+
-+ // Use simple mux for 25/125 Mhz clock switching
-+ *(volatile u32*)SYS_CTRL_GMAC_CTRL |= (1UL << SYS_CTRL_GMAC_SIMPLE_MAX);
-+
-+ // Enable GMII_GTXCLK to follow GMII_REFCLK - required for gigabit PHY
-+ *(volatile u32*)SYS_CTRL_GMAC_CTRL |= (1UL << SYS_CTRL_GMAC_CKEN_GTX);
-+
-+ // Disable all GMAC interrupts
-+ dma_reg_write(priv, DMA_INT_ENABLE_REG, 0);
-+
-+ // Reset the entire GMAC
-+ dma_reg_write(priv, DMA_BUS_MODE_REG, 1UL << DMA_BUS_MODE_SWR_BIT);
-+
-+ // Wait for the reset operation to complete
-+ printf("Wait GMAC to reset");
-+ while (dma_reg_read(priv, DMA_BUS_MODE_REG) & (1UL << DMA_BUS_MODE_SWR_BIT)) {
-+ udelay(250000);
-+ printf(".");
-+ }
-+ printf("\n");
-+
-+ // Attempt to discover link speed from the PHY
-+ if (!phy_detect()) {
-+ printf("No PHY found\n");
-+ } else {
-+ // Ensure the PHY is in a sensible state by resetting it
-+ start_phy_reset();
-+
-+ // Read back the status until it indicates reset, or we timeout
-+ printf("Wait for PHY reset");
-+ while (!is_phy_reset_complete()) {
-+ udelay(250000);
-+ printf(".");
-+ }
-+ printf("\n");
-+
-+ // Setup the PHY based on its type
-+ phy_initialise();
-+
-+ printf("Wait for link to come up");
-+ while (!is_link_ok()) {
-+ udelay(250000);
-+ printf(".");
-+ }
-+ printf("Link up\n");
-+
-+ // Wait for PHY to have completed autonegotiation
-+ printf("Wait for auto-negotiation to complete");
-+ while (!is_autoneg_complete()) {
-+ udelay(250000);
-+ printf(".");
-+ }
-+ printf("\n");
-+
-+ // Interrogate the PHY for the link speed
-+ if (detect_link_speed()) {
-+ printf("Failed to detect link speed\n");
-+ } else {
-+ printf("Link is %s\n", priv->link_is_1000M ? "1000M" : "10M/100M");
-+ }
-+ }
-+
-+ // Form the MAC config register contents
-+ reg_contents = 0;
-+ if (!priv->link_is_1000M) {
-+ reg_contents |= (1UL << MAC_CONFIG_PS_BIT); // Gigabit
-+ }
-+ reg_contents |= (1UL << MAC_CONFIG_DM_BIT); // Full duplex
-+ reg_contents |= ((1UL << MAC_CONFIG_TE_BIT) |
-+ (1UL << MAC_CONFIG_RE_BIT));
-+ mac_reg_write(priv, MAC_CONFIG_REG, reg_contents);
-+
-+ // Form the MAC frame filter register contents
-+ reg_contents = 0;
-+ mac_reg_write(priv, MAC_FRAME_FILTER_REG, reg_contents);
-+
-+ // Form the hash table registers contents
-+ mac_reg_write(priv, MAC_HASH_HIGH_REG, 0);
-+ mac_reg_write(priv, MAC_HASH_LOW_REG, 0);
-+
-+ // Form the MAC flow control register contents
-+ reg_contents = 0;
-+ reg_contents |= ((1UL << MAC_FLOW_CNTL_RFE_BIT) |
-+ (1UL << MAC_FLOW_CNTL_TFE_BIT));
-+ mac_reg_write(priv, MAC_FLOW_CNTL_REG, reg_contents);
-+
-+ // Form the MAC VLAN tag register contents
-+ reg_contents = 0;
-+ mac_reg_write(priv, MAC_VLAN_TAG_REG, reg_contents);
-+
-+ // Form the MAC addr0 high and low registers contents from the character
-+ // string representation from the environment
-+ mac_addr = getenv("ethaddr");
-+#ifdef DEBUG_GMAC_INIT
-+ printf("eth_init(): Mac addr = %s\n", mac_addr);
-+#endif // DEBUG_GMAC_INIT
-+ reg_contents = simple_strtoul(mac_addr+0, 0, 16);
-+ reg_contents |= (simple_strtoul(mac_addr+3, 0, 16) << 8);
-+ reg_contents |= (simple_strtoul(mac_addr+6, 0, 16) << 16);
-+ reg_contents |= (simple_strtoul(mac_addr+9, 0, 16) << 24);
-+ mac_reg_write(priv, MAC_ADR0_LOW_REG, reg_contents);
-+ reg_contents = simple_strtoul(mac_addr+12, 0, 16);
-+ reg_contents |= (simple_strtoul(mac_addr+15, 0, 16) << 8);
-+ mac_reg_write(priv, MAC_ADR0_HIGH_REG, reg_contents);
-+
-+ // Disable all MMC interrupt sources
-+ mac_reg_write(priv, MMC_RX_MASK_REG, ~0UL);
-+ mac_reg_write(priv, MMC_TX_MASK_REG, ~0UL);
-+
-+ // Remember how large the unified descriptor array is to be
-+ priv->total_num_descriptors = NUM_RX_DMA_DESCRIPTORS + NUM_TX_DMA_DESCRIPTORS;
-+
-+ // Need a consistent DMA mapping covering all the memory occupied by DMA
-+ // unified descriptor array, as both CPU and DMA engine will be reading and
-+ // writing descriptor fields.
-+ priv->desc_base_addr = (gmac_dma_desc_t*)malloc(sizeof(gmac_dma_desc_t) * priv->total_num_descriptors);
-+ if (!priv->desc_base_addr) {
-+ printf("eth_init(): Failed to allocate memory for DMA descriptors\n");
-+ goto err_out;
-+ }
-+
-+ // Initialise the structures managing the TX descriptor list
-+ init_tx_desc_list(&priv->tx_gmac_desc_list_info,
-+ priv->desc_base_addr,
-+ NUM_TX_DMA_DESCRIPTORS);
-+
-+ // Initialise the structures managing the RX descriptor list
-+ init_rx_desc_list(&priv->rx_gmac_desc_list_info,
-+ priv->desc_base_addr + NUM_TX_DMA_DESCRIPTORS,
-+ priv->total_num_descriptors - NUM_TX_DMA_DESCRIPTORS);
-+
-+ // Prepare receive descriptors
-+ desc = 0;
-+ while (available_for_write(&priv->rx_gmac_desc_list_info)) {
-+ // Allocate a new buffer for the descriptor which is large enough for
-+ // any packet received from the link
-+ dma_addr_t dma_address = (dma_addr_t)malloc(ETHER_MTU + ETHER_FRAME_ALIGN_WASTAGE + EXTRA_RX_SKB_SPACE);
-+ if (!dma_address) {
-+ printf("eth_init(): No memory for socket buffer\n");
-+ break;
-+ }
-+
-+ desc = set_rx_descriptor(priv,
-+ dma_address + ETHER_FRAME_ALIGN_WASTAGE,
-+ ETHER_MTU + EXTRA_RX_SKB_SPACE,
-+ 0);
-+
-+ if (desc < 0) {
-+ // Release the buffer
-+ free((void*)dma_address);
-+
-+ printf("eth_init(): Error, no RX descriptor available\n");
-+ goto err_out;
-+ }
-+ }
-+
-+ // Initialise the GMAC DMA bus mode register
-+ dma_reg_write(priv, DMA_BUS_MODE_REG, ((0UL << DMA_BUS_MODE_FB_BIT) |
-+ (0UL << DMA_BUS_MODE_PR_BIT) |
-+ (32UL << DMA_BUS_MODE_PBL_BIT) | // AHB burst size
-+ (1UL << DMA_BUS_MODE_DSL_BIT) |
-+ (0UL << DMA_BUS_MODE_DA_BIT)));
-+
-+ // Write the address of the start of the tx descriptor array
-+ dma_reg_write(priv, DMA_TX_DESC_ADR_REG, (u32)priv->desc_base_addr);
-+
-+ // Write the address of the start of the rx descriptor array
-+ dma_reg_write(priv, DMA_RX_DESC_ADR_REG,
-+ (u32)(priv->desc_base_addr + priv->tx_gmac_desc_list_info.num_descriptors));
-+
-+ // Clear any pending interrupt requests
-+ dma_reg_write(priv, DMA_STATUS_REG, dma_reg_read(priv, DMA_STATUS_REG));
-+
-+ // Initialise the GMAC DMA operation mode register, starting both the
-+ // transmitter and receiver
-+ dma_reg_write(priv, DMA_OP_MODE_REG, ((1UL << DMA_OP_MODE_SF_BIT) | // Store and forward
-+ (0UL << DMA_OP_MODE_TTC_BIT) | // Tx threshold
-+ (1UL << DMA_OP_MODE_ST_BIT) | // Enable transmitter
-+ (0UL << DMA_OP_MODE_RTC_BIT) | // Rx threshold
-+ (1UL << DMA_OP_MODE_SR_BIT))); // Enable receiver
-+
-+ // Success
-+ return 1;
-+
-+err_out:
-+ eth_down();
-+
-+ return 0;
-+}
-+
-+void eth_halt(void)
-+{
-+ eth_down();
-+
-+ // Disable the clock to the MAC block
-+ *(volatile u32*)(SYS_CTRL_CKEN_CLR_CTRL) = (1UL << SYS_CTRL_CKEN_MAC_BIT);
-+}
-+
-+int eth_rx(void)
-+{
-+ static const int MAX_LOOPS = 2000; // 2 seconds
-+
-+ int length = 0;
-+ dma_addr_t dma_address;
-+ u32 desc_status;
-+ int loops = 0;
-+
-+ // Look for the first available received packet
-+ while (loops++ < MAX_LOOPS) {
-+ if (get_rx_descriptor(priv, &desc_status, &dma_address, 0, 0) >= 0) {
-+ if (is_rx_valid(desc_status)) {
-+ // Get the length of the packet within the buffer
-+ length = get_rx_length(desc_status);
-+
-+ // Pass packet up the network stack - will block until processing is
-+ // completed
-+ NetReceive((uchar*)dma_address, length);
-+ } else {
-+ printf("eth_rx() Received packet has bad desc_status = 0x%08x\n", desc_status);
-+ }
-+
-+ // Re-initialise the RX descriptor with its buffer - relies on always
-+ // setting an RX descriptor directly after getting it
-+ if (set_rx_descriptor(priv, dma_address, ETHER_MTU + EXTRA_RX_SKB_SPACE, 0) < 0) {
-+ printf("eth_rx(): Failed to set RX descriptor\n");
-+ }
-+
-+ break;
-+ }
-+
-+ // Wait a bit before trying again to get a descriptor
-+ udelay(1000); // 1mS
-+ }
-+
-+ return length;
-+}
-+
-+int eth_send(volatile void *packet, int length)
-+{
-+ // Transmit the new packet
-+ while (1) {
-+ // Get the TX descriptor
-+ if (set_tx_descriptor(priv, (dma_addr_t)packet, length, 0) >= 0) {
-+ // Tell the GMAC to poll for the updated descriptor
-+ dma_reg_write(priv, DMA_TX_POLL_REG, 0);
-+ break;
-+ }
-+
-+ // Wait a bit before trying again to get a descriptor
-+ udelay(1000); // 1mS
-+ }
-+
-+ // Wait for the packet buffer to be finished with
-+ while (get_tx_descriptor(priv, 0, 0, 0, 0) < 0) {
-+ // Wait a bit before examining the descriptor again
-+ udelay(1000); // 1mS
-+ }
-+
-+ return length;
-+}
-+
-diff -Nurd u-boot-1.1.2/board/oxnas/ide-810.c u-boot-1.1.2-oxe810/board/oxnas/ide-810.c
---- u-boot-1.1.2/board/oxnas/ide-810.c 1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/board/oxnas/ide-810.c 2008-06-11 17:55:18.000000000 +0200
-@@ -0,0 +1,892 @@
-+/*
-+ * (C) Copyright 2005
-+ * Oxford Semiconductor Ltd
-+ *
-+ * See file CREDITS for list of people who contributed to this
-+ * project.
-+ *
-+ * 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 <common.h>
-+
-+#define SATA_DMA_CHANNEL 0
-+
-+#define DMA_CTRL_STATUS (0x0)
-+#define DMA_BASE_SRC_ADR (0x4)
-+#define DMA_BASE_DST_ADR (0x8)
-+#define DMA_BYTE_CNT (0xC)
-+#define DMA_CURRENT_SRC_ADR (0x10)
-+#define DMA_CURRENT_DST_ADR (0x14)
-+#define DMA_CURRENT_BYTE_CNT (0x18)
-+#define DMA_INTR_ID (0x1C)
-+#define DMA_INTR_CLEAR_REG (DMA_CURRENT_SRC_ADR)
-+
-+#define DMA_CALC_REG_ADR(channel, register) ((volatile u32*)(DMA_BASE_PA + ((channel) << 5) + (register)))
-+
-+#define DMA_CTRL_STATUS_FAIR_SHARE_ARB (1 << 0)
-+#define DMA_CTRL_STATUS_IN_PROGRESS (1 << 1)
-+#define DMA_CTRL_STATUS_SRC_DREQ_MASK (0x0000003C)
-+#define DMA_CTRL_STATUS_SRC_DREQ_SHIFT (2)
-+#define DMA_CTRL_STATUS_DEST_DREQ_MASK (0x000003C0)
-+#define DMA_CTRL_STATUS_DEST_DREQ_SHIFT (6)
-+#define DMA_CTRL_STATUS_INTR (1 << 10)
-+#define DMA_CTRL_STATUS_NXT_FREE (1 << 11)
-+#define DMA_CTRL_STATUS_RESET (1 << 12)
-+#define DMA_CTRL_STATUS_DIR_MASK (0x00006000)
-+#define DMA_CTRL_STATUS_DIR_SHIFT (13)
-+#define DMA_CTRL_STATUS_SRC_ADR_MODE (1 << 15)
-+#define DMA_CTRL_STATUS_DEST_ADR_MODE (1 << 16)
-+#define DMA_CTRL_STATUS_TRANSFER_MODE_A (1 << 17)
-+#define DMA_CTRL_STATUS_TRANSFER_MODE_B (1 << 18)
-+#define DMA_CTRL_STATUS_SRC_WIDTH_MASK (0x00380000)
-+#define DMA_CTRL_STATUS_SRC_WIDTH_SHIFT (19)
-+#define DMA_CTRL_STATUS_DEST_WIDTH_MASK (0x01C00000)
-+#define DMA_CTRL_STATUS_DEST_WIDTH_SHIFT (22)
-+#define DMA_CTRL_STATUS_PAUSE (1 << 25)
-+#define DMA_CTRL_STATUS_INTERRUPT_ENABLE (1 << 26)
-+#define DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED (1 << 27)
-+#define DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED (1 << 28)
-+#define DMA_CTRL_STATUS_STARVE_LOW_PRIORITY (1 << 29)
-+#define DMA_CTRL_STATUS_INTR_CLEAR_ENABLE (1 << 30)
-+
-+#define DMA_BYTE_CNT_MASK ((1 << 21) - 1)
-+#define DMA_BYTE_CNT_WR_EOT_MASK (1 << 30)
-+#define DMA_BYTE_CNT_RD_EOT_MASK (1 << 31)
-+
-+#define MAKE_FIELD(value, num_bits, bit_num) (((value) & ((1 << (num_bits)) - 1)) << (bit_num))
-+
-+typedef enum oxnas_dma_mode {
-+ OXNAS_DMA_MODE_FIXED,
-+ OXNAS_DMA_MODE_INC
-+} oxnas_dma_mode_t;
-+
-+typedef enum oxnas_dma_direction {
-+ OXNAS_DMA_TO_DEVICE,
-+ OXNAS_DMA_FROM_DEVICE
-+} oxnas_dma_direction_t;
-+
-+/* The available buses to which the DMA controller is attached */
-+typedef enum oxnas_dma_transfer_bus
-+{
-+ OXNAS_DMA_SIDE_A,
-+ OXNAS_DMA_SIDE_B
-+} oxnas_dma_transfer_bus_t;
-+
-+/* Direction of data flow between the DMA controller's pair of interfaces */
-+typedef enum oxnas_dma_transfer_direction
-+{
-+ OXNAS_DMA_A_TO_A,
-+ OXNAS_DMA_B_TO_A,
-+ OXNAS_DMA_A_TO_B,
-+ OXNAS_DMA_B_TO_B
-+} oxnas_dma_transfer_direction_t;
-+
-+/* The available data widths */
-+typedef enum oxnas_dma_transfer_width
-+{
-+ OXNAS_DMA_TRANSFER_WIDTH_8BITS,
-+ OXNAS_DMA_TRANSFER_WIDTH_16BITS,
-+ OXNAS_DMA_TRANSFER_WIDTH_32BITS
-+} oxnas_dma_transfer_width_t;
-+
-+/* The mode of the DMA transfer */
-+typedef enum oxnas_dma_transfer_mode
-+{
-+ OXNAS_DMA_TRANSFER_MODE_SINGLE,
-+ OXNAS_DMA_TRANSFER_MODE_BURST
-+} oxnas_dma_transfer_mode_t;
-+
-+/* The available transfer targets */
-+typedef enum oxnas_dma_dreq
-+{
-+ OXNAS_DMA_DREQ_SATA = 0,
-+ OXNAS_DMA_DREQ_MEMORY = 15
-+} oxnas_dma_dreq_t;
-+
-+typedef struct oxnas_dma_device_settings {
-+ unsigned long address_;
-+ unsigned fifo_size_; // Chained transfers must take account of FIFO offset at end of previous transfer
-+ unsigned char dreq_;
-+ unsigned read_eot_:1;
-+ unsigned read_final_eot_:1;
-+ unsigned write_eot_:1;
-+ unsigned write_final_eot_:1;
-+ unsigned bus_:1;
-+ unsigned width_:2;
-+ unsigned transfer_mode_:1;
-+ unsigned address_mode_:1;
-+ unsigned address_really_fixed_:1;
-+} oxnas_dma_device_settings_t;
-+
-+static const int MAX_NO_ERROR_LOOPS = 100000; /* 1 second in units of 10uS */
-+static const int MAX_DMA_XFER_LOOPS = 300000; /* 30 seconds in units of 100uS */
-+static const int MAX_DMA_ABORT_LOOPS = 10000; /* 0.1 second in units of 10uS */
-+static const int MAX_SRC_READ_LOOPS = 10000; /* 0.1 second in units of 10uS */
-+static const int MAX_SRC_WRITE_LOOPS = 10000; /* 0.1 second in units of 10uS */
-+static const int MAX_NOT_BUSY_LOOPS = 10000; /* 1 second in units of 100uS */
-+
-+/* The internal SATA drive on which we should attempt to find partitions */
-+static volatile u32* sata_regs_base[2] =
-+{
-+ (volatile u32*)SATA_0_REGS_BASE,
-+ (volatile u32*)SATA_1_REGS_BASE,
-+
-+};
-+static u32 wr_sata_orb1[2] = { 0, 0 };
-+static u32 wr_sata_orb2[2] = { 0, 0 };
-+static u32 wr_sata_orb3[2] = { 0, 0 };
-+static u32 wr_sata_orb4[2] = { 0, 0 };
-+
-+static oxnas_dma_device_settings_t oxnas_sata_dma_settings = {
-+ .address_ = SATA_DATA_BASE_PA,
-+ .fifo_size_ = 16,
-+ .dreq_ = OXNAS_DMA_DREQ_SATA,
-+ .read_eot_ = 0,
-+ .read_final_eot_ = 1,
-+ .write_eot_ = 0,
-+ .write_final_eot_ = 1,
-+ .bus_ = OXNAS_DMA_SIDE_A,
-+ .width_ = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
-+ .transfer_mode_ = OXNAS_DMA_TRANSFER_MODE_BURST,
-+ .address_mode_ = OXNAS_DMA_MODE_FIXED,
-+ .address_really_fixed_ = 0
-+};
-+
-+oxnas_dma_device_settings_t oxnas_ram_dma_settings = {
-+ .address_ = 0,
-+ .fifo_size_ = 0,
-+ .dreq_ = OXNAS_DMA_DREQ_MEMORY,
-+ .read_eot_ = 1,
-+ .read_final_eot_ = 1,
-+ .write_eot_ = 1,
-+ .write_final_eot_ = 1,
-+ .bus_ = OXNAS_DMA_SIDE_B,
-+ .width_ = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
-+ .transfer_mode_ = OXNAS_DMA_TRANSFER_MODE_BURST,
-+ .address_mode_ = OXNAS_DMA_MODE_FIXED,
-+ .address_really_fixed_ = 1
-+};
-+
-+static void xfer_wr_shadow_to_orbs(int device)
-+{
-+ *(sata_regs_base[device] + SATA_ORB1_OFF) = wr_sata_orb1[device];
-+ *(sata_regs_base[device] + SATA_ORB2_OFF) = wr_sata_orb2[device];
-+ *(sata_regs_base[device] + SATA_ORB3_OFF) = wr_sata_orb3[device];
-+ *(sata_regs_base[device] + SATA_ORB4_OFF) = wr_sata_orb4[device];
-+}
-+
-+static inline void device_select(int device)
-+{
-+ /* master/slave has no meaning to SATA core */
-+}
-+
-+static int disk_present[CFG_IDE_MAXDEVICE];
-+
-+#include <ata.h>
-+
-+unsigned char oxnas_sata_inb(int device, int port)
-+{
-+ unsigned char val = 0;
-+
-+ /* Only permit accesses to disks found to be present during ide_preinit() */
-+ if (!disk_present[device]) {
-+ return ATA_STAT_FAULT;
-+ }
-+
-+ device_select(device);
-+
-+ switch (port) {
-+ case ATA_PORT_CTL:
-+ val = (*(sata_regs_base[device] + SATA_ORB4_OFF) & (0xFFUL << SATA_CTL_BIT)) >> SATA_CTL_BIT;
-+ break;
-+ case ATA_PORT_FEATURE:
-+ val = (*(sata_regs_base[device] + SATA_ORB2_OFF) & (0xFFUL << SATA_FEATURE_BIT)) >> SATA_FEATURE_BIT;
-+ break;
-+ case ATA_PORT_NSECT:
-+ val = (*(sata_regs_base[device] + SATA_ORB2_OFF) & (0xFFUL << SATA_NSECT_BIT)) >> SATA_NSECT_BIT;
-+ break;
-+ case ATA_PORT_LBAL:
-+ val = (*(sata_regs_base[device] + SATA_ORB3_OFF) & (0xFFUL << SATA_LBAL_BIT)) >> SATA_LBAL_BIT;
-+ break;
-+ case ATA_PORT_LBAM:
-+ val = (*(sata_regs_base[device] + SATA_ORB3_OFF) & (0xFFUL << SATA_LBAM_BIT)) >> SATA_LBAM_BIT;
-+ break;
-+ case ATA_PORT_LBAH:
-+ val = (*(sata_regs_base[device] + SATA_ORB3_OFF) & (0xFFUL << SATA_LBAH_BIT)) >> SATA_LBAH_BIT;
-+ break;
-+ case ATA_PORT_DEVICE:
-+ val = (*(sata_regs_base[device] + SATA_ORB3_OFF) & (0xFFUL << SATA_HOB_LBAH_BIT)) >> SATA_HOB_LBAH_BIT;
-+ val |= (*(sata_regs_base[device] + SATA_ORB1_OFF) & (0xFFUL << SATA_DEVICE_BIT)) >> SATA_DEVICE_BIT;
-+ break;
-+ case ATA_PORT_COMMAND:
-+ val = (*(sata_regs_base[device] + SATA_ORB2_OFF) & (0xFFUL << SATA_COMMAND_BIT)) >> SATA_COMMAND_BIT;
-+ val |= ATA_STAT_DRQ ;
-+ break;
-+ default:
-+ printf("ide_inb() Unknown port = %d\n", port);
-+ break;
-+ }
-+
-+// printf("inb: %d:%01x => %02x\n", device, port, val);
-+
-+ return val;
-+}
-+
-+/**
-+ * Possible that ATA status will not become no-error, so must have timeout
-+ * @returns An int which is zero on error
-+ */
-+static inline int wait_no_error(int device)
-+{
-+ int status = 0;
-+
-+ /* Check for ATA core error */
-+ if (*(sata_regs_base[device] + SATA_INT_STATUS_OFF) & (1 << SATA_INT_STATUS_ERROR_BIT)) {
-+ printf("wait_no_error() SATA core flagged error\n");
-+ } else {
-+ int loops = MAX_NO_ERROR_LOOPS;
-+ do {
-+ /* Check for ATA device error */
-+ if (!(oxnas_sata_inb(device, ATA_PORT_COMMAND) & (1 << ATA_STATUS_ERR_BIT))) {
-+ status = 1;
-+ break;
-+ }
-+ udelay(10);
-+ } while (--loops);
-+
-+ if (!loops) {
-+ printf("wait_no_error() Timed out of wait for SATA no-error condition\n");
-+ }
-+ }
-+
-+ return status;
-+}
-+
-+/**
-+ * Expect SATA command to always finish, perhaps with error
-+ * @returns An int which is zero on error
-+ */
-+static inline int wait_sata_command_not_busy(int device)
-+{
-+ /* Wait for data to be available */
-+ int status = 0;
-+ int loops = MAX_NOT_BUSY_LOOPS;
-+ do {
-+ if (!(*(sata_regs_base[device] + SATA_COMMAND_OFF) & (1 << SATA_CMD_BUSY_BIT) )) {
-+ status = 1;
-+ break;
-+ }
-+ udelay(100);
-+ } while (--loops);
-+
-+ if (!loops) {
-+ printf("wait_sata_command_not_busy() Timed out of wait for SATA command to finish\n");
-+ }
-+
-+ return status;
-+}
-+
-+void oxnas_sata_outb(int device, int port, unsigned char val)
-+{
-+ typedef enum send_method {
-+ SEND_NONE,
-+ SEND_SIMPLE,
-+ SEND_CMD,
-+ SEND_CTL,
-+ } send_method_t;
-+
-+ /* Only permit accesses to disks found to be present during ide_preinit() */
-+ if (!disk_present[device]) {
-+ return;
-+ }
-+
-+// printf("outb: %d:%01x <= %02x\n", device, port, val);
-+
-+ device_select(device);
-+
-+ send_method_t send_regs = SEND_NONE;
-+ switch (port) {
-+ case ATA_PORT_CTL:
-+ wr_sata_orb4[device] &= ~(0xFFUL << SATA_CTL_BIT);
-+ wr_sata_orb4[device] |= (val << SATA_CTL_BIT);
-+ send_regs = SEND_CTL;
-+ break;
-+ case ATA_PORT_FEATURE:
-+ wr_sata_orb2[device] &= ~(0xFFUL << SATA_FEATURE_BIT);
-+ wr_sata_orb2[device] |= (val << SATA_FEATURE_BIT);
-+ send_regs = SEND_SIMPLE;
-+ break;
-+ case ATA_PORT_NSECT:
-+ wr_sata_orb2[device] &= ~(0xFFUL << SATA_NSECT_BIT);
-+ wr_sata_orb2[device] |= (val << SATA_NSECT_BIT);
-+ send_regs = SEND_SIMPLE;
-+ break;
-+ case ATA_PORT_LBAL:
-+ wr_sata_orb3[device] &= ~(0xFFUL << SATA_LBAL_BIT);
-+ wr_sata_orb3[device] |= (val << SATA_LBAL_BIT);
-+ send_regs = SEND_SIMPLE;
-+ break;
-+ case ATA_PORT_LBAM:
-+ wr_sata_orb3[device] &= ~(0xFFUL << SATA_LBAM_BIT);
-+ wr_sata_orb3[device] |= (val << SATA_LBAM_BIT);
-+ send_regs = SEND_SIMPLE;
-+ break;
-+ case ATA_PORT_LBAH:
-+ wr_sata_orb3[device] &= ~(0xFFUL << SATA_LBAH_BIT);
-+ wr_sata_orb3[device] |= (val << SATA_LBAH_BIT);
-+ send_regs = SEND_SIMPLE;
-+ break;
-+ case ATA_PORT_DEVICE:
-+ wr_sata_orb1[device] &= ~(0xFFUL << SATA_DEVICE_BIT);
-+ wr_sata_orb1[device] |= ((val & 0xf0) << SATA_DEVICE_BIT);
-+ wr_sata_orb3[device] &= ~(0xFFUL << SATA_HOB_LBAH_BIT);
-+ wr_sata_orb3[device] |= ((val & 0x0f) << SATA_HOB_LBAH_BIT);
-+ send_regs = SEND_SIMPLE;
-+ break;
-+ case ATA_PORT_COMMAND:
-+ wr_sata_orb2[device] &= ~(0xFFUL << SATA_COMMAND_BIT);
-+ wr_sata_orb2[device] |= (val << SATA_COMMAND_BIT);
-+ send_regs = SEND_CMD;
-+ break;
-+ default:
-+ printf("ide_outb() Unknown port = %d\n", port);
-+ }
-+
-+ u32 command;
-+ switch (send_regs) {
-+ case SEND_CMD:
-+ wait_sata_command_not_busy(device);
-+ command = *(sata_regs_base[device] + SATA_COMMAND_OFF);
-+ command &= ~SATA_OPCODE_MASK;
-+ command |= SATA_CMD_WRITE_TO_ORB_REGS;
-+ xfer_wr_shadow_to_orbs(device);
-+ wait_sata_command_not_busy(device);
-+ *(sata_regs_base[device] + SATA_COMMAND_OFF) = command;
-+ if (!wait_no_error(device)) {
-+ printf("oxnas_sata_outb() Wait for ATA no-error timed-out\n");
-+ }
-+ break;
-+ case SEND_CTL:
-+ wait_sata_command_not_busy(device);
-+ command = *(sata_regs_base[device] + SATA_COMMAND_OFF);
-+ command &= ~SATA_OPCODE_MASK;
-+ command |= SATA_CMD_WRITE_TO_ORB_REGS_NO_COMMAND;
-+ xfer_wr_shadow_to_orbs(device);
-+ wait_sata_command_not_busy(device);
-+ *(sata_regs_base[device] + SATA_COMMAND_OFF) = command;
-+ if (!wait_no_error(device)) {
-+ printf("oxnas_sata_outb() Wait for ATA no-error timed-out\n");
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
-+static u32 encode_start(u32 ctrl_status)
-+{
-+ return ctrl_status & ~DMA_CTRL_STATUS_PAUSE;
-+}
-+
-+static void dma_start(void)
-+{
-+ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS) =
-+ encode_start(*(DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS)));
-+}
-+
-+static unsigned long encode_control_status(
-+ oxnas_dma_device_settings_t* src_settings,
-+ oxnas_dma_device_settings_t* dst_settings)
-+{
-+ unsigned long ctrl_status;
-+ oxnas_dma_transfer_direction_t direction;
-+
-+ ctrl_status = DMA_CTRL_STATUS_PAUSE; // Paused
-+ ctrl_status |= DMA_CTRL_STATUS_FAIR_SHARE_ARB; // High priority
-+ ctrl_status |= (src_settings->dreq_ << DMA_CTRL_STATUS_SRC_DREQ_SHIFT); // Dreq
-+ ctrl_status |= (dst_settings->dreq_ << DMA_CTRL_STATUS_DEST_DREQ_SHIFT); // Dreq
-+ ctrl_status &= ~DMA_CTRL_STATUS_RESET; // !RESET
-+
-+ // Use new interrupt clearing register
-+ ctrl_status |= DMA_CTRL_STATUS_INTR_CLEAR_ENABLE;
-+
-+ // Setup the transfer direction and burst/single mode for the two DMA busses
-+ if (src_settings->bus_ == OXNAS_DMA_SIDE_A) {
-+ // Set the burst/single mode for bus A based on src device's settings
-+ if (src_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
-+ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_A;
-+ } else {
-+ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_A;
-+ }
-+
-+ if (dst_settings->bus_ == OXNAS_DMA_SIDE_A) {
-+ direction = OXNAS_DMA_A_TO_A;
-+ } else {
-+ direction = OXNAS_DMA_A_TO_B;
-+
-+ // Set the burst/single mode for bus B based on dst device's settings
-+ if (dst_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
-+ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_B;
-+ } else {
-+ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_B;
-+ }
-+ }
-+ } else {
-+ // Set the burst/single mode for bus B based on src device's settings
-+ if (src_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
-+ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_B;
-+ } else {
-+ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_B;
-+ }
-+
-+ if (dst_settings->bus_ == OXNAS_DMA_SIDE_A) {
-+ direction = OXNAS_DMA_B_TO_A;
-+
-+ // Set the burst/single mode for bus A based on dst device's settings
-+ if (dst_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
-+ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_A;
-+ } else {
-+ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_A;
-+ }
-+ } else {
-+ direction = OXNAS_DMA_B_TO_B;
-+ }
-+ }
-+ ctrl_status |= (direction << DMA_CTRL_STATUS_DIR_SHIFT);
-+
-+ // Setup source address mode fixed or increment
-+ if (src_settings->address_mode_ == OXNAS_DMA_MODE_FIXED) {
-+ // Fixed address
-+ ctrl_status &= ~(DMA_CTRL_STATUS_SRC_ADR_MODE);
-+
-+ // Set up whether fixed address is _really_ fixed
-+ if (src_settings->address_really_fixed_) {
-+ ctrl_status |= DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
-+ } else {
-+ ctrl_status &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
-+ }
-+ } else {
-+ // Incrementing address
-+ ctrl_status |= DMA_CTRL_STATUS_SRC_ADR_MODE;
-+ ctrl_status &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
-+ }
-+
-+ // Setup destination address mode fixed or increment
-+ if (dst_settings->address_mode_ == OXNAS_DMA_MODE_FIXED) {
-+ // Fixed address
-+ ctrl_status &= ~(DMA_CTRL_STATUS_DEST_ADR_MODE);
-+
-+ // Set up whether fixed address is _really_ fixed
-+ if (dst_settings->address_really_fixed_) {
-+ ctrl_status |= DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
-+ } else {
-+ ctrl_status &= ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
-+ }
-+ } else {
-+ // Incrementing address
-+ ctrl_status |= DMA_CTRL_STATUS_DEST_ADR_MODE;
-+ ctrl_status &= ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
-+ }
-+
-+ // Set up the width of the transfers on the DMA buses
-+ ctrl_status |= (src_settings->width_ << DMA_CTRL_STATUS_SRC_WIDTH_SHIFT);
-+ ctrl_status |= (dst_settings->width_ << DMA_CTRL_STATUS_DEST_WIDTH_SHIFT);
-+
-+ // Setup the priority arbitration scheme
-+ ctrl_status &= ~DMA_CTRL_STATUS_STARVE_LOW_PRIORITY; // !Starve low priority
-+
-+ return ctrl_status;
-+}
-+
-+static u32 encode_final_eot(
-+ oxnas_dma_device_settings_t* src_settings,
-+ oxnas_dma_device_settings_t* dst_settings,
-+ unsigned long length)
-+{
-+ // Write the length, with EOT configuration for a final transfer
-+ unsigned long encoded = length;
-+ if (dst_settings->write_final_eot_) {
-+ encoded |= DMA_BYTE_CNT_WR_EOT_MASK;
-+ } else {
-+ encoded &= ~DMA_BYTE_CNT_WR_EOT_MASK;
-+ }
-+ if (src_settings->read_final_eot_) {
-+ encoded |= DMA_BYTE_CNT_RD_EOT_MASK;
-+ } else {
-+ encoded &= ~DMA_BYTE_CNT_RD_EOT_MASK;
-+ }
-+ return encoded;
-+}
-+
-+static void dma_start_write(ulong* buffer, int num_bytes)
-+{
-+ // Assemble complete memory settings
-+ oxnas_dma_device_settings_t mem_settings = oxnas_ram_dma_settings;
-+ mem_settings.address_ = (unsigned long)buffer;
-+ mem_settings.address_mode_ = OXNAS_DMA_MODE_INC;
-+
-+ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS) = encode_control_status(&mem_settings, &oxnas_sata_dma_settings);
-+ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_BASE_SRC_ADR) = mem_settings.address_;
-+ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_BASE_DST_ADR) = oxnas_sata_dma_settings.address_;
-+ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_BYTE_CNT) = encode_final_eot(&mem_settings, &oxnas_sata_dma_settings, num_bytes);
-+
-+ dma_start();
-+}
-+
-+static void dma_start_read(ulong* buffer, int num_bytes)
-+{
-+ // Assemble complete memory settings
-+ oxnas_dma_device_settings_t mem_settings = oxnas_ram_dma_settings;
-+ mem_settings.address_ = (unsigned long)buffer;
-+ mem_settings.address_mode_ = OXNAS_DMA_MODE_INC;
-+
-+ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS) = encode_control_status(&oxnas_sata_dma_settings, &mem_settings);
-+ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_BASE_SRC_ADR) = oxnas_sata_dma_settings.address_;
-+ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_BASE_DST_ADR) = mem_settings.address_;
-+ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_BYTE_CNT) = encode_final_eot(&oxnas_sata_dma_settings, &mem_settings, num_bytes);
-+
-+ dma_start();
-+}
-+
-+static inline int dma_busy(void)
-+{
-+ return (*DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS)) & DMA_CTRL_STATUS_IN_PROGRESS;
-+}
-+
-+static int wait_dma_not_busy(int device)
-+{
-+ unsigned int cleanup_required = 0;
-+
-+ /* Poll for DMA completion */
-+ int loops = MAX_DMA_XFER_LOOPS;
-+ do {
-+ if (!dma_busy()) {
-+ break;
-+ }
-+ udelay(100);
-+ } while (--loops);
-+
-+ if (!loops) {
-+ printf("wait_dma_not_busy() Timed out of wait for DMA not busy\n");
-+ cleanup_required = 1;
-+ }
-+
-+ if (cleanup_required) {
-+ /* Abort DMA to make sure it has finished. */
-+ unsigned long ctrl_status = *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS);
-+ ctrl_status |= DMA_CTRL_STATUS_RESET;
-+ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS) = ctrl_status;
-+
-+ // Wait for the channel to become idle - should be quick as should
-+ // finish after the next AHB single or burst transfer
-+ loops = MAX_DMA_ABORT_LOOPS;
-+ do {
-+ if (!(*DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS) & DMA_CTRL_STATUS_IN_PROGRESS)) {
-+ break;
-+ }
-+ udelay(10);
-+ } while (--loops);
-+
-+ if (!loops) {
-+ printf("wait_dma_not_busy() Timed out of wait for DMA channel abort\n");
-+ } else {
-+ /* Successfully cleanup the DMA channel */
-+ cleanup_required = 0;
-+ }
-+
-+ // Deassert reset for the channel
-+ ctrl_status = *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS);
-+ ctrl_status &= ~DMA_CTRL_STATUS_RESET;
-+ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS) = ctrl_status;
-+ }
-+
-+ return !cleanup_required;
-+}
-+
-+/**
-+ * Possible that ATA status will not become not-busy, so must have timeout
-+ */
-+static unsigned int wait_not_busy(int device, unsigned long timeout_secs)
-+{
-+ int busy = 1;
-+ unsigned long loops = (timeout_secs * 1000) / 50;
-+ do {
-+ // Test the ATA status register BUSY flag
-+ if (!((*(sata_regs_base[device] + SATA_ORB2_OFF) >> SATA_COMMAND_BIT) & (1UL << ATA_STATUS_BSY_BIT))) {
-+ /* Not busy, so stop polling */
-+ busy = 0;
-+ break;
-+ }
-+
-+ // Wait for 50mS before sampling ATA status register again
-+ udelay(50000);
-+ } while (--loops);
-+
-+ return busy;
-+}
-+
-+void oxnas_sata_output_data(int device, ulong *sect_buf, int words)
-+{
-+ /* Only permit accesses to disks found to be present during ide_preinit() */
-+ if (!disk_present[device]) {
-+ return;
-+ }
-+
-+ /* Select the required internal SATA drive */
-+ device_select(device);
-+
-+ /* Start the DMA channel sending data from the passed buffer to the SATA core */
-+ dma_start_write(sect_buf, words << 2);
-+
-+ /* Don't know why we need this delay, but without it the wait for DMA not
-+ busy times soemtimes out, e.g. when saving environment to second disk */
-+ udelay(1000);
-+
-+ /* Wait for DMA to finish */
-+ if (!wait_dma_not_busy(device)) {
-+ printf("Timed out of wait for DMA channel for SATA device %d to have in-progress clear\n", device);
-+ }
-+
-+ /* Sata core should finish after DMA */
-+ if (wait_not_busy(device, 30)) {
-+ printf("Timed out of wait for SATA device %d to have BUSY clear\n", device);
-+ }
-+ if (!wait_no_error(device)) {
-+ printf("oxnas_sata_output_data() Wait for ATA no-error timed-out\n");
-+ }
-+}
-+
-+void oxnas_sata_input_data(int device, ulong *sect_buf, int words)
-+{
-+ /* Only permit accesses to disks found to be present during ide_preinit() */
-+ if (!disk_present[device]) {
-+ return;
-+ }
-+
-+ /* Select the required internal SATA drive */
-+ device_select(device);
-+
-+ /* Start the DMA channel receiving data from the SATA core into the passed buffer */
-+ dma_start_read(sect_buf, words << 2);
-+
-+ /* Sata core should finish before DMA */
-+ if (wait_not_busy(device, 30)) {
-+ printf("Timed out of wait for SATA device %d to have BUSY clear\n", device);
-+ }
-+ if (!wait_no_error(device)) {
-+ printf("oxnas_sata_output_data() Wait for ATA no-error timed-out\n");
-+ }
-+
-+ /* Wait for DMA to finish */
-+ if (!wait_dma_not_busy(device)) {
-+ printf("Timed out of wait for DMA channel for SATA device %d to have in-progress clear\n", device);
-+ }
-+}
-+
-+static u32 scr_read(int device, unsigned int sc_reg)
-+{
-+ /* Setup adr of required register. std regs start eight into async region */
-+ *(sata_regs_base[device] + SATA_LINK_RD_ADDR) = sc_reg*4 + SATA_STD_ASYNC_REGS_OFF;
-+
-+ /* Wait for data to be available */
-+ int loops = MAX_SRC_READ_LOOPS;
-+ do {
-+ if (*(sata_regs_base[device] + SATA_LINK_CONTROL) & 1UL) {
-+ break;
-+ }
-+ udelay(10);
-+ } while (--loops);
-+
-+ if (!loops) {
-+ printf("scr_read() Timed out of wait for read completion\n");
-+ }
-+
-+ /* Read the data from the async register */
-+ return *(sata_regs_base[device] + SATA_LINK_DATA);
-+}
-+
-+static void scr_write(int device, unsigned int sc_reg, u32 val)
-+{
-+ /* Setup the data for the write */
-+ *(sata_regs_base[device] + SATA_LINK_DATA) = val;
-+
-+ /* Setup adr of required register. std regs start eight into async region */
-+ *(sata_regs_base[device] + SATA_LINK_WR_ADDR) = sc_reg*4 + SATA_STD_ASYNC_REGS_OFF;
-+
-+ /* Wait for data to be written */
-+ int loops = MAX_SRC_WRITE_LOOPS;
-+ do {
-+ if (*(sata_regs_base[device] + SATA_LINK_CONTROL) & 1UL) {
-+ break;
-+ }
-+ udelay(10);
-+ } while (--loops);
-+
-+ if (!loops) {
-+ printf("scr_write() Timed out of wait for write completion\n");
-+ }
-+}
-+
-+#define PHY_LOOP_COUNT 25 /* Wait for upto 5 seconds for PHY to be found */
-+static int phy_reset(int device)
-+{
-+#ifdef FPGA
-+ /* The FPGA thinks it can do 3G when infact only 1.5G is possible, so limit
-+ it to Gen-1 SATA (1.5G) */
-+ scr_write(device, SATA_SCR_CONTROL, 0x311); /* Issue phy wake & core reset */
-+ scr_read(device, SATA_SCR_STATUS); /* Dummy read; flush */
-+ udelay(1000);
-+ scr_write(device, SATA_SCR_CONTROL, 0x310); /* Issue phy wake & clear core reset */
-+#else
-+ scr_write(device, SATA_SCR_CONTROL, 0x301); /* Issue phy wake & core reset */
-+ scr_read(device, SATA_SCR_STATUS); /* Dummy read; flush */
-+ udelay(1000);
-+ scr_write(device, SATA_SCR_CONTROL, 0x300); /* Issue phy wake & clear core reset */
-+#endif
-+ /* Wait for upto 5 seconds for PHY to become ready */
-+ int phy_status = 0;
-+ int loops = 0;
-+ do {
-+ udelay(200000);
-+ if ((scr_read(device, SATA_SCR_STATUS) & 0xf) != 1) {
-+ phy_status = 1;
-+ break;
-+ }
-+ printf("No SATA PHY found\n");
-+ } while (++loops < PHY_LOOP_COUNT);
-+
-+ if (phy_status) {
-+ udelay(500000); /* wait half a second */
-+ }
-+ return phy_status;
-+}
-+
-+#define FIS_LOOP_COUNT 25 /* Wait for upto 5 seconds for FIS to be received */
-+static int wait_FIS(int device)
-+{
-+ int status = 0;
-+ int loops = 0;
-+
-+ do {
-+ udelay(200000);
-+ if (oxnas_sata_inb(device, ATA_PORT_NSECT) > 0) {
-+ status = 1;
-+ break;
-+ }
-+ } while (++loops < FIS_LOOP_COUNT);
-+
-+ return status;
-+}
-+
-+int ide_preinit(void)
-+{
-+ int num_disks_found = 0;
-+
-+ /* Initialise records of which disks are present to all present */
-+ int i;
-+ for (i=0; i < CFG_IDE_MAXDEVICE; i++) {
-+ disk_present[i] = 1;
-+ }
-+
-+//udelay(1000000);
-+ /* Enable clocks to SATA and DMA cores */
-+ *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_SATA_BIT);
-+ *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_DMA_BIT);
-+
-+ /* Block reset SATA and DMA cores */
-+ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_SATA_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_SATA_LINK_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_DMA_BIT);
-+ udelay(50);
-+ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT);
-+ udelay(50);
-+ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_SATA_LINK_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_SATA_BIT);
-+ udelay(50);
-+ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_DMA_BIT);
-+ udelay(50);
-+//udelay(1000000);
-+
-+ /* disable and clear core interrupts */
-+ *((unsigned long*)SATA_HOST_REGS_BASE + SATA_INT_ENABLE_CLR_OFF) = ~0UL;
-+ *((unsigned long*)SATA_HOST_REGS_BASE + SATA_INT_CLR_OFF) = ~0UL;
-+
-+ int device;
-+ for (device = 0; device < CFG_IDE_MAXDEVICE; device++) {
-+ int found = 0;
-+ int retries = 1;
-+
-+ /* Disable SATA interrupts */
-+ *(sata_regs_base[device] + SATA_INT_ENABLE_CLR_OFF) = ~0UL;
-+
-+ /* Clear any pending SATA interrupts */
-+ *(sata_regs_base[device] + SATA_INT_CLR_OFF) = ~0UL;
-+
-+ do {
-+ /* clear sector count register for FIS detection */
-+ oxnas_sata_outb(device, ATA_PORT_NSECT, 0);
-+
-+ /* Get the PHY working */
-+ if (!phy_reset(device)) {
-+ printf("SATA PHY not ready for device %d\n", device);
-+ break;
-+ }
-+
-+ if (!wait_FIS(device)) {
-+ printf("No FIS received from device %d\n", device);
-+ } else {
-+ if ((scr_read(device, SATA_SCR_STATUS) & 0xf) == 0x3) {
-+ if (wait_not_busy(device, 30)) {
-+ printf("Timed out of wait for SATA device %d to have BUSY clear\n", device);
-+ } else {
-+ ++num_disks_found;
-+ found = 1;
-+ }
-+ } else {
-+ printf("No SATA device %d found, PHY status = 0x%08x\n",
-+ device, scr_read(device, SATA_SCR_STATUS));
-+ }
-+ break;
-+ }
-+ } while (retries--) ;
-+
-+ /* Record whether disk is present, so won't attempt to access it later */
-+ disk_present[device] = found;
-+ }
-+
-+ /* post disk detection clean-up */
-+ for (device = 0; device < CFG_IDE_MAXDEVICE; device++) {
-+ if ( disk_present[device] ) {
-+ /* set as ata-5 (28-bit) */
-+ *(sata_regs_base[device] + SATA_DRIVE_CONTROL_OFF) = 0UL;
-+
-+ /* clear phy/link errors */
-+ scr_write(device, SATA_SCR_ERROR, ~0);
-+
-+ /* clear host errors */
-+ *(sata_regs_base[device] + SATA_CONTROL_OFF) |= SATA_SCTL_CLR_ERR;
-+
-+ /* clear interrupt register as this clears the error bit in the IDE
-+ status register */
-+ *(sata_regs_base[device] + SATA_INT_CLR_OFF) = ~0UL;
-+ }
-+ }
-+
-+
-+ return !num_disks_found;
-+}
-+
-diff -Nurd u-boot-1.1.2/board/oxnas/Makefile u-boot-1.1.2-oxe810/board/oxnas/Makefile
---- u-boot-1.1.2/board/oxnas/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/board/oxnas/Makefile 2008-06-11 17:55:18.000000000 +0200
-@@ -0,0 +1,51 @@
-+#
-+# (C) Copyright 2000-2004
-+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-+#
-+# (C) Copyright 2004
-+# ARM Ltd.
-+# Philippe Robin, <philippe.robin@arm.com>
-+#
-+# See file CREDITS for list of people who contributed to this
-+# project.
-+#
-+# 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 $(TOPDIR)/config.mk
-+
-+LIB = lib$(BOARD).a
-+
-+OBJS := oxnas.o eth.o ide-$(NAS_VERSION).o
-+SOBJS := platform-$(NAS_VERSION).o
-+
-+$(LIB): $(OBJS) $(SOBJS)
-+ $(AR) crv $@ $^
-+
-+clean:
-+ rm -f $(SOBJS) $(OBJS)
-+
-+distclean: clean
-+ rm -f $(LIB) core *.bak .depend
-+
-+#########################################################################
-+
-+.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
-+ $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
-+
-+-include .depend
-+
-+#########################################################################
-diff -Nurd u-boot-1.1.2/board/oxnas/oxnas.c u-boot-1.1.2-oxe810/board/oxnas/oxnas.c
---- u-boot-1.1.2/board/oxnas/oxnas.c 1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/board/oxnas/oxnas.c 2008-06-11 17:55:18.000000000 +0200
-@@ -0,0 +1,280 @@
-+/*
-+ * (C) Copyright 2005
-+ * Oxford Semiconductor Ltd
-+ *
-+ * See file CREDITS for list of people who contributed to this
-+ * project.
-+ *
-+ * 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 <common.h>
-+
-+#if defined(CONFIG_SHOW_BOOT_PROGRESS)
-+void show_boot_progress(int progress)
-+{
-+ printf("Boot reached stage %d\n", progress);
-+}
-+#endif
-+
-+static inline void delay(unsigned long loops)
-+{
-+ __asm__ volatile ("1:\n"
-+ "subs %0, %1, #1\n"
-+ "bne 1b":"=r" (loops):"0" (loops));
-+}
-+
-+/*
-+ * Miscellaneous platform dependent initialisations
-+ */
-+
-+/** Expected Intel 28F320B3T CFI info */
-+// mfr_id: MANUFACTURER_INTEL, -> 0x0089
-+// dev_id: I28F320B3T, -> 0x8896
-+// name: "Intel 28F320B3T",
-+// DevSize: SIZE_4MiB, -> 22
-+// CmdSet: P_ID_INTEL_STD, -> 0x0003
-+// NumEraseRegions: 2,
-+// regions: { -> #define ERASEINFO(size,blocks) (size<<8)|(blocks-1)
-+// ERASEINFO(0x10000, 63),
-+// ERASEINFO(0x02000, 8),
-+// }
-+
-+#define FLASH_WORD_SIZE unsigned short
-+
-+int board_init(void)
-+{
-+ DECLARE_GLOBAL_DATA_PTR;
-+
-+ gd->bd->bi_arch_number = MACH_TYPE_OXNAS;
-+ gd->bd->bi_boot_params = PHYS_SDRAM_1_PA + 0x100;
-+ gd->flags = 0;
-+
-+ icache_enable();
-+
-+ /* Block reset Static core */
-+ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_STATIC_BIT);
-+ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_STATIC_BIT);
-+
-+ /* Enable clock to Static core */
-+ *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_STATIC_BIT);
-+
-+#ifdef CONFIG_OXNAS_ENABLE_PCI
-+ /* Block reset PCI core */
-+ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_PCI_BIT);
-+ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_PCI_BIT);
-+
-+ /* Enable clock to PCI core */
-+ *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_PCI_BIT);
-+#endif // CONFIG_OXNAS_ENABLE_PCI
-+
-+#ifdef CONFIG_OXNAS_MANUAL_STATIC_ARBITRATION
-+ /* Assert manual static bus PCI arbitration request */
-+ *(volatile u32*)SYS_CTRL_PCI_CTRL1 |= (1UL << SYS_CTRL_PCI_CTRL1_PCI_STATIC_RQ_BIT);
-+#endif // CONFIG_OXNAS_MANUAL_STATIC_ARBITRATION
-+
-+#ifdef CONFIG_OXNAS_FEEDBACK_PCI_CLKS
-+ /* Set PCI feedback clk GPIO pin as an output */
-+ *(volatile u32*)GPIO_1_SET_OE |= 0x800;
-+
-+ /* Enable PCI feedback clk onto GPIO pin */
-+ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 |= 0x00000800;
-+#endif // CONFIG_OXNAS_FEEDBACK_PCI_CLKS
-+
-+#ifndef CFG_NO_FLASH
-+ /* Enable static bus onto GPIOs, only CS0 as CS1 conflicts with UART2 */
-+ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 |= 0x002FF000;
-+
-+ /* Setup the static bus CS0 to access FLASH */
-+ *(volatile u32*)STATIC_CONTROL_BANK0 = STATIC_BUS_FLASH_CONFIG;
-+#endif // !CFG_NO_FLASH
-+
-+ /* Set 33MHz PCI clock */
-+ *(volatile u32*)SYS_CTRL_CKCTRL_CTRL_ADDR = 5;
-+ /* Enable full speed RPS clock */
-+ *(volatile u32*)SYS_CTRL_CKCTRL_CTRL_ADDR &= ~(1UL << SYS_CTRL_CKCTRL_SLOW_BIT);
-+
-+#if (USE_EXTERNAL_UART == 0)
-+#ifdef CONFIG_OXNAS_UART1
-+ /* Block reset UART1 */
-+ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART1_BIT);
-+ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART1_BIT);
-+
-+ /* Setup pin mux'ing for first internal UART */
-+ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x80000000;
-+ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 &= ~0x80000000;
-+ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |= 0x80000000; // Route UART1 SOUT onto external pins
-+
-+ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_1 &= ~0x00000001;
-+ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_1 &= ~0x00000001;
-+ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_1 |= 0x00000001; // Route UART1 SIN onto external pins
-+
-+ *(volatile u32*)GPIO_1_SET_OE |= 0x80000000; // Make UART1 SOUT an o/p
-+ *(volatile u32*)GPIO_2_CLR_OE |= 0x00000001; // Make UART1 SIN an i/p
-+#endif // CONFIG_OXNAS_UART1
-+
-+#ifdef CONFIG_OXNAS_UART2
-+ // Block reset UART2
-+ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART2_BIT);
-+ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART2_BIT);
-+
-+ /* Setup pin mux'ing for second internal UART */
-+ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x00500000;
-+ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 &= ~0x00500000;
-+ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |= 0x00500000; // Route UART2 SOUT and SIN onto external pins
-+
-+ *(volatile u32*)GPIO_1_SET_OE |= 0x00100000; // Make UART2 SOUT an o/p
-+ *(volatile u32*)GPIO_1_CLR_OE |= 0x00400000; // Make UART2 SIN an i/p
-+#endif // CONFIG_OXNAS_UART2
-+
-+#ifdef CONFIG_OXNAS_UART3
-+ // Block reset UART3
-+ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART3_BIT);
-+ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART3_BIT);
-+
-+ // Route UART3 SIN/SOUT onto external pin
-+ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x000000C0;
-+ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 &= ~0x000000C0;
-+ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |= 0x000000C0;
-+
-+ // Setup GPIO line directions for UART3 SIN/SOUT
-+ *(volatile u32*)GPIO_1_SET_OE |= 0x00000080;
-+ *(volatile u32*)GPIO_1_CLR_OE |= 0x00000040;
-+#endif // CONFIG_ARCH_OXNAS_UART3
-+
-+#ifdef CONFIG_OXNAS_UART4
-+ // Block reset UART4
-+ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART4_BIT);
-+ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART4_BIT);
-+
-+ // Enable UART4 to override PCI functions onto GPIOs
-+ *(volatile u32*)SYS_CTRL_UART_CTRL |= (1UL << SYS_CTRL_UART4_NOT_PCI_MODE);
-+#endif // CONFIG_OXNAS_UART4
-+#endif // !USE_EXTERNAL_UART
-+
-+ return 0;
-+}
-+
-+int board_late_init()
-+{
-+ return 0;
-+}
-+
-+int misc_init_r(void)
-+{
-+ return 0;
-+}
-+
-+int dram_init(void)
-+{
-+#ifdef PROBE_MEM_SIZE
-+ /* Determine the amount of SDRAM the DDR controller is configured for */
-+ volatile unsigned long * const ddr_config_reg_adr = (volatile unsigned long *)(0x45800000);
-+ static const int DDR_SIZE_BIT = 17;
-+ static const int DDR_SIZE_NUM_BITS = 4;
-+ static const unsigned long DDR_SIZE_MASK = (((1UL << DDR_SIZE_NUM_BITS) - 1) << DDR_SIZE_BIT);
-+
-+ unsigned long ddr_config_reg = *ddr_config_reg_adr;
-+ int ddr_size_pow2 = (ddr_config_reg & DDR_SIZE_MASK) >> DDR_SIZE_BIT;
-+
-+ DECLARE_GLOBAL_DATA_PTR;
-+
-+ gd->bd->bi_dram[0].size = (1 << ddr_size_pow2) * 1024 * 1024;
-+
-+ if ((gd->bd->bi_dram[0].size >> 20) == 256) {
-+ /* Do we really have 256M, or are we working around the DDR controller's
-+ * problem with 128M size? */
-+ volatile unsigned long * const PROBE_ADR_1 = (volatile unsigned long * const)PHYS_SDRAM_1_PA;
-+ volatile unsigned long * const PROBE_ADR_2 = (volatile unsigned long * const)(PHYS_SDRAM_1_PA + (128*1024*1024));
-+ static const unsigned long PROBE_VAL_1 = 0xdeadbeef;
-+ static const unsigned long PROBE_VAL_2 = 0x12345678;
-+
-+ *PROBE_ADR_1 = PROBE_VAL_1;
-+ *PROBE_ADR_2 = PROBE_VAL_2;
-+ if (*PROBE_ADR_1 != PROBE_VAL_1) {
-+ gd->bd->bi_dram[0].size = 128*1024*1024;
-+ }
-+ }
-+#else // PROBE_MEM_SIZE
-+ gd->bd->bi_dram[0].size = MEM_SIZE;
-+#endif // PROBE_MEM_SIZE
-+
-+ gd->bd->bi_dram[0].start = PHYS_SDRAM_1_PA;
-+
-+ gd->bd->bi_sramstart = CFG_SRAM_BASE;
-+ gd->bd->bi_sramsize = CFG_SRAM_SIZE;
-+
-+ return 0;
-+}
-+
-+int reset_cpu(void)
-+{
-+ printf("Resetting Oxsemi NAS...");
-+
-+ // Assert reset to cores as per power on defaults
-+ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL =
-+ (1UL << SYS_CTRL_RSTEN_COPRO_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_USBHS_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_USBHSPHY_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_MAC_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_PCI_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_DMA_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_DPE_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_SATA_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_SATA_LINK_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_STATIC_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_UART1_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_UART2_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_MISC_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_I2S_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_AHB_MON_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_UART3_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_UART4_BIT) |
-+ (1UL << SYS_CTRL_RSTEN_SGDMA_BIT);
-+
-+ // Release reset to cores as per power on defaults
-+ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_GPIO_BIT);
-+
-+ // Disable clocks to cores as per power-on defaults
-+ *(volatile u32*)SYS_CTRL_CKEN_CLR_CTRL =
-+ (1UL << SYS_CTRL_CKEN_COPRO_BIT) |
-+ (1UL << SYS_CTRL_CKEN_DMA_BIT) |
-+ (1UL << SYS_CTRL_CKEN_DPE_BIT) |
-+ (1UL << SYS_CTRL_CKEN_SATA_BIT) |
-+ (1UL << SYS_CTRL_CKEN_I2S_BIT) |
-+ (1UL << SYS_CTRL_CKEN_USBHS_BIT) |
-+ (1UL << SYS_CTRL_CKEN_MAC_BIT) |
-+ (1UL << SYS_CTRL_CKEN_STATIC_BIT);
-+
-+ // Enable clocks to cores as per power-on defaults
-+ *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_PCI_BIT);
-+
-+ // Set sys-control pin mux'ing as per power-on defaults
-+ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 = 0x800UL;
-+ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_1 = 0x0UL;
-+ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 = 0x0UL;
-+ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_1 = 0x0UL;
-+ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 = 0x0UL;
-+ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_1 = 0x0UL;
-+
-+ // No need to save any state, as the ROM loader can determine whether reset
-+ // is due to power cycling or programatic action, just hit the (self-
-+ // clearing) CPU reset bit of the block reset register
-+ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_ARM_BIT);
-+
-+ return 0;
-+}
-diff -Nurd u-boot-1.1.2/board/oxnas/platform-800.S u-boot-1.1.2-oxe810/board/oxnas/platform-800.S
---- u-boot-1.1.2/board/oxnas/platform-800.S 1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/board/oxnas/platform-800.S 2008-06-11 17:55:18.000000000 +0200
-@@ -0,0 +1,254 @@
-+/*
-+ * Board specific setup info
-+ *
-+ * (C) Copyright 2005
-+ * Oxford Semiconductor Ltd
-+ *
-+ * See file CREDITS for list of people who contributed to this
-+ * project.
-+ *
-+ * 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 <config.h>
-+#include <version.h>
-+
-+/* use estimate of processor speed to calculate number of cycles delay */
-+/* delay count is nominal (PLL200 frequency x delay time) / loop count
-+ * expressing 200us as 200/1000000 and re-arranging gives the expression below
-+ */
-+
-+#define DELAY_200US ((NOMINAL_ARMCLK / (5 * 1000000)) * 200)
-+/* this is 8 cycles of ? so choose 8 resulting in 40 cycles */
-+#define DELAY_1S ((DELAY_200US) * 5000)
-+#define DELAY_8 8
-+#define DELAY_200 200
-+
-+.globl platformsetup
-+platformsetup:
-+/* register allocations
-+ * r0 - delay counter and scratch
-+ * r1 - address register
-+ * r2 - data register
-+ * r3 - index to table pointer
-+ * r4 - iteration counter.
-+ *
-+ * r5 - hold return address.
-+ * lr - (R14) link register
-+ * pc - (R15) program counter.
-+ */
-+
-+#ifdef INITIALISE_SDRAM
-+/*
-+ * Check that not in SDRAM execution. Suicide if re-initialise DRAM.
-+ * Controller function is linked to execute in SDRAM must be in ROM if not
-+ * there. Check for wrong place.
-+ */
-+ adrl r0, platformsetup /* Relative location of function start.*/
-+ ldr r1, _platformsetup
-+ cmp r0, r1
-+ moveq pc, lr
-+#else
-+ mov pc, lr
-+#endif
-+
-+ /* Establish a working setup for the SDRAM */
-+ mov r6, lr
-+
-+#ifdef OXNAS_OVERCLOCK
-+ /* Delay so the broken JTAG can get control */
-+ ldr r0, =DELAY_1S
-+ bl delay
-+
-+ /* Configure the PLL to run faster */
-+ ldr r1, =SYS_CTRL_PLLSYS_CTRL
-+ ldr r2, =SYS_CTRL_PLLSYS_KEY_CTRL
-+
-+ /* 0xBEADFACE -> PLL_KEY */
-+ /* Bypass PLL */
-+ ldr r3, [r1]
-+ ldr r5, =0x20000
-+ orr r3, r3, r5
-+ ldr r4, =0xbeadface
-+ str r4, [r2]
-+ str r3, [r1]
-+
-+ /* 0xBEADFACE -> PLL_KEY */
-+ /* Set m,p and s for PLL at 400MHz */
-+ ldr r5, =0xffff0000
-+ and r3, r3, r5
-+ ldr r5, =OXNAS_OVERCLOCK
-+ orr r3, r3, r5
-+ str r4, [r2]
-+ str r3, [r1]
-+
-+ /* Wait at least 300uS */
-+ ldr r0, =DELAY_200US
-+ bl delay
-+ ldr r0, =DELAY_200US
-+ bl delay
-+
-+ /* 0xBEADFACE -> PLL_KEY */
-+ /* Disable PLL bypass */
-+ ldr r5, =0xfffdffff
-+ and r3, r3, r5
-+ str r4, [r2]
-+ str r3, [r1]
-+#endif // OXNAS_OVERCLOCK
-+
-+ /* Assert reset to the DDR core */
-+ ldr r0, =SYS_CTRL_RSTEN_SET_CTRL
-+ ldr r1, =1
-+ ldr r2, =SYS_CTRL_RSTEN_DDR_BIT
-+ mov r1, r1, LSL r2
-+ str r1, [r0]
-+
-+ /* Deassert reset to the DDR core */
-+ ldr r0, =SYS_CTRL_RSTEN_CLR_CTRL
-+ str r1, [r0]
-+
-+ /* Turn on the DDR core clock */
-+ ldr r0, =SYS_CTRL_CKEN_SET_CTRL
-+ ldr r1, =1
-+ ldr r2, =SYS_CTRL_CKEN_DDR_BIT
-+ mov r1, r1, LSL r2
-+ str r1, [r0]
-+
-+ /* Start using the initialisation value list */
-+ adrl r3, init_table
-+
-+ /* Copy next 6 entries from DDR init table*/
-+ ldr r4, =6
-+loop0:
-+ ldmia r3!, {r1, r2}
-+ str r2, [r1]
-+ subs r4, r4, #1
-+ bne loop0
-+
-+ /* Delay for 200uS while DRAM controller stabilises. */
-+ ldr r0, =DELAY_200US
-+ bl delay
-+
-+#if !TEST_BRD
-+ /* Copy next entry */
-+ ldr r4, =1
-+loopx:
-+ ldmia r3!, {r1, r2}
-+ str r2, [r1]
-+ subs r4, r4, #1
-+ bne loopx
-+
-+ /* Delay for 200uS while DRAM controller stabilises. */
-+ ldr r0, =DELAY_200US
-+ bl delay
-+#endif // TEST_BRD
-+
-+ /* Copy next entry */
-+ ldr r4, =1
-+loop1:
-+ ldmia r3!, {r1, r2}
-+ str r2, [r1]
-+ subs r4, r4, #1
-+ bne loop1
-+
-+ /* Delay for 200uS while DRAM controller stabilises. */
-+ ldr r0, =DELAY_200US
-+ bl delay
-+
-+ /* Copy next entry */
-+ ldr r4, =1
-+loop2:
-+ ldmia r3!, {r1, r2}
-+ str r2, [r1]
-+ subs r4, r4, #1
-+ bne loop2
-+
-+ /* Delay for 200uS while DRAM controller stabilises. */
-+ ldr r0, =DELAY_200US
-+ bl delay
-+
-+ /* Copy next entry */
-+ ldr r4, =1
-+loop3:
-+ ldmia r3!, {r1, r2}
-+ str r2, [r1]
-+ subs r4, r4, #1
-+ bne loop3
-+
-+ /* Delay for 200uS while DRAM controller stabilises. */
-+ ldr r0, =DELAY_200US
-+ bl delay
-+
-+ /* Copy next 5 entries */
-+ ldr r4, =5
-+loop4:
-+ ldmia r3!, {r1, r2}
-+ str r2, [r1]
-+ subs r4, r4, #1
-+ bne loop4
-+
-+ /* SDRAM initialised so now exit. */
-+ mov lr, r6
-+ mov pc, lr
-+
-+/*
-+ * delay()
-+ *
-+ * uses 1 + r0 * 5 cycles
-+ */
-+delay:
-+ nop
-+ nop
-+ nop
-+ subs r0, r0, #1
-+ bne delay
-+ mov pc, lr
-+
-+_platformsetup:
-+ .word platformsetup
-+
-+init_table:
-+ /* Table of address, data for loading into the DRAM controller */
-+ /* Configure for a single DDR device */
-+ .word 0x4500002C, 0x08
-+ .word 0x45000038, 0x400
-+ .word 0x45800000, 0x80100000
-+ .word 0x45800004, 0x8000ffff // Enable DDR core and all clients
-+ .word 0x45800024, 0x1e4
-+ .word 0x45800014, 0xe0000001 // DLL to automatic with starting value=1
-+/* 200uS delay */
-+#if !TEST_BRD
-+ .word 0x45800014, 0xa0000003 // DLL to automatic with offset value=3
-+/* 200uS delay */
-+#endif // TEST_BRD
-+#if (MEM_SIZE == 32)
-+ .word 0x45800000, 0x801B030C
-+#else
-+ .word 0x45800000, 0x801D030C
-+#endif // MEM_SIZE
-+/* 200uS delay */
-+ .word 0x4580000c, 0x80280400
-+/* 200uS delay */
-+ .word 0x4580000c, 0x80210000
-+/* 200uS delay */
-+ .word 0x4580000c, 0x80200063
-+ .word 0x45800028, 0x0000001f // Enable all arbiter features
-+ .word 0x45800018, 0x00000000 // Disable all monitoring
-+ .word 0x45800010, 0xffffffff // Disable all read buffering, due to h/w bug
-+ .word 0x4580002C, 0x00000000 // Do NOT disable HPROT, ie want write coherency
-+
-+.ltorg
-+
-diff -Nurd u-boot-1.1.2/board/oxnas/platform-810.S u-boot-1.1.2-oxe810/board/oxnas/platform-810.S
---- u-boot-1.1.2/board/oxnas/platform-810.S 1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/board/oxnas/platform-810.S 2008-06-11 17:55:18.000000000 +0200
-@@ -0,0 +1,477 @@
-+/*
-+ * Board specific setup info
-+ *
-+ * (C) Copyright 2005
-+ * Oxford Semiconductor Ltd
-+ *
-+ * See file CREDITS for list of people who contributed to this
-+ * project.
-+ *
-+ * 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 <config.h>
-+#include <version.h>
-+
-+/* use estimate of processor speed to calculate number of cycles delay */
-+/* delay count is nominal (PLL200 frequency x delay time) / loop count
-+ * expressing 200us as 200/1000000 and re-arranging gives the expression below
-+ */
-+
-+#define DELAY_200US ((NOMINAL_ARMCLK / (5 * 1000000)) * 200)
-+#define DELAY_300US ((NOMINAL_ARMCLK / (5 * 1000000)) * 300)
-+/* this is 8 cycles of ? so choose 8 resulting in 40 cycles */
-+#define DELAY_1S ((DELAY_200US) * 5000)
-+#define DELAY_8 8
-+#define DELAY_200 200
-+
-+
-+.globl platformsetup
-+platformsetup:
-+/* register allocations
-+ * r0 - delay counter and scratch
-+ * r1 - address register
-+ * r2 - data register
-+ * r3 - index to table pointer
-+ * r4 - iteration counter.
-+ *
-+ * r5 - hold return address.
-+ * lr - (R14) link register
-+ * pc - (R15) program counter.
-+ */
-+
-+#ifdef INITIALISE_SDRAM
-+/*
-+ * Check that not in SDRAM execution. Suicide if re-initialise DRAM.
-+ * Controller function is linked to execute in SDRAM must be in ROM if not
-+ * there. Check for wrong place.
-+ */
-+ adrl r0, platformsetup /* Relative location of function start.*/
-+ ldr r1, _platformsetup
-+ cmp r0, r1
-+ moveq pc, lr
-+#else
-+ mov pc, lr
-+#endif
-+
-+#if (FPGA == 1)
-+ /* Establish a working setup for the SDRAM */
-+ mov r6, lr
-+
-+ /* Assert reset to the DDR core */
-+ ldr r0, =SYS_CTRL_RSTEN_SET_CTRL
-+ ldr r1, =1
-+ ldr r2, =SYS_CTRL_RSTEN_DDR_BIT
-+ mov r1, r1, LSL r2
-+ str r1, [r0]
-+
-+ /* Deassert reset to the DDR core */
-+ ldr r0, =SYS_CTRL_RSTEN_CLR_CTRL
-+ str r1, [r0]
-+
-+ /* Turn on the DDR core clock */
-+ ldr r0, =SYS_CTRL_CKEN_SET_CTRL
-+ ldr r1, =1
-+ ldr r2, =SYS_CTRL_CKEN_DDR_BIT
-+ mov r1, r1, LSL r2
-+ str r1, [r0]
-+
-+ /* Start using the initialisation value list */
-+ adrl r3, init_table
-+
-+ /* Copy first 6 entries */
-+ ldr r4, =6
-+loop0:
-+ ldmia r3!, {r1, r2}
-+ str r2, [r1]
-+ subs r4, r4, #1
-+ bne loop0
-+
-+ /* Delay for 200uS while DRAM controller stabilises. */
-+ ldr r0, =DELAY_200US
-+ bl delay
-+
-+ /* Copy next 4 entries */
-+ ldr r4, =4
-+loop1:
-+ ldmia r3!, {r1, r2}
-+ str r2, [r1]
-+ subs r4, r4, #1
-+ bne loop1
-+
-+ /* Wait at least 200 clock cycles. */
-+ ldr r0, =DELAY_200
-+ bl delay
-+
-+ /* Copy next 2 entries */
-+ ldr r4, =2
-+loop2:
-+ ldmia r3!, {r1, r2}
-+ str r2, [r1]
-+ subs r4, r4, #1
-+ bne loop2
-+
-+ /* Wait at least 8 clock cycles. */
-+ ldr r0, =DELAY_8
-+ bl delay
-+
-+ /* Copy next 9 entries */
-+ ldr r4, =9
-+loop3:
-+ ldmia r3!, {r1, r2}
-+ str r2, [r1]
-+ subs r4, r4, #1
-+ bne loop3
-+
-+ /* SDRAM initialised so now exit. */
-+ mov lr, r6
-+ mov pc, lr
-+
-+/*
-+ * delay()
-+ *
-+ * uses 1 + r0 * 5 cycles
-+ */
-+delay:
-+ nop
-+ nop
-+ nop
-+ subs r0, r0, #1
-+ bne delay
-+ mov pc, lr
-+
-+_platformsetup:
-+ .word platformsetup
-+#else // ASIC, (DDR-2)
-+/*
-+ * Check that not in SDRAM execution. Suicide if re-initialise DRAM.
-+ * Controller function is linked to execute in SDRAM must be in ROM if not
-+ * there. Check for wrong place.
-+ */
-+ /* Establish a working setup for the SDRAM */
-+ mov r6, lr
-+
-+#ifdef OVERCLOCK
-+ /*
-+ change clock speed on chip
-+ */
-+
-+ /* read SYS_CTRL_PLLSYS_CTRL into r3*/
-+ mov r5, #0x45000000
-+ ldr r3, [r5, #72]
-+
-+ /* load the value at dllkey (0xbeadface) into r7 */
-+ adrl r7, dllkey
-+ ldr r7, [r7]
-+
-+ /* pll_sys |= 0x20000; */
-+ orr r3, r3, #131072 /* 0x20000 */
-+
-+ /* write 0xbeadface into SYS_CTRL_PLLSYS_KEY_CTRL */
-+ str r7, [r5, #108]
-+
-+ /* write pll_sys (bypass pll)*/
-+ str r3, [r5, #72]
-+
-+ /* pll_sys &= 0xff000000; */
-+ mov r4, r3, lsr #16
-+ mov r4, r4, lsl #16
-+
-+ /* pll_sys |= 0x00F00061 */
-+ orr r4, r4, #15728640 /* 0xf00000 */
-+ orr r4, r4, #97 /* 0x61 */
-+#if 0
-+ orr r4, r4, #7864320 /* 0x780000 */
-+ orr r4, r4, #96 /* 0x60 */
-+#endif
-+
-+ /* write 0xbeadface into SYS_CTRL_PLLSYS_KEY_CTRL */
-+ str r7, [r5, #108]
-+
-+ /* write pll_sys (with new pll speeds) */
-+ str r4, [r5, #72]
-+
-+ /* delay 300us */
-+ ldr r0, =DELAY_300US
-+ bl delay
-+
-+ /* clear bypass pll bit */
-+ bic r4, r4, #131072 /* 0x20000 */
-+
-+ /* write 0xbeadface into SYS_CTRL_PLLSYS_KEY_CTRL */
-+ str r7, [r5, #108]
-+
-+ /* write pll_sys (with new pll speeds and pll un-bypassed) */
-+ str r4, [r5, #72]
-+#endif /* OVERCLOCK */
-+
-+ /* Turn on the DDR core and phy clocks */
-+ ldr r0, =SYS_CTRL_CKEN_SET_CTRL
-+ ldr r1, =1
-+ ldr r2, =SYS_CTRL_CKEN_DDR_BIT
-+ mov r1, r1, LSL r2
-+ str r1, [r0]
-+ ldr r1, =1
-+ ldr r2, =SYS_CTRL_CKEN_DDR_PHY_BIT
-+ mov r1, r1, LSL r2
-+ str r1, [r0]
-+
-+ /* Assert reset to the DDR core and phy */
-+ ldr r0, =SYS_CTRL_RSTEN_SET_CTRL
-+ ldr r1, =1
-+ ldr r2, =SYS_CTRL_RSTEN_DDR_PHY_BIT
-+ mov r1, r1, LSL r2
-+ str r1, [r0]
-+ ldr r1, =1
-+ ldr r2, =SYS_CTRL_RSTEN_DDR_BIT
-+ mov r1, r1, LSL r2
-+ str r1, [r0]
-+
-+ /* Deassert reset to the DDR core and phy*/
-+ ldr r0, =SYS_CTRL_RSTEN_CLR_CTRL
-+ ldr r1, =1
-+ ldr r2, =SYS_CTRL_RSTEN_DDR_PHY_BIT
-+ mov r1, r1, LSL r2
-+ str r1, [r0]
-+ ldr r1, =1
-+ ldr r2, =SYS_CTRL_RSTEN_DDR_BIT
-+ mov r1, r1, LSL r2
-+ str r1, [r0]
-+
-+ /* Start using the initialisation value list */
-+ adrl r3, init_table
-+
-+ /* Copy first 14 entries of DDR core setup (section A)*/
-+ ldr r4, =14
-+loop0:
-+ ldmia r3!, {r1, r2}
-+ str r2, [r1]
-+ subs r4, r4, #1
-+ bne loop0
-+
-+ /* Delay for 200uS while DDR controller stabilises. */
-+ ldr r0, =DELAY_200US
-+ bl delay
-+
-+ /* Copy next 13 entries of DDR device commands (section B)*/
-+ ldr r4, =13
-+loop1:
-+ ldmia r3!, {r1, r2}
-+ str r2, [r1]
-+
-+ /* Wait at least 200 clock cycles between ram chip command writes */
-+ ldr r0, =DELAY_200
-+ bl delay
-+
-+ subs r4, r4, #1
-+ bne loop1
-+
-+ /* Copy final DDR controller setup to set memory size/banks (section C)*/
-+ ldmia r3!, {r1, r2}
-+ str r2, [r1]
-+
-+#if (PROBE_MEM_SIZE == 1)
-+ /* Load the probe values into SDRAM */
-+ adrl r3, probe_table
-+ mov r4, #4
-+.globl pl1
-+pl1:
-+ ldmia r3!, {r1, r2}
-+ str r2, [r1]
-+ subs r4, r4, #1
-+ bne pl1
-+
-+ /* Get the current contents of the DDR controller core's config register */
-+ adrl r1, ddr_config_reg
-+ ldr r1, [r1]
-+ ldr r1, [r1]
-+
-+ /* Zero the number of banks field - bit 23*/
-+ mov r2, #1
-+ bic r1, r1, r2, lsl #23
-+
-+ /* Zero the size field - bits 17-20 inclusive */
-+ mov r2, #15
-+ bic r1, r1, r2, lsl #17
-+
-+ /* First probe location tells us the SDRAM size */
-+ adrl r3, probe_table
-+ ldr r0, [r3]
-+ ldr r0, [r0]
-+
-+ /* Is size 64MB? */
-+ ldr r2, [r3, #28] /* Get probe value 4 */
-+ cmp r0, r2
-+ moveq r4, #6
-+ orreq r1, r1, r4, lsl #17
-+ beq pl2
-+
-+ /* Is 128M or 256M so set banks to 8 */
-+ mov r4, #1
-+ orr r1, r1, r4, lsl #23
-+
-+ /* Is size 128MB? */
-+ ldr r2, [r3, #20] /* Get probe value 3 */
-+ cmp r0, r2
-+// moveq r4, #7
-+ moveq r4, #8 /* DDR controller does not work at 128M, use 256M instead
-+ orreq r1, r1, r4, lsl #17
-+ beq pl2
-+
-+ /* Must be 256MB, or something is very wrong */
-+ mov r4, #8
-+ orr r1, r1, r4, lsl #17
-+
-+pl2:
-+ /* Write the revised contents to the DDR controller core's config register */
-+ adrl r2, ddr_config_reg
-+ ldr r2, [r2]
-+ str r1, [r2]
-+#endif
-+
-+ /* SDRAM setup complete */
-+ mov lr, r6
-+ mov pc, lr
-+
-+/*
-+ * delay()
-+ *
-+ * uses 1 + r0 * 5 cycles
-+ */
-+delay:
-+ nop
-+ nop
-+ nop
-+ subs r0, r0, #1
-+ bne delay
-+ mov pc, lr
-+
-+_platformsetup:
-+ .word platformsetup
-+#endif
-+
-+
-+init_table:
-+#if (FPGA == 1)
-+ /* Table of address, data for loading into the DRAM controller on FPGA */
-+ .word 0x45800000, 0x000d0000 // Enable the DDR in SDR mode and width 32 bits
-+ .word 0x45800034, 0x04442032 // SDR mode timings - #0
-+ .word 0x45800038, 0x570A0907 // SDR mode timings - #1
-+ .word 0x4580003C, 0x00000002 // SDR mode timings - #2
-+ .word 0x45800004, 0x80000000 // Enable DDR core, but not clients yet
-+ .word 0x45800014, 0x80000001 // Enable CK and set DLL mode to manual
-+/* 200uS delay */
-+ .word 0x4580000c, 0x80200000 // Assert CKE for all further commands
-+ .word 0x4580000c, 0x80280400 // Issue precharge to all banks
-+ .word 0x4580000c, 0x80200000 // NOP, as only DDR has real command here
-+ .word 0x4580000c, 0x80200022 // Set burst length 4, sequential CAS 2
-+/* 200uS delay */
-+ .word 0x4580000c, 0x80280400 // Issue precharge to all banks
-+ .word 0x4580000c, 0x80240000 // Issue auto-refresh command, CKE not asserted
-+/* 200uS delay */
-+ .word 0x4580000c, 0x80240000 // Issue auto-refresh command, CKE not asserted
-+ .word 0x4580000c, 0x80200000 // Assert CKE for all further commands
-+ .word 0x4580000c, 0x80200022 // Set burst length 4, sequential CAS 2
-+ .word 0x45800000, 0x000d0186 // SDR, size and width and refresh rate, assuming
-+ // 25Mhz clk to SDR, divide down to get 15.625uS
-+ // refresh rate
-+ .word 0x45800024, 0x00000124 // Set I/O drive strengths
-+ .word 0x45800028, 0x0000001f // Enable all arbiter features
-+ .word 0x45800018, 0x00000000 // Disable all monitoring
-+ .word 0x45800010, 0xFFFFFFFF // Disable all read buffering
-+ .word 0x45800004, 0x800000ff // Enable all client interfaces
-+#else // ASIC DDR-2
-+ // SECTION A - DDR controller core configuration
-+ .word 0x45800000, 0x802d0591 // enable in ddr-2 mode 16 bit wide
-+ .word 0x45800034, 0x04442032 // ddr-2 mode timings
-+ .word 0x45800038, 0x870f0b25 // ddr-2 mode timings
-+ .word 0x4580003c, 0x00000a23 // ddr-2 mode timings
-+ .word 0x45800054, 0x00072000 // phy-3 settings
-+ .word 0x45800050, 0x00022828 // phy-2 settings, start
-+ .word 0x45800050, 0x00032828 // phy-2 settings, on
-+ .word 0x45800028, 0x0000001f // Enable all arbiter features
-+ .word 0x45800018, 0x00000000 // Disable all monitoring
-+ .word 0x45800010, 0xffff0000 // Enable all read buffering
-+ .word 0x4580002c, 0x00ff00fd // no burst accl, no hprot on arm data
-+ .word 0x45800040, 0x00000000 // enable burst and read cache
-+ .word 0x45800044, 0xffff0000 // enable write behind prot, disable timeout
-+ .word 0x45800004, 0x8000ffff // Enable all client interfaces
-+/* 200uS delay after configuring DDR controller core */
-+
-+ // SECTION B - Memory device configuration
-+ .word 0x4580000c, 0x807c0000 // exit something or other
-+ .word 0x4580000c, 0x803c0000 // nop - wake up
-+ .word 0x4580000c, 0x80280400 // precharge all
-+ .word 0x4580000c, 0x80220000 // emr2
-+ .word 0x4580000c, 0x80230000 // emr3
-+
-+#if (MEM_ODT == 150)
-+ .word 0x4580000c, 0x80210042 // enable dll, odt to 150
-+#elif (MEM_ODT == 75)
-+ .word 0x4580000c, 0x80210006 // enable dll, odt to 75
-+#elif (MEM_ODT == 50)
-+ .word 0x4580000c, 0x80210046 // enable dll, odt to 50
-+#else
-+#error Unsupported memory on-die termination, set MEM_ODT to 50, 75, or 150
-+#endif
-+
-+ .word 0x4580000c, 0x80200733 // set WR CL BL and reset dll
-+ .word 0x4580000c, 0x80280400 // precharge all
-+ .word 0x4580000c, 0x80240000 // auto refresh
-+ .word 0x4580000c, 0x80240000 // auto refresh
-+ .word 0x4580000c, 0x80200733 // set WR CL BL and reset dll
-+
-+#if (MEM_ODT == 150)
-+ .word 0x4580000c, 0x802103c2 // enable OCD
-+ .word 0x4580000c, 0x80210042 // disable OCD
-+#elif (MEM_ODT == 75)
-+ .word 0x4580000c, 0x80210386 // enable OCD
-+ .word 0x4580000c, 0x80210006 // disable OCD
-+#elif (MEM_ODT == 50)
-+ .word 0x4580000c, 0x802103c6 // enable OCD
-+ .word 0x4580000c, 0x80210046 // disable OCD
-+#else
-+#error Unsupported memory on-die termination, set MEM_ODT to 50, 75, or 150
-+#endif
-+
-+ // SECTION C - Final memory size/bank configuration
-+#if (PROBE_MEM_SIZE == 1)
-+ .word 0x45800000, 0x80b10591 // 256M, 8 banks, 1425 clocks for 7.8us refresh.
-+#elif (MEM_SIZE == 64)
-+ .word 0x45800000, 0x802d0591 // 64M, 4 banks, 1425 clocks for 7.8us refresh.
-+#elif (MEM_SIZE == 128)
-+ .word 0x45800000, 0x80af0591 // 128M, 8 banks, 1425 clocks for 7.8us refresh.
-+#elif (MEM_SIZE == 256)
-+ .word 0x45800000, 0x80b10591 // 256M, 8 banks, 1425 clocks for 7.8us refresh.
-+#else
-+#error Unsupported memory size, set MEM_SIZE to 64, 128 or 256
-+#endif
-+
-+#endif // FPGA or ASIC
-+dllkey:
-+ .word 0xbeadface
-+
-+ddr_config_reg:
-+ .word 0x45800000
-+
-+probe_table:
-+ .word 0x48000000, 0x12345678
-+ .word 0x48000040, 0xdeadbeef
-+ .word 0x50000000, 0xfafafafa
-+ .word 0x50000040, 0xabcdef01
-+
-+.ltorg
-+
-diff -Nurd u-boot-1.1.2/board/oxnas/u-boot.lds u-boot-1.1.2-oxe810/board/oxnas/u-boot.lds
---- u-boot-1.1.2/board/oxnas/u-boot.lds 1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/board/oxnas/u-boot.lds 2008-06-11 17:55:18.000000000 +0200
-@@ -0,0 +1,50 @@
-+/*
-+ * (C) Copyright 2002
-+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
-+ *
-+ * See file CREDITS for list of people who contributed to this
-+ * project.
-+ *
-+ * 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
-+ */
-+
-+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-+OUTPUT_ARCH(arm)
-+ENTRY(_start)
-+SECTIONS
-+{
-+ . = 0x00000000;
-+ . = ALIGN(4);
-+ .text :
-+ {
-+ cpu/arm926ejs/start.o (.text)
-+ *(.text)
-+ }
-+ .rodata : { *(.rodata) }
-+ . = ALIGN(4);
-+ .data : { *(.data) }
-+ . = ALIGN(4);
-+ .got : { *(.got) }
-+
-+ __u_boot_cmd_start = .;
-+ .u_boot_cmd : { *(.u_boot_cmd) }
-+ __u_boot_cmd_end = .;
-+
-+ . = ALIGN(4);
-+ __bss_start = .;
-+ .bss : { *(.bss) }
-+ _end = .;
-+}
-diff -Nurd u-boot-1.1.2/common/cmd_ext2.c u-boot-1.1.2-oxe810/common/cmd_ext2.c
---- u-boot-1.1.2/common/cmd_ext2.c 2004-12-16 18:34:53.000000000 +0100
-+++ u-boot-1.1.2-oxe810/common/cmd_ext2.c 2008-06-11 17:55:30.000000000 +0200
-@@ -223,7 +223,7 @@
- PRINTF("Using device %s%d, partition %d\n", argv[1], dev, part);
-
- if (part != 0) {
-- if (get_partition_info (&dev_desc[dev], part, &info)) {
-+ if (get_partition_info (dev_desc, part, &info)) {
- printf ("** Bad partition %d **\n", part);
- return(1);
- }
-diff -Nurd u-boot-1.1.2/common/cmd_ide.c u-boot-1.1.2-oxe810/common/cmd_ide.c
---- u-boot-1.1.2/common/cmd_ide.c 2004-12-31 10:32:50.000000000 +0100
-+++ u-boot-1.1.2-oxe810/common/cmd_ide.c 2008-06-11 17:55:30.000000000 +0200
-@@ -193,6 +193,13 @@
- static void set_pcmcia_timing (int pmode);
- #endif
-
-+#ifdef CONFIG_OXNAS
-+extern unsigned char oxnas_sata_inb(int dev, int port);
-+extern void oxnas_sata_outb(int dev, int port, unsigned char val);
-+extern void oxnas_sata_output_data(int dev, ulong *sect_buf, int words);
-+extern void oxnas_sata_input_data(int dev, ulong *sect_buf, int words);
-+#endif // CONFIG_OXNAS
-+
- /* ------------------------------------------------------------------------- */
-
- int do_ide (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-@@ -491,175 +498,103 @@
- return rcode;
- }
-
--/* ------------------------------------------------------------------------- */
-
--void ide_init (void)
-+static int ide_probe(int device)
- {
-+ int found = 0;
-+
-+ /* Select device */
-+ udelay(100000); /* 100 ms */
-+ ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
-+ udelay(100000); /* 100 ms */
-
--#ifdef CONFIG_IDE_8xx_DIRECT
-- DECLARE_GLOBAL_DATA_PTR;
-- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-- volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia);
--#endif
- unsigned char c;
-- int i, bus;
--#ifdef CONFIG_AMIGAONEG3SE
-- unsigned int max_bus_scan;
-- unsigned int ata_reset_time;
-- char *s;
-+ int i = 0;
-+ do {
-+ udelay(10000); /* 10 ms */
-+
-+ c = ide_inb(device, ATA_STATUS);
-+ if (++i > (ATA_RESET_TIME * 100)) {
-+ PRINTF("ide_probe() timeout\n");
-+ ide_led((LED_IDE1 | LED_IDE2), 0); /* LED's off */
-+ return found;
-+ }
-+ if ((i >= 100) && ((i%100) == 0)) {
-+ putc ('.');
-+ }
-+ } while (c & ATA_STAT_BUSY);
-+
-+ if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) {
-+ PRINTF("ide_probe() status = 0x%02X ", c);
-+#ifndef CONFIG_ATAPI /* ATAPI Devices do not set DRDY */
-+ } else if ((c & ATA_STAT_READY) == 0) {
-+ PRINTF("ide_probe() status = 0x%02X ", c);
- #endif
--#ifdef CONFIG_IDE_8xx_PCCARD
-- extern int pcmcia_on (void);
-- extern int ide_devices_found; /* Initialized in check_ide_device() */
--#endif /* CONFIG_IDE_8xx_PCCARD */
-+ } else {
-+ found = 1;
-+ }
-
--#ifdef CONFIG_IDE_PREINIT
-- extern int ide_preinit (void);
-- WATCHDOG_RESET();
-+ return found;
-+}
-
-- if (ide_preinit ()) {
-- puts ("ide_preinit failed\n");
-+void ide_init(void)
-+{
-+ static int ide_init_called = 0;
-+ int i, bus;
-+
-+ if (ide_init_called) {
- return;
- }
--#endif /* CONFIG_IDE_PREINIT */
--
--#ifdef CONFIG_IDE_8xx_PCCARD
-- extern int pcmcia_on (void);
-- extern int ide_devices_found; /* Initialized in check_ide_device() */
-+ ide_init_called = 1;
-
-+#ifdef CONFIG_IDE_PREINIT
-+ extern int ide_preinit(void);
- WATCHDOG_RESET();
-
-- ide_devices_found = 0;
-- /* initialize the PCMCIA IDE adapter card */
-- pcmcia_on();
-- if (!ide_devices_found)
-+ printf("Initialising disks\n");
-+ if (ide_preinit()) {
-+ puts ("ide_preinit failed\n");
- return;
-- udelay (1000000); /* 1 s */
--#endif /* CONFIG_IDE_8xx_PCCARD */
-+ }
-+#endif /* CONFIG_IDE_PREINIT */
-
- WATCHDOG_RESET();
-
--#ifdef CONFIG_IDE_8xx_DIRECT
-- /* Initialize PIO timing tables */
-- for (i=0; i <= IDE_MAX_PIO_MODE; ++i) {
-- pio_config_clk[i].t_setup = PCMCIA_MK_CLKS(pio_config_ns[i].t_setup,
-- gd->bus_clk);
-- pio_config_clk[i].t_length = PCMCIA_MK_CLKS(pio_config_ns[i].t_length,
-- gd->bus_clk);
-- pio_config_clk[i].t_hold = PCMCIA_MK_CLKS(pio_config_ns[i].t_hold,
-- gd->bus_clk);
-- PRINTF ("PIO Mode %d: setup=%2d ns/%d clk"
-- " len=%3d ns/%d clk"
-- " hold=%2d ns/%d clk\n",
-- i,
-- pio_config_ns[i].t_setup, pio_config_clk[i].t_setup,
-- pio_config_ns[i].t_length, pio_config_clk[i].t_length,
-- pio_config_ns[i].t_hold, pio_config_clk[i].t_hold);
-- }
--#endif /* CONFIG_IDE_8xx_DIRECT */
--
- /* Reset the IDE just to be sure.
- * Light LED's to show
- */
-- ide_led ((LED_IDE1 | LED_IDE2), 1); /* LED's on */
-- ide_reset (); /* ATAPI Drives seems to need a proper IDE Reset */
--
--#ifdef CONFIG_IDE_8xx_DIRECT
-- /* PCMCIA / IDE initialization for common mem space */
-- pcmp->pcmc_pgcrb = 0;
--
-- /* start in PIO mode 0 - most relaxed timings */
-- pio_mode = 0;
-- set_pcmcia_timing (pio_mode);
--#endif /* CONFIG_IDE_8xx_DIRECT */
-+ ide_led((LED_IDE1 | LED_IDE2), 1); /* LED's on */
-+ ide_reset(); /* ATAPI Drives seems to need a proper IDE Reset */
-
- /*
- * Wait for IDE to get ready.
- * According to spec, this can take up to 31 seconds!
- */
--#ifndef CONFIG_AMIGAONEG3SE
-- for (bus=0; bus<CFG_IDE_MAXBUS; ++bus) {
-- int dev = bus * (CFG_IDE_MAXDEVICE / CFG_IDE_MAXBUS);
--#else
-- s = getenv("ide_maxbus");
-- if (s)
-- max_bus_scan = simple_strtol(s, NULL, 10);
-- else
-- max_bus_scan = CFG_IDE_MAXBUS;
--
-- for (bus=0; bus<max_bus_scan; ++bus) {
-- int dev = bus * (CFG_IDE_MAXDEVICE / max_bus_scan);
--#endif
--
--#ifdef CONFIG_IDE_8xx_PCCARD
-- /* Skip non-ide devices from probing */
-- if ((ide_devices_found & (1 << bus)) == 0) {
-- ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */
-- continue;
-- }
--#endif
-- printf ("Bus %d: ", bus);
--
-- ide_bus_ok[bus] = 0;
--
-- /* Select device
-- */
-- udelay (100000); /* 100 ms */
-- ide_outb (dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(dev));
-- udelay (100000); /* 100 ms */
--#ifdef CONFIG_AMIGAONEG3SE
-- ata_reset_time = ATA_RESET_TIME;
-- s = getenv("ide_reset_timeout");
-- if (s) ata_reset_time = 2*simple_strtol(s, NULL, 10);
--#endif
-- i = 0;
-- do {
-- udelay (10000); /* 10 ms */
--
-- c = ide_inb (dev, ATA_STATUS);
-- i++;
--#ifdef CONFIG_AMIGAONEG3SE
-- if (i > (ata_reset_time * 100)) {
--#else
-- if (i > (ATA_RESET_TIME * 100)) {
--#endif
-- puts ("** Timeout **\n");
-- ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */
--#ifdef CONFIG_AMIGAONEG3SE
-- /* If this is the second bus, the first one was OK */
-- if (bus != 0) {
-- ide_bus_ok[bus] = 0;
-- goto skip_bus;
-- }
--#endif
-- return;
-- }
-- if ((i >= 100) && ((i%100)==0)) {
-- putc ('.');
-- }
-- } while (c & ATA_STAT_BUSY);
-+ printf("Detecting SATA busses:\n");
-+ for (bus=0; bus < CFG_IDE_MAXBUS; ++bus) {
-+ printf("Bus %d: ", bus);
-
-- if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) {
-- puts ("not available ");
-- PRINTF ("Status = 0x%02X ", c);
--#ifndef CONFIG_ATAPI /* ATAPI Devices do not set DRDY */
-- } else if ((c & ATA_STAT_READY) == 0) {
-- puts ("not available ");
-- PRINTF ("Status = 0x%02X ", c);
--#endif
-- } else {
-- puts ("OK ");
-- ide_bus_ok[bus] = 1;
-- }
-- WATCHDOG_RESET();
-- }
-+ /* Try to discover if bus is present by probing first device on bus */
-+ int device = bus * (CFG_IDE_MAXDEVICE / CFG_IDE_MAXBUS);
-+ ide_bus_ok[bus] = ide_probe(device);
-+ if (ide_bus_ok[bus]) {
-+ puts("Found first device OK\n");
-+ } else {
-+ WATCHDOG_RESET();
-+
-+ /* Try second device on bus */
-+ ide_bus_ok[bus] = ide_probe(++device);
-+ if (ide_bus_ok[bus]) {
-+ puts("Found second device OK\n");
-+ } else {
-+ puts("No devices found\n");
-+ }
-+ }
-
--#ifdef CONFIG_AMIGAONEG3SE
-- skip_bus:
--#endif
-- putc ('\n');
-+ WATCHDOG_RESET();
-+ }
-
-- ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */
-+ ide_led((LED_IDE1 | LED_IDE2), 0); /* LED's off */
-
- curr_device = -1;
- for (i=0; i<CFG_IDE_MAXDEVICE; ++i) {
-@@ -675,13 +610,12 @@
- ide_dev_desc[i].block_read=ide_read;
- if (!ide_bus_ok[IDE_BUS(i)])
- continue;
-- ide_led (led, 1); /* LED on */
-+ ide_led(led, 1); /* LED on */
- ide_ident(&ide_dev_desc[i]);
-- ide_led (led, 0); /* LED off */
-+ ide_led(led, 0); /* LED off */
- dev_print(&ide_dev_desc[i]);
--/* ide_print (i); */
- if ((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) {
-- init_part (&ide_dev_desc[i]); /* initialize partition type */
-+ init_part(&ide_dev_desc[i]); /* initialize partition type */
- if (curr_device < 0)
- curr_device = i;
- }
-@@ -689,6 +623,11 @@
- WATCHDOG_RESET();
- }
-
-+int is_device_present(int device_number)
-+{
-+ return ide_dev_desc[device_number].part_type != PART_TYPE_UNKNOWN;
-+}
-+
- /* ------------------------------------------------------------------------- */
-
- block_dev_desc_t * ide_get_dev(int dev)
-@@ -798,6 +737,11 @@
- EIEIO;
- *((uchar *)(ATA_CURR_BASE(dev)+port)) = val;
- }
-+#elif defined(CONFIG_OXNAS)
-+static void __inline__ ide_outb(int dev, int port, unsigned char val)
-+{
-+ oxnas_sata_outb(dev, port, val);
-+}
- #else /* ! __PPC__ */
- static void __inline__
- ide_outb(int dev, int port, unsigned char val)
-@@ -819,6 +763,11 @@
- dev, port, (ATA_CURR_BASE(dev)+port), val);
- return (val);
- }
-+#elif defined(CONFIG_OXNAS)
-+static unsigned char __inline__ ide_inb(int dev, int port)
-+{
-+ return oxnas_sata_inb(dev, port);
-+}
- #else /* ! __PPC__ */
- static unsigned char __inline__
- ide_inb(int dev, int port)
-@@ -921,6 +870,11 @@
- }
- #endif /* CONFIG_HMI10 */
- }
-+#elif defined(CONFIG_OXNAS)
-+static void output_data(int dev, ulong *sect_buf, int words)
-+{
-+ oxnas_sata_output_data(dev, sect_buf, words);
-+}
- #else /* ! __PPC__ */
- static void
- output_data(int dev, ulong *sect_buf, int words)
-@@ -968,6 +922,11 @@
- }
- #endif /* CONFIG_HMI10 */
- }
-+#elif defined(CONFIG_OXNAS)
-+static void input_data(int dev, ulong *sect_buf, int words)
-+{
-+ oxnas_sata_input_data(dev, sect_buf, words);
-+}
- #else /* ! __PPC__ */
- static void
- input_data(int dev, ulong *sect_buf, int words)
-@@ -1001,10 +960,36 @@
-
- /* -------------------------------------------------------------------------
- */
-+#ifdef CONFIG_OXNAS
-+static void byte_swap_and_trim(char* buf)
-+{
-+ char *src = buf;
-+
-+ // Swap bytes in 16-bit words
-+ while ((*src != '\0') && (*(src+1) != '\0')) {
-+ char tmp = *(src+1);
-+ *(src+1) = *src;
-+ *src = tmp;
-+ src += 2;
-+ }
-+
-+ // Trim leading spaces
-+ src = buf;
-+ while (*src == ' ') {
-+ ++src;
-+ }
-+ if (src != buf) {
-+ memcpy(buf, src, strlen(src));
-+ buf[strlen(buf) - (src-buf)] = '\0';
-+ }
-+}
-+#endif // CONFIG_OXNAS
-+
- static void ide_ident (block_dev_desc_t *dev_desc)
- {
- ulong iobuf[ATA_SECTORWORDS];
- unsigned char c;
-+ unsigned int i;
- hd_driveid_t *iop = (hd_driveid_t *)iobuf;
-
- #ifdef CONFIG_AMIGAONEG3SE
-@@ -1023,6 +1008,10 @@
- device=dev_desc->dev;
- printf (" Device %d: ", device);
-
-+ for ( i=0; i < ATA_SECTORWORDS; ++i) {
-+ iobuf[i] = 0;
-+ }
-+
- #ifdef CONFIG_AMIGAONEG3SE
- s = getenv("ide_maxbus");
- if (s) {
-@@ -1110,20 +1099,22 @@
-
- input_swap_data (device, iobuf, ATA_SECTORWORDS);
-
-- ident_cpy (dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision));
-- ident_cpy (dev_desc->vendor, iop->model, sizeof(dev_desc->vendor));
-- ident_cpy (dev_desc->product, iop->serial_no, sizeof(dev_desc->product));
-+ ident_cpy(dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision));
-+ ident_cpy(dev_desc->vendor, iop->model, sizeof(dev_desc->vendor));
-+ ident_cpy(dev_desc->product, iop->serial_no, sizeof(dev_desc->product));
-+
- #ifdef __LITTLE_ENDIAN
- /*
-- * firmware revision and model number have Big Endian Byte
-+ * firmware revision, model number and product have Big Endian Byte
- * order in Word. Convert both to little endian.
- *
- * See CF+ and CompactFlash Specification Revision 2.0:
- * 6.2.1.6: Identfy Drive, Table 39 for more details
- */
-
-- strswab (dev_desc->revision);
-- strswab (dev_desc->vendor);
-+ byte_swap_and_trim(dev_desc->revision);
-+ byte_swap_and_trim(dev_desc->vendor);
-+ byte_swap_and_trim(dev_desc->product);
- #endif /* __LITTLE_ENDIAN */
-
- if ((iop->config & 0x0080)==0x0080)
-diff -Nurd u-boot-1.1.2/common/cmd_ledfail.c u-boot-1.1.2-oxe810/common/cmd_ledfail.c
---- u-boot-1.1.2/common/cmd_ledfail.c 1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/common/cmd_ledfail.c 2008-06-11 17:55:30.000000000 +0200
-@@ -0,0 +1,58 @@
-+
-+#include <common.h>
-+#include <command.h>
-+
-+#if (CONFIG_COMMANDS & CFG_CMD_LEDFAIL)
-+#define FAILURE_LED (1 << (34-32))
-+
-+#define GPIO_B 0x44100000
-+#define WARN_GPIO_OUT_REG (GPIO_B + 0x10)
-+#define WARN_GPIO_OUT_ENABLE_SET (GPIO_B + 0x1C)
-+#define WARN_GPIO_OUT_ENABLE_CLR (GPIO_B + 0x20)
-+
-+static void ledfail_light(void)
-+{
-+ printf("Light LED\n");
-+ /* Light the failure LED - assumes active low drive */
-+ u_int32_t led_state = *((volatile u_int32_t *)WARN_GPIO_OUT_REG);
-+ led_state = led_state & ~FAILURE_LED;
-+ *((volatile u_int32_t *)WARN_GPIO_OUT_REG) = led_state;
-+
-+ /* Enable GPIO for output */
-+ *((volatile u_int32_t *)WARN_GPIO_OUT_ENABLE_SET) = FAILURE_LED;
-+}
-+
-+static void ledfail_extinguish(void)
-+{
-+ printf("Extinguish LED\n");
-+ /* Extinguish the failure LED - assumes active low drive */
-+ u_int32_t led_state = *((volatile u_int32_t *)WARN_GPIO_OUT_REG);
-+ led_state = led_state | FAILURE_LED;
-+ *((volatile u_int32_t *)WARN_GPIO_OUT_REG) = led_state;
-+
-+ /* Clear the failure bit output enable in GPIO's */
-+ *((volatile u_int32_t *)WARN_GPIO_OUT_ENABLE_CLR) = FAILURE_LED;
-+}
-+
-+int do_ledfail(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-+{
-+ if (argc != 2) {
-+ printf ("Usage:\n%s\n", cmdtp->usage);
-+ return 1;
-+ }
-+
-+ ulong arg = simple_strtoul(argv[1], NULL, 10);
-+ switch (arg) {
-+ case 0:
-+ ledfail_extinguish();
-+ break;
-+ case 1:
-+ ledfail_light();
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+U_BOOT_CMD(ledfail, 2, 2, do_ledfail, "ledfail - Extinguish (0) or light (1) failure LED\n", NULL);
-+#endif /* CFG_CMD_LEDFAIL */
-diff -Nurd u-boot-1.1.2/common/cmd_mem.c u-boot-1.1.2-oxe810/common/cmd_mem.c
---- u-boot-1.1.2/common/cmd_mem.c 2004-12-16 18:42:39.000000000 +0100
-+++ u-boot-1.1.2-oxe810/common/cmd_mem.c 2008-06-11 17:55:30.000000000 +0200
-@@ -731,13 +731,17 @@
- if (argc > 1) {
- start = (ulong *)simple_strtoul(argv[1], NULL, 16);
- } else {
-- start = (ulong *)CFG_MEMTEST_START;
-+ DECLARE_GLOBAL_DATA_PTR;
-+
-+ start = (ulong *)(gd->bd->bi_dram[0].start);
- }
-
- if (argc > 2) {
- end = (ulong *)simple_strtoul(argv[2], NULL, 16);
- } else {
-- end = (ulong *)(CFG_MEMTEST_END);
-+ DECLARE_GLOBAL_DATA_PTR;
-+
-+ end = (ulong *)(start + gd->bd->bi_dram[0].size);
- }
-
- if (argc > 3) {
-diff -Nurd u-boot-1.1.2/common/cmd_nvedit.c u-boot-1.1.2-oxe810/common/cmd_nvedit.c
---- u-boot-1.1.2/common/cmd_nvedit.c 2004-09-30 00:55:14.000000000 +0200
-+++ u-boot-1.1.2-oxe810/common/cmd_nvedit.c 2008-06-11 17:55:30.000000000 +0200
-@@ -55,8 +55,9 @@
- !defined(CFG_ENV_IS_IN_FLASH) && \
- !defined(CFG_ENV_IS_IN_DATAFLASH) && \
- !defined(CFG_ENV_IS_IN_NAND) && \
-+ !defined(CFG_ENV_IS_IN_DISK) && \
- !defined(CFG_ENV_IS_NOWHERE)
--# error Define one of CFG_ENV_IS_IN_{NVRAM|EEPROM|FLASH|DATAFLASH|NOWHERE}
-+# error Define one of CFG_ENV_IS_IN_{NVRAM|EEPROM|FLASH|DATAFLASH|DISK|NOWHERE}
- #endif
-
- #define XMK_STR(x) #x
-@@ -483,7 +484,7 @@
- * or NULL if not found
- */
-
--char *getenv (uchar *name)
-+char *getenv (const uchar *name)
- {
- int i, nxt;
-
-@@ -530,7 +531,9 @@
- return (-1);
- }
-
--#if defined(CFG_ENV_IS_IN_NVRAM) || defined(CFG_ENV_IS_IN_EEPROM) || \
-+#if defined(CFG_ENV_IS_IN_NVRAM) || \
-+ defined(CFG_ENV_IS_IN_EEPROM) || \
-+ defined(CFG_ENV_IS_IN_DISK) || \
- ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_FLASH)) == \
- (CFG_CMD_ENV|CFG_CMD_FLASH))
- int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-@@ -586,7 +589,9 @@
- " - delete environment variable 'name'\n"
- );
-
--#if defined(CFG_ENV_IS_IN_NVRAM) || defined(CFG_ENV_IS_IN_EEPROM) || \
-+#if defined(CFG_ENV_IS_IN_NVRAM) || \
-+ defined(CFG_ENV_IS_IN_EEPROM) || \
-+ defined(CFG_ENV_IS_IN_DISK) || \
- ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_FLASH)) == \
- (CFG_CMD_ENV|CFG_CMD_FLASH))
- U_BOOT_CMD(
-diff -Nurd u-boot-1.1.2/common/env_common.c u-boot-1.1.2-oxe810/common/env_common.c
---- u-boot-1.1.2/common/env_common.c 2004-06-09 16:58:14.000000000 +0200
-+++ u-boot-1.1.2-oxe810/common/env_common.c 2008-06-11 17:55:30.000000000 +0200
-@@ -42,7 +42,7 @@
- extern void disable_nvram(void);
- #endif
-
--#undef DEBUG_ENV
-+//#undef DEBUG_ENV
- #ifdef DEBUG_ENV
- #define DEBUGF(fmt,args...) printf(fmt ,##args)
- #else
-diff -Nurd u-boot-1.1.2/common/env_disk.c u-boot-1.1.2-oxe810/common/env_disk.c
---- u-boot-1.1.2/common/env_disk.c 1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/common/env_disk.c 2008-06-11 17:55:30.000000000 +0200
-@@ -0,0 +1,152 @@
-+/*
-+ * (C) Copyright 2006
-+ * Oxford Semiconductor Ltd
-+ *
-+ * See file CREDITS for list of people who contributed to this
-+ * project.
-+ *
-+ * 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 <common.h>
-+
-+#if defined(CFG_ENV_IS_IN_DISK)
-+
-+#include <command.h>
-+#include <environment.h>
-+#include <ide.h>
-+
-+extern int is_device_present(int device_number);
-+
-+/* Point to the environment as held in SRAM */
-+env_t *env_ptr = NULL;
-+
-+char *env_name_spec = "Disk";
-+
-+/* The default environment compiled into U-Boot */
-+extern uchar default_environment[];
-+
-+uchar env_get_char_spec(int index)
-+{
-+ DECLARE_GLOBAL_DATA_PTR;
-+
-+ return *((uchar *)(gd->env_addr + index));
-+}
-+
-+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-+
-+void env_relocate_spec(void)
-+{
-+ /* Compute the CRC of the environment in SRAM, copied from disk at boot */
-+ env_t *sram_env = (env_t*)CFG_ENV_ADDR;
-+ ulong crc = crc32(0, sram_env->data, CFG_ENV_SIZE - offsetof(env_t, data));
-+
-+ /* Copy the SRAM environment and CRC to the working environment */
-+ memcpy(env_ptr->data, sram_env->data, CFG_ENV_SIZE - offsetof(env_t, data));
-+ env_ptr->crc = crc;
-+}
-+
-+int saveenv(void)
-+{
-+ /* Compute the CRC of the working environment */
-+ env_ptr->crc = crc32(0, env_ptr->data, CFG_ENV_SIZE - offsetof(env_t, data));
-+
-+ /* Copy the working environment to the reserved area on each disk device */
-+ int status = 1;
-+ int i;
-+ for (i=0; i < CFG_IDE_MAXDEVICE; ++i) {
-+ if (!is_device_present(i)) {
-+ continue;
-+ }
-+
-+ /* Write environment to the main environment area on disk */
-+ unsigned long written = ide_write(i, CFG_ENV_DISK_SECTOR, CFG_ENV_SIZE/512, (ulong*)env_ptr);
-+ if (written != CFG_ENV_SIZE/512) {
-+ printf("Saving environment to disk %d primary image failed\n", i);
-+ status = 0;
-+ } else {
-+ /* Write environment to the redundant environment area on disk */
-+ written = ide_write(i, CFG_ENV_DISK_REDUNDANT_SECTOR, CFG_ENV_SIZE/512, (ulong*)env_ptr);
-+ if (written != CFG_ENV_SIZE/512) {
-+ printf("Saving environment to disk %d secondary image failed\n", i);
-+ status = 0;
-+ }
-+ }
-+ }
-+
-+ return status;
-+}
-+
-+static int check_sram_env_integrity(void)
-+{
-+ DECLARE_GLOBAL_DATA_PTR;
-+
-+ env_t *sram_env = (env_t*)CFG_ENV_ADDR;
-+ ulong crc = crc32(0, sram_env->data, CFG_ENV_SIZE - offsetof(env_t, data));
-+
-+ if (crc == sram_env->crc) {
-+ gd->env_addr = (ulong)sram_env->data;
-+ gd->env_valid = 1;
-+ }
-+
-+ return gd->env_valid;
-+}
-+
-+int env_init(void)
-+{
-+ DECLARE_GLOBAL_DATA_PTR;
-+
-+ /* Have not yet found a valid environment */
-+ gd->env_valid = 0;
-+
-+ /* Need SATA available to load environment from alternate disk locations */
-+ ide_init();
-+
-+ int i;
-+ for (i=0; i < CFG_IDE_MAXDEVICE; ++i) {
-+ if (!is_device_present(i)) {
-+ continue;
-+ }
-+
-+ /* Read environment from the primary environment area on disk */
-+ unsigned long read = ide_read(i, CFG_ENV_DISK_SECTOR, CFG_ENV_SIZE/512, (ulong*)CFG_ENV_ADDR);
-+ if (read == CFG_ENV_SIZE/512) {
-+ /* Check integrity of primary environment data */
-+ if (check_sram_env_integrity()) {
-+ printf("Environment successfully read from disk %d primary image\n", i);
-+ break;
-+ }
-+ }
-+
-+ /* Read environment from the secondary environment area on disk */
-+ read = ide_read(i, CFG_ENV_DISK_REDUNDANT_SECTOR, CFG_ENV_SIZE/512, (ulong*)CFG_ENV_ADDR);
-+ if (read == CFG_ENV_SIZE/512) {
-+ /* Check integrity of secondary environment data */
-+ if (check_sram_env_integrity()) {
-+ printf("Environment successfully read from disk %d secondary image\n", i);
-+ break;
-+ }
-+ }
-+ }
-+
-+ if (!gd->env_valid) {
-+ printf("Failed to read valid environment from disk, using built-in default\n");
-+ gd->env_addr = (ulong)default_environment;
-+ gd->env_valid = 0;
-+ }
-+
-+ return 0;
-+}
-+#endif // CFG_ENV_IS_IN_DISK
-diff -Nurd u-boot-1.1.2/common/main.c u-boot-1.1.2-oxe810/common/main.c
---- u-boot-1.1.2/common/main.c 2004-04-23 22:32:06.000000000 +0200
-+++ u-boot-1.1.2-oxe810/common/main.c 2008-06-11 17:55:30.000000000 +0200
-@@ -182,7 +182,7 @@
- else {
- for (i = 0; i < presskey_max - 1; i ++)
- presskey [i] = presskey [i + 1];
--
-+do_recovery
- presskey [i] = getc();
- }
- }
-@@ -369,6 +369,149 @@
- install_auto_complete();
- #endif
-
-+
-+#if defined(CONFIG_OXNAS)
-+ /* Set the memory size given to Linux */
-+ {
-+ DECLARE_GLOBAL_DATA_PTR;
-+
-+ /* Get a copy of the bootargs string from the runtime environment */
-+ char tempBuf[1024];
-+ char* cmd_string = strcpy(&tempBuf[0], getenv("bootargs"));
-+
-+ /* Find the extent of memory token in the bootargs string */
-+ char* mem_token = strstr(cmd_string, "mem=");
-+ char* mem_token_end = mem_token;
-+ while ((*mem_token_end != ' ') &&
-+ (*mem_token_end != '\0')) {
-+ ++mem_token_end;
-+ }
-+
-+ if ((*mem_token_end == '\0') && (mem_token != mem_token_end)) {
-+ /* Memory token is last in bootargs string */
-+ if (mem_token != cmd_string) {
-+ /* Is not the only token, so erase token and previous space" */
-+ *(mem_token-1) = '\0';
-+ } else {
-+ /* Is the only token, so no previous space to erase */
-+ *mem_token = '\0';
-+ }
-+ } else {
-+ /* Memory token is at intermediate location in bootargs string */
-+ if (*mem_token_end == ' ') {
-+ ++mem_token_end;
-+ }
-+
-+ /* Form the bootargs string without the memory token present */
-+ strcpy(mem_token, mem_token_end);
-+ }
-+
-+ /* How many MB of SDRAM are present */
-+ int megabytes = gd->bd->bi_dram[0].size >> 20;
-+
-+ /* Append the memory token to the bootargs string */
-+ switch (megabytes) {
-+ case 64:
-+ cmd_string = strcat(cmd_string, " mem=64M");
-+ break;
-+ case 128:
-+ cmd_string = strcat(cmd_string, " mem=128M");
-+ break;
-+ case 256:
-+ cmd_string = strcat(cmd_string, " mem=256M");
-+ break;
-+ default:
-+ printf("Unsupported memory size, defaulting to 64M\n");
-+ cmd_string = strcat(cmd_string, " mem=64M");
-+ }
-+
-+ /* Save the revised bootargs string to the runtime environment */
-+ setenv("bootargs", cmd_string);
-+ }
-+
-+/* Upgrade, recovery and power button monitor code
-+*/
-+ int do_recovery = 0; /* default no recovery */
-+
-+ /* Read the upgrade flag from disk into memory */
-+ ide_init();
-+ run_command("ide read 48700000 ff 1", 0);
-+
-+ char upgrade_mode = *(volatile char*)0x48700000;
-+ char recovery_mode = *(volatile char*)0x48700001;
-+ char controlled_pd_mode = *(volatile char*)0x48700002;
-+
-+ if (recovery_mode == RECOVERY_MAGIC) {
-+ do_recovery = 1; /* perform recovery */
-+ }
-+
-+ if (controlled_pd_mode == CONTROLLED_POWER_DOWN_MAGIC) {
-+ /* System in controlled pwer down mode */
-+
-+ /* Read the SRAM location for normal boot flag */
-+ char sram_data = *(volatile char*)(CFG_SRAM_BASE + CFG_SRAM_SIZE - POWER_ON_FLAG_SRAM_OFFSET);
-+ char tempBuf[1024];
-+ char* cmd_string = strcpy(&tempBuf[0], getenv("bootargs"));
-+
-+ if (sram_data == CONTROLLED_POWER_UP_MAGIC) {
-+ /* The system has to remain in power down state */
-+
-+ /* Set appropriate boot args */
-+ cmd_string = strcat(cmd_string, " powermode=controlledpup");
-+ printf("Controlled Power UP requested\n");
-+ } else {
-+ /* The system is moving to power up state from power down state */
-+ cmd_string = strcat(cmd_string, " powermode=controlledpdown");
-+ printf("Controlled Power DOWN requested\n");
-+ }
-+ setenv("bootargs", cmd_string);
-+ }
-+
-+ /* branch off inot recovery or upadate */
-+ if (upgrade_mode == UPGRADE_MAGIC) {
-+ /* Script to select first disk */
-+ parse_string_outer("set select0 ide dev 0", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
-+
-+ /* Script to select second disk */
-+ parse_string_outer("set select1 ide dev 1", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
-+
-+ /* Script for loading 256KB of upgrade rootfs image from hidden sectors */
-+ parse_string_outer("set loadf ide read 48700000 1770 200", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
-+
-+ /* Script for loading 2MB of upgrade kernel image from hidden sectors */
-+ parse_string_outer("set loadk ide read 48800000 1970 1000", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
-+
-+ /* Script to light failure LED */
-+ parse_string_outer("set lightled ledfail 1", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
-+
-+ /* Script to extinguish failure LED */
-+ parse_string_outer("set extinguishled ledfail 0", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
-+
-+ /* Script for booting Linux kernel image with mkimage-wrapped initrd */
-+ parse_string_outer("set boot bootm 48800000 48700000", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
-+
-+ /* Set Linux bootargs to use rootfs in initial ramdisk */
-+ parse_string_outer("set bootargs mem=32M console=ttyS0,115200 root=/dev/ram0", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
-+
-+ /* Validate, load and boot the first validate set of initrd and kernel
-+ Theres alot of combos here due to disk/backup/fk arrangments, it'll
-+ no doubt work on the first or second one though. */
-+ parse_string_outer("run select0 loadf loadk boot || "
-+ "run lightled select1 loadf loadk extinguishled boot || "
-+ "run lightled select0 loadf select1 loadk extinguishled boot || "
-+ "run lightled select1 loadf select0 loadk extinguishled boot || "
-+ "run lightled ", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
-+ } else if (do_recovery) {
-+ printf ("\nRecovery mode selected\n");
-+
-+ char tempBuf[1024];
-+ char* cmd_string = strcpy(&tempBuf[0], getenv("bootargs"));
-+ cmd_string = strcat(cmd_string, " adminmode=recovery");
-+ setenv("bootargs", cmd_string);
-+ }
-+
-+#endif // CONFIG_OXNAS
-+
- #ifdef CONFIG_PREBOOT
- if ((p = getenv ("preboot")) != NULL) {
- # ifdef CONFIG_AUTOBOOT_KEYED
-diff -Nurd u-boot-1.1.2/common/Makefile u-boot-1.1.2-oxe810/common/Makefile
---- u-boot-1.1.2/common/Makefile 2004-12-16 18:35:57.000000000 +0100
-+++ u-boot-1.1.2-oxe810/common/Makefile 2008-06-11 17:55:30.000000000 +0200
-@@ -40,9 +40,10 @@
- cmd_nand.o cmd_net.o cmd_nvedit.o \
- cmd_pci.o cmd_pcmcia.o cmd_portio.o \
- cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_universe.o cmd_usb.o cmd_vfd.o \
-+ cmd_ledfail.o \
- command.o console.o devices.o dlmalloc.o docecc.o \
- environment.o env_common.o \
-- env_nand.o env_dataflash.o env_flash.o env_eeprom.o env_nvram.o env_nowhere.o exports.o \
-+ env_nand.o env_dataflash.o env_flash.o env_eeprom.o env_nvram.o env_nowhere.o env_disk.o exports.o \
- flash.o fpga.o \
- hush.o kgdb.o lcd.o lists.o lynxkdi.o \
- memsize.o miiphybb.o miiphyutil.o \
-diff -Nurd u-boot-1.1.2/cpu/arm926ejs/config.mk u-boot-1.1.2-oxe810/cpu/arm926ejs/config.mk
---- u-boot-1.1.2/cpu/arm926ejs/config.mk 2003-08-30 00:00:47.000000000 +0200
-+++ u-boot-1.1.2-oxe810/cpu/arm926ejs/config.mk 2008-06-11 17:55:03.000000000 +0200
-@@ -21,7 +21,6 @@
- # MA 02111-1307 USA
- #
-
--PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \
-- -mshort-load-bytes -msoft-float
-+PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8
-
--PLATFORM_CPPFLAGS += -mapcs-32 -march=armv4
-+PLATFORM_CPPFLAGS += -march=armv5te
-diff -Nurd u-boot-1.1.2/cpu/arm926ejs/interrupts.c u-boot-1.1.2-oxe810/cpu/arm926ejs/interrupts.c
---- u-boot-1.1.2/cpu/arm926ejs/interrupts.c 2004-03-23 22:43:08.000000000 +0100
-+++ u-boot-1.1.2-oxe810/cpu/arm926ejs/interrupts.c 2008-06-11 17:55:03.000000000 +0200
-@@ -41,7 +41,12 @@
- #include <asm/proc-armv/ptrace.h>
-
- extern void reset_cpu(ulong addr);
-+
-+#ifdef CONFIG_OXNAS
-+#define TIMER_LOAD_VAL 0xffffUL
-+#else // CONFIG_OXNAS
- #define TIMER_LOAD_VAL 0xffffffff
-+#endif // CONFIG_OXNAS
-
- /* macro to read the 32 bit timer */
- #ifdef CONFIG_OMAP
-@@ -53,6 +58,9 @@
- #ifdef CONFIG_VERSATILE
- #define READ_TIMER (*(volatile ulong *)(CFG_TIMERBASE+4))
- #endif
-+#ifdef CONFIG_OXNAS
-+#define READ_TIMER ((*(volatile ushort *)(CFG_TIMERBASE+4)) & 0xFFFFUL) /* RPS timer value register has only 16 defined bits */
-+#endif
-
- #ifdef CONFIG_USE_IRQ
- /* enable IRQ interrupts */
-@@ -212,6 +220,16 @@
- *(volatile ulong *)(CFG_TIMERBASE + 4) = CFG_TIMER_RELOAD; /* TimerValue */
- *(volatile ulong *)(CFG_TIMERBASE + 8) = 0x8C;
- #endif /* CONFIG_VERSATILE */
-+#ifdef CONFIG_OXNAS
-+ // Setup timer 1 load value
-+ *(volatile ulong*)(CFG_TIMERBASE + 0) = TIMER_LOAD_VAL;
-+
-+ // Setup timer 1 prescaler, periodic operation and start it
-+ *(volatile ulong*)(CFG_TIMERBASE + 8) =
-+ (TIMER_PRESCALE_ENUM << TIMER_PRESCALE_BIT) |
-+ (TIMER_MODE_PERIODIC << TIMER_MODE_BIT) |
-+ (TIMER_ENABLE_ENABLE << TIMER_ENABLE_BIT);
-+#endif /* CONFIG_OXNAS */
-
- /* init the timestamp and lastdec value */
- reset_timer_masked();
-diff -Nurd u-boot-1.1.2/cpu/arm926ejs/start.S u-boot-1.1.2-oxe810/cpu/arm926ejs/start.S
---- u-boot-1.1.2/cpu/arm926ejs/start.S 2004-06-09 02:11:01.000000000 +0200
-+++ u-boot-1.1.2-oxe810/cpu/arm926ejs/start.S 2008-06-11 17:55:03.000000000 +0200
-@@ -94,6 +94,11 @@
- _TEXT_BASE:
- .word TEXT_BASE
-
-+#ifdef CONFIG_OXNAS
-+_EXCEPTION_BASE:
-+ .word EXCEPTION_BASE
-+#endif
-+
- .globl _armboot_start
- _armboot_start:
- .word _start
-@@ -135,6 +140,18 @@
- orr r0,r0,#0xd3
- msr cpsr,r0
-
-+#ifdef CONFIG_OXNAS
-+ /*
-+ * Copy exception table to relocated address in internal SRAM
-+ */
-+ adr r0, _start /* Address of exception table in flash */
-+ ldr r1, _EXCEPTION_BASE /* Relocated address of exception table */
-+ ldmia r0!, {r3-r10} /* Copy exception table and jump values from */
-+ stmia r1!, {r3-r10} /* FLASH to relocated address */
-+ ldmia r0!, {r3-r10}
-+ stmia r1!, {r3-r10}
-+#endif
-+
- /*
- * we do sys-critical inits only at reboot,
- * not when booting from ram!
-@@ -143,21 +160,21 @@
- bl cpu_init_crit
- #endif
-
--relocate: /* relocate U-Boot to RAM */
-- adr r0, _start /* r0 <- current position of code */
-- ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
-- cmp r0, r1 /* don't reloc during debug */
-- beq stack_setup
-+relocate: /* relocate U-Boot to RAM */
-+ adr r0, _start /* current position of code */
-+ ldr r1, _TEXT_BASE /* relocated position of code */
-+ cmp r0, r1
-+ beq stack_setup
-
- ldr r2, _armboot_start
- ldr r3, _bss_start
-- sub r2, r3, r2 /* r2 <- size of armboot */
-- add r2, r0, r2 /* r2 <- source end address */
-+ sub r2, r3, r2 /* r2 <- size of armboot */
-+ add r2, r0, r2 /* r2 <- source end address */
-
- copy_loop:
-- ldmia r0!, {r3-r10} /* copy from source address [r0] */
-- stmia r1!, {r3-r10} /* copy to target address [r1] */
-- cmp r0, r2 /* until source end addreee [r2] */
-+ ldmia r0!, {r3-r10} /* copy from source address [r0] */
-+ stmia r1!, {r3-r10} /* copy to target address [r1] */
-+ cmp r0, r2 /* until source end addreee [r2] */
- ble copy_loop
-
- /* Set up the stack */
-@@ -212,7 +229,7 @@
- mrc p15, 0, r0, c1, c0, 0
- bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */
- bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */
-- orr r0, r0, #0x00000002 /* set bit 2 (A) Align */
-+ orr r0, r0, #0x00000002 /* set bit 1 (A) Align */
- orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
- mcr p15, 0, r0, c1, c0, 0
-
-@@ -391,6 +408,7 @@
-
- #endif
-
-+#ifndef CONFIG_OXNAS
- .align 5
- .globl reset_cpu
- reset_cpu:
-@@ -405,3 +423,4 @@
-
- rstctl1:
- .word 0xfffece10
-+#endif // !CONFIG_OXNAS
-diff -Nurd u-boot-1.1.2/drivers/cfi_flash.c u-boot-1.1.2-oxe810/drivers/cfi_flash.c
---- u-boot-1.1.2/drivers/cfi_flash.c 2004-12-18 23:35:45.000000000 +0100
-+++ u-boot-1.1.2-oxe810/drivers/cfi_flash.c 2008-06-11 17:55:31.000000000 +0200
-@@ -1056,7 +1056,11 @@
- }
- tmp = flash_read_long (info, 0,
- FLASH_OFFSET_ERASE_REGIONS +
-+#ifdef FORCE_TOP_BOOT_FLASH
-+ (num_erase_regions - 1 - i) * 4);
-+#else
- i * 4);
-+#endif
- erase_region_size =
- (tmp & 0xffff) ? ((tmp & 0xffff) * 256) : 128;
- tmp >>= 16;
-@@ -1104,6 +1108,7 @@
- cfiptr_t ctladdr;
- cfiptr_t cptr;
- int flag;
-+ ulong start;
-
- ctladdr.cp = flash_make_addr (info, 0, 0);
- cptr.cp = (uchar *) dest;
-@@ -1151,6 +1156,15 @@
- break;
- case FLASH_CFI_16BIT:
- cptr.wp[0] = cword.w;
-+ /* Wait for write to complete */
-+ start = get_timer (0);
-+ while (cptr.wp[0] != cword.w) {
-+ printf(".");
-+ if (get_timer (start) > info->erase_blk_tout * CFG_HZ) {
-+ printf ("Flash write timeout!");;
-+ }
-+ }
-+ printf("\n");
- break;
- case FLASH_CFI_32BIT:
- cptr.lp[0] = cword.l;
-diff -Nurd u-boot-1.1.2/drivers/ns16550.c u-boot-1.1.2-oxe810/drivers/ns16550.c
---- u-boot-1.1.2/drivers/ns16550.c 2004-06-07 01:13:57.000000000 +0200
-+++ u-boot-1.1.2-oxe810/drivers/ns16550.c 2008-06-11 17:55:31.000000000 +0200
-@@ -14,8 +14,25 @@
- #define MCRVAL (MCR_DTR | MCR_RTS) /* RTS/DTR */
- #define FCRVAL (FCR_FIFO_EN | FCR_RXSR | FCR_TXSR) /* Clear & enable FIFOs */
-
-+#ifdef USE_UART_FRACTIONAL_DIVIDER
-+static int oxnas_fractional_divider(NS16550_t com_port, int baud_divisor)
-+{
-+ // Baud rate is passed around x16
-+ int real_divisor = baud_divisor >> 4;
-+ // Top three bits of 8-bit dlf register hold the number of eigths
-+ // for the fractional part of the divide ratio
-+ com_port->dlf = (unsigned char)(((baud_divisor - (real_divisor << 4)) << 4) & 0xFF);
-+ // Return the x1 divider for the normal divider register
-+ return real_divisor;
-+}
-+#endif // USE_UART_FRACTIONAL_DIVIDER
-+
- void NS16550_init (NS16550_t com_port, int baud_divisor)
- {
-+#ifdef USE_UART_FRACTIONAL_DIVIDER
-+ baud_divisor = oxnas_fractional_divider(com_port, baud_divisor);
-+#endif // USE_UART_FRACTIONAL_DIVIDER
-+
- com_port->ier = 0x00;
- #ifdef CONFIG_OMAP1510
- com_port->mdr1 = 0x7; /* mode select reset TL16C750*/
-@@ -33,6 +50,10 @@
-
- void NS16550_reinit (NS16550_t com_port, int baud_divisor)
- {
-+#ifdef USE_UART_FRACTIONAL_DIVIDER
-+ baud_divisor = oxnas_fractional_divider(com_port, baud_divisor);
-+#endif // USE_UART_FRACTIONAL_DIVIDER
-+
- com_port->ier = 0x00;
- com_port->lcr = LCR_BKSE;
- com_port->dll = baud_divisor & 0xff;
-diff -Nurd u-boot-1.1.2/drivers/serial.c u-boot-1.1.2-oxe810/drivers/serial.c
---- u-boot-1.1.2/drivers/serial.c 2003-08-30 00:00:47.000000000 +0200
-+++ u-boot-1.1.2-oxe810/drivers/serial.c 2008-06-11 17:55:31.000000000 +0200
-@@ -59,7 +59,13 @@
- return (26); /* return 26 for base divisor */
- }
- #endif
-- return (CFG_NS16550_CLK / 16 / gd->baudrate);
-+
-+#ifdef USE_UART_FRACTIONAL_DIVIDER
-+ return (((CFG_NS16550_CLK << 4) / gd->baudrate) + 8) >> 4;
-+#endif // USE_UART_FRACTIONAL_DIVIDER
-+
-+ // Round to nearest integer
-+ return (((CFG_NS16550_CLK / gd->baudrate) + 8 ) / 16);
- }
-
- int serial_init (void)
-diff -Nurd u-boot-1.1.2/examples/Makefile u-boot-1.1.2-oxe810/examples/Makefile
---- u-boot-1.1.2/examples/Makefile 2004-10-10 23:27:33.000000000 +0200
-+++ u-boot-1.1.2-oxe810/examples/Makefile 2008-06-11 17:55:30.000000000 +0200
-@@ -30,7 +30,8 @@
- endif
-
- ifeq ($(ARCH),arm)
--LOAD_ADDR = 0xc100000
-+#LOAD_ADDR = 0xc100000
-+LOAD_ADDR = 0x4C004000
- endif
-
- ifeq ($(ARCH),mips)
-@@ -58,6 +59,11 @@
- SREC = hello_world.srec
- BIN = hello_world.bin hello_world
-
-+ifeq ($(ARCH),arm)
-+SREC += mem_test.srec
-+BIN += mem_test.bin mem_test
-+endif
-+
- ifeq ($(ARCH),i386)
- SREC += 82559_eeprom.srec
- BIN += 82559_eeprom.bin 82559_eeprom
-@@ -115,10 +121,10 @@
- $(LD) -g $(EX_LDFLAGS) -Ttext $(LOAD_ADDR) \
- -o $@ -e $(<:.o=) $< $(LIB) \
- -L$(gcclibdir) -lgcc
--%.srec: %
-+%.srec: %.o
- $(OBJCOPY) -O srec $< $@ 2>/dev/null
-
--%.bin: %
-+%.bin: %.o
- $(OBJCOPY) -O binary $< $@ 2>/dev/null
-
- #########################################################################
-diff -Nurd u-boot-1.1.2/examples/mem_test.c u-boot-1.1.2-oxe810/examples/mem_test.c
---- u-boot-1.1.2/examples/mem_test.c 1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/examples/mem_test.c 2008-06-11 17:55:30.000000000 +0200
-@@ -0,0 +1,1322 @@
-+/*
-+ * (C) Copyright 2006
-+ * Oxford Semiconductor Ltd, www.oxsemi.com
-+ * 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
-+ */
-+
-+/********************* OPTIONS ********************************************************/
-+
-+#define ARM
-+/*
-+#define QUIET
-+#define SHORT
-+*/
-+
-+/********************* TEST DEFINITIONS ********************************************************/
-+
-+
-+#define NUM_PATTYPES 5
-+#define PATTYPE_A5 0
-+#define PATTYPE_5A 1
-+#define PATTYPE_NO_FF 2
-+#define PATTYPE_INCR 3
-+#define PATTYPE_DECR 4
-+
-+/* Number of words in a block (to ensure that neither data not ~data is 0xFFxx) */
-+
-+#ifdef SHORT
-+ #define BLOCKWORDS (254*4)
-+ #define BLOCKSIZE (256*4)
-+#else
-+ #define BLOCKWORDS (254*256*4)
-+ #define BLOCKSIZE (256*256*4)
-+#endif
-+
-+#ifdef ARM
-+ #include <common.h>
-+ #include <exports.h>
-+
-+ #define SDRAM_BASE 0x48000000
-+ #define SDRAM_TOP 0x49000000
-+ #define SDRAM_BLOCK 0x10000
-+// #define SDRAM_WRITE(ADDR, DATA) printf("Write 0x%08x to 0x%08x\n", (DATA), (ADDR));
-+// #define SDRAM_READ(ADDR, VAR) printf("Read from 0x%08x\n", (ADDR));
-+// #define SDRAM_WRITE(ADDR, DATA) printf("Write 0x%08x to 0x%08x\n", (DATA), (ADDR)); (*((volatile unsigned int *)(ADDR)) = (DATA))
-+// #define SDRAM_READ(ADDR, VAR) printf("Read from 0x%08x\n", (ADDR)); (*(VAR) = *((volatile unsigned int *)(ADDR)))
-+ #define SDRAM_WRITE(ADDR, DATA) (*((volatile unsigned int *)(ADDR)) = (DATA))
-+ #define SDRAM_READ(ADDR, VAR) (*(VAR) = *((volatile unsigned int *)(ADDR)))
-+#else
-+ #include <stdio.h>
-+ #include <stdlib.h>
-+ /* Not so much space - just 2 blocks from addr 0... */
-+ #define SDRAM_BASE 0
-+ #define SDRAM_TOP (2 * BLOCKSIZE)
-+ #define SDRAM_BLOCK 0x10000
-+ #ifdef QUIET
-+ #define SDRAM_WRITE(ADDR, DATA) array[ADDR] = (DATA)
-+ #define SDRAM_READ(ADDR, VAR) *((volatile unsigned int *)(VAR)) = array[ADDR]
-+ #else
-+ #define SDRAM_WRITE(ADDR, DATA) printf("WRITE(%08x)=%08x\n", ADDR, DATA); array[ADDR] = (DATA)
-+ #define SDRAM_READ(ADDR, VAR) printf("READ (%08x)=%08x\n", ADDR, array[ADDR]); *((volatile unsigned int *)(VAR)) = array[ADDR]
-+ #endif
-+ unsigned volatile int array[SDRAM_TOP];
-+#endif
-+
-+
-+#define SYSCTRL_PRIMSEL_LO 0x4500000C
-+#define SYSCTRL_SECSEL_LO 0x45000014
-+#define SYSCTRL_TERSEL_LO 0x4500008C
-+#define SYSCTRL_PRIMSEL_HI 0x45000010
-+#define SYSCTRL_SECSEL_HI 0x45000018
-+#define SYSCTRL_TERSEL_HI 0x45000090
-+
-+/* GPIO */
-+#define GPIOB_IO_VAL 0x44100000
-+#define GPIOB_OE_VAL 0x44100004
-+#define GPIOB_SET_OE 0x4410001C
-+#define GPIOB_CLEAR_OE 0x44100020
-+#define GPIOB_OUTPUT_VAL 0x44100010
-+#define GPIOB_SET_OUTPUT 0x44100014
-+#define GPIOB_CLEAR_OUTPUT 0x44100018
-+#define GPIOB_BIT_34 0x00000004
-+
-+void configure_caches(void);
-+void report_err(unsigned int address, unsigned int bad_data, unsigned int correct_data, unsigned int iteration);
-+
-+/********************* TYPES.H ********************************************************/
-+
-+typedef unsigned int UINT, *PUINT;
-+/*
-+#ifndef __MY_BASIC_TYPES_H
-+#define __MY_BASIC_TYPES_H
-+
-+typedef signed char CHAR, *PCHAR;
-+typedef unsigned char BYTE, UCHAR, *PBYTE, *PUCHAR;
-+typedef signed short SHORT, *PSHORT;
-+typedef unsigned short WORD, USHORT, *PWORD, *PUSHORT;
-+typedef signed long LONG, *PLONG;
-+typedef unsigned long DWORD, *PDWORD;
-+typedef int BOOL, *PBOOL;
-+typedef unsigned int UINT, *PUINT;
-+typedef void VOID, *PVOID;
-+
-+typedef float SINGLE,*PSINGLE;
-+typedef double DOUBLE,*PDOUBLE;
-+
-+
-+#define FALSE 0
-+#define TRUE 1
-+
-+#endif
-+*/
-+
-+/********************* CHIP.H ********************************************************/
-+
-+// Address Map
-+#define BOOT_ROM_BASE 0x00000000
-+#define USBHS_BASE 0x00200000
-+#define GMAC_BASE 0x00400000
-+#define PCI_BASE 0x00600000
-+#define PCI_DATA_BASE 0x00800000
-+#define STATIC0_BASE 0x01000000
-+#define STATIC1_BASE 0x01400000
-+#define STATIC2_BASE 0x01800000
-+#define STATIC_BASE 0x01C00000
-+#define SATA_DATA_BASE 0x02000000
-+#define DPE_DATA_BASE 0x03000000
-+#define GPIOA_BASE 0x04000000
-+#define GPIOB_BASE 0x04100000
-+#define UARTA_BASE 0x04200000
-+#define UARTB_BASE 0x04300000
-+#define I2C_MASTER_BASE 0x04400000
-+#define AUDIO_BASE 0x04500000
-+#define FAN_BASE 0x04600000
-+#define PWM_BASE 0x04700000
-+#define IR_RX_BASE 0x04800000
-+#define UARTC_BASE 0x04900000
-+#define UARTD_BASE 0x04A00000
-+#define SYS_CTRL_BASE 0x05000000
-+#define RPSA_BASE 0x05300000
-+#define ARM_RPS_BASE RPSA_BASE
-+#define RPSC_BASE 0x05400000
-+#define AHB_MON_BASE 0x05500000
-+#define DMA_BASE 0x05600000
-+#define DPE_BASE 0x05700000
-+#define IBIW_BASE 0x05780000
-+#define DDR_BASE 0x05800000
-+#define SATA0_BASE 0x05900000
-+#define SATA1_BASE 0x05980000
-+#define DMA_CHKSUM_BASE 0x05A00000
-+#define COPRO_BASE 0x05B00000
-+#define SGDMA_BASE 0x05C00000
-+#define DDR_DATA_BASE 0x08000000
-+#define SRAM_BASE 0x0C000000
-+#define SRAM0_BASE 0x0C000000
-+#define SRAM1_BASE 0x0C002000
-+#define SRAM2_BASE 0x0C004000
-+#define SRAM3_BASE 0x0C006000
-+
-+// Virtual peripheral for TB sync
-+#define TB_SYNC_BASE 0x05F00100
-+
-+
-+/********************* DMA.H ********************************************************/
-+
-+
-+// DMA Control register settings
-+
-+#define DMA_FAIR_SHARE (1<<0)
-+#define DMA_IN_PROGRESS (1<<1)
-+
-+#define DMA_SDREQ_SATA (0<<2)
-+#define DMA_SDREQ_DPE_OUT (2<<2)
-+#define DMA_SDREQ_UARTA_RX (4<<2)
-+#define DMA_SDREQ_AUDIO_RX (6<<2)
-+#define DMA_SDREQ_MEM (0xF<<2)
-+
-+#define DMA_DDREQ_SATA (0<<6)
-+#define DMA_DDREQ_DPE_IN (1<<6)
-+#define DMA_DDREQ_UARTA_TX (3<<6)
-+#define DMA_DDREQ_AUDIO_TX (5<<6)
-+#define DMA_DDREQ_MEM (0xF<<6)
-+
-+#define DMA_INTERRUPT (1 << 10)
-+#define DMA_NEXT_FREE (1 << 11)
-+#define DMA_CH_RESET (1 << 12)
-+
-+#define DMA_DIR_ATOA (0 << 13)
-+#define DMA_DIR_BTOA (1 << 13)
-+#define DMA_DIR_ATOB (2 << 13)
-+#define DMA_DIR_BTOB (3 << 13)
-+
-+#define DMA_BURST_A (1 << 17)
-+#define DMA_BURST_B (1 << 18)
-+
-+#define DMA_SWIDTH_8 (0 << 19)
-+#define DMA_SWIDTH_16 (1 << 19)
-+#define DMA_SWIDTH_32 (2 << 19)
-+
-+#define DMA_DWIDTH_8 (0 << 22)
-+#define DMA_DWIDTH_16 (1 << 22)
-+#define DMA_DWIDTH_32 (2 << 22)
-+
-+#define DMA_PAUSE (1 << 25)
-+#define DMA_INT_ENABLE (1 << 26)
-+#define DMA_STARVE_LO_PRIORITY (1 << 29)
-+#define DMA_NEW_INT_CLEAR (1 << 30)
-+
-+#define DMA_FIXED_SADDR ((0 << 15) | (1 << 27))
-+#define DMA_INCR_SADDR ((1 << 15) | (0 << 27))
-+#define DMA_SEMI_FIXED_SADDR ((0 << 15) | (0 << 27))
-+
-+#define DMA_FIXED_DADDR ((0 << 16) | (1 << 28))
-+#define DMA_INCR_DADDR ((1 << 16) | (0 << 28))
-+#define DMA_SEMI_FIXED_DADDR ((0 << 16) | (0 << 28))
-+
-+#define DMA_BASE_CTRL (DMA_BURST_A | DMA_BURST_B | DMA_INT_ENABLE | DMA_NEW_INT_CLEAR)
-+
-+// Common base setups
-+
-+#define DMA_CTRL_A32TOA32 ( DMA_BASE_CTRL | DMA_DIR_ATOA | DMA_SWIDTH_32 | DMA_DWIDTH_32 )
-+#define DMA_CTRL_B32TOA32 ( DMA_BASE_CTRL | DMA_DIR_BTOA | DMA_SWIDTH_32 | DMA_DWIDTH_32 )
-+#define DMA_CTRL_A32TOB32 ( DMA_BASE_CTRL | DMA_DIR_ATOB | DMA_SWIDTH_32 | DMA_DWIDTH_32 )
-+#define DMA_CTRL_B32TOB32 ( DMA_BASE_CTRL | DMA_DIR_BTOB | DMA_SWIDTH_32 | DMA_DWIDTH_32 )
-+
-+#define DMA_CTRL_A8TOB32 ( DMA_BASE_CTRL | DMA_DIR_ATOB | DMA_SWIDTH_8 | DMA_DWIDTH_32 )
-+#define DMA_CTRL_B32TOA8 ( DMA_BASE_CTRL | DMA_DIR_BTOA | DMA_SWIDTH_32 | DMA_DWIDTH_8 )
-+#define DMA_CTRL_A32TOB8 ( DMA_BASE_CTRL | DMA_DIR_ATOB | DMA_SWIDTH_32 | DMA_DWIDTH_8 )
-+
-+// Most likely transactions
-+
-+#define DMA_CTRL_MEM_TO_MEM_AA ( DMA_CTRL_A32TOA32 | DMA_SDREQ_MEM | DMA_DDREQ_MEM | DMA_INCR_SADDR | DMA_INCR_DADDR )
-+#define DMA_CTRL_MEM_TO_MEM_AB ( DMA_CTRL_A32TOB32 | DMA_SDREQ_MEM | DMA_DDREQ_MEM | DMA_INCR_SADDR | DMA_INCR_DADDR )
-+#define DMA_CTRL_MEM_TO_MEM_BB ( DMA_CTRL_B32TOB32 | DMA_SDREQ_MEM | DMA_DDREQ_MEM | DMA_INCR_SADDR | DMA_INCR_DADDR )
-+#define DMA_CTRL_MEM_TO_MEM_BA ( DMA_CTRL_B32TOA32 | DMA_SDREQ_MEM | DMA_DDREQ_MEM | DMA_INCR_SADDR | DMA_INCR_DADDR )
-+#define DMA_CTRL_MEM_TO_MEM ( DMA_CTRL_MEM_TO_MEM_AB )
-+
-+//DMA A-A
-+#define DMA_CTRL_SATA_TO_MEM_AA ( DMA_CTRL_A32TOA32 | DMA_SDREQ_SATA | DMA_DDREQ_MEM | DMA_INCR_SADDR | DMA_INCR_DADDR )
-+#define DMA_CTRL_MEM_TO_SATA_AA ( DMA_CTRL_A32TOA32 | DMA_SDREQ_MEM | DMA_DDREQ_SATA | DMA_INCR_SADDR | DMA_INCR_DADDR )
-+
-+#define DMA_CTRL_SATA_TO_MEM ( DMA_CTRL_A32TOB32 | DMA_SDREQ_SATA | DMA_DDREQ_MEM | DMA_INCR_SADDR | DMA_INCR_DADDR )
-+#define DMA_CTRL_MEM_TO_SATA ( DMA_CTRL_B32TOA32 | DMA_SDREQ_MEM | DMA_DDREQ_SATA | DMA_INCR_SADDR | DMA_INCR_DADDR )
-+#define DMA_CTRL_SATA_TO_DPE ( DMA_CTRL_A32TOA32 | DMA_SDREQ_SATA | DMA_DDREQ_DPE_IN | DMA_INCR_SADDR | DMA_INCR_DADDR )
-+#define DMA_CTRL_DPE_TO_SATA ( DMA_CTRL_A32TOA32 | DMA_SDREQ_DPE_OUT | DMA_DDREQ_SATA | DMA_INCR_SADDR | DMA_INCR_DADDR )
-+#define DMA_CTRL_MEM_TO_DPE ( DMA_CTRL_B32TOA32 | DMA_SDREQ_MEM | DMA_DDREQ_DPE_IN | DMA_INCR_SADDR | DMA_INCR_DADDR )
-+#define DMA_CTRL_DPE_TO_MEM ( DMA_CTRL_A32TOB32 | DMA_SDREQ_DPE_OUT | DMA_DDREQ_MEM | DMA_INCR_SADDR | DMA_INCR_DADDR )
-+#define DMA_CTRL_PCI_TO_MEM ( DMA_CTRL_A32TOB32 | DMA_SDREQ_MEM | DMA_DDREQ_MEM | DMA_INCR_SADDR | DMA_INCR_DADDR )
-+
-+#define DMA_CTRL_MEM_TO_PCI ( DMA_CTRL_B32TOA32 | DMA_SDREQ_MEM | DMA_DDREQ_MEM | DMA_INCR_SADDR | DMA_INCR_DADDR )
-+#define DMA_CTRL_MEM_TO_AUDIO ( DMA_CTRL_B32TOA32 | DMA_SDREQ_MEM | DMA_DDREQ_AUDIO_TX | DMA_INCR_SADDR | DMA_FIXED_DADDR )
-+#define DMA_CTRL_AUDIO_TO_MEM ( DMA_CTRL_A32TOB32 | DMA_SDREQ_AUDIO_RX | DMA_DDREQ_MEM | DMA_FIXED_SADDR | DMA_INCR_DADDR )
-+#define DMA_CTRL_MEM_TO_UART ( DMA_CTRL_B32TOA8 | DMA_SDREQ_MEM | DMA_DDREQ_UARTA_TX | DMA_INCR_SADDR | DMA_FIXED_DADDR )
-+#define DMA_CTRL_UART_TO_MEM ( DMA_CTRL_A8TOB32 | DMA_SDREQ_UARTA_RX | DMA_DDREQ_MEM | DMA_FIXED_SADDR | DMA_INCR_DADDR )
-+
-+// Byte count register flags
-+
-+#define DMA_HBURST_EN (1<<28)
-+#define DMA_WR_BUFFERABLE (1<<29)
-+#define DMA_WR_EOT (1<<30)
-+#define DMA_RD_EOT (1<<31)
-+
-+
-+// Pause the DMA channel specified
-+void PauseDMA( UINT channel );
-+
-+// UnPause the DMA channel specified
-+void UnPauseDMA( UINT channel );
-+
-+// Configure a DMA
-+void SetupDMA( UINT channel,
-+ UINT src_addr,
-+ UINT dest_addr,
-+ UINT byte_count,
-+ UINT control,
-+ UINT flags );
-+
-+// Wait while the given DMA channel is busy
-+void WaitWhileDMABusy( UINT channel );
-+
-+// Perform a memory to memory copy
-+void DMAMemCopy ( UINT channel,
-+ UINT src_addr,
-+ UINT dest_addr,
-+ UINT byte_count );
-+
-+
-+/****************************** MAIN ***********************************************/
-+#ifdef ARM
-+int mem_test(int argc, char* argv[])
-+#else
-+int main(int argc, char* argv[])
-+#endif
-+{
-+ unsigned int i;
-+ unsigned int iteration;
-+ unsigned int block_base;
-+ unsigned int datapattern;
-+ unsigned int correct_data;
-+ unsigned volatile int read_data;
-+ unsigned int pattype, starting_pattype;
-+ unsigned int end_addr;
-+ unsigned int row, col, bank;
-+
-+#ifdef ARM
-+ /* Print the ABI version */
-+ app_startup(argv);
-+ printf ("Example expects ABI version %d\n", XF_VERSION);
-+ printf ("Actual U-Boot ABI version %d\n", (int)get_version());
-+
-+ printf("GPIO34 is output, low\n");
-+ * (volatile unsigned int *) GPIOB_CLEAR_OUTPUT = GPIOB_BIT_34;
-+ * (volatile unsigned int *) GPIOB_SET_OE = GPIOB_BIT_34;
-+#endif
-+
-+// configure_caches();
-+//printf("Caches enabled\n");
-+
-+ /* ******************************************************************* */
-+ printf("DMA TEST.\n" );
-+ /* ******************************************************************* */
-+
-+
-+ #define DMA0_CTRL_STAT 0x45A00000
-+ #define DMA0_SRC_BASE 0x45A00004
-+ #define DMA0_DEST_BASE 0x45A00008
-+ #define DMA0_BYTE_COUNT 0x45A0000C
-+ #define DMA0_CURRENT_BYTE 0x45A00018
-+
-+ printf("Test to top of 1st SDRAM" );
-+ #define BLOCK_BYTES 0x20000
-+ #define SDRAM_STOP SDRAM_TOP
-+
-+ for (iteration=0; 1; iteration++) {
-+
-+ if ((iteration % 5)==0)
-+ printf("Iteration %d\n", iteration );
-+
-+// printf("Write pattern into first block.\n" );
-+ end_addr = SDRAM_BASE + BLOCK_BYTES;
-+ for (i=SDRAM_BASE; i < end_addr; i=i+4) {
-+ SDRAM_WRITE( i, i);
-+ }
-+
-+// printf("Clear last block and a few blocks more - easy to see on LA.\n" );
-+ end_addr = SDRAM_BASE + (BLOCK_BYTES << 3);
-+ for (i=SDRAM_STOP - BLOCK_BYTES; i < end_addr; i=i+4) {
-+ SDRAM_WRITE( i, 0);
-+ }
-+
-+ end_addr = SDRAM_STOP - BLOCK_BYTES;
-+ for (i=SDRAM_BASE; i < end_addr; i=i+BLOCK_BYTES) {
-+
-+// printf("DMA transfer from %08x to %08x.\n", i, i + BLOCK_BYTES );
-+#ifdef ARM
-+ DMAMemCopy ( 0, i, i + BLOCK_BYTES, BLOCK_BYTES );
-+#endif
-+// printf("...pending.\n" );
-+#ifdef ARM
-+ WaitWhileDMABusy( 0 );
-+#endif
-+// printf("...complete.\n" );
-+ }
-+
-+// printf("Verify pattern in last block.\n" );
-+ end_addr = SDRAM_STOP;
-+ correct_data = SDRAM_BASE;
-+ for (i=SDRAM_STOP - BLOCK_BYTES; i < end_addr; i=i+4) {
-+ SDRAM_READ( i, &read_data);
-+ if (read_data != correct_data)
-+ {
-+ /* Expand out the report_err function to avoid the stack operations. */
-+ #ifdef ARM
-+ /* ASSERT GPIO */
-+ * (volatile unsigned int *) GPIOB_SET_OUTPUT = GPIOB_BIT_34;
-+ #endif
-+
-+ /* REPORT ERROR */
-+ printf("Wrong on [%08x]= %08x should be %08x on iteration %d\n", i, read_data, correct_data, iteration );
-+
-+ /* WRITE TO ANOTHER LOCATION */
-+ SDRAM_WRITE(SDRAM_BASE, 0xFFFFFFFF);
-+
-+ /* READ AGAIN */
-+ SDRAM_READ(i, &read_data);
-+ if (read_data != correct_data)
-+ printf("Again 1 [%08x]= %08x should be %08x\n", i, read_data, correct_data );
-+
-+ /* WRITE TO ANOTHER LOCATION */
-+ SDRAM_WRITE(SDRAM_BASE, 0xFFFFFFFF);
-+
-+ /* READ AGAIN */
-+ SDRAM_READ(i, &read_data);
-+ if (read_data != correct_data)
-+ printf("Again 2 [%08x]= %08x should be %08x\n", i, read_data, correct_data );
-+
-+ /* WRITE TO ANOTHER LOCATION */
-+ SDRAM_WRITE(SDRAM_BASE, 0xFFFFFFFF);
-+
-+ /* READ AGAIN */
-+ SDRAM_READ(i, &read_data);
-+ if (read_data != correct_data)
-+ printf("Again 3 [%08x]= %08x should be %08x\n", i, read_data, correct_data );
-+
-+ row = (((i >> 26) & 0x1) << 13) | (((i >> 23) & 0x3) << 11) | ((i >> 10) & 0x7FF); /* [26], [24:23], [20:10]*/
-+ col = (((i >> 27) & 0x1) << 10) | (((i >> 25) & 0x1) << 9) | (((i >> 22) & 0x1) << 8); /* [27], [25], [22]... */
-+ col |= (((i >> 6) & 0xF) << 4) | (((i >> 21) & 0x1) << 3) | (((i >> 1) & 0x3) << 1); /* ...[9:8], [21], [3:2], '0' */
-+ col |= 0x800; /* bit 11 set for auto-precharge */
-+ bank = (i >> 4) & 0x3; /* [5:4] */
-+ printf("Bank %08x\n", bank );
-+ printf("Row %08x\n", row );
-+ printf("Column %08x\n", col );
-+ #ifdef ARM
-+ /* DEASSERT GPIO */
-+ * (volatile unsigned int *) GPIOB_CLEAR_OUTPUT = GPIOB_BIT_34;
-+ #endif
-+ }
-+
-+
-+ correct_data += 4;
-+ }
-+ }
-+
-+
-+ /* ******************************************************************* */
-+ printf("MEM_TEST2\n");
-+ /* ******************************************************************* */
-+
-+
-+ pattype=0;
-+ iteration=0;
-+
-+ for (;;) {
-+ /* FOR EACH 64Kword==256KB BLOCK IN 16Mword=64MB (2 OFF 16M16) MEMORY... */
-+
-+#ifdef SHORT
-+ if ((iteration % 5)==0)
-+ printf("Iteration %d\n", iteration );
-+#else
-+ if ((iteration % 1000)==0)
-+ printf("Iteration %d\n", iteration );
-+#endif
-+
-+ /* WRITE DATA BLOCKS */
-+ starting_pattype = pattype; /* Record for later */
-+
-+ for (block_base=SDRAM_BASE; block_base < SDRAM_TOP; block_base=block_base + BLOCKSIZE) {
-+ switch (pattype) {
-+ case PATTYPE_A5 :
-+ /* Write alternating 1s and 0s... */
-+ end_addr = block_base + BLOCKWORDS;
-+ for (i=block_base; i < end_addr; i=i+4) {
-+ SDRAM_WRITE( i, 0xaa55aa55);
-+ }
-+ break;
-+ case PATTYPE_5A :
-+ /* Write alternating 1s and 0s (inverse of above)... */
-+ end_addr = block_base + BLOCKWORDS;
-+ for (i=block_base; i < end_addr; i=i+4) {
-+ SDRAM_WRITE( i, 0x55aa55aa);
-+ }
-+ break;
-+ case PATTYPE_NO_FF :
-+ /* Write data=address with bit[n+16]=~bit[n]... */
-+ datapattern = 0x0100FEFF;
-+ /* In range 0x0100...0xFEFF so that
-+ a. temp[15:8] is never 0xFF
-+ b. Inverse of temp[15:8] is never 0xFF
-+ */
-+ end_addr = block_base + BLOCKWORDS;
-+ for (i=block_base; i < end_addr; i=i+4) {
-+ SDRAM_WRITE( i, datapattern);
-+ datapattern = datapattern + 0xFFFF;
-+ }
-+ break;
-+ case PATTYPE_INCR :
-+ /* Write data=address... */
-+ end_addr = block_base + BLOCKSIZE;
-+ for (i=block_base; i < end_addr; i=i+4) {
-+ SDRAM_WRITE( i, i);
-+ }
-+ break;
-+ case PATTYPE_DECR :
-+ /* Write data=~address... */
-+ end_addr = block_base + BLOCKSIZE;
-+ for (i=block_base; i < end_addr; i=i+4) {
-+ SDRAM_WRITE( i, ~i);
-+ }
-+ break;
-+ }
-+ }
-+
-+ /* VERIFY DATA BLOCKS */
-+ pattype = starting_pattype; /* Reset to same as for writes */
-+
-+ for (block_base=SDRAM_BASE; block_base < SDRAM_TOP; block_base=block_base + BLOCKSIZE) {
-+ switch (pattype) {
-+ case PATTYPE_A5 :
-+ correct_data = 0xaa55aa55;
-+ end_addr = block_base + BLOCKWORDS;
-+ for (i=block_base; i < end_addr; i=i+4) {
-+ SDRAM_READ( i, &read_data);
-+ if (read_data != correct_data)
-+ report_err(i, read_data, correct_data, iteration);
-+ }
-+ break;
-+ case PATTYPE_5A :
-+ correct_data = 0x55aa55aa;
-+ end_addr = block_base + BLOCKWORDS;
-+ for (i=block_base; i < end_addr; i=i+4) {
-+ SDRAM_READ( i, &read_data);
-+ if (read_data != correct_data)
-+ report_err(i, read_data, correct_data, iteration);
-+ }
-+ break;
-+ case PATTYPE_NO_FF :
-+ correct_data = 0x0100FEFF;
-+ end_addr = block_base + BLOCKWORDS;
-+ for (i=block_base; i < end_addr; i=i+4) {
-+ SDRAM_READ( i, &read_data);
-+ if (read_data != correct_data)
-+ report_err(i, read_data, correct_data, iteration);
-+ correct_data = correct_data + 0xFFFF;
-+ }
-+ break;
-+ case PATTYPE_INCR :
-+ end_addr = block_base + BLOCKSIZE;
-+ for (i=block_base; i < end_addr; i=i+4) {
-+ SDRAM_READ( i, &read_data);
-+ if (read_data != i)
-+ report_err(i, read_data, i, iteration);
-+ }
-+ break;
-+ case PATTYPE_DECR :
-+ end_addr = block_base + BLOCKSIZE;
-+ for (i=block_base; i < end_addr; i=i+4) {
-+ SDRAM_READ( i, &read_data);
-+ if (read_data != ~i)
-+ report_err(i, read_data, ~i, iteration);
-+ }
-+ break;
-+ }
-+ }
-+
-+ pattype = pattype + 1;
-+ if (pattype >= NUM_PATTYPES) { pattype = 0; }
-+ ++iteration;
-+ }
-+
-+ return 0;
-+}
-+
-+/********************* REPORT ERROR FUNC ********************************************************/
-+
-+void report_err(unsigned int address, unsigned int bad_data, unsigned int correct_data, unsigned int iteration)
-+{
-+ volatile unsigned int readvalue;
-+
-+#ifdef ARM
-+ /* ASSERT GPIO */
-+ * (volatile unsigned int *) GPIOB_SET_OUTPUT = GPIOB_BIT_34;
-+#endif
-+
-+ /* REPORT ERROR */
-+ printf("Wrong on [%08x]= %08x should be %08x on iteration %d\n", address, bad_data, correct_data, iteration );
-+
-+ /* WRITE TO ANOTHER LOCATION */
-+ SDRAM_WRITE(SDRAM_BASE, 0xFFFFFFFF);
-+
-+ /* READ AGAIN */
-+ SDRAM_READ(address, &readvalue);
-+ if (readvalue != correct_data)
-+ printf("Again 1 [%08x]= %08x should be %08x\n", address, readvalue, correct_data );
-+
-+ /* WRITE TO ANOTHER LOCATION */
-+ SDRAM_WRITE(SDRAM_BASE, 0xFFFFFFFF);
-+
-+ /* READ AGAIN */
-+ SDRAM_READ(address, &readvalue);
-+ if (readvalue != correct_data)
-+ printf("Again 2 [%08x]= %08x should be %08x\n", address, readvalue, correct_data );
-+
-+ /* WRITE TO ANOTHER LOCATION */
-+ SDRAM_WRITE(SDRAM_BASE, 0xFFFFFFFF);
-+
-+ /* READ AGAIN */
-+ SDRAM_READ(address, &readvalue);
-+ if (readvalue != correct_data)
-+ printf("Again 3 [%08x]= %08x should be %08x\n", address, readvalue, correct_data );
-+
-+#ifdef ARM
-+ /* DEASSERT GPIO */
-+ * (volatile unsigned int *) GPIOB_CLEAR_OUTPUT = GPIOB_BIT_34;
-+#endif
-+
-+} /* end of report_err */
-+
-+
-+
-+
-+/********************* DMA.C FUNCTIONS ********************************************************/
-+
-+void ResetDMA( UINT channel ) {
-+
-+ // Clear and abort the dma channel
-+
-+ volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
-+ dma[0] = (1 << 12);
-+ dma[0] &= ~(1 << 12);
-+}
-+
-+
-+
-+
-+void PauseDMA( UINT channel ) {
-+
-+ // Pause the DMA channel specified
-+
-+ volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
-+ UINT rd;
-+
-+ rd = dma[0];
-+
-+ rd |= DMA_PAUSE;
-+
-+ dma[0] = rd;
-+}
-+
-+
-+
-+
-+void UnPauseDMA( UINT channel ) {
-+
-+ // UnPause the DMA channel specified
-+
-+ volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
-+ UINT rd;
-+
-+ rd = dma[0];
-+
-+ rd &= ~DMA_PAUSE;
-+
-+ dma[0] = rd;
-+}
-+
-+
-+
-+
-+void SetupDMA( UINT channel,
-+ UINT src_addr,
-+ UINT dest_addr,
-+ UINT byte_count,
-+ UINT control,
-+ UINT flags ) {
-+
-+ // Configure a DMA
-+
-+ volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
-+
-+ dma[0] = control;
-+ dma[1] = src_addr;
-+ dma[2] = dest_addr;
-+ dma[3] = byte_count | (flags & 0xF0000000);
-+}
-+
-+// EXAMPLE:
-+//
-+// DMA 2kB from SRAM to SATA core with a write EOT set, and HBURST enabled, using DMA channel 2
-+// Then wait for the DMA to complete
-+//
-+// SetupDMA ( 2 , 0x4C001100, BASE_SATA, 2048, DMA_CTRL_MEM_TO_SATA, WR_EOT | DMA_HBURST_EN );
-+// WaitWhileDMABusy( 2 );
-+
-+int DMABusy(UINT channel)
-+{
-+ volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
-+ return (dma[0] & DMA_IN_PROGRESS ? 1 : 0);
-+}
-+
-+
-+void WaitWhileDMABusy( UINT channel ) // Wait while the given DMA channel is busy
-+{
-+ volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
-+ while (dma[0] & DMA_IN_PROGRESS) ; // Do Nothing
-+}
-+
-+void DMAClearIRQ(UINT channel)
-+{
-+ volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
-+ dma[4] = 1; // write any value to offset 0x10 (16 / 4 => 4)
-+
-+}
-+
-+void DMAMemCopy ( UINT channel,
-+ UINT src_addr,
-+ UINT dest_addr,
-+ UINT byte_count ) {
-+
-+ // Perform a memory to memory copy
-+
-+ volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
-+
-+ // Choose fastest configuration possible for required transfer
-+
-+ if (src_addr < SRAM_BASE) {
-+ if (dest_addr < SRAM_BASE) {
-+ dma[0] = DMA_CTRL_MEM_TO_MEM_AA; // Src and Dest must use A
-+ } else {
-+ dma[0] = DMA_CTRL_MEM_TO_MEM_AB; // Src must use A
-+ }
-+ } else {
-+ if (dest_addr < SRAM_BASE) {
-+ dma[0] = DMA_CTRL_MEM_TO_MEM_BA; // Dest must use A
-+ } else {
-+ dma[0] = DMA_CTRL_MEM_TO_MEM_AB; // No restriction
-+ }
-+ }
-+
-+ dma[1] = src_addr;
-+ dma[2] = dest_addr;
-+ dma[3] = byte_count | DMA_WR_BUFFERABLE | DMA_HBURST_EN;
-+
-+ WaitWhileDMABusy( channel );
-+}
-+
-+
-+
-+
-+
-+
-+
-+#define CP15R1_M_ENABLE 0x0001 // MMU Enable
-+#define CP15R1_A_ENABLE 0x0002 // Address alignment fault enable
-+#define CP15R1_C_ENABLE 0x0004 // (data) cache enable
-+#define CP15R1_W_ENABLE 0x0008 // write buffer enable
-+#define CP15R1_PROG32 0x0010 // PROG32
-+#define CP15R1_DATA32 0x0020 // DATA32
-+#define CP15R1_L_ENABLE 0x0040 // Late abort on earlier CPUs
-+#define CP15R1_BIGEND 0x0080 // Big-endian (=1), little-endian (=0)
-+#define CP15R1_SYSTEM 0x0100 // System bit, modifies MMU protections
-+#define CP15R1_ROM 0x0200 // ROM bit, modifies MMU protections
-+#define CP15R1_F 0x0400 // Should Be Zero
-+#define CP15R1_Z_ENABLE 0x0800 // Branch prediction enable on 810
-+#define CP15R1_I_ENABLE 0x1000 // Instruction cache enable
-+#define CP15R1_RESERVED 0x00000078
-+#define CP15R2_RESERVED 0xFFFFC000
-+
-+#define NUM_DOMAINS 16
-+
-+#define DAV_NO_ACCESS 0
-+#define DAV_CLIENT 1
-+#define DAV_RESERVED 2
-+#define DAV_MANAGER 3
-+#define NUM_DOMAIN_ACCESS_VALUES 4
-+
-+#define AP_LEVEL_0 0
-+#define AP_LEVEL_1 0
-+#define AP_LEVEL_2 0
-+#define AP_LEVEL_3 0
-+#define NUM_ACCESS_PERMISSIONS 4
-+
-+#define FAULT_ID 0
-+
-+#define FLD_COURSE_ID 1
-+#define FLD_SECTION_ID 2
-+#define FLD_FINE_ID 3
-+
-+#define FD_USER_DATA_BIT 2
-+
-+#define FD_USER_DATA_NUM_BITS 30
-+
-+#define SD_BUFFERABLE_BIT 2
-+#define SD_CACHEABLE_BIT 3
-+#define SD_IMP_BIT 4
-+#define SD_DOMAIN_BIT 5
-+#define SD_AP_BIT 10
-+#define SD_ADDRESS_BIT 20
-+
-+#define SD_DOMAIN_NUM_BITS 4
-+#define SD_AP_NUM_BITS 2
-+
-+void CoPro15Regs_SetCP15Reg1(const unsigned long mask) {
-+ asm volatile(
-+ "MOV r0, %0;"
-+ "MRC p15, 0, r1, c1, c0, 0;"
-+ "ORR r1,r1,r0;"
-+ "MCR p15, 0, r1, c1, c0, 0;"
-+ :
-+ : "r" (mask | CP15R1_RESERVED)
-+ : "r0","r1");
-+}
-+
-+void CoPro15Regs_ClearCP15Reg1(const unsigned long mask) {
-+ asm volatile(
-+ "MOV r0, %0;"
-+ "MRC p15, 0, r1, c1, c0, 0;"
-+ "BIC r1,r1,r0;"
-+ "MCR p15, 0, r1, c1, c0, 0;"
-+ :
-+ : "r" (mask)
-+ : "r0","r1");
-+}
-+
-+unsigned long CoPro15Regs_GetCP15Reg1(const unsigned long mask) {
-+ unsigned long value;
-+ asm volatile(
-+ "MRC p15, 0, r1, c1, c0, 0;"
-+ "MOV r0, %1;"
-+ "BIC %0,r1,r0; "
-+ : "=r" (value)
-+ : "r" (mask)
-+ : "r0","r1");
-+ return value;
-+}
-+
-+unsigned long CoPro15Regs_GetCP15Reg2(void) {
-+ unsigned long value;
-+ asm volatile(
-+ "MRC p15, 0, r0, c2, c0, 0;"
-+ "MOV %0, r0;"
-+ : "=r" (value)
-+ :
-+ : "r0");
-+ return value & CP15R2_RESERVED;
-+}
-+
-+unsigned long CoPro15Regs_GetCP15Reg3(void) {
-+ unsigned long value;
-+ asm volatile(
-+ "MRC p15, 0, r0, c3, c0, 0;"
-+ "MOV %0, r0;"
-+ : "=r" (value)
-+ :
-+ : "r0");
-+ return value;
-+}
-+
-+void CoPro15Regs_SetCP15Reg3(unsigned long value) {
-+ asm volatile(
-+ "MOV r0, %0;"
-+ "MCR p15, 0, r0, c3, c0, 0;"
-+ :
-+ : "r" (value)
-+ : "r0");
-+}
-+
-+void CoPro15Regs_SetCP15Reg2(unsigned long value) {
-+ asm volatile(
-+ "MOV r0, %0;"
-+ "MCR p15, 0, r0, c2, c0, 0;"
-+ :
-+ : "r" (value & CP15R2_RESERVED)
-+ : "r0");
-+}
-+
-+void Cache_CleanDataCache(void)
-+{
-+ // Clean the data cache - usually precedes a data cache invalidation.
-+ // Forces the data cache content to be written to main memory - only
-+ // required if using write-back data cache
-+ asm volatile(
-+ "MOV r3,pc;"
-+ "LDR r1, =0;"
-+ " MOV r4,pc;"
-+ " LDR r0, =0;"
-+ " ORR r2, r1, r0;"
-+ " MCR p15, 0, r2, c7, c10, 2 ;" // I (BHC) think that this should be c10, 2 not c14, 1 -- See ARM ARM
-+ " ADD r0, r0, #0x10;"
-+ " CMP r0,#0x40;"
-+ " BXNE r4;"
-+ " ADD r1, r1, #0x04000000;"
-+ " CMP r1, #0x0;"
-+ "BXNE r3;"
-+ :
-+ :
-+ : "r0","r1","r2","r3","r4");
-+}
-+
-+void Cache_DrainWriteBuffer(void)
-+{
-+ // Forces the write buffer to update to main memory
-+ asm volatile(
-+ "LDR r1, =0;"
-+ "MCR p15, 0, r1, c7, c10, 4 ;"
-+ :
-+ :
-+ : "r1");
-+}
-+
-+void Cache_FlushPrefetchBuffer(void)
-+{
-+ // Forces the CPU to flush the instruction prefetch buffer
-+ asm volatile(
-+ "LDR r1, =0;"
-+ "MCR p15, 0, r1, c7, c5, 4 ;"
-+ :
-+ :
-+ : "r1");
-+}
-+
-+void Cache_InvalidateDataCache(void)
-+{
-+ asm volatile(
-+ "LDR r1, =0;"
-+ "MCR p15, 0, r1, c7, c6, 0;"
-+ :
-+ :
-+ : "r1");
-+}
-+
-+void Cache_InvalidateInstructionCache(void)
-+{
-+ asm volatile(
-+ "LDR r1, =0;"
-+ "MCR p15, 0, r1, c7, c5, 0;"
-+ :
-+ :
-+ : "r1");
-+}
-+
-+void Cache_InstOn(void)
-+{
-+ // Invalidate the instruction cache, in case there's anything
-+ // left from when it was last enabled
-+ Cache_InvalidateInstructionCache();
-+
-+ // Enable the instruction cache
-+ CoPro15Regs_SetCP15Reg1(CP15R1_I_ENABLE);
-+}
-+
-+void Cache_InstOff(void)
-+{
-+ // Disable the instruction cache
-+ CoPro15Regs_ClearCP15Reg1(CP15R1_I_ENABLE);
-+}
-+
-+void Cache_DataOn(void)
-+{
-+ // Invalidate the data cache, in case there's anything left from when
-+ // it was last enabled
-+ Cache_InvalidateDataCache();
-+
-+ // Enable the data cache
-+ CoPro15Regs_SetCP15Reg1(CP15R1_C_ENABLE);
-+}
-+
-+void Cache_DataOff(void)
-+{
-+ // Ensure all data in data cache or write buffer is written to memory
-+ Cache_CleanDataCache();
-+ Cache_DrainWriteBuffer();
-+
-+ // Disable the data cache
-+ CoPro15Regs_ClearCP15Reg1(CP15R1_C_ENABLE);
-+}
-+
-+void Cache_WriteBufferOn(void)
-+{
-+ // Enable the write buffer
-+ CoPro15Regs_SetCP15Reg1(CP15R1_W_ENABLE);
-+}
-+
-+void Cache_WriteBufferOff(void)
-+{
-+ // Ensure all data in the write buffer is written to memory
-+ Cache_DrainWriteBuffer();
-+
-+ // Disable the write buffer
-+ CoPro15Regs_ClearCP15Reg1(CP15R1_W_ENABLE);
-+}
-+
-+int MMU_SetDomainAccessValue(
-+ int domainNumber,
-+ int value) {
-+ int status = 0;
-+ if ((value < NUM_DOMAIN_ACCESS_VALUES) && (domainNumber < NUM_DOMAINS))
-+ {
-+ // Insert the 2-bit domain field into the slot for the specified domain
-+ unsigned long registerContents = CoPro15Regs_GetCP15Reg3();
-+ registerContents &= ~(3UL << (2*domainNumber));
-+ registerContents |= ((unsigned long)value << (2*domainNumber));
-+ CoPro15Regs_SetCP15Reg3(registerContents);
-+ status = 1;
-+ }
-+ return status;
-+}
-+
-+void MMU_SetAlignmentChecked(int alignmentChecked) {
-+ alignmentChecked ? CoPro15Regs_SetCP15Reg1(CP15R1_A_ENABLE) : CoPro15Regs_ClearCP15Reg1(CP15R1_A_ENABLE);
-+}
-+
-+void MMU_SetEnabled(int enabled) {
-+ enabled ? CoPro15Regs_SetCP15Reg1(CP15R1_M_ENABLE) : CoPro15Regs_ClearCP15Reg1(CP15R1_M_ENABLE);
-+}
-+void MMU_InvalidateDataTLB(void)
-+{
-+ asm volatile(
-+ "MCR p15, 0, r0, c8, c6, 0;"
-+ :
-+ :
-+ : "r0");
-+}
-+
-+void MMU_InvalidateInstructionTLB(void)
-+{
-+ asm volatile(
-+ "MCR p15, 0, r0, c8, c5, 0;"
-+ :
-+ :
-+ : "r0");
-+}
-+
-+void MMU_SetROMPermission(int rOM_Permitted) {
-+ rOM_Permitted ? CoPro15Regs_SetCP15Reg1(CP15R1_ROM) : CoPro15Regs_ClearCP15Reg1(CP15R1_ROM);
-+}
-+
-+void MMU_SetSystemPermission(int systemPermitted) {
-+ systemPermitted ? CoPro15Regs_SetCP15Reg1(CP15R1_SYSTEM) : CoPro15Regs_ClearCP15Reg1(CP15R1_SYSTEM);
-+}
-+
-+void MMU_SetTranslationTableBaseAddress(unsigned long *baseAddress) {
-+ CoPro15Regs_SetCP15Reg2((unsigned long)baseAddress);
-+}
-+
-+unsigned long SetBit(
-+ unsigned long source,
-+ int state,
-+ int offset)
-+{
-+ source = state ? (source | (1UL << offset)) :
-+ (source & ~(1UL << offset));
-+ return source;
-+}
-+
-+unsigned long SetField(
-+ unsigned long source,
-+ unsigned long newFieldContents,
-+ int offset,
-+ int length)
-+{
-+ unsigned long mask = (1UL << length) - 1;
-+ source &= ~(mask << offset);
-+ source |= ((newFieldContents & mask) << offset);
-+ return source;
-+}
-+
-+unsigned long FD_SetUserData(
-+ unsigned long userData,
-+ unsigned long descriptor)
-+{
-+ return SetField(descriptor, userData, FD_USER_DATA_BIT, FD_USER_DATA_NUM_BITS);
-+}
-+
-+unsigned long FLPT_CreateFaultDescriptor(unsigned long userData)
-+{
-+ unsigned long descriptor = FAULT_ID;
-+ descriptor = FD_SetUserData(userData, descriptor);
-+ return descriptor;
-+}
-+
-+void FLPT_InsertFaultDescriptor(
-+ unsigned long *tableBaseAdr,
-+ int index,
-+ unsigned long descriptor)
-+{
-+ *(tableBaseAdr + index) = descriptor;
-+}
-+
-+unsigned long SD_SetAccessPermission(
-+ int ap,
-+ unsigned long descriptor)
-+{
-+ return SetField(descriptor, ap, SD_AP_BIT, SD_AP_NUM_BITS);
-+}
-+
-+unsigned long SD_SetBaseAddress(
-+ unsigned long baseAddress,
-+ unsigned long descriptor)
-+{
-+ unsigned long mask = ~0UL << SD_ADDRESS_BIT;
-+ baseAddress &= mask;
-+ descriptor &= ~mask;
-+ descriptor |= baseAddress;
-+ return descriptor;
-+}
-+
-+unsigned long SD_SetBufferable(
-+ int bufferable,
-+ unsigned long descriptor)
-+{
-+ return SetBit(descriptor, bufferable, SD_BUFFERABLE_BIT);
-+}
-+
-+unsigned long SD_SetCacheable(
-+ int cacheable,
-+ unsigned long descriptor)
-+{
-+ return SetBit(descriptor, cacheable, SD_CACHEABLE_BIT);
-+}
-+
-+unsigned long SD_SetDomain(
-+ int domain,
-+ unsigned long descriptor)
-+{
-+ return SetField(descriptor, domain, SD_DOMAIN_BIT, SD_DOMAIN_NUM_BITS);
-+}
-+
-+unsigned long SD_SetImplementationDefined(
-+ unsigned long implementationDefined,
-+ unsigned long descriptor)
-+{
-+ return SetBit(descriptor, implementationDefined, SD_IMP_BIT);
-+}
-+
-+unsigned long FLPT_CreateSectionDescriptor(
-+ unsigned long baseAddress,
-+ unsigned char domain,
-+ int implementationDefined,
-+ int ap,
-+ int bufferable,
-+ int cacheable)
-+{
-+ unsigned long descriptor = FLD_SECTION_ID;
-+ descriptor = SD_SetAccessPermission(ap, descriptor);
-+ descriptor = SD_SetBaseAddress(baseAddress, descriptor);
-+ descriptor = SD_SetBufferable(bufferable, descriptor);
-+ descriptor = SD_SetCacheable(cacheable, descriptor);
-+ descriptor = SD_SetDomain(domain, descriptor);
-+ descriptor = SD_SetImplementationDefined(implementationDefined, descriptor);
-+ return descriptor;
-+}
-+
-+void FLPT_InsertSectionDescriptor(
-+ unsigned long *tableBaseAdr,
-+ int index,
-+ unsigned long descriptor)
-+{
-+ *(tableBaseAdr + index) = descriptor;
-+}
-+
-+void FLPT_Zeroise(
-+ unsigned long *base_adr,
-+ int numberOfdescriptors) {
-+ unsigned long faultDescriptor = FLPT_CreateFaultDescriptor(0);
-+ int i;
-+ for (i=0; i < numberOfdescriptors; i++) {
-+ FLPT_InsertFaultDescriptor(base_adr, i, faultDescriptor);
-+ }
-+}
-+
-+void configure_caches(void)
-+{
-+ // Disable caches
-+// Cache_DataOff();
-+printf("1");
-+ Cache_InstOff();
-+// Cache_WriteBufferOff();
-+
-+ // Disable MMU
-+printf("2");
-+ MMU_SetEnabled(0);
-+printf("3");
-+ MMU_InvalidateDataTLB();
-+printf("4");
-+ MMU_InvalidateInstructionTLB();
-+
-+ // Setup the MMU
-+printf("5");
-+ MMU_SetAlignmentChecked(1);
-+printf("6");
-+ MMU_SetROMPermission(0);
-+printf("7");
-+ MMU_SetSystemPermission(1);
-+
-+ // Allow client access to all protection domains
-+ int i;
-+ for (i=0; i < NUM_DOMAINS; i++) {
-+ MMU_SetDomainAccessValue(i, DAV_CLIENT);
-+ }
-+printf("8");
-+
-+ // Allocate first level page table, which we'll populate only with section
-+ // descriptors, which cover 1MB each. Table must be aligned to a 16KB
-+ // boundary.
-+ // We'll put it 4KB into the SRAM and it will occupy:
-+ // 64 entries for SDRAM
-+ // 1 entry for SRAM
-+ // 16 entries for APB bridge A
-+ // 16 entries for APB bridge B
-+ // The largest memory address we need to map is that of the SRAM at
-+ // 0x4c000000 -> (4c000000/2^20)*4 = offset 1300h from table start ->
-+ // require at least 1300h/4 +1 entries in table = 1217
-+ unsigned long *firstLevelPageTableBaseAdr = (unsigned long*)SRAM_BASE;
-+ FLPT_Zeroise(firstLevelPageTableBaseAdr, 4096);
-+printf("9");
-+
-+ // Map entire adr space uncached, unbuffered, read/write, virtual == physical
-+ unsigned megabytesPresent = 4096;
-+ unsigned index = 0;
-+ for (i=0; i < megabytesPresent; i++) {
-+ FLPT_InsertSectionDescriptor(
-+ firstLevelPageTableBaseAdr,
-+ index,
-+ FLPT_CreateSectionDescriptor(
-+ index * 1024 * 1024, // Base address
-+ 0, // Domain number
-+ 0, // Implementation defined
-+ AP_LEVEL_1, // Access permissions
-+ 0, // Bufferable
-+ 0)); // Cacheable
-+
-+ ++index;
-+ }
-+printf("10");
-+
-+ // Map SDRAM as cached and buffered, read/write, virtual == physical
-+ megabytesPresent = 64;
-+ index = PHYS_SDRAM_1_PA / (1024 * 1024);
-+ for (i=0; i < megabytesPresent; i++) {
-+ FLPT_InsertSectionDescriptor(
-+ firstLevelPageTableBaseAdr,
-+ index,
-+ FLPT_CreateSectionDescriptor(
-+ index * 1024 * 1024, // Base address
-+ 0, // Domain number
-+ 0, // Implementation defined
-+ AP_LEVEL_1, // Access permissions
-+ 1, // Bufferable
-+ 1)); // Cacheable
-+
-+ ++index;
-+ }
-+printf("11");
-+
-+ // Map SRAM as cached and buffered, read/write, virtual == physical
-+ megabytesPresent = 1; // Actually only 32KB
-+ index = SRAM_BASE / (1024 * 1024);
-+ for (i=0; i < megabytesPresent; i++) {
-+ FLPT_InsertSectionDescriptor(
-+ firstLevelPageTableBaseAdr,
-+ index,
-+ FLPT_CreateSectionDescriptor(
-+ index * 1024 * 1024, // Base address
-+ 0, // Domain number
-+ 0, // Implementation defined
-+ AP_LEVEL_1, // Access permissions
-+ 1, // Bufferable
-+ 1)); // Cacheable
-+
-+ ++index;
-+ }
-+printf("12");
-+
-+ // Map APB bridge A address space as uncached, unbuffered, read/write,
-+ // virtual == physical
-+ megabytesPresent = 16;
-+ index = APB_BRIDGE_A_BASE_PA / (1024 * 1024);
-+ for (i=0; i < megabytesPresent; i++) {
-+ FLPT_InsertSectionDescriptor(
-+ firstLevelPageTableBaseAdr,
-+ index,
-+ FLPT_CreateSectionDescriptor(
-+ index * 1024 * 1024, // Base address
-+ 0, // Domain number
-+ 0, // Implementation defined
-+ AP_LEVEL_1, // Access permissions
-+ 0, // Bufferable
-+ 0)); // Cacheable
-+
-+ ++index;
-+ }
-+printf("13");
-+
-+ // Map APB bridge B address space as uncached, unbuffered, read/write,
-+ // virtual == physical
-+ megabytesPresent = 16;
-+ index = APB_BRIDGE_B_BASE_PA / (1024 * 1024);
-+ for (i=0; i < megabytesPresent; i++) {
-+ FLPT_InsertSectionDescriptor(
-+ firstLevelPageTableBaseAdr,
-+ index,
-+ FLPT_CreateSectionDescriptor(
-+ index * 1024 * 1024, // Base address
-+ 0, // Domain number
-+ 0, // Implementation defined
-+ AP_LEVEL_1, // Access permissions
-+ 0, // Bufferable
-+ 0)); // Cacheable
-+
-+ ++index;
-+ }
-+printf("14");
-+
-+ // Load base address of first level page table
-+ MMU_SetTranslationTableBaseAddress(firstLevelPageTableBaseAdr);
-+printf("15");
-+
-+ // Enable MMU
-+ MMU_SetEnabled(1);
-+printf("16");
-+
-+ // Enable caches
-+ Cache_DataOn();
-+printf("17");
-+ Cache_InstOn();
-+printf("18");
-+ Cache_WriteBufferOn();
-+printf("19");
-+}
-+
-diff -Nurd u-boot-1.1.2/include/asm-arm/barrier.h u-boot-1.1.2-oxe810/include/asm-arm/barrier.h
---- u-boot-1.1.2/include/asm-arm/barrier.h 1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/include/asm-arm/barrier.h 2008-06-11 17:55:08.000000000 +0200
-@@ -0,0 +1,25 @@
-+#if !defined(__BARRIER_H__)
-+#define __BARRIER_H__
-+
-+static inline void rmb(void)
-+{
-+ asm volatile ("" : : : "memory");
-+}
-+
-+/*
-+ * wmb() Would normally need to ensure shared memory regions are marked as
-+ * non-cacheable and non-bufferable, then the work to be done by wmb() is
-+ * to ensure the compiler and any possible CPU out of order writes are
-+ * flushed to memory, however we have no data cache and as far as I'm
-+ * aware we can't use the MMU to set page properties, so in our case wmb()
-+ * must cause the compiler to flush.
-+ */
-+
-+static inline void wmb(void)
-+{
-+ // Cause the compiler to flush any registers containing pending write data
-+ // to memory
-+ asm volatile ("" : : : "memory");
-+
-+}
-+#endif // #if !defined(__BARRIER_H__)
-diff -Nurd u-boot-1.1.2/include/asm-arm/global_data.h u-boot-1.1.2-oxe810/include/asm-arm/global_data.h
---- u-boot-1.1.2/include/asm-arm/global_data.h 2003-10-10 12:05:43.000000000 +0200
-+++ u-boot-1.1.2-oxe810/include/asm-arm/global_data.h 2008-06-11 17:55:08.000000000 +0200
-@@ -61,6 +61,7 @@
- #define GD_FLG_DEVINIT 0x00002 /* Devices have been initialized */
- #define GD_FLG_SILENT 0x00004 /* Silent mode */
-
--#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8")
-+#define DECLARE_GLOBAL_DATA_PTR register gd_t* volatile gd asm ("r8");
-
- #endif /* __ASM_GBL_DATA_H */
-+
-diff -Nurd u-boot-1.1.2/include/asm-arm/mach-types.h u-boot-1.1.2-oxe810/include/asm-arm/mach-types.h
---- u-boot-1.1.2/include/asm-arm/mach-types.h 2004-10-10 20:41:14.000000000 +0200
-+++ u-boot-1.1.2-oxe810/include/asm-arm/mach-types.h 2008-06-11 17:55:08.000000000 +0200
-@@ -624,6 +624,7 @@
- #define MACH_TYPE_RMS100 611
- #define MACH_TYPE_KB9200 612
- #define MACH_TYPE_SX1 613
-+#define MACH_TYPE_OXNAS 1152
-
- #ifdef CONFIG_ARCH_EBSA110
- # ifdef machine_arch_type
-@@ -7945,6 +7946,18 @@
- # define machine_is_sx1() (0)
- #endif
-
-+#ifdef CONFIG_MACH_OXNAS
-+# ifdef machine_arch_type
-+# undef machine_arch_type
-+# define machine_arch_type __machine_arch_type
-+# else
-+# define machine_arch_type MACH_TYPE_OXNAS
-+# endif
-+# define machine_is_oxnas() (machine_arch_type == MACH_TYPE_OXNAS)
-+#else
-+# define machine_is_oxnas() (0)
-+#endif
-+
- /*
- * These have not yet been registered
- */
-diff -Nurd u-boot-1.1.2/include/asm-arm/u-boot.h u-boot-1.1.2-oxe810/include/asm-arm/u-boot.h
---- u-boot-1.1.2/include/asm-arm/u-boot.h 2002-11-03 01:33:10.000000000 +0100
-+++ u-boot-1.1.2-oxe810/include/asm-arm/u-boot.h 2008-06-11 17:55:08.000000000 +0200
-@@ -41,6 +41,8 @@
- ulong start;
- ulong size;
- } bi_dram[CONFIG_NR_DRAM_BANKS];
-+ unsigned long bi_sramstart; /* start of SRAM memory */
-+ unsigned long bi_sramsize; /* size of SRAM memory */
- } bd_t;
-
- #define bi_env_data bi_env->data
-diff -Nurd u-boot-1.1.2/include/ata.h u-boot-1.1.2-oxe810/include/ata.h
---- u-boot-1.1.2/include/ata.h 2004-03-14 23:25:50.000000000 +0100
-+++ u-boot-1.1.2-oxe810/include/ata.h 2008-06-11 17:55:11.000000000 +0200
-@@ -80,7 +80,12 @@
- /*
- * Device / Head Register Bits
- */
-+#ifdef CONFIG_OXNAS
-+#define ATA_DEVICE(x) (0)
-+#else
- #define ATA_DEVICE(x) ((x & 1)<<4)
-+#endif // CONFIG_OXNAS
-+
- #define ATA_LBA 0xE0
-
- /*
-diff -Nurd u-boot-1.1.2/include/cmd_confdefs.h u-boot-1.1.2-oxe810/include/cmd_confdefs.h
---- u-boot-1.1.2/include/cmd_confdefs.h 2004-12-16 18:59:53.000000000 +0100
-+++ u-boot-1.1.2-oxe810/include/cmd_confdefs.h 2008-06-11 17:55:11.000000000 +0200
-@@ -92,6 +92,7 @@
- #define CFG_CMD_XIMG 0x0400000000000000ULL /* Load part of Multi Image */
- #define CFG_CMD_UNIVERSE 0x0800000000000000ULL /* Tundra Universe Support */
- #define CFG_CMD_EXT2 0x1000000000000000ULL /* EXT2 Support */
-+#define CFG_CMD_LEDFAIL 0x2000000000000000ULL /* OXNAS Failure LED support */
-
- #define CFG_CMD_ALL 0xFFFFFFFFFFFFFFFFULL /* ALL commands */
-
-diff -Nurd u-boot-1.1.2/include/common.h u-boot-1.1.2-oxe810/include/common.h
---- u-boot-1.1.2/include/common.h 2004-12-13 10:49:01.000000000 +0100
-+++ u-boot-1.1.2-oxe810/include/common.h 2008-06-11 17:55:11.000000000 +0200
-@@ -204,7 +204,7 @@
- /* common/cmd_nvedit.c */
- int env_init (void);
- void env_relocate (void);
--char *getenv (uchar *);
-+char *getenv (const uchar *);
- int getenv_r (uchar *name, uchar *buf, unsigned len);
- int saveenv (void);
- #ifdef CONFIG_PPC /* ARM version to be fixed! */
-diff -Nurd u-boot-1.1.2/include/configs/oxnas.h u-boot-1.1.2-oxe810/include/configs/oxnas.h
---- u-boot-1.1.2/include/configs/oxnas.h 1970-01-01 01:00:00.000000000 +0100
-+++ u-boot-1.1.2-oxe810/include/configs/oxnas.h 2008-06-12 13:57:57.000000000 +0200
-@@ -0,0 +1,593 @@
-+/*
-+ * (C) Copyright 2005
-+ * Oxford Semiconductor Ltd
-+ *
-+ * See file CREDITS for list of people who contributed to this
-+ * project.
-+ *
-+ * 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 __CONFIG_H
-+#define __CONFIG_H
-+
-+#define readb(p) (*(volatile u8 *)(p))
-+#define readl(p) (*(volatile u32 *)(p))
-+#define writeb(v, p) (*(volatile u8 *)(p)= (v))
-+#define writel(v, p) (*(volatile u32*)(p)=(v))
-+
-+#define CFG_FLASH_EMPTY_INFO
-+
-+/**
-+ * Architecture
-+ */
-+#define CONFIG_ARM926EJS 1
-+#define CONFIG_OXNAS 1
-+#define CONFIG_OXNAS_ENABLE_PCI /* Enables PCI clock and takes out of reset - needed if require access to static bus */
-+#define CONFIG_OXNAS_FEEDBACK_PCI_CLKS /* Feedback PCI clock out 3 to drive PCI core clock - needed if require access to static bus */
-+#define CONFIG_OXNAS_MANUAL_STATIC_ARBITRATION
-+#if (USE_SATA == 1)
-+#define CONFIG_OXNAS_USE_SATA /* Define to include support for SATA disks */
-+#if (USE_SATA_ENV == 1)
-+#define ENV_ON_SATA /* Define to have the U-Boot env. stored on SATA disk */
-+#endif // USE_SATA_ENV
-+#endif // USE_SATA
-+#if (USE_FLASH == 0)
-+#define CFG_NO_FLASH /* Define to NOT include flash support on static bus*/
-+#endif //USE_FLASH
-+
-+/* Won't be using any interrupts */
-+#undef CONFIG_USE_IRQ
-+
-+/* Everything, incl board info, in Hz */
-+#undef CFG_CLKS_IN_HZ
-+
-+#define CFG_HUSH_PARSER 1
-+#define CFG_PROMPT_HUSH_PS2 "> "
-+
-+/* Miscellaneous configurable options */
-+#define CFG_LONGHELP /* undef to save memory */
-+#ifdef CFG_HUSH_PARSER
-+#define CFG_PROMPT "$ " /* Monitor Command Prompt */
-+#else
-+#define CFG_PROMPT "# " /* Monitor Command Prompt */
-+#endif
-+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
-+
-+/* Print Buffer Size */
-+#define CFG_PBSIZE ((CFG_CBSIZE)+sizeof(CFG_PROMPT)+16)
-+#define CFG_MAXARGS 16 /* max number of command args */
-+#define CFG_BARGSIZE (CFG_CBSIZE) /* Boot Argument Buffer Size */
-+
-+#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
-+#define CONFIG_SETUP_MEMORY_TAGS 1
-+#define CONFIG_MISC_INIT_R 1 /* call misc_init_r during start up */
-+#define CONFIG_INITRD_TAG 1 /* allow initrd tag to be generated */
-+
-+/* May want to do some setup prior to relocation */
-+#define CONFIG_INIT_CRITICAL
-+
-+/* ARM specific late initialisation */
-+#define BOARD_LATE_INIT
-+
-+/**
-+ * Stack sizes
-+ *
-+ * The stack sizes are set up in start.S using the settings below
-+ */
-+#define CONFIG_STACKSIZE (128*1024) /* regular stack */
-+#ifdef CONFIG_USE_IRQ
-+#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
-+#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
-+#endif
-+
-+/**
-+ * RAM
-+ */
-+#define CONFIG_NR_DRAM_BANKS 1 /* We have 1 bank of SDRAM */
-+#define PHYS_SDRAM_1_PA 0x48000000 /* SDRAM Bank #1 */
-+#if (NAS_VERSION == 810)
-+#define PHYS_SDRAM_1_MAX_SIZE (256 * 1024 * 1024)
-+#endif // NAS_VERSION
-+#define CFG_SRAM_BASE ((PHYS_SDRAM_1_PA) + (PHYS_SDRAM_1_MAX_SIZE))
-+#if (NAS_VERSION == 810)
-+#define CFG_SRAM_SIZE (128 * 1024)
-+#endif // NAS_VERSION
-+
-+#define INITIALISE_SDRAM
-+
-+/* Default location from which bootm etc will load */
-+#define CFG_LOAD_ADDR (PHYS_SDRAM_1_PA)
-+
-+/**
-+ * Core addresses
-+ */
-+#define MAC_BASE_PA 0x40400000
-+#define STATIC_CS0_BASE_PA 0x41000000
-+#define STATIC_CS1_BASE_PA 0x41400000
-+#define STATIC_CS2_BASE_PA 0x41800000
-+#define STATIC_CONTROL_BASE_PA 0x41C00000
-+#define SATA_DATA_BASE_PA 0x42000000
-+
-+#define APB_BRIDGE_A_BASE_PA 0x44000000
-+#define APB_BRIDGE_B_BASE_PA 0x45000000
-+
-+#define GPIO_1_PA ((APB_BRIDGE_A_BASE_PA) + 0x0)
-+#define GPIO_2_PA ((APB_BRIDGE_A_BASE_PA) + 0x100000)
-+
-+#define SYS_CONTROL_BASE_PA ((APB_BRIDGE_B_BASE_PA) + 0x0)
-+#define DMA_BASE_PA ((APB_BRIDGE_B_BASE_PA) + 0x600000)
-+#define RPS_BASE ((APB_BRIDGE_B_BASE_PA) + 0x300000)
-+
-+/* Static bus registers */
-+#define STATIC_CONTROL_VERSION ((STATIC_CONTROL_BASE_PA) + 0x0)
-+#define STATIC_CONTROL_BANK0 ((STATIC_CONTROL_BASE_PA) + 0x4)
-+#define STATIC_CONTROL_BANK1 ((STATIC_CONTROL_BASE_PA) + 0x8)
-+#define STATIC_CONTROL_BANK2 ((STATIC_CONTROL_BASE_PA) + 0xC)
-+
-+/* Clock to the ARM/DDR */
-+#if (FPGA == 0)
-+#define NOMINAL_ARMCLK ((PLL400) / 2)
-+#define NOMINAL_SYSCLK ((PLL400) / 4)
-+#else // !FPGA
-+#define NOMINAL_ARMCLK (FPGA_ARM_CLK)
-+#define NOMINAL_SYSCLK ((PLL400) / 4)
-+#endif // !FPGA
-+
-+/**
-+ * Timer
-+ */
-+#define CFG_TIMERBASE ((RPS_BASE) + 0x200)
-+#define TIMER_PRESCALE_BIT 2
-+#define TIMER_PRESCALE_1_ENUM 0
-+#define TIMER_PRESCALE_16_ENUM 1
-+#define TIMER_PRESCALE_256_ENUM 2
-+#define TIMER_MODE_BIT 6
-+#define TIMER_MODE_FREE_RUNNING 0
-+#define TIMER_MODE_PERIODIC 1
-+#define TIMER_ENABLE_BIT 7
-+#define TIMER_ENABLE_DISABLE 0
-+#define TIMER_ENABLE_ENABLE 1
-+
-+#define TIMER_PRESCALE_ENUM (TIMER_PRESCALE_256_ENUM)
-+#define CFG_HZ ((RPSCLK) / 256)
-+
-+/**
-+ * GPIO
-+ */
-+#define GPIO_1_OE ((GPIO_1_PA) + 0x4)
-+#define GPIO_1_SET_OE ((GPIO_1_PA) + 0x1C)
-+#define GPIO_1_CLR_OE ((GPIO_1_PA) + 0x20)
-+
-+#define GPIO_2_OE ((GPIO_2_PA) + 0x4)
-+#define GPIO_2_SET_OE ((GPIO_2_PA) + 0x1C)
-+#define GPIO_2_CLR_OE ((GPIO_2_PA) + 0x20)
-+
-+/**
-+ * Serial Configuration
-+ */
-+#define EXT_UART_BASE 0x28000000
-+
-+#define UART_1_BASE (APB_BRIDGE_A_BASE_PA + 0x200000)
-+#define UART_2_BASE (APB_BRIDGE_A_BASE_PA + 0x300000)
-+#define UART_3_BASE (APB_BRIDGE_A_BASE_PA + 0x900000)
-+#define UART_4_BASE (APB_BRIDGE_A_BASE_PA + 0xA00000)
-+
-+#define CFG_NS16550 1
-+#define CFG_NS16550_SERIAL 1
-+#define CFG_NS16550_REG_SIZE 1
-+
-+#if (USE_EXTERNAL_UART != 0)
-+#define CFG_NS16550_CLK 16000000
-+#define CFG_NS16550_COM1 (EXT_UART_BASE)
-+#else // USE_EXTERNAL_UART
-+#define CFG_NS16550_CLK (NOMINAL_SYSCLK)
-+#define USE_UART_FRACTIONAL_DIVIDER
-+#if (INTERNAL_UART == 1)
-+#define CONFIG_OXNAS_UART1
-+#define CFG_NS16550_COM1 (UART_1_BASE)
-+#elif (INTERNAL_UART == 2)
-+#define CONFIG_OXNAS_UART2
-+#define CFG_NS16550_COM1 (UART_2_BASE)
-+#elif (INTERNAL_UART == 3)
-+#define CONFIG_OXNAS_UART3
-+#define CFG_NS16550_COM1 (UART_3_BASE)
-+#else
-+#define CONFIG_OXNAS_UART4
-+#define CFG_NS16550_COM1 (UART_4_BASE)
-+#endif // CONFIG_OXNAS_UART
-+#endif // USE_EXTERNAL_UART
-+
-+#define CONFIG_CONS_INDEX 1
-+#define CONFIG_BAUDRATE 115200
-+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
-+
-+/**
-+ * Monitor commands
-+ */
-+#define BASE_COMMANDS (CFG_CMD_IMI | \
-+ CFG_CMD_IMLS | \
-+ CFG_CMD_BDI | \
-+ CFG_CMD_NET | \
-+ CFG_CMD_PING | \
-+ CFG_CMD_ENV | \
-+ CFG_CMD_RUN | \
-+ CFG_CMD_MEMORY)
-+
-+#ifdef CFG_NO_FLASH
-+#define FLASH_COMMANDS (BASE_COMMANDS)
-+#else
-+#define FLASH_COMMANDS (BASE_COMMANDS | CFG_CMD_FLASH)
-+#endif // CFG_NO_FLASH
-+
-+#ifdef CONFIG_OXNAS_USE_SATA
-+#define SATA_COMMANDS (FLASH_COMMANDS | CFG_CMD_IDE | CFG_CMD_EXT2 | CFG_CMD_LEDFAIL)
-+#else
-+#define SATA_COMMANDS (FLASH_COMMANDS)
-+#endif // CONFIG_OXNAS_USE_SATA
-+
-+#define CONFIG_COMMANDS SATA_COMMANDS
-+
-+/* This must be included AFTER the definition of CONFIG_COMMANDS */
-+#include <cmd_confdefs.h>
-+
-+/**
-+ * Booting
-+ */
-+#if (LINUX_ROOT_RAIDED == 1)
-+#define LINUX_ROOT_DEVICE "root=/dev/md1"
-+#else
-+#define LINUX_ROOT_DEVICE "root=/dev/sda1"
-+#endif
-+#define CONFIG_BOOTARGS LINUX_ROOT_DEVICE " console=ttyS0,115200 elevator=cfq gmac.mac_adr=0x00,0x30,0xe0,0x00,0x00,0x01"
-+
-+#ifdef CONFIG_OXNAS_USE_SATA
-+#define CONFIG_BOOTDELAY 2
-+#define CONFIG_BOOTCOMMAND "run select0 load boot || run select0 load2 boot || run lightled select1 load extinguishled boot || run lightled select1 load2 extinguishled boot || lightled"
-+#define CONFIG_EXTRA_ENV_SETTINGS \
-+ "select0=ide dev 0\0" \
-+ "select1=ide dev 1\0" \
-+ "load=ide read 0x48500000 12c 1644\0" \
-+ "load2=ide read 0x48500000 2a6e 1644\0" \
-+ "lightled=ledfail 1\0" \
-+ "extinguishled=ledfail 0\0" \
-+ "boot=bootm 48500000\0"
-+#else // CONFIG_OXNAS_USE_SATA
-+#define CONFIG_BOOTDELAY 15
-+#define CONFIG_BOOTCOMMAND "bootm 0x41020000"
-+#endif // CONFIG_OXNAS_USE_SATA
-+
-+//#define CONFIG_SHOW_BOOT_PROGRESS 1
-+
-+/**
-+ * Networking
-+ */
-+#define CONFIG_ETHADDR 00:30:e0:00:00:01
-+#define CONFIG_NETMASK 255.255.0.0
-+#define CONFIG_IPADDR 172.31.0.128
-+#define CONFIG_SERVERIP 172.31.0.100
-+#define CONFIG_BOOTFILE "uImage"
-+#define CFG_AUTOLOAD "n"
-+#define CONFIG_NET_RETRY_COUNT 30
-+
-+/**
-+ * Flash support
-+ */
-+#ifndef CFG_NO_FLASH
-+
-+#define FORCE_TOP_BOOT_FLASH 1
-+
-+#define CFG_FLASH_CFI 1
-+#define CFG_FLASH_CFI_DRIVER 1
-+
-+#define NUM_FLASH_MAIN_BLOCKS 63 /* For Intel 28F320B3T */
-+#define NUM_FLASH_PARAM_BLOCKS 8 /* For Intel 28F320B3T */
-+#define FLASH_MAIN_BLOCK_SIZE (64*1024) /* For Intel 28F320B3T family */
-+#define FLASH_PARAM_BLOCK_SIZE (8*1024) /* For Intel 28F320B3T family */
-+
-+/* Assuming counts main blocks and parameter blocks, as the Intel/AMD detection */
-+/* I'm intending to copy would seem to indicate */
-+#define CFG_MAX_FLASH_SECT (NUM_FLASH_MAIN_BLOCKS + NUM_FLASH_PARAM_BLOCKS)
-+
-+#define CFG_MAX_FLASH_BANKS 1 /* Assume counts flash devices */
-+#define FLASH_BASE_OFF 0
-+#define CFG_FLASH_BASE ((STATIC_CS0_BASE_PA) + (FLASH_BASE_OFF))
-+#define PHYS_FLASH_1 (CFG_FLASH_BASE)
-+
-+#define CFG_FLASH_ERASE_TOUT (20*CFG_HZ) /* Timeout for Flash Erase */
-+#define CFG_FLASH_WRITE_TOUT (20*CFG_HZ) /* Timeout for Flash Write */
-+#define CFG_FLASH_WRITE_ATTEMPTS 5
-+
-+#define STATIC_BUS_FLASH_CONFIG 0x4f1f3f3f /* Slow ASIC settings */
-+
-+#endif // !CFG_NO_FLASH
-+
-+/**
-+ * Environment organization
-+ */
-+#ifdef ENV_ON_SATA
-+
-+/* Environment on SATA disk */
-+#define SIZE_TO_SECTORS(x) ((x) / 512)
-+#define CFG_ENV_IS_IN_DISK
-+#define CFG_ENV_SIZE (8*1024)
-+#define ENVIRONMENT_OFFSET ((CFG_SRAM_SIZE) - (CFG_ENV_SIZE) - 1024)
-+#define CFG_ENV_ADDR ((CFG_SRAM_BASE) + (ENVIRONMENT_OFFSET))
-+#define ROM_LOADER_LOAD_START_SECTOR 1
-+#define CFG_ENV_DISK_SECTOR ((ROM_LOADER_LOAD_START_SECTOR) + SIZE_TO_SECTORS(ENVIRONMENT_OFFSET))
-+#define ROM_LOADER_LOAD_REDUNDANT_START_SECTOR 10608
-+#define CFG_ENV_DISK_REDUNDANT_SECTOR ((ROM_LOADER_LOAD_REDUNDANT_START_SECTOR) + SIZE_TO_SECTORS(ENVIRONMENT_OFFSET))
-+
-+#else
-+/** Flash based environment
-+ *
-+ * It appears that all flash env start/size info. has to be pre-defined. How
-+ * this is supposed to work when the flash detection code could cope with all
-+ * sorts of different flash is hard to see.
-+ * It appears from the README that with bottom/top boot flashes with smaller
-+ * parameter blocks available, the environment code will only use a single
-+ * one of these smaller sectors for the environment, i.e. CFG_ENV_SECT_SIZE
-+ * is the size of the environment. I hope this isn't really true. The defines
-+ * below may well not work if this is the truth
-+ */
-+#define CFG_ENV_IS_IN_FLASH
-+/* Environment in flash device parameter blocks */
-+#define CFG_ENV_SECT_SIZE (8*1024)
-+/* First parameter block for environment */
-+#define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
-+/* Second parameter block for backup environment */
-+#define CFG_ENV_SIZE_REDUND (CFG_ENV_SIZE)
-+/* Main environment occupies first parameter block */
-+#define CFG_ENV_ADDR ((CFG_FLASH_BASE)+((NUM_FLASH_MAIN_BLOCKS)*(FLASH_MAIN_BLOCK_SIZE)))
-+/* Backup environment occupies second parameter block */
-+#define CFG_ENV_ADDR_REDUND ((CFG_ENV_ADDR)+(CFG_ENV_SIZE))
-+
-+#endif // ENV_ON_SATA
-+
-+#define CONFIG_ENV_OVERWRITE
-+
-+/* Magic number that indicates rebooting into upgrade mode */
-+#define UPGRADE_MAGIC 0x31 /* ASCII '1' */
-+
-+/* Magic number that indicates user recovery on reboot */
-+/* Also defined in oxnas_user_recovery.agent */
-+#define RECOVERY_MAGIC 0x31 /* ASCII '1' */
-+
-+/* Magic number that indicates controlled power down on reboot */
-+/* Also defined in controlled_power_down.sh in init.d */
-+#define CONTROLLED_POWER_DOWN_MAGIC 0x31 /* ASCII '1' */
-+
-+/* This flag is set in SRAM location by Co Proc */
-+#define CONTROLLED_POWER_UP_MAGIC 0x31 /* ASCII '1' */
-+/* 9k + a quad from top */
-+/* Be carefule on changing the location of this flag
-+ * u-boot has other things to write in SRAM too
-+ */
-+#define POWER_ON_FLAG_SRAM_OFFSET 9220
-+
-+/* Size of malloc() pool */
-+#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024)
-+#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
-+
-+/**
-+ * ASM startup control
-+ */
-+/* Start of address within SRAM of loader's exception table. */
-+/* ROM-based exception table will redirect to here */
-+#define EXCEPTION_BASE (CFG_SRAM_BASE)
-+
-+/**
-+ * Disk related stuff
-+ */
-+#define CONFIG_LBA48
-+#define CONFIG_DOS_PARTITION
-+#define CFG_IDE_MAXDEVICE 2
-+#define CFG_IDE_MAXBUS 1
-+#define CONFIG_IDE_PREINIT
-+#undef CONFIG_IDE_RESET
-+#undef CONFIG_IDE_LED
-+#define CFG_ATA_DATA_OFFSET 0
-+#define CFG_ATA_REG_OFFSET 0
-+#define CFG_ATA_ALT_OFFSET 0
-+
-+/**
-+ * System block reset and clock control
-+ */
-+#define SYS_CTRL_USB11_CTRL (SYS_CONTROL_BASE_PA + 0x00)
-+#define SYS_CTRL_PCI_CTRL0 (SYS_CONTROL_BASE_PA + 0x04)
-+#define SYS_CTRL_PCI_CTRL1 (SYS_CONTROL_BASE_PA + 0x08)
-+#define SYS_CTRL_GPIO_PRIMSEL_CTRL_0 (SYS_CONTROL_BASE_PA + 0x0C)
-+#define SYS_CTRL_GPIO_PRIMSEL_CTRL_1 (SYS_CONTROL_BASE_PA + 0x10)
-+#define SYS_CTRL_GPIO_SECSEL_CTRL_0 (SYS_CONTROL_BASE_PA + 0x14)
-+#define SYS_CTRL_GPIO_SECSEL_CTRL_1 (SYS_CONTROL_BASE_PA + 0x18)
-+#define SYS_CTRL_GPIO_TERTSEL_CTRL_0 (SYS_CONTROL_BASE_PA + 0x8C)
-+#define SYS_CTRL_GPIO_TERTSEL_CTRL_1 (SYS_CONTROL_BASE_PA + 0x90)
-+#define SYS_CTRL_USB11_STAT (SYS_CONTROL_BASE_PA + 0x1c)
-+#define SYS_CTRL_PCI_STAT (SYS_CONTROL_BASE_PA + 0x20)
-+#define SYS_CTRL_CKEN_SET_CTRL (SYS_CONTROL_BASE_PA + 0x2C)
-+#define SYS_CTRL_CKEN_CLR_CTRL (SYS_CONTROL_BASE_PA + 0x30)
-+#define SYS_CTRL_RSTEN_SET_CTRL (SYS_CONTROL_BASE_PA + 0x34)
-+#define SYS_CTRL_RSTEN_CLR_CTRL (SYS_CONTROL_BASE_PA + 0x38)
-+#define SYS_CTRL_PLLSYS_CTRL (SYS_CONTROL_BASE_PA + 0x48)
-+#define SYS_CTRL_PLLSYS_KEY_CTRL (SYS_CONTROL_BASE_PA + 0x6C)
-+#define SYS_CTRL_GMAC_CTRL (SYS_CONTROL_BASE_PA + 0x78)
-+#define SYS_CTRL_UART_CTRL (SYS_CONTROL_BASE_PA + 0x94)
-+
-+#define SYS_CTRL_CKEN_COPRO_BIT 0
-+#define SYS_CTRL_CKEN_DMA_BIT 1
-+#define SYS_CTRL_CKEN_DPE_BIT 2
-+#define SYS_CTRL_CKEN_DDR_BIT 3
-+#define SYS_CTRL_CKEN_SATA_BIT 4
-+#define SYS_CTRL_CKEN_I2S_BIT 5
-+#define SYS_CTRL_CKEN_USBHS_BIT 6
-+#define SYS_CTRL_CKEN_MAC_BIT 7
-+#define SYS_CTRL_CKEN_PCI_BIT 8
-+#define SYS_CTRL_CKEN_STATIC_BIT 9
-+#define SYS_CTRL_CKEN_DDR_PHY_BIT 10
-+
-+#define SYS_CTRL_RSTEN_ARM_BIT 0
-+#define SYS_CTRL_RSTEN_COPRO_BIT 1
-+#define SYS_CTRL_RSTEN_USBHS_BIT 4
-+#define SYS_CTRL_RSTEN_USBHSPHY_BIT 5
-+#define SYS_CTRL_RSTEN_MAC_BIT 6
-+#define SYS_CTRL_RSTEN_PCI_BIT 7
-+#define SYS_CTRL_RSTEN_DMA_BIT 8
-+#define SYS_CTRL_RSTEN_DPE_BIT 9
-+#define SYS_CTRL_RSTEN_DDR_BIT 10
-+#define SYS_CTRL_RSTEN_SATA_BIT 11
-+#define SYS_CTRL_RSTEN_SATA_LINK_BIT 12
-+#define SYS_CTRL_RSTEN_SATA_PHY_BIT 13
-+#define SYS_CTRL_RSTEN_STATIC_BIT 15
-+#define SYS_CTRL_RSTEN_GPIO_BIT 16
-+#define SYS_CTRL_RSTEN_UART1_BIT 17
-+#define SYS_CTRL_RSTEN_UART2_BIT 18
-+#define SYS_CTRL_RSTEN_MISC_BIT 19
-+#define SYS_CTRL_RSTEN_I2S_BIT 20
-+#define SYS_CTRL_RSTEN_AHB_MON_BIT 21
-+#define SYS_CTRL_RSTEN_UART3_BIT 22
-+#define SYS_CTRL_RSTEN_UART4_BIT 23
-+#define SYS_CTRL_RSTEN_SGDMA_BIT 24
-+#define SYS_CTRL_RSTEN_DDR_PHY_BIT 25
-+#define SYS_CTRL_RSTEN_BUS_BIT 31
-+
-+#define SYS_CTRL_GMAC_RGMII 2
-+#define SYS_CTRL_GMAC_SIMPLE_MAX 1
-+#define SYS_CTRL_GMAC_CKEN_GTX 0
-+
-+#define SYS_CTRL_CKCTRL_CTRL_ADDR (SYS_CONTROL_BASE_PA + 0x64)
-+
-+#define SYS_CTRL_CKCTRL_PCI_DIV_BIT 0
-+#define SYS_CTRL_CKCTRL_SLOW_BIT 8
-+
-+#define SYS_CTRL_UART2_DEQ_EN 0
-+#define SYS_CTRL_UART3_DEQ_EN 1
-+#define SYS_CTRL_UART3_IQ_EN 2
-+#define SYS_CTRL_UART4_IQ_EN 3
-+#define SYS_CTRL_UART4_NOT_PCI_MODE 4
-+
-+#define SYS_CTRL_PCI_CTRL1_PCI_STATIC_RQ_BIT 11
-+
-+/**
-+ * SATA related definitions
-+ */
-+#define ATA_PORT_CTL 0
-+#define ATA_PORT_FEATURE 1
-+#define ATA_PORT_NSECT 2
-+#define ATA_PORT_LBAL 3
-+#define ATA_PORT_LBAM 4
-+#define ATA_PORT_LBAH 5
-+#define ATA_PORT_DEVICE 6
-+#define ATA_PORT_COMMAND 7
-+
-+#define SATA_0_REGS_BASE (APB_BRIDGE_B_BASE_PA + 0x900000)
-+#define SATA_1_REGS_BASE (APB_BRIDGE_B_BASE_PA + 0x910000)
-+#define SATA_HOST_REGS_BASE (APB_BRIDGE_B_BASE_PA + 0x9e0000)
-+
-+/* The offsets to the SATA registers */
-+#define SATA_ORB1_OFF 0
-+#define SATA_ORB2_OFF 1
-+#define SATA_ORB3_OFF 2
-+#define SATA_ORB4_OFF 3
-+#define SATA_ORB5_OFF 4
-+
-+#define SATA_FIS_ACCESS 11
-+#define SATA_INT_STATUS_OFF 12 /* Read only */
-+#define SATA_INT_CLR_OFF 12 /* Write only */
-+#define SATA_INT_ENABLE_OFF 13 /* Read only */
-+#define SATA_INT_ENABLE_SET_OFF 13 /* Write only */
-+#define SATA_INT_ENABLE_CLR_OFF 14 /* Write only */
-+#define SATA_VERSION_OFF 15
-+#define SATA_CONTROL_OFF 23
-+#define SATA_COMMAND_OFF 24
-+#define SATA_PORT_CONTROL_OFF 25
-+#define SATA_DRIVE_CONTROL_OFF 26
-+
-+/* The offsets to the link registers that are access in an asynchronous manner */
-+#define SATA_LINK_DATA 28
-+#define SATA_LINK_RD_ADDR 29
-+#define SATA_LINK_WR_ADDR 30
-+#define SATA_LINK_CONTROL 31
-+
-+/* SATA interrupt status register fields */
-+#define SATA_INT_STATUS_EOC_RAW_BIT ( 0 + 16)
-+#define SATA_INT_STATUS_ERROR_BIT ( 2 + 16)
-+#define SATA_INT_STATUS_EOADT_RAW_BIT ( 1 + 16)
-+
-+/* SATA core command register commands */
-+#define SATA_CMD_WRITE_TO_ORB_REGS 2
-+#define SATA_CMD_WRITE_TO_ORB_REGS_NO_COMMAND 4
-+
-+#define SATA_CMD_BUSY_BIT 7
-+
-+#define SATA_SCTL_CLR_ERR 0x00000316UL
-+
-+#define SATA_OPCODE_MASK 0x3
-+
-+#define SATA_LBAL_BIT 0
-+#define SATA_LBAM_BIT 8
-+#define SATA_LBAH_BIT 16
-+#define SATA_HOB_LBAH_BIT 24
-+#define SATA_DEVICE_BIT 24
-+#define SATA_NSECT_BIT 0
-+#define SATA_FEATURE_BIT 16
-+#define SATA_COMMAND_BIT 24
-+#define SATA_CTL_BIT 24
-+
-+/* ATA status (7) register field definitions */
-+#define ATA_STATUS_BSY_BIT 7
-+#define ATA_STATUS_DRDY_BIT 6
-+#define ATA_STATUS_DF_BIT 5
-+#define ATA_STATUS_DRQ_BIT 3
-+#define ATA_STATUS_ERR_BIT 0
-+
-+/* ATA device (6) register field definitions */
-+#define ATA_DEVICE_FIXED_MASK 0xA0
-+#define ATA_DEVICE_DRV_BIT 4
-+#define ATA_DEVICE_DRV_NUM_BITS 1
-+#define ATA_DEVICE_LBA_BIT 6
-+
-+/* ATA control (0) register field definitions */
-+#define ATA_CTL_SRST_BIT 2
-+
-+/* ATA Command register initiated commands */
-+#define ATA_CMD_INIT 0x91
-+#define ATA_CMD_IDENT 0xEC
-+
-+#define SATA_STD_ASYNC_REGS_OFF 0x20
-+#define SATA_SCR_STATUS 0
-+#define SATA_SCR_ERROR 1
-+#define SATA_SCR_CONTROL 2
-+#define SATA_SCR_ACTIVE 3
-+#define SATA_SCR_NOTIFICAION 4
-+
-+#define SATA_BURST_BUF_FORCE_EOT_BIT 0
-+#define SATA_BURST_BUF_DATA_INJ_ENABLE_BIT 1
-+#define SATA_BURST_BUF_DIR_BIT 2
-+#define SATA_BURST_BUF_DATA_INJ_END_BIT 3
-+#define SATA_BURST_BUF_FIFO_DIS_BIT 4
-+#define SATA_BURST_BUF_DIS_DREQ_BIT 5
-+#define SATA_BURST_BUF_DREQ_BIT 6
-+
-+/* Button on GPIO 32 */
-+#define RECOVERY_BUTTON (0x00000001 << 0)
-+#define RECOVERY_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_1
-+#define RECOVERY_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_1
-+#define RECOVERY_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_1
-+#define RECOVERY_CLR_OE_REG GPIO_2_CLR_OE
-+#define RECOVERY_DEBOUNCE_REG GPIO_2_INPUT_DEBOUNCE_ENABLE
-+#define RECOVERY_DATA GPIO_2_PA
-+
-+#endif // CONFIG_H
-diff -Nurd u-boot-1.1.2/include/_exports.h u-boot-1.1.2-oxe810/include/_exports.h
---- u-boot-1.1.2/include/_exports.h 2003-09-12 17:35:33.000000000 +0200
-+++ u-boot-1.1.2-oxe810/include/_exports.h 2008-06-11 17:55:11.000000000 +0200
-@@ -12,6 +12,7 @@
- EXPORT_FUNC(get_timer)
- EXPORT_FUNC(vprintf)
- EXPORT_FUNC(do_reset)
-+EXPORT_FUNC(raise)
- #if (CONFIG_COMMANDS & CFG_CMD_I2C)
- EXPORT_FUNC(i2c_write)
- EXPORT_FUNC(i2c_read)
-diff -Nurd u-boot-1.1.2/include/flash.h u-boot-1.1.2-oxe810/include/flash.h
---- u-boot-1.1.2/include/flash.h 2004-12-16 19:01:48.000000000 +0100
-+++ u-boot-1.1.2-oxe810/include/flash.h 2008-06-11 17:55:11.000000000 +0200
-@@ -207,6 +207,7 @@
- #define ATM_ID_BV1614 0x000000C0 /* 49BV1614 ID */
- #define ATM_ID_BV1614A 0x000000C8 /* 49BV1614A ID */
- #define ATM_ID_BV6416 0x000000D6 /* 49BV6416 ID */
-+#define ATM_ID_BV322 0x000000c9 /* 49BV322A ID */
-
- #define FUJI_ID_29F800BA 0x22582258 /* MBM29F800BA ID (8M) */
- #define FUJI_ID_29F800TA 0x22D622D6 /* MBM29F800TA ID (8M) */
-@@ -405,6 +406,7 @@
- #define FLASH_MAN_INTEL 0x00300000
- #define FLASH_MAN_MT 0x00400000
- #define FLASH_MAN_SHARP 0x00500000
-+#define FLASH_MAN_ATM 0x00070000 /* Atmel */
-
-
- #define FLASH_TYPEMASK 0x0000FFFF /* extract FLASH type information */
-diff -Nurd u-boot-1.1.2/include/ns16550.h u-boot-1.1.2-oxe810/include/ns16550.h
---- u-boot-1.1.2/include/ns16550.h 2004-06-07 01:13:57.000000000 +0200
-+++ u-boot-1.1.2-oxe810/include/ns16550.h 2008-06-11 17:55:11.000000000 +0200
-@@ -19,6 +19,10 @@
- unsigned char lsr; /* 5 */
- unsigned char msr; /* 6 */
- unsigned char scr; /* 7 */
-+#if defined(CONFIG_OXNAS)
-+ unsigned char ext; /* 8 */
-+ unsigned char dlf; /* 9 */
-+#endif
- #if defined(CONFIG_OMAP730)
- unsigned char mdr1; /* 8 */
- unsigned char reg9; /* 9 */
-diff -Nurd u-boot-1.1.2/lib_arm/board.c u-boot-1.1.2-oxe810/lib_arm/board.c
---- u-boot-1.1.2/lib_arm/board.c 2004-08-02 00:48:22.000000000 +0200
-+++ u-boot-1.1.2-oxe810/lib_arm/board.c 2008-06-11 17:55:06.000000000 +0200
-@@ -39,6 +39,9 @@
- #include "../drivers/lan91c96.h"
- #endif
-
-+DECLARE_GLOBAL_DATA_PTR
-+
-+
- #if (CONFIG_COMMANDS & CFG_CMD_NAND)
- void nand_init (void);
- #endif
-@@ -106,7 +109,6 @@
-
- static int init_baudrate (void)
- {
-- DECLARE_GLOBAL_DATA_PTR;
-
- uchar tmp[64]; /* long enough for environment variables */
- int i = getenv_r ("baudrate", tmp, sizeof (tmp));
-@@ -142,16 +144,18 @@
- */
- static int display_dram_config (void)
- {
-- DECLARE_GLOBAL_DATA_PTR;
- int i;
-
- puts ("RAM Configuration:\n");
-
- for(i=0; i<CONFIG_NR_DRAM_BANKS; i++) {
-- printf ("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
-+ printf ("\tBank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
- print_size (gd->bd->bi_dram[i].size, "\n");
- }
-
-+ puts("SRAM Configuration:\n");
-+ printf("\t%dKB at 0x%08x\n", gd->bd->bi_sramsize >> 10, gd->bd->bi_sramstart);
-+
- return (0);
- }
-
-@@ -191,6 +195,12 @@
- cpu_init, /* basic cpu dependent setup */
- board_init, /* basic board dependent setup */
- interrupt_init, /* set up exceptions */
-+#ifdef CONFIG_OXNAS
-+ /* Need early console to see SATA env. load messages */
-+ init_baudrate, /* initialze baudrate settings */
-+ serial_init, /* serial communications setup */
-+ console_init_f, /* stage 1 init of console */
-+#endif // CONFIG_OXNAS
- env_init, /* initialize environment */
- init_baudrate, /* initialze baudrate settings */
- serial_init, /* serial communications setup */
-@@ -206,7 +216,6 @@
-
- void start_armboot (void)
- {
-- DECLARE_GLOBAL_DATA_PTR;
-
- ulong size;
- init_fnc_t **init_fnc_ptr;
-@@ -232,9 +241,11 @@
- }
- }
-
-+#ifndef CFG_NO_FLASH
- /* configure available FLASH banks */
- size = flash_init ();
- display_flash_config (size);
-+#endif // CFG_NO_FLASH
-
- #ifdef CONFIG_VFD
- # ifndef PAGE_SIZE
-@@ -354,6 +365,12 @@
- {
- puts ("### ERROR ### Please RESET the board ###\n");
- for (;;);
-+}
-+
-+void raise (int n)
-+{
-+ puts ("### ERROR ### Please RESET the board ###\n");
-+ for (;;);
- }
-
- #ifdef CONFIG_MODEM_SUPPORT
-diff -Nurd u-boot-1.1.2/MAKEALL u-boot-1.1.2-oxe810/MAKEALL
---- u-boot-1.1.2/MAKEALL 2004-12-31 10:32:48.000000000 +0100
-+++ u-boot-1.1.2-oxe810/MAKEALL 2008-06-11 17:55:31.000000000 +0200
-@@ -154,7 +154,7 @@
- lpd7a400 mx1ads mx1fs2 omap1510inn \
- omap1610h2 omap1610inn omap730p2 scb9328 \
- smdk2400 smdk2410 trab VCMA9 \
-- versatile \
-+ versatile oxnas \
- "
-
- #########################################################################
-diff -Nurd u-boot-1.1.2/Makefile u-boot-1.1.2-oxe810/Makefile
---- u-boot-1.1.2/Makefile 2004-12-19 10:58:11.000000000 +0100
-+++ u-boot-1.1.2-oxe810/Makefile 2008-06-11 17:55:31.000000000 +0200
-@@ -1296,6 +1296,9 @@
- SX1_config : unconfig
- @./mkconfig $(@:_config=) arm arm925t sx1
-
-+oxnas_config : unconfig
-+ @./mkconfig $(@:_config=) arm arm926ejs oxnas
-+
- # TRAB default configuration: 8 MB Flash, 32 MB RAM
- trab_config \
- trab_bigram_config \
-@@ -1561,11 +1564,12 @@
- clean:
- find . -type f \
- \( -name 'core' -o -name '*.bak' -o -name '*~' \
-- -o -name '*.o' -o -name '*.a' \) -print \
-+ -o -name '*.o' -o -name '*.a' -o -name '.depend' \) -print \
- | xargs rm -f
- rm -f examples/hello_world examples/timer \
- examples/eepro100_eeprom examples/sched \
-- examples/mem_to_mem_idma2intr examples/82559_eeprom
-+ examples/mem_to_mem_idma2intr examples/82559_eeprom \
-+ examples/mem_test
- rm -f tools/img2srec tools/mkimage tools/envcrc tools/gen_eth_addr
- rm -f tools/mpc86x_clk tools/ncb
- rm -f tools/easylogo/easylogo tools/bmp_logo
-diff -Nurd u-boot-1.1.2/net/net.c u-boot-1.1.2-oxe810/net/net.c
---- u-boot-1.1.2/net/net.c 2004-10-12 00:51:14.000000000 +0200
-+++ u-boot-1.1.2-oxe810/net/net.c 2008-06-11 17:55:11.000000000 +0200
-@@ -225,7 +225,7 @@
- return;
-
- t = get_timer(0);
--
-+
- /* check for arp timeout */
- if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT * CFG_HZ) {
- NetArpWaitTry++;
-@@ -235,6 +235,7 @@
- NetArpWaitTry = 0;
- NetStartAgain();
- } else {
-+ puts ("\nARP Resend request\n");
- NetArpWaitTimerStart = t;
- ArpRequest();
- }
-@@ -738,7 +739,7 @@
- #if defined(CONFIG_NET_MULTI)
- printf ("Using %s device\n", eth_get_name());
- #endif /* CONFIG_NET_MULTI */
-- NetSetTimeout (10 * CFG_HZ, PingTimeout);
-+ NetSetTimeout (30 * CFG_HZ, PingTimeout);
- NetSetHandler (PingHandler);
-
- PingSend();
-@@ -1384,7 +1385,7 @@
- */
- /* XXX point to ip packet */
- (*packetHandler)((uchar *)ip, 0, 0, 0);
-- break;
-+ return;/**break; BHC Changed to remove second invocation of ping handler below */
- #endif
- default:
- return;
-@@ -1492,10 +1493,11 @@
- NetCksum(uchar * ptr, int len)
- {
- ulong xsum;
-+ ushort *s = ptr;
-
- xsum = 0;
- while (len-- > 0)
-- xsum += *((ushort *)ptr)++;
-+ xsum += *s++;
- xsum = (xsum & 0xffff) + (xsum >> 16);
- xsum = (xsum & 0xffff) + (xsum >> 16);
- return (xsum & 0xffff);
-diff -Nurd u-boot-1.1.2/net/tftp.c u-boot-1.1.2-oxe810/net/tftp.c
---- u-boot-1.1.2/net/tftp.c 2004-04-15 23:48:55.000000000 +0200
-+++ u-boot-1.1.2-oxe810/net/tftp.c 2008-06-11 17:55:11.000000000 +0200
-@@ -106,6 +106,7 @@
- volatile uchar * pkt;
- volatile uchar * xp;
- int len = 0;
-+ volatile ushort * s;
-
- /*
- * We will always be sending some sort of packet, so
-@@ -117,7 +118,9 @@
-
- case STATE_RRQ:
- xp = pkt;
-- *((ushort *)pkt)++ = htons(TFTP_RRQ);
-+ s = (ushort *)pkt;
-+ *s++ = htons(TFTP_RRQ);
-+ pkt = (uchar *)s;
- strcpy ((char *)pkt, tftp_filename);
- pkt += strlen(tftp_filename) + 1;
- strcpy ((char *)pkt, "octet");
-@@ -135,15 +138,19 @@
- case STATE_DATA:
- case STATE_OACK:
- xp = pkt;
-- *((ushort *)pkt)++ = htons(TFTP_ACK);
-- *((ushort *)pkt)++ = htons(TftpBlock);
-+ s = (ushort *)pkt;
-+ *s++ = htons(TFTP_ACK);
-+ *s++ = htons(TftpBlock);
-+ pkt = (uchar *)s;
- len = pkt - xp;
- break;
-
- case STATE_TOO_LARGE:
- xp = pkt;
-- *((ushort *)pkt)++ = htons(TFTP_ERROR);
-- *((ushort *)pkt)++ = htons(3);
-+ s = (ushort *)pkt;
-+ *s++ = htons(TFTP_ERROR);
-+ *s++ = htons(3);
-+ pkt = (uchar *)s;
- strcpy ((char *)pkt, "File too large");
- pkt += 14 /*strlen("File too large")*/ + 1;
- len = pkt - xp;
-@@ -151,8 +158,10 @@
-
- case STATE_BAD_MAGIC:
- xp = pkt;
-- *((ushort *)pkt)++ = htons(TFTP_ERROR);
-- *((ushort *)pkt)++ = htons(2);
-+ s = (ushort *)pkt;
-+ *s++ = htons(TFTP_ERROR);
-+ *s++ = htons(2);
-+ pkt = (uchar *)s;
- strcpy ((char *)pkt, "File has bad magic");
- pkt += 18 /*strlen("File has bad magic")*/ + 1;
- len = pkt - xp;
-@@ -167,6 +176,7 @@
- TftpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
- {
- ushort proto;
-+ ushort *s;
-
- if (dest != TftpOurPort) {
- return;
-@@ -180,7 +190,9 @@
- }
- len -= 2;
- /* warning: don't use increment (++) in ntohs() macros!! */
-- proto = *((ushort *)pkt)++;
-+ s = (ushort *)pkt;
-+ proto = *s++;
-+ pkt = (uchar *)s;
- switch (ntohs(proto)) {
-
- case TFTP_RRQ:
--- /dev/null
+diff -Nurd u-boot-1.1.2/board/oxnas/config.mk u-boot-1.1.2-oxe810/board/oxnas/config.mk
+--- u-boot-1.1.2/board/oxnas/config.mk 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-1.1.2-oxe810/board/oxnas/config.mk 2008-06-11 17:55:18.000000000 +0200
+@@ -0,0 +1,26 @@
++TEXT_BASE = 0x48d00000
++CROSS_COMPILE = arm-linux-
++
++PLL400 ?= 733333333
++RPSCLK ?= 25000000
++
++NAS_VERSION ?= 810
++FPGA ?= 0
++FPGA_ARM_CLK ?= 25000000
++
++PROBE_MEM_SIZE ?= 1
++MEM_SIZE ?= 64 # Memory size in megabytes if probing is not enabled
++MEM_ODT ?= 150
++
++USE_SATA ?= 1
++USE_SATA_ENV ?= 1
++USE_FLASH ?= 1
++
++LINUX_ROOT_RAIDED ?= 1
++
++USE_EXTERNAL_UART ?= 0
++INTERNAL_UART ?= 2
++
++TEST_BRD ?= 0 # Only significant for OX800
++
++PLATFORM_CPPFLAGS += -DLINUX_ROOT_RAIDED=$(LINUX_ROOT_RAIDED) -DMEM_ODT=$(MEM_ODT) -DPROBE_MEM_SIZE=$(PROBE_MEM_SIZE) -DNAS_VERSION=$(NAS_VERSION) -DFPGA=$(FPGA) -DFPGA_ARM_CLK=$(FPGA_ARM_CLK) -DINTERNAL_UART=$(INTERNAL_UART) -DUSE_EXTERNAL_UART=$(USE_EXTERNAL_UART) -DMEM_SIZE=$(MEM_SIZE) -DPLL400=$(PLL400) -DRPSCLK=$(RPSCLK) -DTEST_BRD=$(TEST_BRD) -DUSE_SATA=$(USE_SATA) -DUSE_SATA_ENV=$(USE_SATA_ENV) -DUSE_FLASH=$(USE_FLASH)
+diff -Nurd u-boot-1.1.2/board/oxnas/eth.c u-boot-1.1.2-oxe810/board/oxnas/eth.c
+--- u-boot-1.1.2/board/oxnas/eth.c 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-1.1.2-oxe810/board/oxnas/eth.c 2008-06-11 17:55:18.000000000 +0200
+@@ -0,0 +1,1666 @@
++/*
++ * (C) Copyright 2005
++ * Oxford Semiconductor Ltd
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * 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 <common.h>
++#include <malloc.h>
++#include <net.h>
++#include <asm/barrier.h>
++
++//#define DEBUG_GMAC_INIT
++
++// The number of bytes wasted at the start of a received packet buffer in order
++// to ensure the IP header will be aligned to a 32-bit boundary
++static const int ETHER_FRAME_ALIGN_WASTAGE = 2;
++static const int EXTRA_RX_SKB_SPACE = 32; // Otherwise GMAC spans over >1 skb
++static const int ETHER_MTU = 1500;
++
++static const u32 MAC_BASE_OFFSET = 0x0000;
++static const u32 DMA_BASE_OFFSET = 0x1000;
++
++static const int NUM_TX_DMA_DESCRIPTORS = 1;
++static const int NUM_RX_DMA_DESCRIPTORS = 32;
++
++/* Generic MII registers. */
++#define MII_BMCR 0x00 /* Basic mode control register */
++#define MII_BMSR 0x01 /* Basic mode status register */
++#define MII_PHYSID1 0x02 /* PHYS ID 1 */
++#define MII_PHYSID2 0x03 /* PHYS ID 2 */
++#define MII_ADVERTISE 0x04 /* Advertisement control reg */
++#define MII_LPA 0x05 /* Link partner ability reg */
++#define MII_EXPANSION 0x06 /* Expansion register */
++#define MII_CTRL1000 0x09 /* 1000BASE-T control */
++#define MII_STAT1000 0x0a /* 1000BASE-T status */
++#define MII_ESTATUS 0x0f /* Extended Status */
++
++/* Basic mode control register. */
++#define BMCR_RESV 0x003f /* Unused... */
++#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */
++#define BMCR_CTST 0x0080 /* Collision test */
++#define BMCR_FULLDPLX 0x0100 /* Full duplex */
++#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
++#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */
++#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */
++#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
++#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
++#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
++#define BMCR_RESET 0x8000 /* Reset the DP83840 */
++
++/* Basic mode status register. */
++#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
++#define BMSR_JCD 0x0002 /* Jabber detected */
++#define BMSR_LSTATUS 0x0004 /* Link status */
++#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
++#define BMSR_RFAULT 0x0010 /* Remote fault detected */
++#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
++#define BMSR_RESV 0x00c0 /* Unused... */
++#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */
++#define BMSR_100FULL2 0x0200 /* Can do 100BASE-T2 HDX */
++#define BMSR_100HALF2 0x0400 /* Can do 100BASE-T2 FDX */
++#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
++#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
++#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
++#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
++#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
++
++/* 1000BASE-T Status register */
++#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */
++#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */
++#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */
++#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */
++#define PHY_TYPE_NONE 0
++#define PHY_TYPE_MICREL_KS8721BL 0x00221619
++#define PHY_TYPE_VITESSE_VSC8201XVZ 0x000fc413
++#define PHY_TYPE_REALTEK_RTL8211BGR 0x001cc912
++#define PHY_TYPE_LSI_ET1011C 0x0282f013
++
++/* Specific PHY values */
++#define VSC8201_MII_ACSR 0x1c // Vitesse VCS8201 gigabit PHY Auxillary Control and Status register
++#define VSC8201_MII_ACSR_MDPPS_BIT 2 // Mode/Duplex Pin Priority Select
++
++#define ET1011C_MII_CONFIG 0x16
++#define ET1011C_MII_CONFIG_IFMODESEL 0
++#define ET1011C_MII_CONFIG_IFMODESEL_NUM_BITS 3
++#define ET1011C_MII_CONFIG_SYSCLKEN 4
++#define ET1011C_MII_CONFIG_TXCLKEN 5
++#define ET1011C_MII_CONFIG_TBI_RATESEL 8
++#define ET1011C_MII_CONFIG_CRS_TX_EN 15
++
++#define ET1011C_MII_CONFIG_IFMODESEL_GMII_MII 0
++#define ET1011C_MII_CONFIG_IFMODESEL_TBI 1
++#define ET1011C_MII_CONFIG_IFMODESEL_GMII_MII_GTX 2
++
++#define ET1011C_MII_LED2 0x1c
++#define ET1011C_MII_LED2_LED_TXRX 12
++#define ET1011C_MII_LED2_LED_NUM_BITS 4
++
++#define ET1011C_MII_LED2_LED_TXRX_ON 0xe
++#define ET1011C_MII_LED2_LED_TXRX_ACTIVITY 0x7
++
++// Some typedefs to cope with std Linux types
++typedef void sk_buff_t;
++
++// The in-memory descriptor structures
++typedef struct gmac_dma_desc
++{
++ /** The encoded status field of the GMAC descriptor */
++ u32 status;
++ /** The encoded length field of GMAC descriptor */
++ u32 length;
++ /** Buffer 1 pointer field of GMAC descriptor */
++ u32 buffer1;
++ /** Buffer 2 pointer or next descriptor pointer field of GMAC descriptor */
++ u32 buffer2;
++ /** Not used for U-Boot */
++ u32 skb;
++} __attribute ((packed)) gmac_dma_desc_t;
++
++typedef struct gmac_desc_list_info
++{
++ gmac_dma_desc_t* base_ptr;
++ int num_descriptors;
++ int empty_count;
++ int full_count;
++ int r_index;
++ int w_index;
++} gmac_desc_list_info_t;
++
++// Private data structure for the GMAC driver
++typedef struct gmac_priv
++{
++ /** Base address of GMAC MAC registers */
++ u32 macBase;
++ /** Base address of GMAC DMA registers */
++ u32 dmaBase;
++
++ /** The number of descriptors in the gmac_dma_desc_t array holding both the
++ * TX and RX descriptors. The TX descriptors reside at the start of the
++ * array */
++ unsigned total_num_descriptors;
++
++ /** The address of the start of the descriptor array */
++ gmac_dma_desc_t *desc_base_addr;
++
++ /** Descriptor list management */
++ gmac_desc_list_info_t tx_gmac_desc_list_info;
++ gmac_desc_list_info_t rx_gmac_desc_list_info;
++
++ /** PHY info */
++ u32 phy_type;
++ u32 phy_addr;
++ int phy_id;
++ int link_is_1000M;
++} gmac_priv_t;
++
++/**
++ * MAC register indices
++ */
++typedef enum gmac_mac_regs {
++ MAC_CONFIG_REG = 0,
++ MAC_FRAME_FILTER_REG = 1,
++ MAC_HASH_HIGH_REG = 2,
++ MAC_HASH_LOW_REG = 3,
++ MAC_GMII_ADR_REG = 4,
++ MAC_GMII_DATA_REG = 5,
++ MAC_FLOW_CNTL_REG = 6,
++ MAC_VLAN_TAG_REG = 7,
++ MAC_VERSION_REG = 8,
++ MAC_ADR0_HIGH_REG = 16,
++ MAC_ADR0_LOW_REG = 17,
++ MAC_ADR1_HIGH_REG = 18,
++ MAC_ADR1_LOW_REG = 19,
++ MAC_ADR2_HIGH_REG = 20,
++ MAC_ADR2_LOW_REG = 21,
++ MAC_ADR3_HIGH_REG = 22,
++ MAC_ADR3_LOW_REG = 23,
++ MAC_ADR4_HIGH_REG = 24,
++ MAC_ADR4_LOW_REG = 25,
++ MAC_ADR5_HIGH_REG = 26,
++ MAC_ADR5_LOW_REG = 27,
++ MAC_ADR6_HIGH_REG = 28,
++ MAC_ADR6_LOW_REG = 29,
++ MAC_ADR7_HIGH_REG = 30,
++ MAC_ADR7_LOW_REG = 31,
++ MAC_ADR8_HIGH_REG = 32,
++ MAC_ADR8_LOW_REG = 33,
++ MAC_ADR9_HIGH_REG = 34,
++ MAC_ADR9_LOW_REG = 35,
++ MAC_ADR10_HIGH_REG = 36,
++ MAC_ADR10_LOW_REG = 37,
++ MAC_ADR11_HIGH_REG = 38,
++ MAC_ADR11_LOW_REG = 39,
++ MAC_ADR12_HIGH_REG = 40,
++ MAC_ADR12_LOW_REG = 41,
++ MAC_ADR13_HIGH_REG = 42,
++ MAC_ADR13_LOW_REG = 43,
++ MAC_ADR14_HIGH_REG = 44,
++ MAC_ADR14_LOW_REG = 45,
++ MAC_ADR15_HIGH_REG = 46,
++ MAC_ADR15_LOW_REG = 47
++} gmac_mac_regs_t;
++
++
++/**
++ * MAC register field definitions
++ */
++typedef enum gmac_config_reg {
++ MAC_CONFIG_WD_BIT = 23,
++ MAC_CONFIG_JD_BIT = 22,
++ MAC_CONFIG_BE_BIT = 21,
++ MAC_CONFIG_JE_BIT = 20,
++ MAC_CONFIG_IFG_BIT = 17,
++ MAC_CONFIG_PS_BIT = 15,
++ MAC_CONFIG_DO_BIT = 13,
++ MAC_CONFIG_LM_BIT = 12,
++ MAC_CONFIG_DM_BIT = 11,
++ MAC_CONFIG_IPC_BIT = 10,
++ MAC_CONFIG_DR_BIT = 9,
++ MAC_CONFIG_ACS_BIT = 7,
++ MAC_CONFIG_BL_BIT = 5,
++ MAC_CONFIG_DC_BIT = 4,
++ MAC_CONFIG_TE_BIT = 3,
++ MAC_CONFIG_RE_BIT = 2
++} gmac_config_reg_t;
++
++#define MAC_CONFIG_IFG_NUM_BITS 3
++#define MAC_CONFIG_BL_NUM_BITS 2
++
++typedef enum gmac_frame_filter_reg {
++ MAC_FRAME_FILTER_RA_BIT = 31,
++ MAC_FRAME_FILTER_SAF_BIT = 9,
++ MAC_FRAME_FILTER_SAIF_BIT = 8,
++ MAC_FRAME_FILTER_PCF_BIT = 6,
++ MAC_FRAME_FILTER_DBF_BIT = 5,
++ MAC_FRAME_FILTER_PM_BIT = 4,
++ MAC_FRAME_FILTER_DAIF_BIT = 3,
++ MAC_FRAME_FILTER_HMC_BIT = 2,
++ MAC_FRAME_FILTER_HUC_BIT = 1,
++ MAC_FRAME_FILTER_PR_BIT = 0
++} gmac_frame_filter_reg_t;
++
++#define MAC_FRAME_FILTER_PCF_NUM_BITS 2
++
++typedef enum gmac_hash_table_high_reg {
++ MAC_HASH_HIGH_HTH_BIT = 0
++} gmac_hash_table_high_reg_t;
++
++typedef enum gmac_hash_table_low_reg {
++ MAC_HASH_LOW_HTL_BIT = 0
++} gmac_hash_table_low_reg_t;
++
++typedef enum gmac_gmii_address_reg {
++ MAC_GMII_ADR_PA_BIT = 11,
++ MAC_GMII_ADR_GR_BIT = 6,
++ MAC_GMII_ADR_CR_BIT = 2,
++ MAC_GMII_ADR_GW_BIT = 1,
++ MAC_GMII_ADR_GB_BIT = 0
++} gmac_gmii_address_reg_t;
++
++#define MAC_GMII_ADR_PA_NUM_BITS 5
++#define MAC_GMII_ADR_GR_NUM_BITS 5
++#define MAC_GMII_ADR_CR_NUM_BITS 3
++
++typedef enum gmac_gmii_data_reg {
++ MAC_GMII_DATA_GD_BIT = 0
++} gmac_gmii_data_reg_t;
++
++#define MAC_GMII_DATA_GD_NUM_BITS 16
++
++typedef enum gmac_flow_control_reg {
++ MAC_FLOW_CNTL_PT_BIT = 16,
++ MAC_FLOW_CNTL_PLT_BIT = 4,
++ MAC_FLOW_CNTL_UP_BIT = 3,
++ MAC_FLOW_CNTL_RFE_BIT = 2,
++ MAC_FLOW_CNTL_TFE_BIT = 1,
++ MAC_FLOW_CNTL_FCB_BPA_BIT = 0
++} gmac_flow_control_reg_t;
++
++#define MAC_FLOW_CNTL_PT_NUM_BITS 16
++#define MAC_FLOW_CNTL_PLT_NUM_BITS 2
++
++typedef enum gmac_vlan_tag_reg {
++ MAC_VLAN_TAG_LV_BIT = 0
++} gmac_vlan_tag_reg_t;
++
++#define MAC_VLAN_TAG_LV_NUM_BITS 16
++
++typedef enum gmac_version_reg {
++ MAC_VERSION_UD_BIT = 8,
++ MAC_VERSION_SD_BIT = 0
++} gmac_version_reg_t;
++
++#define MAC_VERSION_UD_NUM_BITS 8
++#define MAC_VERSION_SD_NUM_BITS 8
++
++typedef enum gmac_mac_adr_0_high_reg {
++ MAC_ADR0_HIGH_MO_BIT = 31,
++ MAC_ADR0_HIGH_A_BIT = 0
++} gmac_mac_adr_0_high_reg_t;
++
++#define MAC_ADR0_HIGH_A_NUM_BITS 16
++
++typedef enum gmac_mac_adr_0_low_reg {
++ MAC_ADR0_LOW_A_BIT = 0
++} gmac_mac_adr_0_low_reg_t;
++
++typedef enum gmac_mac_adr_1_high_reg {
++ MAC_ADR1_HIGH_AE_BIT = 31,
++ MAC_ADR1_HIGH_SA_BIT = 30,
++ MAC_ADR1_HIGH_MBC_BIT = 24,
++ MAC_ADR1_HIGH_A_BIT = 0
++} gmac_mac_adr_1_high_reg_t;
++
++#define MAC_ADR1_HIGH_MBC_NUM_BITS 6
++#define MAC_ADR1_HIGH_A_NUM_BITS 16
++
++typedef enum gmac_mac_adr_1_low_reg {
++ MAC_ADR1_LOW_A_BIT = 0
++} gmac_mac_adr_1_low_reg_t;
++
++
++/**
++ * MMC register indices - registers accessed via the MAC accessor functions
++ */
++typedef enum gmac_mmc_regs {
++ MMC_CONTROL_REG = 64,
++ MMC_RX_INT_REG = 65,
++ MMC_TX_INT_REG = 66,
++ MMC_RX_MASK_REG = 67,
++ MMC_TX_MASK_REG = 68
++} gmac_mmc_regs_t;
++
++/**
++ * DMA register indices
++ */
++typedef enum gmac_dma_regs {
++ DMA_BUS_MODE_REG = 0,
++ DMA_TX_POLL_REG = 1,
++ DMA_RX_POLL_REG = 2,
++ DMA_RX_DESC_ADR_REG = 3,
++ DMA_TX_DESC_ADR_REG = 4,
++ DMA_STATUS_REG = 5,
++ DMA_OP_MODE_REG = 6,
++ DMA_INT_ENABLE_REG = 7,
++ DMA_MISSED_OVERFLOW_REG = 8,
++ DMA_CUR_TX_DESC_REG = 18,
++ DMA_CUR_RX_DESC_REG = 19,
++ DMA_CUR_TX_ADR_REG = 20,
++ DMA_CUR_RX_ADR_REG = 21
++} gmac_dma_regs_t;
++
++/**
++ * DMA register field definitions
++ */
++
++typedef enum gmac_dma_bus_mode_reg {
++ DMA_BUS_MODE_FB_BIT = 16,
++ DMA_BUS_MODE_PR_BIT = 14,
++ DMA_BUS_MODE_PBL_BIT = 8,
++ DMA_BUS_MODE_DSL_BIT = 2,
++ DMA_BUS_MODE_DA_BIT = 1,
++ DMA_BUS_MODE_SWR_BIT = 0
++} gmac_dma_bus_mode_reg_t;
++
++#define DMA_BUS_MODE_PR_NUM_BITS 2
++#define DMA_BUS_MODE_PBL_NUM_BITS 6
++#define DMA_BUS_MODE_DSL_NUM_BITS 5
++
++typedef enum gmac_dma_tx_poll_demand_reg {
++ DMA_TX_POLL_TPD_BIT = 0
++} gmac_dma_tx_poll_demand_reg_t;
++
++typedef enum gmac_dma_rx_poll_demand_reg {
++ DMA_RX_POLL_RPD_BIT = 0
++} gmac_dma_rx_poll_demand_reg_t;
++
++typedef enum gmac_dma_rx_desc_list_adr_reg {
++ DMA_RX_DESC_ADR_SRL_BIT = 0
++} gmac_dma_rx_desc_list_adr_reg_t;
++
++typedef enum gmac_dma_tx_desc_list_adr_reg {
++ DMA_TX_DESC_ADR_STL_BIT = 0
++} gmac_dma_tx_desc_list_adr_reg_t;
++
++typedef enum gmac_dma_status_reg {
++ DMA_STATUS_GPI_BIT = 28,
++ DMA_STATUS_GMI_BIT = 27,
++ DMA_STATUS_GLI_BIT = 26,
++ DMA_STATUS_EB_BIT = 23,
++ DMA_STATUS_TS_BIT = 20,
++ DMA_STATUS_RS_BIT = 17,
++ DMA_STATUS_NIS_BIT = 16,
++ DMA_STATUS_AIS_BIT = 15,
++ DMA_STATUS_ERI_BIT = 14,
++ DMA_STATUS_FBE_BIT = 13,
++ DMA_STATUS_ETI_BIT = 10,
++ DMA_STATUS_RWT_BIT = 9,
++ DMA_STATUS_RPS_BIT = 8,
++ DMA_STATUS_RU_BIT = 7,
++ DMA_STATUS_RI_BIT = 6,
++ DMA_STATUS_UNF_BIT = 5,
++ DMA_STATUS_OVF_BIT = 4,
++ DMA_STATUS_TJT_BIT = 3,
++ DMA_STATUS_TU_BIT = 2,
++ DMA_STATUS_TPS_BIT = 1,
++ DMA_STATUS_TI_BIT = 0
++} gmac_dma_status_reg_t;
++
++#define DMA_STATUS_EB_NUM_BITS 3
++#define DMA_STATUS_TS_NUM_BITS 3
++#define DMA_STATUS_RS_NUM_BITS 3
++
++typedef enum gmac_dma_op_mode_reg {
++ DMA_OP_MODE_SF_BIT = 21,
++ DMA_OP_MODE_FTF_BIT = 20,
++ DMA_OP_MODE_TTC_BIT = 14,
++ DMA_OP_MODE_ST_BIT = 13,
++ DMA_OP_MODE_RFD_BIT = 11,
++ DMA_OP_MODE_RFA_BIT = 9,
++ DMA_OP_MODE_EFC_BIT = 8,
++ DMA_OP_MODE_FEF_BIT = 7,
++ DMA_OP_MODE_FUF_BIT = 6,
++ DMA_OP_MODE_RTC_BIT = 3,
++ DMA_OP_MODE_OSF_BIT = 2,
++ DMA_OP_MODE_SR_BIT = 1
++} gmac_dma_op_mode_reg_t;
++
++#define DMA_OP_MODE_TTC_NUM_BITS 3
++#define DMA_OP_MODE_RFD_NUM_BITS 2
++#define DMA_OP_MODE_RFA_NUM_BITS 2
++#define DMA_OP_MODE_RTC_NUM_BITS 2
++
++typedef enum gmac_dma_intr_enable_reg {
++ DMA_INT_ENABLE_NI_BIT = 16,
++ DMA_INT_ENABLE_AI_BIT = 15,
++ DMA_INT_ENABLE_ERE_BIT = 14,
++ DMA_INT_ENABLE_FBE_BIT = 13,
++ DMA_INT_ENABLE_ETE_BIT = 10,
++ DMA_INT_ENABLE_RW_BIT = 9,
++ DMA_INT_ENABLE_RS_BIT = 8,
++ DMA_INT_ENABLE_RU_BIT = 7,
++ DMA_INT_ENABLE_RI_BIT = 6,
++ DMA_INT_ENABLE_UN_BIT = 5,
++ DMA_INT_ENABLE_OV_BIT = 4,
++ DMA_INT_ENABLE_TJ_BIT = 3,
++ DMA_INT_ENABLE_TU_BIT = 2,
++ DMA_INT_ENABLE_TS_BIT = 1,
++ DMA_INT_ENABLE_TI_BIT = 0
++} gmac_dma_intr_enable_reg_t;
++
++typedef enum gmac_dma_missed_overflow_reg {
++ DMA_MISSED_OVERFLOW_OFOC_BIT = 28, // Overflow bit for FIFO Overflow Counter
++ DMA_MISSED_OVERFLOW_AMFC_BIT = 17, // Application Missed Frames Count
++ DMA_MISSED_OVERFLOW_OAMFO_BIT = 16, // Overflow bit for Application Missed Frames Count
++ DMA_MISSED_OVERFLOW_CMFC_BIT = 0 // Controller Missed Frames Count
++} gmac_dma_missed_overflow_reg_t;
++
++#define DMA_MISSED_OVERFLOW_OAMFO_NUM_BITS 11
++#define DMA_MISSED_OVERFLOW_CMFC_NUM_BITS 16
++
++typedef enum gmac_dma_current_tx_desc_reg {
++ DMA_CUR_TX_DESC_A_BIT = 0
++} gmac_dma_current_tx_desc_reg_t;
++
++typedef enum gmac_dma_current_rx_desc_reg {
++ DMA_CUR_RX_DESC_A_BIT = 0
++} gmac_dma_current_rx_desc_reg_t;
++
++typedef enum gmac_dma_current_tx_adr_reg {
++ DMA_CUR_TX_ADR_A_BIT = 0
++} gmac_dma_current_tx_adr_reg_t;
++
++typedef enum gmac_dma_current_rx_adr_reg {
++ DMA_CUR_RX_ADR_A_BIT = 0
++} gmac_dma_current_rx_adr_reg_t;
++
++/**
++ * Descriptor support
++ */
++/** Descriptor status word field definitions */
++typedef enum desc_status {
++ descOwnByDma = 0x80000000, /* descriptor is owned by DMA engine */
++
++ descFrameLengthMask = 0x3FFF0000, /* Receive descriptor frame length */
++ descFrameLengthShift = 16,
++
++ descError = 0x00008000, /* Error summary bit - OR of the following bits: v */
++
++ descRxTruncated = 0x00004000, /* Rx - no more descriptors for receive frame E */
++
++ descRxLengthError = 0x00001000, /* Rx - frame size not matching with length field */
++ descRxDamaged = 0x00000800, /* Rx - frame was damaged due to buffer overflow E */
++ descRxFirst = 0x00000200, /* Rx - first descriptor of the frame */
++ descRxLast = 0x00000100, /* Rx - last descriptor of the frame */
++ descRxLongFrame = 0x00000080, /* Rx - frame is longer than 1518 bytes E */
++ descRxCollision = 0x00000040, /* Rx - late collision occurred during reception E */
++ descRxFrameEther = 0x00000020, /* Rx - Frame type - Ethernet, otherwise 802.3 */
++ descRxWatchdog = 0x00000010, /* Rx - watchdog timer expired during reception E */
++ descRxMiiError = 0x00000008, /* Rx - error reported by MII interface E */
++ descRxDribbling = 0x00000004, /* Rx - frame contains noninteger multiple of 8 bits */
++ descRxCrc = 0x00000002, /* Rx - CRC error E */
++
++ descTxTimeout = 0x00004000, /* Tx - Transmit jabber timeout E */
++ descTxLostCarrier = 0x00000800, /* Tx - carrier lost during tramsmission E */
++ descTxNoCarrier = 0x00000400, /* Tx - no carrier signal from the tranceiver E */
++ descTxLateCollision = 0x00000200, /* Tx - transmission aborted due to collision E */
++ descTxExcCollisions = 0x00000100, /* Tx - transmission aborted after 16 collisions E */
++ descTxVLANFrame = 0x00000080, /* Tx - VLAN-type frame */
++ descTxCollMask = 0x00000078, /* Tx - Collision count */
++ descTxCollShift = 3,
++ descTxExcDeferral = 0x00000004, /* Tx - excessive deferral E */
++ descTxUnderflow = 0x00000002, /* Tx - late data arrival from the memory E */
++ descTxDeferred = 0x00000001, /* Tx - frame transmision deferred */
++} desc_status_t;
++
++/** Descriptor length word field definitions */
++typedef enum desc_length {
++ descTxIntEnable = 0x80000000, /* Tx - interrupt on completion */
++ descTxLast = 0x40000000, /* Tx - Last segment of the frame */
++ descTxFirst = 0x20000000, /* Tx - First segment of the frame */
++ descTxDisableCrc = 0x04000000, /* Tx - Add CRC disabled (first segment only) */
++
++ descEndOfRing = 0x02000000, /* End of descriptors ring */
++ descChain = 0x01000000, /* Second buffer address is chain address */
++ descTxDisablePadd = 0x00800000, /* disable padding, added by - reyaz */
++
++ descSize2Mask = 0x003FF800, /* Buffer 2 size */
++ descSize2Shift = 11,
++ descSize1Mask = 0x000007FF, /* Buffer 1 size */
++ descSize1Shift = 0,
++} desc_length_t;
++
++typedef enum rx_desc_status {
++ RX_DESC_STATUS_OWN_BIT = 31,
++ RX_DESC_STATUS_AFM_BIT = 30,
++ RX_DESC_STATUS_FL_BIT = 16,
++ RX_DESC_STATUS_ES_BIT = 15,
++ RX_DESC_STATUS_DE_BIT = 14,
++ RX_DESC_STATUS_SAF_BIT = 13,
++ RX_DESC_STATUS_LE_BIT = 12,
++ RX_DESC_STATUS_OE_BIT = 11,
++ RX_DESC_STATUS_IPC_BIT = 10,
++ RX_DESC_STATUS_FS_BIT = 9,
++ RX_DESC_STATUS_LS_BIT = 8,
++ RX_DESC_STATUS_VLAN_BIT = 7,
++ RX_DESC_STATUS_LC_BIT = 6,
++ RX_DESC_STATUS_FT_BIT = 5,
++ RX_DESC_STATUS_RWT_BIT = 4,
++ RX_DESC_STATUS_RE_BIT = 3,
++ RX_DESC_STATUS_DRE_BIT = 2,
++ RX_DESC_STATUS_CE_BIT = 1,
++ RX_DESC_STATUS_MAC_BIT = 0
++} rx_desc_status_t;
++
++#define RX_DESC_STATUS_FL_NUM_BITS 14
++
++typedef enum rx_desc_length {
++ RX_DESC_LENGTH_DIC_BIT = 31,
++ RX_DESC_LENGTH_RER_BIT = 25,
++ RX_DESC_LENGTH_RCH_BIT = 24,
++ RX_DESC_LENGTH_RBS2_BIT = 11,
++ RX_DESC_LENGTH_RBS1_BIT = 0,
++} rx_desc_length_t;
++
++#define RX_DESC_LENGTH_RBS2_NUM_BITS 11
++#define RX_DESC_LENGTH_RBS1_NUM_BITS 11
++
++typedef enum tx_desc_status {
++ TX_DESC_STATUS_OWN_BIT = 31,
++ TX_DESC_STATUS_ES_BIT = 15,
++ TX_DESC_STATUS_JT_BIT = 14,
++ TX_DESC_STATUS_FF_BIT = 13,
++ TX_DESC_STATUS_LOC_BIT = 11,
++ TX_DESC_STATUS_NC_BIT = 10,
++ TX_DESC_STATUS_LC_BIT = 9,
++ TX_DESC_STATUS_EC_BIT = 8,
++ TX_DESC_STATUS_VF_BIT = 7,
++ TX_DESC_STATUS_CC_BIT = 3,
++ TX_DESC_STATUS_ED_BIT = 2,
++ TX_DESC_STATUS_UF_BIT = 1,
++ TX_DESC_STATUS_DB_BIT = 0
++} tx_desc_status_t;
++
++#define TX_DESC_STATUS_CC_NUM_BITS 4
++
++typedef enum tx_desc_length {
++ TX_DESC_LENGTH_IC_BIT = 31,
++ TX_DESC_LENGTH_LS_BIT = 30,
++ TX_DESC_LENGTH_FS_BIT = 29,
++ TX_DESC_LENGTH_DC_BIT = 26,
++ TX_DESC_LENGTH_TER_BIT = 25,
++ TX_DESC_LENGTH_TCH_BIT = 24,
++ TX_DESC_LENGTH_DP_BIT = 23,
++ TX_DESC_LENGTH_TBS2_BIT = 11,
++ TX_DESC_LENGTH_TBS1_BIT = 0
++} tx_desc_length_t;
++
++#define TX_DESC_LENGTH_TBS2_NUM_BITS 11
++#define TX_DESC_LENGTH_TBS1_NUM_BITS 11
++
++/** Return the number of descriptors available for the CPU to fill with new
++ * packet info */
++static inline int available_for_write(gmac_desc_list_info_t* desc_list)
++{
++ return desc_list->empty_count;
++}
++
++/** Return non-zero if there is a descriptor available with a packet with which
++ * the GMAC DMA has finished */
++static inline int tx_available_for_read(gmac_desc_list_info_t* desc_list)
++{
++ return desc_list->full_count &&
++ !((desc_list->base_ptr + desc_list->r_index)->status & (1UL << TX_DESC_STATUS_OWN_BIT));
++}
++
++/** Return non-zero if there is a descriptor available with a packet with which
++ * the GMAC DMA has finished */
++static inline int rx_available_for_read(gmac_desc_list_info_t* desc_list)
++{
++ return desc_list->full_count &&
++ !((desc_list->base_ptr + desc_list->r_index)->status & (1UL << RX_DESC_STATUS_OWN_BIT));
++}
++
++/**
++ * @param A u32 containing the status from a received frame's DMA descriptor
++ * @return An int which is non-zero if a valid received frame is fully contained
++ * within the descriptor from whence the status came
++ */
++static inline int is_rx_valid(u32 status)
++{
++ return !(status & descError) &&
++ (status & descRxFirst) &&
++ (status & descRxLast);
++}
++
++static inline int is_rx_dribbling(u32 status)
++{
++ return status & descRxDribbling;
++}
++
++static inline u32 get_rx_length(u32 status)
++{
++ return (status & descFrameLengthMask) >> descFrameLengthShift;
++}
++
++static inline int is_rx_collision_error(u32 status)
++{
++ return status & (descRxDamaged | descRxCollision);
++}
++
++static inline int is_rx_crc_error(u32 status)
++{
++ return status & descRxCrc;
++}
++
++static inline int is_rx_frame_error(u32 status)
++{
++ return status & descRxDribbling;
++}
++
++static inline int is_rx_length_error(u32 status)
++{
++ return status & descRxLengthError;
++}
++
++static inline int is_rx_long_frame(u32 status)
++{
++ return status & descRxLongFrame;
++}
++
++static inline int is_tx_valid(u32 status)
++{
++ return !(status & descError);
++}
++
++static inline int is_tx_collision_error(u32 status)
++{
++ return (status & descTxCollMask) >> descTxCollShift;
++}
++
++static inline int is_tx_aborted(u32 status)
++{
++ return status & (descTxLateCollision | descTxExcCollisions);
++}
++
++static inline int is_tx_carrier_error(u32 status)
++{
++ return status & (descTxLostCarrier | descTxNoCarrier);
++}
++
++/**
++ * GMAC private metadata
++ */
++static gmac_priv_t priv_data;
++static gmac_priv_t* priv = &priv_data;
++
++/**
++ * Descriptor list management
++ */
++
++static void init_rx_descriptor(
++ gmac_dma_desc_t* desc,
++ int end_of_ring,
++ int disable_ioc)
++{
++ desc->status = 0;
++ desc->length = 0;
++ if (disable_ioc) {
++ desc->length |= (1UL << RX_DESC_LENGTH_DIC_BIT);
++ }
++ if (end_of_ring) {
++ desc->length |= (1UL << RX_DESC_LENGTH_RER_BIT);
++ }
++ desc->buffer1 = 0;
++ desc->buffer2 = 0;
++ desc->skb = 0;
++}
++
++static void init_tx_descriptor(
++ gmac_dma_desc_t* desc,
++ int end_of_ring,
++ int enable_ioc,
++ int disable_crc,
++ int disable_padding)
++{
++ desc->status = 0;
++ desc->length = 0;
++ if (enable_ioc) {
++ desc->length |= (1UL << TX_DESC_LENGTH_IC_BIT);
++ }
++ if (disable_crc) {
++ desc->length |= (1UL << TX_DESC_LENGTH_DC_BIT);
++ }
++ if (disable_padding) {
++ desc->length |= (1UL << TX_DESC_LENGTH_DP_BIT);
++ }
++ if (end_of_ring) {
++ desc->length |= (1UL << TX_DESC_LENGTH_TER_BIT);
++ }
++ desc->buffer1 = 0;
++ desc->buffer2 = 0;
++ desc->skb = 0;
++}
++
++static void init_rx_desc_list(
++ gmac_desc_list_info_t* desc_list,
++ gmac_dma_desc_t* base_ptr,
++ int num_descriptors)
++{
++ int i;
++
++ desc_list->base_ptr = base_ptr;
++ desc_list->num_descriptors = num_descriptors;
++ desc_list->empty_count = num_descriptors;
++ desc_list->full_count = 0;
++ desc_list->r_index = 0;
++ desc_list->w_index = 0;
++
++ for (i=0; i < (num_descriptors - 1); i++) {
++ init_rx_descriptor(base_ptr + i, 0, 0);
++ }
++ init_rx_descriptor(base_ptr + i, 1, 0);
++}
++
++static void init_tx_desc_list(
++ gmac_desc_list_info_t* desc_list,
++ gmac_dma_desc_t* base_ptr,
++ int num_descriptors)
++{
++ int i;
++
++ desc_list->base_ptr = base_ptr;
++ desc_list->num_descriptors = num_descriptors;
++ desc_list->empty_count = num_descriptors;
++ desc_list->full_count = 0;
++ desc_list->r_index = 0;
++ desc_list->w_index = 0;
++
++ for (i=0; i < (num_descriptors - 1); i++) {
++ init_tx_descriptor(base_ptr + i, 0, 1, 0, 0);
++ }
++ init_tx_descriptor(base_ptr + i, 1, 1, 0, 0);
++}
++
++static void rx_take_ownership(gmac_desc_list_info_t* desc_list)
++{
++ int i;
++ for (i=0; i < desc_list->num_descriptors; i++) {
++ (desc_list->base_ptr + i)->status &= ~(1UL << RX_DESC_STATUS_OWN_BIT);
++ }
++}
++
++static void tx_take_ownership(gmac_desc_list_info_t* desc_list)
++{
++ int i;
++ for (i=0; i < desc_list->num_descriptors; i++) {
++ (desc_list->base_ptr + i)->status &= ~(1UL << TX_DESC_STATUS_OWN_BIT);
++ }
++}
++
++static int set_tx_descriptor(
++ gmac_priv_t* priv,
++ dma_addr_t dma_address,
++ u32 length,
++ sk_buff_t* skb)
++{
++ int index;
++ gmac_dma_desc_t* tx;
++
++ // Are sufficicent descriptors available for writing by the CPU?
++ if (!available_for_write(&priv->tx_gmac_desc_list_info)) {
++ return -1;
++ }
++
++ // Get the index of the next TX descriptor available for writing by the CPU
++ index = priv->tx_gmac_desc_list_info.w_index;
++
++ // Get a pointer to the next TX descriptor available for writing by the CPU
++ tx = priv->tx_gmac_desc_list_info.base_ptr + index;
++
++ // Initialise the TX descriptor length field for the passed single buffer,
++ // without destroying any fields we wish to be persistent
++
++ // No chained second buffer
++ tx->length &= ~(1UL << TX_DESC_LENGTH_TCH_BIT);
++ // Single descriptor holds entire packet
++ tx->length |= ((1UL << TX_DESC_LENGTH_LS_BIT) | (1UL << TX_DESC_LENGTH_FS_BIT));
++ // Zero the second buffer length field
++ tx->length &= ~(((1UL << TX_DESC_LENGTH_TBS2_NUM_BITS) - 1) << TX_DESC_LENGTH_TBS2_BIT);
++ // Zero the first buffer length field
++ tx->length &= ~(((1UL << TX_DESC_LENGTH_TBS1_NUM_BITS) - 1) << TX_DESC_LENGTH_TBS1_BIT);
++ // Fill in the first buffer length
++ tx->length |= (length << TX_DESC_LENGTH_TBS1_BIT);
++
++ // Initialise the first buffer pointer to the single passed buffer
++ tx->buffer1 = dma_address;
++
++ // Remember the socket buffer associated with the single passed buffer
++ tx->skb = (u32)skb;
++
++ // Update the index of the next descriptor available for writing by the CPU
++ priv->tx_gmac_desc_list_info.w_index = (tx->length & (1UL << TX_DESC_LENGTH_TER_BIT)) ? 0 : index + 1;
++
++ // make sure all memory updates are complete before releasing the GMAC on the data.
++ wmb();
++
++ // Hand TX descriptor to the GMAC DMA by setting the status bit.
++ tx->status = (1UL << TX_DESC_STATUS_OWN_BIT);
++
++ // Account for the number of descriptors used to hold the new packet
++ --priv->tx_gmac_desc_list_info.empty_count;
++ ++priv->tx_gmac_desc_list_info.full_count;
++
++ return index;
++}
++
++static int get_tx_descriptor(
++ gmac_priv_t* priv,
++ u32* status,
++ dma_addr_t* dma_address,
++ u32* length,
++ sk_buff_t** skb)
++{
++ int index;
++ gmac_dma_desc_t *tx;
++
++ // Is there at least one descriptor with which the GMAC DMA has finished?
++ if (!tx_available_for_read(&priv->tx_gmac_desc_list_info)) {
++ return -1;
++ }
++
++ // Get the index of the descriptor released the longest time ago by the
++ // GMAC DMA
++ index = priv->tx_gmac_desc_list_info.r_index;
++
++ // Get a pointer to the descriptor released the longest time ago by the
++ // GMAC DMA
++ tx = priv->tx_gmac_desc_list_info.base_ptr + index;
++
++ // Extract the status field
++ if (status) {
++ *status = tx->status;
++ }
++
++ // Extract the length field - only cope with the first buffer associated
++ // with the descriptor
++ if (length) {
++ *length = (tx->length >> TX_DESC_LENGTH_TBS1_BIT) &
++ ((1UL << TX_DESC_LENGTH_TBS1_NUM_BITS) - 1);
++ }
++
++ // Extract the pointer to the buffer containing the packet - only cope with
++ // the first buffer associated with the descriptor
++ if (dma_address) {
++ *dma_address = tx->buffer1;
++ }
++
++ // Extract the pointer to the socket buffer associated with the packet
++ if (skb) {
++ *skb = (sk_buff_t*)(tx->skb);
++ }
++
++ // Update the index of the next descriptor with which the GMAC DMA may have
++ // finished
++ priv->tx_gmac_desc_list_info.r_index = (tx->length & (1UL << TX_DESC_LENGTH_TER_BIT)) ? 0 : index + 1;
++
++ // Account for the number of descriptors freed to hold new packets
++ ++priv->tx_gmac_desc_list_info.empty_count;
++ --priv->tx_gmac_desc_list_info.full_count;
++
++ return index;
++}
++
++int set_rx_descriptor(
++ gmac_priv_t* priv,
++ dma_addr_t dma_address,
++ u32 length,
++ sk_buff_t* skb)
++{
++ int index;
++ gmac_dma_desc_t* rx;
++ int num_descriptors_required;
++
++ // Currently only support using a single descriptor to describe each packet
++ // queued with the GMAc DMA
++ num_descriptors_required = 1;
++
++ // Are sufficicent descriptors available for writing by the CPU?
++ if (available_for_write(&priv->rx_gmac_desc_list_info) < num_descriptors_required) {
++ index = -1;
++ } else {
++ // Get the index of the next RX descriptor available for writing by the CPU
++ index = priv->rx_gmac_desc_list_info.w_index;
++
++ // Get a pointer to the next RX descriptor available for writing by the CPU
++ rx = priv->rx_gmac_desc_list_info.base_ptr + index;
++
++ // Initialise the RX descriptor length field for the passed single buffer,
++ // without destroying any fields we wish to be persistent
++
++ // No chained second buffer
++ rx->length &= ~(1UL << RX_DESC_LENGTH_RCH_BIT);
++ // Zero the second buffer length field
++ rx->length &= ~(((1UL << RX_DESC_LENGTH_RBS2_NUM_BITS) - 1) << RX_DESC_LENGTH_RBS2_BIT);
++ // Zero the first buffer length field
++ rx->length &= ~(((1UL << RX_DESC_LENGTH_RBS1_NUM_BITS) - 1) << RX_DESC_LENGTH_RBS1_BIT);
++ // Fill in the first buffer length
++ rx->length |= (length << RX_DESC_LENGTH_RBS1_BIT);
++
++ // Initialise the first buffer pointer to the single passed buffer
++ rx->buffer1 = dma_address;
++
++ // Remember the socket buffer associated with the single passed buffer
++ rx->skb = (u32)skb;
++
++ wmb();
++
++ // Initialise RX descriptor status to be owned by the GMAC DMA
++ rx->status = (1UL << RX_DESC_STATUS_OWN_BIT);
++
++ // Update the index of the next descriptor available for writing by the CPU
++ priv->rx_gmac_desc_list_info.w_index = (rx->length & (1UL << RX_DESC_LENGTH_RER_BIT)) ? 0 : index + 1;
++
++ // Account for the number of descriptors used to hold the new packet
++ priv->rx_gmac_desc_list_info.empty_count -= num_descriptors_required;
++ priv->rx_gmac_desc_list_info.full_count += num_descriptors_required;
++ }
++
++ return index;
++}
++
++int get_rx_descriptor(
++ gmac_priv_t* priv,
++ u32* status,
++ dma_addr_t* dma_address,
++ u32* length,
++ sk_buff_t** skb)
++{
++ int index;
++ gmac_dma_desc_t *rx;
++ int num_descriptors_required;
++
++ // Is there at least one descriptor with which the GMAC DMA has finished?
++ if (!rx_available_for_read(&priv->rx_gmac_desc_list_info)) {
++ return -1;
++ }
++
++ // Currently can only cope with packets entirely contained within a single
++ // descriptor
++ num_descriptors_required = 1;
++
++ // Get the index of the descriptor released the longest time ago by the
++ // GMAC DMA
++ index = priv->rx_gmac_desc_list_info.r_index;
++
++ // Get a pointer to the descriptor released the longest time ago by the
++ // GMAC DMA
++ rx = priv->rx_gmac_desc_list_info.base_ptr + index;
++
++ // Extract the status field
++ if (status) {
++ *status = rx->status;
++ }
++
++ // Extract the length field - only cope with the first buffer associated
++ // with the descriptor
++ if (length) {
++ *length = (rx->length >> RX_DESC_LENGTH_RBS1_BIT) &
++ ((1UL << RX_DESC_LENGTH_RBS1_NUM_BITS) - 1);
++ }
++
++ // Extract the pointer to the buffer containing the packet - only cope with
++ // the first buffer associated with the descriptor
++ if (dma_address) {
++ *dma_address = rx->buffer1;
++ }
++
++ // Extract the pointer to the socket buffer associated with the packet
++ if (skb) {
++ *skb = (sk_buff_t*)(rx->skb);
++ }
++
++ wmb();
++ // Update the index of the next descriptor with which the GMAC DMA may have
++ // finished
++ priv->rx_gmac_desc_list_info.r_index = (rx->length & (1UL << RX_DESC_LENGTH_RER_BIT)) ? 0 : index + 1;
++
++ // Account for the number of descriptors freed to hold new packets
++ priv->rx_gmac_desc_list_info.empty_count += num_descriptors_required;
++ priv->rx_gmac_desc_list_info.full_count -= num_descriptors_required;
++
++ return index;
++}
++
++/**
++ * GMAC register access functions
++ */
++
++/**
++ * MAC register access functions
++ */
++
++/**
++ * @param priv A gmac_priv_t* pointing to private device data
++ * @param reg_num An int specifying the index of the MAC register to access
++ */
++static inline u32 mac_reg_read(gmac_priv_t* priv, int reg_num)
++{
++ return *(volatile u32*)(priv->macBase + (reg_num << 2));
++}
++
++/**
++ * @param priv A gmac_priv_t* pointing to private device data
++ * @param reg_num An int specifying the index of the MAC register to access
++ */
++static inline void mac_reg_write(gmac_priv_t* priv, int reg_num, u32 value)
++{
++ *(volatile u32*)(priv->macBase + (reg_num << 2)) = value;
++
++}
++
++/**
++ * @param priv A gmac_priv_t* pointing to private device data
++ * @param reg_num An int specifying the index of the MAC register to access
++ * @param bits_to_clear A u32 specifying which bits of the specified register to
++ * clear. A set bit in this parameter will cause the matching bit in the
++ * register to be cleared
++ */
++static inline void mac_reg_clear_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_clear)
++{
++ mac_reg_write(priv, reg_num, mac_reg_read(priv, reg_num) & ~bits_to_clear);
++}
++
++/**
++ * @param priv A gmac_priv_t* pointing to private device data
++ * @param reg_num An int specifying the index of the MAC register to access
++ * @param bits_to_set A u32 specifying which bits of the specified register to
++ * set. A set bit in this parameter will cause the matching bit in the register
++ * to be set
++ */
++static inline void mac_reg_set_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_set)
++{
++ mac_reg_write(priv, reg_num, mac_reg_read(priv, reg_num) | bits_to_set);
++}
++
++
++/**
++ * DMA register access functions
++ */
++
++/**
++ * @param priv A gmac_priv_t* pointing to private device data
++ * @param reg_num An int specifying the index of the DMA register to access
++ */
++static inline u32 dma_reg_read(gmac_priv_t* priv, int reg_num)
++{
++ return *(volatile u32*)(priv->dmaBase + (reg_num << 2));
++}
++
++/**
++ * @param priv A gmac_priv_t* pointing to private device data
++ * @param reg_num An int specifying the index of the DMA register to access
++ */
++static inline void dma_reg_write(gmac_priv_t* priv, int reg_num, u32 value)
++{
++ *(volatile u32*)(priv->dmaBase + (reg_num << 2)) = value;
++ wmb();
++}
++
++/**
++ * @param priv A gmac_priv_t* pointing to private device data
++ * @param reg_num An int specifying the index of the DMA register to access
++ * @param bits_to_clear A u32 specifying which bits of the specified register to
++ * clear. A set bit in this parameter will cause the matching bit in the
++ * register to be cleared
++ * @return An u32 containing the new value written to the register
++ */
++static inline u32 dma_reg_clear_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_clear)
++{
++ u32 new_value = dma_reg_read(priv, reg_num) & ~bits_to_clear;
++ dma_reg_write(priv, reg_num, new_value);
++ return new_value;
++}
++
++/**
++ * @param priv A gmac_priv_t* pointing to private device data
++ * @param reg_num An int specifying the index of the DMA register to access
++ * @param bits_to_set A u32 specifying which bits of the specified register to
++ * set. A set bit in this parameter will cause the matching bit in the register
++ * to be set
++ * @return An u32 containing the new value written to the register
++ */
++static inline u32 dma_reg_set_mask(gmac_priv_t* priv, int reg_num, u32 bits_to_set)
++{
++ u32 new_value = dma_reg_read(priv, reg_num) | bits_to_set;
++ dma_reg_write(priv, reg_num, new_value);
++ return new_value;
++}
++
++static void eth_down(void)
++{
++ // Stop transmitter, take ownership of all tx descriptors
++ dma_reg_clear_mask(priv, DMA_OP_MODE_REG, DMA_OP_MODE_ST_BIT);
++ if (priv->desc_base_addr) {
++ tx_take_ownership(&priv->tx_gmac_desc_list_info);
++ }
++
++ // Stop receiver, take ownership of all rx descriptors
++ dma_reg_clear_mask(priv, DMA_OP_MODE_REG, DMA_OP_MODE_SR_BIT);
++ if (priv->desc_base_addr) {
++ rx_take_ownership(&priv->rx_gmac_desc_list_info);
++ }
++
++ // Free descriptor resources. The TX descriptor will not have a packet
++ // buffer attached, as this is provided by the stack when transmission is
++ // required and ownership is not retained by the descriptor, as the stack
++ // waits for transmission to complete via polling
++ if (priv->desc_base_addr) {
++ // Free receive descriptors, accounting for buffer offset used to
++ // ensure IP header alignment
++ while (1) {
++ dma_addr_t dma_address;
++ if (get_rx_descriptor(priv, 0, &dma_address, 0, 0) < 0) {
++ break;
++ }
++ free((void*)(dma_address - ETHER_FRAME_ALIGN_WASTAGE));
++ }
++
++ // Free DMA descriptors' storage
++ free(priv->desc_base_addr);
++
++ // Remember that we've freed the descriptors memory
++ priv->desc_base_addr = 0;
++ }
++}
++
++/*
++ * Reads a register from the MII Management serial interface
++ */
++int phy_read(int phyaddr, int phyreg)
++{
++ int data = 0;
++ u32 addr = (phyaddr << MAC_GMII_ADR_PA_BIT) |
++ (phyreg << MAC_GMII_ADR_GR_BIT) |
++ (5 << MAC_GMII_ADR_CR_BIT) |
++ (1UL << MAC_GMII_ADR_GB_BIT);
++
++ mac_reg_write(priv, MAC_GMII_ADR_REG, addr);
++
++ for (;;) {
++ if (!(mac_reg_read(priv, MAC_GMII_ADR_REG) & (1UL << MAC_GMII_ADR_GB_BIT))) {
++ // Successfully read from PHY
++ data = mac_reg_read(priv, MAC_GMII_DATA_REG) & 0xFFFF;
++ break;
++ }
++ }
++
++#ifdef DEBUG_GMAC_INIT
++ printf("phy_read() phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", phyaddr, phyreg, data);
++#endif // DEBUG_GMAC_INIT
++
++ return data;
++}
++
++/*
++ * Writes a register to the MII Management serial interface
++ */
++void phy_write(int phyaddr, int phyreg, int phydata)
++{
++ u32 addr = (phyaddr << MAC_GMII_ADR_PA_BIT) |
++ (phyreg << MAC_GMII_ADR_GR_BIT) |
++ (5 << MAC_GMII_ADR_CR_BIT) |
++ (1UL << MAC_GMII_ADR_GW_BIT) |
++ (1UL << MAC_GMII_ADR_GB_BIT);
++
++ mac_reg_write(priv, MAC_GMII_DATA_REG, phydata);
++ mac_reg_write(priv, MAC_GMII_ADR_REG, addr);
++
++ for (;;) {
++ if (!(mac_reg_read(priv, MAC_GMII_ADR_REG) & (1UL << MAC_GMII_ADR_GB_BIT))) {
++ break;
++ }
++ }
++
++#ifdef DEBUG_GMAC_INIT
++ printf("phy_write() phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", phyaddr, phyreg, phydata);
++#endif // DEBUG_GMAC_INIT
++}
++
++/*
++ * Finds and reports the PHY address
++ */
++int phy_detect(void)
++{
++ int found = 0;
++ int phyaddr;
++
++ // Scan all 32 PHY addresses if necessary
++ priv->phy_type = 0;
++ for (phyaddr = 1; phyaddr < 33; ++phyaddr) {
++ unsigned int id1, id2;
++
++ // Read the PHY identifiers
++ id1 = phy_read(phyaddr & 31, MII_PHYSID1);
++ id2 = phy_read(phyaddr & 31, MII_PHYSID2);
++
++#ifdef DEBUG_GMAC_INIT
++ printf("phy_detect() PHY adr = %u -> phy_id1=0x%x, phy_id2=0x%x\n", phyaddr, id1, id2);
++#endif // DEBUG_GMAC_INIT
++
++ // Make sure it is a valid identifier
++ if (id1 != 0x0000 && id1 != 0xffff && id1 != 0x8000 &&
++ id2 != 0x0000 && id2 != 0xffff && id2 != 0x8000) {
++#ifdef DEBUG_GMAC_INIT
++ printf("phy_detect() Found PHY at address = %u\n", phyaddr);
++#endif // DEBUG_GMAC_INIT
++
++ priv->phy_id = phyaddr & 31;
++ priv->phy_type = id1 << 16 | id2;
++ priv->phy_addr = phyaddr;
++
++ found = 1;
++ break;
++ }
++ }
++
++ return found;
++}
++
++void start_phy_reset(void)
++{
++ // Ask the PHY to reset
++ phy_write(priv->phy_addr, MII_BMCR, BMCR_RESET);
++}
++
++int is_phy_reset_complete(void)
++{
++ int complete = 0;
++ int bmcr;
++
++ // Read back the status until it indicates reset, or we timeout
++ bmcr = phy_read(priv->phy_addr, MII_BMCR);
++ if (!(bmcr & BMCR_RESET)) {
++ complete = 1;
++ }
++
++ return complete;
++}
++
++void set_phy_type_rgmii(void)
++{
++ // Use sysctrl to switch MAC link lines into either (G)MII or RGMII mode
++ *(volatile u32*)SYS_CTRL_GMAC_CTRL |= (1UL << SYS_CTRL_GMAC_RGMII);
++}
++
++void phy_initialise(void)
++{
++ switch (priv->phy_type) {
++ case PHY_TYPE_VITESSE_VSC8201XVZ:
++ {
++ // Allow s/w to override mode/duplex pin settings
++ u32 acsr = phy_read(priv->phy_id, VSC8201_MII_ACSR);
++
++ printf("PHY is Vitesse VSC8201XVZ\n");
++ acsr |= (1UL << VSC8201_MII_ACSR_MDPPS_BIT);
++ phy_write(priv->phy_id, VSC8201_MII_ACSR, acsr);
++ }
++ break;
++ case PHY_TYPE_REALTEK_RTL8211BGR:
++ printf("PHY is Realtek RTL8211BGR\n");
++ set_phy_type_rgmii();
++ break;
++ case PHY_TYPE_LSI_ET1011C:
++ {
++ u32 phy_reg;
++
++ printf("PHY is LSI ET1011C\n");
++
++ // Configure clocks
++ phy_reg = phy_read(priv->phy_id, ET1011C_MII_CONFIG);
++ phy_reg &= ~(((1UL << ET1011C_MII_CONFIG_IFMODESEL_NUM_BITS) - 1) << ET1011C_MII_CONFIG_IFMODESEL);
++ phy_reg |= (ET1011C_MII_CONFIG_IFMODESEL_GMII_MII << ET1011C_MII_CONFIG_IFMODESEL);
++ phy_reg |= ((1UL << ET1011C_MII_CONFIG_SYSCLKEN) |
++ (1UL << ET1011C_MII_CONFIG_TXCLKEN) |
++ (1UL << ET1011C_MII_CONFIG_TBI_RATESEL) |
++ (1UL << ET1011C_MII_CONFIG_CRS_TX_EN));
++ phy_write(priv->phy_id, ET1011C_MII_CONFIG, phy_reg);
++
++ // Enable Tx/Rx LED
++ phy_reg = phy_read(priv->phy_id, ET1011C_MII_LED2);
++ phy_reg &= ~(((1UL << ET1011C_MII_LED2_LED_NUM_BITS) - 1) << ET1011C_MII_LED2_LED_TXRX);
++ phy_reg |= (ET1011C_MII_LED2_LED_TXRX_ACTIVITY << ET1011C_MII_LED2_LED_TXRX);
++ phy_write(priv->phy_id, ET1011C_MII_LED2, phy_reg);
++ }
++ break;
++ }
++}
++
++int detect_link_speed(void)
++{
++ u32 lpa2 = phy_read(priv->phy_id, MII_STAT1000);
++
++ if (((lpa2 & LPA_1000FULL)) ||
++ ((lpa2 & LPA_1000HALF))) {
++ priv->link_is_1000M = 1;
++ } else {
++ priv->link_is_1000M = 0;
++ }
++
++ return 0;
++}
++
++int is_autoneg_complete(void)
++{
++ return phy_read(priv->phy_addr, MII_BMSR) & BMSR_ANEGCOMPLETE;
++}
++
++int is_link_ok(void)
++{
++ return phy_read(priv->phy_id, MII_BMSR) & BMSR_LSTATUS;
++}
++
++int eth_init(bd_t *bd)
++{
++ u32 version;
++ u32 reg_contents;
++ u8 *mac_addr;
++ int desc;
++
++ // Set hardware device base addresses
++ priv->macBase = (MAC_BASE_PA + MAC_BASE_OFFSET);
++ priv->dmaBase = (MAC_BASE_PA + DMA_BASE_OFFSET);
++
++#ifdef DEBUG_GMAC_INIT
++ printf("eth_init(): About to reset MAC core\n");
++#endif // DEBUG_GMAC_INIT
++ // Ensure the MAC block is properly reset
++ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_MAC_BIT);
++ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_MAC_BIT);
++
++ // Enable the clock to the MAC block
++ *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_MAC_BIT);
++
++ version = mac_reg_read(priv, MAC_VERSION_REG);
++#ifdef DEBUG_GMAC_INIT
++ printf("eth_init(): GMAC Synopsis version = 0x%x, vendor version = 0x%x\n", version & 0xff, (version >> 8) & 0xff);
++#endif // DEBUG_GMAC_INIT
++
++ // Use simple mux for 25/125 Mhz clock switching
++ *(volatile u32*)SYS_CTRL_GMAC_CTRL |= (1UL << SYS_CTRL_GMAC_SIMPLE_MAX);
++
++ // Enable GMII_GTXCLK to follow GMII_REFCLK - required for gigabit PHY
++ *(volatile u32*)SYS_CTRL_GMAC_CTRL |= (1UL << SYS_CTRL_GMAC_CKEN_GTX);
++
++ // Disable all GMAC interrupts
++ dma_reg_write(priv, DMA_INT_ENABLE_REG, 0);
++
++ // Reset the entire GMAC
++ dma_reg_write(priv, DMA_BUS_MODE_REG, 1UL << DMA_BUS_MODE_SWR_BIT);
++
++ // Wait for the reset operation to complete
++ printf("Wait GMAC to reset");
++ while (dma_reg_read(priv, DMA_BUS_MODE_REG) & (1UL << DMA_BUS_MODE_SWR_BIT)) {
++ udelay(250000);
++ printf(".");
++ }
++ printf("\n");
++
++ // Attempt to discover link speed from the PHY
++ if (!phy_detect()) {
++ printf("No PHY found\n");
++ } else {
++ // Ensure the PHY is in a sensible state by resetting it
++ start_phy_reset();
++
++ // Read back the status until it indicates reset, or we timeout
++ printf("Wait for PHY reset");
++ while (!is_phy_reset_complete()) {
++ udelay(250000);
++ printf(".");
++ }
++ printf("\n");
++
++ // Setup the PHY based on its type
++ phy_initialise();
++
++ printf("Wait for link to come up");
++ while (!is_link_ok()) {
++ udelay(250000);
++ printf(".");
++ }
++ printf("Link up\n");
++
++ // Wait for PHY to have completed autonegotiation
++ printf("Wait for auto-negotiation to complete");
++ while (!is_autoneg_complete()) {
++ udelay(250000);
++ printf(".");
++ }
++ printf("\n");
++
++ // Interrogate the PHY for the link speed
++ if (detect_link_speed()) {
++ printf("Failed to detect link speed\n");
++ } else {
++ printf("Link is %s\n", priv->link_is_1000M ? "1000M" : "10M/100M");
++ }
++ }
++
++ // Form the MAC config register contents
++ reg_contents = 0;
++ if (!priv->link_is_1000M) {
++ reg_contents |= (1UL << MAC_CONFIG_PS_BIT); // Gigabit
++ }
++ reg_contents |= (1UL << MAC_CONFIG_DM_BIT); // Full duplex
++ reg_contents |= ((1UL << MAC_CONFIG_TE_BIT) |
++ (1UL << MAC_CONFIG_RE_BIT));
++ mac_reg_write(priv, MAC_CONFIG_REG, reg_contents);
++
++ // Form the MAC frame filter register contents
++ reg_contents = 0;
++ mac_reg_write(priv, MAC_FRAME_FILTER_REG, reg_contents);
++
++ // Form the hash table registers contents
++ mac_reg_write(priv, MAC_HASH_HIGH_REG, 0);
++ mac_reg_write(priv, MAC_HASH_LOW_REG, 0);
++
++ // Form the MAC flow control register contents
++ reg_contents = 0;
++ reg_contents |= ((1UL << MAC_FLOW_CNTL_RFE_BIT) |
++ (1UL << MAC_FLOW_CNTL_TFE_BIT));
++ mac_reg_write(priv, MAC_FLOW_CNTL_REG, reg_contents);
++
++ // Form the MAC VLAN tag register contents
++ reg_contents = 0;
++ mac_reg_write(priv, MAC_VLAN_TAG_REG, reg_contents);
++
++ // Form the MAC addr0 high and low registers contents from the character
++ // string representation from the environment
++ mac_addr = getenv("ethaddr");
++#ifdef DEBUG_GMAC_INIT
++ printf("eth_init(): Mac addr = %s\n", mac_addr);
++#endif // DEBUG_GMAC_INIT
++ reg_contents = simple_strtoul(mac_addr+0, 0, 16);
++ reg_contents |= (simple_strtoul(mac_addr+3, 0, 16) << 8);
++ reg_contents |= (simple_strtoul(mac_addr+6, 0, 16) << 16);
++ reg_contents |= (simple_strtoul(mac_addr+9, 0, 16) << 24);
++ mac_reg_write(priv, MAC_ADR0_LOW_REG, reg_contents);
++ reg_contents = simple_strtoul(mac_addr+12, 0, 16);
++ reg_contents |= (simple_strtoul(mac_addr+15, 0, 16) << 8);
++ mac_reg_write(priv, MAC_ADR0_HIGH_REG, reg_contents);
++
++ // Disable all MMC interrupt sources
++ mac_reg_write(priv, MMC_RX_MASK_REG, ~0UL);
++ mac_reg_write(priv, MMC_TX_MASK_REG, ~0UL);
++
++ // Remember how large the unified descriptor array is to be
++ priv->total_num_descriptors = NUM_RX_DMA_DESCRIPTORS + NUM_TX_DMA_DESCRIPTORS;
++
++ // Need a consistent DMA mapping covering all the memory occupied by DMA
++ // unified descriptor array, as both CPU and DMA engine will be reading and
++ // writing descriptor fields.
++ priv->desc_base_addr = (gmac_dma_desc_t*)malloc(sizeof(gmac_dma_desc_t) * priv->total_num_descriptors);
++ if (!priv->desc_base_addr) {
++ printf("eth_init(): Failed to allocate memory for DMA descriptors\n");
++ goto err_out;
++ }
++
++ // Initialise the structures managing the TX descriptor list
++ init_tx_desc_list(&priv->tx_gmac_desc_list_info,
++ priv->desc_base_addr,
++ NUM_TX_DMA_DESCRIPTORS);
++
++ // Initialise the structures managing the RX descriptor list
++ init_rx_desc_list(&priv->rx_gmac_desc_list_info,
++ priv->desc_base_addr + NUM_TX_DMA_DESCRIPTORS,
++ priv->total_num_descriptors - NUM_TX_DMA_DESCRIPTORS);
++
++ // Prepare receive descriptors
++ desc = 0;
++ while (available_for_write(&priv->rx_gmac_desc_list_info)) {
++ // Allocate a new buffer for the descriptor which is large enough for
++ // any packet received from the link
++ dma_addr_t dma_address = (dma_addr_t)malloc(ETHER_MTU + ETHER_FRAME_ALIGN_WASTAGE + EXTRA_RX_SKB_SPACE);
++ if (!dma_address) {
++ printf("eth_init(): No memory for socket buffer\n");
++ break;
++ }
++
++ desc = set_rx_descriptor(priv,
++ dma_address + ETHER_FRAME_ALIGN_WASTAGE,
++ ETHER_MTU + EXTRA_RX_SKB_SPACE,
++ 0);
++
++ if (desc < 0) {
++ // Release the buffer
++ free((void*)dma_address);
++
++ printf("eth_init(): Error, no RX descriptor available\n");
++ goto err_out;
++ }
++ }
++
++ // Initialise the GMAC DMA bus mode register
++ dma_reg_write(priv, DMA_BUS_MODE_REG, ((0UL << DMA_BUS_MODE_FB_BIT) |
++ (0UL << DMA_BUS_MODE_PR_BIT) |
++ (32UL << DMA_BUS_MODE_PBL_BIT) | // AHB burst size
++ (1UL << DMA_BUS_MODE_DSL_BIT) |
++ (0UL << DMA_BUS_MODE_DA_BIT)));
++
++ // Write the address of the start of the tx descriptor array
++ dma_reg_write(priv, DMA_TX_DESC_ADR_REG, (u32)priv->desc_base_addr);
++
++ // Write the address of the start of the rx descriptor array
++ dma_reg_write(priv, DMA_RX_DESC_ADR_REG,
++ (u32)(priv->desc_base_addr + priv->tx_gmac_desc_list_info.num_descriptors));
++
++ // Clear any pending interrupt requests
++ dma_reg_write(priv, DMA_STATUS_REG, dma_reg_read(priv, DMA_STATUS_REG));
++
++ // Initialise the GMAC DMA operation mode register, starting both the
++ // transmitter and receiver
++ dma_reg_write(priv, DMA_OP_MODE_REG, ((1UL << DMA_OP_MODE_SF_BIT) | // Store and forward
++ (0UL << DMA_OP_MODE_TTC_BIT) | // Tx threshold
++ (1UL << DMA_OP_MODE_ST_BIT) | // Enable transmitter
++ (0UL << DMA_OP_MODE_RTC_BIT) | // Rx threshold
++ (1UL << DMA_OP_MODE_SR_BIT))); // Enable receiver
++
++ // Success
++ return 1;
++
++err_out:
++ eth_down();
++
++ return 0;
++}
++
++void eth_halt(void)
++{
++ eth_down();
++
++ // Disable the clock to the MAC block
++ *(volatile u32*)(SYS_CTRL_CKEN_CLR_CTRL) = (1UL << SYS_CTRL_CKEN_MAC_BIT);
++}
++
++int eth_rx(void)
++{
++ static const int MAX_LOOPS = 2000; // 2 seconds
++
++ int length = 0;
++ dma_addr_t dma_address;
++ u32 desc_status;
++ int loops = 0;
++
++ // Look for the first available received packet
++ while (loops++ < MAX_LOOPS) {
++ if (get_rx_descriptor(priv, &desc_status, &dma_address, 0, 0) >= 0) {
++ if (is_rx_valid(desc_status)) {
++ // Get the length of the packet within the buffer
++ length = get_rx_length(desc_status);
++
++ // Pass packet up the network stack - will block until processing is
++ // completed
++ NetReceive((uchar*)dma_address, length);
++ } else {
++ printf("eth_rx() Received packet has bad desc_status = 0x%08x\n", desc_status);
++ }
++
++ // Re-initialise the RX descriptor with its buffer - relies on always
++ // setting an RX descriptor directly after getting it
++ if (set_rx_descriptor(priv, dma_address, ETHER_MTU + EXTRA_RX_SKB_SPACE, 0) < 0) {
++ printf("eth_rx(): Failed to set RX descriptor\n");
++ }
++
++ break;
++ }
++
++ // Wait a bit before trying again to get a descriptor
++ udelay(1000); // 1mS
++ }
++
++ return length;
++}
++
++int eth_send(volatile void *packet, int length)
++{
++ // Transmit the new packet
++ while (1) {
++ // Get the TX descriptor
++ if (set_tx_descriptor(priv, (dma_addr_t)packet, length, 0) >= 0) {
++ // Tell the GMAC to poll for the updated descriptor
++ dma_reg_write(priv, DMA_TX_POLL_REG, 0);
++ break;
++ }
++
++ // Wait a bit before trying again to get a descriptor
++ udelay(1000); // 1mS
++ }
++
++ // Wait for the packet buffer to be finished with
++ while (get_tx_descriptor(priv, 0, 0, 0, 0) < 0) {
++ // Wait a bit before examining the descriptor again
++ udelay(1000); // 1mS
++ }
++
++ return length;
++}
++
+diff -Nurd u-boot-1.1.2/board/oxnas/ide-810.c u-boot-1.1.2-oxe810/board/oxnas/ide-810.c
+--- u-boot-1.1.2/board/oxnas/ide-810.c 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-1.1.2-oxe810/board/oxnas/ide-810.c 2008-06-11 17:55:18.000000000 +0200
+@@ -0,0 +1,892 @@
++/*
++ * (C) Copyright 2005
++ * Oxford Semiconductor Ltd
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * 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 <common.h>
++
++#define SATA_DMA_CHANNEL 0
++
++#define DMA_CTRL_STATUS (0x0)
++#define DMA_BASE_SRC_ADR (0x4)
++#define DMA_BASE_DST_ADR (0x8)
++#define DMA_BYTE_CNT (0xC)
++#define DMA_CURRENT_SRC_ADR (0x10)
++#define DMA_CURRENT_DST_ADR (0x14)
++#define DMA_CURRENT_BYTE_CNT (0x18)
++#define DMA_INTR_ID (0x1C)
++#define DMA_INTR_CLEAR_REG (DMA_CURRENT_SRC_ADR)
++
++#define DMA_CALC_REG_ADR(channel, register) ((volatile u32*)(DMA_BASE_PA + ((channel) << 5) + (register)))
++
++#define DMA_CTRL_STATUS_FAIR_SHARE_ARB (1 << 0)
++#define DMA_CTRL_STATUS_IN_PROGRESS (1 << 1)
++#define DMA_CTRL_STATUS_SRC_DREQ_MASK (0x0000003C)
++#define DMA_CTRL_STATUS_SRC_DREQ_SHIFT (2)
++#define DMA_CTRL_STATUS_DEST_DREQ_MASK (0x000003C0)
++#define DMA_CTRL_STATUS_DEST_DREQ_SHIFT (6)
++#define DMA_CTRL_STATUS_INTR (1 << 10)
++#define DMA_CTRL_STATUS_NXT_FREE (1 << 11)
++#define DMA_CTRL_STATUS_RESET (1 << 12)
++#define DMA_CTRL_STATUS_DIR_MASK (0x00006000)
++#define DMA_CTRL_STATUS_DIR_SHIFT (13)
++#define DMA_CTRL_STATUS_SRC_ADR_MODE (1 << 15)
++#define DMA_CTRL_STATUS_DEST_ADR_MODE (1 << 16)
++#define DMA_CTRL_STATUS_TRANSFER_MODE_A (1 << 17)
++#define DMA_CTRL_STATUS_TRANSFER_MODE_B (1 << 18)
++#define DMA_CTRL_STATUS_SRC_WIDTH_MASK (0x00380000)
++#define DMA_CTRL_STATUS_SRC_WIDTH_SHIFT (19)
++#define DMA_CTRL_STATUS_DEST_WIDTH_MASK (0x01C00000)
++#define DMA_CTRL_STATUS_DEST_WIDTH_SHIFT (22)
++#define DMA_CTRL_STATUS_PAUSE (1 << 25)
++#define DMA_CTRL_STATUS_INTERRUPT_ENABLE (1 << 26)
++#define DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED (1 << 27)
++#define DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED (1 << 28)
++#define DMA_CTRL_STATUS_STARVE_LOW_PRIORITY (1 << 29)
++#define DMA_CTRL_STATUS_INTR_CLEAR_ENABLE (1 << 30)
++
++#define DMA_BYTE_CNT_MASK ((1 << 21) - 1)
++#define DMA_BYTE_CNT_WR_EOT_MASK (1 << 30)
++#define DMA_BYTE_CNT_RD_EOT_MASK (1 << 31)
++
++#define MAKE_FIELD(value, num_bits, bit_num) (((value) & ((1 << (num_bits)) - 1)) << (bit_num))
++
++typedef enum oxnas_dma_mode {
++ OXNAS_DMA_MODE_FIXED,
++ OXNAS_DMA_MODE_INC
++} oxnas_dma_mode_t;
++
++typedef enum oxnas_dma_direction {
++ OXNAS_DMA_TO_DEVICE,
++ OXNAS_DMA_FROM_DEVICE
++} oxnas_dma_direction_t;
++
++/* The available buses to which the DMA controller is attached */
++typedef enum oxnas_dma_transfer_bus
++{
++ OXNAS_DMA_SIDE_A,
++ OXNAS_DMA_SIDE_B
++} oxnas_dma_transfer_bus_t;
++
++/* Direction of data flow between the DMA controller's pair of interfaces */
++typedef enum oxnas_dma_transfer_direction
++{
++ OXNAS_DMA_A_TO_A,
++ OXNAS_DMA_B_TO_A,
++ OXNAS_DMA_A_TO_B,
++ OXNAS_DMA_B_TO_B
++} oxnas_dma_transfer_direction_t;
++
++/* The available data widths */
++typedef enum oxnas_dma_transfer_width
++{
++ OXNAS_DMA_TRANSFER_WIDTH_8BITS,
++ OXNAS_DMA_TRANSFER_WIDTH_16BITS,
++ OXNAS_DMA_TRANSFER_WIDTH_32BITS
++} oxnas_dma_transfer_width_t;
++
++/* The mode of the DMA transfer */
++typedef enum oxnas_dma_transfer_mode
++{
++ OXNAS_DMA_TRANSFER_MODE_SINGLE,
++ OXNAS_DMA_TRANSFER_MODE_BURST
++} oxnas_dma_transfer_mode_t;
++
++/* The available transfer targets */
++typedef enum oxnas_dma_dreq
++{
++ OXNAS_DMA_DREQ_SATA = 0,
++ OXNAS_DMA_DREQ_MEMORY = 15
++} oxnas_dma_dreq_t;
++
++typedef struct oxnas_dma_device_settings {
++ unsigned long address_;
++ unsigned fifo_size_; // Chained transfers must take account of FIFO offset at end of previous transfer
++ unsigned char dreq_;
++ unsigned read_eot_:1;
++ unsigned read_final_eot_:1;
++ unsigned write_eot_:1;
++ unsigned write_final_eot_:1;
++ unsigned bus_:1;
++ unsigned width_:2;
++ unsigned transfer_mode_:1;
++ unsigned address_mode_:1;
++ unsigned address_really_fixed_:1;
++} oxnas_dma_device_settings_t;
++
++static const int MAX_NO_ERROR_LOOPS = 100000; /* 1 second in units of 10uS */
++static const int MAX_DMA_XFER_LOOPS = 300000; /* 30 seconds in units of 100uS */
++static const int MAX_DMA_ABORT_LOOPS = 10000; /* 0.1 second in units of 10uS */
++static const int MAX_SRC_READ_LOOPS = 10000; /* 0.1 second in units of 10uS */
++static const int MAX_SRC_WRITE_LOOPS = 10000; /* 0.1 second in units of 10uS */
++static const int MAX_NOT_BUSY_LOOPS = 10000; /* 1 second in units of 100uS */
++
++/* The internal SATA drive on which we should attempt to find partitions */
++static volatile u32* sata_regs_base[2] =
++{
++ (volatile u32*)SATA_0_REGS_BASE,
++ (volatile u32*)SATA_1_REGS_BASE,
++
++};
++static u32 wr_sata_orb1[2] = { 0, 0 };
++static u32 wr_sata_orb2[2] = { 0, 0 };
++static u32 wr_sata_orb3[2] = { 0, 0 };
++static u32 wr_sata_orb4[2] = { 0, 0 };
++
++static oxnas_dma_device_settings_t oxnas_sata_dma_settings = {
++ .address_ = SATA_DATA_BASE_PA,
++ .fifo_size_ = 16,
++ .dreq_ = OXNAS_DMA_DREQ_SATA,
++ .read_eot_ = 0,
++ .read_final_eot_ = 1,
++ .write_eot_ = 0,
++ .write_final_eot_ = 1,
++ .bus_ = OXNAS_DMA_SIDE_A,
++ .width_ = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
++ .transfer_mode_ = OXNAS_DMA_TRANSFER_MODE_BURST,
++ .address_mode_ = OXNAS_DMA_MODE_FIXED,
++ .address_really_fixed_ = 0
++};
++
++oxnas_dma_device_settings_t oxnas_ram_dma_settings = {
++ .address_ = 0,
++ .fifo_size_ = 0,
++ .dreq_ = OXNAS_DMA_DREQ_MEMORY,
++ .read_eot_ = 1,
++ .read_final_eot_ = 1,
++ .write_eot_ = 1,
++ .write_final_eot_ = 1,
++ .bus_ = OXNAS_DMA_SIDE_B,
++ .width_ = OXNAS_DMA_TRANSFER_WIDTH_32BITS,
++ .transfer_mode_ = OXNAS_DMA_TRANSFER_MODE_BURST,
++ .address_mode_ = OXNAS_DMA_MODE_FIXED,
++ .address_really_fixed_ = 1
++};
++
++static void xfer_wr_shadow_to_orbs(int device)
++{
++ *(sata_regs_base[device] + SATA_ORB1_OFF) = wr_sata_orb1[device];
++ *(sata_regs_base[device] + SATA_ORB2_OFF) = wr_sata_orb2[device];
++ *(sata_regs_base[device] + SATA_ORB3_OFF) = wr_sata_orb3[device];
++ *(sata_regs_base[device] + SATA_ORB4_OFF) = wr_sata_orb4[device];
++}
++
++static inline void device_select(int device)
++{
++ /* master/slave has no meaning to SATA core */
++}
++
++static int disk_present[CFG_IDE_MAXDEVICE];
++
++#include <ata.h>
++
++unsigned char oxnas_sata_inb(int device, int port)
++{
++ unsigned char val = 0;
++
++ /* Only permit accesses to disks found to be present during ide_preinit() */
++ if (!disk_present[device]) {
++ return ATA_STAT_FAULT;
++ }
++
++ device_select(device);
++
++ switch (port) {
++ case ATA_PORT_CTL:
++ val = (*(sata_regs_base[device] + SATA_ORB4_OFF) & (0xFFUL << SATA_CTL_BIT)) >> SATA_CTL_BIT;
++ break;
++ case ATA_PORT_FEATURE:
++ val = (*(sata_regs_base[device] + SATA_ORB2_OFF) & (0xFFUL << SATA_FEATURE_BIT)) >> SATA_FEATURE_BIT;
++ break;
++ case ATA_PORT_NSECT:
++ val = (*(sata_regs_base[device] + SATA_ORB2_OFF) & (0xFFUL << SATA_NSECT_BIT)) >> SATA_NSECT_BIT;
++ break;
++ case ATA_PORT_LBAL:
++ val = (*(sata_regs_base[device] + SATA_ORB3_OFF) & (0xFFUL << SATA_LBAL_BIT)) >> SATA_LBAL_BIT;
++ break;
++ case ATA_PORT_LBAM:
++ val = (*(sata_regs_base[device] + SATA_ORB3_OFF) & (0xFFUL << SATA_LBAM_BIT)) >> SATA_LBAM_BIT;
++ break;
++ case ATA_PORT_LBAH:
++ val = (*(sata_regs_base[device] + SATA_ORB3_OFF) & (0xFFUL << SATA_LBAH_BIT)) >> SATA_LBAH_BIT;
++ break;
++ case ATA_PORT_DEVICE:
++ val = (*(sata_regs_base[device] + SATA_ORB3_OFF) & (0xFFUL << SATA_HOB_LBAH_BIT)) >> SATA_HOB_LBAH_BIT;
++ val |= (*(sata_regs_base[device] + SATA_ORB1_OFF) & (0xFFUL << SATA_DEVICE_BIT)) >> SATA_DEVICE_BIT;
++ break;
++ case ATA_PORT_COMMAND:
++ val = (*(sata_regs_base[device] + SATA_ORB2_OFF) & (0xFFUL << SATA_COMMAND_BIT)) >> SATA_COMMAND_BIT;
++ val |= ATA_STAT_DRQ ;
++ break;
++ default:
++ printf("ide_inb() Unknown port = %d\n", port);
++ break;
++ }
++
++// printf("inb: %d:%01x => %02x\n", device, port, val);
++
++ return val;
++}
++
++/**
++ * Possible that ATA status will not become no-error, so must have timeout
++ * @returns An int which is zero on error
++ */
++static inline int wait_no_error(int device)
++{
++ int status = 0;
++
++ /* Check for ATA core error */
++ if (*(sata_regs_base[device] + SATA_INT_STATUS_OFF) & (1 << SATA_INT_STATUS_ERROR_BIT)) {
++ printf("wait_no_error() SATA core flagged error\n");
++ } else {
++ int loops = MAX_NO_ERROR_LOOPS;
++ do {
++ /* Check for ATA device error */
++ if (!(oxnas_sata_inb(device, ATA_PORT_COMMAND) & (1 << ATA_STATUS_ERR_BIT))) {
++ status = 1;
++ break;
++ }
++ udelay(10);
++ } while (--loops);
++
++ if (!loops) {
++ printf("wait_no_error() Timed out of wait for SATA no-error condition\n");
++ }
++ }
++
++ return status;
++}
++
++/**
++ * Expect SATA command to always finish, perhaps with error
++ * @returns An int which is zero on error
++ */
++static inline int wait_sata_command_not_busy(int device)
++{
++ /* Wait for data to be available */
++ int status = 0;
++ int loops = MAX_NOT_BUSY_LOOPS;
++ do {
++ if (!(*(sata_regs_base[device] + SATA_COMMAND_OFF) & (1 << SATA_CMD_BUSY_BIT) )) {
++ status = 1;
++ break;
++ }
++ udelay(100);
++ } while (--loops);
++
++ if (!loops) {
++ printf("wait_sata_command_not_busy() Timed out of wait for SATA command to finish\n");
++ }
++
++ return status;
++}
++
++void oxnas_sata_outb(int device, int port, unsigned char val)
++{
++ typedef enum send_method {
++ SEND_NONE,
++ SEND_SIMPLE,
++ SEND_CMD,
++ SEND_CTL,
++ } send_method_t;
++
++ /* Only permit accesses to disks found to be present during ide_preinit() */
++ if (!disk_present[device]) {
++ return;
++ }
++
++// printf("outb: %d:%01x <= %02x\n", device, port, val);
++
++ device_select(device);
++
++ send_method_t send_regs = SEND_NONE;
++ switch (port) {
++ case ATA_PORT_CTL:
++ wr_sata_orb4[device] &= ~(0xFFUL << SATA_CTL_BIT);
++ wr_sata_orb4[device] |= (val << SATA_CTL_BIT);
++ send_regs = SEND_CTL;
++ break;
++ case ATA_PORT_FEATURE:
++ wr_sata_orb2[device] &= ~(0xFFUL << SATA_FEATURE_BIT);
++ wr_sata_orb2[device] |= (val << SATA_FEATURE_BIT);
++ send_regs = SEND_SIMPLE;
++ break;
++ case ATA_PORT_NSECT:
++ wr_sata_orb2[device] &= ~(0xFFUL << SATA_NSECT_BIT);
++ wr_sata_orb2[device] |= (val << SATA_NSECT_BIT);
++ send_regs = SEND_SIMPLE;
++ break;
++ case ATA_PORT_LBAL:
++ wr_sata_orb3[device] &= ~(0xFFUL << SATA_LBAL_BIT);
++ wr_sata_orb3[device] |= (val << SATA_LBAL_BIT);
++ send_regs = SEND_SIMPLE;
++ break;
++ case ATA_PORT_LBAM:
++ wr_sata_orb3[device] &= ~(0xFFUL << SATA_LBAM_BIT);
++ wr_sata_orb3[device] |= (val << SATA_LBAM_BIT);
++ send_regs = SEND_SIMPLE;
++ break;
++ case ATA_PORT_LBAH:
++ wr_sata_orb3[device] &= ~(0xFFUL << SATA_LBAH_BIT);
++ wr_sata_orb3[device] |= (val << SATA_LBAH_BIT);
++ send_regs = SEND_SIMPLE;
++ break;
++ case ATA_PORT_DEVICE:
++ wr_sata_orb1[device] &= ~(0xFFUL << SATA_DEVICE_BIT);
++ wr_sata_orb1[device] |= ((val & 0xf0) << SATA_DEVICE_BIT);
++ wr_sata_orb3[device] &= ~(0xFFUL << SATA_HOB_LBAH_BIT);
++ wr_sata_orb3[device] |= ((val & 0x0f) << SATA_HOB_LBAH_BIT);
++ send_regs = SEND_SIMPLE;
++ break;
++ case ATA_PORT_COMMAND:
++ wr_sata_orb2[device] &= ~(0xFFUL << SATA_COMMAND_BIT);
++ wr_sata_orb2[device] |= (val << SATA_COMMAND_BIT);
++ send_regs = SEND_CMD;
++ break;
++ default:
++ printf("ide_outb() Unknown port = %d\n", port);
++ }
++
++ u32 command;
++ switch (send_regs) {
++ case SEND_CMD:
++ wait_sata_command_not_busy(device);
++ command = *(sata_regs_base[device] + SATA_COMMAND_OFF);
++ command &= ~SATA_OPCODE_MASK;
++ command |= SATA_CMD_WRITE_TO_ORB_REGS;
++ xfer_wr_shadow_to_orbs(device);
++ wait_sata_command_not_busy(device);
++ *(sata_regs_base[device] + SATA_COMMAND_OFF) = command;
++ if (!wait_no_error(device)) {
++ printf("oxnas_sata_outb() Wait for ATA no-error timed-out\n");
++ }
++ break;
++ case SEND_CTL:
++ wait_sata_command_not_busy(device);
++ command = *(sata_regs_base[device] + SATA_COMMAND_OFF);
++ command &= ~SATA_OPCODE_MASK;
++ command |= SATA_CMD_WRITE_TO_ORB_REGS_NO_COMMAND;
++ xfer_wr_shadow_to_orbs(device);
++ wait_sata_command_not_busy(device);
++ *(sata_regs_base[device] + SATA_COMMAND_OFF) = command;
++ if (!wait_no_error(device)) {
++ printf("oxnas_sata_outb() Wait for ATA no-error timed-out\n");
++ }
++ break;
++ default:
++ break;
++ }
++}
++
++static u32 encode_start(u32 ctrl_status)
++{
++ return ctrl_status & ~DMA_CTRL_STATUS_PAUSE;
++}
++
++static void dma_start(void)
++{
++ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS) =
++ encode_start(*(DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS)));
++}
++
++static unsigned long encode_control_status(
++ oxnas_dma_device_settings_t* src_settings,
++ oxnas_dma_device_settings_t* dst_settings)
++{
++ unsigned long ctrl_status;
++ oxnas_dma_transfer_direction_t direction;
++
++ ctrl_status = DMA_CTRL_STATUS_PAUSE; // Paused
++ ctrl_status |= DMA_CTRL_STATUS_FAIR_SHARE_ARB; // High priority
++ ctrl_status |= (src_settings->dreq_ << DMA_CTRL_STATUS_SRC_DREQ_SHIFT); // Dreq
++ ctrl_status |= (dst_settings->dreq_ << DMA_CTRL_STATUS_DEST_DREQ_SHIFT); // Dreq
++ ctrl_status &= ~DMA_CTRL_STATUS_RESET; // !RESET
++
++ // Use new interrupt clearing register
++ ctrl_status |= DMA_CTRL_STATUS_INTR_CLEAR_ENABLE;
++
++ // Setup the transfer direction and burst/single mode for the two DMA busses
++ if (src_settings->bus_ == OXNAS_DMA_SIDE_A) {
++ // Set the burst/single mode for bus A based on src device's settings
++ if (src_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
++ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_A;
++ } else {
++ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_A;
++ }
++
++ if (dst_settings->bus_ == OXNAS_DMA_SIDE_A) {
++ direction = OXNAS_DMA_A_TO_A;
++ } else {
++ direction = OXNAS_DMA_A_TO_B;
++
++ // Set the burst/single mode for bus B based on dst device's settings
++ if (dst_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
++ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_B;
++ } else {
++ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_B;
++ }
++ }
++ } else {
++ // Set the burst/single mode for bus B based on src device's settings
++ if (src_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
++ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_B;
++ } else {
++ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_B;
++ }
++
++ if (dst_settings->bus_ == OXNAS_DMA_SIDE_A) {
++ direction = OXNAS_DMA_B_TO_A;
++
++ // Set the burst/single mode for bus A based on dst device's settings
++ if (dst_settings->transfer_mode_ == OXNAS_DMA_TRANSFER_MODE_BURST) {
++ ctrl_status |= DMA_CTRL_STATUS_TRANSFER_MODE_A;
++ } else {
++ ctrl_status &= ~DMA_CTRL_STATUS_TRANSFER_MODE_A;
++ }
++ } else {
++ direction = OXNAS_DMA_B_TO_B;
++ }
++ }
++ ctrl_status |= (direction << DMA_CTRL_STATUS_DIR_SHIFT);
++
++ // Setup source address mode fixed or increment
++ if (src_settings->address_mode_ == OXNAS_DMA_MODE_FIXED) {
++ // Fixed address
++ ctrl_status &= ~(DMA_CTRL_STATUS_SRC_ADR_MODE);
++
++ // Set up whether fixed address is _really_ fixed
++ if (src_settings->address_really_fixed_) {
++ ctrl_status |= DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
++ } else {
++ ctrl_status &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
++ }
++ } else {
++ // Incrementing address
++ ctrl_status |= DMA_CTRL_STATUS_SRC_ADR_MODE;
++ ctrl_status &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
++ }
++
++ // Setup destination address mode fixed or increment
++ if (dst_settings->address_mode_ == OXNAS_DMA_MODE_FIXED) {
++ // Fixed address
++ ctrl_status &= ~(DMA_CTRL_STATUS_DEST_ADR_MODE);
++
++ // Set up whether fixed address is _really_ fixed
++ if (dst_settings->address_really_fixed_) {
++ ctrl_status |= DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
++ } else {
++ ctrl_status &= ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
++ }
++ } else {
++ // Incrementing address
++ ctrl_status |= DMA_CTRL_STATUS_DEST_ADR_MODE;
++ ctrl_status &= ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
++ }
++
++ // Set up the width of the transfers on the DMA buses
++ ctrl_status |= (src_settings->width_ << DMA_CTRL_STATUS_SRC_WIDTH_SHIFT);
++ ctrl_status |= (dst_settings->width_ << DMA_CTRL_STATUS_DEST_WIDTH_SHIFT);
++
++ // Setup the priority arbitration scheme
++ ctrl_status &= ~DMA_CTRL_STATUS_STARVE_LOW_PRIORITY; // !Starve low priority
++
++ return ctrl_status;
++}
++
++static u32 encode_final_eot(
++ oxnas_dma_device_settings_t* src_settings,
++ oxnas_dma_device_settings_t* dst_settings,
++ unsigned long length)
++{
++ // Write the length, with EOT configuration for a final transfer
++ unsigned long encoded = length;
++ if (dst_settings->write_final_eot_) {
++ encoded |= DMA_BYTE_CNT_WR_EOT_MASK;
++ } else {
++ encoded &= ~DMA_BYTE_CNT_WR_EOT_MASK;
++ }
++ if (src_settings->read_final_eot_) {
++ encoded |= DMA_BYTE_CNT_RD_EOT_MASK;
++ } else {
++ encoded &= ~DMA_BYTE_CNT_RD_EOT_MASK;
++ }
++ return encoded;
++}
++
++static void dma_start_write(ulong* buffer, int num_bytes)
++{
++ // Assemble complete memory settings
++ oxnas_dma_device_settings_t mem_settings = oxnas_ram_dma_settings;
++ mem_settings.address_ = (unsigned long)buffer;
++ mem_settings.address_mode_ = OXNAS_DMA_MODE_INC;
++
++ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS) = encode_control_status(&mem_settings, &oxnas_sata_dma_settings);
++ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_BASE_SRC_ADR) = mem_settings.address_;
++ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_BASE_DST_ADR) = oxnas_sata_dma_settings.address_;
++ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_BYTE_CNT) = encode_final_eot(&mem_settings, &oxnas_sata_dma_settings, num_bytes);
++
++ dma_start();
++}
++
++static void dma_start_read(ulong* buffer, int num_bytes)
++{
++ // Assemble complete memory settings
++ oxnas_dma_device_settings_t mem_settings = oxnas_ram_dma_settings;
++ mem_settings.address_ = (unsigned long)buffer;
++ mem_settings.address_mode_ = OXNAS_DMA_MODE_INC;
++
++ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS) = encode_control_status(&oxnas_sata_dma_settings, &mem_settings);
++ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_BASE_SRC_ADR) = oxnas_sata_dma_settings.address_;
++ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_BASE_DST_ADR) = mem_settings.address_;
++ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_BYTE_CNT) = encode_final_eot(&oxnas_sata_dma_settings, &mem_settings, num_bytes);
++
++ dma_start();
++}
++
++static inline int dma_busy(void)
++{
++ return (*DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS)) & DMA_CTRL_STATUS_IN_PROGRESS;
++}
++
++static int wait_dma_not_busy(int device)
++{
++ unsigned int cleanup_required = 0;
++
++ /* Poll for DMA completion */
++ int loops = MAX_DMA_XFER_LOOPS;
++ do {
++ if (!dma_busy()) {
++ break;
++ }
++ udelay(100);
++ } while (--loops);
++
++ if (!loops) {
++ printf("wait_dma_not_busy() Timed out of wait for DMA not busy\n");
++ cleanup_required = 1;
++ }
++
++ if (cleanup_required) {
++ /* Abort DMA to make sure it has finished. */
++ unsigned long ctrl_status = *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS);
++ ctrl_status |= DMA_CTRL_STATUS_RESET;
++ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS) = ctrl_status;
++
++ // Wait for the channel to become idle - should be quick as should
++ // finish after the next AHB single or burst transfer
++ loops = MAX_DMA_ABORT_LOOPS;
++ do {
++ if (!(*DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS) & DMA_CTRL_STATUS_IN_PROGRESS)) {
++ break;
++ }
++ udelay(10);
++ } while (--loops);
++
++ if (!loops) {
++ printf("wait_dma_not_busy() Timed out of wait for DMA channel abort\n");
++ } else {
++ /* Successfully cleanup the DMA channel */
++ cleanup_required = 0;
++ }
++
++ // Deassert reset for the channel
++ ctrl_status = *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS);
++ ctrl_status &= ~DMA_CTRL_STATUS_RESET;
++ *DMA_CALC_REG_ADR(SATA_DMA_CHANNEL, DMA_CTRL_STATUS) = ctrl_status;
++ }
++
++ return !cleanup_required;
++}
++
++/**
++ * Possible that ATA status will not become not-busy, so must have timeout
++ */
++static unsigned int wait_not_busy(int device, unsigned long timeout_secs)
++{
++ int busy = 1;
++ unsigned long loops = (timeout_secs * 1000) / 50;
++ do {
++ // Test the ATA status register BUSY flag
++ if (!((*(sata_regs_base[device] + SATA_ORB2_OFF) >> SATA_COMMAND_BIT) & (1UL << ATA_STATUS_BSY_BIT))) {
++ /* Not busy, so stop polling */
++ busy = 0;
++ break;
++ }
++
++ // Wait for 50mS before sampling ATA status register again
++ udelay(50000);
++ } while (--loops);
++
++ return busy;
++}
++
++void oxnas_sata_output_data(int device, ulong *sect_buf, int words)
++{
++ /* Only permit accesses to disks found to be present during ide_preinit() */
++ if (!disk_present[device]) {
++ return;
++ }
++
++ /* Select the required internal SATA drive */
++ device_select(device);
++
++ /* Start the DMA channel sending data from the passed buffer to the SATA core */
++ dma_start_write(sect_buf, words << 2);
++
++ /* Don't know why we need this delay, but without it the wait for DMA not
++ busy times soemtimes out, e.g. when saving environment to second disk */
++ udelay(1000);
++
++ /* Wait for DMA to finish */
++ if (!wait_dma_not_busy(device)) {
++ printf("Timed out of wait for DMA channel for SATA device %d to have in-progress clear\n", device);
++ }
++
++ /* Sata core should finish after DMA */
++ if (wait_not_busy(device, 30)) {
++ printf("Timed out of wait for SATA device %d to have BUSY clear\n", device);
++ }
++ if (!wait_no_error(device)) {
++ printf("oxnas_sata_output_data() Wait for ATA no-error timed-out\n");
++ }
++}
++
++void oxnas_sata_input_data(int device, ulong *sect_buf, int words)
++{
++ /* Only permit accesses to disks found to be present during ide_preinit() */
++ if (!disk_present[device]) {
++ return;
++ }
++
++ /* Select the required internal SATA drive */
++ device_select(device);
++
++ /* Start the DMA channel receiving data from the SATA core into the passed buffer */
++ dma_start_read(sect_buf, words << 2);
++
++ /* Sata core should finish before DMA */
++ if (wait_not_busy(device, 30)) {
++ printf("Timed out of wait for SATA device %d to have BUSY clear\n", device);
++ }
++ if (!wait_no_error(device)) {
++ printf("oxnas_sata_output_data() Wait for ATA no-error timed-out\n");
++ }
++
++ /* Wait for DMA to finish */
++ if (!wait_dma_not_busy(device)) {
++ printf("Timed out of wait for DMA channel for SATA device %d to have in-progress clear\n", device);
++ }
++}
++
++static u32 scr_read(int device, unsigned int sc_reg)
++{
++ /* Setup adr of required register. std regs start eight into async region */
++ *(sata_regs_base[device] + SATA_LINK_RD_ADDR) = sc_reg*4 + SATA_STD_ASYNC_REGS_OFF;
++
++ /* Wait for data to be available */
++ int loops = MAX_SRC_READ_LOOPS;
++ do {
++ if (*(sata_regs_base[device] + SATA_LINK_CONTROL) & 1UL) {
++ break;
++ }
++ udelay(10);
++ } while (--loops);
++
++ if (!loops) {
++ printf("scr_read() Timed out of wait for read completion\n");
++ }
++
++ /* Read the data from the async register */
++ return *(sata_regs_base[device] + SATA_LINK_DATA);
++}
++
++static void scr_write(int device, unsigned int sc_reg, u32 val)
++{
++ /* Setup the data for the write */
++ *(sata_regs_base[device] + SATA_LINK_DATA) = val;
++
++ /* Setup adr of required register. std regs start eight into async region */
++ *(sata_regs_base[device] + SATA_LINK_WR_ADDR) = sc_reg*4 + SATA_STD_ASYNC_REGS_OFF;
++
++ /* Wait for data to be written */
++ int loops = MAX_SRC_WRITE_LOOPS;
++ do {
++ if (*(sata_regs_base[device] + SATA_LINK_CONTROL) & 1UL) {
++ break;
++ }
++ udelay(10);
++ } while (--loops);
++
++ if (!loops) {
++ printf("scr_write() Timed out of wait for write completion\n");
++ }
++}
++
++#define PHY_LOOP_COUNT 25 /* Wait for upto 5 seconds for PHY to be found */
++static int phy_reset(int device)
++{
++#ifdef FPGA
++ /* The FPGA thinks it can do 3G when infact only 1.5G is possible, so limit
++ it to Gen-1 SATA (1.5G) */
++ scr_write(device, SATA_SCR_CONTROL, 0x311); /* Issue phy wake & core reset */
++ scr_read(device, SATA_SCR_STATUS); /* Dummy read; flush */
++ udelay(1000);
++ scr_write(device, SATA_SCR_CONTROL, 0x310); /* Issue phy wake & clear core reset */
++#else
++ scr_write(device, SATA_SCR_CONTROL, 0x301); /* Issue phy wake & core reset */
++ scr_read(device, SATA_SCR_STATUS); /* Dummy read; flush */
++ udelay(1000);
++ scr_write(device, SATA_SCR_CONTROL, 0x300); /* Issue phy wake & clear core reset */
++#endif
++ /* Wait for upto 5 seconds for PHY to become ready */
++ int phy_status = 0;
++ int loops = 0;
++ do {
++ udelay(200000);
++ if ((scr_read(device, SATA_SCR_STATUS) & 0xf) != 1) {
++ phy_status = 1;
++ break;
++ }
++ printf("No SATA PHY found\n");
++ } while (++loops < PHY_LOOP_COUNT);
++
++ if (phy_status) {
++ udelay(500000); /* wait half a second */
++ }
++ return phy_status;
++}
++
++#define FIS_LOOP_COUNT 25 /* Wait for upto 5 seconds for FIS to be received */
++static int wait_FIS(int device)
++{
++ int status = 0;
++ int loops = 0;
++
++ do {
++ udelay(200000);
++ if (oxnas_sata_inb(device, ATA_PORT_NSECT) > 0) {
++ status = 1;
++ break;
++ }
++ } while (++loops < FIS_LOOP_COUNT);
++
++ return status;
++}
++
++int ide_preinit(void)
++{
++ int num_disks_found = 0;
++
++ /* Initialise records of which disks are present to all present */
++ int i;
++ for (i=0; i < CFG_IDE_MAXDEVICE; i++) {
++ disk_present[i] = 1;
++ }
++
++//udelay(1000000);
++ /* Enable clocks to SATA and DMA cores */
++ *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_SATA_BIT);
++ *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_DMA_BIT);
++
++ /* Block reset SATA and DMA cores */
++ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_SATA_BIT) |
++ (1UL << SYS_CTRL_RSTEN_SATA_LINK_BIT) |
++ (1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT) |
++ (1UL << SYS_CTRL_RSTEN_DMA_BIT);
++ udelay(50);
++ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT);
++ udelay(50);
++ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_SATA_LINK_BIT) |
++ (1UL << SYS_CTRL_RSTEN_SATA_BIT);
++ udelay(50);
++ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_DMA_BIT);
++ udelay(50);
++//udelay(1000000);
++
++ /* disable and clear core interrupts */
++ *((unsigned long*)SATA_HOST_REGS_BASE + SATA_INT_ENABLE_CLR_OFF) = ~0UL;
++ *((unsigned long*)SATA_HOST_REGS_BASE + SATA_INT_CLR_OFF) = ~0UL;
++
++ int device;
++ for (device = 0; device < CFG_IDE_MAXDEVICE; device++) {
++ int found = 0;
++ int retries = 1;
++
++ /* Disable SATA interrupts */
++ *(sata_regs_base[device] + SATA_INT_ENABLE_CLR_OFF) = ~0UL;
++
++ /* Clear any pending SATA interrupts */
++ *(sata_regs_base[device] + SATA_INT_CLR_OFF) = ~0UL;
++
++ do {
++ /* clear sector count register for FIS detection */
++ oxnas_sata_outb(device, ATA_PORT_NSECT, 0);
++
++ /* Get the PHY working */
++ if (!phy_reset(device)) {
++ printf("SATA PHY not ready for device %d\n", device);
++ break;
++ }
++
++ if (!wait_FIS(device)) {
++ printf("No FIS received from device %d\n", device);
++ } else {
++ if ((scr_read(device, SATA_SCR_STATUS) & 0xf) == 0x3) {
++ if (wait_not_busy(device, 30)) {
++ printf("Timed out of wait for SATA device %d to have BUSY clear\n", device);
++ } else {
++ ++num_disks_found;
++ found = 1;
++ }
++ } else {
++ printf("No SATA device %d found, PHY status = 0x%08x\n",
++ device, scr_read(device, SATA_SCR_STATUS));
++ }
++ break;
++ }
++ } while (retries--) ;
++
++ /* Record whether disk is present, so won't attempt to access it later */
++ disk_present[device] = found;
++ }
++
++ /* post disk detection clean-up */
++ for (device = 0; device < CFG_IDE_MAXDEVICE; device++) {
++ if ( disk_present[device] ) {
++ /* set as ata-5 (28-bit) */
++ *(sata_regs_base[device] + SATA_DRIVE_CONTROL_OFF) = 0UL;
++
++ /* clear phy/link errors */
++ scr_write(device, SATA_SCR_ERROR, ~0);
++
++ /* clear host errors */
++ *(sata_regs_base[device] + SATA_CONTROL_OFF) |= SATA_SCTL_CLR_ERR;
++
++ /* clear interrupt register as this clears the error bit in the IDE
++ status register */
++ *(sata_regs_base[device] + SATA_INT_CLR_OFF) = ~0UL;
++ }
++ }
++
++
++ return !num_disks_found;
++}
++
+diff -Nurd u-boot-1.1.2/board/oxnas/Makefile u-boot-1.1.2-oxe810/board/oxnas/Makefile
+--- u-boot-1.1.2/board/oxnas/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-1.1.2-oxe810/board/oxnas/Makefile 2008-06-11 17:55:18.000000000 +0200
+@@ -0,0 +1,51 @@
++#
++# (C) Copyright 2000-2004
++# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
++#
++# (C) Copyright 2004
++# ARM Ltd.
++# Philippe Robin, <philippe.robin@arm.com>
++#
++# See file CREDITS for list of people who contributed to this
++# project.
++#
++# 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 $(TOPDIR)/config.mk
++
++LIB = lib$(BOARD).a
++
++OBJS := oxnas.o eth.o ide-$(NAS_VERSION).o
++SOBJS := platform-$(NAS_VERSION).o
++
++$(LIB): $(OBJS) $(SOBJS)
++ $(AR) crv $@ $^
++
++clean:
++ rm -f $(SOBJS) $(OBJS)
++
++distclean: clean
++ rm -f $(LIB) core *.bak .depend
++
++#########################################################################
++
++.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
++ $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
++
++-include .depend
++
++#########################################################################
+diff -Nurd u-boot-1.1.2/board/oxnas/oxnas.c u-boot-1.1.2-oxe810/board/oxnas/oxnas.c
+--- u-boot-1.1.2/board/oxnas/oxnas.c 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-1.1.2-oxe810/board/oxnas/oxnas.c 2008-06-11 17:55:18.000000000 +0200
+@@ -0,0 +1,280 @@
++/*
++ * (C) Copyright 2005
++ * Oxford Semiconductor Ltd
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * 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 <common.h>
++
++#if defined(CONFIG_SHOW_BOOT_PROGRESS)
++void show_boot_progress(int progress)
++{
++ printf("Boot reached stage %d\n", progress);
++}
++#endif
++
++static inline void delay(unsigned long loops)
++{
++ __asm__ volatile ("1:\n"
++ "subs %0, %1, #1\n"
++ "bne 1b":"=r" (loops):"0" (loops));
++}
++
++/*
++ * Miscellaneous platform dependent initialisations
++ */
++
++/** Expected Intel 28F320B3T CFI info */
++// mfr_id: MANUFACTURER_INTEL, -> 0x0089
++// dev_id: I28F320B3T, -> 0x8896
++// name: "Intel 28F320B3T",
++// DevSize: SIZE_4MiB, -> 22
++// CmdSet: P_ID_INTEL_STD, -> 0x0003
++// NumEraseRegions: 2,
++// regions: { -> #define ERASEINFO(size,blocks) (size<<8)|(blocks-1)
++// ERASEINFO(0x10000, 63),
++// ERASEINFO(0x02000, 8),
++// }
++
++#define FLASH_WORD_SIZE unsigned short
++
++int board_init(void)
++{
++ DECLARE_GLOBAL_DATA_PTR;
++
++ gd->bd->bi_arch_number = MACH_TYPE_OXNAS;
++ gd->bd->bi_boot_params = PHYS_SDRAM_1_PA + 0x100;
++ gd->flags = 0;
++
++ icache_enable();
++
++ /* Block reset Static core */
++ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_STATIC_BIT);
++ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_STATIC_BIT);
++
++ /* Enable clock to Static core */
++ *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_STATIC_BIT);
++
++#ifdef CONFIG_OXNAS_ENABLE_PCI
++ /* Block reset PCI core */
++ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_PCI_BIT);
++ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_PCI_BIT);
++
++ /* Enable clock to PCI core */
++ *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_PCI_BIT);
++#endif // CONFIG_OXNAS_ENABLE_PCI
++
++#ifdef CONFIG_OXNAS_MANUAL_STATIC_ARBITRATION
++ /* Assert manual static bus PCI arbitration request */
++ *(volatile u32*)SYS_CTRL_PCI_CTRL1 |= (1UL << SYS_CTRL_PCI_CTRL1_PCI_STATIC_RQ_BIT);
++#endif // CONFIG_OXNAS_MANUAL_STATIC_ARBITRATION
++
++#ifdef CONFIG_OXNAS_FEEDBACK_PCI_CLKS
++ /* Set PCI feedback clk GPIO pin as an output */
++ *(volatile u32*)GPIO_1_SET_OE |= 0x800;
++
++ /* Enable PCI feedback clk onto GPIO pin */
++ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 |= 0x00000800;
++#endif // CONFIG_OXNAS_FEEDBACK_PCI_CLKS
++
++#ifndef CFG_NO_FLASH
++ /* Enable static bus onto GPIOs, only CS0 as CS1 conflicts with UART2 */
++ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 |= 0x002FF000;
++
++ /* Setup the static bus CS0 to access FLASH */
++ *(volatile u32*)STATIC_CONTROL_BANK0 = STATIC_BUS_FLASH_CONFIG;
++#endif // !CFG_NO_FLASH
++
++ /* Set 33MHz PCI clock */
++ *(volatile u32*)SYS_CTRL_CKCTRL_CTRL_ADDR = 5;
++ /* Enable full speed RPS clock */
++ *(volatile u32*)SYS_CTRL_CKCTRL_CTRL_ADDR &= ~(1UL << SYS_CTRL_CKCTRL_SLOW_BIT);
++
++#if (USE_EXTERNAL_UART == 0)
++#ifdef CONFIG_OXNAS_UART1
++ /* Block reset UART1 */
++ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART1_BIT);
++ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART1_BIT);
++
++ /* Setup pin mux'ing for first internal UART */
++ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x80000000;
++ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 &= ~0x80000000;
++ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |= 0x80000000; // Route UART1 SOUT onto external pins
++
++ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_1 &= ~0x00000001;
++ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_1 &= ~0x00000001;
++ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_1 |= 0x00000001; // Route UART1 SIN onto external pins
++
++ *(volatile u32*)GPIO_1_SET_OE |= 0x80000000; // Make UART1 SOUT an o/p
++ *(volatile u32*)GPIO_2_CLR_OE |= 0x00000001; // Make UART1 SIN an i/p
++#endif // CONFIG_OXNAS_UART1
++
++#ifdef CONFIG_OXNAS_UART2
++ // Block reset UART2
++ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART2_BIT);
++ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART2_BIT);
++
++ /* Setup pin mux'ing for second internal UART */
++ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x00500000;
++ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 &= ~0x00500000;
++ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |= 0x00500000; // Route UART2 SOUT and SIN onto external pins
++
++ *(volatile u32*)GPIO_1_SET_OE |= 0x00100000; // Make UART2 SOUT an o/p
++ *(volatile u32*)GPIO_1_CLR_OE |= 0x00400000; // Make UART2 SIN an i/p
++#endif // CONFIG_OXNAS_UART2
++
++#ifdef CONFIG_OXNAS_UART3
++ // Block reset UART3
++ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART3_BIT);
++ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART3_BIT);
++
++ // Route UART3 SIN/SOUT onto external pin
++ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 &= ~0x000000C0;
++ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 &= ~0x000000C0;
++ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 |= 0x000000C0;
++
++ // Setup GPIO line directions for UART3 SIN/SOUT
++ *(volatile u32*)GPIO_1_SET_OE |= 0x00000080;
++ *(volatile u32*)GPIO_1_CLR_OE |= 0x00000040;
++#endif // CONFIG_ARCH_OXNAS_UART3
++
++#ifdef CONFIG_OXNAS_UART4
++ // Block reset UART4
++ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_UART4_BIT);
++ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_UART4_BIT);
++
++ // Enable UART4 to override PCI functions onto GPIOs
++ *(volatile u32*)SYS_CTRL_UART_CTRL |= (1UL << SYS_CTRL_UART4_NOT_PCI_MODE);
++#endif // CONFIG_OXNAS_UART4
++#endif // !USE_EXTERNAL_UART
++
++ return 0;
++}
++
++int board_late_init()
++{
++ return 0;
++}
++
++int misc_init_r(void)
++{
++ return 0;
++}
++
++int dram_init(void)
++{
++#ifdef PROBE_MEM_SIZE
++ /* Determine the amount of SDRAM the DDR controller is configured for */
++ volatile unsigned long * const ddr_config_reg_adr = (volatile unsigned long *)(0x45800000);
++ static const int DDR_SIZE_BIT = 17;
++ static const int DDR_SIZE_NUM_BITS = 4;
++ static const unsigned long DDR_SIZE_MASK = (((1UL << DDR_SIZE_NUM_BITS) - 1) << DDR_SIZE_BIT);
++
++ unsigned long ddr_config_reg = *ddr_config_reg_adr;
++ int ddr_size_pow2 = (ddr_config_reg & DDR_SIZE_MASK) >> DDR_SIZE_BIT;
++
++ DECLARE_GLOBAL_DATA_PTR;
++
++ gd->bd->bi_dram[0].size = (1 << ddr_size_pow2) * 1024 * 1024;
++
++ if ((gd->bd->bi_dram[0].size >> 20) == 256) {
++ /* Do we really have 256M, or are we working around the DDR controller's
++ * problem with 128M size? */
++ volatile unsigned long * const PROBE_ADR_1 = (volatile unsigned long * const)PHYS_SDRAM_1_PA;
++ volatile unsigned long * const PROBE_ADR_2 = (volatile unsigned long * const)(PHYS_SDRAM_1_PA + (128*1024*1024));
++ static const unsigned long PROBE_VAL_1 = 0xdeadbeef;
++ static const unsigned long PROBE_VAL_2 = 0x12345678;
++
++ *PROBE_ADR_1 = PROBE_VAL_1;
++ *PROBE_ADR_2 = PROBE_VAL_2;
++ if (*PROBE_ADR_1 != PROBE_VAL_1) {
++ gd->bd->bi_dram[0].size = 128*1024*1024;
++ }
++ }
++#else // PROBE_MEM_SIZE
++ gd->bd->bi_dram[0].size = MEM_SIZE;
++#endif // PROBE_MEM_SIZE
++
++ gd->bd->bi_dram[0].start = PHYS_SDRAM_1_PA;
++
++ gd->bd->bi_sramstart = CFG_SRAM_BASE;
++ gd->bd->bi_sramsize = CFG_SRAM_SIZE;
++
++ return 0;
++}
++
++int reset_cpu(void)
++{
++ printf("Resetting Oxsemi NAS...");
++
++ // Assert reset to cores as per power on defaults
++ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL =
++ (1UL << SYS_CTRL_RSTEN_COPRO_BIT) |
++ (1UL << SYS_CTRL_RSTEN_USBHS_BIT) |
++ (1UL << SYS_CTRL_RSTEN_USBHSPHY_BIT) |
++ (1UL << SYS_CTRL_RSTEN_MAC_BIT) |
++ (1UL << SYS_CTRL_RSTEN_PCI_BIT) |
++ (1UL << SYS_CTRL_RSTEN_DMA_BIT) |
++ (1UL << SYS_CTRL_RSTEN_DPE_BIT) |
++ (1UL << SYS_CTRL_RSTEN_SATA_BIT) |
++ (1UL << SYS_CTRL_RSTEN_SATA_LINK_BIT) |
++ (1UL << SYS_CTRL_RSTEN_SATA_PHY_BIT) |
++ (1UL << SYS_CTRL_RSTEN_STATIC_BIT) |
++ (1UL << SYS_CTRL_RSTEN_UART1_BIT) |
++ (1UL << SYS_CTRL_RSTEN_UART2_BIT) |
++ (1UL << SYS_CTRL_RSTEN_MISC_BIT) |
++ (1UL << SYS_CTRL_RSTEN_I2S_BIT) |
++ (1UL << SYS_CTRL_RSTEN_AHB_MON_BIT) |
++ (1UL << SYS_CTRL_RSTEN_UART3_BIT) |
++ (1UL << SYS_CTRL_RSTEN_UART4_BIT) |
++ (1UL << SYS_CTRL_RSTEN_SGDMA_BIT);
++
++ // Release reset to cores as per power on defaults
++ *(volatile u32*)SYS_CTRL_RSTEN_CLR_CTRL = (1UL << SYS_CTRL_RSTEN_GPIO_BIT);
++
++ // Disable clocks to cores as per power-on defaults
++ *(volatile u32*)SYS_CTRL_CKEN_CLR_CTRL =
++ (1UL << SYS_CTRL_CKEN_COPRO_BIT) |
++ (1UL << SYS_CTRL_CKEN_DMA_BIT) |
++ (1UL << SYS_CTRL_CKEN_DPE_BIT) |
++ (1UL << SYS_CTRL_CKEN_SATA_BIT) |
++ (1UL << SYS_CTRL_CKEN_I2S_BIT) |
++ (1UL << SYS_CTRL_CKEN_USBHS_BIT) |
++ (1UL << SYS_CTRL_CKEN_MAC_BIT) |
++ (1UL << SYS_CTRL_CKEN_STATIC_BIT);
++
++ // Enable clocks to cores as per power-on defaults
++ *(volatile u32*)SYS_CTRL_CKEN_SET_CTRL = (1UL << SYS_CTRL_CKEN_PCI_BIT);
++
++ // Set sys-control pin mux'ing as per power-on defaults
++ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_0 = 0x800UL;
++ *(volatile u32*)SYS_CTRL_GPIO_PRIMSEL_CTRL_1 = 0x0UL;
++ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_0 = 0x0UL;
++ *(volatile u32*)SYS_CTRL_GPIO_SECSEL_CTRL_1 = 0x0UL;
++ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_0 = 0x0UL;
++ *(volatile u32*)SYS_CTRL_GPIO_TERTSEL_CTRL_1 = 0x0UL;
++
++ // No need to save any state, as the ROM loader can determine whether reset
++ // is due to power cycling or programatic action, just hit the (self-
++ // clearing) CPU reset bit of the block reset register
++ *(volatile u32*)SYS_CTRL_RSTEN_SET_CTRL = (1UL << SYS_CTRL_RSTEN_ARM_BIT);
++
++ return 0;
++}
+diff -Nurd u-boot-1.1.2/board/oxnas/platform-800.S u-boot-1.1.2-oxe810/board/oxnas/platform-800.S
+--- u-boot-1.1.2/board/oxnas/platform-800.S 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-1.1.2-oxe810/board/oxnas/platform-800.S 2008-06-11 17:55:18.000000000 +0200
+@@ -0,0 +1,254 @@
++/*
++ * Board specific setup info
++ *
++ * (C) Copyright 2005
++ * Oxford Semiconductor Ltd
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * 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 <config.h>
++#include <version.h>
++
++/* use estimate of processor speed to calculate number of cycles delay */
++/* delay count is nominal (PLL200 frequency x delay time) / loop count
++ * expressing 200us as 200/1000000 and re-arranging gives the expression below
++ */
++
++#define DELAY_200US ((NOMINAL_ARMCLK / (5 * 1000000)) * 200)
++/* this is 8 cycles of ? so choose 8 resulting in 40 cycles */
++#define DELAY_1S ((DELAY_200US) * 5000)
++#define DELAY_8 8
++#define DELAY_200 200
++
++.globl platformsetup
++platformsetup:
++/* register allocations
++ * r0 - delay counter and scratch
++ * r1 - address register
++ * r2 - data register
++ * r3 - index to table pointer
++ * r4 - iteration counter.
++ *
++ * r5 - hold return address.
++ * lr - (R14) link register
++ * pc - (R15) program counter.
++ */
++
++#ifdef INITIALISE_SDRAM
++/*
++ * Check that not in SDRAM execution. Suicide if re-initialise DRAM.
++ * Controller function is linked to execute in SDRAM must be in ROM if not
++ * there. Check for wrong place.
++ */
++ adrl r0, platformsetup /* Relative location of function start.*/
++ ldr r1, _platformsetup
++ cmp r0, r1
++ moveq pc, lr
++#else
++ mov pc, lr
++#endif
++
++ /* Establish a working setup for the SDRAM */
++ mov r6, lr
++
++#ifdef OXNAS_OVERCLOCK
++ /* Delay so the broken JTAG can get control */
++ ldr r0, =DELAY_1S
++ bl delay
++
++ /* Configure the PLL to run faster */
++ ldr r1, =SYS_CTRL_PLLSYS_CTRL
++ ldr r2, =SYS_CTRL_PLLSYS_KEY_CTRL
++
++ /* 0xBEADFACE -> PLL_KEY */
++ /* Bypass PLL */
++ ldr r3, [r1]
++ ldr r5, =0x20000
++ orr r3, r3, r5
++ ldr r4, =0xbeadface
++ str r4, [r2]
++ str r3, [r1]
++
++ /* 0xBEADFACE -> PLL_KEY */
++ /* Set m,p and s for PLL at 400MHz */
++ ldr r5, =0xffff0000
++ and r3, r3, r5
++ ldr r5, =OXNAS_OVERCLOCK
++ orr r3, r3, r5
++ str r4, [r2]
++ str r3, [r1]
++
++ /* Wait at least 300uS */
++ ldr r0, =DELAY_200US
++ bl delay
++ ldr r0, =DELAY_200US
++ bl delay
++
++ /* 0xBEADFACE -> PLL_KEY */
++ /* Disable PLL bypass */
++ ldr r5, =0xfffdffff
++ and r3, r3, r5
++ str r4, [r2]
++ str r3, [r1]
++#endif // OXNAS_OVERCLOCK
++
++ /* Assert reset to the DDR core */
++ ldr r0, =SYS_CTRL_RSTEN_SET_CTRL
++ ldr r1, =1
++ ldr r2, =SYS_CTRL_RSTEN_DDR_BIT
++ mov r1, r1, LSL r2
++ str r1, [r0]
++
++ /* Deassert reset to the DDR core */
++ ldr r0, =SYS_CTRL_RSTEN_CLR_CTRL
++ str r1, [r0]
++
++ /* Turn on the DDR core clock */
++ ldr r0, =SYS_CTRL_CKEN_SET_CTRL
++ ldr r1, =1
++ ldr r2, =SYS_CTRL_CKEN_DDR_BIT
++ mov r1, r1, LSL r2
++ str r1, [r0]
++
++ /* Start using the initialisation value list */
++ adrl r3, init_table
++
++ /* Copy next 6 entries from DDR init table*/
++ ldr r4, =6
++loop0:
++ ldmia r3!, {r1, r2}
++ str r2, [r1]
++ subs r4, r4, #1
++ bne loop0
++
++ /* Delay for 200uS while DRAM controller stabilises. */
++ ldr r0, =DELAY_200US
++ bl delay
++
++#if !TEST_BRD
++ /* Copy next entry */
++ ldr r4, =1
++loopx:
++ ldmia r3!, {r1, r2}
++ str r2, [r1]
++ subs r4, r4, #1
++ bne loopx
++
++ /* Delay for 200uS while DRAM controller stabilises. */
++ ldr r0, =DELAY_200US
++ bl delay
++#endif // TEST_BRD
++
++ /* Copy next entry */
++ ldr r4, =1
++loop1:
++ ldmia r3!, {r1, r2}
++ str r2, [r1]
++ subs r4, r4, #1
++ bne loop1
++
++ /* Delay for 200uS while DRAM controller stabilises. */
++ ldr r0, =DELAY_200US
++ bl delay
++
++ /* Copy next entry */
++ ldr r4, =1
++loop2:
++ ldmia r3!, {r1, r2}
++ str r2, [r1]
++ subs r4, r4, #1
++ bne loop2
++
++ /* Delay for 200uS while DRAM controller stabilises. */
++ ldr r0, =DELAY_200US
++ bl delay
++
++ /* Copy next entry */
++ ldr r4, =1
++loop3:
++ ldmia r3!, {r1, r2}
++ str r2, [r1]
++ subs r4, r4, #1
++ bne loop3
++
++ /* Delay for 200uS while DRAM controller stabilises. */
++ ldr r0, =DELAY_200US
++ bl delay
++
++ /* Copy next 5 entries */
++ ldr r4, =5
++loop4:
++ ldmia r3!, {r1, r2}
++ str r2, [r1]
++ subs r4, r4, #1
++ bne loop4
++
++ /* SDRAM initialised so now exit. */
++ mov lr, r6
++ mov pc, lr
++
++/*
++ * delay()
++ *
++ * uses 1 + r0 * 5 cycles
++ */
++delay:
++ nop
++ nop
++ nop
++ subs r0, r0, #1
++ bne delay
++ mov pc, lr
++
++_platformsetup:
++ .word platformsetup
++
++init_table:
++ /* Table of address, data for loading into the DRAM controller */
++ /* Configure for a single DDR device */
++ .word 0x4500002C, 0x08
++ .word 0x45000038, 0x400
++ .word 0x45800000, 0x80100000
++ .word 0x45800004, 0x8000ffff // Enable DDR core and all clients
++ .word 0x45800024, 0x1e4
++ .word 0x45800014, 0xe0000001 // DLL to automatic with starting value=1
++/* 200uS delay */
++#if !TEST_BRD
++ .word 0x45800014, 0xa0000003 // DLL to automatic with offset value=3
++/* 200uS delay */
++#endif // TEST_BRD
++#if (MEM_SIZE == 32)
++ .word 0x45800000, 0x801B030C
++#else
++ .word 0x45800000, 0x801D030C
++#endif // MEM_SIZE
++/* 200uS delay */
++ .word 0x4580000c, 0x80280400
++/* 200uS delay */
++ .word 0x4580000c, 0x80210000
++/* 200uS delay */
++ .word 0x4580000c, 0x80200063
++ .word 0x45800028, 0x0000001f // Enable all arbiter features
++ .word 0x45800018, 0x00000000 // Disable all monitoring
++ .word 0x45800010, 0xffffffff // Disable all read buffering, due to h/w bug
++ .word 0x4580002C, 0x00000000 // Do NOT disable HPROT, ie want write coherency
++
++.ltorg
++
+diff -Nurd u-boot-1.1.2/board/oxnas/platform-810.S u-boot-1.1.2-oxe810/board/oxnas/platform-810.S
+--- u-boot-1.1.2/board/oxnas/platform-810.S 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-1.1.2-oxe810/board/oxnas/platform-810.S 2008-06-11 17:55:18.000000000 +0200
+@@ -0,0 +1,477 @@
++/*
++ * Board specific setup info
++ *
++ * (C) Copyright 2005
++ * Oxford Semiconductor Ltd
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * 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 <config.h>
++#include <version.h>
++
++/* use estimate of processor speed to calculate number of cycles delay */
++/* delay count is nominal (PLL200 frequency x delay time) / loop count
++ * expressing 200us as 200/1000000 and re-arranging gives the expression below
++ */
++
++#define DELAY_200US ((NOMINAL_ARMCLK / (5 * 1000000)) * 200)
++#define DELAY_300US ((NOMINAL_ARMCLK / (5 * 1000000)) * 300)
++/* this is 8 cycles of ? so choose 8 resulting in 40 cycles */
++#define DELAY_1S ((DELAY_200US) * 5000)
++#define DELAY_8 8
++#define DELAY_200 200
++
++
++.globl platformsetup
++platformsetup:
++/* register allocations
++ * r0 - delay counter and scratch
++ * r1 - address register
++ * r2 - data register
++ * r3 - index to table pointer
++ * r4 - iteration counter.
++ *
++ * r5 - hold return address.
++ * lr - (R14) link register
++ * pc - (R15) program counter.
++ */
++
++#ifdef INITIALISE_SDRAM
++/*
++ * Check that not in SDRAM execution. Suicide if re-initialise DRAM.
++ * Controller function is linked to execute in SDRAM must be in ROM if not
++ * there. Check for wrong place.
++ */
++ adrl r0, platformsetup /* Relative location of function start.*/
++ ldr r1, _platformsetup
++ cmp r0, r1
++ moveq pc, lr
++#else
++ mov pc, lr
++#endif
++
++#if (FPGA == 1)
++ /* Establish a working setup for the SDRAM */
++ mov r6, lr
++
++ /* Assert reset to the DDR core */
++ ldr r0, =SYS_CTRL_RSTEN_SET_CTRL
++ ldr r1, =1
++ ldr r2, =SYS_CTRL_RSTEN_DDR_BIT
++ mov r1, r1, LSL r2
++ str r1, [r0]
++
++ /* Deassert reset to the DDR core */
++ ldr r0, =SYS_CTRL_RSTEN_CLR_CTRL
++ str r1, [r0]
++
++ /* Turn on the DDR core clock */
++ ldr r0, =SYS_CTRL_CKEN_SET_CTRL
++ ldr r1, =1
++ ldr r2, =SYS_CTRL_CKEN_DDR_BIT
++ mov r1, r1, LSL r2
++ str r1, [r0]
++
++ /* Start using the initialisation value list */
++ adrl r3, init_table
++
++ /* Copy first 6 entries */
++ ldr r4, =6
++loop0:
++ ldmia r3!, {r1, r2}
++ str r2, [r1]
++ subs r4, r4, #1
++ bne loop0
++
++ /* Delay for 200uS while DRAM controller stabilises. */
++ ldr r0, =DELAY_200US
++ bl delay
++
++ /* Copy next 4 entries */
++ ldr r4, =4
++loop1:
++ ldmia r3!, {r1, r2}
++ str r2, [r1]
++ subs r4, r4, #1
++ bne loop1
++
++ /* Wait at least 200 clock cycles. */
++ ldr r0, =DELAY_200
++ bl delay
++
++ /* Copy next 2 entries */
++ ldr r4, =2
++loop2:
++ ldmia r3!, {r1, r2}
++ str r2, [r1]
++ subs r4, r4, #1
++ bne loop2
++
++ /* Wait at least 8 clock cycles. */
++ ldr r0, =DELAY_8
++ bl delay
++
++ /* Copy next 9 entries */
++ ldr r4, =9
++loop3:
++ ldmia r3!, {r1, r2}
++ str r2, [r1]
++ subs r4, r4, #1
++ bne loop3
++
++ /* SDRAM initialised so now exit. */
++ mov lr, r6
++ mov pc, lr
++
++/*
++ * delay()
++ *
++ * uses 1 + r0 * 5 cycles
++ */
++delay:
++ nop
++ nop
++ nop
++ subs r0, r0, #1
++ bne delay
++ mov pc, lr
++
++_platformsetup:
++ .word platformsetup
++#else // ASIC, (DDR-2)
++/*
++ * Check that not in SDRAM execution. Suicide if re-initialise DRAM.
++ * Controller function is linked to execute in SDRAM must be in ROM if not
++ * there. Check for wrong place.
++ */
++ /* Establish a working setup for the SDRAM */
++ mov r6, lr
++
++#ifdef OVERCLOCK
++ /*
++ change clock speed on chip
++ */
++
++ /* read SYS_CTRL_PLLSYS_CTRL into r3*/
++ mov r5, #0x45000000
++ ldr r3, [r5, #72]
++
++ /* load the value at dllkey (0xbeadface) into r7 */
++ adrl r7, dllkey
++ ldr r7, [r7]
++
++ /* pll_sys |= 0x20000; */
++ orr r3, r3, #131072 /* 0x20000 */
++
++ /* write 0xbeadface into SYS_CTRL_PLLSYS_KEY_CTRL */
++ str r7, [r5, #108]
++
++ /* write pll_sys (bypass pll)*/
++ str r3, [r5, #72]
++
++ /* pll_sys &= 0xff000000; */
++ mov r4, r3, lsr #16
++ mov r4, r4, lsl #16
++
++ /* pll_sys |= 0x00F00061 */
++ orr r4, r4, #15728640 /* 0xf00000 */
++ orr r4, r4, #97 /* 0x61 */
++#if 0
++ orr r4, r4, #7864320 /* 0x780000 */
++ orr r4, r4, #96 /* 0x60 */
++#endif
++
++ /* write 0xbeadface into SYS_CTRL_PLLSYS_KEY_CTRL */
++ str r7, [r5, #108]
++
++ /* write pll_sys (with new pll speeds) */
++ str r4, [r5, #72]
++
++ /* delay 300us */
++ ldr r0, =DELAY_300US
++ bl delay
++
++ /* clear bypass pll bit */
++ bic r4, r4, #131072 /* 0x20000 */
++
++ /* write 0xbeadface into SYS_CTRL_PLLSYS_KEY_CTRL */
++ str r7, [r5, #108]
++
++ /* write pll_sys (with new pll speeds and pll un-bypassed) */
++ str r4, [r5, #72]
++#endif /* OVERCLOCK */
++
++ /* Turn on the DDR core and phy clocks */
++ ldr r0, =SYS_CTRL_CKEN_SET_CTRL
++ ldr r1, =1
++ ldr r2, =SYS_CTRL_CKEN_DDR_BIT
++ mov r1, r1, LSL r2
++ str r1, [r0]
++ ldr r1, =1
++ ldr r2, =SYS_CTRL_CKEN_DDR_PHY_BIT
++ mov r1, r1, LSL r2
++ str r1, [r0]
++
++ /* Assert reset to the DDR core and phy */
++ ldr r0, =SYS_CTRL_RSTEN_SET_CTRL
++ ldr r1, =1
++ ldr r2, =SYS_CTRL_RSTEN_DDR_PHY_BIT
++ mov r1, r1, LSL r2
++ str r1, [r0]
++ ldr r1, =1
++ ldr r2, =SYS_CTRL_RSTEN_DDR_BIT
++ mov r1, r1, LSL r2
++ str r1, [r0]
++
++ /* Deassert reset to the DDR core and phy*/
++ ldr r0, =SYS_CTRL_RSTEN_CLR_CTRL
++ ldr r1, =1
++ ldr r2, =SYS_CTRL_RSTEN_DDR_PHY_BIT
++ mov r1, r1, LSL r2
++ str r1, [r0]
++ ldr r1, =1
++ ldr r2, =SYS_CTRL_RSTEN_DDR_BIT
++ mov r1, r1, LSL r2
++ str r1, [r0]
++
++ /* Start using the initialisation value list */
++ adrl r3, init_table
++
++ /* Copy first 14 entries of DDR core setup (section A)*/
++ ldr r4, =14
++loop0:
++ ldmia r3!, {r1, r2}
++ str r2, [r1]
++ subs r4, r4, #1
++ bne loop0
++
++ /* Delay for 200uS while DDR controller stabilises. */
++ ldr r0, =DELAY_200US
++ bl delay
++
++ /* Copy next 13 entries of DDR device commands (section B)*/
++ ldr r4, =13
++loop1:
++ ldmia r3!, {r1, r2}
++ str r2, [r1]
++
++ /* Wait at least 200 clock cycles between ram chip command writes */
++ ldr r0, =DELAY_200
++ bl delay
++
++ subs r4, r4, #1
++ bne loop1
++
++ /* Copy final DDR controller setup to set memory size/banks (section C)*/
++ ldmia r3!, {r1, r2}
++ str r2, [r1]
++
++#if (PROBE_MEM_SIZE == 1)
++ /* Load the probe values into SDRAM */
++ adrl r3, probe_table
++ mov r4, #4
++.globl pl1
++pl1:
++ ldmia r3!, {r1, r2}
++ str r2, [r1]
++ subs r4, r4, #1
++ bne pl1
++
++ /* Get the current contents of the DDR controller core's config register */
++ adrl r1, ddr_config_reg
++ ldr r1, [r1]
++ ldr r1, [r1]
++
++ /* Zero the number of banks field - bit 23*/
++ mov r2, #1
++ bic r1, r1, r2, lsl #23
++
++ /* Zero the size field - bits 17-20 inclusive */
++ mov r2, #15
++ bic r1, r1, r2, lsl #17
++
++ /* First probe location tells us the SDRAM size */
++ adrl r3, probe_table
++ ldr r0, [r3]
++ ldr r0, [r0]
++
++ /* Is size 64MB? */
++ ldr r2, [r3, #28] /* Get probe value 4 */
++ cmp r0, r2
++ moveq r4, #6
++ orreq r1, r1, r4, lsl #17
++ beq pl2
++
++ /* Is 128M or 256M so set banks to 8 */
++ mov r4, #1
++ orr r1, r1, r4, lsl #23
++
++ /* Is size 128MB? */
++ ldr r2, [r3, #20] /* Get probe value 3 */
++ cmp r0, r2
++// moveq r4, #7
++ moveq r4, #8 /* DDR controller does not work at 128M, use 256M instead
++ orreq r1, r1, r4, lsl #17
++ beq pl2
++
++ /* Must be 256MB, or something is very wrong */
++ mov r4, #8
++ orr r1, r1, r4, lsl #17
++
++pl2:
++ /* Write the revised contents to the DDR controller core's config register */
++ adrl r2, ddr_config_reg
++ ldr r2, [r2]
++ str r1, [r2]
++#endif
++
++ /* SDRAM setup complete */
++ mov lr, r6
++ mov pc, lr
++
++/*
++ * delay()
++ *
++ * uses 1 + r0 * 5 cycles
++ */
++delay:
++ nop
++ nop
++ nop
++ subs r0, r0, #1
++ bne delay
++ mov pc, lr
++
++_platformsetup:
++ .word platformsetup
++#endif
++
++
++init_table:
++#if (FPGA == 1)
++ /* Table of address, data for loading into the DRAM controller on FPGA */
++ .word 0x45800000, 0x000d0000 // Enable the DDR in SDR mode and width 32 bits
++ .word 0x45800034, 0x04442032 // SDR mode timings - #0
++ .word 0x45800038, 0x570A0907 // SDR mode timings - #1
++ .word 0x4580003C, 0x00000002 // SDR mode timings - #2
++ .word 0x45800004, 0x80000000 // Enable DDR core, but not clients yet
++ .word 0x45800014, 0x80000001 // Enable CK and set DLL mode to manual
++/* 200uS delay */
++ .word 0x4580000c, 0x80200000 // Assert CKE for all further commands
++ .word 0x4580000c, 0x80280400 // Issue precharge to all banks
++ .word 0x4580000c, 0x80200000 // NOP, as only DDR has real command here
++ .word 0x4580000c, 0x80200022 // Set burst length 4, sequential CAS 2
++/* 200uS delay */
++ .word 0x4580000c, 0x80280400 // Issue precharge to all banks
++ .word 0x4580000c, 0x80240000 // Issue auto-refresh command, CKE not asserted
++/* 200uS delay */
++ .word 0x4580000c, 0x80240000 // Issue auto-refresh command, CKE not asserted
++ .word 0x4580000c, 0x80200000 // Assert CKE for all further commands
++ .word 0x4580000c, 0x80200022 // Set burst length 4, sequential CAS 2
++ .word 0x45800000, 0x000d0186 // SDR, size and width and refresh rate, assuming
++ // 25Mhz clk to SDR, divide down to get 15.625uS
++ // refresh rate
++ .word 0x45800024, 0x00000124 // Set I/O drive strengths
++ .word 0x45800028, 0x0000001f // Enable all arbiter features
++ .word 0x45800018, 0x00000000 // Disable all monitoring
++ .word 0x45800010, 0xFFFFFFFF // Disable all read buffering
++ .word 0x45800004, 0x800000ff // Enable all client interfaces
++#else // ASIC DDR-2
++ // SECTION A - DDR controller core configuration
++ .word 0x45800000, 0x802d0591 // enable in ddr-2 mode 16 bit wide
++ .word 0x45800034, 0x04442032 // ddr-2 mode timings
++ .word 0x45800038, 0x870f0b25 // ddr-2 mode timings
++ .word 0x4580003c, 0x00000a23 // ddr-2 mode timings
++ .word 0x45800054, 0x00072000 // phy-3 settings
++ .word 0x45800050, 0x00022828 // phy-2 settings, start
++ .word 0x45800050, 0x00032828 // phy-2 settings, on
++ .word 0x45800028, 0x0000001f // Enable all arbiter features
++ .word 0x45800018, 0x00000000 // Disable all monitoring
++ .word 0x45800010, 0xffff0000 // Enable all read buffering
++ .word 0x4580002c, 0x00ff00fd // no burst accl, no hprot on arm data
++ .word 0x45800040, 0x00000000 // enable burst and read cache
++ .word 0x45800044, 0xffff0000 // enable write behind prot, disable timeout
++ .word 0x45800004, 0x8000ffff // Enable all client interfaces
++/* 200uS delay after configuring DDR controller core */
++
++ // SECTION B - Memory device configuration
++ .word 0x4580000c, 0x807c0000 // exit something or other
++ .word 0x4580000c, 0x803c0000 // nop - wake up
++ .word 0x4580000c, 0x80280400 // precharge all
++ .word 0x4580000c, 0x80220000 // emr2
++ .word 0x4580000c, 0x80230000 // emr3
++
++#if (MEM_ODT == 150)
++ .word 0x4580000c, 0x80210042 // enable dll, odt to 150
++#elif (MEM_ODT == 75)
++ .word 0x4580000c, 0x80210006 // enable dll, odt to 75
++#elif (MEM_ODT == 50)
++ .word 0x4580000c, 0x80210046 // enable dll, odt to 50
++#else
++#error Unsupported memory on-die termination, set MEM_ODT to 50, 75, or 150
++#endif
++
++ .word 0x4580000c, 0x80200733 // set WR CL BL and reset dll
++ .word 0x4580000c, 0x80280400 // precharge all
++ .word 0x4580000c, 0x80240000 // auto refresh
++ .word 0x4580000c, 0x80240000 // auto refresh
++ .word 0x4580000c, 0x80200733 // set WR CL BL and reset dll
++
++#if (MEM_ODT == 150)
++ .word 0x4580000c, 0x802103c2 // enable OCD
++ .word 0x4580000c, 0x80210042 // disable OCD
++#elif (MEM_ODT == 75)
++ .word 0x4580000c, 0x80210386 // enable OCD
++ .word 0x4580000c, 0x80210006 // disable OCD
++#elif (MEM_ODT == 50)
++ .word 0x4580000c, 0x802103c6 // enable OCD
++ .word 0x4580000c, 0x80210046 // disable OCD
++#else
++#error Unsupported memory on-die termination, set MEM_ODT to 50, 75, or 150
++#endif
++
++ // SECTION C - Final memory size/bank configuration
++#if (PROBE_MEM_SIZE == 1)
++ .word 0x45800000, 0x80b10591 // 256M, 8 banks, 1425 clocks for 7.8us refresh.
++#elif (MEM_SIZE == 64)
++ .word 0x45800000, 0x802d0591 // 64M, 4 banks, 1425 clocks for 7.8us refresh.
++#elif (MEM_SIZE == 128)
++ .word 0x45800000, 0x80af0591 // 128M, 8 banks, 1425 clocks for 7.8us refresh.
++#elif (MEM_SIZE == 256)
++ .word 0x45800000, 0x80b10591 // 256M, 8 banks, 1425 clocks for 7.8us refresh.
++#else
++#error Unsupported memory size, set MEM_SIZE to 64, 128 or 256
++#endif
++
++#endif // FPGA or ASIC
++dllkey:
++ .word 0xbeadface
++
++ddr_config_reg:
++ .word 0x45800000
++
++probe_table:
++ .word 0x48000000, 0x12345678
++ .word 0x48000040, 0xdeadbeef
++ .word 0x50000000, 0xfafafafa
++ .word 0x50000040, 0xabcdef01
++
++.ltorg
++
+diff -Nurd u-boot-1.1.2/board/oxnas/u-boot.lds u-boot-1.1.2-oxe810/board/oxnas/u-boot.lds
+--- u-boot-1.1.2/board/oxnas/u-boot.lds 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-1.1.2-oxe810/board/oxnas/u-boot.lds 2008-06-11 17:55:18.000000000 +0200
+@@ -0,0 +1,50 @@
++/*
++ * (C) Copyright 2002
++ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * 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
++ */
++
++OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
++OUTPUT_ARCH(arm)
++ENTRY(_start)
++SECTIONS
++{
++ . = 0x00000000;
++ . = ALIGN(4);
++ .text :
++ {
++ cpu/arm926ejs/start.o (.text)
++ *(.text)
++ }
++ .rodata : { *(.rodata) }
++ . = ALIGN(4);
++ .data : { *(.data) }
++ . = ALIGN(4);
++ .got : { *(.got) }
++
++ __u_boot_cmd_start = .;
++ .u_boot_cmd : { *(.u_boot_cmd) }
++ __u_boot_cmd_end = .;
++
++ . = ALIGN(4);
++ __bss_start = .;
++ .bss : { *(.bss) }
++ _end = .;
++}
+diff -Nurd u-boot-1.1.2/common/cmd_ext2.c u-boot-1.1.2-oxe810/common/cmd_ext2.c
+--- u-boot-1.1.2/common/cmd_ext2.c 2004-12-16 18:34:53.000000000 +0100
++++ u-boot-1.1.2-oxe810/common/cmd_ext2.c 2008-06-11 17:55:30.000000000 +0200
+@@ -223,7 +223,7 @@
+ PRINTF("Using device %s%d, partition %d\n", argv[1], dev, part);
+
+ if (part != 0) {
+- if (get_partition_info (&dev_desc[dev], part, &info)) {
++ if (get_partition_info (dev_desc, part, &info)) {
+ printf ("** Bad partition %d **\n", part);
+ return(1);
+ }
+diff -Nurd u-boot-1.1.2/common/cmd_ide.c u-boot-1.1.2-oxe810/common/cmd_ide.c
+--- u-boot-1.1.2/common/cmd_ide.c 2004-12-31 10:32:50.000000000 +0100
++++ u-boot-1.1.2-oxe810/common/cmd_ide.c 2008-06-11 17:55:30.000000000 +0200
+@@ -193,6 +193,13 @@
+ static void set_pcmcia_timing (int pmode);
+ #endif
+
++#ifdef CONFIG_OXNAS
++extern unsigned char oxnas_sata_inb(int dev, int port);
++extern void oxnas_sata_outb(int dev, int port, unsigned char val);
++extern void oxnas_sata_output_data(int dev, ulong *sect_buf, int words);
++extern void oxnas_sata_input_data(int dev, ulong *sect_buf, int words);
++#endif // CONFIG_OXNAS
++
+ /* ------------------------------------------------------------------------- */
+
+ int do_ide (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+@@ -491,175 +498,103 @@
+ return rcode;
+ }
+
+-/* ------------------------------------------------------------------------- */
+
+-void ide_init (void)
++static int ide_probe(int device)
+ {
++ int found = 0;
++
++ /* Select device */
++ udelay(100000); /* 100 ms */
++ ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
++ udelay(100000); /* 100 ms */
+
+-#ifdef CONFIG_IDE_8xx_DIRECT
+- DECLARE_GLOBAL_DATA_PTR;
+- volatile immap_t *immr = (immap_t *)CFG_IMMR;
+- volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia);
+-#endif
+ unsigned char c;
+- int i, bus;
+-#ifdef CONFIG_AMIGAONEG3SE
+- unsigned int max_bus_scan;
+- unsigned int ata_reset_time;
+- char *s;
++ int i = 0;
++ do {
++ udelay(10000); /* 10 ms */
++
++ c = ide_inb(device, ATA_STATUS);
++ if (++i > (ATA_RESET_TIME * 100)) {
++ PRINTF("ide_probe() timeout\n");
++ ide_led((LED_IDE1 | LED_IDE2), 0); /* LED's off */
++ return found;
++ }
++ if ((i >= 100) && ((i%100) == 0)) {
++ putc ('.');
++ }
++ } while (c & ATA_STAT_BUSY);
++
++ if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) {
++ PRINTF("ide_probe() status = 0x%02X ", c);
++#ifndef CONFIG_ATAPI /* ATAPI Devices do not set DRDY */
++ } else if ((c & ATA_STAT_READY) == 0) {
++ PRINTF("ide_probe() status = 0x%02X ", c);
+ #endif
+-#ifdef CONFIG_IDE_8xx_PCCARD
+- extern int pcmcia_on (void);
+- extern int ide_devices_found; /* Initialized in check_ide_device() */
+-#endif /* CONFIG_IDE_8xx_PCCARD */
++ } else {
++ found = 1;
++ }
+
+-#ifdef CONFIG_IDE_PREINIT
+- extern int ide_preinit (void);
+- WATCHDOG_RESET();
++ return found;
++}
+
+- if (ide_preinit ()) {
+- puts ("ide_preinit failed\n");
++void ide_init(void)
++{
++ static int ide_init_called = 0;
++ int i, bus;
++
++ if (ide_init_called) {
+ return;
+ }
+-#endif /* CONFIG_IDE_PREINIT */
+-
+-#ifdef CONFIG_IDE_8xx_PCCARD
+- extern int pcmcia_on (void);
+- extern int ide_devices_found; /* Initialized in check_ide_device() */
++ ide_init_called = 1;
+
++#ifdef CONFIG_IDE_PREINIT
++ extern int ide_preinit(void);
+ WATCHDOG_RESET();
+
+- ide_devices_found = 0;
+- /* initialize the PCMCIA IDE adapter card */
+- pcmcia_on();
+- if (!ide_devices_found)
++ printf("Initialising disks\n");
++ if (ide_preinit()) {
++ puts ("ide_preinit failed\n");
+ return;
+- udelay (1000000); /* 1 s */
+-#endif /* CONFIG_IDE_8xx_PCCARD */
++ }
++#endif /* CONFIG_IDE_PREINIT */
+
+ WATCHDOG_RESET();
+
+-#ifdef CONFIG_IDE_8xx_DIRECT
+- /* Initialize PIO timing tables */
+- for (i=0; i <= IDE_MAX_PIO_MODE; ++i) {
+- pio_config_clk[i].t_setup = PCMCIA_MK_CLKS(pio_config_ns[i].t_setup,
+- gd->bus_clk);
+- pio_config_clk[i].t_length = PCMCIA_MK_CLKS(pio_config_ns[i].t_length,
+- gd->bus_clk);
+- pio_config_clk[i].t_hold = PCMCIA_MK_CLKS(pio_config_ns[i].t_hold,
+- gd->bus_clk);
+- PRINTF ("PIO Mode %d: setup=%2d ns/%d clk"
+- " len=%3d ns/%d clk"
+- " hold=%2d ns/%d clk\n",
+- i,
+- pio_config_ns[i].t_setup, pio_config_clk[i].t_setup,
+- pio_config_ns[i].t_length, pio_config_clk[i].t_length,
+- pio_config_ns[i].t_hold, pio_config_clk[i].t_hold);
+- }
+-#endif /* CONFIG_IDE_8xx_DIRECT */
+-
+ /* Reset the IDE just to be sure.
+ * Light LED's to show
+ */
+- ide_led ((LED_IDE1 | LED_IDE2), 1); /* LED's on */
+- ide_reset (); /* ATAPI Drives seems to need a proper IDE Reset */
+-
+-#ifdef CONFIG_IDE_8xx_DIRECT
+- /* PCMCIA / IDE initialization for common mem space */
+- pcmp->pcmc_pgcrb = 0;
+-
+- /* start in PIO mode 0 - most relaxed timings */
+- pio_mode = 0;
+- set_pcmcia_timing (pio_mode);
+-#endif /* CONFIG_IDE_8xx_DIRECT */
++ ide_led((LED_IDE1 | LED_IDE2), 1); /* LED's on */
++ ide_reset(); /* ATAPI Drives seems to need a proper IDE Reset */
+
+ /*
+ * Wait for IDE to get ready.
+ * According to spec, this can take up to 31 seconds!
+ */
+-#ifndef CONFIG_AMIGAONEG3SE
+- for (bus=0; bus<CFG_IDE_MAXBUS; ++bus) {
+- int dev = bus * (CFG_IDE_MAXDEVICE / CFG_IDE_MAXBUS);
+-#else
+- s = getenv("ide_maxbus");
+- if (s)
+- max_bus_scan = simple_strtol(s, NULL, 10);
+- else
+- max_bus_scan = CFG_IDE_MAXBUS;
+-
+- for (bus=0; bus<max_bus_scan; ++bus) {
+- int dev = bus * (CFG_IDE_MAXDEVICE / max_bus_scan);
+-#endif
+-
+-#ifdef CONFIG_IDE_8xx_PCCARD
+- /* Skip non-ide devices from probing */
+- if ((ide_devices_found & (1 << bus)) == 0) {
+- ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */
+- continue;
+- }
+-#endif
+- printf ("Bus %d: ", bus);
+-
+- ide_bus_ok[bus] = 0;
+-
+- /* Select device
+- */
+- udelay (100000); /* 100 ms */
+- ide_outb (dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(dev));
+- udelay (100000); /* 100 ms */
+-#ifdef CONFIG_AMIGAONEG3SE
+- ata_reset_time = ATA_RESET_TIME;
+- s = getenv("ide_reset_timeout");
+- if (s) ata_reset_time = 2*simple_strtol(s, NULL, 10);
+-#endif
+- i = 0;
+- do {
+- udelay (10000); /* 10 ms */
+-
+- c = ide_inb (dev, ATA_STATUS);
+- i++;
+-#ifdef CONFIG_AMIGAONEG3SE
+- if (i > (ata_reset_time * 100)) {
+-#else
+- if (i > (ATA_RESET_TIME * 100)) {
+-#endif
+- puts ("** Timeout **\n");
+- ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */
+-#ifdef CONFIG_AMIGAONEG3SE
+- /* If this is the second bus, the first one was OK */
+- if (bus != 0) {
+- ide_bus_ok[bus] = 0;
+- goto skip_bus;
+- }
+-#endif
+- return;
+- }
+- if ((i >= 100) && ((i%100)==0)) {
+- putc ('.');
+- }
+- } while (c & ATA_STAT_BUSY);
++ printf("Detecting SATA busses:\n");
++ for (bus=0; bus < CFG_IDE_MAXBUS; ++bus) {
++ printf("Bus %d: ", bus);
+
+- if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) {
+- puts ("not available ");
+- PRINTF ("Status = 0x%02X ", c);
+-#ifndef CONFIG_ATAPI /* ATAPI Devices do not set DRDY */
+- } else if ((c & ATA_STAT_READY) == 0) {
+- puts ("not available ");
+- PRINTF ("Status = 0x%02X ", c);
+-#endif
+- } else {
+- puts ("OK ");
+- ide_bus_ok[bus] = 1;
+- }
+- WATCHDOG_RESET();
+- }
++ /* Try to discover if bus is present by probing first device on bus */
++ int device = bus * (CFG_IDE_MAXDEVICE / CFG_IDE_MAXBUS);
++ ide_bus_ok[bus] = ide_probe(device);
++ if (ide_bus_ok[bus]) {
++ puts("Found first device OK\n");
++ } else {
++ WATCHDOG_RESET();
++
++ /* Try second device on bus */
++ ide_bus_ok[bus] = ide_probe(++device);
++ if (ide_bus_ok[bus]) {
++ puts("Found second device OK\n");
++ } else {
++ puts("No devices found\n");
++ }
++ }
+
+-#ifdef CONFIG_AMIGAONEG3SE
+- skip_bus:
+-#endif
+- putc ('\n');
++ WATCHDOG_RESET();
++ }
+
+- ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */
++ ide_led((LED_IDE1 | LED_IDE2), 0); /* LED's off */
+
+ curr_device = -1;
+ for (i=0; i<CFG_IDE_MAXDEVICE; ++i) {
+@@ -675,13 +610,12 @@
+ ide_dev_desc[i].block_read=ide_read;
+ if (!ide_bus_ok[IDE_BUS(i)])
+ continue;
+- ide_led (led, 1); /* LED on */
++ ide_led(led, 1); /* LED on */
+ ide_ident(&ide_dev_desc[i]);
+- ide_led (led, 0); /* LED off */
++ ide_led(led, 0); /* LED off */
+ dev_print(&ide_dev_desc[i]);
+-/* ide_print (i); */
+ if ((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) {
+- init_part (&ide_dev_desc[i]); /* initialize partition type */
++ init_part(&ide_dev_desc[i]); /* initialize partition type */
+ if (curr_device < 0)
+ curr_device = i;
+ }
+@@ -689,6 +623,11 @@
+ WATCHDOG_RESET();
+ }
+
++int is_device_present(int device_number)
++{
++ return ide_dev_desc[device_number].part_type != PART_TYPE_UNKNOWN;
++}
++
+ /* ------------------------------------------------------------------------- */
+
+ block_dev_desc_t * ide_get_dev(int dev)
+@@ -798,6 +737,11 @@
+ EIEIO;
+ *((uchar *)(ATA_CURR_BASE(dev)+port)) = val;
+ }
++#elif defined(CONFIG_OXNAS)
++static void __inline__ ide_outb(int dev, int port, unsigned char val)
++{
++ oxnas_sata_outb(dev, port, val);
++}
+ #else /* ! __PPC__ */
+ static void __inline__
+ ide_outb(int dev, int port, unsigned char val)
+@@ -819,6 +763,11 @@
+ dev, port, (ATA_CURR_BASE(dev)+port), val);
+ return (val);
+ }
++#elif defined(CONFIG_OXNAS)
++static unsigned char __inline__ ide_inb(int dev, int port)
++{
++ return oxnas_sata_inb(dev, port);
++}
+ #else /* ! __PPC__ */
+ static unsigned char __inline__
+ ide_inb(int dev, int port)
+@@ -921,6 +870,11 @@
+ }
+ #endif /* CONFIG_HMI10 */
+ }
++#elif defined(CONFIG_OXNAS)
++static void output_data(int dev, ulong *sect_buf, int words)
++{
++ oxnas_sata_output_data(dev, sect_buf, words);
++}
+ #else /* ! __PPC__ */
+ static void
+ output_data(int dev, ulong *sect_buf, int words)
+@@ -968,6 +922,11 @@
+ }
+ #endif /* CONFIG_HMI10 */
+ }
++#elif defined(CONFIG_OXNAS)
++static void input_data(int dev, ulong *sect_buf, int words)
++{
++ oxnas_sata_input_data(dev, sect_buf, words);
++}
+ #else /* ! __PPC__ */
+ static void
+ input_data(int dev, ulong *sect_buf, int words)
+@@ -1001,10 +960,36 @@
+
+ /* -------------------------------------------------------------------------
+ */
++#ifdef CONFIG_OXNAS
++static void byte_swap_and_trim(char* buf)
++{
++ char *src = buf;
++
++ // Swap bytes in 16-bit words
++ while ((*src != '\0') && (*(src+1) != '\0')) {
++ char tmp = *(src+1);
++ *(src+1) = *src;
++ *src = tmp;
++ src += 2;
++ }
++
++ // Trim leading spaces
++ src = buf;
++ while (*src == ' ') {
++ ++src;
++ }
++ if (src != buf) {
++ memcpy(buf, src, strlen(src));
++ buf[strlen(buf) - (src-buf)] = '\0';
++ }
++}
++#endif // CONFIG_OXNAS
++
+ static void ide_ident (block_dev_desc_t *dev_desc)
+ {
+ ulong iobuf[ATA_SECTORWORDS];
+ unsigned char c;
++ unsigned int i;
+ hd_driveid_t *iop = (hd_driveid_t *)iobuf;
+
+ #ifdef CONFIG_AMIGAONEG3SE
+@@ -1023,6 +1008,10 @@
+ device=dev_desc->dev;
+ printf (" Device %d: ", device);
+
++ for ( i=0; i < ATA_SECTORWORDS; ++i) {
++ iobuf[i] = 0;
++ }
++
+ #ifdef CONFIG_AMIGAONEG3SE
+ s = getenv("ide_maxbus");
+ if (s) {
+@@ -1110,20 +1099,22 @@
+
+ input_swap_data (device, iobuf, ATA_SECTORWORDS);
+
+- ident_cpy (dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision));
+- ident_cpy (dev_desc->vendor, iop->model, sizeof(dev_desc->vendor));
+- ident_cpy (dev_desc->product, iop->serial_no, sizeof(dev_desc->product));
++ ident_cpy(dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision));
++ ident_cpy(dev_desc->vendor, iop->model, sizeof(dev_desc->vendor));
++ ident_cpy(dev_desc->product, iop->serial_no, sizeof(dev_desc->product));
++
+ #ifdef __LITTLE_ENDIAN
+ /*
+- * firmware revision and model number have Big Endian Byte
++ * firmware revision, model number and product have Big Endian Byte
+ * order in Word. Convert both to little endian.
+ *
+ * See CF+ and CompactFlash Specification Revision 2.0:
+ * 6.2.1.6: Identfy Drive, Table 39 for more details
+ */
+
+- strswab (dev_desc->revision);
+- strswab (dev_desc->vendor);
++ byte_swap_and_trim(dev_desc->revision);
++ byte_swap_and_trim(dev_desc->vendor);
++ byte_swap_and_trim(dev_desc->product);
+ #endif /* __LITTLE_ENDIAN */
+
+ if ((iop->config & 0x0080)==0x0080)
+diff -Nurd u-boot-1.1.2/common/cmd_ledfail.c u-boot-1.1.2-oxe810/common/cmd_ledfail.c
+--- u-boot-1.1.2/common/cmd_ledfail.c 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-1.1.2-oxe810/common/cmd_ledfail.c 2008-06-11 17:55:30.000000000 +0200
+@@ -0,0 +1,58 @@
++
++#include <common.h>
++#include <command.h>
++
++#if (CONFIG_COMMANDS & CFG_CMD_LEDFAIL)
++#define FAILURE_LED (1 << (34-32))
++
++#define GPIO_B 0x44100000
++#define WARN_GPIO_OUT_REG (GPIO_B + 0x10)
++#define WARN_GPIO_OUT_ENABLE_SET (GPIO_B + 0x1C)
++#define WARN_GPIO_OUT_ENABLE_CLR (GPIO_B + 0x20)
++
++static void ledfail_light(void)
++{
++ printf("Light LED\n");
++ /* Light the failure LED - assumes active low drive */
++ u_int32_t led_state = *((volatile u_int32_t *)WARN_GPIO_OUT_REG);
++ led_state = led_state & ~FAILURE_LED;
++ *((volatile u_int32_t *)WARN_GPIO_OUT_REG) = led_state;
++
++ /* Enable GPIO for output */
++ *((volatile u_int32_t *)WARN_GPIO_OUT_ENABLE_SET) = FAILURE_LED;
++}
++
++static void ledfail_extinguish(void)
++{
++ printf("Extinguish LED\n");
++ /* Extinguish the failure LED - assumes active low drive */
++ u_int32_t led_state = *((volatile u_int32_t *)WARN_GPIO_OUT_REG);
++ led_state = led_state | FAILURE_LED;
++ *((volatile u_int32_t *)WARN_GPIO_OUT_REG) = led_state;
++
++ /* Clear the failure bit output enable in GPIO's */
++ *((volatile u_int32_t *)WARN_GPIO_OUT_ENABLE_CLR) = FAILURE_LED;
++}
++
++int do_ledfail(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
++{
++ if (argc != 2) {
++ printf ("Usage:\n%s\n", cmdtp->usage);
++ return 1;
++ }
++
++ ulong arg = simple_strtoul(argv[1], NULL, 10);
++ switch (arg) {
++ case 0:
++ ledfail_extinguish();
++ break;
++ case 1:
++ ledfail_light();
++ break;
++ }
++
++ return 0;
++}
++
++U_BOOT_CMD(ledfail, 2, 2, do_ledfail, "ledfail - Extinguish (0) or light (1) failure LED\n", NULL);
++#endif /* CFG_CMD_LEDFAIL */
+diff -Nurd u-boot-1.1.2/common/cmd_mem.c u-boot-1.1.2-oxe810/common/cmd_mem.c
+--- u-boot-1.1.2/common/cmd_mem.c 2004-12-16 18:42:39.000000000 +0100
++++ u-boot-1.1.2-oxe810/common/cmd_mem.c 2008-06-11 17:55:30.000000000 +0200
+@@ -731,13 +731,17 @@
+ if (argc > 1) {
+ start = (ulong *)simple_strtoul(argv[1], NULL, 16);
+ } else {
+- start = (ulong *)CFG_MEMTEST_START;
++ DECLARE_GLOBAL_DATA_PTR;
++
++ start = (ulong *)(gd->bd->bi_dram[0].start);
+ }
+
+ if (argc > 2) {
+ end = (ulong *)simple_strtoul(argv[2], NULL, 16);
+ } else {
+- end = (ulong *)(CFG_MEMTEST_END);
++ DECLARE_GLOBAL_DATA_PTR;
++
++ end = (ulong *)(start + gd->bd->bi_dram[0].size);
+ }
+
+ if (argc > 3) {
+diff -Nurd u-boot-1.1.2/common/cmd_nvedit.c u-boot-1.1.2-oxe810/common/cmd_nvedit.c
+--- u-boot-1.1.2/common/cmd_nvedit.c 2004-09-30 00:55:14.000000000 +0200
++++ u-boot-1.1.2-oxe810/common/cmd_nvedit.c 2008-06-11 17:55:30.000000000 +0200
+@@ -55,8 +55,9 @@
+ !defined(CFG_ENV_IS_IN_FLASH) && \
+ !defined(CFG_ENV_IS_IN_DATAFLASH) && \
+ !defined(CFG_ENV_IS_IN_NAND) && \
++ !defined(CFG_ENV_IS_IN_DISK) && \
+ !defined(CFG_ENV_IS_NOWHERE)
+-# error Define one of CFG_ENV_IS_IN_{NVRAM|EEPROM|FLASH|DATAFLASH|NOWHERE}
++# error Define one of CFG_ENV_IS_IN_{NVRAM|EEPROM|FLASH|DATAFLASH|DISK|NOWHERE}
+ #endif
+
+ #define XMK_STR(x) #x
+@@ -483,7 +484,7 @@
+ * or NULL if not found
+ */
+
+-char *getenv (uchar *name)
++char *getenv (const uchar *name)
+ {
+ int i, nxt;
+
+@@ -530,7 +531,9 @@
+ return (-1);
+ }
+
+-#if defined(CFG_ENV_IS_IN_NVRAM) || defined(CFG_ENV_IS_IN_EEPROM) || \
++#if defined(CFG_ENV_IS_IN_NVRAM) || \
++ defined(CFG_ENV_IS_IN_EEPROM) || \
++ defined(CFG_ENV_IS_IN_DISK) || \
+ ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_FLASH)) == \
+ (CFG_CMD_ENV|CFG_CMD_FLASH))
+ int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+@@ -586,7 +589,9 @@
+ " - delete environment variable 'name'\n"
+ );
+
+-#if defined(CFG_ENV_IS_IN_NVRAM) || defined(CFG_ENV_IS_IN_EEPROM) || \
++#if defined(CFG_ENV_IS_IN_NVRAM) || \
++ defined(CFG_ENV_IS_IN_EEPROM) || \
++ defined(CFG_ENV_IS_IN_DISK) || \
+ ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_FLASH)) == \
+ (CFG_CMD_ENV|CFG_CMD_FLASH))
+ U_BOOT_CMD(
+diff -Nurd u-boot-1.1.2/common/env_common.c u-boot-1.1.2-oxe810/common/env_common.c
+--- u-boot-1.1.2/common/env_common.c 2004-06-09 16:58:14.000000000 +0200
++++ u-boot-1.1.2-oxe810/common/env_common.c 2008-06-11 17:55:30.000000000 +0200
+@@ -42,7 +42,7 @@
+ extern void disable_nvram(void);
+ #endif
+
+-#undef DEBUG_ENV
++//#undef DEBUG_ENV
+ #ifdef DEBUG_ENV
+ #define DEBUGF(fmt,args...) printf(fmt ,##args)
+ #else
+diff -Nurd u-boot-1.1.2/common/env_disk.c u-boot-1.1.2-oxe810/common/env_disk.c
+--- u-boot-1.1.2/common/env_disk.c 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-1.1.2-oxe810/common/env_disk.c 2008-06-11 17:55:30.000000000 +0200
+@@ -0,0 +1,152 @@
++/*
++ * (C) Copyright 2006
++ * Oxford Semiconductor Ltd
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * 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 <common.h>
++
++#if defined(CFG_ENV_IS_IN_DISK)
++
++#include <command.h>
++#include <environment.h>
++#include <ide.h>
++
++extern int is_device_present(int device_number);
++
++/* Point to the environment as held in SRAM */
++env_t *env_ptr = NULL;
++
++char *env_name_spec = "Disk";
++
++/* The default environment compiled into U-Boot */
++extern uchar default_environment[];
++
++uchar env_get_char_spec(int index)
++{
++ DECLARE_GLOBAL_DATA_PTR;
++
++ return *((uchar *)(gd->env_addr + index));
++}
++
++#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
++
++void env_relocate_spec(void)
++{
++ /* Compute the CRC of the environment in SRAM, copied from disk at boot */
++ env_t *sram_env = (env_t*)CFG_ENV_ADDR;
++ ulong crc = crc32(0, sram_env->data, CFG_ENV_SIZE - offsetof(env_t, data));
++
++ /* Copy the SRAM environment and CRC to the working environment */
++ memcpy(env_ptr->data, sram_env->data, CFG_ENV_SIZE - offsetof(env_t, data));
++ env_ptr->crc = crc;
++}
++
++int saveenv(void)
++{
++ /* Compute the CRC of the working environment */
++ env_ptr->crc = crc32(0, env_ptr->data, CFG_ENV_SIZE - offsetof(env_t, data));
++
++ /* Copy the working environment to the reserved area on each disk device */
++ int status = 1;
++ int i;
++ for (i=0; i < CFG_IDE_MAXDEVICE; ++i) {
++ if (!is_device_present(i)) {
++ continue;
++ }
++
++ /* Write environment to the main environment area on disk */
++ unsigned long written = ide_write(i, CFG_ENV_DISK_SECTOR, CFG_ENV_SIZE/512, (ulong*)env_ptr);
++ if (written != CFG_ENV_SIZE/512) {
++ printf("Saving environment to disk %d primary image failed\n", i);
++ status = 0;
++ } else {
++ /* Write environment to the redundant environment area on disk */
++ written = ide_write(i, CFG_ENV_DISK_REDUNDANT_SECTOR, CFG_ENV_SIZE/512, (ulong*)env_ptr);
++ if (written != CFG_ENV_SIZE/512) {
++ printf("Saving environment to disk %d secondary image failed\n", i);
++ status = 0;
++ }
++ }
++ }
++
++ return status;
++}
++
++static int check_sram_env_integrity(void)
++{
++ DECLARE_GLOBAL_DATA_PTR;
++
++ env_t *sram_env = (env_t*)CFG_ENV_ADDR;
++ ulong crc = crc32(0, sram_env->data, CFG_ENV_SIZE - offsetof(env_t, data));
++
++ if (crc == sram_env->crc) {
++ gd->env_addr = (ulong)sram_env->data;
++ gd->env_valid = 1;
++ }
++
++ return gd->env_valid;
++}
++
++int env_init(void)
++{
++ DECLARE_GLOBAL_DATA_PTR;
++
++ /* Have not yet found a valid environment */
++ gd->env_valid = 0;
++
++ /* Need SATA available to load environment from alternate disk locations */
++ ide_init();
++
++ int i;
++ for (i=0; i < CFG_IDE_MAXDEVICE; ++i) {
++ if (!is_device_present(i)) {
++ continue;
++ }
++
++ /* Read environment from the primary environment area on disk */
++ unsigned long read = ide_read(i, CFG_ENV_DISK_SECTOR, CFG_ENV_SIZE/512, (ulong*)CFG_ENV_ADDR);
++ if (read == CFG_ENV_SIZE/512) {
++ /* Check integrity of primary environment data */
++ if (check_sram_env_integrity()) {
++ printf("Environment successfully read from disk %d primary image\n", i);
++ break;
++ }
++ }
++
++ /* Read environment from the secondary environment area on disk */
++ read = ide_read(i, CFG_ENV_DISK_REDUNDANT_SECTOR, CFG_ENV_SIZE/512, (ulong*)CFG_ENV_ADDR);
++ if (read == CFG_ENV_SIZE/512) {
++ /* Check integrity of secondary environment data */
++ if (check_sram_env_integrity()) {
++ printf("Environment successfully read from disk %d secondary image\n", i);
++ break;
++ }
++ }
++ }
++
++ if (!gd->env_valid) {
++ printf("Failed to read valid environment from disk, using built-in default\n");
++ gd->env_addr = (ulong)default_environment;
++ gd->env_valid = 0;
++ }
++
++ return 0;
++}
++#endif // CFG_ENV_IS_IN_DISK
+diff -Nurd u-boot-1.1.2/common/main.c u-boot-1.1.2-oxe810/common/main.c
+--- u-boot-1.1.2/common/main.c 2004-04-23 22:32:06.000000000 +0200
++++ u-boot-1.1.2-oxe810/common/main.c 2008-06-11 17:55:30.000000000 +0200
+@@ -182,7 +182,7 @@
+ else {
+ for (i = 0; i < presskey_max - 1; i ++)
+ presskey [i] = presskey [i + 1];
+-
++do_recovery
+ presskey [i] = getc();
+ }
+ }
+@@ -369,6 +369,149 @@
+ install_auto_complete();
+ #endif
+
++
++#if defined(CONFIG_OXNAS)
++ /* Set the memory size given to Linux */
++ {
++ DECLARE_GLOBAL_DATA_PTR;
++
++ /* Get a copy of the bootargs string from the runtime environment */
++ char tempBuf[1024];
++ char* cmd_string = strcpy(&tempBuf[0], getenv("bootargs"));
++
++ /* Find the extent of memory token in the bootargs string */
++ char* mem_token = strstr(cmd_string, "mem=");
++ char* mem_token_end = mem_token;
++ while ((*mem_token_end != ' ') &&
++ (*mem_token_end != '\0')) {
++ ++mem_token_end;
++ }
++
++ if ((*mem_token_end == '\0') && (mem_token != mem_token_end)) {
++ /* Memory token is last in bootargs string */
++ if (mem_token != cmd_string) {
++ /* Is not the only token, so erase token and previous space" */
++ *(mem_token-1) = '\0';
++ } else {
++ /* Is the only token, so no previous space to erase */
++ *mem_token = '\0';
++ }
++ } else {
++ /* Memory token is at intermediate location in bootargs string */
++ if (*mem_token_end == ' ') {
++ ++mem_token_end;
++ }
++
++ /* Form the bootargs string without the memory token present */
++ strcpy(mem_token, mem_token_end);
++ }
++
++ /* How many MB of SDRAM are present */
++ int megabytes = gd->bd->bi_dram[0].size >> 20;
++
++ /* Append the memory token to the bootargs string */
++ switch (megabytes) {
++ case 64:
++ cmd_string = strcat(cmd_string, " mem=64M");
++ break;
++ case 128:
++ cmd_string = strcat(cmd_string, " mem=128M");
++ break;
++ case 256:
++ cmd_string = strcat(cmd_string, " mem=256M");
++ break;
++ default:
++ printf("Unsupported memory size, defaulting to 64M\n");
++ cmd_string = strcat(cmd_string, " mem=64M");
++ }
++
++ /* Save the revised bootargs string to the runtime environment */
++ setenv("bootargs", cmd_string);
++ }
++
++/* Upgrade, recovery and power button monitor code
++*/
++ int do_recovery = 0; /* default no recovery */
++
++ /* Read the upgrade flag from disk into memory */
++ ide_init();
++ run_command("ide read 48700000 ff 1", 0);
++
++ char upgrade_mode = *(volatile char*)0x48700000;
++ char recovery_mode = *(volatile char*)0x48700001;
++ char controlled_pd_mode = *(volatile char*)0x48700002;
++
++ if (recovery_mode == RECOVERY_MAGIC) {
++ do_recovery = 1; /* perform recovery */
++ }
++
++ if (controlled_pd_mode == CONTROLLED_POWER_DOWN_MAGIC) {
++ /* System in controlled pwer down mode */
++
++ /* Read the SRAM location for normal boot flag */
++ char sram_data = *(volatile char*)(CFG_SRAM_BASE + CFG_SRAM_SIZE - POWER_ON_FLAG_SRAM_OFFSET);
++ char tempBuf[1024];
++ char* cmd_string = strcpy(&tempBuf[0], getenv("bootargs"));
++
++ if (sram_data == CONTROLLED_POWER_UP_MAGIC) {
++ /* The system has to remain in power down state */
++
++ /* Set appropriate boot args */
++ cmd_string = strcat(cmd_string, " powermode=controlledpup");
++ printf("Controlled Power UP requested\n");
++ } else {
++ /* The system is moving to power up state from power down state */
++ cmd_string = strcat(cmd_string, " powermode=controlledpdown");
++ printf("Controlled Power DOWN requested\n");
++ }
++ setenv("bootargs", cmd_string);
++ }
++
++ /* branch off inot recovery or upadate */
++ if (upgrade_mode == UPGRADE_MAGIC) {
++ /* Script to select first disk */
++ parse_string_outer("set select0 ide dev 0", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
++
++ /* Script to select second disk */
++ parse_string_outer("set select1 ide dev 1", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
++
++ /* Script for loading 256KB of upgrade rootfs image from hidden sectors */
++ parse_string_outer("set loadf ide read 48700000 1770 200", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
++
++ /* Script for loading 2MB of upgrade kernel image from hidden sectors */
++ parse_string_outer("set loadk ide read 48800000 1970 1000", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
++
++ /* Script to light failure LED */
++ parse_string_outer("set lightled ledfail 1", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
++
++ /* Script to extinguish failure LED */
++ parse_string_outer("set extinguishled ledfail 0", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
++
++ /* Script for booting Linux kernel image with mkimage-wrapped initrd */
++ parse_string_outer("set boot bootm 48800000 48700000", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
++
++ /* Set Linux bootargs to use rootfs in initial ramdisk */
++ parse_string_outer("set bootargs mem=32M console=ttyS0,115200 root=/dev/ram0", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
++
++ /* Validate, load and boot the first validate set of initrd and kernel
++ Theres alot of combos here due to disk/backup/fk arrangments, it'll
++ no doubt work on the first or second one though. */
++ parse_string_outer("run select0 loadf loadk boot || "
++ "run lightled select1 loadf loadk extinguishled boot || "
++ "run lightled select0 loadf select1 loadk extinguishled boot || "
++ "run lightled select1 loadf select0 loadk extinguishled boot || "
++ "run lightled ", FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
++ } else if (do_recovery) {
++ printf ("\nRecovery mode selected\n");
++
++ char tempBuf[1024];
++ char* cmd_string = strcpy(&tempBuf[0], getenv("bootargs"));
++ cmd_string = strcat(cmd_string, " adminmode=recovery");
++ setenv("bootargs", cmd_string);
++ }
++
++#endif // CONFIG_OXNAS
++
+ #ifdef CONFIG_PREBOOT
+ if ((p = getenv ("preboot")) != NULL) {
+ # ifdef CONFIG_AUTOBOOT_KEYED
+diff -Nurd u-boot-1.1.2/common/Makefile u-boot-1.1.2-oxe810/common/Makefile
+--- u-boot-1.1.2/common/Makefile 2004-12-16 18:35:57.000000000 +0100
++++ u-boot-1.1.2-oxe810/common/Makefile 2008-06-11 17:55:30.000000000 +0200
+@@ -40,9 +40,10 @@
+ cmd_nand.o cmd_net.o cmd_nvedit.o \
+ cmd_pci.o cmd_pcmcia.o cmd_portio.o \
+ cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_universe.o cmd_usb.o cmd_vfd.o \
++ cmd_ledfail.o \
+ command.o console.o devices.o dlmalloc.o docecc.o \
+ environment.o env_common.o \
+- env_nand.o env_dataflash.o env_flash.o env_eeprom.o env_nvram.o env_nowhere.o exports.o \
++ env_nand.o env_dataflash.o env_flash.o env_eeprom.o env_nvram.o env_nowhere.o env_disk.o exports.o \
+ flash.o fpga.o \
+ hush.o kgdb.o lcd.o lists.o lynxkdi.o \
+ memsize.o miiphybb.o miiphyutil.o \
+diff -Nurd u-boot-1.1.2/cpu/arm926ejs/config.mk u-boot-1.1.2-oxe810/cpu/arm926ejs/config.mk
+--- u-boot-1.1.2/cpu/arm926ejs/config.mk 2003-08-30 00:00:47.000000000 +0200
++++ u-boot-1.1.2-oxe810/cpu/arm926ejs/config.mk 2008-06-11 17:55:03.000000000 +0200
+@@ -21,7 +21,6 @@
+ # MA 02111-1307 USA
+ #
+
+-PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \
+- -mshort-load-bytes -msoft-float
++PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8
+
+-PLATFORM_CPPFLAGS += -mapcs-32 -march=armv4
++PLATFORM_CPPFLAGS += -march=armv5te
+diff -Nurd u-boot-1.1.2/cpu/arm926ejs/interrupts.c u-boot-1.1.2-oxe810/cpu/arm926ejs/interrupts.c
+--- u-boot-1.1.2/cpu/arm926ejs/interrupts.c 2004-03-23 22:43:08.000000000 +0100
++++ u-boot-1.1.2-oxe810/cpu/arm926ejs/interrupts.c 2008-06-11 17:55:03.000000000 +0200
+@@ -41,7 +41,12 @@
+ #include <asm/proc-armv/ptrace.h>
+
+ extern void reset_cpu(ulong addr);
++
++#ifdef CONFIG_OXNAS
++#define TIMER_LOAD_VAL 0xffffUL
++#else // CONFIG_OXNAS
+ #define TIMER_LOAD_VAL 0xffffffff
++#endif // CONFIG_OXNAS
+
+ /* macro to read the 32 bit timer */
+ #ifdef CONFIG_OMAP
+@@ -53,6 +58,9 @@
+ #ifdef CONFIG_VERSATILE
+ #define READ_TIMER (*(volatile ulong *)(CFG_TIMERBASE+4))
+ #endif
++#ifdef CONFIG_OXNAS
++#define READ_TIMER ((*(volatile ushort *)(CFG_TIMERBASE+4)) & 0xFFFFUL) /* RPS timer value register has only 16 defined bits */
++#endif
+
+ #ifdef CONFIG_USE_IRQ
+ /* enable IRQ interrupts */
+@@ -212,6 +220,16 @@
+ *(volatile ulong *)(CFG_TIMERBASE + 4) = CFG_TIMER_RELOAD; /* TimerValue */
+ *(volatile ulong *)(CFG_TIMERBASE + 8) = 0x8C;
+ #endif /* CONFIG_VERSATILE */
++#ifdef CONFIG_OXNAS
++ // Setup timer 1 load value
++ *(volatile ulong*)(CFG_TIMERBASE + 0) = TIMER_LOAD_VAL;
++
++ // Setup timer 1 prescaler, periodic operation and start it
++ *(volatile ulong*)(CFG_TIMERBASE + 8) =
++ (TIMER_PRESCALE_ENUM << TIMER_PRESCALE_BIT) |
++ (TIMER_MODE_PERIODIC << TIMER_MODE_BIT) |
++ (TIMER_ENABLE_ENABLE << TIMER_ENABLE_BIT);
++#endif /* CONFIG_OXNAS */
+
+ /* init the timestamp and lastdec value */
+ reset_timer_masked();
+diff -Nurd u-boot-1.1.2/cpu/arm926ejs/start.S u-boot-1.1.2-oxe810/cpu/arm926ejs/start.S
+--- u-boot-1.1.2/cpu/arm926ejs/start.S 2004-06-09 02:11:01.000000000 +0200
++++ u-boot-1.1.2-oxe810/cpu/arm926ejs/start.S 2008-06-11 17:55:03.000000000 +0200
+@@ -94,6 +94,11 @@
+ _TEXT_BASE:
+ .word TEXT_BASE
+
++#ifdef CONFIG_OXNAS
++_EXCEPTION_BASE:
++ .word EXCEPTION_BASE
++#endif
++
+ .globl _armboot_start
+ _armboot_start:
+ .word _start
+@@ -135,6 +140,18 @@
+ orr r0,r0,#0xd3
+ msr cpsr,r0
+
++#ifdef CONFIG_OXNAS
++ /*
++ * Copy exception table to relocated address in internal SRAM
++ */
++ adr r0, _start /* Address of exception table in flash */
++ ldr r1, _EXCEPTION_BASE /* Relocated address of exception table */
++ ldmia r0!, {r3-r10} /* Copy exception table and jump values from */
++ stmia r1!, {r3-r10} /* FLASH to relocated address */
++ ldmia r0!, {r3-r10}
++ stmia r1!, {r3-r10}
++#endif
++
+ /*
+ * we do sys-critical inits only at reboot,
+ * not when booting from ram!
+@@ -143,21 +160,21 @@
+ bl cpu_init_crit
+ #endif
+
+-relocate: /* relocate U-Boot to RAM */
+- adr r0, _start /* r0 <- current position of code */
+- ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
+- cmp r0, r1 /* don't reloc during debug */
+- beq stack_setup
++relocate: /* relocate U-Boot to RAM */
++ adr r0, _start /* current position of code */
++ ldr r1, _TEXT_BASE /* relocated position of code */
++ cmp r0, r1
++ beq stack_setup
+
+ ldr r2, _armboot_start
+ ldr r3, _bss_start
+- sub r2, r3, r2 /* r2 <- size of armboot */
+- add r2, r0, r2 /* r2 <- source end address */
++ sub r2, r3, r2 /* r2 <- size of armboot */
++ add r2, r0, r2 /* r2 <- source end address */
+
+ copy_loop:
+- ldmia r0!, {r3-r10} /* copy from source address [r0] */
+- stmia r1!, {r3-r10} /* copy to target address [r1] */
+- cmp r0, r2 /* until source end addreee [r2] */
++ ldmia r0!, {r3-r10} /* copy from source address [r0] */
++ stmia r1!, {r3-r10} /* copy to target address [r1] */
++ cmp r0, r2 /* until source end addreee [r2] */
+ ble copy_loop
+
+ /* Set up the stack */
+@@ -212,7 +229,7 @@
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */
+ bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */
+- orr r0, r0, #0x00000002 /* set bit 2 (A) Align */
++ orr r0, r0, #0x00000002 /* set bit 1 (A) Align */
+ orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
+ mcr p15, 0, r0, c1, c0, 0
+
+@@ -391,6 +408,7 @@
+
+ #endif
+
++#ifndef CONFIG_OXNAS
+ .align 5
+ .globl reset_cpu
+ reset_cpu:
+@@ -405,3 +423,4 @@
+
+ rstctl1:
+ .word 0xfffece10
++#endif // !CONFIG_OXNAS
+diff -Nurd u-boot-1.1.2/drivers/cfi_flash.c u-boot-1.1.2-oxe810/drivers/cfi_flash.c
+--- u-boot-1.1.2/drivers/cfi_flash.c 2004-12-18 23:35:45.000000000 +0100
++++ u-boot-1.1.2-oxe810/drivers/cfi_flash.c 2008-06-11 17:55:31.000000000 +0200
+@@ -1056,7 +1056,11 @@
+ }
+ tmp = flash_read_long (info, 0,
+ FLASH_OFFSET_ERASE_REGIONS +
++#ifdef FORCE_TOP_BOOT_FLASH
++ (num_erase_regions - 1 - i) * 4);
++#else
+ i * 4);
++#endif
+ erase_region_size =
+ (tmp & 0xffff) ? ((tmp & 0xffff) * 256) : 128;
+ tmp >>= 16;
+@@ -1104,6 +1108,7 @@
+ cfiptr_t ctladdr;
+ cfiptr_t cptr;
+ int flag;
++ ulong start;
+
+ ctladdr.cp = flash_make_addr (info, 0, 0);
+ cptr.cp = (uchar *) dest;
+@@ -1151,6 +1156,15 @@
+ break;
+ case FLASH_CFI_16BIT:
+ cptr.wp[0] = cword.w;
++ /* Wait for write to complete */
++ start = get_timer (0);
++ while (cptr.wp[0] != cword.w) {
++ printf(".");
++ if (get_timer (start) > info->erase_blk_tout * CFG_HZ) {
++ printf ("Flash write timeout!");;
++ }
++ }
++ printf("\n");
+ break;
+ case FLASH_CFI_32BIT:
+ cptr.lp[0] = cword.l;
+diff -Nurd u-boot-1.1.2/drivers/ns16550.c u-boot-1.1.2-oxe810/drivers/ns16550.c
+--- u-boot-1.1.2/drivers/ns16550.c 2004-06-07 01:13:57.000000000 +0200
++++ u-boot-1.1.2-oxe810/drivers/ns16550.c 2008-06-11 17:55:31.000000000 +0200
+@@ -14,8 +14,25 @@
+ #define MCRVAL (MCR_DTR | MCR_RTS) /* RTS/DTR */
+ #define FCRVAL (FCR_FIFO_EN | FCR_RXSR | FCR_TXSR) /* Clear & enable FIFOs */
+
++#ifdef USE_UART_FRACTIONAL_DIVIDER
++static int oxnas_fractional_divider(NS16550_t com_port, int baud_divisor)
++{
++ // Baud rate is passed around x16
++ int real_divisor = baud_divisor >> 4;
++ // Top three bits of 8-bit dlf register hold the number of eigths
++ // for the fractional part of the divide ratio
++ com_port->dlf = (unsigned char)(((baud_divisor - (real_divisor << 4)) << 4) & 0xFF);
++ // Return the x1 divider for the normal divider register
++ return real_divisor;
++}
++#endif // USE_UART_FRACTIONAL_DIVIDER
++
+ void NS16550_init (NS16550_t com_port, int baud_divisor)
+ {
++#ifdef USE_UART_FRACTIONAL_DIVIDER
++ baud_divisor = oxnas_fractional_divider(com_port, baud_divisor);
++#endif // USE_UART_FRACTIONAL_DIVIDER
++
+ com_port->ier = 0x00;
+ #ifdef CONFIG_OMAP1510
+ com_port->mdr1 = 0x7; /* mode select reset TL16C750*/
+@@ -33,6 +50,10 @@
+
+ void NS16550_reinit (NS16550_t com_port, int baud_divisor)
+ {
++#ifdef USE_UART_FRACTIONAL_DIVIDER
++ baud_divisor = oxnas_fractional_divider(com_port, baud_divisor);
++#endif // USE_UART_FRACTIONAL_DIVIDER
++
+ com_port->ier = 0x00;
+ com_port->lcr = LCR_BKSE;
+ com_port->dll = baud_divisor & 0xff;
+diff -Nurd u-boot-1.1.2/drivers/serial.c u-boot-1.1.2-oxe810/drivers/serial.c
+--- u-boot-1.1.2/drivers/serial.c 2003-08-30 00:00:47.000000000 +0200
++++ u-boot-1.1.2-oxe810/drivers/serial.c 2008-06-11 17:55:31.000000000 +0200
+@@ -59,7 +59,13 @@
+ return (26); /* return 26 for base divisor */
+ }
+ #endif
+- return (CFG_NS16550_CLK / 16 / gd->baudrate);
++
++#ifdef USE_UART_FRACTIONAL_DIVIDER
++ return (((CFG_NS16550_CLK << 4) / gd->baudrate) + 8) >> 4;
++#endif // USE_UART_FRACTIONAL_DIVIDER
++
++ // Round to nearest integer
++ return (((CFG_NS16550_CLK / gd->baudrate) + 8 ) / 16);
+ }
+
+ int serial_init (void)
+diff -Nurd u-boot-1.1.2/examples/Makefile u-boot-1.1.2-oxe810/examples/Makefile
+--- u-boot-1.1.2/examples/Makefile 2004-10-10 23:27:33.000000000 +0200
++++ u-boot-1.1.2-oxe810/examples/Makefile 2008-06-11 17:55:30.000000000 +0200
+@@ -30,7 +30,8 @@
+ endif
+
+ ifeq ($(ARCH),arm)
+-LOAD_ADDR = 0xc100000
++#LOAD_ADDR = 0xc100000
++LOAD_ADDR = 0x4C004000
+ endif
+
+ ifeq ($(ARCH),mips)
+@@ -58,6 +59,11 @@
+ SREC = hello_world.srec
+ BIN = hello_world.bin hello_world
+
++ifeq ($(ARCH),arm)
++SREC += mem_test.srec
++BIN += mem_test.bin mem_test
++endif
++
+ ifeq ($(ARCH),i386)
+ SREC += 82559_eeprom.srec
+ BIN += 82559_eeprom.bin 82559_eeprom
+@@ -115,10 +121,10 @@
+ $(LD) -g $(EX_LDFLAGS) -Ttext $(LOAD_ADDR) \
+ -o $@ -e $(<:.o=) $< $(LIB) \
+ -L$(gcclibdir) -lgcc
+-%.srec: %
++%.srec: %.o
+ $(OBJCOPY) -O srec $< $@ 2>/dev/null
+
+-%.bin: %
++%.bin: %.o
+ $(OBJCOPY) -O binary $< $@ 2>/dev/null
+
+ #########################################################################
+diff -Nurd u-boot-1.1.2/examples/mem_test.c u-boot-1.1.2-oxe810/examples/mem_test.c
+--- u-boot-1.1.2/examples/mem_test.c 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-1.1.2-oxe810/examples/mem_test.c 2008-06-11 17:55:30.000000000 +0200
+@@ -0,0 +1,1322 @@
++/*
++ * (C) Copyright 2006
++ * Oxford Semiconductor Ltd, www.oxsemi.com
++ * 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
++ */
++
++/********************* OPTIONS ********************************************************/
++
++#define ARM
++/*
++#define QUIET
++#define SHORT
++*/
++
++/********************* TEST DEFINITIONS ********************************************************/
++
++
++#define NUM_PATTYPES 5
++#define PATTYPE_A5 0
++#define PATTYPE_5A 1
++#define PATTYPE_NO_FF 2
++#define PATTYPE_INCR 3
++#define PATTYPE_DECR 4
++
++/* Number of words in a block (to ensure that neither data not ~data is 0xFFxx) */
++
++#ifdef SHORT
++ #define BLOCKWORDS (254*4)
++ #define BLOCKSIZE (256*4)
++#else
++ #define BLOCKWORDS (254*256*4)
++ #define BLOCKSIZE (256*256*4)
++#endif
++
++#ifdef ARM
++ #include <common.h>
++ #include <exports.h>
++
++ #define SDRAM_BASE 0x48000000
++ #define SDRAM_TOP 0x49000000
++ #define SDRAM_BLOCK 0x10000
++// #define SDRAM_WRITE(ADDR, DATA) printf("Write 0x%08x to 0x%08x\n", (DATA), (ADDR));
++// #define SDRAM_READ(ADDR, VAR) printf("Read from 0x%08x\n", (ADDR));
++// #define SDRAM_WRITE(ADDR, DATA) printf("Write 0x%08x to 0x%08x\n", (DATA), (ADDR)); (*((volatile unsigned int *)(ADDR)) = (DATA))
++// #define SDRAM_READ(ADDR, VAR) printf("Read from 0x%08x\n", (ADDR)); (*(VAR) = *((volatile unsigned int *)(ADDR)))
++ #define SDRAM_WRITE(ADDR, DATA) (*((volatile unsigned int *)(ADDR)) = (DATA))
++ #define SDRAM_READ(ADDR, VAR) (*(VAR) = *((volatile unsigned int *)(ADDR)))
++#else
++ #include <stdio.h>
++ #include <stdlib.h>
++ /* Not so much space - just 2 blocks from addr 0... */
++ #define SDRAM_BASE 0
++ #define SDRAM_TOP (2 * BLOCKSIZE)
++ #define SDRAM_BLOCK 0x10000
++ #ifdef QUIET
++ #define SDRAM_WRITE(ADDR, DATA) array[ADDR] = (DATA)
++ #define SDRAM_READ(ADDR, VAR) *((volatile unsigned int *)(VAR)) = array[ADDR]
++ #else
++ #define SDRAM_WRITE(ADDR, DATA) printf("WRITE(%08x)=%08x\n", ADDR, DATA); array[ADDR] = (DATA)
++ #define SDRAM_READ(ADDR, VAR) printf("READ (%08x)=%08x\n", ADDR, array[ADDR]); *((volatile unsigned int *)(VAR)) = array[ADDR]
++ #endif
++ unsigned volatile int array[SDRAM_TOP];
++#endif
++
++
++#define SYSCTRL_PRIMSEL_LO 0x4500000C
++#define SYSCTRL_SECSEL_LO 0x45000014
++#define SYSCTRL_TERSEL_LO 0x4500008C
++#define SYSCTRL_PRIMSEL_HI 0x45000010
++#define SYSCTRL_SECSEL_HI 0x45000018
++#define SYSCTRL_TERSEL_HI 0x45000090
++
++/* GPIO */
++#define GPIOB_IO_VAL 0x44100000
++#define GPIOB_OE_VAL 0x44100004
++#define GPIOB_SET_OE 0x4410001C
++#define GPIOB_CLEAR_OE 0x44100020
++#define GPIOB_OUTPUT_VAL 0x44100010
++#define GPIOB_SET_OUTPUT 0x44100014
++#define GPIOB_CLEAR_OUTPUT 0x44100018
++#define GPIOB_BIT_34 0x00000004
++
++void configure_caches(void);
++void report_err(unsigned int address, unsigned int bad_data, unsigned int correct_data, unsigned int iteration);
++
++/********************* TYPES.H ********************************************************/
++
++typedef unsigned int UINT, *PUINT;
++/*
++#ifndef __MY_BASIC_TYPES_H
++#define __MY_BASIC_TYPES_H
++
++typedef signed char CHAR, *PCHAR;
++typedef unsigned char BYTE, UCHAR, *PBYTE, *PUCHAR;
++typedef signed short SHORT, *PSHORT;
++typedef unsigned short WORD, USHORT, *PWORD, *PUSHORT;
++typedef signed long LONG, *PLONG;
++typedef unsigned long DWORD, *PDWORD;
++typedef int BOOL, *PBOOL;
++typedef unsigned int UINT, *PUINT;
++typedef void VOID, *PVOID;
++
++typedef float SINGLE,*PSINGLE;
++typedef double DOUBLE,*PDOUBLE;
++
++
++#define FALSE 0
++#define TRUE 1
++
++#endif
++*/
++
++/********************* CHIP.H ********************************************************/
++
++// Address Map
++#define BOOT_ROM_BASE 0x00000000
++#define USBHS_BASE 0x00200000
++#define GMAC_BASE 0x00400000
++#define PCI_BASE 0x00600000
++#define PCI_DATA_BASE 0x00800000
++#define STATIC0_BASE 0x01000000
++#define STATIC1_BASE 0x01400000
++#define STATIC2_BASE 0x01800000
++#define STATIC_BASE 0x01C00000
++#define SATA_DATA_BASE 0x02000000
++#define DPE_DATA_BASE 0x03000000
++#define GPIOA_BASE 0x04000000
++#define GPIOB_BASE 0x04100000
++#define UARTA_BASE 0x04200000
++#define UARTB_BASE 0x04300000
++#define I2C_MASTER_BASE 0x04400000
++#define AUDIO_BASE 0x04500000
++#define FAN_BASE 0x04600000
++#define PWM_BASE 0x04700000
++#define IR_RX_BASE 0x04800000
++#define UARTC_BASE 0x04900000
++#define UARTD_BASE 0x04A00000
++#define SYS_CTRL_BASE 0x05000000
++#define RPSA_BASE 0x05300000
++#define ARM_RPS_BASE RPSA_BASE
++#define RPSC_BASE 0x05400000
++#define AHB_MON_BASE 0x05500000
++#define DMA_BASE 0x05600000
++#define DPE_BASE 0x05700000
++#define IBIW_BASE 0x05780000
++#define DDR_BASE 0x05800000
++#define SATA0_BASE 0x05900000
++#define SATA1_BASE 0x05980000
++#define DMA_CHKSUM_BASE 0x05A00000
++#define COPRO_BASE 0x05B00000
++#define SGDMA_BASE 0x05C00000
++#define DDR_DATA_BASE 0x08000000
++#define SRAM_BASE 0x0C000000
++#define SRAM0_BASE 0x0C000000
++#define SRAM1_BASE 0x0C002000
++#define SRAM2_BASE 0x0C004000
++#define SRAM3_BASE 0x0C006000
++
++// Virtual peripheral for TB sync
++#define TB_SYNC_BASE 0x05F00100
++
++
++/********************* DMA.H ********************************************************/
++
++
++// DMA Control register settings
++
++#define DMA_FAIR_SHARE (1<<0)
++#define DMA_IN_PROGRESS (1<<1)
++
++#define DMA_SDREQ_SATA (0<<2)
++#define DMA_SDREQ_DPE_OUT (2<<2)
++#define DMA_SDREQ_UARTA_RX (4<<2)
++#define DMA_SDREQ_AUDIO_RX (6<<2)
++#define DMA_SDREQ_MEM (0xF<<2)
++
++#define DMA_DDREQ_SATA (0<<6)
++#define DMA_DDREQ_DPE_IN (1<<6)
++#define DMA_DDREQ_UARTA_TX (3<<6)
++#define DMA_DDREQ_AUDIO_TX (5<<6)
++#define DMA_DDREQ_MEM (0xF<<6)
++
++#define DMA_INTERRUPT (1 << 10)
++#define DMA_NEXT_FREE (1 << 11)
++#define DMA_CH_RESET (1 << 12)
++
++#define DMA_DIR_ATOA (0 << 13)
++#define DMA_DIR_BTOA (1 << 13)
++#define DMA_DIR_ATOB (2 << 13)
++#define DMA_DIR_BTOB (3 << 13)
++
++#define DMA_BURST_A (1 << 17)
++#define DMA_BURST_B (1 << 18)
++
++#define DMA_SWIDTH_8 (0 << 19)
++#define DMA_SWIDTH_16 (1 << 19)
++#define DMA_SWIDTH_32 (2 << 19)
++
++#define DMA_DWIDTH_8 (0 << 22)
++#define DMA_DWIDTH_16 (1 << 22)
++#define DMA_DWIDTH_32 (2 << 22)
++
++#define DMA_PAUSE (1 << 25)
++#define DMA_INT_ENABLE (1 << 26)
++#define DMA_STARVE_LO_PRIORITY (1 << 29)
++#define DMA_NEW_INT_CLEAR (1 << 30)
++
++#define DMA_FIXED_SADDR ((0 << 15) | (1 << 27))
++#define DMA_INCR_SADDR ((1 << 15) | (0 << 27))
++#define DMA_SEMI_FIXED_SADDR ((0 << 15) | (0 << 27))
++
++#define DMA_FIXED_DADDR ((0 << 16) | (1 << 28))
++#define DMA_INCR_DADDR ((1 << 16) | (0 << 28))
++#define DMA_SEMI_FIXED_DADDR ((0 << 16) | (0 << 28))
++
++#define DMA_BASE_CTRL (DMA_BURST_A | DMA_BURST_B | DMA_INT_ENABLE | DMA_NEW_INT_CLEAR)
++
++// Common base setups
++
++#define DMA_CTRL_A32TOA32 ( DMA_BASE_CTRL | DMA_DIR_ATOA | DMA_SWIDTH_32 | DMA_DWIDTH_32 )
++#define DMA_CTRL_B32TOA32 ( DMA_BASE_CTRL | DMA_DIR_BTOA | DMA_SWIDTH_32 | DMA_DWIDTH_32 )
++#define DMA_CTRL_A32TOB32 ( DMA_BASE_CTRL | DMA_DIR_ATOB | DMA_SWIDTH_32 | DMA_DWIDTH_32 )
++#define DMA_CTRL_B32TOB32 ( DMA_BASE_CTRL | DMA_DIR_BTOB | DMA_SWIDTH_32 | DMA_DWIDTH_32 )
++
++#define DMA_CTRL_A8TOB32 ( DMA_BASE_CTRL | DMA_DIR_ATOB | DMA_SWIDTH_8 | DMA_DWIDTH_32 )
++#define DMA_CTRL_B32TOA8 ( DMA_BASE_CTRL | DMA_DIR_BTOA | DMA_SWIDTH_32 | DMA_DWIDTH_8 )
++#define DMA_CTRL_A32TOB8 ( DMA_BASE_CTRL | DMA_DIR_ATOB | DMA_SWIDTH_32 | DMA_DWIDTH_8 )
++
++// Most likely transactions
++
++#define DMA_CTRL_MEM_TO_MEM_AA ( DMA_CTRL_A32TOA32 | DMA_SDREQ_MEM | DMA_DDREQ_MEM | DMA_INCR_SADDR | DMA_INCR_DADDR )
++#define DMA_CTRL_MEM_TO_MEM_AB ( DMA_CTRL_A32TOB32 | DMA_SDREQ_MEM | DMA_DDREQ_MEM | DMA_INCR_SADDR | DMA_INCR_DADDR )
++#define DMA_CTRL_MEM_TO_MEM_BB ( DMA_CTRL_B32TOB32 | DMA_SDREQ_MEM | DMA_DDREQ_MEM | DMA_INCR_SADDR | DMA_INCR_DADDR )
++#define DMA_CTRL_MEM_TO_MEM_BA ( DMA_CTRL_B32TOA32 | DMA_SDREQ_MEM | DMA_DDREQ_MEM | DMA_INCR_SADDR | DMA_INCR_DADDR )
++#define DMA_CTRL_MEM_TO_MEM ( DMA_CTRL_MEM_TO_MEM_AB )
++
++//DMA A-A
++#define DMA_CTRL_SATA_TO_MEM_AA ( DMA_CTRL_A32TOA32 | DMA_SDREQ_SATA | DMA_DDREQ_MEM | DMA_INCR_SADDR | DMA_INCR_DADDR )
++#define DMA_CTRL_MEM_TO_SATA_AA ( DMA_CTRL_A32TOA32 | DMA_SDREQ_MEM | DMA_DDREQ_SATA | DMA_INCR_SADDR | DMA_INCR_DADDR )
++
++#define DMA_CTRL_SATA_TO_MEM ( DMA_CTRL_A32TOB32 | DMA_SDREQ_SATA | DMA_DDREQ_MEM | DMA_INCR_SADDR | DMA_INCR_DADDR )
++#define DMA_CTRL_MEM_TO_SATA ( DMA_CTRL_B32TOA32 | DMA_SDREQ_MEM | DMA_DDREQ_SATA | DMA_INCR_SADDR | DMA_INCR_DADDR )
++#define DMA_CTRL_SATA_TO_DPE ( DMA_CTRL_A32TOA32 | DMA_SDREQ_SATA | DMA_DDREQ_DPE_IN | DMA_INCR_SADDR | DMA_INCR_DADDR )
++#define DMA_CTRL_DPE_TO_SATA ( DMA_CTRL_A32TOA32 | DMA_SDREQ_DPE_OUT | DMA_DDREQ_SATA | DMA_INCR_SADDR | DMA_INCR_DADDR )
++#define DMA_CTRL_MEM_TO_DPE ( DMA_CTRL_B32TOA32 | DMA_SDREQ_MEM | DMA_DDREQ_DPE_IN | DMA_INCR_SADDR | DMA_INCR_DADDR )
++#define DMA_CTRL_DPE_TO_MEM ( DMA_CTRL_A32TOB32 | DMA_SDREQ_DPE_OUT | DMA_DDREQ_MEM | DMA_INCR_SADDR | DMA_INCR_DADDR )
++#define DMA_CTRL_PCI_TO_MEM ( DMA_CTRL_A32TOB32 | DMA_SDREQ_MEM | DMA_DDREQ_MEM | DMA_INCR_SADDR | DMA_INCR_DADDR )
++
++#define DMA_CTRL_MEM_TO_PCI ( DMA_CTRL_B32TOA32 | DMA_SDREQ_MEM | DMA_DDREQ_MEM | DMA_INCR_SADDR | DMA_INCR_DADDR )
++#define DMA_CTRL_MEM_TO_AUDIO ( DMA_CTRL_B32TOA32 | DMA_SDREQ_MEM | DMA_DDREQ_AUDIO_TX | DMA_INCR_SADDR | DMA_FIXED_DADDR )
++#define DMA_CTRL_AUDIO_TO_MEM ( DMA_CTRL_A32TOB32 | DMA_SDREQ_AUDIO_RX | DMA_DDREQ_MEM | DMA_FIXED_SADDR | DMA_INCR_DADDR )
++#define DMA_CTRL_MEM_TO_UART ( DMA_CTRL_B32TOA8 | DMA_SDREQ_MEM | DMA_DDREQ_UARTA_TX | DMA_INCR_SADDR | DMA_FIXED_DADDR )
++#define DMA_CTRL_UART_TO_MEM ( DMA_CTRL_A8TOB32 | DMA_SDREQ_UARTA_RX | DMA_DDREQ_MEM | DMA_FIXED_SADDR | DMA_INCR_DADDR )
++
++// Byte count register flags
++
++#define DMA_HBURST_EN (1<<28)
++#define DMA_WR_BUFFERABLE (1<<29)
++#define DMA_WR_EOT (1<<30)
++#define DMA_RD_EOT (1<<31)
++
++
++// Pause the DMA channel specified
++void PauseDMA( UINT channel );
++
++// UnPause the DMA channel specified
++void UnPauseDMA( UINT channel );
++
++// Configure a DMA
++void SetupDMA( UINT channel,
++ UINT src_addr,
++ UINT dest_addr,
++ UINT byte_count,
++ UINT control,
++ UINT flags );
++
++// Wait while the given DMA channel is busy
++void WaitWhileDMABusy( UINT channel );
++
++// Perform a memory to memory copy
++void DMAMemCopy ( UINT channel,
++ UINT src_addr,
++ UINT dest_addr,
++ UINT byte_count );
++
++
++/****************************** MAIN ***********************************************/
++#ifdef ARM
++int mem_test(int argc, char* argv[])
++#else
++int main(int argc, char* argv[])
++#endif
++{
++ unsigned int i;
++ unsigned int iteration;
++ unsigned int block_base;
++ unsigned int datapattern;
++ unsigned int correct_data;
++ unsigned volatile int read_data;
++ unsigned int pattype, starting_pattype;
++ unsigned int end_addr;
++ unsigned int row, col, bank;
++
++#ifdef ARM
++ /* Print the ABI version */
++ app_startup(argv);
++ printf ("Example expects ABI version %d\n", XF_VERSION);
++ printf ("Actual U-Boot ABI version %d\n", (int)get_version());
++
++ printf("GPIO34 is output, low\n");
++ * (volatile unsigned int *) GPIOB_CLEAR_OUTPUT = GPIOB_BIT_34;
++ * (volatile unsigned int *) GPIOB_SET_OE = GPIOB_BIT_34;
++#endif
++
++// configure_caches();
++//printf("Caches enabled\n");
++
++ /* ******************************************************************* */
++ printf("DMA TEST.\n" );
++ /* ******************************************************************* */
++
++
++ #define DMA0_CTRL_STAT 0x45A00000
++ #define DMA0_SRC_BASE 0x45A00004
++ #define DMA0_DEST_BASE 0x45A00008
++ #define DMA0_BYTE_COUNT 0x45A0000C
++ #define DMA0_CURRENT_BYTE 0x45A00018
++
++ printf("Test to top of 1st SDRAM" );
++ #define BLOCK_BYTES 0x20000
++ #define SDRAM_STOP SDRAM_TOP
++
++ for (iteration=0; 1; iteration++) {
++
++ if ((iteration % 5)==0)
++ printf("Iteration %d\n", iteration );
++
++// printf("Write pattern into first block.\n" );
++ end_addr = SDRAM_BASE + BLOCK_BYTES;
++ for (i=SDRAM_BASE; i < end_addr; i=i+4) {
++ SDRAM_WRITE( i, i);
++ }
++
++// printf("Clear last block and a few blocks more - easy to see on LA.\n" );
++ end_addr = SDRAM_BASE + (BLOCK_BYTES << 3);
++ for (i=SDRAM_STOP - BLOCK_BYTES; i < end_addr; i=i+4) {
++ SDRAM_WRITE( i, 0);
++ }
++
++ end_addr = SDRAM_STOP - BLOCK_BYTES;
++ for (i=SDRAM_BASE; i < end_addr; i=i+BLOCK_BYTES) {
++
++// printf("DMA transfer from %08x to %08x.\n", i, i + BLOCK_BYTES );
++#ifdef ARM
++ DMAMemCopy ( 0, i, i + BLOCK_BYTES, BLOCK_BYTES );
++#endif
++// printf("...pending.\n" );
++#ifdef ARM
++ WaitWhileDMABusy( 0 );
++#endif
++// printf("...complete.\n" );
++ }
++
++// printf("Verify pattern in last block.\n" );
++ end_addr = SDRAM_STOP;
++ correct_data = SDRAM_BASE;
++ for (i=SDRAM_STOP - BLOCK_BYTES; i < end_addr; i=i+4) {
++ SDRAM_READ( i, &read_data);
++ if (read_data != correct_data)
++ {
++ /* Expand out the report_err function to avoid the stack operations. */
++ #ifdef ARM
++ /* ASSERT GPIO */
++ * (volatile unsigned int *) GPIOB_SET_OUTPUT = GPIOB_BIT_34;
++ #endif
++
++ /* REPORT ERROR */
++ printf("Wrong on [%08x]= %08x should be %08x on iteration %d\n", i, read_data, correct_data, iteration );
++
++ /* WRITE TO ANOTHER LOCATION */
++ SDRAM_WRITE(SDRAM_BASE, 0xFFFFFFFF);
++
++ /* READ AGAIN */
++ SDRAM_READ(i, &read_data);
++ if (read_data != correct_data)
++ printf("Again 1 [%08x]= %08x should be %08x\n", i, read_data, correct_data );
++
++ /* WRITE TO ANOTHER LOCATION */
++ SDRAM_WRITE(SDRAM_BASE, 0xFFFFFFFF);
++
++ /* READ AGAIN */
++ SDRAM_READ(i, &read_data);
++ if (read_data != correct_data)
++ printf("Again 2 [%08x]= %08x should be %08x\n", i, read_data, correct_data );
++
++ /* WRITE TO ANOTHER LOCATION */
++ SDRAM_WRITE(SDRAM_BASE, 0xFFFFFFFF);
++
++ /* READ AGAIN */
++ SDRAM_READ(i, &read_data);
++ if (read_data != correct_data)
++ printf("Again 3 [%08x]= %08x should be %08x\n", i, read_data, correct_data );
++
++ row = (((i >> 26) & 0x1) << 13) | (((i >> 23) & 0x3) << 11) | ((i >> 10) & 0x7FF); /* [26], [24:23], [20:10]*/
++ col = (((i >> 27) & 0x1) << 10) | (((i >> 25) & 0x1) << 9) | (((i >> 22) & 0x1) << 8); /* [27], [25], [22]... */
++ col |= (((i >> 6) & 0xF) << 4) | (((i >> 21) & 0x1) << 3) | (((i >> 1) & 0x3) << 1); /* ...[9:8], [21], [3:2], '0' */
++ col |= 0x800; /* bit 11 set for auto-precharge */
++ bank = (i >> 4) & 0x3; /* [5:4] */
++ printf("Bank %08x\n", bank );
++ printf("Row %08x\n", row );
++ printf("Column %08x\n", col );
++ #ifdef ARM
++ /* DEASSERT GPIO */
++ * (volatile unsigned int *) GPIOB_CLEAR_OUTPUT = GPIOB_BIT_34;
++ #endif
++ }
++
++
++ correct_data += 4;
++ }
++ }
++
++
++ /* ******************************************************************* */
++ printf("MEM_TEST2\n");
++ /* ******************************************************************* */
++
++
++ pattype=0;
++ iteration=0;
++
++ for (;;) {
++ /* FOR EACH 64Kword==256KB BLOCK IN 16Mword=64MB (2 OFF 16M16) MEMORY... */
++
++#ifdef SHORT
++ if ((iteration % 5)==0)
++ printf("Iteration %d\n", iteration );
++#else
++ if ((iteration % 1000)==0)
++ printf("Iteration %d\n", iteration );
++#endif
++
++ /* WRITE DATA BLOCKS */
++ starting_pattype = pattype; /* Record for later */
++
++ for (block_base=SDRAM_BASE; block_base < SDRAM_TOP; block_base=block_base + BLOCKSIZE) {
++ switch (pattype) {
++ case PATTYPE_A5 :
++ /* Write alternating 1s and 0s... */
++ end_addr = block_base + BLOCKWORDS;
++ for (i=block_base; i < end_addr; i=i+4) {
++ SDRAM_WRITE( i, 0xaa55aa55);
++ }
++ break;
++ case PATTYPE_5A :
++ /* Write alternating 1s and 0s (inverse of above)... */
++ end_addr = block_base + BLOCKWORDS;
++ for (i=block_base; i < end_addr; i=i+4) {
++ SDRAM_WRITE( i, 0x55aa55aa);
++ }
++ break;
++ case PATTYPE_NO_FF :
++ /* Write data=address with bit[n+16]=~bit[n]... */
++ datapattern = 0x0100FEFF;
++ /* In range 0x0100...0xFEFF so that
++ a. temp[15:8] is never 0xFF
++ b. Inverse of temp[15:8] is never 0xFF
++ */
++ end_addr = block_base + BLOCKWORDS;
++ for (i=block_base; i < end_addr; i=i+4) {
++ SDRAM_WRITE( i, datapattern);
++ datapattern = datapattern + 0xFFFF;
++ }
++ break;
++ case PATTYPE_INCR :
++ /* Write data=address... */
++ end_addr = block_base + BLOCKSIZE;
++ for (i=block_base; i < end_addr; i=i+4) {
++ SDRAM_WRITE( i, i);
++ }
++ break;
++ case PATTYPE_DECR :
++ /* Write data=~address... */
++ end_addr = block_base + BLOCKSIZE;
++ for (i=block_base; i < end_addr; i=i+4) {
++ SDRAM_WRITE( i, ~i);
++ }
++ break;
++ }
++ }
++
++ /* VERIFY DATA BLOCKS */
++ pattype = starting_pattype; /* Reset to same as for writes */
++
++ for (block_base=SDRAM_BASE; block_base < SDRAM_TOP; block_base=block_base + BLOCKSIZE) {
++ switch (pattype) {
++ case PATTYPE_A5 :
++ correct_data = 0xaa55aa55;
++ end_addr = block_base + BLOCKWORDS;
++ for (i=block_base; i < end_addr; i=i+4) {
++ SDRAM_READ( i, &read_data);
++ if (read_data != correct_data)
++ report_err(i, read_data, correct_data, iteration);
++ }
++ break;
++ case PATTYPE_5A :
++ correct_data = 0x55aa55aa;
++ end_addr = block_base + BLOCKWORDS;
++ for (i=block_base; i < end_addr; i=i+4) {
++ SDRAM_READ( i, &read_data);
++ if (read_data != correct_data)
++ report_err(i, read_data, correct_data, iteration);
++ }
++ break;
++ case PATTYPE_NO_FF :
++ correct_data = 0x0100FEFF;
++ end_addr = block_base + BLOCKWORDS;
++ for (i=block_base; i < end_addr; i=i+4) {
++ SDRAM_READ( i, &read_data);
++ if (read_data != correct_data)
++ report_err(i, read_data, correct_data, iteration);
++ correct_data = correct_data + 0xFFFF;
++ }
++ break;
++ case PATTYPE_INCR :
++ end_addr = block_base + BLOCKSIZE;
++ for (i=block_base; i < end_addr; i=i+4) {
++ SDRAM_READ( i, &read_data);
++ if (read_data != i)
++ report_err(i, read_data, i, iteration);
++ }
++ break;
++ case PATTYPE_DECR :
++ end_addr = block_base + BLOCKSIZE;
++ for (i=block_base; i < end_addr; i=i+4) {
++ SDRAM_READ( i, &read_data);
++ if (read_data != ~i)
++ report_err(i, read_data, ~i, iteration);
++ }
++ break;
++ }
++ }
++
++ pattype = pattype + 1;
++ if (pattype >= NUM_PATTYPES) { pattype = 0; }
++ ++iteration;
++ }
++
++ return 0;
++}
++
++/********************* REPORT ERROR FUNC ********************************************************/
++
++void report_err(unsigned int address, unsigned int bad_data, unsigned int correct_data, unsigned int iteration)
++{
++ volatile unsigned int readvalue;
++
++#ifdef ARM
++ /* ASSERT GPIO */
++ * (volatile unsigned int *) GPIOB_SET_OUTPUT = GPIOB_BIT_34;
++#endif
++
++ /* REPORT ERROR */
++ printf("Wrong on [%08x]= %08x should be %08x on iteration %d\n", address, bad_data, correct_data, iteration );
++
++ /* WRITE TO ANOTHER LOCATION */
++ SDRAM_WRITE(SDRAM_BASE, 0xFFFFFFFF);
++
++ /* READ AGAIN */
++ SDRAM_READ(address, &readvalue);
++ if (readvalue != correct_data)
++ printf("Again 1 [%08x]= %08x should be %08x\n", address, readvalue, correct_data );
++
++ /* WRITE TO ANOTHER LOCATION */
++ SDRAM_WRITE(SDRAM_BASE, 0xFFFFFFFF);
++
++ /* READ AGAIN */
++ SDRAM_READ(address, &readvalue);
++ if (readvalue != correct_data)
++ printf("Again 2 [%08x]= %08x should be %08x\n", address, readvalue, correct_data );
++
++ /* WRITE TO ANOTHER LOCATION */
++ SDRAM_WRITE(SDRAM_BASE, 0xFFFFFFFF);
++
++ /* READ AGAIN */
++ SDRAM_READ(address, &readvalue);
++ if (readvalue != correct_data)
++ printf("Again 3 [%08x]= %08x should be %08x\n", address, readvalue, correct_data );
++
++#ifdef ARM
++ /* DEASSERT GPIO */
++ * (volatile unsigned int *) GPIOB_CLEAR_OUTPUT = GPIOB_BIT_34;
++#endif
++
++} /* end of report_err */
++
++
++
++
++/********************* DMA.C FUNCTIONS ********************************************************/
++
++void ResetDMA( UINT channel ) {
++
++ // Clear and abort the dma channel
++
++ volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
++ dma[0] = (1 << 12);
++ dma[0] &= ~(1 << 12);
++}
++
++
++
++
++void PauseDMA( UINT channel ) {
++
++ // Pause the DMA channel specified
++
++ volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
++ UINT rd;
++
++ rd = dma[0];
++
++ rd |= DMA_PAUSE;
++
++ dma[0] = rd;
++}
++
++
++
++
++void UnPauseDMA( UINT channel ) {
++
++ // UnPause the DMA channel specified
++
++ volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
++ UINT rd;
++
++ rd = dma[0];
++
++ rd &= ~DMA_PAUSE;
++
++ dma[0] = rd;
++}
++
++
++
++
++void SetupDMA( UINT channel,
++ UINT src_addr,
++ UINT dest_addr,
++ UINT byte_count,
++ UINT control,
++ UINT flags ) {
++
++ // Configure a DMA
++
++ volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
++
++ dma[0] = control;
++ dma[1] = src_addr;
++ dma[2] = dest_addr;
++ dma[3] = byte_count | (flags & 0xF0000000);
++}
++
++// EXAMPLE:
++//
++// DMA 2kB from SRAM to SATA core with a write EOT set, and HBURST enabled, using DMA channel 2
++// Then wait for the DMA to complete
++//
++// SetupDMA ( 2 , 0x4C001100, BASE_SATA, 2048, DMA_CTRL_MEM_TO_SATA, WR_EOT | DMA_HBURST_EN );
++// WaitWhileDMABusy( 2 );
++
++int DMABusy(UINT channel)
++{
++ volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
++ return (dma[0] & DMA_IN_PROGRESS ? 1 : 0);
++}
++
++
++void WaitWhileDMABusy( UINT channel ) // Wait while the given DMA channel is busy
++{
++ volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
++ while (dma[0] & DMA_IN_PROGRESS) ; // Do Nothing
++}
++
++void DMAClearIRQ(UINT channel)
++{
++ volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
++ dma[4] = 1; // write any value to offset 0x10 (16 / 4 => 4)
++
++}
++
++void DMAMemCopy ( UINT channel,
++ UINT src_addr,
++ UINT dest_addr,
++ UINT byte_count ) {
++
++ // Perform a memory to memory copy
++
++ volatile PUINT dma = (PUINT) (DMA_BASE + (channel << 5));
++
++ // Choose fastest configuration possible for required transfer
++
++ if (src_addr < SRAM_BASE) {
++ if (dest_addr < SRAM_BASE) {
++ dma[0] = DMA_CTRL_MEM_TO_MEM_AA; // Src and Dest must use A
++ } else {
++ dma[0] = DMA_CTRL_MEM_TO_MEM_AB; // Src must use A
++ }
++ } else {
++ if (dest_addr < SRAM_BASE) {
++ dma[0] = DMA_CTRL_MEM_TO_MEM_BA; // Dest must use A
++ } else {
++ dma[0] = DMA_CTRL_MEM_TO_MEM_AB; // No restriction
++ }
++ }
++
++ dma[1] = src_addr;
++ dma[2] = dest_addr;
++ dma[3] = byte_count | DMA_WR_BUFFERABLE | DMA_HBURST_EN;
++
++ WaitWhileDMABusy( channel );
++}
++
++
++
++
++
++
++
++#define CP15R1_M_ENABLE 0x0001 // MMU Enable
++#define CP15R1_A_ENABLE 0x0002 // Address alignment fault enable
++#define CP15R1_C_ENABLE 0x0004 // (data) cache enable
++#define CP15R1_W_ENABLE 0x0008 // write buffer enable
++#define CP15R1_PROG32 0x0010 // PROG32
++#define CP15R1_DATA32 0x0020 // DATA32
++#define CP15R1_L_ENABLE 0x0040 // Late abort on earlier CPUs
++#define CP15R1_BIGEND 0x0080 // Big-endian (=1), little-endian (=0)
++#define CP15R1_SYSTEM 0x0100 // System bit, modifies MMU protections
++#define CP15R1_ROM 0x0200 // ROM bit, modifies MMU protections
++#define CP15R1_F 0x0400 // Should Be Zero
++#define CP15R1_Z_ENABLE 0x0800 // Branch prediction enable on 810
++#define CP15R1_I_ENABLE 0x1000 // Instruction cache enable
++#define CP15R1_RESERVED 0x00000078
++#define CP15R2_RESERVED 0xFFFFC000
++
++#define NUM_DOMAINS 16
++
++#define DAV_NO_ACCESS 0
++#define DAV_CLIENT 1
++#define DAV_RESERVED 2
++#define DAV_MANAGER 3
++#define NUM_DOMAIN_ACCESS_VALUES 4
++
++#define AP_LEVEL_0 0
++#define AP_LEVEL_1 0
++#define AP_LEVEL_2 0
++#define AP_LEVEL_3 0
++#define NUM_ACCESS_PERMISSIONS 4
++
++#define FAULT_ID 0
++
++#define FLD_COURSE_ID 1
++#define FLD_SECTION_ID 2
++#define FLD_FINE_ID 3
++
++#define FD_USER_DATA_BIT 2
++
++#define FD_USER_DATA_NUM_BITS 30
++
++#define SD_BUFFERABLE_BIT 2
++#define SD_CACHEABLE_BIT 3
++#define SD_IMP_BIT 4
++#define SD_DOMAIN_BIT 5
++#define SD_AP_BIT 10
++#define SD_ADDRESS_BIT 20
++
++#define SD_DOMAIN_NUM_BITS 4
++#define SD_AP_NUM_BITS 2
++
++void CoPro15Regs_SetCP15Reg1(const unsigned long mask) {
++ asm volatile(
++ "MOV r0, %0;"
++ "MRC p15, 0, r1, c1, c0, 0;"
++ "ORR r1,r1,r0;"
++ "MCR p15, 0, r1, c1, c0, 0;"
++ :
++ : "r" (mask | CP15R1_RESERVED)
++ : "r0","r1");
++}
++
++void CoPro15Regs_ClearCP15Reg1(const unsigned long mask) {
++ asm volatile(
++ "MOV r0, %0;"
++ "MRC p15, 0, r1, c1, c0, 0;"
++ "BIC r1,r1,r0;"
++ "MCR p15, 0, r1, c1, c0, 0;"
++ :
++ : "r" (mask)
++ : "r0","r1");
++}
++
++unsigned long CoPro15Regs_GetCP15Reg1(const unsigned long mask) {
++ unsigned long value;
++ asm volatile(
++ "MRC p15, 0, r1, c1, c0, 0;"
++ "MOV r0, %1;"
++ "BIC %0,r1,r0; "
++ : "=r" (value)
++ : "r" (mask)
++ : "r0","r1");
++ return value;
++}
++
++unsigned long CoPro15Regs_GetCP15Reg2(void) {
++ unsigned long value;
++ asm volatile(
++ "MRC p15, 0, r0, c2, c0, 0;"
++ "MOV %0, r0;"
++ : "=r" (value)
++ :
++ : "r0");
++ return value & CP15R2_RESERVED;
++}
++
++unsigned long CoPro15Regs_GetCP15Reg3(void) {
++ unsigned long value;
++ asm volatile(
++ "MRC p15, 0, r0, c3, c0, 0;"
++ "MOV %0, r0;"
++ : "=r" (value)
++ :
++ : "r0");
++ return value;
++}
++
++void CoPro15Regs_SetCP15Reg3(unsigned long value) {
++ asm volatile(
++ "MOV r0, %0;"
++ "MCR p15, 0, r0, c3, c0, 0;"
++ :
++ : "r" (value)
++ : "r0");
++}
++
++void CoPro15Regs_SetCP15Reg2(unsigned long value) {
++ asm volatile(
++ "MOV r0, %0;"
++ "MCR p15, 0, r0, c2, c0, 0;"
++ :
++ : "r" (value & CP15R2_RESERVED)
++ : "r0");
++}
++
++void Cache_CleanDataCache(void)
++{
++ // Clean the data cache - usually precedes a data cache invalidation.
++ // Forces the data cache content to be written to main memory - only
++ // required if using write-back data cache
++ asm volatile(
++ "MOV r3,pc;"
++ "LDR r1, =0;"
++ " MOV r4,pc;"
++ " LDR r0, =0;"
++ " ORR r2, r1, r0;"
++ " MCR p15, 0, r2, c7, c10, 2 ;" // I (BHC) think that this should be c10, 2 not c14, 1 -- See ARM ARM
++ " ADD r0, r0, #0x10;"
++ " CMP r0,#0x40;"
++ " BXNE r4;"
++ " ADD r1, r1, #0x04000000;"
++ " CMP r1, #0x0;"
++ "BXNE r3;"
++ :
++ :
++ : "r0","r1","r2","r3","r4");
++}
++
++void Cache_DrainWriteBuffer(void)
++{
++ // Forces the write buffer to update to main memory
++ asm volatile(
++ "LDR r1, =0;"
++ "MCR p15, 0, r1, c7, c10, 4 ;"
++ :
++ :
++ : "r1");
++}
++
++void Cache_FlushPrefetchBuffer(void)
++{
++ // Forces the CPU to flush the instruction prefetch buffer
++ asm volatile(
++ "LDR r1, =0;"
++ "MCR p15, 0, r1, c7, c5, 4 ;"
++ :
++ :
++ : "r1");
++}
++
++void Cache_InvalidateDataCache(void)
++{
++ asm volatile(
++ "LDR r1, =0;"
++ "MCR p15, 0, r1, c7, c6, 0;"
++ :
++ :
++ : "r1");
++}
++
++void Cache_InvalidateInstructionCache(void)
++{
++ asm volatile(
++ "LDR r1, =0;"
++ "MCR p15, 0, r1, c7, c5, 0;"
++ :
++ :
++ : "r1");
++}
++
++void Cache_InstOn(void)
++{
++ // Invalidate the instruction cache, in case there's anything
++ // left from when it was last enabled
++ Cache_InvalidateInstructionCache();
++
++ // Enable the instruction cache
++ CoPro15Regs_SetCP15Reg1(CP15R1_I_ENABLE);
++}
++
++void Cache_InstOff(void)
++{
++ // Disable the instruction cache
++ CoPro15Regs_ClearCP15Reg1(CP15R1_I_ENABLE);
++}
++
++void Cache_DataOn(void)
++{
++ // Invalidate the data cache, in case there's anything left from when
++ // it was last enabled
++ Cache_InvalidateDataCache();
++
++ // Enable the data cache
++ CoPro15Regs_SetCP15Reg1(CP15R1_C_ENABLE);
++}
++
++void Cache_DataOff(void)
++{
++ // Ensure all data in data cache or write buffer is written to memory
++ Cache_CleanDataCache();
++ Cache_DrainWriteBuffer();
++
++ // Disable the data cache
++ CoPro15Regs_ClearCP15Reg1(CP15R1_C_ENABLE);
++}
++
++void Cache_WriteBufferOn(void)
++{
++ // Enable the write buffer
++ CoPro15Regs_SetCP15Reg1(CP15R1_W_ENABLE);
++}
++
++void Cache_WriteBufferOff(void)
++{
++ // Ensure all data in the write buffer is written to memory
++ Cache_DrainWriteBuffer();
++
++ // Disable the write buffer
++ CoPro15Regs_ClearCP15Reg1(CP15R1_W_ENABLE);
++}
++
++int MMU_SetDomainAccessValue(
++ int domainNumber,
++ int value) {
++ int status = 0;
++ if ((value < NUM_DOMAIN_ACCESS_VALUES) && (domainNumber < NUM_DOMAINS))
++ {
++ // Insert the 2-bit domain field into the slot for the specified domain
++ unsigned long registerContents = CoPro15Regs_GetCP15Reg3();
++ registerContents &= ~(3UL << (2*domainNumber));
++ registerContents |= ((unsigned long)value << (2*domainNumber));
++ CoPro15Regs_SetCP15Reg3(registerContents);
++ status = 1;
++ }
++ return status;
++}
++
++void MMU_SetAlignmentChecked(int alignmentChecked) {
++ alignmentChecked ? CoPro15Regs_SetCP15Reg1(CP15R1_A_ENABLE) : CoPro15Regs_ClearCP15Reg1(CP15R1_A_ENABLE);
++}
++
++void MMU_SetEnabled(int enabled) {
++ enabled ? CoPro15Regs_SetCP15Reg1(CP15R1_M_ENABLE) : CoPro15Regs_ClearCP15Reg1(CP15R1_M_ENABLE);
++}
++void MMU_InvalidateDataTLB(void)
++{
++ asm volatile(
++ "MCR p15, 0, r0, c8, c6, 0;"
++ :
++ :
++ : "r0");
++}
++
++void MMU_InvalidateInstructionTLB(void)
++{
++ asm volatile(
++ "MCR p15, 0, r0, c8, c5, 0;"
++ :
++ :
++ : "r0");
++}
++
++void MMU_SetROMPermission(int rOM_Permitted) {
++ rOM_Permitted ? CoPro15Regs_SetCP15Reg1(CP15R1_ROM) : CoPro15Regs_ClearCP15Reg1(CP15R1_ROM);
++}
++
++void MMU_SetSystemPermission(int systemPermitted) {
++ systemPermitted ? CoPro15Regs_SetCP15Reg1(CP15R1_SYSTEM) : CoPro15Regs_ClearCP15Reg1(CP15R1_SYSTEM);
++}
++
++void MMU_SetTranslationTableBaseAddress(unsigned long *baseAddress) {
++ CoPro15Regs_SetCP15Reg2((unsigned long)baseAddress);
++}
++
++unsigned long SetBit(
++ unsigned long source,
++ int state,
++ int offset)
++{
++ source = state ? (source | (1UL << offset)) :
++ (source & ~(1UL << offset));
++ return source;
++}
++
++unsigned long SetField(
++ unsigned long source,
++ unsigned long newFieldContents,
++ int offset,
++ int length)
++{
++ unsigned long mask = (1UL << length) - 1;
++ source &= ~(mask << offset);
++ source |= ((newFieldContents & mask) << offset);
++ return source;
++}
++
++unsigned long FD_SetUserData(
++ unsigned long userData,
++ unsigned long descriptor)
++{
++ return SetField(descriptor, userData, FD_USER_DATA_BIT, FD_USER_DATA_NUM_BITS);
++}
++
++unsigned long FLPT_CreateFaultDescriptor(unsigned long userData)
++{
++ unsigned long descriptor = FAULT_ID;
++ descriptor = FD_SetUserData(userData, descriptor);
++ return descriptor;
++}
++
++void FLPT_InsertFaultDescriptor(
++ unsigned long *tableBaseAdr,
++ int index,
++ unsigned long descriptor)
++{
++ *(tableBaseAdr + index) = descriptor;
++}
++
++unsigned long SD_SetAccessPermission(
++ int ap,
++ unsigned long descriptor)
++{
++ return SetField(descriptor, ap, SD_AP_BIT, SD_AP_NUM_BITS);
++}
++
++unsigned long SD_SetBaseAddress(
++ unsigned long baseAddress,
++ unsigned long descriptor)
++{
++ unsigned long mask = ~0UL << SD_ADDRESS_BIT;
++ baseAddress &= mask;
++ descriptor &= ~mask;
++ descriptor |= baseAddress;
++ return descriptor;
++}
++
++unsigned long SD_SetBufferable(
++ int bufferable,
++ unsigned long descriptor)
++{
++ return SetBit(descriptor, bufferable, SD_BUFFERABLE_BIT);
++}
++
++unsigned long SD_SetCacheable(
++ int cacheable,
++ unsigned long descriptor)
++{
++ return SetBit(descriptor, cacheable, SD_CACHEABLE_BIT);
++}
++
++unsigned long SD_SetDomain(
++ int domain,
++ unsigned long descriptor)
++{
++ return SetField(descriptor, domain, SD_DOMAIN_BIT, SD_DOMAIN_NUM_BITS);
++}
++
++unsigned long SD_SetImplementationDefined(
++ unsigned long implementationDefined,
++ unsigned long descriptor)
++{
++ return SetBit(descriptor, implementationDefined, SD_IMP_BIT);
++}
++
++unsigned long FLPT_CreateSectionDescriptor(
++ unsigned long baseAddress,
++ unsigned char domain,
++ int implementationDefined,
++ int ap,
++ int bufferable,
++ int cacheable)
++{
++ unsigned long descriptor = FLD_SECTION_ID;
++ descriptor = SD_SetAccessPermission(ap, descriptor);
++ descriptor = SD_SetBaseAddress(baseAddress, descriptor);
++ descriptor = SD_SetBufferable(bufferable, descriptor);
++ descriptor = SD_SetCacheable(cacheable, descriptor);
++ descriptor = SD_SetDomain(domain, descriptor);
++ descriptor = SD_SetImplementationDefined(implementationDefined, descriptor);
++ return descriptor;
++}
++
++void FLPT_InsertSectionDescriptor(
++ unsigned long *tableBaseAdr,
++ int index,
++ unsigned long descriptor)
++{
++ *(tableBaseAdr + index) = descriptor;
++}
++
++void FLPT_Zeroise(
++ unsigned long *base_adr,
++ int numberOfdescriptors) {
++ unsigned long faultDescriptor = FLPT_CreateFaultDescriptor(0);
++ int i;
++ for (i=0; i < numberOfdescriptors; i++) {
++ FLPT_InsertFaultDescriptor(base_adr, i, faultDescriptor);
++ }
++}
++
++void configure_caches(void)
++{
++ // Disable caches
++// Cache_DataOff();
++printf("1");
++ Cache_InstOff();
++// Cache_WriteBufferOff();
++
++ // Disable MMU
++printf("2");
++ MMU_SetEnabled(0);
++printf("3");
++ MMU_InvalidateDataTLB();
++printf("4");
++ MMU_InvalidateInstructionTLB();
++
++ // Setup the MMU
++printf("5");
++ MMU_SetAlignmentChecked(1);
++printf("6");
++ MMU_SetROMPermission(0);
++printf("7");
++ MMU_SetSystemPermission(1);
++
++ // Allow client access to all protection domains
++ int i;
++ for (i=0; i < NUM_DOMAINS; i++) {
++ MMU_SetDomainAccessValue(i, DAV_CLIENT);
++ }
++printf("8");
++
++ // Allocate first level page table, which we'll populate only with section
++ // descriptors, which cover 1MB each. Table must be aligned to a 16KB
++ // boundary.
++ // We'll put it 4KB into the SRAM and it will occupy:
++ // 64 entries for SDRAM
++ // 1 entry for SRAM
++ // 16 entries for APB bridge A
++ // 16 entries for APB bridge B
++ // The largest memory address we need to map is that of the SRAM at
++ // 0x4c000000 -> (4c000000/2^20)*4 = offset 1300h from table start ->
++ // require at least 1300h/4 +1 entries in table = 1217
++ unsigned long *firstLevelPageTableBaseAdr = (unsigned long*)SRAM_BASE;
++ FLPT_Zeroise(firstLevelPageTableBaseAdr, 4096);
++printf("9");
++
++ // Map entire adr space uncached, unbuffered, read/write, virtual == physical
++ unsigned megabytesPresent = 4096;
++ unsigned index = 0;
++ for (i=0; i < megabytesPresent; i++) {
++ FLPT_InsertSectionDescriptor(
++ firstLevelPageTableBaseAdr,
++ index,
++ FLPT_CreateSectionDescriptor(
++ index * 1024 * 1024, // Base address
++ 0, // Domain number
++ 0, // Implementation defined
++ AP_LEVEL_1, // Access permissions
++ 0, // Bufferable
++ 0)); // Cacheable
++
++ ++index;
++ }
++printf("10");
++
++ // Map SDRAM as cached and buffered, read/write, virtual == physical
++ megabytesPresent = 64;
++ index = PHYS_SDRAM_1_PA / (1024 * 1024);
++ for (i=0; i < megabytesPresent; i++) {
++ FLPT_InsertSectionDescriptor(
++ firstLevelPageTableBaseAdr,
++ index,
++ FLPT_CreateSectionDescriptor(
++ index * 1024 * 1024, // Base address
++ 0, // Domain number
++ 0, // Implementation defined
++ AP_LEVEL_1, // Access permissions
++ 1, // Bufferable
++ 1)); // Cacheable
++
++ ++index;
++ }
++printf("11");
++
++ // Map SRAM as cached and buffered, read/write, virtual == physical
++ megabytesPresent = 1; // Actually only 32KB
++ index = SRAM_BASE / (1024 * 1024);
++ for (i=0; i < megabytesPresent; i++) {
++ FLPT_InsertSectionDescriptor(
++ firstLevelPageTableBaseAdr,
++ index,
++ FLPT_CreateSectionDescriptor(
++ index * 1024 * 1024, // Base address
++ 0, // Domain number
++ 0, // Implementation defined
++ AP_LEVEL_1, // Access permissions
++ 1, // Bufferable
++ 1)); // Cacheable
++
++ ++index;
++ }
++printf("12");
++
++ // Map APB bridge A address space as uncached, unbuffered, read/write,
++ // virtual == physical
++ megabytesPresent = 16;
++ index = APB_BRIDGE_A_BASE_PA / (1024 * 1024);
++ for (i=0; i < megabytesPresent; i++) {
++ FLPT_InsertSectionDescriptor(
++ firstLevelPageTableBaseAdr,
++ index,
++ FLPT_CreateSectionDescriptor(
++ index * 1024 * 1024, // Base address
++ 0, // Domain number
++ 0, // Implementation defined
++ AP_LEVEL_1, // Access permissions
++ 0, // Bufferable
++ 0)); // Cacheable
++
++ ++index;
++ }
++printf("13");
++
++ // Map APB bridge B address space as uncached, unbuffered, read/write,
++ // virtual == physical
++ megabytesPresent = 16;
++ index = APB_BRIDGE_B_BASE_PA / (1024 * 1024);
++ for (i=0; i < megabytesPresent; i++) {
++ FLPT_InsertSectionDescriptor(
++ firstLevelPageTableBaseAdr,
++ index,
++ FLPT_CreateSectionDescriptor(
++ index * 1024 * 1024, // Base address
++ 0, // Domain number
++ 0, // Implementation defined
++ AP_LEVEL_1, // Access permissions
++ 0, // Bufferable
++ 0)); // Cacheable
++
++ ++index;
++ }
++printf("14");
++
++ // Load base address of first level page table
++ MMU_SetTranslationTableBaseAddress(firstLevelPageTableBaseAdr);
++printf("15");
++
++ // Enable MMU
++ MMU_SetEnabled(1);
++printf("16");
++
++ // Enable caches
++ Cache_DataOn();
++printf("17");
++ Cache_InstOn();
++printf("18");
++ Cache_WriteBufferOn();
++printf("19");
++}
++
+diff -Nurd u-boot-1.1.2/include/asm-arm/barrier.h u-boot-1.1.2-oxe810/include/asm-arm/barrier.h
+--- u-boot-1.1.2/include/asm-arm/barrier.h 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-1.1.2-oxe810/include/asm-arm/barrier.h 2008-06-11 17:55:08.000000000 +0200
+@@ -0,0 +1,25 @@
++#if !defined(__BARRIER_H__)
++#define __BARRIER_H__
++
++static inline void rmb(void)
++{
++ asm volatile ("" : : : "memory");
++}
++
++/*
++ * wmb() Would normally need to ensure shared memory regions are marked as
++ * non-cacheable and non-bufferable, then the work to be done by wmb() is
++ * to ensure the compiler and any possible CPU out of order writes are
++ * flushed to memory, however we have no data cache and as far as I'm
++ * aware we can't use the MMU to set page properties, so in our case wmb()
++ * must cause the compiler to flush.
++ */
++
++static inline void wmb(void)
++{
++ // Cause the compiler to flush any registers containing pending write data
++ // to memory
++ asm volatile ("" : : : "memory");
++
++}
++#endif // #if !defined(__BARRIER_H__)
+diff -Nurd u-boot-1.1.2/include/asm-arm/global_data.h u-boot-1.1.2-oxe810/include/asm-arm/global_data.h
+--- u-boot-1.1.2/include/asm-arm/global_data.h 2003-10-10 12:05:43.000000000 +0200
++++ u-boot-1.1.2-oxe810/include/asm-arm/global_data.h 2008-06-11 17:55:08.000000000 +0200
+@@ -61,6 +61,7 @@
+ #define GD_FLG_DEVINIT 0x00002 /* Devices have been initialized */
+ #define GD_FLG_SILENT 0x00004 /* Silent mode */
+
+-#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8")
++#define DECLARE_GLOBAL_DATA_PTR register gd_t* volatile gd asm ("r8");
+
+ #endif /* __ASM_GBL_DATA_H */
++
+diff -Nurd u-boot-1.1.2/include/asm-arm/mach-types.h u-boot-1.1.2-oxe810/include/asm-arm/mach-types.h
+--- u-boot-1.1.2/include/asm-arm/mach-types.h 2004-10-10 20:41:14.000000000 +0200
++++ u-boot-1.1.2-oxe810/include/asm-arm/mach-types.h 2008-06-11 17:55:08.000000000 +0200
+@@ -624,6 +624,7 @@
+ #define MACH_TYPE_RMS100 611
+ #define MACH_TYPE_KB9200 612
+ #define MACH_TYPE_SX1 613
++#define MACH_TYPE_OXNAS 1152
+
+ #ifdef CONFIG_ARCH_EBSA110
+ # ifdef machine_arch_type
+@@ -7945,6 +7946,18 @@
+ # define machine_is_sx1() (0)
+ #endif
+
++#ifdef CONFIG_MACH_OXNAS
++# ifdef machine_arch_type
++# undef machine_arch_type
++# define machine_arch_type __machine_arch_type
++# else
++# define machine_arch_type MACH_TYPE_OXNAS
++# endif
++# define machine_is_oxnas() (machine_arch_type == MACH_TYPE_OXNAS)
++#else
++# define machine_is_oxnas() (0)
++#endif
++
+ /*
+ * These have not yet been registered
+ */
+diff -Nurd u-boot-1.1.2/include/asm-arm/u-boot.h u-boot-1.1.2-oxe810/include/asm-arm/u-boot.h
+--- u-boot-1.1.2/include/asm-arm/u-boot.h 2002-11-03 01:33:10.000000000 +0100
++++ u-boot-1.1.2-oxe810/include/asm-arm/u-boot.h 2008-06-11 17:55:08.000000000 +0200
+@@ -41,6 +41,8 @@
+ ulong start;
+ ulong size;
+ } bi_dram[CONFIG_NR_DRAM_BANKS];
++ unsigned long bi_sramstart; /* start of SRAM memory */
++ unsigned long bi_sramsize; /* size of SRAM memory */
+ } bd_t;
+
+ #define bi_env_data bi_env->data
+diff -Nurd u-boot-1.1.2/include/ata.h u-boot-1.1.2-oxe810/include/ata.h
+--- u-boot-1.1.2/include/ata.h 2004-03-14 23:25:50.000000000 +0100
++++ u-boot-1.1.2-oxe810/include/ata.h 2008-06-11 17:55:11.000000000 +0200
+@@ -80,7 +80,12 @@
+ /*
+ * Device / Head Register Bits
+ */
++#ifdef CONFIG_OXNAS
++#define ATA_DEVICE(x) (0)
++#else
+ #define ATA_DEVICE(x) ((x & 1)<<4)
++#endif // CONFIG_OXNAS
++
+ #define ATA_LBA 0xE0
+
+ /*
+diff -Nurd u-boot-1.1.2/include/cmd_confdefs.h u-boot-1.1.2-oxe810/include/cmd_confdefs.h
+--- u-boot-1.1.2/include/cmd_confdefs.h 2004-12-16 18:59:53.000000000 +0100
++++ u-boot-1.1.2-oxe810/include/cmd_confdefs.h 2008-06-11 17:55:11.000000000 +0200
+@@ -92,6 +92,7 @@
+ #define CFG_CMD_XIMG 0x0400000000000000ULL /* Load part of Multi Image */
+ #define CFG_CMD_UNIVERSE 0x0800000000000000ULL /* Tundra Universe Support */
+ #define CFG_CMD_EXT2 0x1000000000000000ULL /* EXT2 Support */
++#define CFG_CMD_LEDFAIL 0x2000000000000000ULL /* OXNAS Failure LED support */
+
+ #define CFG_CMD_ALL 0xFFFFFFFFFFFFFFFFULL /* ALL commands */
+
+diff -Nurd u-boot-1.1.2/include/common.h u-boot-1.1.2-oxe810/include/common.h
+--- u-boot-1.1.2/include/common.h 2004-12-13 10:49:01.000000000 +0100
++++ u-boot-1.1.2-oxe810/include/common.h 2008-06-11 17:55:11.000000000 +0200
+@@ -204,7 +204,7 @@
+ /* common/cmd_nvedit.c */
+ int env_init (void);
+ void env_relocate (void);
+-char *getenv (uchar *);
++char *getenv (const uchar *);
+ int getenv_r (uchar *name, uchar *buf, unsigned len);
+ int saveenv (void);
+ #ifdef CONFIG_PPC /* ARM version to be fixed! */
+diff -Nurd u-boot-1.1.2/include/configs/oxnas.h u-boot-1.1.2-oxe810/include/configs/oxnas.h
+--- u-boot-1.1.2/include/configs/oxnas.h 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-1.1.2-oxe810/include/configs/oxnas.h 2008-06-12 13:57:57.000000000 +0200
+@@ -0,0 +1,593 @@
++/*
++ * (C) Copyright 2005
++ * Oxford Semiconductor Ltd
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * 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 __CONFIG_H
++#define __CONFIG_H
++
++#define readb(p) (*(volatile u8 *)(p))
++#define readl(p) (*(volatile u32 *)(p))
++#define writeb(v, p) (*(volatile u8 *)(p)= (v))
++#define writel(v, p) (*(volatile u32*)(p)=(v))
++
++#define CFG_FLASH_EMPTY_INFO
++
++/**
++ * Architecture
++ */
++#define CONFIG_ARM926EJS 1
++#define CONFIG_OXNAS 1
++#define CONFIG_OXNAS_ENABLE_PCI /* Enables PCI clock and takes out of reset - needed if require access to static bus */
++#define CONFIG_OXNAS_FEEDBACK_PCI_CLKS /* Feedback PCI clock out 3 to drive PCI core clock - needed if require access to static bus */
++#define CONFIG_OXNAS_MANUAL_STATIC_ARBITRATION
++#if (USE_SATA == 1)
++#define CONFIG_OXNAS_USE_SATA /* Define to include support for SATA disks */
++#if (USE_SATA_ENV == 1)
++#define ENV_ON_SATA /* Define to have the U-Boot env. stored on SATA disk */
++#endif // USE_SATA_ENV
++#endif // USE_SATA
++#if (USE_FLASH == 0)
++#define CFG_NO_FLASH /* Define to NOT include flash support on static bus*/
++#endif //USE_FLASH
++
++/* Won't be using any interrupts */
++#undef CONFIG_USE_IRQ
++
++/* Everything, incl board info, in Hz */
++#undef CFG_CLKS_IN_HZ
++
++#define CFG_HUSH_PARSER 1
++#define CFG_PROMPT_HUSH_PS2 "> "
++
++/* Miscellaneous configurable options */
++#define CFG_LONGHELP /* undef to save memory */
++#ifdef CFG_HUSH_PARSER
++#define CFG_PROMPT "$ " /* Monitor Command Prompt */
++#else
++#define CFG_PROMPT "# " /* Monitor Command Prompt */
++#endif
++#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
++
++/* Print Buffer Size */
++#define CFG_PBSIZE ((CFG_CBSIZE)+sizeof(CFG_PROMPT)+16)
++#define CFG_MAXARGS 16 /* max number of command args */
++#define CFG_BARGSIZE (CFG_CBSIZE) /* Boot Argument Buffer Size */
++
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_MISC_INIT_R 1 /* call misc_init_r during start up */
++#define CONFIG_INITRD_TAG 1 /* allow initrd tag to be generated */
++
++/* May want to do some setup prior to relocation */
++#define CONFIG_INIT_CRITICAL
++
++/* ARM specific late initialisation */
++#define BOARD_LATE_INIT
++
++/**
++ * Stack sizes
++ *
++ * The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE (128*1024) /* regular stack */
++#ifdef CONFIG_USE_IRQ
++#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
++#endif
++
++/**
++ * RAM
++ */
++#define CONFIG_NR_DRAM_BANKS 1 /* We have 1 bank of SDRAM */
++#define PHYS_SDRAM_1_PA 0x48000000 /* SDRAM Bank #1 */
++#if (NAS_VERSION == 810)
++#define PHYS_SDRAM_1_MAX_SIZE (256 * 1024 * 1024)
++#endif // NAS_VERSION
++#define CFG_SRAM_BASE ((PHYS_SDRAM_1_PA) + (PHYS_SDRAM_1_MAX_SIZE))
++#if (NAS_VERSION == 810)
++#define CFG_SRAM_SIZE (128 * 1024)
++#endif // NAS_VERSION
++
++#define INITIALISE_SDRAM
++
++/* Default location from which bootm etc will load */
++#define CFG_LOAD_ADDR (PHYS_SDRAM_1_PA)
++
++/**
++ * Core addresses
++ */
++#define MAC_BASE_PA 0x40400000
++#define STATIC_CS0_BASE_PA 0x41000000
++#define STATIC_CS1_BASE_PA 0x41400000
++#define STATIC_CS2_BASE_PA 0x41800000
++#define STATIC_CONTROL_BASE_PA 0x41C00000
++#define SATA_DATA_BASE_PA 0x42000000
++
++#define APB_BRIDGE_A_BASE_PA 0x44000000
++#define APB_BRIDGE_B_BASE_PA 0x45000000
++
++#define GPIO_1_PA ((APB_BRIDGE_A_BASE_PA) + 0x0)
++#define GPIO_2_PA ((APB_BRIDGE_A_BASE_PA) + 0x100000)
++
++#define SYS_CONTROL_BASE_PA ((APB_BRIDGE_B_BASE_PA) + 0x0)
++#define DMA_BASE_PA ((APB_BRIDGE_B_BASE_PA) + 0x600000)
++#define RPS_BASE ((APB_BRIDGE_B_BASE_PA) + 0x300000)
++
++/* Static bus registers */
++#define STATIC_CONTROL_VERSION ((STATIC_CONTROL_BASE_PA) + 0x0)
++#define STATIC_CONTROL_BANK0 ((STATIC_CONTROL_BASE_PA) + 0x4)
++#define STATIC_CONTROL_BANK1 ((STATIC_CONTROL_BASE_PA) + 0x8)
++#define STATIC_CONTROL_BANK2 ((STATIC_CONTROL_BASE_PA) + 0xC)
++
++/* Clock to the ARM/DDR */
++#if (FPGA == 0)
++#define NOMINAL_ARMCLK ((PLL400) / 2)
++#define NOMINAL_SYSCLK ((PLL400) / 4)
++#else // !FPGA
++#define NOMINAL_ARMCLK (FPGA_ARM_CLK)
++#define NOMINAL_SYSCLK ((PLL400) / 4)
++#endif // !FPGA
++
++/**
++ * Timer
++ */
++#define CFG_TIMERBASE ((RPS_BASE) + 0x200)
++#define TIMER_PRESCALE_BIT 2
++#define TIMER_PRESCALE_1_ENUM 0
++#define TIMER_PRESCALE_16_ENUM 1
++#define TIMER_PRESCALE_256_ENUM 2
++#define TIMER_MODE_BIT 6
++#define TIMER_MODE_FREE_RUNNING 0
++#define TIMER_MODE_PERIODIC 1
++#define TIMER_ENABLE_BIT 7
++#define TIMER_ENABLE_DISABLE 0
++#define TIMER_ENABLE_ENABLE 1
++
++#define TIMER_PRESCALE_ENUM (TIMER_PRESCALE_256_ENUM)
++#define CFG_HZ ((RPSCLK) / 256)
++
++/**
++ * GPIO
++ */
++#define GPIO_1_OE ((GPIO_1_PA) + 0x4)
++#define GPIO_1_SET_OE ((GPIO_1_PA) + 0x1C)
++#define GPIO_1_CLR_OE ((GPIO_1_PA) + 0x20)
++
++#define GPIO_2_OE ((GPIO_2_PA) + 0x4)
++#define GPIO_2_SET_OE ((GPIO_2_PA) + 0x1C)
++#define GPIO_2_CLR_OE ((GPIO_2_PA) + 0x20)
++
++/**
++ * Serial Configuration
++ */
++#define EXT_UART_BASE 0x28000000
++
++#define UART_1_BASE (APB_BRIDGE_A_BASE_PA + 0x200000)
++#define UART_2_BASE (APB_BRIDGE_A_BASE_PA + 0x300000)
++#define UART_3_BASE (APB_BRIDGE_A_BASE_PA + 0x900000)
++#define UART_4_BASE (APB_BRIDGE_A_BASE_PA + 0xA00000)
++
++#define CFG_NS16550 1
++#define CFG_NS16550_SERIAL 1
++#define CFG_NS16550_REG_SIZE 1
++
++#if (USE_EXTERNAL_UART != 0)
++#define CFG_NS16550_CLK 16000000
++#define CFG_NS16550_COM1 (EXT_UART_BASE)
++#else // USE_EXTERNAL_UART
++#define CFG_NS16550_CLK (NOMINAL_SYSCLK)
++#define USE_UART_FRACTIONAL_DIVIDER
++#if (INTERNAL_UART == 1)
++#define CONFIG_OXNAS_UART1
++#define CFG_NS16550_COM1 (UART_1_BASE)
++#elif (INTERNAL_UART == 2)
++#define CONFIG_OXNAS_UART2
++#define CFG_NS16550_COM1 (UART_2_BASE)
++#elif (INTERNAL_UART == 3)
++#define CONFIG_OXNAS_UART3
++#define CFG_NS16550_COM1 (UART_3_BASE)
++#else
++#define CONFIG_OXNAS_UART4
++#define CFG_NS16550_COM1 (UART_4_BASE)
++#endif // CONFIG_OXNAS_UART
++#endif // USE_EXTERNAL_UART
++
++#define CONFIG_CONS_INDEX 1
++#define CONFIG_BAUDRATE 115200
++#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/**
++ * Monitor commands
++ */
++#define BASE_COMMANDS (CFG_CMD_IMI | \
++ CFG_CMD_IMLS | \
++ CFG_CMD_BDI | \
++ CFG_CMD_NET | \
++ CFG_CMD_PING | \
++ CFG_CMD_ENV | \
++ CFG_CMD_RUN | \
++ CFG_CMD_MEMORY)
++
++#ifdef CFG_NO_FLASH
++#define FLASH_COMMANDS (BASE_COMMANDS)
++#else
++#define FLASH_COMMANDS (BASE_COMMANDS | CFG_CMD_FLASH)
++#endif // CFG_NO_FLASH
++
++#ifdef CONFIG_OXNAS_USE_SATA
++#define SATA_COMMANDS (FLASH_COMMANDS | CFG_CMD_IDE | CFG_CMD_EXT2 | CFG_CMD_LEDFAIL)
++#else
++#define SATA_COMMANDS (FLASH_COMMANDS)
++#endif // CONFIG_OXNAS_USE_SATA
++
++#define CONFIG_COMMANDS SATA_COMMANDS
++
++/* This must be included AFTER the definition of CONFIG_COMMANDS */
++#include <cmd_confdefs.h>
++
++/**
++ * Booting
++ */
++#if (LINUX_ROOT_RAIDED == 1)
++#define LINUX_ROOT_DEVICE "root=/dev/md1"
++#else
++#define LINUX_ROOT_DEVICE "root=/dev/sda1"
++#endif
++#define CONFIG_BOOTARGS LINUX_ROOT_DEVICE " console=ttyS0,115200 elevator=cfq gmac.mac_adr=0x00,0x30,0xe0,0x00,0x00,0x01"
++
++#ifdef CONFIG_OXNAS_USE_SATA
++#define CONFIG_BOOTDELAY 2
++#define CONFIG_BOOTCOMMAND "run select0 load boot || run select0 load2 boot || run lightled select1 load extinguishled boot || run lightled select1 load2 extinguishled boot || lightled"
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ "select0=ide dev 0\0" \
++ "select1=ide dev 1\0" \
++ "load=ide read 0x48500000 12c 1644\0" \
++ "load2=ide read 0x48500000 2a6e 1644\0" \
++ "lightled=ledfail 1\0" \
++ "extinguishled=ledfail 0\0" \
++ "boot=bootm 48500000\0"
++#else // CONFIG_OXNAS_USE_SATA
++#define CONFIG_BOOTDELAY 15
++#define CONFIG_BOOTCOMMAND "bootm 0x41020000"
++#endif // CONFIG_OXNAS_USE_SATA
++
++//#define CONFIG_SHOW_BOOT_PROGRESS 1
++
++/**
++ * Networking
++ */
++#define CONFIG_ETHADDR 00:30:e0:00:00:01
++#define CONFIG_NETMASK 255.255.0.0
++#define CONFIG_IPADDR 172.31.0.128
++#define CONFIG_SERVERIP 172.31.0.100
++#define CONFIG_BOOTFILE "uImage"
++#define CFG_AUTOLOAD "n"
++#define CONFIG_NET_RETRY_COUNT 30
++
++/**
++ * Flash support
++ */
++#ifndef CFG_NO_FLASH
++
++#define FORCE_TOP_BOOT_FLASH 1
++
++#define CFG_FLASH_CFI 1
++#define CFG_FLASH_CFI_DRIVER 1
++
++#define NUM_FLASH_MAIN_BLOCKS 63 /* For Intel 28F320B3T */
++#define NUM_FLASH_PARAM_BLOCKS 8 /* For Intel 28F320B3T */
++#define FLASH_MAIN_BLOCK_SIZE (64*1024) /* For Intel 28F320B3T family */
++#define FLASH_PARAM_BLOCK_SIZE (8*1024) /* For Intel 28F320B3T family */
++
++/* Assuming counts main blocks and parameter blocks, as the Intel/AMD detection */
++/* I'm intending to copy would seem to indicate */
++#define CFG_MAX_FLASH_SECT (NUM_FLASH_MAIN_BLOCKS + NUM_FLASH_PARAM_BLOCKS)
++
++#define CFG_MAX_FLASH_BANKS 1 /* Assume counts flash devices */
++#define FLASH_BASE_OFF 0
++#define CFG_FLASH_BASE ((STATIC_CS0_BASE_PA) + (FLASH_BASE_OFF))
++#define PHYS_FLASH_1 (CFG_FLASH_BASE)
++
++#define CFG_FLASH_ERASE_TOUT (20*CFG_HZ) /* Timeout for Flash Erase */
++#define CFG_FLASH_WRITE_TOUT (20*CFG_HZ) /* Timeout for Flash Write */
++#define CFG_FLASH_WRITE_ATTEMPTS 5
++
++#define STATIC_BUS_FLASH_CONFIG 0x4f1f3f3f /* Slow ASIC settings */
++
++#endif // !CFG_NO_FLASH
++
++/**
++ * Environment organization
++ */
++#ifdef ENV_ON_SATA
++
++/* Environment on SATA disk */
++#define SIZE_TO_SECTORS(x) ((x) / 512)
++#define CFG_ENV_IS_IN_DISK
++#define CFG_ENV_SIZE (8*1024)
++#define ENVIRONMENT_OFFSET ((CFG_SRAM_SIZE) - (CFG_ENV_SIZE) - 1024)
++#define CFG_ENV_ADDR ((CFG_SRAM_BASE) + (ENVIRONMENT_OFFSET))
++#define ROM_LOADER_LOAD_START_SECTOR 1
++#define CFG_ENV_DISK_SECTOR ((ROM_LOADER_LOAD_START_SECTOR) + SIZE_TO_SECTORS(ENVIRONMENT_OFFSET))
++#define ROM_LOADER_LOAD_REDUNDANT_START_SECTOR 10608
++#define CFG_ENV_DISK_REDUNDANT_SECTOR ((ROM_LOADER_LOAD_REDUNDANT_START_SECTOR) + SIZE_TO_SECTORS(ENVIRONMENT_OFFSET))
++
++#else
++/** Flash based environment
++ *
++ * It appears that all flash env start/size info. has to be pre-defined. How
++ * this is supposed to work when the flash detection code could cope with all
++ * sorts of different flash is hard to see.
++ * It appears from the README that with bottom/top boot flashes with smaller
++ * parameter blocks available, the environment code will only use a single
++ * one of these smaller sectors for the environment, i.e. CFG_ENV_SECT_SIZE
++ * is the size of the environment. I hope this isn't really true. The defines
++ * below may well not work if this is the truth
++ */
++#define CFG_ENV_IS_IN_FLASH
++/* Environment in flash device parameter blocks */
++#define CFG_ENV_SECT_SIZE (8*1024)
++/* First parameter block for environment */
++#define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
++/* Second parameter block for backup environment */
++#define CFG_ENV_SIZE_REDUND (CFG_ENV_SIZE)
++/* Main environment occupies first parameter block */
++#define CFG_ENV_ADDR ((CFG_FLASH_BASE)+((NUM_FLASH_MAIN_BLOCKS)*(FLASH_MAIN_BLOCK_SIZE)))
++/* Backup environment occupies second parameter block */
++#define CFG_ENV_ADDR_REDUND ((CFG_ENV_ADDR)+(CFG_ENV_SIZE))
++
++#endif // ENV_ON_SATA
++
++#define CONFIG_ENV_OVERWRITE
++
++/* Magic number that indicates rebooting into upgrade mode */
++#define UPGRADE_MAGIC 0x31 /* ASCII '1' */
++
++/* Magic number that indicates user recovery on reboot */
++/* Also defined in oxnas_user_recovery.agent */
++#define RECOVERY_MAGIC 0x31 /* ASCII '1' */
++
++/* Magic number that indicates controlled power down on reboot */
++/* Also defined in controlled_power_down.sh in init.d */
++#define CONTROLLED_POWER_DOWN_MAGIC 0x31 /* ASCII '1' */
++
++/* This flag is set in SRAM location by Co Proc */
++#define CONTROLLED_POWER_UP_MAGIC 0x31 /* ASCII '1' */
++/* 9k + a quad from top */
++/* Be carefule on changing the location of this flag
++ * u-boot has other things to write in SRAM too
++ */
++#define POWER_ON_FLAG_SRAM_OFFSET 9220
++
++/* Size of malloc() pool */
++#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024)
++#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
++
++/**
++ * ASM startup control
++ */
++/* Start of address within SRAM of loader's exception table. */
++/* ROM-based exception table will redirect to here */
++#define EXCEPTION_BASE (CFG_SRAM_BASE)
++
++/**
++ * Disk related stuff
++ */
++#define CONFIG_LBA48
++#define CONFIG_DOS_PARTITION
++#define CFG_IDE_MAXDEVICE 2
++#define CFG_IDE_MAXBUS 1
++#define CONFIG_IDE_PREINIT
++#undef CONFIG_IDE_RESET
++#undef CONFIG_IDE_LED
++#define CFG_ATA_DATA_OFFSET 0
++#define CFG_ATA_REG_OFFSET 0
++#define CFG_ATA_ALT_OFFSET 0
++
++/**
++ * System block reset and clock control
++ */
++#define SYS_CTRL_USB11_CTRL (SYS_CONTROL_BASE_PA + 0x00)
++#define SYS_CTRL_PCI_CTRL0 (SYS_CONTROL_BASE_PA + 0x04)
++#define SYS_CTRL_PCI_CTRL1 (SYS_CONTROL_BASE_PA + 0x08)
++#define SYS_CTRL_GPIO_PRIMSEL_CTRL_0 (SYS_CONTROL_BASE_PA + 0x0C)
++#define SYS_CTRL_GPIO_PRIMSEL_CTRL_1 (SYS_CONTROL_BASE_PA + 0x10)
++#define SYS_CTRL_GPIO_SECSEL_CTRL_0 (SYS_CONTROL_BASE_PA + 0x14)
++#define SYS_CTRL_GPIO_SECSEL_CTRL_1 (SYS_CONTROL_BASE_PA + 0x18)
++#define SYS_CTRL_GPIO_TERTSEL_CTRL_0 (SYS_CONTROL_BASE_PA + 0x8C)
++#define SYS_CTRL_GPIO_TERTSEL_CTRL_1 (SYS_CONTROL_BASE_PA + 0x90)
++#define SYS_CTRL_USB11_STAT (SYS_CONTROL_BASE_PA + 0x1c)
++#define SYS_CTRL_PCI_STAT (SYS_CONTROL_BASE_PA + 0x20)
++#define SYS_CTRL_CKEN_SET_CTRL (SYS_CONTROL_BASE_PA + 0x2C)
++#define SYS_CTRL_CKEN_CLR_CTRL (SYS_CONTROL_BASE_PA + 0x30)
++#define SYS_CTRL_RSTEN_SET_CTRL (SYS_CONTROL_BASE_PA + 0x34)
++#define SYS_CTRL_RSTEN_CLR_CTRL (SYS_CONTROL_BASE_PA + 0x38)
++#define SYS_CTRL_PLLSYS_CTRL (SYS_CONTROL_BASE_PA + 0x48)
++#define SYS_CTRL_PLLSYS_KEY_CTRL (SYS_CONTROL_BASE_PA + 0x6C)
++#define SYS_CTRL_GMAC_CTRL (SYS_CONTROL_BASE_PA + 0x78)
++#define SYS_CTRL_UART_CTRL (SYS_CONTROL_BASE_PA + 0x94)
++
++#define SYS_CTRL_CKEN_COPRO_BIT 0
++#define SYS_CTRL_CKEN_DMA_BIT 1
++#define SYS_CTRL_CKEN_DPE_BIT 2
++#define SYS_CTRL_CKEN_DDR_BIT 3
++#define SYS_CTRL_CKEN_SATA_BIT 4
++#define SYS_CTRL_CKEN_I2S_BIT 5
++#define SYS_CTRL_CKEN_USBHS_BIT 6
++#define SYS_CTRL_CKEN_MAC_BIT 7
++#define SYS_CTRL_CKEN_PCI_BIT 8
++#define SYS_CTRL_CKEN_STATIC_BIT 9
++#define SYS_CTRL_CKEN_DDR_PHY_BIT 10
++
++#define SYS_CTRL_RSTEN_ARM_BIT 0
++#define SYS_CTRL_RSTEN_COPRO_BIT 1
++#define SYS_CTRL_RSTEN_USBHS_BIT 4
++#define SYS_CTRL_RSTEN_USBHSPHY_BIT 5
++#define SYS_CTRL_RSTEN_MAC_BIT 6
++#define SYS_CTRL_RSTEN_PCI_BIT 7
++#define SYS_CTRL_RSTEN_DMA_BIT 8
++#define SYS_CTRL_RSTEN_DPE_BIT 9
++#define SYS_CTRL_RSTEN_DDR_BIT 10
++#define SYS_CTRL_RSTEN_SATA_BIT 11
++#define SYS_CTRL_RSTEN_SATA_LINK_BIT 12
++#define SYS_CTRL_RSTEN_SATA_PHY_BIT 13
++#define SYS_CTRL_RSTEN_STATIC_BIT 15
++#define SYS_CTRL_RSTEN_GPIO_BIT 16
++#define SYS_CTRL_RSTEN_UART1_BIT 17
++#define SYS_CTRL_RSTEN_UART2_BIT 18
++#define SYS_CTRL_RSTEN_MISC_BIT 19
++#define SYS_CTRL_RSTEN_I2S_BIT 20
++#define SYS_CTRL_RSTEN_AHB_MON_BIT 21
++#define SYS_CTRL_RSTEN_UART3_BIT 22
++#define SYS_CTRL_RSTEN_UART4_BIT 23
++#define SYS_CTRL_RSTEN_SGDMA_BIT 24
++#define SYS_CTRL_RSTEN_DDR_PHY_BIT 25
++#define SYS_CTRL_RSTEN_BUS_BIT 31
++
++#define SYS_CTRL_GMAC_RGMII 2
++#define SYS_CTRL_GMAC_SIMPLE_MAX 1
++#define SYS_CTRL_GMAC_CKEN_GTX 0
++
++#define SYS_CTRL_CKCTRL_CTRL_ADDR (SYS_CONTROL_BASE_PA + 0x64)
++
++#define SYS_CTRL_CKCTRL_PCI_DIV_BIT 0
++#define SYS_CTRL_CKCTRL_SLOW_BIT 8
++
++#define SYS_CTRL_UART2_DEQ_EN 0
++#define SYS_CTRL_UART3_DEQ_EN 1
++#define SYS_CTRL_UART3_IQ_EN 2
++#define SYS_CTRL_UART4_IQ_EN 3
++#define SYS_CTRL_UART4_NOT_PCI_MODE 4
++
++#define SYS_CTRL_PCI_CTRL1_PCI_STATIC_RQ_BIT 11
++
++/**
++ * SATA related definitions
++ */
++#define ATA_PORT_CTL 0
++#define ATA_PORT_FEATURE 1
++#define ATA_PORT_NSECT 2
++#define ATA_PORT_LBAL 3
++#define ATA_PORT_LBAM 4
++#define ATA_PORT_LBAH 5
++#define ATA_PORT_DEVICE 6
++#define ATA_PORT_COMMAND 7
++
++#define SATA_0_REGS_BASE (APB_BRIDGE_B_BASE_PA + 0x900000)
++#define SATA_1_REGS_BASE (APB_BRIDGE_B_BASE_PA + 0x910000)
++#define SATA_HOST_REGS_BASE (APB_BRIDGE_B_BASE_PA + 0x9e0000)
++
++/* The offsets to the SATA registers */
++#define SATA_ORB1_OFF 0
++#define SATA_ORB2_OFF 1
++#define SATA_ORB3_OFF 2
++#define SATA_ORB4_OFF 3
++#define SATA_ORB5_OFF 4
++
++#define SATA_FIS_ACCESS 11
++#define SATA_INT_STATUS_OFF 12 /* Read only */
++#define SATA_INT_CLR_OFF 12 /* Write only */
++#define SATA_INT_ENABLE_OFF 13 /* Read only */
++#define SATA_INT_ENABLE_SET_OFF 13 /* Write only */
++#define SATA_INT_ENABLE_CLR_OFF 14 /* Write only */
++#define SATA_VERSION_OFF 15
++#define SATA_CONTROL_OFF 23
++#define SATA_COMMAND_OFF 24
++#define SATA_PORT_CONTROL_OFF 25
++#define SATA_DRIVE_CONTROL_OFF 26
++
++/* The offsets to the link registers that are access in an asynchronous manner */
++#define SATA_LINK_DATA 28
++#define SATA_LINK_RD_ADDR 29
++#define SATA_LINK_WR_ADDR 30
++#define SATA_LINK_CONTROL 31
++
++/* SATA interrupt status register fields */
++#define SATA_INT_STATUS_EOC_RAW_BIT ( 0 + 16)
++#define SATA_INT_STATUS_ERROR_BIT ( 2 + 16)
++#define SATA_INT_STATUS_EOADT_RAW_BIT ( 1 + 16)
++
++/* SATA core command register commands */
++#define SATA_CMD_WRITE_TO_ORB_REGS 2
++#define SATA_CMD_WRITE_TO_ORB_REGS_NO_COMMAND 4
++
++#define SATA_CMD_BUSY_BIT 7
++
++#define SATA_SCTL_CLR_ERR 0x00000316UL
++
++#define SATA_OPCODE_MASK 0x3
++
++#define SATA_LBAL_BIT 0
++#define SATA_LBAM_BIT 8
++#define SATA_LBAH_BIT 16
++#define SATA_HOB_LBAH_BIT 24
++#define SATA_DEVICE_BIT 24
++#define SATA_NSECT_BIT 0
++#define SATA_FEATURE_BIT 16
++#define SATA_COMMAND_BIT 24
++#define SATA_CTL_BIT 24
++
++/* ATA status (7) register field definitions */
++#define ATA_STATUS_BSY_BIT 7
++#define ATA_STATUS_DRDY_BIT 6
++#define ATA_STATUS_DF_BIT 5
++#define ATA_STATUS_DRQ_BIT 3
++#define ATA_STATUS_ERR_BIT 0
++
++/* ATA device (6) register field definitions */
++#define ATA_DEVICE_FIXED_MASK 0xA0
++#define ATA_DEVICE_DRV_BIT 4
++#define ATA_DEVICE_DRV_NUM_BITS 1
++#define ATA_DEVICE_LBA_BIT 6
++
++/* ATA control (0) register field definitions */
++#define ATA_CTL_SRST_BIT 2
++
++/* ATA Command register initiated commands */
++#define ATA_CMD_INIT 0x91
++#define ATA_CMD_IDENT 0xEC
++
++#define SATA_STD_ASYNC_REGS_OFF 0x20
++#define SATA_SCR_STATUS 0
++#define SATA_SCR_ERROR 1
++#define SATA_SCR_CONTROL 2
++#define SATA_SCR_ACTIVE 3
++#define SATA_SCR_NOTIFICAION 4
++
++#define SATA_BURST_BUF_FORCE_EOT_BIT 0
++#define SATA_BURST_BUF_DATA_INJ_ENABLE_BIT 1
++#define SATA_BURST_BUF_DIR_BIT 2
++#define SATA_BURST_BUF_DATA_INJ_END_BIT 3
++#define SATA_BURST_BUF_FIFO_DIS_BIT 4
++#define SATA_BURST_BUF_DIS_DREQ_BIT 5
++#define SATA_BURST_BUF_DREQ_BIT 6
++
++/* Button on GPIO 32 */
++#define RECOVERY_BUTTON (0x00000001 << 0)
++#define RECOVERY_PRISEL_REG SYS_CTRL_GPIO_PRIMSEL_CTRL_1
++#define RECOVERY_SECSEL_REG SYS_CTRL_GPIO_SECSEL_CTRL_1
++#define RECOVERY_TERSEL_REG SYS_CTRL_GPIO_TERTSEL_CTRL_1
++#define RECOVERY_CLR_OE_REG GPIO_2_CLR_OE
++#define RECOVERY_DEBOUNCE_REG GPIO_2_INPUT_DEBOUNCE_ENABLE
++#define RECOVERY_DATA GPIO_2_PA
++
++#endif // CONFIG_H
+diff -Nurd u-boot-1.1.2/include/_exports.h u-boot-1.1.2-oxe810/include/_exports.h
+--- u-boot-1.1.2/include/_exports.h 2003-09-12 17:35:33.000000000 +0200
++++ u-boot-1.1.2-oxe810/include/_exports.h 2008-06-11 17:55:11.000000000 +0200
+@@ -12,6 +12,7 @@
+ EXPORT_FUNC(get_timer)
+ EXPORT_FUNC(vprintf)
+ EXPORT_FUNC(do_reset)
++EXPORT_FUNC(raise)
+ #if (CONFIG_COMMANDS & CFG_CMD_I2C)
+ EXPORT_FUNC(i2c_write)
+ EXPORT_FUNC(i2c_read)
+diff -Nurd u-boot-1.1.2/include/flash.h u-boot-1.1.2-oxe810/include/flash.h
+--- u-boot-1.1.2/include/flash.h 2004-12-16 19:01:48.000000000 +0100
++++ u-boot-1.1.2-oxe810/include/flash.h 2008-06-11 17:55:11.000000000 +0200
+@@ -207,6 +207,7 @@
+ #define ATM_ID_BV1614 0x000000C0 /* 49BV1614 ID */
+ #define ATM_ID_BV1614A 0x000000C8 /* 49BV1614A ID */
+ #define ATM_ID_BV6416 0x000000D6 /* 49BV6416 ID */
++#define ATM_ID_BV322 0x000000c9 /* 49BV322A ID */
+
+ #define FUJI_ID_29F800BA 0x22582258 /* MBM29F800BA ID (8M) */
+ #define FUJI_ID_29F800TA 0x22D622D6 /* MBM29F800TA ID (8M) */
+@@ -405,6 +406,7 @@
+ #define FLASH_MAN_INTEL 0x00300000
+ #define FLASH_MAN_MT 0x00400000
+ #define FLASH_MAN_SHARP 0x00500000
++#define FLASH_MAN_ATM 0x00070000 /* Atmel */
+
+
+ #define FLASH_TYPEMASK 0x0000FFFF /* extract FLASH type information */
+diff -Nurd u-boot-1.1.2/include/ns16550.h u-boot-1.1.2-oxe810/include/ns16550.h
+--- u-boot-1.1.2/include/ns16550.h 2004-06-07 01:13:57.000000000 +0200
++++ u-boot-1.1.2-oxe810/include/ns16550.h 2008-06-11 17:55:11.000000000 +0200
+@@ -19,6 +19,10 @@
+ unsigned char lsr; /* 5 */
+ unsigned char msr; /* 6 */
+ unsigned char scr; /* 7 */
++#if defined(CONFIG_OXNAS)
++ unsigned char ext; /* 8 */
++ unsigned char dlf; /* 9 */
++#endif
+ #if defined(CONFIG_OMAP730)
+ unsigned char mdr1; /* 8 */
+ unsigned char reg9; /* 9 */
+diff -Nurd u-boot-1.1.2/lib_arm/board.c u-boot-1.1.2-oxe810/lib_arm/board.c
+--- u-boot-1.1.2/lib_arm/board.c 2004-08-02 00:48:22.000000000 +0200
++++ u-boot-1.1.2-oxe810/lib_arm/board.c 2008-06-11 17:55:06.000000000 +0200
+@@ -39,6 +39,9 @@
+ #include "../drivers/lan91c96.h"
+ #endif
+
++DECLARE_GLOBAL_DATA_PTR
++
++
+ #if (CONFIG_COMMANDS & CFG_CMD_NAND)
+ void nand_init (void);
+ #endif
+@@ -106,7 +109,6 @@
+
+ static int init_baudrate (void)
+ {
+- DECLARE_GLOBAL_DATA_PTR;
+
+ uchar tmp[64]; /* long enough for environment variables */
+ int i = getenv_r ("baudrate", tmp, sizeof (tmp));
+@@ -142,16 +144,18 @@
+ */
+ static int display_dram_config (void)
+ {
+- DECLARE_GLOBAL_DATA_PTR;
+ int i;
+
+ puts ("RAM Configuration:\n");
+
+ for(i=0; i<CONFIG_NR_DRAM_BANKS; i++) {
+- printf ("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
++ printf ("\tBank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
+ print_size (gd->bd->bi_dram[i].size, "\n");
+ }
+
++ puts("SRAM Configuration:\n");
++ printf("\t%dKB at 0x%08x\n", gd->bd->bi_sramsize >> 10, gd->bd->bi_sramstart);
++
+ return (0);
+ }
+
+@@ -191,6 +195,12 @@
+ cpu_init, /* basic cpu dependent setup */
+ board_init, /* basic board dependent setup */
+ interrupt_init, /* set up exceptions */
++#ifdef CONFIG_OXNAS
++ /* Need early console to see SATA env. load messages */
++ init_baudrate, /* initialze baudrate settings */
++ serial_init, /* serial communications setup */
++ console_init_f, /* stage 1 init of console */
++#endif // CONFIG_OXNAS
+ env_init, /* initialize environment */
+ init_baudrate, /* initialze baudrate settings */
+ serial_init, /* serial communications setup */
+@@ -206,7 +216,6 @@
+
+ void start_armboot (void)
+ {
+- DECLARE_GLOBAL_DATA_PTR;
+
+ ulong size;
+ init_fnc_t **init_fnc_ptr;
+@@ -232,9 +241,11 @@
+ }
+ }
+
++#ifndef CFG_NO_FLASH
+ /* configure available FLASH banks */
+ size = flash_init ();
+ display_flash_config (size);
++#endif // CFG_NO_FLASH
+
+ #ifdef CONFIG_VFD
+ # ifndef PAGE_SIZE
+@@ -354,6 +365,12 @@
+ {
+ puts ("### ERROR ### Please RESET the board ###\n");
+ for (;;);
++}
++
++void raise (int n)
++{
++ puts ("### ERROR ### Please RESET the board ###\n");
++ for (;;);
+ }
+
+ #ifdef CONFIG_MODEM_SUPPORT
+diff -Nurd u-boot-1.1.2/MAKEALL u-boot-1.1.2-oxe810/MAKEALL
+--- u-boot-1.1.2/MAKEALL 2004-12-31 10:32:48.000000000 +0100
++++ u-boot-1.1.2-oxe810/MAKEALL 2008-06-11 17:55:31.000000000 +0200
+@@ -154,7 +154,7 @@
+ lpd7a400 mx1ads mx1fs2 omap1510inn \
+ omap1610h2 omap1610inn omap730p2 scb9328 \
+ smdk2400 smdk2410 trab VCMA9 \
+- versatile \
++ versatile oxnas \
+ "
+
+ #########################################################################
+diff -Nurd u-boot-1.1.2/Makefile u-boot-1.1.2-oxe810/Makefile
+--- u-boot-1.1.2/Makefile 2004-12-19 10:58:11.000000000 +0100
++++ u-boot-1.1.2-oxe810/Makefile 2008-06-11 17:55:31.000000000 +0200
+@@ -1296,6 +1296,9 @@
+ SX1_config : unconfig
+ @./mkconfig $(@:_config=) arm arm925t sx1
+
++oxnas_config : unconfig
++ @./mkconfig $(@:_config=) arm arm926ejs oxnas
++
+ # TRAB default configuration: 8 MB Flash, 32 MB RAM
+ trab_config \
+ trab_bigram_config \
+@@ -1561,11 +1564,12 @@
+ clean:
+ find . -type f \
+ \( -name 'core' -o -name '*.bak' -o -name '*~' \
+- -o -name '*.o' -o -name '*.a' \) -print \
++ -o -name '*.o' -o -name '*.a' -o -name '.depend' \) -print \
+ | xargs rm -f
+ rm -f examples/hello_world examples/timer \
+ examples/eepro100_eeprom examples/sched \
+- examples/mem_to_mem_idma2intr examples/82559_eeprom
++ examples/mem_to_mem_idma2intr examples/82559_eeprom \
++ examples/mem_test
+ rm -f tools/img2srec tools/mkimage tools/envcrc tools/gen_eth_addr
+ rm -f tools/mpc86x_clk tools/ncb
+ rm -f tools/easylogo/easylogo tools/bmp_logo
+diff -Nurd u-boot-1.1.2/net/net.c u-boot-1.1.2-oxe810/net/net.c
+--- u-boot-1.1.2/net/net.c 2004-10-12 00:51:14.000000000 +0200
++++ u-boot-1.1.2-oxe810/net/net.c 2008-06-11 17:55:11.000000000 +0200
+@@ -225,7 +225,7 @@
+ return;
+
+ t = get_timer(0);
+-
++
+ /* check for arp timeout */
+ if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT * CFG_HZ) {
+ NetArpWaitTry++;
+@@ -235,6 +235,7 @@
+ NetArpWaitTry = 0;
+ NetStartAgain();
+ } else {
++ puts ("\nARP Resend request\n");
+ NetArpWaitTimerStart = t;
+ ArpRequest();
+ }
+@@ -738,7 +739,7 @@
+ #if defined(CONFIG_NET_MULTI)
+ printf ("Using %s device\n", eth_get_name());
+ #endif /* CONFIG_NET_MULTI */
+- NetSetTimeout (10 * CFG_HZ, PingTimeout);
++ NetSetTimeout (30 * CFG_HZ, PingTimeout);
+ NetSetHandler (PingHandler);
+
+ PingSend();
+@@ -1384,7 +1385,7 @@
+ */
+ /* XXX point to ip packet */
+ (*packetHandler)((uchar *)ip, 0, 0, 0);
+- break;
++ return;/**break; BHC Changed to remove second invocation of ping handler below */
+ #endif
+ default:
+ return;
+@@ -1492,10 +1493,11 @@
+ NetCksum(uchar * ptr, int len)
+ {
+ ulong xsum;
++ ushort *s = ptr;
+
+ xsum = 0;
+ while (len-- > 0)
+- xsum += *((ushort *)ptr)++;
++ xsum += *s++;
+ xsum = (xsum & 0xffff) + (xsum >> 16);
+ xsum = (xsum & 0xffff) + (xsum >> 16);
+ return (xsum & 0xffff);
+diff -Nurd u-boot-1.1.2/net/tftp.c u-boot-1.1.2-oxe810/net/tftp.c
+--- u-boot-1.1.2/net/tftp.c 2004-04-15 23:48:55.000000000 +0200
++++ u-boot-1.1.2-oxe810/net/tftp.c 2008-06-11 17:55:11.000000000 +0200
+@@ -106,6 +106,7 @@
+ volatile uchar * pkt;
+ volatile uchar * xp;
+ int len = 0;
++ volatile ushort * s;
+
+ /*
+ * We will always be sending some sort of packet, so
+@@ -117,7 +118,9 @@
+
+ case STATE_RRQ:
+ xp = pkt;
+- *((ushort *)pkt)++ = htons(TFTP_RRQ);
++ s = (ushort *)pkt;
++ *s++ = htons(TFTP_RRQ);
++ pkt = (uchar *)s;
+ strcpy ((char *)pkt, tftp_filename);
+ pkt += strlen(tftp_filename) + 1;
+ strcpy ((char *)pkt, "octet");
+@@ -135,15 +138,19 @@
+ case STATE_DATA:
+ case STATE_OACK:
+ xp = pkt;
+- *((ushort *)pkt)++ = htons(TFTP_ACK);
+- *((ushort *)pkt)++ = htons(TftpBlock);
++ s = (ushort *)pkt;
++ *s++ = htons(TFTP_ACK);
++ *s++ = htons(TftpBlock);
++ pkt = (uchar *)s;
+ len = pkt - xp;
+ break;
+
+ case STATE_TOO_LARGE:
+ xp = pkt;
+- *((ushort *)pkt)++ = htons(TFTP_ERROR);
+- *((ushort *)pkt)++ = htons(3);
++ s = (ushort *)pkt;
++ *s++ = htons(TFTP_ERROR);
++ *s++ = htons(3);
++ pkt = (uchar *)s;
+ strcpy ((char *)pkt, "File too large");
+ pkt += 14 /*strlen("File too large")*/ + 1;
+ len = pkt - xp;
+@@ -151,8 +158,10 @@
+
+ case STATE_BAD_MAGIC:
+ xp = pkt;
+- *((ushort *)pkt)++ = htons(TFTP_ERROR);
+- *((ushort *)pkt)++ = htons(2);
++ s = (ushort *)pkt;
++ *s++ = htons(TFTP_ERROR);
++ *s++ = htons(2);
++ pkt = (uchar *)s;
+ strcpy ((char *)pkt, "File has bad magic");
+ pkt += 18 /*strlen("File has bad magic")*/ + 1;
+ len = pkt - xp;
+@@ -167,6 +176,7 @@
+ TftpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
+ {
+ ushort proto;
++ ushort *s;
+
+ if (dest != TftpOurPort) {
+ return;
+@@ -180,7 +190,9 @@
+ }
+ len -= 2;
+ /* warning: don't use increment (++) in ntohs() macros!! */
+- proto = *((ushort *)pkt)++;
++ s = (ushort *)pkt;
++ proto = *s++;
++ pkt = (uchar *)s;
+ switch (ntohs(proto)) {
+
+ case TFTP_RRQ:
file://command-names.patch;patch=1"
SRC_URI_append_magicbox = "file://u-boot-emetec.patch;patch=1 "
-SRC_URI_append_oxe810 = "file://oxe810.patch;patch=1 "
+SRC_URI_append_oxnas = "file://oxnas.patch;patch=1 "
# TODO: SRC_URI_append_rt3000
UBOOT_MACHINE_mnci = "mnci_config"
UBOOT_MACHINE_vibren = "pxa255_idp_config"
UBOOT_MACHINE_magicbox = "EMETEC405_config"
-UBOOT_MACHINE_oxe810 = "oxnas_config"
+UBOOT_MACHINE_oxnas = "oxnas_config"
inherit base
HOMEPAGE = "http://people.igalia.com/berto/"
SECTION = "x11"
DEPENDS = "gtk+ gstreamer"
+RRECOMMENDS = "dbus-x11"
PR = "r0"
SRC_URI = "\
install -d ${D}/${sysconfdir}/dbus-1/system.d
install -m 644 ${S}/dbus-wpa_supplicant.conf ${D}/${sysconfdir}/dbus-1/system.d
install -d ${D}/${datadir}/dbus-1/system-services
- install -m 644 ${S}/dbus-wpa_supplicant.service ${D}/${datadir}/dbus-1/system-services
+ sed -i -e s:${base_sbindir}:${sbindir}:g ${S}/dbus-wpa_supplicant.service
+ install -m 644 ${S}/dbus-wpa_supplicant.service ${D}/${datadir}/dbus-1/system-services/fi.epitest.hostap.WPASupplicant.service
ln -s /etc/wpa_supplicant/ifupdown.sh ${D}${sysconfdir}/network/if-pre-up.d/wpasupplicant
ln -s /etc/wpa_supplicant/ifupdown.sh ${D}${sysconfdir}/network/if-post-down.d/wpasupplicant
require wpa-supplicant-0.6.inc
-PR = "r2"
+PR = "r4"
--- /dev/null
+DESCRIPTION = "A C++ Web Toolkit"
+PRIORITY = "optional"
+SECTION = "devel"
+LICENSE = "GPL"
+DEPENDS = "boost zlib openssl"
+PR = "r0"
+
+SRC_URI = "${SOURCEFORGE_MIRROR}/witty/wt-${PV}.tar.gz \
+ file://cmakelist.patch;patch=1"
+
+FILES_${PN} += "${datadir}/Wt"
+FILES_${PN}-dev += "${datadir}/cmake-2.*"
+
+inherit cmake
+
+STAGE_TEMP = "${WORKDIR}/temp-staging"
+
+do_configure_append() {
+ ${BUILD_CXX} ${BUILD_CXXFLAGS} -o src/filetostring src/web/skeleton/FileToString.C
+}
+
+do_stage() {
+ rm -rf ${STAGE_TEMP}
+ mkdir -p ${STAGE_TEMP}
+ oe_runmake DESTDIR="${STAGE_TEMP}" install
+ cp -pPR ${STAGE_TEMP}/${includedir}/* ${STAGING_INCDIR}
+ cp -pPR ${STAGE_TEMP}/${libdir}/* ${STAGING_LIBDIR}
+ cp -pPR ${STAGE_TEMP}/${datadir}/cmake-2.* ${STAGING_DATADIR}
+ rm -rf ${STAGE_TEMP}
+}
+
diff --git a/pixman/pixman-arm-neon.c b/pixman/pixman-arm-neon.c
new file mode 100644
-index 0000000..f8a41a8
+index 0000000..10050e4
--- /dev/null
+++ b/pixman/pixman-arm-neon.c
-@@ -0,0 +1,1397 @@
+@@ -0,0 +1,1387 @@
+/*
+ * Copyright © 2009 Mozilla Corporation
+ *
+ "b 9f\n\t"
+// LOOP
+ "2:\n\t"
-+ "vld1.8 {d0}, [%[src]]\n\t"
-+ "vld1.8 {d4}, [%[dst]]\n\t"
++ "vld1.8 {d0}, [%[src]]!\n\t"
++ "vld1.8 {d4}, [%[dst]]!\n\t"
+ "vst1.8 {d20}, [%[keep_dst]]\n\t"
-+ "mov %[keep_dst], %[dst]\n\t"
-+ "add %[src], %[src], #8\n\t"
-+ "add %[dst], %[dst], #8\n\t"
++ "sub %[keep_dst], %[dst], #8\n\t"
+ "subs %[w], %[w], #8\n\t"
+ "9:\n\t"
+ "vqadd.u8 d20, d0, d4\n\t"
+ "b 9f\n\t"
+// LOOP
+ "2:\n\t"
-+ "vld4.8 {d0-d3}, [%[src]]\n\t"
-+ "vld4.8 {d4-d7}, [%[dst]]\n\t"
++ "vld4.8 {d0-d3}, [%[src]]!\n\t"
++ "vld4.8 {d4-d7}, [%[dst]]!\n\t"
+ "vst4.8 {d20-d23}, [%[keep_dst]]\n\t"
-+ "mov %[keep_dst], %[dst]\n\t"
-+ "add %[src], %[src], #8*4\n\t"
-+ "add %[dst], %[dst], #8*4\n\t"
++ "sub %[keep_dst], %[dst], #8*4\n\t"
+ "subs %[w], %[w], #8\n\t"
+ "9:\n\t"
+ "vmvn.8 d31, d3\n\t"
+ "b 9f\n\t"
+// LOOP
+ "2:\n\t"
-+ "vld4.8 {d0-d3}, [%[src]]\n\t"
-+ "vld4.8 {d4-d7}, [%[dst]]\n\t"
++ "vld4.8 {d0-d3}, [%[src]]!\n\t"
++ "vld4.8 {d4-d7}, [%[dst]]!\n\t"
+ "vst4.8 {d20-d23}, [%[keep_dst]]\n\t"
-+ "mov %[keep_dst], %[dst]\n\t"
-+ "add %[src], %[src], #8*4\n\t"
-+ "add %[dst], %[dst], #8*4\n\t"
++ "sub %[keep_dst], %[dst], #8*4\n\t"
+ "subs %[w], %[w], #8\n\t"
+
+ "9:\n\t"
+// LOOP
+ "2:\n\t"
+
-+ "vld1.16 {q12}, [%[dst]]\n\t"
-+ "vld1.8 {d31}, [%[mask]]\n\t"
++ "vld1.16 {q12}, [%[dst]]!\n\t"
++ "vld1.8 {d31}, [%[mask]]!\n\t"
+ "vst1.16 {q10}, [%[keep_dst]]\n\t"
-+ "mov %[keep_dst], %[dst]\n\t"
-+ "add %[mask], %[mask], #8\n\t"
-+ "add %[dst], %[dst], #8*2\n\t"
++ "sub %[keep_dst], %[dst], #8*2\n\t"
+ "subs %[w], %[w], #8\n\t"
+ "9:\n\t"
+// expand 0565 q12 to 8888 {d4-d7}
+ "b 9f\n\t"
+// LOOP
+ "2:\n\t"
-+ "vld4.8 {d4-d7}, [%[dst]]\n\t"
-+ "vld1.8 {d31}, [%[mask]]\n\t"
++ "vld4.8 {d4-d7}, [%[dst]]!\n\t"
++ "vld1.8 {d31}, [%[mask]]!\n\t"
+ "vst4.8 {d20-d23}, [%[keep_dst]]\n\t"
-+ "mov %[keep_dst], %[dst]\n\t"
-+ "add %[mask], %[mask], #8\n\t"
-+ "add %[dst], %[dst], #8*4\n\t"
++ "sub %[keep_dst], %[dst], #8*4\n\t"
+ "subs %[w], %[w], #8\n\t"
+ "9:\n\t"
+
+ dval = vld1_u8((void*)dst);
+
+ temp = neon2mul(sval2,alpha);
-+ res = vqadd_u8(temp,neon2mul(dval,vtbl1_u8(vmvn_u8(sval2), alpha_selector)));
++ res = vqadd_u8(temp,neon2mul(dval,vtbl1_u8(vmvn_u8(temp), alpha_selector)));
+
+ vst1_u8((void*)dst,res);
+
+ dval = vreinterpret_u8_u32(vld1_dup_u32((void*)dst));
+
+ temp = neon2mul(sval2,alpha);
-+ res = vqadd_u8(temp,neon2mul(dval,vtbl1_u8(vmvn_u8(sval2), alpha_selector)));
++ res = vqadd_u8(temp,neon2mul(dval,vtbl1_u8(vmvn_u8(temp), alpha_selector)));
+
+ vst1_lane_u32((void*)dst,vreinterpret_u32_u8(res),0);
+ }
+
diff --git a/pixman/pixman-arm-neon.h b/pixman/pixman-arm-neon.h
new file mode 100644
-index 0000000..a473841
+index 0000000..bab4dee
--- /dev/null
+++ b/pixman/pixman-arm-neon.h
@@ -0,0 +1,137 @@
+/*
-+ * Copyright © 2008 Mozilla Corporation
++ * Copyright © 2009 Mozilla Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
-+ * Author: Jeff Muizelaar (jeff@infidigm.net)
++ * Author: Ian Rickards (ian.rickards@arm.com)
+ *
+ */
+
DESCRIPTION = "Low-level pixel manipulation library."
LICENSE = "X11"
-PR = "r1"
+PR = "r2"
DEFAULT_PREFERENCE = "-1"
DESCRIPTION = "Machine specific xorg.conf files"
-PR = "r2"
+PR = "r3"
SRC_URI = "file://xorg.conf"
--- /dev/null
+--- xc/../xqt2.vanilla/xfree86/xqt-driver/qtscreen.cc 2009-02-08 15:47:33.000000000 +0100
++++ xc/../xqt2/xfree86/xqt-driver/qtscreen.cc 2009-02-08 15:52:09.000000000 +0100
+@@ -406,7 +406,9 @@
+ //
+ void qtScreen::keyPressEvent(QKeyEvent *ev)
+ {
+- static QTextCodec *codec = QTextCodec::codecForName("eucJP");
++ //static QTextCodec *codec = QTextCodec::codecForName("eucJP");
++ //Better to choose the locale - even better provide a command line switch!
++ static QTextCodec *codec = QTextCodec::codecForLocale();
+
+ #ifdef QWS
+ QCString euc;
SECTION = "opie/applications"
APPTYPE = "binary"
APPNAME = "Xqt"
-PR = "r3"
+PR = "r4"
inherit palmtop
file://fephack.patch;patch=1 \
file://xchar2b.patch;patch=1 \
file://xqt-make.patch;patch=1 \
- file://fix_qtscreen_HACK.patch;patch=1 "
+ file://fix_qtscreen_HACK.patch;patch=1 \
+ file://fix_seqfault_qtscreen.patch;patch=1 "
S = "${WORKDIR}/xc"
QT_LIBRARY = '${@base_conditional("PALMTOP_USE_MULTITHREADED_QT", "yes", "qte-mt", "qte",d)}'
DESCRIPTION = "xqtlauncher integrates X/Qt2 nicely into opie. You can launch applications with it from opies menue"
HOMEPAGE = "http://angstrom-distribution.org/"
LICENSE = "GPL"
-PR = "r1"
+PR = "r2"
RDEPENDS = "xqt2 xorg-minimal-fonts"
newfile=/usr/lib/opie/apps/XQt2/$name.desktop
if [ ! -f $newfile ] ; then
#cat $i | awk 'BEGIN {FS="="} {if ($1 == "Exec") {print "Exec=run"ENVIRON["name"]" " $2} else if ($1 == "Icon") {print "Icon=/usr/share/pixmaps/"$2} else {print $0} }' > $newfile
- cat $i | awk 'BEGIN {FS="="} {if ($1 == "Exec") {print "Exec=run"ENVIRON["name"]" " $2} else {print $0} }' > $newfile
+ cat $i | awk 'BEGIN {FS="="} {if ($1 == "Exec") {print "Exec=/usr/lib/opie/bin/run"ENVIRON["name"]" " $2} else {print $0} }' > $newfile
icon=$(cat $i | awk 'BEGIN {FS="="} {if ($1 == "Icon") {print $2} }')
ln -sf /usr/bin/xqtlauncher /usr/lib/opie/bin/run$name
#We need to make symlinks for the pics because opie can not handle pics with paths :(
fi
ARGS="$ARGS -dpi 181 -screen 320x320 -hide-cursor $PPM" ;;
"Motorola Ezx Platform")
- ARGS="$ARGS -dpi 170 -screen ${SCREEN_SIZE} -hide-cursor -root-ppm /usr/share/pixmaps/xsplash-qvga.ppm vt1" ;;
+ ARGS="$ARGS -dpi 170 -screen ${SCREEN_SIZE} -hide-cursor -mouse tslib -root-ppm /usr/share/pixmaps/xsplash-qvga.ppm vt1" ;;
"Glofiish M800")
ARGS="$ARGS -dpi 285 -screen ${SCREEN_SIZE} -mouse tslib -hide-cursor -root-ppm /usr/share/pixmaps/xsplash-vga.ppm vt1" ;;
"Freescale MX21ADS")
sed -i \
-e "s|tail -1|tail -n 1|" \
-e "s|dist dist-all dist-all:|dist dist-all:|" \
- Makefile
+ -e "s|docs||g" \
+ Makefile
mkdir ${S}/build
}
+
+
+do_compile_append() {
+for i in ${S}/*/*.pc ; do
+ sed -i -e s:${STAGING_DIR_TARGET}::g \
+ -e s:/${TARGET_SYS}::g \
+ $i
+done
+}
require zziplib.inc
+PR = "r1"
+
SRC_URI += "\
file://zip_c.patch;patch=1 \
file://zziplib-autoconf.patch;patch=1 \