summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/cups/cups_1.1.23.bb2
-rw-r--r--packages/fakeroot/fakeroot_1.2.13.bb4
-rw-r--r--packages/freenote/.mtn2git_empty (renamed from packages/nonworking/freenote/.mtn2git_empty)0
-rw-r--r--packages/freenote/files/.mtn2git_empty (renamed from packages/nonworking/freenote/freenote-1.6.1/.mtn2git_empty)0
-rw-r--r--packages/freenote/files/FreeNote/.mtn2git_empty0
-rw-r--r--packages/freenote/files/FreeNote/FreeNote/.mtn2git_empty0
-rw-r--r--packages/freenote/files/FreeNote/FreeNote/FNCanvas.cpp2244
-rw-r--r--packages/freenote/files/FreeNote/FreeNote/FNFindDialog.cpp143
-rw-r--r--packages/freenote/files/FreeNote/FreeNote/FNMessageBox.cpp243
-rw-r--r--packages/freenote/files/FreeNote/FreeNote/FNTextDialog.cpp93
-rw-r--r--packages/freenote/files/FreeNote/FreeNote/FmtEngine.cpp512
-rw-r--r--packages/freenote/files/FreeNote/FreeNote/FrmMain.cpp1442
-rw-r--r--packages/freenote/files/FreeNote/apps/.mtn2git_empty0
-rw-r--r--packages/freenote/files/FreeNote/apps/Applications/.mtn2git_empty0
-rw-r--r--packages/freenote/files/FreeNote/apps/Applications/FreeNote.desktop10
-rw-r--r--packages/freenote/files/FreeNote/apps/Settings/.mtn2git_empty0
-rw-r--r--packages/freenote/files/FreeNote/apps/Settings/FreeNoteSetup.desktop9
-rw-r--r--packages/freenote/files/FreeNote/pics/.mtn2git_empty0
-rw-r--r--packages/freenote/files/FreeNote/pics/fnsetup.pngbin0 -> 1317 bytes
-rw-r--r--packages/freenote/files/FreeNote/pics/freenote.pngbin0 -> 1024 bytes
-rw-r--r--packages/freenote/freenote_1.12.0.bb33
-rw-r--r--packages/gcc/gcc_4.0.2.bb8
-rw-r--r--packages/gimp/gimp_2.3.8.bb19
-rw-r--r--packages/gnutls/gnutls-1.4.0/.mtn2git_empty0
-rw-r--r--packages/gnutls/gnutls-1.4.0/gnutls-openssl.patch120
-rw-r--r--packages/gnutls/gnutls-1.4.0/gnutls-texinfo-euro.patch16
-rw-r--r--packages/gnutls/gnutls_1.4.0.bb34
-rw-r--r--packages/gomunicator/gomunicator_cvs.bb3
-rw-r--r--packages/gpe-nmf/gpe-nmf-0.22/fix-includepath.patch15
-rw-r--r--packages/gpe-nmf/gpe-nmf_0.22.bb5
-rw-r--r--packages/gpe-package/gpe-package_0.3.bb6
-rw-r--r--packages/libeventdb/libeventdb_0.30.bb15
-rw-r--r--packages/libgpevtype/libgpevtype_0.17.bb25
-rw-r--r--packages/libgpg-error/libgpg-error-1.3/.mtn2git_empty0
-rw-r--r--packages/libgpg-error/libgpg-error-1.3/pkgconfig.patch54
-rw-r--r--packages/libgpg-error/libgpg-error_1.3.bb28
-rw-r--r--packages/liboil/liboil_0.3.9.bb (renamed from packages/liboil/liboil_0.3.6.bb)2
-rw-r--r--packages/linux/ixp4xx-kernel/2.6.16/defconfig8
-rw-r--r--packages/linux/ixp4xx-kernel_2.6.16.bb2
-rw-r--r--packages/linux/linux-ezx/defconfig-a78019
-rw-r--r--packages/linux/linux-ezx/defconfig-e68023
-rw-r--r--packages/linux/linux-ezx_2.6.16.13.bb2
-rw-r--r--packages/linux/linux-h6300-omap1-2.6.16.16/.mtn2git_empty0
-rw-r--r--packages/linux/linux-h6300-omap1-2.6.16.16/defconfig1558
-rw-r--r--packages/linux/linux-h6300-omap1-2.6.16.16/linux-2.6.16.16.patch5134
-rw-r--r--packages/linux/linux-h6300-omap1-2.6.16.16/linux-h6300-omap2-2.6.16.16.patch3736
-rw-r--r--packages/linux/linux-h6300-omap1_2.6.16.16.bb19
-rw-r--r--packages/linux/linux-openzaurus-2.6.16/defconfig-akita12
-rw-r--r--packages/linux/linux-openzaurus-2.6.16/defconfig-c7x09
-rw-r--r--packages/linux/linux-openzaurus-2.6.16/defconfig-collie15
-rw-r--r--packages/linux/linux-openzaurus-2.6.16/defconfig-ipaq-pxa2708
-rw-r--r--packages/linux/linux-openzaurus-2.6.16/defconfig-poodle12
-rw-r--r--packages/linux/linux-openzaurus-2.6.16/defconfig-spitz12
-rw-r--r--packages/linux/linux-openzaurus-2.6.16/defconfig-tosa7
-rw-r--r--packages/linux/linux-openzaurus-2.6.16/squashfs3.0-2.6.15.patch4173
-rw-r--r--packages/linux/linux-openzaurus_2.6.16.bb5
-rw-r--r--packages/meta/slugos-packages.bb1
-rw-r--r--packages/meta/task-python-everything_20060425.bb4
-rw-r--r--packages/meta/task-python-sharprom_20060425.bb7
-rw-r--r--packages/meta/task-qpe.bb3
-rw-r--r--packages/meta/unslung-image.bb24
-rw-r--r--packages/ncurses/ncurses.inc1
-rw-r--r--packages/nonworking/freenote/freenote-1.6.1/compile.patch3285
-rw-r--r--packages/nonworking/freenote/freenote_1.6.1.bb22
-rw-r--r--packages/nslu2-binary-only/unslung-rootfs/NOTES8
-rw-r--r--packages/nslu2-binary-only/unslung-rootfs/rc.samba-syntaxfix.patch23
-rw-r--r--packages/nslu2-binary-only/unslung-rootfs/rc.sysinit-cpbug.patch19
-rwxr-xr-xpackages/nslu2-binary-only/unslung-rootfs/unsling2
-rw-r--r--packages/nslu2-binary-only/unslung-rootfs_2.3r63.bb17
-rw-r--r--packages/obexftp/files/i-hate-libtool.patch20
-rw-r--r--packages/obexftp/obexftp_0.20.bb (renamed from packages/obexftp/obexftp_0.19.bb)7
-rw-r--r--packages/prismstumbler/prismstumbler-0.7.3/fix-includes.patch26
-rw-r--r--packages/prismstumbler/prismstumbler_0.7.3.bb3
-rw-r--r--packages/puzzles/puzzles_r6712.bb50
-rw-r--r--packages/python/python-gammu_0.13.bb4
-rw-r--r--packages/python/python-pyfits_1.0.1.bb13
-rw-r--r--packages/python/python-pyraf_1.2.1.bb14
-rw-r--r--packages/python/python-pysqlite/.mtn2git_empty0
-rw-r--r--packages/python/python-pysqlite/no-host-includes.patch40
-rw-r--r--packages/python/python-pysqlite2_2.2.2.bb2
-rw-r--r--packages/python/python-pysqlite_1.0.bb4
-rw-r--r--packages/schroedinger/.mtn2git_empty0
-rw-r--r--packages/schroedinger/schroedinger_0.2.0.0.bb11
-rw-r--r--packages/xmms/.mtn2git_empty0
-rw-r--r--packages/xmms/files/.mtn2git_empty0
-rw-r--r--packages/xmms/files/gcc4.patch20
-rw-r--r--packages/xmms/xmms_1.2.10.bb23
87 files changed, 20113 insertions, 3379 deletions
diff --git a/packages/cups/cups_1.1.23.bb b/packages/cups/cups_1.1.23.bb
index 9094bb9dff..2fa5178cac 100644
--- a/packages/cups/cups_1.1.23.bb
+++ b/packages/cups/cups_1.1.23.bb
@@ -22,7 +22,7 @@ do_compile () {
"-I."
}
-do_install () {
+fakeroot do_install () {
oe_runmake "DSTROOT=${D}" install
}
diff --git a/packages/fakeroot/fakeroot_1.2.13.bb b/packages/fakeroot/fakeroot_1.2.13.bb
index f141330276..8ae7ca38be 100644
--- a/packages/fakeroot/fakeroot_1.2.13.bb
+++ b/packages/fakeroot/fakeroot_1.2.13.bb
@@ -1,8 +1,8 @@
-SECTION = "base"
DESCRIPTION = "Gives a fake root environment"
+SECTION = "base"
HOMEPAGE = "http://joostje.op.het.net/fakeroot/index.html"
LICENSE = "GPL"
-SRC_URI = "${DEBIAN_MIRROR}/main/f/fakeroot/fakeroot_${PV}.tar.gz"
+SRC_URI = "http://openzaurus.org/mirror/fakeroot_${PV}.tar.gz"
inherit autotools
diff --git a/packages/nonworking/freenote/.mtn2git_empty b/packages/freenote/.mtn2git_empty
index e69de29bb2..e69de29bb2 100644
--- a/packages/nonworking/freenote/.mtn2git_empty
+++ b/packages/freenote/.mtn2git_empty
diff --git a/packages/nonworking/freenote/freenote-1.6.1/.mtn2git_empty b/packages/freenote/files/.mtn2git_empty
index e69de29bb2..e69de29bb2 100644
--- a/packages/nonworking/freenote/freenote-1.6.1/.mtn2git_empty
+++ b/packages/freenote/files/.mtn2git_empty
diff --git a/packages/freenote/files/FreeNote/.mtn2git_empty b/packages/freenote/files/FreeNote/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/freenote/files/FreeNote/.mtn2git_empty
diff --git a/packages/freenote/files/FreeNote/FreeNote/.mtn2git_empty b/packages/freenote/files/FreeNote/FreeNote/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/freenote/files/FreeNote/FreeNote/.mtn2git_empty
diff --git a/packages/freenote/files/FreeNote/FreeNote/FNCanvas.cpp b/packages/freenote/files/FreeNote/FreeNote/FNCanvas.cpp
new file mode 100644
index 0000000000..6e7f615600
--- /dev/null
+++ b/packages/freenote/files/FreeNote/FreeNote/FNCanvas.cpp
@@ -0,0 +1,2244 @@
+/* FreeNote for Sharp SLA300, B500, C7x0, C860 Linux PDA
+ Copyright (C) 2003-2005 Joe Kanemori.<kanemori@ymg.urban.ne.jp>
+
+ 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
+*/
+/*
+2005/06/04 FreeNote 1.11.12pre
+・グリッドの枠線を実際の選択範囲よりも大きく表示するように変更。
+・範囲選択、グリッド、ガイド、罫線カラーのカスタマイズを可能に。
+・カラーピッカーモードの追加
+
+2005/06/02 FreeNote 1.11.11Apre
+・テキスト移動枠の不具合修正
+・罫線をグリッドの2倍で表示するように変更
+・消しゴム時の範囲指定時に、ペンオフしてワンテンポおいてから範囲確定するように変更
+
+2005/03/18 FreeNote 1.11.10Bpre
+・描画の最適化
+
+2005/02/27 FreeNote 1.11.10pre
+・PDFの出力形式を一部変更
+・インポート時のバグfix
+
+2005/01/04 FreeNote 1.11.6pre
+・カーブモードで8の字がかけるように整形エンジンを改善
+
+2005/01/04 FreeNote 1.11.5Apre
+・バグフィックス
+
+2004/12/25 FreeNote 1.11.5pre
+・レイヤー機能追加
+
+2004/11/24 FreeNote 1.11.0pre
+・テキストペースト機能
+
+2004/10/17 FreeNote 1.10.0リリース
+2004/08/26 ver 1.9.3pre
+・罫線機能を追加
+
+2004/05/23 ver 1.9.1Apre
+・欧文環境対応
+
+2004/02/16 ver 1.7.3pre
+・編集機能強化
+
+2004/02/14 ver 1.7.2pre
+・検索機能追加
+
+2004/02/12 ver 1.7.1pre
+・フォント仕様の変更
+・テキスト処理の高速化
+・テキストボックスの多機能化
+
+2003/02/10 ver 1.7.0pre
+・文字入力
+
+2003/12/23 ver 1.6.1
+・保存情報のサイズ縮小
+
+2003/12/16-19 ver 1.5.5pre
+・ペンサイズの追加(1-8)
+・アンドゥ・リドゥの実装
+
+2003/12/14 ver 1.5.4pre
+・ペンサイズを選択可能に。
+
+2003/12/05 ver 1.5.3Apre
+・グリッドの色を修正
+
+2003/12/04 ver 1.5.3pre
+・グリッドの描画を一部修正
+
+2003/11/10 ver 1.5.1pre
+・曲線整形モード追加
+
+2003/11/09 ver 1.5.0pre
+・自動整形モード追加
+
+2003/09/03 ver 1.3.4pre
+・Use all quadrant OFF時に表示位置がリセットされる場合があるバグ対応。
+
+2003/09/01-03 ver 1.3.3pre
+・スクロールの改良
+・Use all quadrant(全象限を使用する)メニューを追加
+
+2003/08/31 FreeNote 1.3.2pre
+・全方向スクロール
+
+2003/08/23 FreeNote 1.3.0pre
+・CR動作の修正
+
+2003/08/15 FreeNote 1.2.1を公開
+・保存時のバグ修正
+・完了ダイアログの自動消去
+・PNGファイルへの出力
+
+2003/08/15 FreeNote 1.2を公開
+・オプション追加
+・スクロールガイド
+・Freeファイル関連付け
+・アイコンの変更
+
+2003/08/05 FreeNote 1.1.1preを公開
+・高速起動時に閉じた状態を保持
+・描画モード切替え時に消しゴム表示
+・保存時間短縮
+・Viewモードの挙動を変更
+・メニューの見た目を変更
+*/
+#include "fncanvas.h"
+#include <qsjiscodec.h>
+#include <stdio.h>
+#include <qfile.h>
+#include <qmessagebox.h>
+#include <qtextstream.h>
+#include <qpen.h>
+#include <qcolor.h>
+#include <qpoint.h>
+#include <qthread.h>
+#include <qimage.h>
+#include <math.h>
+#include <qtextcodec.h>
+#include <qmultilineedit.h>
+#include <qbitmap.h>
+#include "fnmessagebox.h"
+#include "fmtengine.h"
+#include "fntextdialog.h"
+#include <qfont.h>
+#include <qapplication.h>
+#include <qclipboard.h>
+#include "frmmain.h"
+#include "fnlayerdlg.h"
+#include <stdlib.h>
+
+int snap(int v) {
+ int tv = abs(v);
+ tv = ((int)(tv + SNAP_SIZE / 2) / SNAP_SIZE) * SNAP_SIZE;
+ if (0 > v) {
+ return -tv;
+ } else {
+ return tv;
+ }
+}
+
+FNCanvas::FNCanvas(FNColorDialog* dlg, QWidget* parent, const char* name, WFlags f)
+ :QWidget(parent, name, f),
+ _txtTmp(NULL),
+ _pen(black, 1, SolidLine, RoundCap, RoundJoin),
+ _asMode(AS_NONE),
+ _drawMode(MODE_DRAW),
+ _prevMode(MODE_DRAW),
+ _eraser_l(50),
+ _eraser_s(10),
+ _h_step(100),
+ _v_step(100),
+ _margin(5),
+ _scrollTiming(800),
+ _selIdx(0),
+ _viewMode(false),
+ _isWaiting(false),
+ _isDragging(false),
+ _isDrawing(false),
+ _isHeadingEnables(false),
+ _isShowGuide(false),
+ _isUseAllQuadrant(false),
+ _showRuler(false),
+ _isTinyPaging(false),
+ _scale_x(1.0),
+ _scale_y(1.0),
+ _tboxRect(0, 50, 220, 240),
+ _isEraseWaiting(false),
+ _colorSelector(dlg),
+ _isColorRevision(true)
+{
+ _tracks.setAutoDelete(true);
+ _clipboard.setAutoDelete(true);
+ _current = new FNLayer();
+ _layers.append(_current);
+ _layers.setAutoDelete(true);
+ _undobuf.setAutoDelete(true);
+ _current->Name = "Layer0";
+ this->setBackgroundMode(NoBackground);
+ _timer = new QTimer(this);
+ connect(_timer, SIGNAL(timeout()), this, SLOT(autoScroll()));
+ _dlgFind = new FNFindDialog(this, "Find");
+ connect(_dlgFind, SIGNAL(originChanged(int, int)), this, SLOT(setOrigin(int, int)));
+ connect(_dlgFind, SIGNAL(resetOrigin()), this, SLOT(resetOrigin()));
+
+}
+
+FNCanvas::~FNCanvas()
+{
+ _timer->stop();
+ delete _timer;
+
+ _tracks.clear();
+ _layers.clear();
+ //clearList(_draws);
+
+ delete _dlgFind;
+}
+
+
+void FNCanvas::addLayer()
+{
+ FNLayer* layer = new FNLayer();
+ _current=layer;
+ uint cnt = _layers.count();
+ while (1) {
+ QString name = "Layer";
+ name += QString::number(cnt);
+
+ bool nameExists = false;
+ for (uint i = 0; i < _layers.count(); ++i) {
+ if (_layers.at(i)->Name == name) {
+ nameExists = true;
+ break;
+ }
+ }
+ if (false == nameExists) {
+ layer->Name = name;
+ break;
+ }
+ ++cnt;
+ }
+ _layers.append(layer);
+ _selIdx = _layers.count() - 1;
+ redraw();
+
+}
+
+//表示レイヤーを下に移動する
+void FNCanvas::moveAboveLayer()
+{
+ --_selIdx;
+ if (0 > _selIdx) {
+ _selIdx = 0;
+ }
+ _current = _layers.at(_selIdx);
+ redraw();
+}
+
+//表示レイヤーを上に移動する
+void FNCanvas::moveBelowLayer()
+{
+ ++_selIdx;
+ if (_layers.count() - 1 <= (uint)_selIdx) {
+ _selIdx = _layers.count() - 1;
+ }
+ _current = _layers.at(_selIdx);
+ redraw();
+}
+
+
+void FNCanvas::setScrollTiming(int v)
+{
+ _scrollTiming = v;
+}
+
+
+void FNCanvas::setVStep(int v)
+{
+ _v_step = v;
+}
+
+void FNCanvas::setHStep(int v)
+{
+ _h_step = v;
+}
+
+void FNCanvas::setSEraser(int v)
+{
+ _eraser_s = v;
+}
+
+void FNCanvas::setLEraser(int v)
+{
+ _eraser_l = v;
+}
+
+
+void FNCanvas::setMargin(int v)
+{
+ if (v < 3) {
+ v = 3;
+ }
+ _margin = v;
+}
+void FNCanvas::find()
+{
+ if (_viewMode) {
+ return;
+ }
+ _dlgFind->setElements(_layers);
+ _dlgFind->show();
+ _dlgFind->exec();
+}
+
+void FNCanvas::setScrollMode(int as)
+{
+ _asMode = as;
+ redraw();
+}
+
+void FNCanvas::autoScroll()
+{
+ if (MODE_ERASE == _drawMode) {
+ if (0 < _selection.width()) {
+ int hsn = SNAP_SIZE / 2;
+ int qsn = hsn / 2;
+ int x = ((_selection.x() - qsn) / hsn) * hsn;
+ int y = ((_selection.y() - qsn) / hsn) * hsn;
+ int dx = _selection.x() - x;
+ int dy = _selection.y() - y;
+ int w = ((_selection.width() + dx + hsn) / hsn) * hsn;
+ int h = ((_selection.height() + dy + hsn) / hsn) * hsn;
+ _selection.setRect(x, y, w, h);
+ _isSelected = true;
+ }
+ _last = QPoint(-1, -1);
+ _tracks.clear();
+ _isHeadingEnables = false;
+ _isEraseWaiting = false;
+ redraw();
+ } else {
+ if (AS_NONE == _asMode) {
+ setOrigin(_origin.x(), _origin.y(), false);
+ redraw();
+ return;
+ }
+ bool tmp = _isHeadingEnables;
+ int dx = 0;
+ int dy = 0;
+ if (AS_BOTH == _asMode || AS_HORIZONTAL == _asMode) {
+ if (_last.x() > width() * (_margin - 1) / _margin) {
+ dx = _h_step;
+ } else if (_last.x() < width() / _margin) {
+ dx = -_h_step;
+ }
+ }
+ if (AS_BOTH == _asMode || AS_VERTICAL == _asMode) {
+ if (_last.y() > height() * (_margin - 1) / _margin) {
+ dy = _v_step;
+ } else if (_last.y() < height() / _margin) {
+ dy = -_v_step;
+ }
+ }
+ setOrigin(_origin.x() + dx, _origin.y() + dy, false);
+ _isHeadingEnables = tmp;
+ redraw();
+ }
+}
+
+void FNCanvas::drawRect(QPainter& pa, const QRect& r)
+{
+ int w = width();
+ int h = height();
+ int sx = r.left();
+ int sy = r.top();
+ int ex = r.right();
+ int ey = r.bottom();
+ if (0 > sx) {
+ sx = 0;
+ }
+ if (0 > sy) {
+ sy = 0;
+ }
+ if (h < ey) {
+ ey = h;
+ }
+ if (w < ex) {
+ ex = w;
+ }
+ if (0 <= r.left()) {
+ pa.drawLine(sx, sy, sx, ey);
+ }
+ if (0 <= r.top()) {
+ pa.drawLine(sx, sy, ex, sy);
+ }
+ if (w >= r.right()) {
+ pa.drawLine(ex, sy, ex, ey);
+ }
+ if (h >= r.bottom()) {
+ pa.drawLine(sx, ey, ex, ey);
+ }
+}
+
+void FNCanvas::mousePressEvent(QMouseEvent* evt)
+{
+ if (!_current->IsShow) {
+ return;
+ }
+ setFocus();
+ _timer->stop();
+ _tracks.clear();
+ _txtwait = 10;
+ if (_viewMode) {
+ _isWaiting = true;
+ _viewMode = false;
+ setOrigin((int)((evt->x()) / _scale_x) - width() / 2, (int)((evt->y()) / _scale_y) - height() / 2, false);
+ //redraw();
+ emit resetViewMode();
+ } else if (MODE_CPICK == _drawMode) {
+ QRgb c = _buffer.convertToImage().pixel(evt->pos().x(), evt->pos().y());
+ emit pickColor(c);
+ return;
+ } else if (MODE_TEXT == _drawMode) {
+ _txtTmp = NULL;
+// _last = evt->pos();
+ _last = SnapPoint(evt->pos(), SNAP_SIZE / 4);
+ int x = _last.x();
+ int y = _last.y();
+ for (int i = _current->draws.count() - _current->disp_offset() - 1; i >= 0; --i) {
+ FNPolygon* p = _current->draws.at((uint)i);
+ if (FN_TEXT == p->type()) {
+ QRect r = p->boundingRect();
+ if (r.contains(x, y)) {
+ _txtTmp = (FNText*)p;
+ _selection.setRect(0, 0, -1, -1);
+ _tdx = _last.x() - r.x();
+ _tdy = _last.y() - r.y();
+ break;
+ }
+ }
+ }
+ } else if (MODE_ERASE == _drawMode) {
+ if (_isEraseWaiting) {
+ return;
+ }
+ _last = evt->pos();
+
+ if (0 >= _selection.width() || !_selection.contains(_last)) {
+ _isSelected = false;
+ }
+ if (!_isSelected) {
+ _selection = QRect(0, 0, -1, -1);
+ _selected.clear();
+ redraw();
+
+ int w = _eraser_s;
+ if (PENWIDTH_MAX / 2 < _pen.width()) {
+ w = _eraser_l;
+ }
+ // 大バグ対策:
+ // 0 > xの座標に、縦150位の四角形を書くと、C系ザウのパフォーマンスが激落ちします。
+ // 以降同様のロジックはこの対策のためです。
+ QPainter pwin;
+ pwin.begin(this);
+ pwin.setRasterOp(XorROP);
+ pwin.setPen(QPen(white, 1));
+ _preRect.setRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
+ drawRect(pwin, _preRect);
+ pwin.flush();
+ pwin.end();
+ _selection = QRect(0, 0, -1, -1);
+ _selected.clear();
+ } else {
+ QPainter pwin;
+ pwin.begin(this);
+
+ pwin.setRasterOp(XorROP);
+ pwin.setPen(QPen(white, 1));
+ _preRect.setRect(_selection.x(), _selection.y(), _selection.width(), _selection.height());
+ drawRect(pwin, _preRect);
+
+ pwin.flush();
+ pwin.end();
+ QPoint t = SnapPoint(QPoint(_selection.x(), _selection.y()));
+ _last = SnapPoint(_last);
+
+ _tdx = _last.x() - t.x();
+ _tdy = _last.y() - t.y();
+ }
+ } else {
+ _last = evt->pos();
+ _tracks.append(new QPoint(_last));
+ }
+ _isDragging = true;
+}
+
+void FNCanvas::mouseMoveEvent(QMouseEvent* evt)
+{
+ if (!_current->IsShow) {
+ return;
+ }
+ if (_isWaiting) {
+ return;
+ }
+ if (MODE_TEXT == _drawMode) {
+ if (NULL == _txtTmp) {
+ return;
+ }
+ if (0 < _txtwait) {
+ --_txtwait;
+ return;
+ }
+ QPainter pwin;
+ pwin.begin(this);
+ if (-1 != _selection.width()) {
+ pwin.setRasterOp(XorROP);
+ pwin.setPen(QPen(white, 1));
+ drawRect(pwin, _selection);
+ } else {
+ _selection = _txtTmp->boundingRect();
+ }
+ QPoint tmp = SnapPoint(evt->pos(), SNAP_SIZE / 4);
+ tmp.setX(tmp.x() - _tdx);
+ tmp.setY(tmp.y() - _tdy);
+ if (tmp != _last) {
+ _selection.moveTopLeft(tmp);
+ _last = tmp;
+ }
+ drawRect(pwin, _selection);
+ pwin.flush();
+ pwin.end();
+ } else if (MODE_CPICK == _drawMode) {
+ QRgb c = _buffer.convertToImage().pixel(evt->pos().x(), evt->pos().y());
+ emit pickColor(c);
+ return;
+ } else if (MODE_ERASE == _drawMode) {
+ //redraw();
+ if (_last.x() == -1) {
+ return;
+ }
+ if (!_isSelected) {
+ int w = _eraser_s;
+ if (PENWIDTH_MAX / 2 < _pen.width()) {
+ w = _eraser_l;
+ }
+ QPainter pwin;
+ pwin.begin(this);
+
+ pwin.setRasterOp(XorROP);
+ pwin.setPen(QPen(white, 1));
+ drawRect(pwin, _preRect);
+
+ _last = evt->pos();
+
+ _preRect.setRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
+ pwin.setRasterOp(CopyROP);
+ QRect r = QRect(0, 0, width(), height());
+ for (uint i = 0; i < _current->draws.count() - _current->disp_offset(); ++i) {
+ FNPolygon* p = _current->draws.at(i);
+ QRect bounds = p->boundingRect();
+ if (r.intersects(bounds)) {
+ bool f = false;
+ QRect& selected = _preRect;
+ for (uint j = 0; j < p->points().count(); ++j) {
+ QPoint& pts = p->points().at(j);
+ if (selected.contains(pts)) {
+ f = true;
+ if (-1 == _selection.width()) {
+ _selection = bounds;
+ } else {
+ if (bounds.x() < _selection.x()) {
+ _selection.setX(bounds.x());
+ }
+ if (bounds.y() < _selection.y()) {
+ _selection.setY(bounds.y());
+ }
+ if (bounds.right() > _selection.right()) {
+ _selection.setRight(bounds.right());
+ }
+ if (bounds.bottom() > _selection.bottom()) {
+ _selection.setBottom(bounds.bottom());
+ }
+ }
+ break;
+ }
+ }
+ if (f) {
+ if (0 == _selected.contains(p)) {
+ _selected.append(p);
+ }
+ p->drawShape(pwin, f);
+ }
+ }
+ }
+ pwin.setRasterOp(XorROP);
+ pwin.setPen(QPen(white, 1));
+ drawRect(pwin, _preRect);
+ pwin.flush();
+ pwin.end();
+ } else {
+ if (0 >= _selection.width()) {
+ return;
+ }
+ //選択中(移動処理)
+ QPainter pwin;
+ pwin.begin(this);
+ pwin.setRasterOp(XorROP);
+ pwin.setPen(QPen(white, 1));
+ drawRect(pwin, _preRect);
+ _last = SnapPoint(evt->pos(), SNAP_SIZE / 4);
+ _preRect.setRect(_last.x() - _tdx, _last.y() - _tdy, _selection.width(), _selection.height());
+ drawRect(pwin, _preRect);
+ pwin.flush();
+ pwin.end();
+ }
+ } else {
+ QPainter pwin;
+ pwin.begin(this);
+ pwin.setPen(_pen);
+
+ pwin.drawLine(_last, evt->pos());
+ pwin.flush();
+
+ pwin.end();
+ _last = evt->pos();
+ _tracks.append(new QPoint(_last));
+ }
+}
+
+void FNCanvas::mouseReleaseEvent(QMouseEvent* evt)
+{
+ if (!_current->IsShow) {
+ return;
+ }
+ _isDragging = false;
+ if (_isWaiting) {
+ _isWaiting = false;
+ return;
+ }
+ if (MODE_ERASE == _drawMode) {
+ if (_isSelected) {
+ //_lastへ移動
+ _last = SnapPoint(evt->pos(), SNAP_SIZE / 4);
+ int dx = _last.x() - _tdx - _selection.x();
+ int dy = _last.y() - _tdy - _selection.y();
+ for (uint i = 0; i < _selected.count(); ++i) {
+ FNPolygon* p = _selected.at(i);
+ p->translate(dx, dy);
+ }
+ _selection.moveBy(dx, dy);
+ redraw();
+ } else {
+ if (false == _isEraseWaiting) {
+ _isEraseWaiting = true;
+ }
+ redraw();
+ _timer->start(_scrollTiming, true);
+ }
+ } else if (MODE_CPICK == _drawMode) {
+ QRgb c = _buffer.convertToImage().pixel(evt->pos().x(), evt->pos().y());
+ emit pickColor(c);
+ emit changeMode(_prevMode);
+ return;
+ } else {
+ if (1 < _tracks.count()) {
+ _last = evt->pos();
+ FNPolygon* p = NULL;
+ if (MODE_FORMAT == _drawMode) {
+ p = new FNPolygon(_pen);
+ _tracks = AutoFormat(_tracks);
+ } else if (MODE_CURVE == _drawMode) {
+ QPoint sp = SnapPoint(*_tracks.at(0));
+ QPoint ep = SnapPoint(*_tracks.at(_tracks.count()-1));
+ FNPointList tracks;
+ tracks.setAutoDelete(true);
+ for (uint i = 0; i < _tracks.count(); ++i) {
+ QPoint t = *_tracks.at(i);
+ tracks.append(new QPoint(t.x(), t.y()));
+ }
+ _tracks = AutoCurve(_tracks);
+ bool isEllipse = false;
+ if (sp == ep) {
+ if (0 < _tracks.count()) {
+ int vdconv = 0; //縦方向転換
+ int vdir = 0;
+ int svdir = 0;
+
+ int hdconv = 0; //横方向転換
+ int hdir = 0;
+ int shdir = 0;
+ QPoint* st = _tracks.at(0);
+ QPoint* l = st;
+ for (uint i = 1; i < _tracks.count(); ++i) {
+ QPoint* p = _tracks.at(i);
+ int thdir = sign(p->x() - l->x());
+ if (l->x() != p->x()) {
+ //水平方向転換
+ if (0 != thdir) {
+ if (0 == hdir) {
+ shdir = thdir;
+ } else if (thdir != hdir) {
+ ++hdconv;
+ }
+ hdir = thdir;
+ }
+ }
+ int tvdir = sign(p->y() - l->y());
+ if (l->y() != p->y()) {
+ //垂直方向転換
+ if (0 != tvdir) {
+ if (0 == vdir) {
+ svdir = tvdir;
+ } else if (tvdir != vdir) {
+ ++vdconv;
+ }
+ vdir = tvdir;
+ }
+ }
+ l = p;
+ }
+ if (shdir == hdir) {
+ --hdconv;
+ }
+ if (svdir == vdir) {
+ --vdconv;
+ }
+
+ if (1 >= hdconv && 1 >= vdconv) {
+ isEllipse = true;
+ int dircnt = 0;
+ //もう1判定
+ tracks = AutoFormat(tracks);
+ if (2 < tracks.count()) {
+ int phdir = sign(tracks.at(1)->x() - tracks.at(0)->x());
+ int pvdir = sign(tracks.at(1)->y() - tracks.at(0)->y());
+ l = tracks.at(1);
+ for (uint i = 2; i < tracks.count(); ++i) {
+ QPoint* p = tracks.at(i);
+ int thdir = sign(p->x() - l->x());
+ int tvdir = sign(p->y() - l->y());
+ if ((0 == pvdir && 0 != tvdir && 0 != phdir && 0 == thdir) ||
+ (0 != pvdir && 0 == tvdir && 0 == phdir && 0 != thdir))
+ {
+ if (3 < dircnt) {
+ isEllipse = false;
+ break;
+ }
+ ++dircnt;
+ }
+ l = p;
+ phdir = thdir;
+ pvdir = tvdir;
+ }
+ }
+ }
+ }
+ }
+ if (isEllipse) {
+ QRect r = GetBounds(_tracks);
+ _tracks.clear();
+ sp = SnapPoint(QPoint(r.x(), r.y()));
+ ep = SnapPoint(QPoint(r.x() + r.width(), r.y() + r.height()));
+ _tracks.append(new QPoint(sp.x(), sp.y()));
+ _tracks.append(new QPoint(ep.x(), ep.y()));
+ p = new FNEllipse(_pen);
+ } else if (2 < _tracks.count()) {
+ p = new FNBezier(_pen);
+ } else {
+ p = new FNPolygon(_pen);
+ }
+ } else if (MODE_SMOOTH == _drawMode) {
+ _tracks = Smoothing(_tracks);
+ if (2 < _tracks.count()) {
+ p = new FNBezier(_pen);
+ } else {
+ p = new FNPolygon(_pen);
+ }
+ } else {
+ _tracks = Reduce(_tracks);
+ p = new FNPolygon(_pen);
+ }
+ if (NULL != p) {
+ p->setFill(_fill);
+ if (1 < _tracks.count()) {
+ p->setPoints(_tracks);
+ redobuf_flush();
+ _current->draws.append(p);
+ }
+ }
+ } else if (MODE_TEXT == _drawMode) {
+ if (NULL == _txtTmp) {
+ textEdit(_last.x(), _last.y());
+ } else {
+ QRect r = _txtTmp->boundingRect();
+ if (_selection == r || 0 < _txtwait) {
+ textEdit(r.x(), r.y(), _txtTmp);
+ } else {
+ if (-1 != _selection.width()) {
+ _txtTmp->translate(_last.x() - r.x(), _last.y() - r.y());
+ }
+ }
+ }
+ _txtTmp = NULL;
+ }
+ _tracks.clear();
+ _isHeadingEnables = true;
+ _timer->start(_scrollTiming, true);
+ }
+}
+
+void FNCanvas::textEdit(int x, int y, FNText* obj)
+{
+ FNTextDialog dlg(fontname, _colorSelector, this);
+ dlg.show();
+ /*
+ if (width() < _tboxRect.x()) {
+ _tboxRect.setX(0);
+ }
+ if (50 > _tboxRect.y()) {
+ _tboxRect.setY(50);
+ }
+ if (height() < _tboxRect.height()) {
+ _tboxRect.setHeight(height());
+ }
+ if (width() < _tboxRect.width()) {
+ _tboxRect.setWidth(width());
+ }
+ dlg.move(_tboxRect.x(), _tboxRect.y());
+ dlg.resize(_tboxRect.width(), _tboxRect.height());
+ */
+ dlg.move(width() / 8, height() / 8);
+ dlg.resize(width() * 6 / 8, height() * 6 / 8);
+ QPen pen = _pen;
+ if (NULL != obj) {
+ for (uint i = 0; i < obj->lines.count(); ++i) {
+ dlg.lines->append(obj->lines[i]);
+ }
+ pen = obj->pen();
+ }
+ dlg.setPen(pen);
+
+ int mx = x;
+ int my = y;
+ if (dlg.exec()) {
+ pen = dlg.pen();
+ if (0 < dlg.lines->text().length()) {
+ FNText* p = obj;
+ if (NULL == obj) {
+ p = new FNText(pen);
+ _current->draws.append((FNPolygon*)p);
+ }
+ p->pen() = pen;
+ p->lines.clear();
+ FNPointList l;
+ l.append(new QPoint(x, y));
+ QFont font(fontname);
+ font.setPointSize(FONTSIZE[pen.width()]);
+ QFontMetrics fm(font);
+ int h = fm.height();
+ for (int i = 0; i < dlg.lines->numLines(); ++i) {
+ p->lines.append(dlg.lines->textLine(i));
+ int w = fm.width(dlg.lines->textLine(i)) + x;
+ l.append(new QPoint(w, my));
+ my += h;
+ l.append(new QPoint(w, my));
+ l.append(new QPoint(x, my));
+ if (mx < w) {
+ mx = w;
+ }
+ }
+ p->setPoints(l);
+ redobuf_flush();
+ redraw();
+ } else {
+ if (NULL != obj) {
+ _current->draws.remove(obj);
+ }
+ }
+ }
+ _tboxRect = QRect(dlg.x(), dlg.y(), dlg.width(), dlg.height());
+}
+void FNCanvas::paintEvent(QPaintEvent*)
+{
+ bitBlt(this, 0, 0, &_buffer);
+}
+
+void FNCanvas::resizeEvent(QResizeEvent* evt)
+{
+ QPixmap save(_buffer);
+ _buffer.resize(evt->size());
+ _buffer.fill(white);
+ bitBlt(&_buffer, 0, 0, &save);
+ redraw();
+}
+
+void FNCanvas::setOrigin(QPoint& o)
+{
+ this->setOrigin(o.x(), o.y());
+}
+
+QPoint FNCanvas::getTopLeft()
+{
+ bool hasValue = false;
+ int dx = 0;
+ int dy = 0;
+ if (0 < _current->draws.count()) {
+ dx = ((FNPolygon*)_current->draws.at(0))->boundingRect().x();
+ dy = ((FNPolygon*)_current->draws.at(0))->boundingRect().y();
+ }
+
+ for (uint j = 0; j < _layers.count(); ++j) {
+ FNPolygonList& draws = _layers.at(j)->draws;
+ for (uint i = 0; i < draws.count(); ++i) {
+ FNPolygon* p = draws.at(i);
+ hasValue = true;
+ if (dx > p->boundingRect().x()) {
+ dx = p->boundingRect().x();
+ }
+ if (dy > p->boundingRect().y()) {
+ dy = p->boundingRect().y();
+ }
+ }
+ }
+ if (!hasValue || !_isUseAllQuadrant) {
+ return _origin;
+ }
+ return QPoint(snap(dx), snap(dy));
+}
+
+
+void FNCanvas::rebuild()
+{
+ if (!_isUseAllQuadrant) {
+ return;
+ }
+
+ QPoint d = getTopLeft();
+ d.setX(d.x() - SNAP_SIZE);
+ d.setY(d.y() - SNAP_SIZE);
+ for (uint j = 0; j < _layers.count(); ++j) {
+ FNPolygonList& draws = _layers.at(j)->draws;
+ for (uint i = 0; i < draws.count(); ++i) {
+ FNPolygon* p = draws.at(i);
+ p->translate(-d.x(), -d.y());
+ }
+ }
+ _origin = QPoint(0, 0);
+}
+
+void FNCanvas::resetOrigin()
+{
+ int ox = 0;
+ int oy = 0;
+ _isHeadingEnables = false;
+ _timer->stop();
+
+
+ int dx = 0;
+ int dy = 0;
+ if (!_isUseAllQuadrant) {
+ if (0 > ox) {
+ ox = 0;
+ }
+ if (0 > oy) {
+ oy = 0;
+ }
+ dx = _origin.x() - ox;
+ dy = _origin.y() - oy;
+ } else {
+ dx = _origin.x() - ox;
+ dy = _origin.y() - oy;
+ if (0 > ox) {
+ ox = 0;
+ }
+ if (0 > oy) {
+ oy = 0;
+ }
+ }
+ for (uint i = 0; i < _tracks.count(); ++i) {
+ QPoint* p = _tracks.at(i);
+ p->setX(p->x() + dx);
+ p->setY(p->y() + dy);
+ }
+
+ for (uint i = 0; i < _layers.count(); ++i) {
+ FNPolygonList& draws = _layers.at(i)->draws;
+ for (uint j = 0; j < draws.count(); ++j) {
+ FNPolygon* p = draws.at(j);
+ p->translate(dx, dy);
+ }
+ }
+ _origin = QPoint(ox, oy);
+}
+
+void FNCanvas::setOrigin(int ox, int oy, bool isRedrawEnabled)
+{
+ ox = snap(ox);
+ oy = snap(oy);
+ _isHeadingEnables = false;
+ _timer->stop();
+
+ int dx = 0;
+ int dy = 0;
+ if (!_isUseAllQuadrant) {
+ if (0 > ox) {
+ ox = 0;
+ }
+ if (0 > oy) {
+ oy = 0;
+ }
+ dx = _origin.x() - ox;
+ dy = _origin.y() - oy;
+ } else {
+ dx = _origin.x() - ox;
+ dy = _origin.y() - oy;
+ if (0 > ox) {
+ ox = 0;
+ }
+ if (0 > oy) {
+ oy = 0;
+ }
+ }
+ if (dx == 0 && dy == 0) {
+ return;
+ }
+ for (uint i = 0; i < _tracks.count(); ++i) {
+ QPoint* p = _tracks.at(i);
+ p->setX(p->x() + dx);
+ p->setY(p->y() + dy);
+ }
+
+ for (uint j = 0; j < _layers.count(); ++j) {
+ FNPolygonList& draws = _layers.at(j)->draws;
+ for (uint i = 0; i < draws.count(); ++i) {
+ FNPolygon* p = draws.at(i);
+ p->translate(dx, dy);
+ }
+ }
+ if (-1 != _selection.width()) {
+ _selection.moveBy(dx, dy);
+ }
+
+ _origin = QPoint(ox, oy);
+ emit originChanged(ox, oy);
+ if (isRedrawEnabled) {
+ redraw();
+ }
+}
+
+void FNCanvas::redraw()
+{
+ if (_isDrawing) {
+ return;
+ }
+ if (_isDragging) {
+ return;
+ }
+ if (!this->isVisible()) {
+ return;
+ }
+
+ _isDrawing = true;
+ for (uint l = 0; l < _layers.count(); ++l) {
+ FNLayer& layer = *_layers.at(l);
+ if (_isTinyPaging) {
+ if (_current == &layer) {
+ layer.IsShow = true;
+ } else {
+ layer.IsShow = false;
+ }
+ }
+ }
+ int h = height(); //(height() / 40) * 40;
+ _buffer.fill(white);
+ QRect r = QRect(0, 0, width(), height());
+ QPainter pbuf;
+ pbuf.begin(&_buffer);
+ pbuf.setFont(QFont(fontname));
+ pbuf.setClipRect(0, 0, width(), height());
+ if (_viewMode) {
+ float wx = 0;
+ float wy = 0;
+ for (uint l = 0; l < _layers.count(); ++l) {
+ FNLayer& layer = *_layers.at(l);
+ if (layer.IsShow) {
+ FNPolygonList& draws = layer.draws;
+ for (uint i = 0; i < draws.count() - layer.disp_offset(); ++i) {
+ FNPolygon* p = draws.at(i);
+ QRect r = p->boundingRect();
+ if (wx < r.right()) {
+ wx = r.right();
+ }
+ if (wy < r.bottom()) {
+ wy = r.bottom();
+ }
+ }
+ }
+ }
+ wx += SNAP_SIZE;
+ wy += SNAP_SIZE;
+ wx = snap((int)wx);
+ wy = snap((int)wy);
+ wx = wx + _origin.x();
+ wy = wy + _origin.y();
+ _scale_x = (float)width() / wx;
+ _scale_y = (float)height() / wy;
+ if (1.0f < _scale_x) {
+ _scale_x = 1.0f;
+ }
+ if (1.0f < _scale_y) {
+ _scale_y = 1.0f;
+ }
+ if (_scale_x > _scale_y) {
+ _scale_x = _scale_y;
+ } else if (_scale_x < _scale_y) {
+ _scale_y = _scale_x;
+ }
+ for (uint l = 0; l < _layers.count(); ++l) {
+ FNLayer& layer = *_layers.at(l);
+ if (!layer.IsShow) {
+ continue;
+ }
+ FNPolygonList& draws = layer.draws;
+ for (uint i = 0; i < draws.count() - layer.disp_offset(); ++i) {
+ FNPolygon* p = draws.at(i);
+ FNPolygon* t = NULL;
+ if (p->type() == FN_BEZIER) {
+ t = new FNBezier(*(FNBezier*)p);
+ } else if (p->type() == FN_ELLIPSE) {
+ t = new FNEllipse(*(FNEllipse*)p);
+ } else if (p->type() == FN_TEXT) {
+ t = new FNText(*(FNText*)p);
+ } else {
+ t = new FNPolygon(*p);
+ }
+ t->translate(-_origin.x(), -_origin.y());
+ for (uint j = 0; j < t->points().count(); ++j) {
+ QPoint& pts = t->points().at(j);
+ int x = (int)(pts.x() * _scale_x);
+ int y = (int)(pts.y() * _scale_y);
+ pts.setX(x);
+ pts.setY(y);
+ }
+ double pensize = t->pen().width();
+ if (_scale_x > _scale_y) {
+ pensize = pensize * _scale_y;
+ } else {
+ pensize = pensize * _scale_x;
+ }
+ if (0 >= pensize) {
+ pensize = 1;
+ }
+ if (p->type() == FN_TEXT) {
+ FNText* tp = (FNText*)t;
+ QPoint& sp = t->points().at(0);
+
+ //default font size checking...
+ QFont f(fontname, FONTSIZE[p->pen().width()]);
+ QFontMetrics fm(f);
+ int h = fm.height();
+ int wx = 0;
+ int wy = 0;
+ for (uint i = 0; i < tp->lines.count(); ++i) {
+ int tw = fm.width(tp->lines[i]);
+ if (tw > wx) {
+ wx = tw;
+ }
+ wy += h;
+ }
+
+ //create default font image...
+ QRect r = tp->boundingRect();
+ QPixmap tmp(wx + 1, wy + 1);
+ tmp.fill(Qt::white);
+ QPainter pt;
+ pt.begin(&tmp);
+ pt.setFont(f);
+ pt.setPen(p->pen());
+ int y = h + 1;
+ for (uint i = 0; i < tp->lines.count(); ++i) {
+ pt.drawText(1, y, tp->lines[i]);
+ y += h;
+ }
+ pt.flush();
+ pt.end();
+
+ //draw to font image
+ tmp = tmp.convertToImage().smoothScale(r.width(), r.height());
+ tmp.setMask(tmp.createHeuristicMask());
+ pbuf.drawPixmap(sp.x(), sp.y(), tmp);
+ pbuf.flush();
+ } else {
+ t->pen().setWidth(pensize);
+ t->drawShape(pbuf);
+ }
+ delete t;
+ }
+ }
+ } else {
+ if (MODE_ERASE == _drawMode || MODE_FORMAT == _drawMode || MODE_CURVE == _drawMode || MODE_TEXT == _drawMode) {
+ //グリッド描画
+ //QPen pen2(QColor(0, 0, 0), 1);
+ //pbuf.setPen(QPen(QColor(50, 240, 240), 1));
+ pbuf.setPen(QPen(GridColor));
+ for (int x = 0; x < width() + SNAP_SIZE; x += SNAP_SIZE) {
+ pbuf.drawLine(x - SNAP_SIZE / 2, 0, x - SNAP_SIZE / 2, h);
+ for (int y = 0; y < h + SNAP_SIZE; y += SNAP_SIZE) {
+ pbuf.drawLine(0, y - SNAP_SIZE / 2, width(), y - SNAP_SIZE / 2);
+ pbuf.drawRect(x-1,y-1,2,2);
+ }
+ }
+ }
+ if (MODE_ERASE != _drawMode) {
+ if (!(MODE_FORMAT == _drawMode || MODE_CURVE == _drawMode || MODE_TEXT == _drawMode)) {
+ if (_showRuler) {
+ //罫線
+ pbuf.setPen(QPen(RulerColor, 1, SolidLine));
+ int step = SNAP_SIZE * 2; //SNAP_SIZEの2倍に。
+ for (int i = 0; i < height(); i += step) {
+ pbuf.drawLine(0, i, width(), i);
+ }
+ }
+ }
+
+ if (_isShowGuide) {
+ pbuf.setPen(QPen(GuideColor, 1, DashLine));
+ if (AS_HORIZONTAL == _asMode || AS_BOTH == _asMode) {
+ if (0 != _origin.x() || _isUseAllQuadrant) {
+ pbuf.drawLine(width() / _margin, 0, width() / _margin, h);
+ }
+ pbuf.drawLine(width() * (_margin - 1) / _margin, 0, width() * (_margin - 1) / _margin, h);
+ }
+
+ if (AS_VERTICAL == _asMode || AS_BOTH == _asMode) {
+ if (0 != _origin.y() || _isUseAllQuadrant) {
+ pbuf.drawLine(0, h / _margin, width(), h / _margin);
+ }
+ pbuf.drawLine(0, h * (_margin - 1) / _margin, width(), h * (_margin - 1) / _margin);
+ }
+ }
+
+ for (uint l = 0; l < _layers.count(); ++l) {
+ FNLayer& layer = *_layers.at(l);
+ if (layer.IsShow) {
+ FNPolygonList& draws = layer.draws;
+ for (uint i = 0; i < draws.count() - layer.disp_offset(); ++i) {
+ FNPolygon* p = draws.at(i);
+ if (r.intersects(p->boundingRect())) {
+ p->drawShape(pbuf);
+ }
+ }
+ }
+ }
+ } else {
+ for (uint l = 0; l < _layers.count(); ++l) {
+ FNLayer& layer = *_layers.at(l);
+ if (layer.IsShow) {
+ FNPolygonList& draws = layer.draws;
+ for (uint i = 0; i < draws.count() - layer.disp_offset(); ++i) {
+ FNPolygon* p = draws.at(i);
+ if (!_selected.contains(p)) {
+ if (r.intersects(p->boundingRect())) {
+ p->drawShape(pbuf);
+ }
+ }
+ }
+ }
+ }
+ for (uint i = 0; i < _selected.count(); ++i) {
+ _selected.at(i)->drawShape(pbuf, true);
+ }
+ if (_isSelected) {
+ pbuf.setPen(QPen(SelectionFrameColor, 1, DashLine));
+ pbuf.setBrush(NoBrush);
+ pbuf.drawRect(_selection);
+ }
+ }
+ }
+ pbuf.end();
+ _isDrawing = false;
+ repaint();
+}
+
+void FNCanvas::changeColor(QRgb c)
+{
+ _pen.setColor(QColor(c));
+ if (_isSelected && _drawMode == MODE_ERASE) {
+ for (uint i = 0; i < _selected.count(); ++i) {
+ _selected.at(i)->pen().setColor(QColor(c));
+ }
+ }
+}
+
+void FNCanvas::selectionMoveTo(int dx, int dy)
+{
+ if (_isSelected) {
+ for (uint i = 0; i < _selected.count(); ++i) {
+ _selected.at(i)->translate(dx, dy);
+ }
+ _selection.moveBy(dx, dy);
+ }
+ redraw();
+}
+
+void FNCanvas::copy()
+{
+ if (MODE_ERASE != _drawMode || _viewMode) {
+ return;
+ }
+ _clipboard.clear();
+ int size = _selected.count();
+ int a1[size];
+ int a2[size];
+ for (int i = 0; i < size; ++i) {
+ a1[i] = _current->draws.findRef(_selected.at(i));
+ a2[i] = i;
+ }
+
+ //ソート
+ FNPolygonList tmp;
+ for (int i = 0; i < size; ++i) {
+ int min = i;
+ for (int j = i + 1; j < size; ++j) {
+ if (a1[min] > a1[j]) {
+ min = j;
+ }
+ }
+ tmp.append(_selected.at(a2[min]));
+ a1[min] = a1[i];
+ a2[min] = a2[i];
+ }
+
+ //並び順を保証してコピー
+ tmp.clone(_clipboard);
+ tmp.clear();
+}
+
+void FNCanvas::paste()
+{
+ if (_viewMode) {
+ return;
+ }
+ if (MODE_ERASE == _drawMode) {
+ _selected.clear();
+ _clipboard.clone(_selected);
+ _selection = QRect(0, 0, -1, -1);
+ for (uint i = 0; i < _selected.count(); ++i) {
+ FNPolygon* o = _selected.at(i);
+ o->translate(10, 10);
+ QRect bounds = o->boundingRect();
+ if (-1 == _selection.width()) {
+ _selection = bounds;
+ } else {
+ if (bounds.x() < _selection.x()) {
+ _selection.setX(bounds.x());
+ }
+ if (bounds.y() < _selection.y()) {
+ _selection.setY(bounds.y());
+ }
+ if (bounds.right() > _selection.right()) {
+ _selection.setRight(bounds.right());
+ }
+ if (bounds.bottom() > _selection.bottom()) {
+ _selection.setBottom(bounds.bottom());
+ }
+ }
+ }
+ _selected.copy(_current->draws);
+ _isSelected = true;
+ } else {
+ int my = 10;
+ int mx = 10;
+ int x = 10;
+ QStringList lines = QStringList::split("\n", QApplication::clipboard()->text());
+ if (0 < lines.count()) {
+ FNText* p = new FNText(_pen);
+ _current->draws.append((FNPolygon*)p);
+ p->lines.clear();
+ FNPointList l;
+ l.append(new QPoint(0, 0));
+ QFont font(fontname);
+ font.setPointSize(FONTSIZE[_pen.width()]);
+ QFontMetrics fm(font);
+ int h = fm.height();
+ for (uint i = 0; i < lines.count(); ++i) {
+ p->lines.append(lines[i]);
+ int w = fm.width(lines[i]) + x;
+ l.append(new QPoint(w, my));
+ my += h;
+ l.append(new QPoint(w, my));
+ l.append(new QPoint(x, my));
+ if (mx < w) {
+ mx = w;
+ }
+ }
+ p->setPoints(l);
+ }
+ }
+ redraw();
+}
+
+void FNCanvas::redo()
+{
+ if (MODE_ERASE != _drawMode) {
+ _current->redo();
+ }
+ redraw();
+}
+
+void FNCanvas::clearList(FNPolygonList& list)
+{
+ list.setAutoDelete(true);
+ list.clear();
+ list.setAutoDelete(false);
+}
+
+void FNCanvas::resetSelection()
+{
+ _selection = QRect(0, 0, -1, -1);
+ _selected.clear();
+ _isSelected = false;
+}
+
+void FNCanvas::clear()
+{
+ resetSelection();
+ _layers.clear();
+ _current = new FNLayer();
+ _layers.append(_current);
+ _current->Name = "Layer0";
+ _selIdx = 0;
+ _isTinyPaging = false;
+ //_undobuf.clear();
+ setOrigin(0, 0);
+ redraw();
+}
+
+void FNCanvas::undo()
+{
+ _timer->stop();
+ if (MODE_ERASE != _drawMode) {
+ _current->undo();
+ } else {
+ _selected.clear();
+ _isSelected = false;
+ _layers.clear();
+ for (uint i = 0; i < _undobuf.count(); ++i) {
+ _layers.append(new FNLayer(*_undobuf.at(i)));
+ }
+ _current = _layers.at(0);
+ _selIdx = 0;
+ }
+ redraw();
+}
+
+void FNCanvas::viewChanged(bool flg)
+{
+ _tracks.clear();
+ _viewMode = flg;
+ if (_viewMode) {
+ if (_isUseAllQuadrant) {
+ rebuild();
+ }
+ setOrigin(0, 0, false);
+ }
+ redraw();
+}
+
+void FNCanvas::redobuf_flush()
+{
+ _current->redobuf_flush();
+}
+
+void FNCanvas::modeChanged(int mode)
+{
+ _tracks.clear();
+ resetSelection();
+ _drawMode = mode;
+ for (uint i = 0; i < _layers.count(); ++i) {
+ FNLayer* p = _layers.at(i);
+ p->modeChanged();
+ }
+ _undobuf.clear();
+ if (MODE_ERASE == mode) {
+ _isEraseWaiting = false;
+ for (uint i = 0; i < _layers.count(); ++i) {
+ _undobuf.append(new FNLayer(*_layers.at(i)));
+ }
+ }
+ if (MODE_CPICK != mode) {
+ _prevMode = mode;
+ }
+ redraw();
+}
+
+QRect FNCanvas::getMatrix(const QRect& r) const
+{
+ int ox = _origin.x();
+ int oy = _origin.y();
+ const int wide = 100;
+
+ int left = r.left() + ox;
+ int top = r.top() + oy;
+ int right = r.right() + ox;
+ int bottom = r.bottom() + oy;
+
+ left = (int)(left / wide) * wide;
+ top = (int)(top / wide) * wide;
+ right = (right % wide == 0 && left != right) ? right : (int)((right + wide) / wide) * wide;
+ bottom = (bottom % wide == 0 && top != bottom) ? bottom : (int)((bottom + wide) / wide) * wide;
+
+ return QRect(left - ox, top - oy, right - left, bottom - top);
+}
+
+void FNCanvas::CR()
+{
+ if (MODE_ERASE == _drawMode) {
+ return;
+ }
+ int h = height(); //(height() / 40) * 40;
+ int step = snap(h) / _margin;
+ if (_isHeadingEnables) {
+ //lastから、左方向に向けて探索する。
+ QRect r = getMatrix(_current->draws.last()->boundingRect());
+ bool isSearching = true;
+ r.moveBy(-100, 0);
+ while (isSearching) {
+ isSearching = false;
+ for (uint i = 0; i < _current->draws.count(); ++i) {
+ FNPolygon* p = _current->draws.at(i);
+ const QRect& r2 = p->boundingRect();
+ if (r.intersects(r2)) {
+ if (r.left() + 100 > r2.left()) {
+ r = getMatrix(r2);
+ r.moveBy(-100, 0);
+ isSearching = true;
+ break;
+ }
+ }
+ }
+ }
+ r.moveBy(100, 0);
+ //lastが画面の4/5以下ならば、スクロールアップする。
+ //そうでなければ、ヘッディングのみ。
+ if (_last.y() > h * 4 / 5) {
+ setOrigin(_origin.x() + r.x(), _origin.y() + step);
+ } else {
+ setOrigin(_origin.x() + r.x(), _origin.y());
+ }
+ _isHeadingEnables = false;
+ } else {
+ //lastの周囲に何も無い場合は、縦にスクロールする。
+ setOrigin(_origin.x(), _origin.y() + step);
+ }
+}
+
+void FNCanvas::erase()
+{
+ if (MODE_ERASE != _drawMode) {
+ return;
+ }
+ FNPolygonList temp;
+ int w = _eraser_s;
+ if (PENWIDTH_MAX / 2 < _pen.width()) {
+ w = _eraser_l;
+ }
+ for (uint i = 0; i < _selected.count(); ++i) {
+ _current->draws.remove(_selected.at(i));
+ //_marks.append(_selected.at(i));
+ }
+ resetSelection();
+ _tracks.clear();
+ _isEraseWaiting = false;
+ redraw();
+}
+
+void FNCanvas::setPensize(int sz)
+{
+ _pen.setWidth(sz);
+ if (_isSelected) {
+ for (uint i = 0; i < _selected.count(); ++i) {
+ if (FN_TEXT != _selected.at(i)->type()) {
+ _selected.at(i)->pen().setWidth(sz);
+ }
+ }
+ }
+}
+
+bool FNCanvas::exportPNG(const QFileInfo& info, QPixmap& buf)
+{
+ if (0 == info.fileName().length()) {
+ QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
+ return false;
+ }
+ if (info.extension(false) != "png") {
+ QMessageBox::warning(0,"FreeNoteQt", "extension '.png' expected.");
+ return false;
+ }
+
+ bool ret;
+ if (_isColorRevision) {
+ QImage img = buf.convertToImage();
+ int wd = buf.width();
+ int ht = buf.height();
+ for (int i = 0; i < ht; ++i) {
+ for (int j = 0; j < wd; ++j) {
+ QRgb c = img.pixel(j, i);
+ int r = qRed(c) >> 3;
+ int g = qGreen(c) >> 2;
+ int b = qBlue(c) >> 3;
+ r = (r << 3) | (r >> 2);
+ b = (b << 3) | (b >> 2);
+ g = (g << 2) | (g >> 4);
+ //float f1 = 248f / 255f;
+ //float f2 = 252f / 255f;
+ //img.setPixel(qRed(c) * f1, qGreen(c) * f2, qBlue(c) * f1);
+ img.setPixel(j, i, qRgb(r, g, b));
+ }
+ }
+ ret = img.save(info.absFilePath(), "PNG");
+ } else {
+ ret = buf.save(info.absFilePath(), "PNG");
+ }
+ if (ret) {
+ FNMessageBox::information(0,"FreeNoteQt", "export PNG complete.");
+ } else {
+ QMessageBox::warning(0,"FreeNoteQt", "could not export file.");
+ }
+ return ret;
+}
+
+QString FNCanvas::mkPDFscript(FNPolygon* elm, int wy)
+{
+ QString s ="";
+ char buf[1024];
+ float r;
+ float g;
+ float b;
+ if (_isColorRevision) {
+ r = (float)elm->pen().color().red() / 248.0f;
+ g = (float)elm->pen().color().green() / 252.0f;
+ b = (float)elm->pen().color().blue() / 248.0f;
+ } else {
+ r = (float)elm->pen().color().red() / 255.0f;
+ g = (float)elm->pen().color().green() / 255.0f;
+ b = (float)elm->pen().color().blue() / 255.0f;
+ }
+ if (elm->type() == FN_TEXT) {
+ FNText* t = (FNText*)elm;
+ sprintf(buf, "BT\r\n/F1 %d Tf\r\n", FONTSIZE[elm->pen().width()]);
+ s += buf;
+ sprintf(buf, "0 Tr\r\n%f %f %f rg\r\n", r, g, b);
+ s += buf;
+ QRect r = t->boundingRect();
+ r.moveBy(_origin.x(), _origin.y());
+ QFont font(fontname);
+ font.setPointSize(FONTSIZE[elm->pen().width()]);
+ QFontMetrics fm(font);
+ int h = fm.height();
+ int y = r.y() + h;
+ for (uint i = 0; i < t->lines.count(); ++i) {
+ sprintf(buf, "1 0 0 1 %d %d Tm\r\n", r.x() + 3, wy - y);
+ s += buf;
+ y = y + h;
+ s += "<";
+ for (uint j = 0; j < t->lines[i].length(); ++j) {
+ sprintf(buf, "%04X", (t->lines[i].at(j).unicode() & 0x0ffff));
+ s += buf;
+ }
+ s += "> Tj\r\n";
+ }
+ s += "ET\r\n";
+ } else {
+ s += "q\r\n";
+ if (elm->fill()) {
+ sprintf(buf, "%f %f %f rg\r\n", r, g, b);
+ } else {
+ sprintf(buf, "%f %f %f RG\r\n", r, g, b);
+ }
+ s += buf;
+ QPointArray points = elm->points().copy();
+ points.translate(_origin.x(), _origin.y());
+ if (elm->type() == FN_BEZIER) {
+ sprintf(buf, "%d %d m\r\n", points[0].x(), wy - points[0].y());
+ s += buf;
+ for (uint j = 1; j < points.count(); j += 3) {
+ sprintf(buf, "%d %d %d %d %d %d c\r\n",
+ points[j].x(), wy - points[j].y(),
+ points[j + 1].x(), wy - points[j + 1].y(),
+ points[j + 2].x(), wy - points[j + 2].y()
+ );
+ s += buf;
+ }
+ } else if (elm->type() == FN_ELLIPSE) {
+ int x = points[0].x();
+ int y = points[0].y();
+ int ex = points[1].x();
+ int ey = points[1].y();
+ int w = ex - x;
+ int h = ey - y;
+ int cx = x + w/2;
+ int cy = y;
+ int x1 = x + 3*w/4;
+ int y1 = y;
+ int x2 = x + w;
+ int y2 = y + h/4;
+ int x3 = x + w;
+ int y3 = y + h/2;
+
+ sprintf(buf, "%d %d m\r\n%d %d %d %d %d %d c\r\n", cx, wy - cy, x1, wy - y1, x2, wy - y2, x3, wy - y3);
+ s += buf;
+ x1 = x + w;
+ y1 = y + 3 * h / 4;
+ x2 = x + 3 * w / 4;
+ y2 = y + h;
+ x3 = x + w/2;
+ y3 = y + h;
+ sprintf(buf, "%d %d %d %d %d %d c\r\n", x1, wy - y1, x2, wy - y2, x3, wy - y3);
+ s += buf;
+
+ x1 = x + w / 4;
+ y1 = y + h;
+ x2 = x;
+ y2 = y + 3 * h / 4;
+ x3 = x;
+ y3 = y + h / 2;
+ sprintf(buf, "%d %d %d %d %d %d c\r\n", x1, wy - y1, x2, wy - y2, x3, wy - y3);
+ s += buf;
+ x1 = x;
+ y1 = y + h / 4;
+ x2 = x + w / 4;
+ y2 = y;
+ x3 = x + w / 2;
+ y3 = y;
+ sprintf(buf, "%d %d %d %d %d %d c\r\n", x1, wy - y1, x2, wy - y2, x3, wy - y3);
+ s += buf;
+ } else {
+ sprintf(buf, "%d %d m\r\n", points[0].x(), wy - points[0].y());
+ s += buf;
+ for (uint j = 1; j < points.count(); ++j) {
+ sprintf(buf, "%d %d l\r\n", points[j].x(), wy - points[j].y());
+ s += buf;
+ }
+ }
+ sprintf(buf, "%d w\r\n", elm->pen().width());
+ s += buf;
+ if (elm->fill()) {
+ s += "f*\r\n";
+ } else {
+ s += "S\r\n";
+ }
+ s += "Q\r\n";
+ }
+ return s;
+}
+
+bool FNCanvas::exportPDF(const QFileInfo& info)
+{
+ if (0 == info.fileName().length()) {
+ QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
+ return false;
+ }
+ if (info.extension(false) != "pdf") {
+ QMessageBox::warning(0,"FreeNoteQt", "extension '.pdf' expected.");
+ return false;
+ }
+
+ FILE* fp = NULL;
+ if (!(fp = fopen(info.absFilePath().utf8(), "wt"))) {
+ QMessageBox::warning(0,"FreeNoteQt", "could not export file.");
+ return false;
+ }
+
+ QPoint o = getTopLeft();
+ rebuild();
+ int wx = 595;
+ int wy = 842;
+ char buf[1024];
+ int bias = 0;
+ if (_isUseAllQuadrant) {
+ bias = SNAP_SIZE;
+ }
+ for (uint l = 0; l < _layers.count(); ++l) {
+ FNLayer& layer = *_layers.at(l);
+ FNPolygonList& draws = layer.draws;
+ for (uint i = 0; i < draws.count() - layer.disp_offset(); ++i) {
+ FNPolygon* p = draws.at(i);
+ QRect r = p->boundingRect();
+ r.moveBy(_origin.x(), _origin.y());
+ if (wx < r.right() + bias) {
+ wx = r.right() + bias;
+ }
+ if (wy < r.bottom() + bias) {
+ wy = r.bottom() + bias;
+ }
+ }
+ }
+
+ int len = 0;
+
+ /*
+ sprintf(buf, "1 0 0 -1 0 %d cm\r\n", wy);
+ QString cm = buf;
+ len += cm.length();
+ */
+ QString cm = "";
+
+ for (uint l = 0; l < _layers.count(); ++l) {
+ FNLayer& layer = *_layers.at(l);
+ if (layer.IsShow) {
+ FNPolygonList& draws = layer.draws;
+ for (uint i = 0; i < draws.count() - layer.disp_offset(); ++i) {
+ QString s = mkPDFscript(draws.at(i), wy);
+ len += s.length();
+ }
+ }
+ }
+
+ //int ref = 0;
+ QString header = "";
+ QStringList xref;
+ xref.append("0000000000 65535 f\r\n");
+
+ header += "%PDF-1.3\r\n";
+ sprintf(buf, "%010d 00000 n\r\n", header.length());
+ xref.append(buf);
+
+ header += "1 0 obj<</Type/Catalog/Outlines 2 0 R/Pages 3 0 R>>\r\n";
+ header += "endobj\r\n";
+ sprintf(buf, "%010d 00000 n\r\n", header.length());
+ xref.append(buf);
+
+
+ header += "2 0 obj<</Type/Outlines/Count 0>>\r\n";
+ header += "endobj\r\n";
+ sprintf(buf, "%010d 00000 n\r\n", header.length());
+ xref.append(buf);
+
+ header += "3 0 obj<</Type/Pages/Kids[4 0 R]/Count 1>>\r\n";
+ header += "endobj\r\n";
+ sprintf(buf, "%010d 00000 n\r\n", header.length());
+ xref.append(buf);
+
+ header += "4 0 obj<</Type/Page/Parent 3 0 R";
+ sprintf(buf, "/MediaBox[0 0 %d %d]", wx, wy);
+ header += buf;
+ header += "/Contents 6 0 R/Resources<</Font<</F1 5 0 R>>/ProcSet[/PDF/Text]>>>>\r\n";
+ header += "endobj\r\n";
+ sprintf(buf, "%010d 00000 n\r\n", header.length());
+ xref.append(buf);
+
+ if (encode == QString("WinAnsiEncoding")) {
+ header += "5 0 obj<</Type/Font/Subtype/Type1/BaseFont/Helvetica/FirstChar 0/LastChar 255/Encoding/WinAnsiEncoding>>\r\n";
+ } else if (encode == QString("UniJIS-UCS2-H")) {
+ header += "5 0 obj<</Type/Font/Encoding/UniJIS-UCS2-H/BaseFont/MSGothic/Subtype/Type0/DescendantFonts[<</W[0[1000] 1 94 500 231 324 500 327 389 500 631 [500] 668 [500]]/Type/Font/BaseFont/MSGothic/Subtype/CIDFontType2/CIDSystemInfo<</Ordering(Japan1)/Registry(Adobe)/Supplement 2>>/FontDescriptor<</Type/FontDescriptor/FontBBox[0 -137 1000 859]/FontName/MSGothic/Flags 32/StemV 92/CapHeight 770/XHeight 543/Ascent 859/Descent -137/ItalicAngle 0>>/DW 1000>>]>>\r\n";
+ }
+ header += "endobj\r\n";
+ sprintf(buf, "%010d 00000 n\r\n", header.length());
+ xref.append(buf);
+
+ sprintf(buf, "6 0 obj<</Length %d>>\r\n", len);
+ header += buf;
+ header += "stream\r\n";
+
+ QString footer = "";
+ footer += "xref\r\n";
+ sprintf(buf, "0 %d\r\n", xref.count());
+ footer += buf;
+ for (uint i = 0; i < xref.count(); ++i) {
+ footer += xref[i];
+ }
+ footer += "trailer\r\n";
+ sprintf(buf, "<</Size %d/Root 1 0 R>>\r\n", xref.count());
+ footer += buf;
+ footer += "startxref\r\n";
+
+ len = cm.length();
+ len += header.length();
+ fputs(header, fp);
+ fputs(cm, fp);
+
+ for (uint l = 0; l < _layers.count(); ++l) {
+ FNLayer& layer = *_layers.at(l);
+ if (layer.IsShow) {
+ FNPolygonList& draws = layer.draws;
+ for (uint i = 0; i < draws.count() - layer.disp_offset(); ++i) {
+ QString s = mkPDFscript(draws.at(i), wy);
+ len += s.length();
+ fputs(s, fp);
+ }
+ }
+ }
+ QString streamfooter = "endstream\r\nendobj\r\n";
+ len += streamfooter.length();
+ fputs(streamfooter, fp);
+
+ fputs(footer, fp);
+ sprintf(buf, "%d\r\n", len);
+ fputs(buf, fp);
+ fputs("%%EOF\r\n", fp);
+ fclose(fp);
+ if (_isUseAllQuadrant) {
+ setOrigin(-o.x(), -o.y());
+ }
+ FNMessageBox::information(0,"FreeNoteQt", "export PDF complete.");
+ return true;
+}
+
+bool FNCanvas::save(const QFileInfo& info)
+{
+ if (0 == info.fileName().length()) {
+ QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
+ return false;
+ }
+ if (info.extension(false) != "free") {
+ QMessageBox::warning(0,"FreeNoteQt", "extension '.free' expected.");
+ return false;
+ }
+ FILE* fp = NULL;
+ if (!(fp = fopen(info.absFilePath().utf8(), "wt"))) {
+ QMessageBox::warning(0,"FreeNoteQt", "could not save file.");
+ return false;
+ }
+ QPoint o = getTopLeft();
+ rebuild();
+ fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
+ char buf[1024];
+ sprintf(buf, "<freenote version=\"4.1\" pg=%d idx=\"%d\">\n", _isTinyPaging, _selIdx);
+ fputs(buf, fp);
+ for (uint l = 0; l < _layers.count(); ++l) {
+ FNLayer& layer = *_layers.at(l);
+ FNPolygonList& draws = layer.draws;
+ QString s = "<layer v=";
+ if (layer.IsShow) {
+ s += "1 name=\"";
+ } else {
+ s += "0 name=\"";
+ }
+ s += layer.Name;
+ s += "\">\n";
+ fputs(s.utf8(), fp);
+ for (uint i = 0; i < draws.count() - layer.disp_offset(); ++i) {
+ FNPolygon p(*draws.at(i));
+ p.translate(_origin.x(), _origin.y());
+ if (p.type() == FN_BEZIER) {
+ sprintf(buf, "\t<bz color=\"%x\" width=\"%d\" f=\"%d\">\n", (uint)p.pen().color().rgb(), p.pen().width(), p.fill());
+ } else if (p.type() == FN_ELLIPSE) {
+ sprintf(buf, "\t<el color=\"%x\" width=\"%d\" f=\"%d\">\n", (uint)p.pen().color().rgb(), p.pen().width(), p.fill());
+ } else if (p.type() == FN_TEXT) {
+ sprintf(buf, "\t<tx color=\"%x\" width=\"%d\">\n", (uint)p.pen().color().rgb(), p.pen().width());
+ } else {
+ sprintf(buf, "\t<po color=\"%x\" width=\"%d\" f=\"%d\">\n", (uint)p.pen().color().rgb(), p.pen().width(), p.fill());
+ }
+ fputs(buf, fp);
+ QPointArray& points = p.points();
+ for (uint j = 0; j < points.count(); ++j) {
+ QPoint point = points.point(j);
+ sprintf(buf, "\t\t<p x=\"%d\" y=\"%d\"/>\n", point.x(), point.y());
+ fputs(buf, fp);
+ }
+ if (p.type() == FN_BEZIER) {
+ fputs("\t</bz>\n", fp);
+ } else if (p.type() == FN_ELLIPSE) {
+ fputs("\t</el>\n", fp);
+ } else if (p.type() == FN_TEXT) {
+ FNText* tp = (FNText*)draws.at(i);
+ for (uint j = 0; j < tp->lines.count(); ++j) {
+ s = "\t\t<t v=\"";
+ s += tp->lines[j];
+ s += "\"/>\n";
+ fputs(s.utf8(), fp);
+ }
+ fputs("\t</tx>\n", fp);
+ } else {
+ fputs("\t</po>\n", fp);
+ }
+ }
+ fputs("</layer>\n", fp);
+ }
+ fputs("</freenote>\n", fp);
+ fclose(fp);
+ if (_isUseAllQuadrant) {
+ setOrigin(-o.x()+SNAP_SIZE, -o.y()+SNAP_SIZE);
+ }
+ FNMessageBox::information(0, "FreeNoteQt", "save complete.");
+ return true;
+}
+
+bool FNCanvas::load(const QFileInfo& info)
+{
+ if (0 == info.fileName().length()) {
+ QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
+ return false;
+ }
+ if (!info.exists()) {
+ QMessageBox::warning(0,"FreeNoteQt", "file not exists.");
+ return false;
+ }
+ FILE* fp = NULL;
+ if (!(fp = fopen(info.absFilePath().utf8(), "rt"))) {
+ QMessageBox::warning(0,"FreeNoteQt", "could not open file.");
+ return false;
+ }
+ clear();
+ open(_layers, fp);
+ if ((uint)_selIdx >= _layers.count()) {
+ _selIdx = 0;
+ }
+ _current = _layers.at(_selIdx);
+ fclose(fp);
+
+ redraw();
+ FNMessageBox::information(0,"FreeNoteQt", "load complete.");
+
+ return true;
+}
+
+bool FNCanvas::import(const QFileInfo& info)
+{
+ if (0 == info.fileName().length()) {
+ QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
+ return false;
+ }
+ if (!info.exists()) {
+ QMessageBox::warning(0,"FreeNoteQt", "file not exists.");
+ return false;
+ }
+ FILE* fp = NULL;
+ if (!(fp = fopen(info.absFilePath().utf8(), "rt"))) {
+ QMessageBox::warning(0,"FreeNoteQt", "could not open file.");
+ return false;
+ }
+ clearList(_clipboard);
+ open(_clipboard, fp);
+ fclose(fp);
+ if (0 < _clipboard.count()) {
+ int x = _clipboard.at(0)->boundingRect().left();
+ int y = _clipboard.at(0)->boundingRect().top();
+ for (uint i = 1; i < _clipboard.count(); ++i) {
+ if (y > _clipboard.at(i)->boundingRect().top()) {
+ y = _clipboard.at(i)->boundingRect().top();
+ }
+ if (x > _clipboard.at(i)->boundingRect().left()) {
+ x = _clipboard.at(i)->boundingRect().left();
+ }
+ }
+ for (uint i = 0; i < _clipboard.count(); ++i) {
+ _clipboard.at(i)->translate(-x, -y);
+ }
+ }
+ FNMessageBox::information(0,"FreeNoteQt", "import complete.");
+
+ return true;
+}
+void FNCanvas::open(FNPolygonList& list, FILE* fp)
+{
+ clearList(list);
+ FNLayerList layers;
+ open(layers, fp);
+ for (uint i = 0; i < layers.count(); ++i) {
+ FNLayer& layer = *layers.at(i);
+ if (layer.IsShow) {
+ layer.draws.clone(list);
+ /*
+ FNPolygonList& elmlst = layer.draws;
+ for (uint j = 0; j < elmlst.count(); ++j) {
+ list.append(elmlst.at(j));
+ }
+ elmlst.clear();
+ */
+ }
+ }
+ layers.clear();
+}
+
+void FNCanvas::open(FNLayerList& layers, FILE* fp)
+{
+ QString line;
+ FNPointList points;
+ points.setAutoDelete(true);
+ int c;
+ int w;
+ QPen pen(Qt::black, 1);
+ FNPolygon* polygon;
+
+ char rdbuf[1024];
+ char buf[1024];
+ QString type = "";
+ QStringList lines;
+ layers.setAutoDelete(true);
+ layers.clear();
+ layers.setAutoDelete(false);
+ FNLayer* layer = new FNLayer();
+ layer->IsShow = true;
+ layer->Name = "Layer0";
+ //_current = layer;
+ layers.append(layer);
+ FNPolygonList* list = &layer->draws;
+ bool isFirstLayer = true;
+ bool fill = false;
+ while (!feof(fp)) {
+ fgets(rdbuf, sizeof(rdbuf), fp);
+ line = rdbuf;
+ if (-1 != line.find("<freenote")) {
+ if (-1 != line.find("pg=1")) {
+ _isTinyPaging = true;
+ } else {
+ _isTinyPaging = false;
+ }
+ int st = line.find("idx=") + 5;
+ int ed = line.find("\"", st);
+ strcpy(buf, line.mid(st, ed - st));
+ sscanf(buf, "%d", &_selIdx);
+ } else if (-1 != line.find("<layer ")) {
+ if (false == isFirstLayer) {
+ layer = new FNLayer();
+ list = &layer->draws;
+ layers.append(layer);
+ }
+ isFirstLayer = false;
+
+ if (-1 != line.find("v=0")) {
+ layer->IsShow = false;
+ } else if (-1 != line.find("v=1")) {
+ layer->IsShow = true;
+ }
+ int st = line.find("name=") + 6;
+ int ed = line.find("\"", st);
+ strcpy(buf, line.mid(st, ed - st));
+ QTextCodec *codec = QTextCodec::codecForName("utf8");
+ layer->Name = codec->toUnicode(buf);
+ } else if (-1 != line.find("<fnpolygon ") ||
+ -1 != line.find("<po ") ||
+ -1 != line.find("<bz ") ||
+ -1 != line.find("<el ") ||
+ -1 != line.find("<tx ")
+ ) {
+ if (-1 != line.find("<el ")) {
+ type = "Ellipse";
+ } else if (-1 != line.find("<bz ")) {
+ type = "Bezier";
+ } else if (-1 != line.find("<tx ")) {
+ type = "Text";
+ lines.clear();
+ } else {
+ type = "Polygon";
+ }
+ fill = false;
+ points.clear();
+ int st = line.find("color") + 7;
+ int ed = line.find("\"", st);
+ strcpy(buf, line.mid(st, ed - st));
+ sscanf(buf, "%x", &c);
+
+ st = line.find("width") + 7;
+ ed = line.find("\"", st);
+ strcpy(buf, line.mid(st, ed - st));
+ sscanf(buf, "%d", &w);
+
+ if (-1 != line.find(" f=\"1\"")) {
+ fill = true;
+ }
+ } else if (-1 != line.find("<point ") ||
+ -1 != line.find("<p ")
+ ) {
+ int st = line.find("x=") + 3;
+ int ed = line.find("\"", st);
+ strcpy(buf, line.mid(st, ed - st));
+ int x;
+ sscanf(buf, "%d", &x);
+
+ st = line.find("y=") + 3;
+ ed = line.find("\"", st);
+ strcpy(buf, line.mid(st, ed - st));
+ int y;
+ sscanf(buf, "%d", &y);
+ points.append(createPts(x, y)); //バグ対策
+ } else if (-1 != line.find("<t ")) {
+ int st = line.find("v=") + 3;
+ int ed = line.findRev("\"");
+ strcpy(buf, line.mid(st, ed - st));
+ QTextCodec *codec = QTextCodec::codecForName("utf8");
+ lines.append(codec->toUnicode(buf));
+ } else if (-1 != line.find("</fnpolygon") ||
+ -1 != line.find("</bz") ||
+ -1 != line.find("</el") ||
+ -1 != line.find("</po") ||
+ -1 != line.find("</tx")) {
+ pen.setColor((QRgb)c);
+ pen.setWidth(w);
+ if (type == "Bezier") {
+ list->append(polygon = createBezier(pen)); //バグ対策
+ } else if (type == "Ellipse") {
+ list->append(polygon = createEllipse(pen)); //バグ対策
+ } else if (type == "Text") {
+ list->append(polygon = createText(pen, lines));
+ } else {
+ list->append(polygon = createPolygon(pen)); //バグ対策
+ }
+ polygon->setFill(fill);
+ polygon->setPoints(points);
+ points.clear();
+ }
+ }
+}
+
+FNPolygon* FNCanvas::createPolygon(QPen& pen)
+{
+ return new FNPolygon(pen);
+}
+
+FNPolygon* FNCanvas::createBezier(QPen& pen)
+{
+ return new FNBezier(pen);
+}
+
+
+FNPolygon* FNCanvas::createEllipse(QPen& pen)
+{
+ return new FNEllipse(pen);
+}
+
+FNPolygon* FNCanvas::createText(QPen& pen, QStringList& lines)
+{
+ FNText* p = new FNText(pen);
+ p->lines = lines;
+ return p;
+}
+
+QPoint* FNCanvas::createPts(int x, int y)
+{
+ return new QPoint(x, y);
+}
+
+void FNCanvas::setGuide(bool f)
+{
+ _isShowGuide = f;
+ redraw();
+}
+
+void FNCanvas::fillChanged(bool f) {
+ _fill = f;
+ if (_isSelected) {
+ for (uint i = 0; i < _selected.count(); ++i) {
+ _selected.at(i)->setFill(f);
+ }
+ }
+}
diff --git a/packages/freenote/files/FreeNote/FreeNote/FNFindDialog.cpp b/packages/freenote/files/FreeNote/FreeNote/FNFindDialog.cpp
new file mode 100644
index 0000000000..9d0998ad04
--- /dev/null
+++ b/packages/freenote/files/FreeNote/FreeNote/FNFindDialog.cpp
@@ -0,0 +1,143 @@
+/* FreeNote for Sharp SLA300, B500, C7x0, C860 Linux PDA
+ Copyright (C) 2003-2005 Joe Kanemori.<kanemori@ymg.urban.ne.jp>
+
+ 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
+*/
+/*
+2005/02/27 FreeNote 1.11.10pre
+・PDFの出力形式を一部変更
+・インポート時のバグfix
+
+2005/01/04 FreeNote 1.11.6pre
+・カーブモードで8の字がかけるように整形エンジンを改善
+
+2004/10/17 FreeNote 1.10.0リリース
+2004/02/14 ver 1.7.2pre
+・検索機能の追加
+*/
+#include "fnfinddialog.h"
+#include "fmtengine.h"
+#include <qlineedit.h>
+#include <stdio.h>
+#include <qregexp.h>
+#include <qcheckbox.h>
+
+FNFindDialog::FNFindDialog( QWidget* parent, const char* name)
+ :FNFindDialogBase(parent, name, true, 0), _idx(0)
+{
+}
+
+void FNFindDialog::setElements(FNLayerList& v)
+{
+ _texts.clear();
+ for (uint i = 0; i < v.count(); ++i) {
+ FNLayer& layer = *v.at(i);
+ if (layer.IsShow) {
+ FNPolygonList& draws = layer.draws;
+ for (uint j = 0; j < draws.count(); ++j) {
+ FNPolygon* p = draws.at(j);
+ if (FN_TEXT == p->type()) {
+ _texts.append(p);
+ }
+ }
+ }
+ }
+ _idx = -1;
+}
+
+void FNFindDialog::findPrev()
+{
+ QString sch = txtSearch->text();
+ QRegExp rex(sch);
+ if (0 == sch.length()) {
+ return;
+ }
+ if (0 > _idx) {
+ _idx = _texts.count() - 1;
+ }
+ if ((uint)_idx >= _texts.count()) {
+ _idx = _texts.count() - 1;
+ }
+ for (; _idx >= 0; --_idx) {
+ FNText* p = (FNText*)_texts.at(_idx);
+ for (uint i = 0; i < p->lines.count(); ++i) {
+ if (ckbIsRegExp->isChecked()) {
+ for (uint i = 0; i < p->lines.count(); ++i) {
+ if (-1 != p->lines[i].find(rex)) {
+ emit resetOrigin();
+ QPoint sp = p->points().point(0);
+ emit originChanged(sp.x() - SNAP_SIZE, sp.y() - SNAP_SIZE);
+ --_idx;
+ return;
+ }
+ }
+ } else {
+ for (uint i = 0; i < p->lines.count(); ++i) {
+ if (-1 != p->lines[i].find(sch)) {
+ emit resetOrigin();
+ QPoint sp = p->points().point(0);
+ emit originChanged(sp.x() - SNAP_SIZE, sp.y() - SNAP_SIZE);
+ --_idx;
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+void FNFindDialog::findNext()
+{
+ QString sch = txtSearch->text();
+ QRegExp rex(sch);
+ if (0 == sch.length()) {
+ return;
+ }
+ if (0 > _idx) {
+ _idx = 0;
+ }
+ if ((uint)_idx >= _texts.count()) {
+ _idx = 0;
+ }
+ for (; (uint)_idx < _texts.count(); ++_idx) {
+ FNText* p = (FNText*)_texts.at(_idx);
+ if (ckbIsRegExp->isChecked()) {
+ for (uint i = 0; i < p->lines.count(); ++i) {
+ if (-1 != p->lines[i].find(rex)) {
+ emit resetOrigin();
+ QPoint sp = p->points().point(0);
+ emit originChanged(sp.x() - SNAP_SIZE, sp.y() - SNAP_SIZE);
+ ++_idx;
+ return;
+ }
+ }
+ } else {
+ for (uint i = 0; i < p->lines.count(); ++i) {
+ if (-1 != p->lines[i].find(sch)) {
+ emit resetOrigin();
+ QPoint sp = p->points().point(0);
+ emit originChanged(sp.x() - SNAP_SIZE, sp.y() - SNAP_SIZE);
+ ++_idx;
+ return;
+ }
+ }
+ }
+ }
+}
+
+
+FNFindDialog::~FNFindDialog()
+{
+}
diff --git a/packages/freenote/files/FreeNote/FreeNote/FNMessageBox.cpp b/packages/freenote/files/FreeNote/FreeNote/FNMessageBox.cpp
new file mode 100644
index 0000000000..1518651338
--- /dev/null
+++ b/packages/freenote/files/FreeNote/FreeNote/FNMessageBox.cpp
@@ -0,0 +1,243 @@
+/* FreeNote for Sharp SLA300, B500, C7x0, C860 Linux PDA
+ Copyright (C) 2003-2005 Joe Kanemori.<kanemori@ymg.urban.ne.jp>
+
+ 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
+*/
+/*
+2005/02/27 FreeNote 1.11.10pre
+・PDFの出力形式を一部変更
+・インポート時のバグfix
+
+2004/10/17 FreeNote 1.10.0リリース
+2003/08/15 FreeNote 1.2.1を公開
+・保存時のバグ修正
+・完了ダイアログの自動消去
+・PNGファイルへの出力
+*/
+#include "fnmessagebox.h"
+int ___fnmessagebox_timing = 1500;
+
+FNMessageBox::FNMessageBox(QWidget *parent, const char* name) : QMessageBox(parent, name)
+{
+ _timer = new QTimer(this);
+ connect(_timer, SIGNAL(timeout()), this, SLOT(timeout()));
+}
+
+FNMessageBox::FNMessageBox(const QString& caption, const QString& text, Icon icon, int button0, int button1, int button2, QWidget* parent, const char* name, bool modal, WFlags f) : QMessageBox(caption, text, icon, button0, button1, button2, parent, name, modal, f)
+{
+ _timer = new QTimer(this);
+ connect(_timer, SIGNAL(timeout()), this, SLOT(timeout()));
+}
+
+FNMessageBox::~FNMessageBox()
+{
+ delete _timer;
+}
+
+int FNMessageBox::information(QWidget* parent, const QString& caption, const QString& text, int button0, int button1, int button2)
+{
+ FNMessageBox dlg(caption, text, QMessageBox::Information, button0, button1, button2, parent);
+ dlg.show();
+ return dlg.exec();
+}
+
+int FNMessageBox::information(QWidget* parent, const QString& caption, const QString& text, const QString& button0Text, const QString& button1Text, const QString& button2Text, int defaultButtonNumber, int escapeButtonNumber)
+{
+ int button0 = 0;
+ int button1 = 0;
+ int button2 = 0;
+ if (QString::null == button0Text) {
+ int id = Ok;
+ if (0 == defaultButtonNumber) {
+ id += Default;
+ }
+ if (0 == escapeButtonNumber) {
+ id += Escape;
+ }
+ button0 = id;
+ }
+ if (QString::null != button1Text) {
+ int id = Cancel;
+ if (1 == defaultButtonNumber) {
+ id += Default;
+ }
+ if (1 == escapeButtonNumber) {
+ id += Escape;
+ }
+ button1 = id;
+ }
+ if (QString::null != button2Text) {
+ int id = Abort;
+ if (2 == defaultButtonNumber) {
+ id += Default;
+ }
+ if (2 == escapeButtonNumber) {
+ id += Escape;
+ }
+ button2 = id;
+ }
+ FNMessageBox dlg(caption, text, QMessageBox::Information, button0, button1, button2, parent);
+ if (0 != button0) {
+ dlg.setButtonText(button0, button0Text);
+ }
+ if (0 != button1) {
+ dlg.setButtonText(button1, button1Text);
+ }
+ if (0 != button2) {
+ dlg.setButtonText(button2, button2Text);
+ }
+ dlg.show();
+ return dlg.exec();
+}
+
+int FNMessageBox::warning(QWidget* parent, const QString& caption, const QString& text, int button0, int button1, int button2)
+{
+ FNMessageBox dlg(caption, text, QMessageBox::Warning, button0, button1, button2, parent);
+ dlg.show();
+ return dlg.exec();
+}
+
+int FNMessageBox::warning(QWidget* parent, const QString& caption, const QString& text, const QString& button0Text, const QString& button1Text, const QString& button2Text, int defaultButtonNumber, int escapeButtonNumber)
+{
+ int button0 = 0;
+ int button1 = 0;
+ int button2 = 0;
+ if (QString::null == button0Text) {
+ int id = Ok;
+ if (0 == defaultButtonNumber) {
+ id += Default;
+ }
+ if (0 == escapeButtonNumber) {
+ id += Escape;
+ }
+ button0 = id;
+ }
+ if (QString::null != button1Text) {
+ int id = Cancel;
+ if (1 == defaultButtonNumber) {
+ id += Default;
+ }
+ if (1 == escapeButtonNumber) {
+ id += Escape;
+ }
+ button1 = id;
+ }
+ if (QString::null != button2Text) {
+ int id = Abort;
+ if (2 == defaultButtonNumber) {
+ id += Default;
+ }
+ if (2 == escapeButtonNumber) {
+ id += Escape;
+ }
+ button2 = id;
+ }
+ FNMessageBox dlg(caption, text, QMessageBox::Warning, button0, button1, button2, parent);
+ if (0 != button0) {
+ dlg.setButtonText(button0, button0Text);
+ }
+ if (0 != button1) {
+ dlg.setButtonText(button1, button1Text);
+ }
+ if (0 != button2) {
+ dlg.setButtonText(button2, button2Text);
+ }
+ dlg.show();
+ return dlg.exec();
+}
+
+int FNMessageBox::critical(QWidget* parent, const QString& caption, const QString& text, int button0, int button1, int button2)
+{
+ FNMessageBox dlg(caption, text, QMessageBox::Critical, button0, button1, button2, parent);
+ dlg.show();
+ return dlg.exec();
+}
+
+int FNMessageBox::critical(QWidget* parent, const QString& caption, const QString& text, const QString& button0Text, const QString& button1Text, const QString& button2Text, int defaultButtonNumber, int escapeButtonNumber)
+{
+ int button0 = 0;
+ int button1 = 0;
+ int button2 = 0;
+ if (QString::null == button0Text) {
+ int id = Ok;
+ if (0 == defaultButtonNumber) {
+ id += Default;
+ }
+ if (0 == escapeButtonNumber) {
+ id += Escape;
+ }
+ button0 = id;
+ }
+ if (QString::null != button1Text) {
+ int id = Cancel;
+ if (1 == defaultButtonNumber) {
+ id += Default;
+ }
+ if (1 == escapeButtonNumber) {
+ id += Escape;
+ }
+ button1 = id;
+ }
+ if (QString::null != button2Text) {
+ int id = Abort;
+ if (2 == defaultButtonNumber) {
+ id += Default;
+ }
+ if (2 == escapeButtonNumber) {
+ id += Escape;
+ }
+ button2 = id;
+ }
+ FNMessageBox dlg(caption, text, QMessageBox::Critical, button0, button1, button2, parent);
+ if (0 != button0) {
+ dlg.setButtonText(button0, button0Text);
+ }
+ if (0 != button1) {
+ dlg.setButtonText(button1, button1Text);
+ }
+ if (0 != button2) {
+ dlg.setButtonText(button2, button2Text);
+ }
+ dlg.show();
+ return dlg.exec();
+}
+
+void FNMessageBox::about(QWidget* parent, const QString& caption, const QString& text)
+{
+ FNMessageBox dlg(caption, text, QMessageBox::NoIcon, 0, 0, 0, parent);
+ dlg.show();
+ dlg.exec();
+}
+
+void FNMessageBox::about(QWidget* parent, const QString& caption)
+{
+ FNMessageBox dlg(caption, QString::null, QMessageBox::NoIcon, 0, 0, 0, parent);
+ dlg.show();
+ dlg.exec();
+}
+
+void FNMessageBox::setTiming(const int v)
+{
+ ___fnmessagebox_timing = v;
+}
+
+void FNMessageBox::timeout() {
+ accept();
+}
+
+void FNMessageBox::showEvent(QShowEvent* ext)
+{
+ _timer->start(___fnmessagebox_timing, true);
+}
diff --git a/packages/freenote/files/FreeNote/FreeNote/FNTextDialog.cpp b/packages/freenote/files/FreeNote/FreeNote/FNTextDialog.cpp
new file mode 100644
index 0000000000..b4eea5454c
--- /dev/null
+++ b/packages/freenote/files/FreeNote/FreeNote/FNTextDialog.cpp
@@ -0,0 +1,93 @@
+/* FreeNote for Sharp SLA300, B500, C7x0, C860 Linux PDA
+ Copyright (C) 2003-2005 Joe Kanemori.<kanemori@ymg.urban.ne.jp>
+
+ 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
+*/
+/*
+2005/02/27 FreeNote 1.11.10pre
+・PDFの出力形式を一部変更
+・インポート時のバグfix
+
+2005/01/04 FreeNote 1.11.6pre
+・カーブモードで8の字がかけるように整形エンジンを改善
+
+2004/10/17 FreeNote 1.10.0リリース
+2004/02/12 ver 1.7.1pre
+・フォント仕様の変更
+・テキスト処理の高速化
+・テキストボックスの多機能化
+*/
+#include "fntextdialog.h"
+#include <stdio.h>
+#include <qcombobox.h>
+#include <qfontdatabase.h>
+#include <qcolor.h>
+#include <qtoolbutton.h>
+#include <qpalette.h>
+#include <qmultilineedit.h>
+#include "fncolordialog.h"
+
+FNTextDialog::FNTextDialog(const QString& fontname, FNColorDialog* dlg, QWidget* parent, const char* name )
+ :FNTextDialogBase(parent, name, true, 0), _pen(1), _colorSelector(dlg)
+{
+ static QFontDatabase fbase;
+ QValueList<int> sizes = fbase.pointSizes(fontname);
+ char buf[10];
+ for (uint i = 0; i < sizes.count(); ++i) {
+ sprintf(buf, "%d", sizes[i]);
+ cboFontSize->insertItem(buf);
+ }
+ lines->setFont(QFont(fontname, 20));
+}
+
+
+FNTextDialog::~FNTextDialog()
+{
+}
+
+void FNTextDialog::changeColor(QRgb c)
+{
+ fraColor->setBackgroundColor(QColor(c));
+ _pen.setColor(QColor(c));
+}
+
+void FNTextDialog::choose(int v)
+{
+ _pen.setWidth(v);
+}
+
+void FNTextDialog::btnColor_Clicked()
+{
+ _colorSelector->setColor(_pen.color());
+ _colorSelector->show();
+ if (_colorSelector->exec()) {
+ changeColor(_colorSelector->color().rgb());
+ }
+}
+
+void FNTextDialog::setPen(const QPen& pen)
+{
+ _pen = pen;
+ if (cboFontSize->count() <= (int)pen.width()) {
+ _pen.setWidth(cboFontSize->count()-1);
+ }
+ cboFontSize->setCurrentItem(_pen.width());
+ fraColor->setBackgroundColor(_pen.color());
+}
+
+const QPen& FNTextDialog::pen() const
+{
+ return _pen;
+}
diff --git a/packages/freenote/files/FreeNote/FreeNote/FmtEngine.cpp b/packages/freenote/files/FreeNote/FreeNote/FmtEngine.cpp
new file mode 100644
index 0000000000..dae8a81b3b
--- /dev/null
+++ b/packages/freenote/files/FreeNote/FreeNote/FmtEngine.cpp
@@ -0,0 +1,512 @@
+/* FreeNote for Sharp SLA300, B500, C7x0, C860 Linux PDA
+ Copyright (C) 2003-2005 Joe Kanemori.<kanemori@ymg.urban.ne.jp>
+
+ 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
+*/
+/*
+2005/02/27 FreeNote 1.11.10pre
+・PDFの出力形式を一部変更
+・インポート時のバグfix
+
+2005/01/04 FreeNote 1.11.6pre
+・カーブモードで8の字がかけるように整形エンジンを改善
+
+2005/01/09 FNViewer ジェスチャー用ロジック追加
+2004/10/17 FreeNote 1.10.0リリース
+2003/12/16-19 FreeNote ver 1.5.5pre
+・曲線描画ロジックの改良
+
+2003/12/14 FreeNote 1.5.4pre
+・曲線描画ロジックの改良
+
+2003/11/30-2003/12/04 FreeNote 1.5.3pre
+・ベジェ関数のスペルミスを修正
+
+2003/11/16 FreeNote 1.5.2pre
+・円描画のロジックを追加
+
+2003/11/13 FreeNote 1.5.1pre
+・スムージング追加
+2003/11/10-12
+・曲線整形モード追加
+2003/11/09 追加
+*/
+#include "fmtengine.h"
+#include <qpointarray.h>
+#include <qpe/qmath.h>
+#include <math.h>
+#include <qrect.h>
+#include <stdlib.h>
+
+int SNAP_SIZE = 32;
+int PHASE1_ANGLE = 30;
+int PHASE2_ANGLE = 30;
+double Surface(const QPoint& p1, const QPoint& p2)
+{
+ return 0.5 * abs(p1.x() * p2.y() - p1.y() * p2.x());
+}
+
+bool IsLinear(const QPoint& p1, const QPoint& p2, const QPoint& p3)
+{
+ double s1 = Surface(p1, p2);
+ double s2 = Surface(p2, p3);
+ double s3 = Surface(p1, p3);
+ if (s1 + s2 == s3) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+const double Angle(const QPoint& p1, const QPoint& p2)
+{
+ return qATan2((double)(p2.y() - p1.y()), (double)(p2.x() - p1.x()));
+}
+
+const double DiffAngle(double a1, double a2)
+{
+ if (0.0 > a1) {
+ a1 = 2 * M_PI + a1;
+ }
+ if (0.0 > a2) {
+ a2 = 2 * M_PI + a2;
+ }
+ return fabs(a1 - a2);
+}
+
+const double DiffAngle2(double a1, double a2)
+{
+ if (0.0 > a1) {
+ a1 = 360 + a1;
+ }
+ if (0.0 > a2) {
+ a2 = 360 + a2;
+ }
+ return fabs(a1 - a2);
+}
+
+const double DiffAngle(const QPoint& p1, const QPoint& p2, const QPoint& p3)
+{
+ return DiffAngle(Angle(p1, p2), Angle(p2, p3));
+}
+
+const double ToDegree(double t)
+{
+ return t * 180 / M_PI;
+}
+
+const double ToRadian(double d)
+{
+ return d * M_PI / 180;
+}
+
+const double Distance(const QPoint& p1, const QPoint& p2)
+{
+ return hypot(p1.x() - p2.x(), p1.y() - p2.y());
+}
+
+const QPoint SnapPoint(const QPoint& p, int snap)
+{
+ int x = ((int)(p.x() + snap / 2) / snap) * snap;
+ int y = ((int)(p.y() + snap / 2) / snap) * snap;
+ return QPoint(x, y);
+}
+const QPoint SnapPoint(const QPoint& p)
+{
+ return SnapPoint(p, SNAP_SIZE);
+}
+/*
+const QPoint SnapPoint(const QPoint& p)
+{
+ int x = ((int)(p.x() + SNAP_SIZE / 2) / SNAP_SIZE) * SNAP_SIZE;
+ int y = ((int)(p.y() + SNAP_SIZE / 2) / SNAP_SIZE) * SNAP_SIZE;
+ return QPoint(x, y);
+}
+*/
+
+const QPoint ArrangePoint(const QPoint& p1, const QPoint& p2)
+{
+ int x = p2.x();
+ int y = p2.y();
+ if (p1.x() - SNAP_SIZE / 2 <= x && p1.x() + SNAP_SIZE / 2 >= x) {
+ x = p1.x();
+ }
+ if (p1.y() - SNAP_SIZE / 2 <= y && p1.y() + SNAP_SIZE / 2 >= y) {
+ y = p1.y();
+ }
+ return QPoint(x, y);
+}
+
+FNPointList ReducePoints(FNPointList& p)
+{
+ if (2 >= p.count()) {
+ return p;
+ }
+ FNPointList rt;
+ rt.append(p.first());
+ QPoint* p1 = p.first();
+ QPoint* p2 = p.at(1);
+ QPoint* p3 = NULL;
+ for (uint i = 2; i < p.count(); ++i) {
+ p3 = p.at(i);
+ if (false == IsLinear(*p1, *p2, *p3)) {
+ rt.append(p2);
+ p1 = p2;
+ }
+ p2 = p3;
+ }
+ rt.append(p3);
+ return rt;
+}
+
+FNPointList ExtractAngle2(FNPointList& p, const int deg)
+{
+ FNPointList rt;
+ rt.append(p.first());
+ QPoint* st = p.first();
+ QPoint* mp = p.at(1);
+ QPoint* ed = p.last();
+ for (uint i = 2; i < p.count(); ++i) {
+ ed = p.at(i);
+ if (ToRadian(deg) <= DiffAngle(*st, *mp, *ed)) {
+ st = mp;
+ rt.append(mp);
+ }
+ mp = ed;
+ }
+ rt.append(ed);
+ return rt;
+}
+
+FNPointList ExtractAngle(FNPointList& p, const int deg)
+{
+ FNPointList rt;
+ rt.append(p.first());
+ QPoint* st = p.first();
+ QPoint* mp = p.at(1);
+ QPoint* ed = p.last();
+ for (uint i = 2; i < p.count(); ++i) {
+ ed = p.at(i);
+ if (ToRadian(deg) <= DiffAngle(*st, *mp, *ed)) {
+ st = mp;
+ rt.append(mp);
+ }
+ mp = ed;
+ }
+ if (SNAP_SIZE / 2 > Distance(*p.first(), *p.last()) && 3 < p.count()) {
+ rt.append(p.first());
+ } else {
+ rt.append(ed);
+ }
+ return rt;
+}
+
+FNPointList SumupPoints(FNPointList& p)
+{
+ if (3 >= p.count()) {
+ return p;
+ }
+ FNPointList rt;
+ rt.append(p.first());
+ QPoint* p1 = p.first();
+ QPoint* p2 = NULL;
+ double pred = 0;
+ for (uint i = 1; i < p.count() - 1; ++i) {
+ p2 = p.at(i);
+ double d = Distance(*p1, *p2);
+ if (SNAP_SIZE / 2 < d || pred > d) {
+ rt.append(p2);
+ p1 = p2;
+ d = 0;
+ }
+ pred = d;
+ }
+ rt.append(p.last());
+ return rt;
+}
+
+FNPointList SnapPoints(FNPointList& p)
+{
+ FNPointList rt;
+ for (uint i = 0; i < p.count(); ++i) {
+ QPoint tp = SnapPoint(*p.at(i));
+ p.at(i)->setX(tp.x());
+ p.at(i)->setY(tp.y());
+ rt.append(p.at(i));
+ }
+ return rt;
+}
+
+FNPointList ArrangePoints(FNPointList& p)
+{
+ if (3 >= p.count() && 2 != p.count()) {
+ return p;
+ }
+ FNPointList rt;
+ rt.append(p.first());
+ QPoint* p1 = p.first();
+ QPoint* p2 = NULL;
+ for (uint i = 1; i < p.count(); ++i) {
+ p2 = p.at(i);
+ QPoint tp = ArrangePoint(*p1, *p2);
+ p2->setX(tp.x());
+ p2->setY(tp.y());
+ rt.append(p2);
+ p1 = p2;
+ }
+ if (*p.first() == *p.last()) {
+ QPoint tp = ArrangePoint(*p1, *p.first());
+ rt.first()->setX(tp.x());
+ rt.first()->setY(tp.y());
+ }
+ return rt;
+}
+
+FNPointList TuningPoints(FNPointList& p)
+{
+ FNPointList rt;
+ if (3 >= p.count()) {
+ for (uint i = 0; i < p.count(); ++i) {
+ rt.append(new QPoint(*p.at(i)));
+ }
+ return rt;
+ }
+ rt.append(new QPoint(*p.at(0)));
+ for (uint i = 1; i < p.count() - 1; ++i) {
+ QPoint* p1 = p.at(i);
+ QPoint* p2 = p.at(i + 1);
+ rt.append(new QPoint(*p1));
+ if (i < p.count() - 2) {
+ rt.append(new QPoint((p1->x() + p2->x())/2, (p1->y() + p2->y())/2));
+ }
+ }
+ rt.append(new QPoint(*p.at(p.count()-1)));
+ return rt;
+}
+
+FNPointList ToBezier(FNPointList& p) {
+ FNPointList rt;
+ rt.append(new QPoint(*p.at(0)));
+ for (uint i = 0; i < p.count() - 2; i += 2) {
+ int x1 = p.at(i)->x();
+ int xa = p.at(i + 1)->x();
+ int x4 = p.at(i + 2)->x();
+
+ int x2 = (x1 + xa) / 2;
+ int x3 = (xa + x4) / 2;
+
+ int y1 = p.at(i)->y();
+ int ya = p.at(i + 1)->y();
+ int y4 = p.at(i + 2)->y();
+
+ int y2 = (y1 + ya) / 2;
+ int y3 = (ya + y4) / 2;
+
+ rt.append(new QPoint(x2 ,y2));
+ rt.append(new QPoint(x3 ,y3));
+ rt.append(new QPoint(x4 ,y4));
+ }
+ return rt;
+}
+
+FNPointList ToCurves(FNPointList& p) {
+ if (3 <= p.count()) {
+ //ベジェによる補完
+ return ToBezier(p);
+ } else {
+ FNPointList rt;
+ for (uint i = 0; i < p.count(); ++i) {
+ rt.append(new QPoint(*p.at(i)));
+ }
+ return rt;
+ }
+}
+
+FNPointList AutoFormat(FNPointList& p)
+{
+ FNPointList tp = ExtractAngle(p, PHASE1_ANGLE);
+ uint n;
+ do {
+ n = tp.count();
+ tp = SumupPoints(tp);
+ tp = ExtractAngle(tp, PHASE1_ANGLE);
+ tp = ArrangePoints(tp);
+ } while (n > tp.count());
+ tp = SnapPoints(tp);
+ tp = ReducePoints(tp);
+ FNPointList rt;
+ if (2 == tp.count()) {
+ if (*tp.first() == *tp.last()) {
+ return rt;
+ }
+ }
+ for (uint i = 0; i < tp.count(); ++i) {
+ rt.append(new QPoint(*tp.at(i)));
+ }
+ return rt;
+}
+
+FNPointList ToEllipse(int x, int y, int w, int h) {
+ FNPointList rt;
+ QPointArray pa;
+ pa.makeEllipse(x, y, w, h);
+ for (uint i = 0; i < pa.count(); ++i) {
+ rt.append(new QPoint(pa.point(i)));
+ }
+ return rt;
+}
+
+FNPointList AutoCurve(FNPointList& p)
+{
+ FNPointList tp2;
+ tp2.setAutoDelete(true);
+ FNPointList tp4;
+ tp4.setAutoDelete(true);
+ /*
+ QPoint sp = SnapPoint(*p.at(0));
+ QPoint ep = SnapPoint(*p.at(p.count()-1));
+ if (sp == ep) {
+ //楕円
+ int sx = p.at(0)->x();
+ int sy = p.at(0)->y();
+ int ex = sx;
+ int ey = sy;
+ for (uint i = 1; i < p.count(); ++i) {
+ QPoint tp = *p.at(i);
+ if (sx > tp.x()) {
+ sx = tp.x();
+ } else if (ex < tp.x()) {
+ ex = tp.x();
+ }
+ if (sy > tp.y()) {
+ sy = tp.y();
+ } else if (ey < tp.y()) {
+ ey = tp.y();
+ }
+ }
+ sp = SnapPoint(QPoint(sx, sy));
+ ep = SnapPoint(QPoint(ex, ey));
+ tp2.append(new QPoint(sp.x(), sp.y()));
+ tp2.append(new QPoint(ep.x(), ep.y()));
+ } else {
+ */
+ FNPointList tp = ExtractAngle2(p, PHASE2_ANGLE);
+ uint n;
+ do {
+ n = tp.count();
+ tp = SumupPoints(tp);
+ tp = ExtractAngle2(tp, PHASE2_ANGLE);
+ tp = SnapPoints(tp);
+ } while (n > tp.count());
+ tp = SumupPoints(tp);
+ tp = ReducePoints(tp);
+ tp4 = TuningPoints(tp);
+ tp2 = ToCurves(tp4);
+ //}
+ FNPointList rt;
+ if (2 == tp2.count()) {
+ if (*tp2.first() == *tp2.last()) {
+ return rt;
+ }
+ }
+ for (uint i = 0; i < tp2.count(); ++i) {
+ rt.append(new QPoint(*tp2.at(i)));
+ }
+ return rt;
+}
+
+FNPointList Smoothing(FNPointList& p)
+{
+ int tsnap = SNAP_SIZE;
+ SNAP_SIZE=8;
+ FNPointList tp = ExtractAngle2(p, PHASE2_ANGLE);
+ tp = SumupPoints(tp);
+ tp = ReducePoints(tp);
+ FNPointList tp4 = TuningPoints(tp);
+ tp4.setAutoDelete(true);
+ FNPointList tp2 = ToCurves(tp4);
+ tp2.setAutoDelete(true);
+ FNPointList rt;
+ for (uint i = 0; i < tp2.count(); ++i) {
+ rt.append(new QPoint(*tp2.at(i)));
+ }
+ SNAP_SIZE = tsnap;
+ return rt;
+}
+
+FNPointList Reduce(FNPointList& p)
+{
+ FNPointList tp = ReducePoints(p);
+ FNPointList rt;
+ for (uint i = 0; i < tp.count(); ++i) {
+ rt.append(new QPoint(*tp.at(i)));
+ }
+ return rt;
+}
+
+QRect GetBounds(FNPointList& v)
+{
+ if (1 > v.count()) {
+ return QRect(0, 0, 1, 1);
+ }
+ QPoint sp = *v.at(0);
+ QPoint ep = sp;
+ for (uint i = 1; i < v.count(); ++i) {
+ QPoint& p = *v.at(i);
+ if (sp.x() > p.x()) {
+ sp.setX(p.x());
+ }
+ if (sp.y() > p.y()) {
+ sp.setY(p.y());
+ }
+ if (ep.x() < p.x()) {
+ ep.setX(p.x());
+ }
+ if (ep.y() < p.y()) {
+ ep.setY(p.y());
+ }
+ }
+ return QRect(sp, ep);
+}
+
+FNPointList Translate(FNPointList& v, int x, int y, double xs, double ys)
+{
+ FNPointList rt;
+ for (uint i = 0; i < v.count(); ++i) {
+ QPoint& p = *v.at(i);
+ int X = (int)((p.x() - x) * xs);
+ int Y = (int)((p.y() - y) * ys);
+ rt.append(new QPoint(X, Y));
+ }
+ return rt;
+}
+
+double ToStrokeDeg(double v)
+{
+ double d = ((int)(v * 10 / 225)) * 22.5;
+ return d;
+}
+
+int sign(int v)
+{
+ if (0 > v) {
+ return -1;
+ } else if (0 < v) {
+ return 1;
+ } else {
+ return 0;
+ }
+};
+
diff --git a/packages/freenote/files/FreeNote/FreeNote/FrmMain.cpp b/packages/freenote/files/FreeNote/FreeNote/FrmMain.cpp
new file mode 100644
index 0000000000..1cb4407d32
--- /dev/null
+++ b/packages/freenote/files/FreeNote/FreeNote/FrmMain.cpp
@@ -0,0 +1,1442 @@
+/* FreeNote for Sharp SLA300, B500, C7x0, C860 Linux PDA
+ Copyright (C) 2003-2005 Joe Kanemori.<kanemori@ymg.urban.ne.jp>
+
+ 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 Foundatibannwaon; 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
+*/
+/*
+2005/07/12 FreeNote 1.12.0
+・Fixリリース
+
+2005/06/04 FreeNote 1.11.12pre
+・グリッドの枠線を実際の選択範囲よりも大きく表示するように変更。
+・範囲選択、グリッド、ガイド、罫線カラーのカスタマイズを可能に。
+・カラーピッカーモードの追加
+
+2005/06/02 FreeNote 1.11.11Apre
+・テキスト移動枠の不具合修正
+・罫線をグリッドの2倍で表示するように変更
+・消しゴム時の範囲指定時に、ペンオフしてワンテンポおいてから範囲確定するように変更
+
+2005/03/18 FreeNote 1.11.10Bpre
+・描画の最適化
+
+2005/02/27 FreeNote 1.11.10pre
+・PDFの出力形式を一部変更
+・インポート時のバグfix
+
+2005/01/04 FreeNote 1.11.6pre
+・カーブモードで8の字がかけるように整形エンジンを改善
+
+2005/01/04 FreeNote 1.11.5Apre
+・バグフィックス
+
+2004/12/25 FreeNote 1.11.5pre
+・レイヤー機能追加
+
+2004/10/17 FreeNote 1.10.0リリース
+・ツール機能追2004/08/26 ver 1.9.3Apre
+・罫線機能の修正
+
+・ツール機能追2004/08/26 ver 1.9.3pre
+・罫線機能を追加
+
+2004/06/19-25 ver 1.9.2pre
+・qcop装備
+
+2004/05/19 ver 1.9.1pre
+・PDFのテキストをUnicodeへ。
+・オプションにPDF::Encode項目を追加。
+
+2004/02/26 ver 1.9.0pre
+・インポート機能
+
+2004/02/19 ver 1.8.0 fix.
+2004/02/16 ver 1.7.3pre
+・編集機能強化
+
+2004/02/14 ver 1.7.2pre
+・検索機能追加
+
+2004/02/12 ver 1.7.1pre
+・フォント仕様の変更
+・テキスト処理の高速化
+・テキストボックスの多機能化
+
+2004/02/10 ver 1.7.0pre
+・文字入力
+
+2003/12/21 ver 1.6.0
+・フローティングパレットが無効となっていたバグを修正
+・機能をFix
+
+2003/12/16-19 ver 1.5.5pre
+・ペン幅の拡張(1-8)
+・アンドゥ、リドゥの実装
+・メニューの処理方法を一部改良
+・高速Quit実装
+
+2003/12/14 FreeNote 1.5.4pre
+・ペンサイズを選択可能に。
+
+2003/11/30-2003/12/04 FreeNote 1.5.3pre
+・ExportPNG, ExportPDFの初期ファイル名がfreeファイル名に沿うように修正
+
+2003/11/16 FreeNote 1.5.2pre
+・曲線整形モード修正
+ 円描画のロジックを追加
+
+2003/11/10-12 ver 1.5.1pre
+・曲線整形モード追加
+
+2003/11/09 ver 1.5.0pre
+・自動整形モード追加
+
+2003/09/03 ver 1.3.4pre
+・Use all quadrant OFF時に表示位置がリセットされる場合があるバグ対応。
+
+2003/09/01-03 ver 1.3.3pre
+・スクロールの改良
+・Use all quadrant(全象限を使用する)メニューを追加
+
+2003/08/17-23 ver 1.3.0pre
+・aboutを付与
+・CRボタン追加
+・スクロールモードの保存
+・ガイド状態の保存
+
+2003/08/17 FreeNote 1.2.2を公開
+・拡張子.freeの自動付与が失敗するケースを修正
+
+2003/08/15 FreeNote 1.2.1を公開
+・保存時のバグ修正
+・完了ダイアログの自動消去
+・PNGファイルへの出力
+
+2003/08/15 FreeNote 1.2を公開
+・オプション追加
+・スクロールガイド
+・Freeファイル関連付け
+・アイコンの変更
+
+2003/08/05 FreeNote 1.1.1preを公開
+・高速起動時に閉じた状態を保持
+・描画モード切替え時に消しゴム表示
+・保存時間短縮
+・Viewモードの挙動を変更
+・メニューの見た目を変更
+*/
+#include "frmmain.h"
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <qpe/global.h>
+#include <qpe/qcopenvelope_qws.h>
+#include <qpe/applnk.h>
+#include <qpe/mimetype.h>
+
+#include <qapplication.h>
+#include <qtoolbutton.h>
+#include <qmessagebox.h>
+#include <qgrid.h>
+#include <qdir.h>
+#include <qstring.h>
+#include <qdatetime.h>
+#include <qtextcodec.h>
+#include <qdatastream.h>
+#include <qpixmap.h>
+
+#include "fnfiledialog.h"
+#include "fniconset.h"
+#include "fmtengine.h"
+#include "fnmessagebox.h"
+#include "fnlayerdlg.h"
+#include "fnpolygon.h"
+
+#define VERSION "1.12.0"
+/*
+ * Constructs a FrmMain which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ */
+FrmMain::FrmMain( QWidget* parent, const char* name, WFlags fl )
+ : QMainWindow( parent, name, fl ),
+ _drawMode(MODE_DRAW),
+ _scrollMode(AS_BOTH),
+ _useAllQuadrant(false),
+ _showRuler(false),
+ _isFullscreen(false),
+ _isLocked(true),
+ _isTinyPaging(false),
+ _isTracking(true)
+{
+ connect( qApp, SIGNAL(appMessage( const QCString&, const QByteArray&)), this, SLOT( qcop_receive( const QCString&, const QByteArray& )));
+ init();
+ setup();
+ setTitle();
+}
+
+void FrmMain::setup()
+{
+ _options.load();
+ setOptions(_options);
+}
+
+void FrmMain::qcop_receive(const QCString& msg, const QByteArray& data)
+{
+ QDataStream stream(data, IO_ReadOnly );
+
+ if (msg == "setPensize(int)") {
+ int v;
+ stream >> v;
+ if (0 <= v && v <= 8) {
+ penSelected(v);
+ }
+ } else if (msg == "setup()") {
+ setup();
+ } else if (msg == "modeChanged(int)") {
+ int v;
+ stream >> v;
+ if (0 <= v && v <= MODE_MAX) {
+ modeChanged(v);
+ }
+ } else if (msg == "changeColor(int,int,int)") {
+ int r;
+ int g;
+ int b;
+ stream >> r;
+ stream >> g;
+ stream >> b;
+ if (0 <= r && r <= 255 &&
+ 0 <= g && g <= 255 &&
+ 0 <= b && b <= 255)
+ {
+ changeColor(qRgb(r, g, b));
+ }
+ } else if (msg == "find()") {
+ _canvas->find();
+ } else if (msg == "undo()") {
+ undo();
+ } else if (msg == "redo()") {
+ _canvas->redo();
+ } else if (msg == "erase()") {
+ _canvas->erase();
+ } else if (msg == "copy()") {
+ _canvas->copy();
+ } else if (msg == "paste()") {
+ _canvas->paste();
+ } else if (msg == "clear()") {
+ clear();
+ } else if (msg == "CR()") {
+ hitRet();
+ } else if (msg == "setViewMode(int)") {
+ int v;
+ stream >> v;
+ if (0 == v) {
+ setViewMode(false);
+ } else {
+ setViewMode(true);
+ }
+ } else if (msg == "load(QString)") {
+ QString fname;
+ stream >> fname;
+ _canvas->load(QFileInfo(fname));
+ } else if (msg == "import(QString)") {
+ QString fname;
+ stream >> fname;
+ _canvas->import(QFileInfo(fname));
+ } else if (msg == "save(QString)") {
+ QString fname;
+ stream >> fname;
+ _canvas->save(QFileInfo(fname));
+ } else if (msg == "exportPDF(QString)") {
+ QString fname;
+ stream >> fname;
+ _canvas->exportPDF(QFileInfo(fname));
+ } else if (msg == "exportPNG(QString)") {
+ QString fname;
+ stream >> fname;
+ QPixmap save(_canvas->wbuffer());
+ _canvas->exportPNG(QFileInfo(fname), save);
+ } else if (msg == "tool(int)") {
+ int v;
+ stream >> v;
+ if (1 <= v && v <= 8) {
+ tool(v);
+ }
+ }
+}
+
+
+//描画モードの変更
+void FrmMain::modeChanged(int mode)
+{
+ _drawMode = mode;
+ _btnCopy->setEnabled(false);
+ //_btnPaste->setEnabled(false);
+ _btnPaste->setEnabled(true);
+ _btnRedo->setEnabled(true);
+ _btnUndo->setEnabled(true);
+ switch (_drawMode) {
+ case MODE_DRAW: //描画
+ _menubar->changeItem(_id_mode, QPixmap((const char**)draw_xpm));
+ break;
+ case MODE_FORMAT: //自動整形
+ _menubar->changeItem(_id_mode, QPixmap((const char**)format_xpm));
+ break;
+ case MODE_CURVE: //曲線整形
+ _menubar->changeItem(_id_mode, QPixmap((const char**)curve_xpm));
+ break;
+ case MODE_SMOOTH: //スムージング
+ _menubar->changeItem(_id_mode, QPixmap((const char**)smooth_xpm));
+ break;
+ case MODE_TEXT: //テキスト
+ _menubar->changeItem(_id_mode, QPixmap((const char**)text_xpm));
+ break;
+ case MODE_ERASE: //編集モード
+ _btnCopy->setEnabled(true);
+ _btnRedo->setEnabled(false);
+ _menubar->changeItem(_id_mode, QPixmap((const char**)eraser_xpm));
+ break;
+ case MODE_CPICK:
+ _menubar->changeItem(_id_mode, QPixmap((const char**)cpick_xpm));
+ break;
+ }
+ _canvas->modeChanged(_drawMode);
+}
+
+//描画モードの切り替え
+void FrmMain::modeMenuChanged(int id)
+{
+ modeChanged(_draw_menu->indexOf(id));
+}
+
+void FrmMain::tool(int id)
+{
+ QString home = getenv("HOME");
+ QString cmd = _options.toolScripts[id];
+ if (cmd == "") {
+ return;
+ }
+ QStringList token = QStringList::split(' ', cmd);
+ QDateTime dtime = QDateTime::currentDateTime();
+ QDate dt = dtime.date();
+ QTime tm = dtime.time();
+ char buf[32];
+ sprintf(buf, "%02d%02d%02d%02d%02d%02d", dt.year() % 100, dt.month(), dt.day(), tm.hour(), tm.minute(), tm.second());
+ QString wkdir = _options.wkdir;
+ if (false == QFileInfo(wkdir).isDir()) {
+ wkdir = home;
+ }
+ int st = 0;
+ for (uint i = st; i < token.count(); ++i) {
+ if (token[i] == "%file") {
+ save();
+ if (_prefile == "") {
+ return;
+ }
+ token[i] = _prefile;
+ } else if (token[i] == "%pdf") {
+ exportPDF();
+ if (_prepdf == "") {
+ return;
+ }
+ token[i] = _prepdf;
+ } else if (token[i] == "%png") {
+ exportPNG();
+ if (_prepng == "") {
+ return;
+ }
+ token[i] = _prepng;
+ } else if (token[i] == "%tmpfile") {
+ _canvas->save(QFileInfo(home + "/.tmp.free"));
+ token[i] = home + "/.tmp.free";
+ } else if (token[i] == "%tmppng") {
+ QPixmap save(_canvas->wbuffer());
+ _canvas->exportPNG(QFileInfo(home + "/.tmp.png"), save);
+ token[i] = home + "/.tmp.png";
+ } else if (token[i] == "%tmppdf") {
+ _canvas->exportPDF(QFileInfo(home + "/.tmp.pdf"));
+ token[i] = home + "/.tmp.pdf";
+ } else if (token[i] == "%newfile") {
+ token[i] = wkdir + "/" + buf +".free";
+ _canvas->save(QFileInfo(token[i]));
+ } else if (token[i] == "%newpng") {
+ QPixmap save(_canvas->wbuffer());
+ token[i] = wkdir + "/" + buf +".png";
+ _canvas->exportPNG(QFileInfo(token[i]), save);
+ } else if (token[i] == "%newpdf") {
+ token[i] = wkdir + "/" + buf +".pdf";
+ _canvas->exportPDF(QFileInfo(token[i]));
+ }
+ }
+
+ QFileInfo exefile(token[0]);
+ if (exefile.extension() == "desktop") {
+ const AppLnk *app= new AppLnk(exefile.absFilePath());
+ QStringList args;
+ for (uint i = 1; i < token.count(); ++i) {
+ args << token[i];
+ }
+ app->execute(args);
+ delete app;
+ showMinimized();
+ } else if (token[0] == "qcop") {
+ if (3 <= token.count()) {
+ QCopEnvelope qcop((const char*)token[1], (const char*)token[2]);
+ for (uint i = 3; i < token.count(); ++i) {
+ qcop << token[i];
+ }
+ }
+ } else {
+ QString args = token[0];
+ for (uint i = 1; i < token.count(); ++i) {
+ args += " ";
+ args += token[i];
+ }
+ //Global::invoke(args);
+ Global::execute(args);
+ }
+}
+
+//オプションの設定
+void FrmMain::setOptions(const FNOptionData& o)
+{
+ _tool_menu->changeItem(_id_tool1, "1:" + o.toolNames[0]);
+ _tool_menu->changeItem(_id_tool2, "2:" + o.toolNames[1]);
+ _tool_menu->changeItem(_id_tool3, "3:" + o.toolNames[2]);
+ _tool_menu->changeItem(_id_tool4, "4:" + o.toolNames[3]);
+ _tool_menu->changeItem(_id_tool5, "5:" + o.toolNames[4]);
+ _tool_menu->changeItem(_id_tool6, "6:" + o.toolNames[5]);
+ _tool_menu->changeItem(_id_tool7, "7:" + o.toolNames[6]);
+ _tool_menu->changeItem(_id_tool8, "8:" + o.toolNames[7]);
+
+ _canvas->setScrollTiming(o.timing);
+ _canvas->setVStep(o.v_step);
+ _canvas->setHStep(o.h_step);
+ _canvas->setSEraser(o.eraser_s);
+ _canvas->setLEraser(o.eraser_l);
+ _canvas->setMargin(o.margin);
+
+ _vscb->setPageStep(o.v_step);
+ _vscb->setLineStep(o.grid_size * 2);
+ _hscb->setPageStep(o.h_step);
+ _hscb->setLineStep(o.grid_size * 2);
+
+ SNAP_SIZE = o.grid_size;
+ PHASE1_ANGLE = o.phase1;
+ PHASE2_ANGLE = o.phase2;
+
+ if (o.isLMvAOn) {
+ _btnLMvA->show();
+ } else {
+ _btnLMvA->hide();
+ }
+ if (o.isLMvBOn) {
+ _btnLMvB->show();
+ } else {
+ _btnLMvB->hide();
+ }
+ if (o.isLAddOn) {
+ _btnLAdd->show();
+ } else {
+ _btnLAdd->hide();
+ }
+ if (o.isFindOn) {
+ _btnFind->show();
+ } else {
+ _btnFind->hide();
+ }
+
+ if (o.isMaximizedOn) {
+ _btnMaximized->show();
+ } else {
+ _btnMaximized->hide();
+ }
+
+ if (o.isCopyOn) {
+ _btnCopy->show();
+ } else {
+ _btnCopy->hide();
+ }
+
+ if (o.isPasteOn) {
+ _btnPaste->show();
+ } else {
+ _btnPaste->hide();
+ }
+
+ if (o.isImportOn) {
+ _btnImport->show();
+ } else {
+ _btnImport->hide();
+ }
+
+ if (o.isUndoOn) {
+ _btnUndo->show();
+ } else {
+ _btnUndo->hide();
+ }
+
+ if (o.isRedoOn) {
+ _btnRedo->show();
+ } else {
+ _btnRedo->hide();
+ }
+
+ if (o.isZoomOn) {
+ _btnZoom->show();
+ } else {
+ _btnZoom->hide();
+ }
+
+ if (o.isCROn) {
+ _btnRet->show();
+ } else {
+ _btnRet->hide();
+ }
+
+ if (o.isGuideOn) {
+ _btnGuide->show();
+ } else {
+ _btnGuide->hide();
+ }
+
+ if (o.isNewOn) {
+ _btnNew->show();
+ } else {
+ _btnNew->hide();
+ }
+
+ if (o.isClearOn) {
+ _btnClear->show();
+ } else {
+ _btnClear->hide();
+ }
+
+ if (o.isOpenOn) {
+ _btnLoad->show();
+ } else {
+ _btnLoad->hide();
+ }
+
+ if (o.isSaveOn) {
+ _btnSave->show();
+ } else {
+ _btnSave->hide();
+ }
+
+ if (o.isExportOn) {
+ _btnExportPDF->show();
+ } else {
+ _btnExportPDF->hide();
+ }
+
+ if (o.isExportPNGOn) {
+ _btnExportPNG->show();
+ } else {
+ _btnExportPNG->hide();
+ }
+
+ if (o.isLayerOn) {
+ _btnLayer->show();
+ } else {
+ _btnLayer->hide();
+ }
+
+ if (AS_HORIZONTAL == o.scrollMode) {
+ _as_horz->setOn(true);
+ } else if (AS_VERTICAL == o.scrollMode) {
+ _as_vert->setOn(true);
+ } else if (AS_BOTH == o.scrollMode) {
+ _as_both->setOn(true);
+ }
+ _btnGuide->setOn(o.isAutoScrollEnabled);
+ this->showGuide(o.isAutoScrollEnabled);
+ _canvas->setShowRuler(_showRuler = o.isShowRuler);
+ _canvas->setUseAllQuadrant(_useAllQuadrant = o.useAllQuadrant);
+ _scroll_menu->setItemChecked(_id_quadrant, _useAllQuadrant);
+ if (_useAllQuadrant) {
+ _vscb->setMinValue(-200);
+ _hscb->setMinValue(-200);
+ } else {
+ _vscb->setMinValue(0);
+ _hscb->setMinValue(0);
+ }
+ _scroll_menu->setItemChecked(_id_ruler, _showRuler);
+ _canvas->setEncode(o.encode);
+ _canvas->setFontName(o.fontname);
+ _canvas->setColorRevision(o.isColorRevision);
+ _canvas->setTxtBoxRect(o.txtBoxRect);
+ SelectionLineColor = o.selectionLineColor;
+ SelectionBrushColor = o.selectionBrushColor;
+ SelectionFrameColor = o.selectionFrameColor;
+ RulerColor = o.rulerColor;
+ GuideColor = o.guideColor;
+ GridColor = o.gridColor;
+
+ _canvas->redraw();
+}
+
+//罫線を表示する(トグル)
+void FrmMain::showRuler()
+{
+ _showRuler = !_showRuler;
+ _canvas->setShowRuler(_showRuler);
+ _options.isShowRuler = _showRuler;
+ _scroll_menu->setItemChecked(_id_ruler, _showRuler);
+ _options.save();
+}
+
+//全象限を使用する(トグル)
+void FrmMain::useAllQuadrant()
+{
+ _useAllQuadrant = !_useAllQuadrant;
+ if (_useAllQuadrant) {
+ _vscb->setMinValue(-200);
+ _hscb->setMinValue(-200);
+ } else {
+ _vscb->setMinValue(0);
+ _hscb->setMinValue(0);
+ }
+ _canvas->setUseAllQuadrant(_useAllQuadrant);
+ _scroll_menu->setItemChecked(_id_quadrant, _useAllQuadrant);
+ _options.useAllQuadrant = _useAllQuadrant;
+ _options.save();
+}
+
+//ファイルを渡してオープン
+void FrmMain::setDocument(const QString& fname)
+{
+ this->open(fname);
+}
+
+void FrmMain::showFullScreen()
+{
+ showNormal();
+ _isFullscreen = true;
+ QMainWindow::showFullScreen();
+}
+
+void FrmMain::changeColor(QRgb c)
+{
+ _btnColor->setBGColor(c);
+ _canvas->changeColor(c);
+}
+
+//ビューモードの切り替え
+void FrmMain::setViewMode(bool flg)
+{
+ if (MODE_ERASE == _drawMode) {
+ if (flg) {
+ _btnCopy->setEnabled(false);
+ _btnPaste->setEnabled(false);
+ _btnUndo->setEnabled(false);
+ _btnRedo->setEnabled(false);
+ } else {
+ _btnCopy->setEnabled(true);
+ _btnPaste->setEnabled(true);
+ _btnUndo->setEnabled(true);
+ }
+ } else {
+ _btnCopy->setEnabled(false);
+ _btnPaste->setEnabled(true);
+ _btnUndo->setEnabled(true);
+ _btnRedo->setEnabled(true);
+ }
+ _canvas->viewChanged(flg);
+ _vscb->setEnabled(!flg);
+ _hscb->setEnabled(!flg);
+}
+
+//初期設定
+void FrmMain::init()
+{
+ _colorSelector = new FNColorDialog(this);
+ QGrid* grid = new QGrid(2, this);
+ _canvas = new FNCanvas(_colorSelector, grid);
+ _canvas->resize(240, 320);
+ _vscb = new QScrollBar(0, 960, 10, 100, 0, Qt::Vertical, grid);
+ _hscb = new QScrollBar(0, 960, 10, 100, 0, Qt::Horizontal, grid);
+ this->setCentralWidget(grid);
+ this->setToolBarsMovable(false);
+ connect(_vscb, SIGNAL(valueChanged(int)), this, SLOT(scroll()));
+ connect(_hscb, SIGNAL(valueChanged(int)), this, SLOT(scroll()));
+ connect(_canvas, SIGNAL(originChanged(int, int)), this, SLOT( scrollbarChange(int, int)));
+ //メニューの構築
+ bool isVGA = false;
+ if (320 < QApplication::desktop()->width()) {
+ isVGA = true;
+ }
+
+ _page_tool = new QPEToolBar(this);
+ _page_tool->setHorizontalStretchable(true);
+
+ _btnColor = new FNColorPalette(black, _page_tool);
+ _chkFill = new QCheckBox(_page_tool);
+ _chkFill->setText("F");
+ _chkFill->setFocusPolicy(NoFocus);
+ _page_tool->addSeparator();
+ if (isVGA) {
+ _btnColor->setMinimumSize(48, 32);
+ _btnColor->setMaximumSize(48, 32);
+ } else {
+ _btnColor->setMinimumSize(24, 18);
+ _btnColor->setMaximumSize(24, 18);
+ }
+ _btnLMvA = newToolButton(_page_tool, (const char**)movetoabove_xpm, "move to above layer", isVGA);
+ _btnLMvB = newToolButton(_page_tool, (const char**)movetobelow_xpm, "move to below layer", isVGA);
+ _btnLAdd = newToolButton(_page_tool, (const char**)addlayer_xpm, "add new layer", isVGA);
+ _btnFind = newToolButton(_page_tool, (const char**)find_xpm, "find", isVGA);
+ _btnMaximized = newToolButton(_page_tool, (const char **)maximized_xpm, "maximized", isVGA);
+ _btnCopy = newToolButton(_page_tool, (const char**)copy_xpm, "copy", isVGA);
+ _btnPaste = newToolButton(_page_tool, (const char**)paste_xpm, "paste", isVGA);
+ _btnImport = newToolButton(_page_tool, (const char**)import_xpm, "import", isVGA);
+ _btnUndo = newToolButton(_page_tool, (const char**)undo_xpm, "undo", isVGA);
+ _btnRedo = newToolButton(_page_tool, (const char**)redo_xpm, "redo", isVGA);
+ //_btnColor = newToolButton(_page_tool, (const char **)color_xpm, "select color", isVGA);
+
+ _btnZoom = newToolButton(_page_tool, (const char **)zoom_xpm, "zoom", isVGA, true, false, 48);
+ _btnRet = newToolButton(_page_tool, (const char**)ret_xpm, "return", isVGA);
+ _btnGuide = newToolButton(_page_tool, (const char **)guide_xpm, "scroll guide", isVGA, true);
+ _btnNew = newToolButton(_page_tool, (const char **)new_xpm, "new page", isVGA);
+ _btnClear = newToolButton(_page_tool, (const char **)clear_xpm, "clear page", isVGA);
+ _btnLoad = newToolButton(_page_tool, (const char **)open_xpm, "load page", isVGA);
+ _btnSave = newToolButton(_page_tool, (const char **)save_xpm, "save page", isVGA);
+ _btnExportPDF = newToolButton(_page_tool, (const char **)pdf_xpm, "export PDF", isVGA);
+ _btnExportPNG = newToolButton(_page_tool, (const char **)png_xpm, "export PNG", isVGA);
+ _btnLayer = newToolButton(_page_tool, (const char**)layer_xpm, "layer on", isVGA);
+
+ connect(_btnLMvA, SIGNAL(clicked()), this, SLOT(moveAboveLayer()));
+ connect(_btnLMvB, SIGNAL(clicked()), this, SLOT(moveBelowLayer()));
+ connect(_btnLAdd, SIGNAL(clicked()), this, SLOT(addLayer()));
+ connect(_btnFind, SIGNAL(clicked()), _canvas, SLOT(find()));
+ connect(_btnColor, SIGNAL(clicked(FNPaletteBase*)), this, SLOT(colorSelectorPopup()));
+
+ connect(_btnRet, SIGNAL(clicked()), this, SLOT(hitRet()));
+ connect(_btnSave, SIGNAL(clicked()), this, SLOT(save()));
+ connect(_btnLoad, SIGNAL(clicked()), this, SLOT(load()));
+ connect(_btnNew, SIGNAL(clicked()), this, SLOT(newPage()));
+ connect(_btnClear, SIGNAL(clicked()), this, SLOT(clear()));
+ connect(_btnExportPDF, SIGNAL(clicked()), this, SLOT(exportPDF()));
+ connect(_btnExportPNG, SIGNAL(clicked()), this, SLOT(exportPNG()));
+ connect(_btnLayer, SIGNAL(clicked()), this, SLOT(showLayer()));
+
+ connect(_btnMaximized, SIGNAL(clicked()), this, SLOT(showFullScreen()));
+ connect(_btnZoom, SIGNAL(toggled(bool)), this, SLOT(setViewMode(bool)));
+ connect(_btnCopy, SIGNAL(clicked()), _canvas, SLOT(copy()));
+ connect(_btnPaste, SIGNAL(clicked()), _canvas, SLOT(paste()));
+ connect(_btnImport, SIGNAL(clicked()), this, SLOT(import()));
+ connect(_btnUndo, SIGNAL(clicked()), this, SLOT(undo()));
+ connect(_btnRedo, SIGNAL(clicked()), _canvas, SLOT(redo()));
+ connect(_btnGuide, SIGNAL(toggled(bool)), this, SLOT(showGuide(bool)));
+ connect(_canvas, SIGNAL(resetViewMode()), _btnZoom, SLOT(toggle()));
+ connect(_chkFill, SIGNAL(toggled(bool)), _canvas, SLOT(fillChanged(bool)));
+ connect(_canvas, SIGNAL(pickColor(QRgb)), this, SLOT(changeColor(QRgb)));
+
+ _scroll_menu = new QPopupMenu();
+ QActionGroup* scroll_action_group = new QActionGroup(_scroll_menu, "scroll actions", true);
+ scroll_action_group->insert(_as_horz = new QAction("horz", "&Horizontal", 0, scroll_action_group, 0, true));
+ scroll_action_group->insert(_as_vert = new QAction("vert", "&Vertical", 0, scroll_action_group, 0, true));
+ scroll_action_group->insert(_as_both = new QAction("both", "&Both", 0, scroll_action_group, 0, true));
+ _as_both->setOn(true);
+ _id_guide = _scroll_menu->insertItem("&Guide", _btnGuide, SLOT(toggle()), CTRL + Key_G);
+ _id_ruler = _scroll_menu->insertItem("show &Ruler", this, SLOT(showRuler()), CTRL + Key_K);
+ _id_quadrant = _scroll_menu->insertItem("&Use all quadrant", this, SLOT(useAllQuadrant()), CTRL + Key_U);
+ _scroll_menu->insertSeparator();
+ scroll_action_group->addTo(_scroll_menu);
+ connect(scroll_action_group, SIGNAL(selected(QAction*)), this, SLOT(scroll_menu_selected(QAction*)));
+
+ _main_menu = new QPopupMenu();
+ _main_menu->setCheckable(true);
+
+ _edit_menu = new QPopupMenu();
+ _edit_menu->insertItem("&Copy", _canvas, SLOT(copy()), CTRL + Key_C);
+ _edit_menu->insertItem("&Paste", _canvas, SLOT(paste()), CTRL + Key_V);
+ _edit_menu->insertItem("&Undo", this, SLOT(undo()), CTRL + Key_Z);
+ _edit_menu->insertItem("&Redo", _canvas, SLOT(redo()), CTRL + Key_Y);
+ _edit_menu->insertItem("&Find", _canvas, SLOT(find()), CTRL + Key_F);
+
+ _main_menu->insertItem("&Edit", _edit_menu);
+
+ _layer_menu = new QPopupMenu();
+ _layer_menu->insertItem("show", this, SLOT(showLayer()), CTRL + Key_B);
+ _layer_menu->insertItem("move above", this, SLOT(moveAboveLayer()), Key_A);
+ _layer_menu->insertItem("move below", this, SLOT(moveBelowLayer()), Key_Z);
+ _layer_menu->insertItem("add layer", this, SLOT(addLayer()), CTRL + Key_A);
+ _id_tinyPaging = _layer_menu->insertItem("tiny paging mode", this, SLOT(toggleTinyPaging()), CTRL + Key_T);
+ _main_menu->insertItem("&Layer", _layer_menu);
+
+
+ _tool_menu = new QPopupMenu();
+ _id_tool1 = _tool_menu->insertItem("1:", this, SLOT(tool1()), CTRL + Key_1);
+ _id_tool2 = _tool_menu->insertItem("2:", this, SLOT(tool2()), CTRL + Key_2);
+ _id_tool3 = _tool_menu->insertItem("3:", this, SLOT(tool3()), CTRL + Key_3);
+ _id_tool4 = _tool_menu->insertItem("4:", this, SLOT(tool4()), CTRL + Key_4);
+ _id_tool5 = _tool_menu->insertItem("5:", this, SLOT(tool5()), CTRL + Key_5);
+ _id_tool6 = _tool_menu->insertItem("6:", this, SLOT(tool6()), CTRL + Key_6);
+ _id_tool7 = _tool_menu->insertItem("7:", this, SLOT(tool7()), CTRL + Key_7);
+ _id_tool8 = _tool_menu->insertItem("8:", this, SLOT(tool8()), CTRL + Key_8);
+ _main_menu->insertItem("&Tool", _tool_menu);
+
+ _main_menu->insertItem("&Zoom", _btnZoom, SLOT(toggle()), Key_Tab);
+ _main_menu->insertItem("&Maximize", this, SLOT(showFullScreen()), CTRL + Key_M);
+ _main_menu->insertItem("&Normalize", this, SLOT(showNormal()), CTRL + Key_R);
+ _main_menu->insertSeparator();
+
+ _main_menu->insertItem("&Scroll", _scroll_menu);
+ _main_menu->insertSeparator();
+
+ _file_menu = new QPopupMenu();
+ _file_menu->setCheckable(true);
+ _file_menu->insertItem("&New", this, SLOT(newPage()), CTRL + Key_N);
+ _file_menu->insertItem("&Clear", this, SLOT(clear()), CTRL + Key_L);
+ _file_menu->insertItem("&Import", this, SLOT(import()), CTRL + Key_I);
+ _file_menu->insertItem("&Load", this, SLOT(load()), CTRL + Key_O);
+ _file_menu->insertItem("&Save", this, SLOT(save()), CTRL + Key_S);
+ _file_menu->insertItem("save &As", this, SLOT(saveAs()));
+ _main_menu->insertItem("&File", _file_menu);
+
+ _export_menu = new QPopupMenu();
+ _export_menu->setCheckable(true);
+ _export_menu->insertItem("PDF", this, SLOT(exportPDF()), CTRL + Key_P);
+ _export_menu->insertItem("PNG", this, SLOT(exportPNG()), CTRL + Key_E);
+ _export_menu->insertSeparator();
+ _id_saveNPdf = _export_menu->insertItem("save with pdf", this, SLOT(toggleSaveNPdf()));
+
+ _main_menu->insertItem("&Export", _export_menu);
+ _main_menu->insertSeparator();
+ _main_menu->insertItem("&Quit", this, SLOT(quit()), Key_Escape);
+ _main_menu->insertSeparator();
+ _main_menu->insertItem("&About", this, SLOT(about()));
+
+ _menubar = new QPEMenuBar(this);
+ _menubar->insertItem("&Menu", _main_menu);
+
+ _draw_menu = new QPopupMenu();
+ int id_draw;
+ id_draw = _draw_menu->insertItem(QIconSet(QPixmap((const char**)draw_xpm)), "&Draw");
+ _draw_menu->setAccel(Key_D, id_draw);
+ id_draw = _draw_menu->insertItem(QIconSet(QPixmap((const char**)format_xpm)), "Auto&Format");
+ _draw_menu->setAccel(Key_F, id_draw);
+ id_draw = _draw_menu->insertItem(QIconSet(QPixmap((const char**)curve_xpm)), "Auto&Curve");
+ _draw_menu->setAccel(Key_C, id_draw);
+ id_draw = _draw_menu->insertItem(QIconSet(QPixmap((const char**)smooth_xpm)), "&Smooth");
+ _draw_menu->setAccel(Key_S, id_draw);
+ id_draw = _draw_menu->insertItem(QIconSet(QPixmap((const char**)text_xpm)), "&Text");
+ _draw_menu->setAccel(Key_T, id_draw);
+ id_draw = _draw_menu->insertItem(QIconSet(QPixmap((const char**)eraser_xpm)), "&Eraser");
+ _draw_menu->setAccel(Key_E, id_draw);
+ id_draw = _draw_menu->insertItem(QIconSet(QPixmap((const char**)cpick_xpm)), "Color&Picker");
+ _draw_menu->setAccel(Key_P, id_draw);
+ _id_mode = _menubar->insertItem(QPixmap((const char**)draw_xpm), _draw_menu);
+ connect(_draw_menu, SIGNAL(activated(int)), this, SLOT(modeMenuChanged(int)));
+ connect(_canvas, SIGNAL(changeMode(int)), this, SLOT(modeChanged(int)));
+
+ _pen_menu = new QPopupMenu();
+ for (int i = 0; i < 8; ++i) {
+ char buf[5];
+ sprintf(buf, "%dpts.", (i + 1));
+ int id = _pen_menu->insertItem(QIconSet(makePenPixmap(i + 1)), buf);
+ _pen_menu->setAccel(Key_1 + i, id);
+ }
+ _id_pen = _menubar->insertItem(makePenPixmap(1), _pen_menu);
+ connect(_pen_menu, SIGNAL(activated(int)), this, SLOT(penSelected(int)));
+ _menubar->insertItem(_page_tool);
+ _btnCopy->setEnabled(false);
+ _btnPaste->setEnabled(true);
+ _title = "";
+}
+
+void FrmMain::undo()
+{
+ _canvas->undo();
+ setTitle();
+}
+
+void FrmMain::addLayer()
+{
+ _canvas->addLayer();
+ setTitle();
+}
+
+void FrmMain::moveAboveLayer()
+{
+ _canvas->moveAboveLayer();
+ setTitle();
+}
+
+void FrmMain::moveBelowLayer()
+{
+ _canvas->moveBelowLayer();
+ setTitle();
+}
+
+//簡易ページモードを切り替える
+void FrmMain::toggleTinyPaging()
+{
+ bool f = _canvas->isTinyPaging();
+ _canvas->setTinyPaging(!f);
+ setTitle();
+}
+
+
+//ペン画像の作成
+QPixmap FrmMain::makePenPixmap(int n)
+{
+ const char** icons[] = {
+ (const char**)pt1_xpm,
+ (const char**)pt2_xpm,
+ (const char**)pt3_xpm,
+ (const char**)pt4_xpm,
+ (const char**)pt5_xpm,
+ (const char**)pt6_xpm,
+ (const char**)pt7_xpm,
+ (const char**)pt8_xpm,
+ };
+ QPixmap pt(icons[n - 1]);
+ QImage mask = pt.mask()->convertToImage();
+ pt = pt.convertToImage().smoothScale(32/*48*/, 16);
+ QBitmap msk;
+ msk = mask.smoothScale(32/*48*/, 16);
+ pt.setMask(msk);
+ return pt;
+}
+
+//ペンの選択
+void FrmMain::penSelected(int id)
+{
+ int idx = _pen_menu->indexOf(id);
+ if (-1 != idx) {
+ _menubar->changeItem(_id_pen, makePenPixmap(idx + 1));
+ _canvas->setPensize(idx + 1);
+ }
+}
+
+//Save with PDFの切り替え
+void FrmMain::toggleSaveNPdf()
+{
+ if (_export_menu->isItemChecked(_id_saveNPdf)) {
+ _export_menu->setItemChecked(_id_saveNPdf, false);
+ } else {
+ _export_menu->setItemChecked(_id_saveNPdf, true);
+ }
+}
+
+//ツールボタンの作成
+QToolButton* FrmMain::newToolButton(QWidget* parent, const char** icon1, const char** icon2, const QString& textLabel, const bool isVGA, const bool isToggle, const bool isOn, const int width)
+{
+ QToolButton* btn = new QToolButton(parent);
+ if (isVGA) {
+ btn->setMinimumSize(width, 32);
+ btn->setMaximumSize(width, 32);
+ } else {
+ btn->setMinimumSize(18, 18);
+ btn->setMaximumSize(18, 18);
+ }
+ btn->setOnIconSet(QIconSet(QPixmap(icon1)));
+ btn->setOffIconSet(QIconSet(QPixmap(icon2)));
+ btn->setToggleButton(isToggle);
+ btn->setOn(isOn);
+ btn->setTextLabel(textLabel);
+ btn->setAutoRaise(false);
+
+ return btn;
+}
+
+//ツールボタンの作成
+QToolButton* FrmMain::newToolButton(QWidget* parent, const char** icon, const QString& textLabel, const bool isVGA, const bool isToggle, const bool isOn, const int width)
+{
+ QToolButton* btn = new QToolButton(parent);
+ if (isVGA) {
+ btn->setMinimumSize(width, 32);
+ btn->setMaximumSize(width, 32);
+ } else {
+ btn->setMinimumSize(20, 20);
+ btn->setMaximumSize(20, 20);
+ }
+ btn->setPixmap(QPixmap(icon));
+ btn->setToggleButton(isToggle);
+ btn->setOn(isOn);
+ btn->setTextLabel(textLabel);
+ btn->setAutoRaise(false);
+
+ return btn;
+}
+
+//スクロールメニューの選択
+void FrmMain::scroll_menu_selected(QAction* act)
+{
+ if (act->text() == "horz") {
+ _options.scrollMode = _scrollMode = AS_HORIZONTAL;
+ } else if (act->text() == "vert") {
+ _options.scrollMode = _scrollMode = AS_VERTICAL;
+ } else if (act->text() == "both") {
+ _options.scrollMode = _scrollMode = AS_BOTH;
+ }
+ _options.save();
+ if (_btnGuide->isOn()) {
+ _canvas->setScrollMode(_scrollMode);
+ }
+}
+
+//ガイドの表示
+void FrmMain::showGuide(bool flg)
+{
+ _canvas->setGuide(flg);
+ if (flg) {
+ _canvas->setScrollMode(_scrollMode);
+ } else {
+ _canvas->setScrollMode(AS_NONE);
+ }
+ _main_menu->setItemChecked(_id_guide, flg);
+ if (flg != _options.isAutoScrollEnabled) {
+ _options.isAutoScrollEnabled = flg;
+ _options.save();
+ }
+}
+
+//スクロールバーの設定
+void FrmMain::scrollbarChange(int x, int y)
+{
+ //*
+ if (_useAllQuadrant) {
+ if (-200 != _vscb->minValue()) {
+ _vscb->setMinValue(-200);
+ }
+ if (-200 != _hscb->minValue()) {
+ _hscb->setMinValue(-200);
+ }
+ } else {
+ if (0 != _vscb->minValue()) {
+ _vscb->setMinValue(0);
+ }
+ if (0 != _hscb->minValue()) {
+ _hscb->setMinValue(0);
+ }
+ }
+ //*/
+ if (_canvas->isShowGuide()) {
+ _isTracking = false;
+ } else {
+ _isTracking = false;
+ }
+ _hscb->setValue(x);
+ _vscb->setValue(y);
+}
+
+//新規ページ作成
+void FrmMain::newPage()
+{
+ if (QMessageBox::warning( this, "FreeNote Qt", "OK to create new page ?", "OK", "Cancel", 0, 1, 1 )) {
+ return;
+ }
+ _hscb->setMaxValue(960);
+ _vscb->setMaxValue(960);
+ _canvas->clear();
+ QDir dir = _file.dir();
+ _file.setFile(dir, "");
+ _title = "";
+ setTitle();
+}
+
+//ページクリア
+void FrmMain::clear()
+{
+ if (QMessageBox::warning( this, "FreeNote Qt", "OK to clear this page ?", "OK", "Cancel", 0, 1, 1 )) {
+ return;
+ }
+ _hscb->setMaxValue(960);
+ _vscb->setMaxValue(960);
+ _canvas->clear();
+}
+
+//カラーセレクタの表示
+void FrmMain::colorSelectorPopup()
+{
+ _colorSelector->setColor(_btnColor->color());
+ _colorSelector->show();
+ if (_colorSelector->exec()) {
+ changeColor(_colorSelector->color().rgb());
+ }
+}
+
+//ファイルオープン
+void FrmMain::open(const QString& fname)
+{
+ _file.setFile(fname);
+ if (_file.exists()) {
+ _canvas->load(_file.absFilePath());
+ setTitle(&_file);
+ } else {
+ _file.setFile(_file.dir(), "");
+ }
+}
+
+//ファイル保存
+void FrmMain::save()
+{
+ _prefile = "";
+ if (!_file.exists() || _file.isDir() || _file.extension(false) != "free") {
+ return saveAs();
+ } else {
+ Config conf("FreeNoteQt");
+ conf.setGroup("Format");
+ _file.setFile(QDir(conf.readEntry("free", _file.dirPath())), _file.fileName());
+ _canvas->save(_file.absFilePath());
+ _prefile = _file.absFilePath();
+ conf.writeEntry("free", _file.dirPath() + "/");
+ setTitle(&_file);
+ if (_export_menu->isItemChecked(_id_saveNPdf)) {
+ QFileInfo info = _file;
+ QString tmpf = _file.absFilePath();
+ tmpf = tmpf.left(tmpf.findRev(".free"));
+ info.setFile(tmpf + ".pdf");
+ _canvas->exportPDF(info);
+ }
+ }
+}
+
+//別名保存
+void FrmMain::saveAs()
+{
+ _prefile = "";
+ Config conf("FreeNoteQt");
+ conf.setGroup("Format");
+ if (_file.baseName() == "") {
+ _file.setFile(QDir(conf.readEntry("free", _file.dirPath())), "");
+ } else {
+ _file.setFile(QDir(conf.readEntry("free", _file.dirPath())), _file.fileName());
+ }
+
+ //_frmPalette->close();
+ FNFileDialog dlg(this, "*.free", "FreeNote Qt - save", false);
+ dlg.setCurrentFile(_file);
+ dlg.showMaximized();
+ if (dlg.exec()) {
+ QFileInfo info = dlg.currentFile();
+ if (!info.isDir() && !dlg.isTopDir()) {
+ if (info.extension(false) != "free") {
+ QDir dir = info.dir(true);
+ QString fname = info.fileName();
+ info.setFile(dir, fname + ".free");
+ }
+ if (info.exists()) {
+ if (QMessageBox::warning( this, "FreeNote Qt", "file " + info.fileName() + "\n already exists.\n\n OK to overwrite ?", "OK", "Cancel", 0, 1, 1 )) {
+ return;
+ }
+ }
+ _file = info;
+ if (_canvas->save(_file)) {
+ _prefile = _file.absFilePath();
+ conf.writeEntry("free", _file.dirPath() + "/");
+ setTitle(&_file);
+ if (_export_menu->isItemChecked(_id_saveNPdf)) {
+ QString tmpf = _file.absFilePath();
+ tmpf = tmpf.left(tmpf.findRev(".free"));
+ info.setFile(tmpf + ".pdf");
+ _canvas->exportPDF(info);
+ }
+ }
+ }
+ }
+}
+
+//ファイル読み込み
+void FrmMain::load()
+{
+ Config conf("FreeNoteQt");
+ conf.setGroup("Format");
+ if (_file.fileName() == "") {
+ _file.setFile(QDir(conf.readEntry("free", _file.dirPath())), ".free");
+ } else {
+ _file.setFile(QDir(conf.readEntry("free", _file.dirPath())), _file.fileName());
+ }
+
+ //_frmPalette->close();
+ FNFileDialog dlg(this, "*.free", "FreeNote Qt - load", true);
+ dlg.setCurrentFile(_file);
+ dlg.showMaximized();
+ if (dlg.exec()) {
+ QFileInfo info = dlg.currentFile();
+ if (info.isFile() && info.exists()) {
+ _file = info;
+ if (_canvas->load(_file)) {
+ _prefile = _file.absFilePath();
+ conf.writeEntry("free", _file.dirPath() + "/");
+ setTitle(&_file);
+ }
+ }
+ }
+}
+
+//クリップボード読み込み
+void FrmMain::import()
+{
+ Config conf("FreeNoteQt");
+ conf.setGroup("Format");
+ QFileInfo info = _file;
+ if (info.fileName() == "") {
+ info.setFile(QDir(conf.readEntry("import", info.dirPath())), ".free");
+ } else {
+ info.setFile(QDir(conf.readEntry("import", info.dirPath())), info.fileName());
+ }
+
+ //_frmPalette->close();
+ FNFileDialog dlg(this, "*.free", "FreeNote Qt - import", true);
+ dlg.setCurrentFile(info);
+ dlg.showMaximized();
+ if (dlg.exec()) {
+ info = dlg.currentFile();
+ if (info.isFile() && info.exists()) {
+ _canvas->import(info);
+ conf.writeEntry("import", info.dirPath() + "/");
+ }
+ }
+}
+
+//PNGへの出力
+void FrmMain::exportPNG()
+{
+ _prepng = "";
+ Config conf("FreeNoteQt");
+ conf.setGroup("Format");
+ QFileInfo info = _file;
+ if (info.fileName() == "") {
+ info.setFile(QDir(conf.readEntry("png", info.dirPath())), "");
+ } else {
+ info.setFile(QDir(conf.readEntry("png", info.dirPath())), info.fileName());
+ }
+
+ //_frmPalette->close();
+ QPixmap save(_canvas->wbuffer());
+ FNFileDialog dlg(this, "*.png", "FreeNote Qt - exportPNG", false);
+ if (info.extension()=="free") {
+ QString tmpf = info.absFilePath();
+ tmpf = tmpf.left(tmpf.findRev(".free"));
+ info.setFile(tmpf);
+ } else {
+ info.setFile(info.dir(), "");
+ }
+ dlg.setCurrentFile(info);
+ dlg.showMaximized();
+ if (dlg.exec() && !dlg.isTopDir()) {
+ info = dlg.currentFile();
+ if (!info.isDir() && !dlg.isTopDir()) {
+ if (info.extension(false) != "png") {
+ QDir dir = info.dir(true);
+ QString fname = info.fileName();
+ info.setFile(dir, fname + ".png");
+ }
+ if (info.exists()) {
+ if (QMessageBox::warning( this, "FreeNote Qt", "file " + info.fileName() + "\n already exists.\n\n OK to overwrite ?", "OK", "Cancel", 0, 1, 1 )) {
+ return;
+ }
+ }
+ _canvas->exportPNG(info, save);
+ _prepng = info.absFilePath();
+ conf.writeEntry("png", info.dirPath() + "/");
+ }
+ }
+}
+
+//PDFへの出力
+void FrmMain::exportPDF()
+{
+ _prepdf = "";
+ Config conf("FreeNoteQt");
+ conf.setGroup("Format");
+
+ QFileInfo info = _file;
+ if (info.fileName() == "") {
+ info.setFile(QDir(conf.readEntry("pdf", info.dirPath())), "");
+ } else {
+ info.setFile(QDir(conf.readEntry("pdf", info.dirPath())), info.fileName());
+ }
+
+ //_frmPalette->close();
+ FNFileDialog dlg(this, "*.pdf", "FreeNote Qt - exportPDF", false);
+ if (info.extension()=="free") {
+ QString tmpf = info.absFilePath();
+ tmpf = tmpf.left(tmpf.findRev(".free"));
+ info.setFile(tmpf);
+ } else {
+ info.setFile(info.dir(), "");
+ }
+
+ dlg.setCurrentFile(info);
+ dlg.showMaximized();
+
+ if (dlg.exec() && !dlg.isTopDir()) {
+ info = dlg.currentFile();
+ if (!info.isDir() && !dlg.isTopDir()) {
+ if (info.extension(false) != "pdf") {
+ QDir dir = info.dir(true);
+ QString fname = info.fileName();
+ info.setFile(dir, fname + ".pdf");
+ }
+ if (info.exists()) {
+ if (QMessageBox::warning( this, "FreeNote Qt", "file " + info.fileName() + "\n already exists.\n\n OK to overwrite ?", "OK", "Cancel", 0, 1, 1 )) {
+ return;
+ }
+ }
+ _canvas->exportPDF(info);
+ _prepdf = info.absFilePath();
+ conf.writeEntry("pdf", info.dirPath() + "/");
+ }
+ }
+}
+
+//スクロール
+void FrmMain::scroll()
+{
+ if (!_isTracking) {
+ _isTracking = true;
+ return;
+ }
+ if (_canvas->isDrawing()) {
+ return;
+ }
+ int ox = _hscb->value();
+ int oy = _vscb->value();
+ _canvas->setOrigin(ox, oy);
+ int mx = _hscb->maxValue();
+ int my = _vscb->maxValue();
+ if (ox + 50 > mx) {
+ _hscb->setMaxValue(mx + 100);
+ }
+ if (oy + 50 > my) {
+ _vscb->setMaxValue(my + 100);
+ }
+ this->setFocus();
+}
+
+//終了
+void FrmMain::quit()
+{
+ _options.txtBoxRect = _canvas->txtBoxRect();
+ _options.save();
+ showNormal();
+ close();
+}
+
+//終了前処理
+void FrmMain::closeEvent(QCloseEvent* e)
+{
+ if (!_options.isQuitQuickly) {
+ if (QMessageBox::warning( this, "FreeNote Qt", "OK to quit ?", "OK", "Cancel", 0, 1, 1 )) {
+ return;
+ }
+ }
+ e->accept();
+}
+
+//リターン押下処理
+void FrmMain::hitRet()
+{
+ _canvas->erase();
+ _canvas->CR();
+}
+
+//キー押下イベント
+void FrmMain::keyPressEvent(QKeyEvent* evt)
+{
+ if (!_btnZoom->isOn()) {
+ int key = evt->key();
+ switch (key) {
+ case Qt::Key_Return:
+ case Qt::Key_Space:
+ case Qt::Key_F33:
+ _canvas->erase();
+ _canvas->CR();
+ break;
+ case Qt::Key_Left:
+ if (_canvas->isSelected()) {
+ _canvas->selectionMoveTo(-1, 0);
+ } else {
+ _hscb->subtractPage();
+ scroll();
+ }
+ break;
+ case Qt::Key_Right:
+ if (_canvas->isSelected()) {
+ _canvas->selectionMoveTo(1, 0);
+ } else {
+ _hscb->addPage();
+ scroll();
+ }
+ break;
+ case Qt::Key_Up:
+ if (_canvas->isSelected()) {
+ _canvas->selectionMoveTo(0, -1);
+ } else {
+ _vscb->subtractPage();
+ scroll();
+ }
+ break;
+ case Qt::Key_Down:
+ if (_canvas->isSelected()) {
+ _canvas->selectionMoveTo(0, 1);
+ } else {
+ _vscb->addPage();
+ scroll();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void FrmMain::showLayer()
+{
+ FNLayerDlg dlg(_canvas);
+ _canvas->resetSelection();
+ dlg.show();
+ dlg.exec();
+ setTitle();
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+FrmMain::~FrmMain()
+{
+ // no need to delete child widgets, Qt does it all for us
+ delete _colorSelector;
+}
+
+//about boxの表示
+void FrmMain::about()
+{
+ char buf[1024];
+ sprintf(buf, "FreeNote Qt\nversion %s\nCopyright(c) 2003-2005,jojo3", VERSION);
+ QMessageBox::about(this, "FreeNote Qt", buf);
+}
+
+void FrmMain::setTitle(QFileInfo* file) {
+ if (NULL != file) {
+ _title = file->fileName();
+ }
+ QString t = "FreeNote Qt[";
+ if (_canvas->isTinyPaging()) {
+ _layer_menu->setItemChecked(_id_tinyPaging, true);
+ t += "P:";
+ } else {
+ _layer_menu->setItemChecked(_id_tinyPaging, false);
+ t += "L:";
+ }
+ t += _canvas->currentLayerName();
+ t += "] ";
+ setCaption(t + _title);
+}
diff --git a/packages/freenote/files/FreeNote/apps/.mtn2git_empty b/packages/freenote/files/FreeNote/apps/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/freenote/files/FreeNote/apps/.mtn2git_empty
diff --git a/packages/freenote/files/FreeNote/apps/Applications/.mtn2git_empty b/packages/freenote/files/FreeNote/apps/Applications/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/freenote/files/FreeNote/apps/Applications/.mtn2git_empty
diff --git a/packages/freenote/files/FreeNote/apps/Applications/FreeNote.desktop b/packages/freenote/files/FreeNote/apps/Applications/FreeNote.desktop
new file mode 100644
index 0000000000..46e24cd971
--- /dev/null
+++ b/packages/freenote/files/FreeNote/apps/Applications/FreeNote.desktop
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Comment=
+Exec=FreeNote
+Icon=freenote
+Type=Application
+Name=FreeNoteQt
+Display=640x480/144dpi,480x640/144dpi
+MimeType=application/freenote
+MimeTypeIcons=freenote
+CanFastload=1
diff --git a/packages/freenote/files/FreeNote/apps/Settings/.mtn2git_empty b/packages/freenote/files/FreeNote/apps/Settings/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/freenote/files/FreeNote/apps/Settings/.mtn2git_empty
diff --git a/packages/freenote/files/FreeNote/apps/Settings/FreeNoteSetup.desktop b/packages/freenote/files/FreeNote/apps/Settings/FreeNoteSetup.desktop
new file mode 100644
index 0000000000..e621c90318
--- /dev/null
+++ b/packages/freenote/files/FreeNote/apps/Settings/FreeNoteSetup.desktop
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Comment=
+Exec=FreeNoteSetup
+Icon=fnsetup
+Type=Application
+Name=FNSetup
+Name[ja]=FN險ュ螳
+Display=640x480/144dpi,480x640/144dpi
+CanFastload=0
diff --git a/packages/freenote/files/FreeNote/pics/.mtn2git_empty b/packages/freenote/files/FreeNote/pics/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/freenote/files/FreeNote/pics/.mtn2git_empty
diff --git a/packages/freenote/files/FreeNote/pics/fnsetup.png b/packages/freenote/files/FreeNote/pics/fnsetup.png
new file mode 100644
index 0000000000..39028e3511
--- /dev/null
+++ b/packages/freenote/files/FreeNote/pics/fnsetup.png
Binary files differ
diff --git a/packages/freenote/files/FreeNote/pics/freenote.png b/packages/freenote/files/FreeNote/pics/freenote.png
new file mode 100644
index 0000000000..ebde7765a1
--- /dev/null
+++ b/packages/freenote/files/FreeNote/pics/freenote.png
Binary files differ
diff --git a/packages/freenote/freenote_1.12.0.bb b/packages/freenote/freenote_1.12.0.bb
new file mode 100644
index 0000000000..72610c306c
--- /dev/null
+++ b/packages/freenote/freenote_1.12.0.bb
@@ -0,0 +1,33 @@
+DESCRIPTION = "Auto-Correction Paint Program for Opie/Qtopia"
+SECTION = "opie/applications"
+PRIORITY = "optional"
+LICENSE = "GPL"
+APPNAME = "FreeNote"
+APPTYPE = "binary"
+APPDESKTOP = "apps/Applications"
+
+SRC_URI = "http://www.urban.ne.jp/home/kanemori/zaurus/FreeNote_1.12.0.tar.gz \
+ file://FreeNote"
+S = "${WORKDIR}/FreeNote"
+
+inherit opie
+
+do_configure_prepend() {
+ mv -f FreeNote subdir1
+ mv -f FreeNoteSetup subdir2
+ echo -e "TEMPLATE=subdirs\nSUBDIRS=subdir1 subdir2\n" >> freenote.pro
+ pushd ${S}/subdir1 && rm *.pro && qmake -project && echo "TARGET=FreeNote" >> subdir1.pro && popd
+ pushd ${S}/subdir2 && rm *.pro && qmake -project && echo "TARGET=FreeNoteSetup" >> subdir2.pro && popd
+}
+
+do_install() {
+ install -d ${D}${palmtopdir}/bin/
+ install -m 0755 FreeNoteSetup ${D}${palmtopdir}/bin/
+ install -d ${D}${palmtopdir}/pics/
+ install -m 0644 pics/freenote.png ${D}${palmtopdir}/pics
+ install -m 0644 pics/fnsetup.png ${D}${palmtopdir}/pics
+ install -d ${D}${palmtopdir}/apps/Applications
+ install -m 0644 apps/Applications/FreeNote.desktop ${D}${palmtopdir}/apps/Applications
+ install -d ${D}${palmtopdir}/apps/Settings
+ install -m 0644 apps/Settings/FreeNoteSetup.desktop ${D}${palmtopdir}/apps/Settings
+}
diff --git a/packages/gcc/gcc_4.0.2.bb b/packages/gcc/gcc_4.0.2.bb
index 7a8eba47ee..5a9d00e73b 100644
--- a/packages/gcc/gcc_4.0.2.bb
+++ b/packages/gcc/gcc_4.0.2.bb
@@ -1,9 +1,9 @@
-PR = "r1"
DESCRIPTION = "The GNU cc and gcc C compilers."
HOMEPAGE = "http://www.gnu.org/software/gcc/"
SECTION = "devel"
LICENSE = "GPL"
MAINTAINER = "Gerald Britton <gbritton@doomcom.org>"
+PR = "r2"
inherit autotools gettext
@@ -27,3 +27,9 @@ SRC_URI_append_fail-fast = " file://zecke-no-host-includes.patch;patch=1 "
include gcc4-build.inc
+
+EXTRA_OECONF += "--disable-libssp"
+
+FORTRAN = ""
+HAS_GFORTRAN = ""
+HAS_G2C = "no"
diff --git a/packages/gimp/gimp_2.3.8.bb b/packages/gimp/gimp_2.3.8.bb
new file mode 100644
index 0000000000..89d9be3e8d
--- /dev/null
+++ b/packages/gimp/gimp_2.3.8.bb
@@ -0,0 +1,19 @@
+DESCRIPTION = "The GIMP is the GNU Image Manipulation Program."
+HOMEPAGE = "http://www.gimp.org"
+LICENSE = "GPL"
+MAINTAINER = "Koen Kooi <koen@handhelds.org>"
+
+SRC_URI = "ftp://ftp.gimp.org/pub/gimp/v2.3/gimp-${PV}.tar.bz2"
+
+DEPENDS = "sed-native libart-lgpl gtk+ jpeg libpng libexif tiff"
+
+inherit autotools pkgconfig
+#Don't laugh, this just builds a threaded gimp
+EXTRA_OECONF = " --disable-gtktest \
+ --disable-print \
+ --disable-python \
+ --enable-mp"
+
+do_configure_append() {
+ find ${S} -name Makefile | xargs sed -i s:'-I$(includedir)':'-I.':g
+}
diff --git a/packages/gnutls/gnutls-1.4.0/.mtn2git_empty b/packages/gnutls/gnutls-1.4.0/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/gnutls/gnutls-1.4.0/.mtn2git_empty
diff --git a/packages/gnutls/gnutls-1.4.0/gnutls-openssl.patch b/packages/gnutls/gnutls-1.4.0/gnutls-openssl.patch
new file mode 100644
index 0000000000..6eca97efd7
--- /dev/null
+++ b/packages/gnutls/gnutls-1.4.0/gnutls-openssl.patch
@@ -0,0 +1,120 @@
+--- gnutls-1.3.5/libextra/gnutls_openssl.c.orig 2006-04-28 20:01:40.000000000 +0100
++++ gnutls-1.3.5/libextra/gnutls_openssl.c 2006-04-28 20:10:33.000000000 +0100
+@@ -252,12 +252,17 @@
+ ssl->rfd = (gnutls_transport_ptr_t) - 1;
+ ssl->wfd = (gnutls_transport_ptr_t) - 1;
+
++ ssl->ssl_peek_buffer = NULL;
++ ssl->ssl_peek_buffer_size = ssl->ssl_peek_avail = 0;
++
+ return ssl;
+ }
+
+ void
+ SSL_free (SSL * ssl)
+ {
++ if (ssl->ssl_peek_buffer)
++ free(ssl->ssl_peek_buffer);
+ gnutls_certificate_free_credentials (ssl->gnutls_cred);
+ gnutls_deinit (ssl->gnutls_state);
+ free (ssl);
+@@ -281,6 +286,7 @@
+ SSL_set_fd (SSL * ssl, int fd)
+ {
+ gnutls_transport_set_ptr (ssl->gnutls_state, (gnutls_transport_ptr_t) fd);
++ ssl->rfd = ssl->wfd = fd;
+ return 1;
+ }
+
+@@ -306,6 +312,17 @@
+ return 1;
+ }
+
++int SSL_get_rfd(SSL *ssl)
++{
++ return ssl->rfd;
++}
++
++int SSL_get_wfd(SSL *ssl)
++{
++ return ssl->wfd;
++}
++
++
+ void
+ SSL_set_bio (SSL * ssl, BIO * rbio, BIO * wbio)
+ {
+@@ -321,6 +338,8 @@
+ int
+ SSL_pending (SSL * ssl)
+ {
++ if (ssl->ssl_peek_avail)
++ return ssl->ssl_peek_avail;
+ return gnutls_record_check_pending (ssl->gnutls_state);
+ }
+
+@@ -476,11 +495,50 @@
+ return 1;
+ }
+
++int SSL_peek(SSL *ssl, void *buf, int len)
++{
++ if (len > ssl->ssl_peek_buffer_size) {
++ ssl->ssl_peek_buffer = realloc (ssl->ssl_peek_buffer, len);
++ ssl->ssl_peek_buffer_size = len;
++ }
++
++ if (ssl->ssl_peek_avail == 0) {
++
++ int ret;
++
++ ret = gnutls_record_recv(ssl->gnutls_state, ssl->ssl_peek_buffer, len);
++ ssl->last_error = ret;
++
++ if (ret > 0)
++ ssl->ssl_peek_avail += ret;
++ }
++
++ if (len > ssl->ssl_peek_avail)
++ len = ssl->ssl_peek_avail;
++
++ memcpy (buf, ssl->ssl_peek_buffer, len);
++
++ return len;
++}
++
+ int
+ SSL_read (SSL * ssl, void *buf, int len)
+ {
+ int ret;
+
++ if (ssl->ssl_peek_avail) {
++ int n = (ssl->ssl_peek_avail > len) ? len : ssl->ssl_peek_avail;
++
++ memcpy (buf, ssl->ssl_peek_buffer, n);
++
++ if (ssl->ssl_peek_avail > n)
++ memmove (ssl->ssl_peek_buffer, ssl->ssl_peek_buffer + n, ssl->ssl_peek_avail - n);
++
++ ssl->ssl_peek_avail -= n;
++
++ return n;
++ }
++
+ ret = gnutls_record_recv (ssl->gnutls_state, buf, len);
+ ssl->last_error = ret;
+
+--- gnutls-1.3.5/includes/gnutls/openssl.h.orig 2006-04-28 20:10:55.000000000 +0100
++++ gnutls-1.3.5/includes/gnutls/openssl.h 2006-04-28 20:11:52.000000000 +0100
+@@ -164,6 +164,11 @@
+
+ gnutls_transport_ptr_t rfd;
+ gnutls_transport_ptr_t wfd;
++
++ char *ssl_peek_buffer;
++ size_t ssl_peek_buffer_size;
++ size_t ssl_peek_avail;
++
+ };
+
+ #define rbio gnutls_state
diff --git a/packages/gnutls/gnutls-1.4.0/gnutls-texinfo-euro.patch b/packages/gnutls/gnutls-1.4.0/gnutls-texinfo-euro.patch
new file mode 100644
index 0000000000..e2a2762424
--- /dev/null
+++ b/packages/gnutls/gnutls-1.4.0/gnutls-texinfo-euro.patch
@@ -0,0 +1,16 @@
+The version of texinfo in Debian Sarge does not understand the @euro{} command.
+This patch replaces the @euro{} command with the word "euro".
+
+--- gnutls-1.3.5/doc/signatures.texi.orig 2006-04-26 08:06:40.918268000 +0930
++++ gnutls-1.3.5/doc/signatures.texi 2006-04-26 08:06:52.446515440 +0930
+@@ -11,8 +11,8 @@
+ long as it is difficult enough to generate two different messages with
+ the same hash algorithm output. In that case the same signature could
+ be used as a proof for both messages. Nobody wants to sign an innocent
+-message of donating 1 @euro{} to Greenpeace and find out that he
+-donated 1.000.000 @euro{} to Bad Inc.
++message of donating 1 euro to Greenpeace and find out that he
++donated 1.000.000 euro to Bad Inc.
+
+ For a hash algorithm to be called cryptographic the following three
+ requirements must hold
diff --git a/packages/gnutls/gnutls_1.4.0.bb b/packages/gnutls/gnutls_1.4.0.bb
new file mode 100644
index 0000000000..3c48bc95ff
--- /dev/null
+++ b/packages/gnutls/gnutls_1.4.0.bb
@@ -0,0 +1,34 @@
+DESCRIPTION = "GNU Transport Layer Security Library"
+DEPENDS = "zlib libgcrypt lzo"
+MAINTAINER = "Eric Shattow <lucent@gmail.com>"
+HOMEPAGE = "http://www.gnu.org/software/gnutls/"
+LICENSE = "LGPL"
+
+SRC_URI = "ftp://ftp.gnutls.org/pub/gnutls/gnutls-${PV}.tar.bz2 \
+ file://gnutls-openssl.patch;patch=1 \
+ file://gnutls-texinfo-euro.patch;patch=1"
+
+inherit autotools binconfig
+
+PACKAGES =+ "${PN}-openssl ${PN}-extra ${PN}-bin"
+FILES_${PN}-openssl = "${libdir}/libgnutls-openssl.so.*"
+FILES_${PN}-extra = "${libdir}/libgnutls-extra.so.*"
+FILES_${PN} = "${libdir}/libgnutls.so.*"
+FILES_${PN}-bin = "${bindir}/gnutls-serv \
+ ${bindir}/gnutls-cli \
+ ${bindir}/srptool \
+ ${bindir}/certtool \
+ ${bindir}/gnutls-srpcrypt \
+ ${bindir}/psktool"
+
+FILES_${PN}-dev += "${bindir}/*-config ${bindir}/gnutls-cli-debug"
+
+EXTRA_OECONF="--with-included-opencdk --with-included-libtasn1"
+
+do_stage() {
+ oe_libinstall -C lib/.libs -so -a libgnutls ${STAGING_LIBDIR}
+ oe_libinstall -C libextra/.libs -so -a libgnutls-extra ${STAGING_LIBDIR}
+ oe_libinstall -C libextra/.libs -so -a libgnutls-openssl ${STAGING_LIBDIR}
+ autotools_stage_includes
+}
+
diff --git a/packages/gomunicator/gomunicator_cvs.bb b/packages/gomunicator/gomunicator_cvs.bb
index a567d16009..dae9e9f809 100644
--- a/packages/gomunicator/gomunicator_cvs.bb
+++ b/packages/gomunicator/gomunicator_cvs.bb
@@ -10,10 +10,9 @@ PV = "0.1.3+cvs-${SRCDATE}"
inherit autotools pkgconfig
-SRC_URI = "cvs://anonymous@cvs.sourceforge.net/cvsroot/xanadux;module=gomunicator"
+SRC_URI = "cvs://anonymous@xanadux.cvs.sourceforge.net/cvsroot/xanadux;module=gomunicator"
S = "${WORKDIR}/${PN}"
do_install_append() {
install -d ${D}${datadir}/applications
- install -m 0644 gomunicator.desktop ${D}${datadir}/applications/
}
diff --git a/packages/gpe-nmf/gpe-nmf-0.22/fix-includepath.patch b/packages/gpe-nmf/gpe-nmf-0.22/fix-includepath.patch
new file mode 100644
index 0000000000..cf6bd12da7
--- /dev/null
+++ b/packages/gpe-nmf/gpe-nmf-0.22/fix-includepath.patch
@@ -0,0 +1,15 @@
+
+#
+# Patch managed by http://www.holgerschurig.de/patcher.html
+#
+
+--- gpe-nmf-0.22/Makefile~fix-includepath
++++ gpe-nmf-0.22/Makefile
+@@ -27,7 +27,6 @@
+ PACKAGE_LDFLAGS += -L../libgpewidget
+ BUILD = ../build
+ else
+-PACKAGE_CFLAGS += -I/usr/include/gpe
+ BUILD = build
+ endif
+ PACKAGE_LDFLAGS += $(GPELIBS) $(GTKLDFLAGS)
diff --git a/packages/gpe-nmf/gpe-nmf_0.22.bb b/packages/gpe-nmf/gpe-nmf_0.22.bb
index d90c42435b..c4b2ae7c2c 100644
--- a/packages/gpe-nmf/gpe-nmf_0.22.bb
+++ b/packages/gpe-nmf/gpe-nmf_0.22.bb
@@ -17,11 +17,12 @@ RRECOMMENDS = "gst-plugin-mad \
gst-plugin-ivorbis \
gst-plugin-tcp"
-SRC_URI += " file://playlist-segfault.patch;patch=1;pnum=0"
+SRC_URI += " file://playlist-segfault.patch;patch=1;pnum=0 \
+ file://fix-includepath.patch;patch=1"
SECTION = "gpe"
PRIORITY = "optional"
-PR = "r1"
+PR = "r2"
PARALLEL_MAKE=""
diff --git a/packages/gpe-package/gpe-package_0.3.bb b/packages/gpe-package/gpe-package_0.3.bb
index 0084b7e3c3..d74b0df5a3 100644
--- a/packages/gpe-package/gpe-package_0.3.bb
+++ b/packages/gpe-package/gpe-package_0.3.bb
@@ -1,5 +1,5 @@
LICENSE = "GPL"
-PR = "r0"
+PR = "r1"
inherit gpe pkgconfig
DESCRIPTION = "A package manager GUI for GPE"
@@ -8,3 +8,7 @@ RDEPENDS = "gpe-icons"
SECTION = "gpe"
PRIORITY = "optional"
+pkg_postinst () {
+#!/bin/sh
+chmod u+s /usr/bin/gpe-package
+}
diff --git a/packages/libeventdb/libeventdb_0.30.bb b/packages/libeventdb/libeventdb_0.30.bb
new file mode 100644
index 0000000000..30dc81c34c
--- /dev/null
+++ b/packages/libeventdb/libeventdb_0.30.bb
@@ -0,0 +1,15 @@
+LICENSE = "LGPL"
+DESCRIPTION = "Database access library for GPE calendar"
+SECTION = "gpe/libs"
+PRIORITY = "optional"
+DEPENDS = "libgpewidget libgpepimc sqlite"
+MAINTAINER = "Florian Boor <florian.boor@kernelconcepts.de>"
+
+GPE_TARBALL_SUFFIX = "bz2"
+
+inherit pkgconfig gpe autotools
+
+
+do_stage () {
+autotools_stage_all
+}
diff --git a/packages/libgpevtype/libgpevtype_0.17.bb b/packages/libgpevtype/libgpevtype_0.17.bb
new file mode 100644
index 0000000000..a2639f448c
--- /dev/null
+++ b/packages/libgpevtype/libgpevtype_0.17.bb
@@ -0,0 +1,25 @@
+LICENSE = "LGPL"
+DESCRIPTION = "Data interchange library for GPE"
+SECTION = "gpe/libs"
+PRIORITY = "optional"
+DEPENDS = "libmimedir libeventdb"
+MAINTAINER = "Florian Boor <florian.boor@kernelconcepts.de>
+PR = "r0"
+
+inherit pkgconfig gpe autotools
+
+SRC_URI = "${GPE_MIRROR}/${PN}-${PV}.tar.bz2"
+
+headers = "tag-db.h vcard.h vevent.h vtodo.h"
+
+
+do_stage () {
+ oe_libinstall -so libgpevtype ${STAGING_LIBDIR}
+
+ mkdir -p ${STAGING_INCDIR}/gpe
+ for h in ${headers}; do
+ install -m 0644 ${S}/gpe/$h ${STAGING_INCDIR}/gpe/${h}
+ done
+}
+
+
diff --git a/packages/libgpg-error/libgpg-error-1.3/.mtn2git_empty b/packages/libgpg-error/libgpg-error-1.3/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/libgpg-error/libgpg-error-1.3/.mtn2git_empty
diff --git a/packages/libgpg-error/libgpg-error-1.3/pkgconfig.patch b/packages/libgpg-error/libgpg-error-1.3/pkgconfig.patch
new file mode 100644
index 0000000000..f367f1ccc2
--- /dev/null
+++ b/packages/libgpg-error/libgpg-error-1.3/pkgconfig.patch
@@ -0,0 +1,54 @@
+
+#
+# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
+#
+
+Index: libgpg-error-1.3/configure.ac
+===================================================================
+--- libgpg-error-1.3.orig/configure.ac
++++ libgpg-error-1.3/configure.ac
+@@ -117,6 +117,7 @@ GPG_ERROR_CONFIG_CFLAGS=""
+ AC_SUBST(GPG_ERROR_CONFIG_LIBS)
+ AC_SUBST(GPG_ERROR_CONFIG_CFLAGS)
+ AC_CONFIG_FILES([src/gpg-error-config], [chmod +x src/gpg-error-config])
++AC_CONFIG_FILES([src/gpg-error.pc])
+
+
+ # Special defines for certain platforms
+Index: libgpg-error-1.3/src/Makefile.am
+===================================================================
+--- libgpg-error-1.3.orig/src/Makefile.am
++++ libgpg-error-1.3/src/Makefile.am
+@@ -28,6 +28,8 @@ include_HEADERS = gpg-error.h
+ bin_SCRIPTS = gpg-error-config
+ m4datadir = $(datadir)/aclocal
+ m4data_DATA = gpg-error.m4
++pkgconfigdir = $(libdir)/pkgconfig
++pkgconfig_DATA = gpg-error.pc
+
+
+ EXTRA_DIST = mkstrtable.awk err-sources.h.in err-codes.h.in \
+@@ -35,7 +37,7 @@ EXTRA_DIST = mkstrtable.awk err-sources.
+ mkerrcodes.awk mkerrcodes1.awk mkerrcodes2.awk mkerrcodes.c \
+ mkheader.awk gpg-error.h.in \
+ err-sources.h err-codes.h gpg-error-config.in gpg-error.m4 \
+- gpg-error.def versioninfo.rc.in
++ gpg-error.def versioninfo.rc.in gpg-error.pc.in
+
+ BUILT_SOURCES = err-sources.h err-codes.h code-to-errno.h code-from-errno.h \
+ err-sources-sym.h err-codes-sym.h errnos-sym.h gpg-error.h
+Index: libgpg-error-1.3/src/gpg-error.pc.in
+===================================================================
+--- /dev/null
++++ libgpg-error-1.3/src/gpg-error.pc.in
+@@ -0,0 +1,10 @@
++prefix=@prefix@
++exec_prefix=@exec_prefix@
++libdir=@libdir@
++includedir=@includedir@
++
++Name: gpg-error
++Description: a library that defines common error values for all GnuPG components
++Version: @VERSION@
++Libs: -L{libdir} -lgpg-error
++Cflags: -I${includedir}
diff --git a/packages/libgpg-error/libgpg-error_1.3.bb b/packages/libgpg-error/libgpg-error_1.3.bb
new file mode 100644
index 0000000000..c29053832b
--- /dev/null
+++ b/packages/libgpg-error/libgpg-error_1.3.bb
@@ -0,0 +1,28 @@
+PR = "r0"
+DESCRIPTION = "GPG-Error library"
+SECTION = "libs"
+PRIORITY = "optional"
+LICENSE = "GPL LGPL FDL"
+
+SRC_URI = "ftp://ftp.gnupg.org/gcrypt/libgpg-error/libgpg-error-${PV}.tar.gz \
+ file://pkgconfig.patch;patch=1"
+
+# move libgpg-error-config into -dev package
+FILES_${PN} = "${libdir}/lib*.so.*"
+FILES_${PN}-dev += "${bindir}"
+
+inherit autotools binconfig pkgconfig
+
+do_stage() {
+ oe_libinstall -a -so -C src libgpg-error ${STAGING_LIBDIR}
+ install -m 0755 src/gpg-error-config ${STAGING_BINDIR}/
+
+ install -d ${STAGING_INCDIR}/
+ for X in gpg-error.h
+ do
+ install -m 0644 ${S}/src/$X ${STAGING_INCDIR}/$X
+ done
+
+ install -d ${STAGING_DATADIR}/aclocal
+ install -m 0644 src/gpg-error.m4 ${STAGING_DATADIR}/aclocal/
+}
diff --git a/packages/liboil/liboil_0.3.6.bb b/packages/liboil/liboil_0.3.9.bb
index 8eae2fc007..04a83100b0 100644
--- a/packages/liboil/liboil_0.3.6.bb
+++ b/packages/liboil/liboil_0.3.9.bb
@@ -1,7 +1,7 @@
DESCRIPTION = "Liboil is a library of simple functions that are optimized for various CPUs."
HOMEPAGE = "http://liboil.freedesktop.org/"
LICENSE = "various"
-MAINTAINER = "Koen Kooi <koen@handhelds.org>"
+MAINTAINER = "Koen Kooi <koen@on.kabel.utwente.nl>"
SRC_URI = "http://liboil.freedesktop.org/download/${P}.tar.gz"
diff --git a/packages/linux/ixp4xx-kernel/2.6.16/defconfig b/packages/linux/ixp4xx-kernel/2.6.16/defconfig
index 1b190e290d..17d51ba41b 100644
--- a/packages/linux/ixp4xx-kernel/2.6.16/defconfig
+++ b/packages/linux/ixp4xx-kernel/2.6.16/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.16
-# Tue Mar 21 13:57:18 2006
+# Fri Apr 7 02:45:02 2006
#
CONFIG_ARM=y
CONFIG_MMU=y
@@ -572,7 +572,7 @@ CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0x50000000
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=m
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_NBD=m
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_UB is not set
CONFIG_BLK_DEV_RAM=y
@@ -1166,8 +1166,8 @@ CONFIG_VIDEO_CX88=m
CONFIG_VIDEO_CX88_ALSA=m
# CONFIG_VIDEO_EM28XX is not set
CONFIG_VIDEO_OVCAMCHIP=m
-# CONFIG_VIDEO_AUDIO_DECODER is not set
-CONFIG_VIDEO_DECODER=m
+CONFIG_VIDEO_AUDIO_DECODER=m
+# CONFIG_VIDEO_DECODER is not set
#
# Radio Adapters
diff --git a/packages/linux/ixp4xx-kernel_2.6.16.bb b/packages/linux/ixp4xx-kernel_2.6.16.bb
index ca8a64e9ed..d9a048dcb2 100644
--- a/packages/linux/ixp4xx-kernel_2.6.16.bb
+++ b/packages/linux/ixp4xx-kernel_2.6.16.bb
@@ -3,7 +3,7 @@
# Increment PR_CONFIG for changes to the ixp4xx-kernel specific
# defconfig (do *NOT* increment anything in here for changes
# to other kernel configs!)
-PR_CONFIG = "2"
+PR_CONFIG = "3"
#
# Increment the number below (i.e. the digits after PR) when
# making changes within this file or for changes to the patches
diff --git a/packages/linux/linux-ezx/defconfig-a780 b/packages/linux/linux-ezx/defconfig-a780
index 560530a1ce..1ca94e23a9 100644
--- a/packages/linux/linux-ezx/defconfig-a780
+++ b/packages/linux/linux-ezx/defconfig-a780
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.16.13
-# Thu May 18 19:40:25 2006
+# Sun May 21 21:07:54 2006
#
CONFIG_ARM=y
CONFIG_MMU=y
@@ -122,7 +122,7 @@ CONFIG_PXA27x=y
CONFIG_IWMMXT=y
CONFIG_PXA_SPI=y
CONFIG_PXA_EZX_PCAP=y
-CONFIG_PXA_EZX_PCAP_EMU=m
+CONFIG_PXA_EZX_PCAP_EMU=y
#
# Processor Type
@@ -171,7 +171,7 @@ CONFIG_ALIGNMENT_TRAP=y
#
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M root=/dev/mmcblk0p1 rootfstype=ext3 rootdelay=1 ip=192.168.1.2:192.168.1.10:192.168.1.10:255.255.255.0:ezx:usb0:off console=ttyS2,115200n8 console=tty0"
+CONFIG_CMDLINE="console=ttyS2,115200n8 console=tty1 noinitrd root=/dev/mmcblk0p1 rootfstype=ext3 rootdelay=5 ip=192.168.1.2:192.168.1.10:192.168.1.10:255.255.255.0:ezx:usb0:off debug"
# CONFIG_XIP_KERNEL is not set
#
@@ -672,10 +672,10 @@ CONFIG_INPUT=y
#
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
-CONFIG_INPUT_TSDEV=m
+CONFIG_INPUT_TSDEV=y
CONFIG_INPUT_TSDEV_SCREEN_X=240
CONFIG_INPUT_TSDEV_SCREEN_Y=320
-CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
@@ -699,8 +699,9 @@ CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_ELO is not set
# CONFIG_TOUCHSCREEN_MTOUCH is not set
# CONFIG_TOUCHSCREEN_MK712 is not set
-CONFIG_TOUCHSCREEN_PCAP=m
-# CONFIG_INPUT_MISC is not set
+CONFIG_TOUCHSCREEN_PCAP=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
#
# Hardware I/O ports
@@ -837,9 +838,9 @@ CONFIG_SPI_BITBANG=m
#
# Motorola EZX devices
#
-# CONFIG_KEYPAD_A780 is not set
+CONFIG_KEYPAD_A780=y
# CONFIG_KEYPAD_E680 is not set
-# CONFIG_KEYLIGHT_A780 is not set
+CONFIG_KEYLIGHT_A780=y
# CONFIG_FMRADIO_E680 is not set
#
diff --git a/packages/linux/linux-ezx/defconfig-e680 b/packages/linux/linux-ezx/defconfig-e680
index 560530a1ce..365a34df23 100644
--- a/packages/linux/linux-ezx/defconfig-e680
+++ b/packages/linux/linux-ezx/defconfig-e680
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.16.13
-# Thu May 18 19:40:25 2006
+# Sun May 21 21:11:16 2006
#
CONFIG_ARM=y
CONFIG_MMU=y
@@ -116,13 +116,13 @@ CONFIG_PXA_EZX=y
# CONFIG_MACH_MAINSTONE is not set
# CONFIG_ARCH_PXA_IDP is not set
# CONFIG_PXA_SHARPSL is not set
-# CONFIG_PXA_EZX_E680 is not set
-CONFIG_PXA_EZX_A780=y
+CONFIG_PXA_EZX_E680=y
+# CONFIG_PXA_EZX_A780 is not set
CONFIG_PXA27x=y
CONFIG_IWMMXT=y
CONFIG_PXA_SPI=y
CONFIG_PXA_EZX_PCAP=y
-CONFIG_PXA_EZX_PCAP_EMU=m
+CONFIG_PXA_EZX_PCAP_EMU=y
#
# Processor Type
@@ -171,7 +171,7 @@ CONFIG_ALIGNMENT_TRAP=y
#
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M root=/dev/mmcblk0p1 rootfstype=ext3 rootdelay=1 ip=192.168.1.2:192.168.1.10:192.168.1.10:255.255.255.0:ezx:usb0:off console=ttyS2,115200n8 console=tty0"
+CONFIG_CMDLINE="console=ttyS2,115200n8 console=tty1 noinitrd root=/dev/mmcblk0p1 rootfstype=ext3 rootdelay=5 ip=192.168.1.2:192.168.1.10:192.168.1.10:255.255.255.0:ezx:usb0:off debug"
# CONFIG_XIP_KERNEL is not set
#
@@ -672,10 +672,10 @@ CONFIG_INPUT=y
#
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
-CONFIG_INPUT_TSDEV=m
+CONFIG_INPUT_TSDEV=y
CONFIG_INPUT_TSDEV_SCREEN_X=240
CONFIG_INPUT_TSDEV_SCREEN_Y=320
-CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
@@ -699,8 +699,9 @@ CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_ELO is not set
# CONFIG_TOUCHSCREEN_MTOUCH is not set
# CONFIG_TOUCHSCREEN_MK712 is not set
-CONFIG_TOUCHSCREEN_PCAP=m
-# CONFIG_INPUT_MISC is not set
+CONFIG_TOUCHSCREEN_PCAP=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
#
# Hardware I/O ports
@@ -838,9 +839,9 @@ CONFIG_SPI_BITBANG=m
# Motorola EZX devices
#
# CONFIG_KEYPAD_A780 is not set
-# CONFIG_KEYPAD_E680 is not set
+CONFIG_KEYPAD_E680=y
# CONFIG_KEYLIGHT_A780 is not set
-# CONFIG_FMRADIO_E680 is not set
+CONFIG_FMRADIO_E680=y
#
# Multimedia Capabilities Port drivers
diff --git a/packages/linux/linux-ezx_2.6.16.13.bb b/packages/linux/linux-ezx_2.6.16.13.bb
index 8ef702ef0d..29d7faf04e 100644
--- a/packages/linux/linux-ezx_2.6.16.13.bb
+++ b/packages/linux/linux-ezx_2.6.16.13.bb
@@ -6,7 +6,7 @@ MAINTAINER = "Michael 'Mickey' Lauer <mickey@vanille.de>"
LICENSE = "GPL"
DEPENDS += "quilt-native"
EZX = "ezx6"
-PR = "${EZX}-r1"
+PR = "${EZX}-r2"
inherit kernel
diff --git a/packages/linux/linux-h6300-omap1-2.6.16.16/.mtn2git_empty b/packages/linux/linux-h6300-omap1-2.6.16.16/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/linux/linux-h6300-omap1-2.6.16.16/.mtn2git_empty
diff --git a/packages/linux/linux-h6300-omap1-2.6.16.16/defconfig b/packages/linux/linux-h6300-omap1-2.6.16.16/defconfig
new file mode 100644
index 0000000000..ddfa1eb8e6
--- /dev/null
+++ b/packages/linux/linux-h6300-omap1-2.6.16.16/defconfig
@@ -0,0 +1,1558 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.16.16-omap1-h6300
+# Thu May 18 02:10:05 2006
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=m
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+
+#
+# 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_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_L7200 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_OMAP=y
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_AT91RM9200 is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP1=y
+# CONFIG_ARCH_OMAP2 is not set
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_RESET_CLOCKS is not set
+# CONFIG_OMAP_BOOT_TAG is not set
+CONFIG_OMAP_MUX=y
+# CONFIG_OMAP_MUX_DEBUG is not set
+CONFIG_OMAP_MUX_WARNINGS=y
+CONFIG_OMAP_MPU_TIMER=y
+# CONFIG_OMAP_32K_TIMER is not set
+CONFIG_OMAP_LL_DEBUG_UART1=y
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+# CONFIG_OMAP_LL_DEBUG_UART3 is not set
+CONFIG_OMAP_SERIAL_WAKE=y
+
+#
+# OMAP Core Type
+#
+# CONFIG_ARCH_OMAP730 is not set
+CONFIG_ARCH_OMAP15XX=y
+# CONFIG_ARCH_OMAP16XX is not set
+
+#
+# OMAP Board Type
+#
+# CONFIG_MACH_OMAP_INNOVATOR is not set
+CONFIG_MACH_OMAP_H6300=y
+# CONFIG_MACH_VOICEBLUE is not set
+# CONFIG_MACH_OMAP_PALMTE is not set
+# CONFIG_MACH_AMS_DELTA is not set
+# CONFIG_MACH_OMAP_GENERIC is not set
+
+#
+# OMAP CPU Speed
+#
+# CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER is not set
+CONFIG_OMAP_ARM_168MHZ=y
+CONFIG_OMAP_ARM_150MHZ=y
+CONFIG_OMAP_ARM_120MHZ=y
+CONFIG_OMAP_ARM_60MHZ=y
+CONFIG_OMAP_ARM_30MHZ=y
+CONFIG_OMAP_DSP=y
+CONFIG_OMAP_DSP_MBCMD_VERBOSE=y
+CONFIG_OMAP_DSP_TASK_MULTIOPEN=y
+CONFIG_OMAP_DSP_FBEXPORT=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM925T=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=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=y
+
+#
+# Bus support
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+
+#
+# Kernel Features
+#
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+# CONFIG_AEABI 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_SPLIT_PTLOCK_CPUS=4096
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=tty0 root=/dev/nfs nfsroot=192.168.2.1:/opt/h6300/rootfs,rsize=8192,wsize=8192 ip=192.168.2.2:192.168.2.1:192.168.2.1:255.0.0.0:ipaq:"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_MISC=y
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_APM=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# 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=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_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
+CONFIG_IP_NF_TFTP=m
+# CONFIG_IP_NF_AMANDA is not set
+# CONFIG_IP_NF_PPTP is not set
+CONFIG_IP_NF_QUEUE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+# CONFIG_BRIDGE_EBT_BROUTE is not set
+# CONFIG_BRIDGE_EBT_T_FILTER is not set
+# CONFIG_BRIDGE_EBT_T_NAT is not set
+# CONFIG_BRIDGE_EBT_802_3 is not set
+# CONFIG_BRIDGE_EBT_AMONG is not set
+# CONFIG_BRIDGE_EBT_ARP is not set
+# CONFIG_BRIDGE_EBT_IP is not set
+# CONFIG_BRIDGE_EBT_LIMIT is not set
+# CONFIG_BRIDGE_EBT_MARK is not set
+# CONFIG_BRIDGE_EBT_PKTTYPE is not set
+# CONFIG_BRIDGE_EBT_STP is not set
+# CONFIG_BRIDGE_EBT_VLAN is not set
+# CONFIG_BRIDGE_EBT_ARPREPLY is not set
+# CONFIG_BRIDGE_EBT_DNAT is not set
+# CONFIG_BRIDGE_EBT_MARK_T is not set
+# CONFIG_BRIDGE_EBT_REDIRECT is not set
+# CONFIG_BRIDGE_EBT_SNAT is not set
+# CONFIG_BRIDGE_EBT_LOG is not set
+# CONFIG_BRIDGE_EBT_ULOG is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=y
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+CONFIG_IRDA_ULTRA=y
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+# CONFIG_IRTTY_SIR is not set
+
+#
+# Dongle support
+#
+
+#
+# Old SIR device drivers
+#
+# CONFIG_IRPORT_SIR is not set
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
+# CONFIG_OMAP_IR is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+# CONFIG_BT_SCO is not set
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIUSB is not set
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIDTL1 is not set
+# CONFIG_BT_HCIBT3C is not set
+# CONFIG_BT_HCIBLUECARD is not set
+# CONFIG_BT_HCIBTUART is not set
+# CONFIG_BT_HCIBRF6150 is not set
+CONFIG_BT_HCIVHCI=m
+CONFIG_BT_H6300=m
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=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
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_GEOMETRY 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_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_AMDSTD_RETRY=1
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=m
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0x4000000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_OMAP_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_SLRAM=m
+CONFIG_MTD_PHRAM=m
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLKMTD=m
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+CONFIG_MTD_DOC2000=m
+CONFIG_MTD_DOC2001=m
+CONFIG_MTD_DOC2001PLUS=m
+CONFIG_MTD_DOCPROBE=m
+CONFIG_MTD_DOCECC=m
+CONFIG_MTD_DOCPROBE_ADVANCED=y
+CONFIG_MTD_DOCPROBE_ADDRESS=0x0000
+CONFIG_MTD_DOCPROBE_HIGH=y
+CONFIG_MTD_DOCPROBE_55AA=y
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_TOTO is not set
+CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0x0
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH is not set
+CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
+# CONFIG_MTD_NAND_NANDSIM is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+# CONFIG_MTD_ONENAND_SYNC_READ is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# 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_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_SMC91X=y
+# CONFIG_DM9000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+CONFIG_STRIP=y
+# CONFIG_PCMCIA_WAVELAN is not set
+# CONFIG_PCMCIA_NETWAVE is not set
+
+#
+# Wireless 802.11 Frequency Hopping cards support
+#
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_HERMES is not set
+CONFIG_ATMEL=y
+
+#
+# Wireless 802.11b Pcmcia/Cardbus cards support
+#
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_ATMEL is not set
+# CONFIG_PCMCIA_WL3501 is not set
+# CONFIG_HOSTAP is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_PPP=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+# CONFIG_PPP_MPPE is not set
+CONFIG_PPPOE=y
+# 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
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_TSDEV=y
+CONFIG_INPUT_TSDEV_SCREEN_X=240
+CONFIG_INPUT_TSDEV_SCREEN_Y=320
+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_OMAP=m
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=y
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_TOUCHSCREEN_OMAP=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=y
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_CS is not set
+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_CORE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_NVRAM=y
+# CONFIG_RTC is not set
+CONFIG_OMAP_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
+CONFIG_I2C_OMAP=y
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+CONFIG_PCA9535=y
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_TLV320AIC23 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_RTC_X1205_I2C 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
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS 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_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_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_MACMODES is not set
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_OMAP=y
+# CONFIG_FB_OMAP_LCDC_EXTERNAL is not set
+# CONFIG_FB_OMAP_LCD_LPH8923 is not set
+# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
+CONFIG_FB_OMAP_DMA_TUNE=y
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+# CONFIG_FONT_8x16 is not set
+# 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=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+CONFIG_LOGO_LINUX_VGA16=y
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_DEVICE=y
+
+#
+# Telephony Support
+#
+CONFIG_PHONE=m
+# CONFIG_PHONE_IXJ is not set
+CONFIG_GSM_H6300=m
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_SEQUENCER=m
+# CONFIG_SND_SEQ_DUMMY is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PRINTK=y
+CONFIG_SND_DEBUG=y
+# CONFIG_SND_DEBUG_DETECT is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+# CONFIG_SND_OMAP_AIC23 is not set
+CONFIG_SND_OMAP_TSC2101=m
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+
+#
+# PCMCIA devices
+#
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
+CONFIG_USB_ACM=y
+# 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 is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# 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=y
+CONFIG_USB_NET_AX8817X=y
+CONFIG_USB_NET_CDCETHER=y
+# CONFIG_USB_NET_GL620A is not set
+CONFIG_USB_NET_NET1080=y
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+CONFIG_USB_NET_ZAURUS=y
+# CONFIG_USB_ZD1201 is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CONSOLE=y
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ANYDATA is not set
+# CONFIG_USB_SERIAL_BELKIN 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_VISOR=y
+CONFIG_USB_SERIAL_IPAQ=y
+# 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_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_PL2303 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE 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
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 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_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+CONFIG_USB_GADGET_OMAP=y
+CONFIG_USB_OMAP=y
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=y
+# CONFIG_USB_ETH_RNDIS is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BROKEN_RFD=y
+CONFIG_MMC_BULKTRANSFER=y
+CONFIG_MMC_OMAP=y
+
+#
+# Synchronous Serial Interfaces (SSI)
+#
+CONFIG_OMAP_UWIRE=y
+CONFIG_OMAP_TSC2101=y
+
+#
+# CBUS support
+#
+# CONFIG_CBUS is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+CONFIG_ROMFS_FS=y
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=y
+# 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_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_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS 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_JFFS_FS=y
+CONFIG_JFFS_FS_VERBOSE=0
+CONFIG_JFFS_PROC_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=4
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=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_CRAMFS=y
+# 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
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+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
+# CONFIG_9P_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
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+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
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+# 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_DES=y
+# 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_DEFLATE=m
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_REED_SOLOMON=m
+CONFIG_REED_SOLOMON_DEC16=y
diff --git a/packages/linux/linux-h6300-omap1-2.6.16.16/linux-2.6.16.16.patch b/packages/linux/linux-h6300-omap1-2.6.16.16/linux-2.6.16.16.patch
new file mode 100644
index 0000000000..ff0aaaac27
--- /dev/null
+++ b/packages/linux/linux-h6300-omap1-2.6.16.16/linux-2.6.16.16.patch
@@ -0,0 +1,5134 @@
+diff -Naur linux-2.6.16/arch/alpha/kernel/setup.c linux-2.6.16.16/arch/alpha/kernel/setup.c
+--- linux-2.6.16/arch/alpha/kernel/setup.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/alpha/kernel/setup.c 2006-05-11 04:56:24.000000000 +0300
+@@ -24,6 +24,7 @@
+ #include <linux/config.h> /* CONFIG_ALPHA_LCA etc */
+ #include <linux/mc146818rtc.h>
+ #include <linux/console.h>
++#include <linux/cpu.h>
+ #include <linux/errno.h>
+ #include <linux/init.h>
+ #include <linux/string.h>
+@@ -477,6 +478,22 @@
+ #undef PFN_PHYS
+ #undef PFN_MAX
+
++static int __init
++register_cpus(void)
++{
++ int i;
++
++ for_each_possible_cpu(i) {
++ struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL);
++ if (!p)
++ return -ENOMEM;
++ register_cpu(p, i, NULL);
++ }
++ return 0;
++}
++
++arch_initcall(register_cpus);
++
+ void __init
+ setup_arch(char **cmdline_p)
+ {
+diff -Naur linux-2.6.16/arch/alpha/kernel/smp.c linux-2.6.16.16/arch/alpha/kernel/smp.c
+--- linux-2.6.16/arch/alpha/kernel/smp.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/alpha/kernel/smp.c 2006-05-11 04:56:24.000000000 +0300
+@@ -439,7 +439,7 @@
+ if ((cpu->flags & 0x1cc) == 0x1cc) {
+ smp_num_probed++;
+ /* Assume here that "whami" == index */
+- cpu_set(i, cpu_possible_map);
++ cpu_set(i, cpu_present_mask);
+ cpu->pal_revision = boot_cpu_palrev;
+ }
+
+@@ -450,9 +450,8 @@
+ }
+ } else {
+ smp_num_probed = 1;
+- cpu_set(boot_cpuid, cpu_possible_map);
++ cpu_set(boot_cpuid, cpu_present_mask);
+ }
+- cpu_present_mask = cpumask_of_cpu(boot_cpuid);
+
+ printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n",
+ smp_num_probed, cpu_possible_map.bits[0]);
+@@ -488,9 +487,8 @@
+ smp_prepare_boot_cpu(void)
+ {
+ /*
+- * Mark the boot cpu (current cpu) as both present and online
++ * Mark the boot cpu (current cpu) as online
+ */
+- cpu_set(smp_processor_id(), cpu_present_mask);
+ cpu_set(smp_processor_id(), cpu_online_map);
+ }
+
+diff -Naur linux-2.6.16/arch/alpha/lib/strncpy.S linux-2.6.16.16/arch/alpha/lib/strncpy.S
+--- linux-2.6.16/arch/alpha/lib/strncpy.S 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/alpha/lib/strncpy.S 2006-05-11 04:56:24.000000000 +0300
+@@ -43,8 +43,8 @@
+
+ .align 4
+ $multiword:
+- subq $24, 1, $2 # clear the final bits in the prev word
+- or $2, $24, $2
++ subq $27, 1, $2 # clear the final bits in the prev word
++ or $2, $27, $2
+ zapnot $1, $2, $1
+ subq $18, 1, $18
+
+@@ -70,8 +70,8 @@
+ bne $18, 0b
+
+ 1: ldq_u $1, 0($16) # clear the leading bits in the final word
+- subq $27, 1, $2
+- or $2, $27, $2
++ subq $24, 1, $2
++ or $2, $24, $2
+
+ zap $1, $2, $1
+ stq_u $1, 0($16)
+diff -Naur linux-2.6.16/arch/i386/kernel/apm.c linux-2.6.16.16/arch/i386/kernel/apm.c
+--- linux-2.6.16/arch/i386/kernel/apm.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/i386/kernel/apm.c 2006-05-11 04:56:24.000000000 +0300
+@@ -1081,7 +1081,7 @@
+ break;
+ }
+
+- if (error == APM_NOT_ENGAGED && state != APM_STATE_READY) {
++ if (error == APM_NOT_ENGAGED) {
+ static int tried;
+ int eng_error;
+ if (tried++ == 0) {
+diff -Naur linux-2.6.16/arch/i386/kernel/cpu/amd.c linux-2.6.16.16/arch/i386/kernel/cpu/amd.c
+--- linux-2.6.16/arch/i386/kernel/cpu/amd.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/i386/kernel/cpu/amd.c 2006-05-11 04:56:24.000000000 +0300
+@@ -207,6 +207,8 @@
+ set_bit(X86_FEATURE_K7, c->x86_capability);
+ break;
+ }
++ if (c->x86 >= 6)
++ set_bit(X86_FEATURE_FXSAVE_LEAK, c->x86_capability);
+
+ display_cacheinfo(c);
+
+diff -Naur linux-2.6.16/arch/i386/kernel/cpu/cpufreq/Kconfig linux-2.6.16.16/arch/i386/kernel/cpu/cpufreq/Kconfig
+--- linux-2.6.16/arch/i386/kernel/cpu/cpufreq/Kconfig 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/i386/kernel/cpu/cpufreq/Kconfig 2006-05-11 04:56:24.000000000 +0300
+@@ -203,6 +203,7 @@
+ config X86_LONGHAUL
+ tristate "VIA Cyrix III Longhaul"
+ select CPU_FREQ_TABLE
++ depends on BROKEN
+ help
+ This adds the CPUFreq driver for VIA Samuel/CyrixIII,
+ VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T
+diff -Naur linux-2.6.16/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c linux-2.6.16.16/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
+--- linux-2.6.16/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c 2006-05-11 04:56:24.000000000 +0300
+@@ -244,7 +244,7 @@
+ for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) {
+ if ((i<2) && (has_N44_O17_errata[policy->cpu]))
+ p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+- else if (has_N60_errata[policy->cpu] && p4clockmod_table[i].frequency < 2000000)
++ else if (has_N60_errata[policy->cpu] && ((stock_freq * i)/8) < 2000000)
+ p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+ else
+ p4clockmod_table[i].frequency = (stock_freq * i)/8;
+diff -Naur linux-2.6.16/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c linux-2.6.16.16/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
+--- linux-2.6.16/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c 2006-05-11 04:56:24.000000000 +0300
+@@ -75,7 +75,9 @@
+ __asm__ __volatile__(
+ "out %%al, (%%dx)\n"
+ : "=D" (result)
+- : "a" (command), "b" (function), "c" (0), "d" (smi_port), "D" (0), "S" (magic)
++ : "a" (command), "b" (function), "c" (0), "d" (smi_port),
++ "D" (0), "S" (magic)
++ : "memory"
+ );
+
+ dprintk("result is %x\n", result);
+diff -Naur linux-2.6.16/arch/i386/kernel/dmi_scan.c linux-2.6.16.16/arch/i386/kernel/dmi_scan.c
+--- linux-2.6.16/arch/i386/kernel/dmi_scan.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/i386/kernel/dmi_scan.c 2006-05-11 04:56:24.000000000 +0300
+@@ -106,7 +106,7 @@
+ struct dmi_device *dev;
+
+ for (i = 0; i < count; i++) {
+- char *d = ((char *) dm) + (i * 2);
++ char *d = (char *)(dm + 1) + (i * 2);
+
+ /* Skip disabled device */
+ if ((*d & 0x80) == 0)
+diff -Naur linux-2.6.16/arch/i386/kernel/vm86.c linux-2.6.16.16/arch/i386/kernel/vm86.c
+--- linux-2.6.16/arch/i386/kernel/vm86.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/i386/kernel/vm86.c 2006-05-11 04:56:24.000000000 +0300
+@@ -43,6 +43,7 @@
+ #include <linux/smp_lock.h>
+ #include <linux/highmem.h>
+ #include <linux/ptrace.h>
++#include <linux/audit.h>
+
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+@@ -252,6 +253,7 @@
+ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk)
+ {
+ struct tss_struct *tss;
++ long eax;
+ /*
+ * make sure the vm86() system call doesn't try to do anything silly
+ */
+@@ -305,13 +307,19 @@
+ tsk->thread.screen_bitmap = info->screen_bitmap;
+ if (info->flags & VM86_SCREEN_BITMAP)
+ mark_screen_rdonly(tsk->mm);
++ __asm__ __volatile__("xorl %eax,%eax; movl %eax,%fs; movl %eax,%gs\n\t");
++ __asm__ __volatile__("movl %%eax, %0\n" :"=r"(eax));
++
++ /*call audit_syscall_exit since we do not exit via the normal paths */
++ if (unlikely(current->audit_context))
++ audit_syscall_exit(current, AUDITSC_RESULT(eax), eax);
++
+ __asm__ __volatile__(
+- "xorl %%eax,%%eax; movl %%eax,%%fs; movl %%eax,%%gs\n\t"
+ "movl %0,%%esp\n\t"
+ "movl %1,%%ebp\n\t"
+ "jmp resume_userspace"
+ : /* no outputs */
+- :"r" (&info->regs), "r" (task_thread_info(tsk)) : "ax");
++ :"r" (&info->regs), "r" (task_thread_info(tsk)));
+ /* we never return here */
+ }
+
+diff -Naur linux-2.6.16/arch/m32r/kernel/m32r_ksyms.c linux-2.6.16.16/arch/m32r/kernel/m32r_ksyms.c
+--- linux-2.6.16/arch/m32r/kernel/m32r_ksyms.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/m32r/kernel/m32r_ksyms.c 2006-05-11 04:56:24.000000000 +0300
+@@ -38,10 +38,6 @@
+ EXPORT_SYMBOL(__delay);
+ EXPORT_SYMBOL(__const_udelay);
+
+-EXPORT_SYMBOL(__get_user_1);
+-EXPORT_SYMBOL(__get_user_2);
+-EXPORT_SYMBOL(__get_user_4);
+-
+ EXPORT_SYMBOL(strpbrk);
+ EXPORT_SYMBOL(strstr);
+
+diff -Naur linux-2.6.16/arch/m32r/kernel/setup.c linux-2.6.16.16/arch/m32r/kernel/setup.c
+--- linux-2.6.16/arch/m32r/kernel/setup.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/m32r/kernel/setup.c 2006-05-11 04:56:24.000000000 +0300
+@@ -9,6 +9,7 @@
+
+ #include <linux/config.h>
+ #include <linux/init.h>
++#include <linux/kernel.h>
+ #include <linux/stddef.h>
+ #include <linux/fs.h>
+ #include <linux/sched.h>
+@@ -218,8 +219,6 @@
+ extern unsigned long setup_memory(void);
+ #endif /* CONFIG_DISCONTIGMEM */
+
+-#define M32R_PCC_PCATCR 0x00ef7014 /* will move to m32r.h */
+-
+ void __init setup_arch(char **cmdline_p)
+ {
+ ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
+@@ -268,15 +267,14 @@
+ paging_init();
+ }
+
+-static struct cpu cpu[NR_CPUS];
++static struct cpu cpu_devices[NR_CPUS];
+
+ static int __init topology_init(void)
+ {
+- int cpu_id;
++ int i;
+
+- for (cpu_id = 0; cpu_id < NR_CPUS; cpu_id++)
+- if (cpu_possible(cpu_id))
+- register_cpu(&cpu[cpu_id], cpu_id, NULL);
++ for_each_present_cpu(i)
++ register_cpu(&cpu_devices[i], i, NULL);
+
+ return 0;
+ }
+diff -Naur linux-2.6.16/arch/m32r/kernel/smpboot.c linux-2.6.16.16/arch/m32r/kernel/smpboot.c
+--- linux-2.6.16/arch/m32r/kernel/smpboot.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/m32r/kernel/smpboot.c 2006-05-11 04:56:24.000000000 +0300
+@@ -39,8 +39,10 @@
+ * Martin J. Bligh : Added support for multi-quad systems
+ */
+
++#include <linux/module.h>
+ #include <linux/config.h>
+ #include <linux/init.h>
++#include <linux/kernel.h>
+ #include <linux/mm.h>
+ #include <linux/smp_lock.h>
+ #include <linux/irq.h>
+@@ -72,11 +74,15 @@
+
+ /* Bitmask of currently online CPUs */
+ cpumask_t cpu_online_map;
++EXPORT_SYMBOL(cpu_online_map);
+
+ cpumask_t cpu_bootout_map;
+ cpumask_t cpu_bootin_map;
+-cpumask_t cpu_callout_map;
+ static cpumask_t cpu_callin_map;
++cpumask_t cpu_callout_map;
++EXPORT_SYMBOL(cpu_callout_map);
++cpumask_t cpu_possible_map = CPU_MASK_ALL;
++EXPORT_SYMBOL(cpu_possible_map);
+
+ /* Per CPU bogomips and other parameters */
+ struct cpuinfo_m32r cpu_data[NR_CPUS] __cacheline_aligned;
+@@ -110,7 +116,6 @@
+
+ void smp_prepare_boot_cpu(void);
+ void smp_prepare_cpus(unsigned int);
+-static void smp_tune_scheduling(void);
+ static void init_ipi_lock(void);
+ static void do_boot_cpu(int);
+ int __cpu_up(unsigned int);
+@@ -177,6 +182,9 @@
+ }
+ for (phys_id = 0 ; phys_id < nr_cpu ; phys_id++)
+ physid_set(phys_id, phys_cpu_present_map);
++#ifndef CONFIG_HOTPLUG_CPU
++ cpu_present_map = cpu_possible_map;
++#endif
+
+ show_mp_info(nr_cpu);
+
+@@ -186,7 +194,6 @@
+ * Setup boot CPU information
+ */
+ smp_store_cpu_info(0); /* Final full version of the data */
+- smp_tune_scheduling();
+
+ /*
+ * If SMP should be disabled, then really disable it!
+@@ -230,11 +237,6 @@
+ Dprintk("Boot done.\n");
+ }
+
+-static void __init smp_tune_scheduling(void)
+-{
+- /* Nothing to do. */
+-}
+-
+ /*
+ * init_ipi_lock : Initialize IPI locks.
+ */
+@@ -629,4 +631,3 @@
+ physid_2_cpu[phys_id] = -1;
+ cpu_2_physid[cpu_id] = -1;
+ }
+-
+diff -Naur linux-2.6.16/arch/m32r/lib/getuser.S linux-2.6.16.16/arch/m32r/lib/getuser.S
+--- linux-2.6.16/arch/m32r/lib/getuser.S 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/m32r/lib/getuser.S 1970-01-01 02:00:00.000000000 +0200
+@@ -1,88 +0,0 @@
+-/*
+- * __get_user functions.
+- *
+- * (C) Copyright 2001 Hirokazu Takata
+- *
+- * These functions have a non-standard call interface
+- * to make them more efficient, especially as they
+- * return an error value in addition to the "real"
+- * return value.
+- */
+-
+-#include <linux/config.h>
+-
+-/*
+- * __get_user_X
+- *
+- * Inputs: r0 contains the address
+- *
+- * Outputs: r0 is error code (0 or -EFAULT)
+- * r1 contains zero-extended value
+- *
+- * These functions should not modify any other registers,
+- * as they get called from within inline assembly.
+- */
+-
+-#ifdef CONFIG_ISA_DUAL_ISSUE
+-
+- .text
+- .balign 4
+- .globl __get_user_1
+-__get_user_1:
+-1: ldub r1, @r0 || ldi r0, #0
+- jmp r14
+-
+- .balign 4
+- .globl __get_user_2
+-__get_user_2:
+-2: lduh r1, @r0 || ldi r0, #0
+- jmp r14
+-
+- .balign 4
+- .globl __get_user_4
+-__get_user_4:
+-3: ld r1, @r0 || ldi r0, #0
+- jmp r14
+-
+-bad_get_user:
+- ldi r1, #0 || ldi r0, #-14
+- jmp r14
+-
+-#else /* not CONFIG_ISA_DUAL_ISSUE */
+-
+- .text
+- .balign 4
+- .globl __get_user_1
+-__get_user_1:
+-1: ldub r1, @r0
+- ldi r0, #0
+- jmp r14
+-
+- .balign 4
+- .globl __get_user_2
+-__get_user_2:
+-2: lduh r1, @r0
+- ldi r0, #0
+- jmp r14
+-
+- .balign 4
+- .globl __get_user_4
+-__get_user_4:
+-3: ld r1, @r0
+- ldi r0, #0
+- jmp r14
+-
+-bad_get_user:
+- ldi r1, #0
+- ldi r0, #-14
+- jmp r14
+-
+-#endif /* not CONFIG_ISA_DUAL_ISSUE */
+-
+-.section __ex_table,"a"
+- .long 1b,bad_get_user
+- .long 2b,bad_get_user
+- .long 3b,bad_get_user
+-.previous
+-
+- .end
+diff -Naur linux-2.6.16/arch/m32r/lib/Makefile linux-2.6.16.16/arch/m32r/lib/Makefile
+--- linux-2.6.16/arch/m32r/lib/Makefile 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/m32r/lib/Makefile 2006-05-11 04:56:24.000000000 +0300
+@@ -2,6 +2,6 @@
+ # Makefile for M32R-specific library files..
+ #
+
+-lib-y := checksum.o ashxdi3.o memset.o memcpy.o getuser.o \
+- putuser.o delay.o strlen.o usercopy.o csum_partial_copy.o
++lib-y := checksum.o ashxdi3.o memset.o memcpy.o \
++ delay.o strlen.o usercopy.o csum_partial_copy.o
+
+diff -Naur linux-2.6.16/arch/m32r/lib/putuser.S linux-2.6.16.16/arch/m32r/lib/putuser.S
+--- linux-2.6.16/arch/m32r/lib/putuser.S 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/m32r/lib/putuser.S 1970-01-01 02:00:00.000000000 +0200
+@@ -1,84 +0,0 @@
+-/*
+- * __put_user functions.
+- *
+- * (C) Copyright 1998 Linus Torvalds
+- * (C) Copyright 2001 Hirokazu Takata
+- *
+- * These functions have a non-standard call interface
+- * to make them more efficient.
+- */
+-
+-#include <linux/config.h>
+-
+-/*
+- * __put_user_X
+- *
+- * Inputs: r0 contains the address
+- * r1 contains the value
+- *
+- * Outputs: r0 is error code (0 or -EFAULT)
+- * r1 is corrupted (will contain "current_task").
+- *
+- * These functions should not modify any other registers,
+- * as they get called from within inline assembly.
+- */
+-
+-#ifdef CONFIG_ISA_DUAL_ISSUE
+-
+- .text
+- .balign 4
+- .globl __put_user_1
+-__put_user_1:
+-1: stb r1, @r0 || ldi r0, #0
+- jmp r14
+-
+- .balign 4
+- .globl __put_user_2
+-__put_user_2:
+-2: sth r1, @r0 || ldi r0, #0
+- jmp r14
+-
+- .balign 4
+- .globl __put_user_4
+-__put_user_4:
+-3: st r1, @r0 || ldi r0, #0
+- jmp r14
+-
+-bad_put_user:
+- ldi r0, #-14 || jmp r14
+-
+-#else /* not CONFIG_ISA_DUAL_ISSUE */
+-
+- .text
+- .balign 4
+- .globl __put_user_1
+-__put_user_1:
+-1: stb r1, @r0
+- ldi r0, #0
+- jmp r14
+-
+- .balign 4
+- .globl __put_user_2
+-__put_user_2:
+-2: sth r1, @r0
+- ldi r0, #0
+- jmp r14
+-
+- .balign 4
+- .globl __put_user_4
+-__put_user_4:
+-3: st r1, @r0
+- ldi r0, #0
+- jmp r14
+-
+-bad_put_user:
+- ldi r0, #-14
+- jmp r14
+-
+-#endif /* not CONFIG_ISA_DUAL_ISSUE */
+-
+-.section __ex_table,"a"
+- .long 1b,bad_put_user
+- .long 2b,bad_put_user
+- .long 3b,bad_put_user
+-.previous
+diff -Naur linux-2.6.16/arch/mips/kernel/branch.c linux-2.6.16.16/arch/mips/kernel/branch.c
+--- linux-2.6.16/arch/mips/kernel/branch.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/mips/kernel/branch.c 2006-05-11 04:56:24.000000000 +0300
+@@ -184,7 +184,7 @@
+ bit = (insn.i_format.rt >> 2);
+ bit += (bit != 0);
+ bit += 23;
+- switch (insn.i_format.rt) {
++ switch (insn.i_format.rt & 3) {
+ case 0: /* bc1f */
+ case 2: /* bc1fl */
+ if (~fcr31 & (1 << bit))
+diff -Naur linux-2.6.16/arch/mips/mm/c-r4k.c linux-2.6.16.16/arch/mips/mm/c-r4k.c
+--- linux-2.6.16/arch/mips/mm/c-r4k.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/mips/mm/c-r4k.c 2006-05-11 04:56:24.000000000 +0300
+@@ -154,7 +154,8 @@
+
+ static inline void tx49_blast_icache32_page_indexed(unsigned long page)
+ {
+- unsigned long start = page;
++ unsigned long indexmask = current_cpu_data.icache.waysize - 1;
++ unsigned long start = INDEX_BASE + (page & indexmask);
+ unsigned long end = start + PAGE_SIZE;
+ unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
+ unsigned long ws_end = current_cpu_data.icache.ways <<
+diff -Naur linux-2.6.16/arch/powerpc/kernel/pci_64.c linux-2.6.16.16/arch/powerpc/kernel/pci_64.c
+--- linux-2.6.16/arch/powerpc/kernel/pci_64.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/powerpc/kernel/pci_64.c 2006-05-11 04:56:24.000000000 +0300
+@@ -78,6 +78,7 @@
+
+ /* Cached ISA bridge dev. */
+ struct pci_dev *ppc64_isabridge_dev = NULL;
++EXPORT_SYMBOL_GPL(ppc64_isabridge_dev);
+
+ static void fixup_broken_pcnet32(struct pci_dev* dev)
+ {
+diff -Naur linux-2.6.16/arch/powerpc/kernel/setup_64.c linux-2.6.16.16/arch/powerpc/kernel/setup_64.c
+--- linux-2.6.16/arch/powerpc/kernel/setup_64.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/powerpc/kernel/setup_64.c 2006-05-11 04:56:24.000000000 +0300
+@@ -256,12 +256,10 @@
+ /*
+ * Initialize stab / SLB management except on iSeries
+ */
+- if (!firmware_has_feature(FW_FEATURE_ISERIES)) {
+- if (cpu_has_feature(CPU_FTR_SLB))
+- slb_initialize();
+- else
+- stab_initialize(lpaca->stab_real);
+- }
++ if (cpu_has_feature(CPU_FTR_SLB))
++ slb_initialize();
++ else if (!firmware_has_feature(FW_FEATURE_ISERIES))
++ stab_initialize(lpaca->stab_real);
+
+ DBG(" <- early_setup()\n");
+ }
+diff -Naur linux-2.6.16/arch/powerpc/kernel/signal_64.c linux-2.6.16.16/arch/powerpc/kernel/signal_64.c
+--- linux-2.6.16/arch/powerpc/kernel/signal_64.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/powerpc/kernel/signal_64.c 2006-05-11 04:56:24.000000000 +0300
+@@ -213,7 +213,7 @@
+ /* Default to using normal stack */
+ newsp = regs->gpr[1];
+
+- if (ka->sa.sa_flags & SA_ONSTACK) {
++ if ((ka->sa.sa_flags & SA_ONSTACK) && current->sas_ss_size) {
+ if (! on_sig_stack(regs->gpr[1]))
+ newsp = (current->sas_ss_sp + current->sas_ss_size);
+ }
+diff -Naur linux-2.6.16/arch/x86_64/ia32/Makefile linux-2.6.16.16/arch/x86_64/ia32/Makefile
+--- linux-2.6.16/arch/x86_64/ia32/Makefile 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/x86_64/ia32/Makefile 2006-05-11 04:56:24.000000000 +0300
+@@ -27,5 +27,5 @@
+ $(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
+ $(call if_changed,syscall)
+
+-AFLAGS_vsyscall-sysenter.o = -m32
+-AFLAGS_vsyscall-syscall.o = -m32
++AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32
++AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32
+diff -Naur linux-2.6.16/arch/x86_64/kernel/entry.S linux-2.6.16.16/arch/x86_64/kernel/entry.S
+--- linux-2.6.16/arch/x86_64/kernel/entry.S 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/x86_64/kernel/entry.S 2006-05-11 04:56:24.000000000 +0300
+@@ -180,6 +180,10 @@
+ *
+ * XXX if we had a free scratch register we could save the RSP into the stack frame
+ * and report it properly in ps. Unfortunately we haven't.
++ *
++ * When user can change the frames always force IRET. That is because
++ * it deals with uncanonical addresses better. SYSRET has trouble
++ * with them due to bugs in both AMD and Intel CPUs.
+ */
+
+ ENTRY(system_call)
+@@ -254,7 +258,10 @@
+ xorl %esi,%esi # oldset -> arg2
+ call ptregscall_common
+ 1: movl $_TIF_NEED_RESCHED,%edi
+- jmp sysret_check
++ /* Use IRET because user could have changed frame. This
++ works because ptregscall_common has called FIXUP_TOP_OF_STACK. */
++ cli
++ jmp int_with_check
+
+ badsys:
+ movq $-ENOSYS,RAX-ARGOFFSET(%rsp)
+@@ -280,7 +287,8 @@
+ call syscall_trace_leave
+ RESTORE_TOP_OF_STACK %rbx
+ RESTORE_REST
+- jmp ret_from_sys_call
++ /* Use IRET because user could have changed frame */
++ jmp int_ret_from_sys_call
+ CFI_ENDPROC
+
+ /*
+@@ -408,25 +416,9 @@
+ CFI_ADJUST_CFA_OFFSET -8
+ CFI_REGISTER rip, r11
+ SAVE_REST
+- movq %r11, %r15
+- CFI_REGISTER rip, r15
+ FIXUP_TOP_OF_STACK %r11
+ call sys_execve
+- GET_THREAD_INFO(%rcx)
+- bt $TIF_IA32,threadinfo_flags(%rcx)
+- CFI_REMEMBER_STATE
+- jc exec_32bit
+ RESTORE_TOP_OF_STACK %r11
+- movq %r15, %r11
+- CFI_REGISTER rip, r11
+- RESTORE_REST
+- pushq %r11
+- CFI_ADJUST_CFA_OFFSET 8
+- CFI_REL_OFFSET rip, 0
+- ret
+-
+-exec_32bit:
+- CFI_RESTORE_STATE
+ movq %rax,RAX(%rsp)
+ RESTORE_REST
+ jmp int_ret_from_sys_call
+diff -Naur linux-2.6.16/arch/x86_64/kernel/pci-gart.c linux-2.6.16.16/arch/x86_64/kernel/pci-gart.c
+--- linux-2.6.16/arch/x86_64/kernel/pci-gart.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/x86_64/kernel/pci-gart.c 2006-05-11 04:56:24.000000000 +0300
+@@ -114,10 +114,6 @@
+ static void free_iommu(unsigned long offset, int size)
+ {
+ unsigned long flags;
+- if (size == 1) {
+- clear_bit(offset, iommu_gart_bitmap);
+- return;
+- }
+ spin_lock_irqsave(&iommu_bitmap_lock, flags);
+ __clear_bit_string(iommu_gart_bitmap, offset, size);
+ spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
+diff -Naur linux-2.6.16/arch/x86_64/kernel/process.c linux-2.6.16.16/arch/x86_64/kernel/process.c
+--- linux-2.6.16/arch/x86_64/kernel/process.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/x86_64/kernel/process.c 2006-05-11 04:56:24.000000000 +0300
+@@ -527,8 +527,6 @@
+ int cpu = smp_processor_id();
+ struct tss_struct *tss = &per_cpu(init_tss, cpu);
+
+- unlazy_fpu(prev_p);
+-
+ /*
+ * Reload esp0, LDT and the page table pointer:
+ */
+@@ -591,6 +589,12 @@
+ prev->userrsp = read_pda(oldrsp);
+ write_pda(oldrsp, next->userrsp);
+ write_pda(pcurrent, next_p);
++
++ /* This must be here to ensure both math_state_restore() and
++ kernel_fpu_begin() work consistently.
++ And the AMD workaround requires it to be after DS reload. */
++ unlazy_fpu(prev_p);
++
+ write_pda(kernelstack,
+ task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
+
+diff -Naur linux-2.6.16/arch/x86_64/kernel/setup.c linux-2.6.16.16/arch/x86_64/kernel/setup.c
+--- linux-2.6.16/arch/x86_64/kernel/setup.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/arch/x86_64/kernel/setup.c 2006-05-11 04:56:24.000000000 +0300
+@@ -909,6 +909,10 @@
+ if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58))
+ set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
+
++ /* Enable workaround for FXSAVE leak */
++ if (c->x86 >= 6)
++ set_bit(X86_FEATURE_FXSAVE_LEAK, &c->x86_capability);
++
+ r = get_model_name(c);
+ if (!r) {
+ switch (c->x86) {
+diff -Naur linux-2.6.16/block/genhd.c linux-2.6.16.16/block/genhd.c
+--- linux-2.6.16/block/genhd.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/block/genhd.c 2006-05-11 04:56:24.000000000 +0300
+@@ -16,8 +16,6 @@
+ #include <linux/kobj_map.h>
+ #include <linux/buffer_head.h>
+
+-#define MAX_PROBE_HASH 255 /* random */
+-
+ static struct subsystem block_subsys;
+
+ static DECLARE_MUTEX(block_subsys_sem);
+@@ -30,108 +28,29 @@
+ struct blk_major_name *next;
+ int major;
+ char name[16];
+-} *major_names[MAX_PROBE_HASH];
++} *major_names[BLKDEV_MAJOR_HASH_SIZE];
+
+ /* index in the above - for now: assume no multimajor ranges */
+ static inline int major_to_index(int major)
+ {
+- return major % MAX_PROBE_HASH;
+-}
+-
+-struct blkdev_info {
+- int index;
+- struct blk_major_name *bd;
+-};
+-
+-/*
+- * iterate over a list of blkdev_info structures. allows
+- * the major_names array to be iterated over from outside this file
+- * must be called with the block_subsys_sem held
+- */
+-void *get_next_blkdev(void *dev)
+-{
+- struct blkdev_info *info;
+-
+- if (dev == NULL) {
+- info = kmalloc(sizeof(*info), GFP_KERNEL);
+- if (!info)
+- goto out;
+- info->index=0;
+- info->bd = major_names[info->index];
+- if (info->bd)
+- goto out;
+- } else {
+- info = dev;
+- }
+-
+- while (info->index < ARRAY_SIZE(major_names)) {
+- if (info->bd)
+- info->bd = info->bd->next;
+- if (info->bd)
+- goto out;
+- /*
+- * No devices on this chain, move to the next
+- */
+- info->index++;
+- info->bd = (info->index < ARRAY_SIZE(major_names)) ?
+- major_names[info->index] : NULL;
+- if (info->bd)
+- goto out;
+- }
+-
+-out:
+- return info;
+-}
+-
+-void *acquire_blkdev_list(void)
+-{
+- down(&block_subsys_sem);
+- return get_next_blkdev(NULL);
+-}
+-
+-void release_blkdev_list(void *dev)
+-{
+- up(&block_subsys_sem);
+- kfree(dev);
++ return major % BLKDEV_MAJOR_HASH_SIZE;
+ }
+
++#ifdef CONFIG_PROC_FS
+
+-/*
+- * Count the number of records in the blkdev_list.
+- * must be called with the block_subsys_sem held
+- */
+-int count_blkdev_list(void)
++void blkdev_show(struct seq_file *f, off_t offset)
+ {
+- struct blk_major_name *n;
+- int i, count;
+-
+- count = 0;
++ struct blk_major_name *dp;
+
+- for (i = 0; i < ARRAY_SIZE(major_names); i++) {
+- for (n = major_names[i]; n; n = n->next)
+- count++;
++ if (offset < BLKDEV_MAJOR_HASH_SIZE) {
++ down(&block_subsys_sem);
++ for (dp = major_names[offset]; dp; dp = dp->next)
++ seq_printf(f, "%3d %s\n", dp->major, dp->name);
++ up(&block_subsys_sem);
+ }
+-
+- return count;
+-}
+-
+-/*
+- * extract the major and name values from a blkdev_info struct
+- * passed in as a void to *dev. Must be called with
+- * block_subsys_sem held
+- */
+-int get_blkdev_info(void *dev, int *major, char **name)
+-{
+- struct blkdev_info *info = dev;
+-
+- if (info->bd == NULL)
+- return 1;
+-
+- *major = info->bd->major;
+- *name = info->bd->name;
+- return 0;
+ }
+
++#endif /* CONFIG_PROC_FS */
+
+ int register_blkdev(unsigned int major, const char *name)
+ {
+diff -Naur linux-2.6.16/Documentation/dvb/get_dvb_firmware linux-2.6.16.16/Documentation/dvb/get_dvb_firmware
+--- linux-2.6.16/Documentation/dvb/get_dvb_firmware 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/Documentation/dvb/get_dvb_firmware 2006-05-11 04:56:24.000000000 +0300
+@@ -240,9 +240,9 @@
+ }
+
+ sub nxt2002 {
+- my $sourcefile = "Broadband4PC_4_2_11.zip";
++ my $sourcefile = "Technisat_DVB-PC_4_4_COMPACT.zip";
+ my $url = "http://www.bbti.us/download/windows/$sourcefile";
+- my $hash = "c6d2ea47a8f456d887ada0cfb718ff2a";
++ my $hash = "476befae8c7c1bb9648954060b1eec1f";
+ my $outfile = "dvb-fe-nxt2002.fw";
+ my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
+
+@@ -250,8 +250,8 @@
+
+ wgetfile($sourcefile, $url);
+ unzip($sourcefile, $tmpdir);
+- verify("$tmpdir/SkyNETU.sys", $hash);
+- extract("$tmpdir/SkyNETU.sys", 375832, 5908, $outfile);
++ verify("$tmpdir/SkyNET.sys", $hash);
++ extract("$tmpdir/SkyNET.sys", 331624, 5908, $outfile);
+
+ $outfile;
+ }
+diff -Naur linux-2.6.16/drivers/base/cpu.c linux-2.6.16.16/drivers/base/cpu.c
+--- linux-2.6.16/drivers/base/cpu.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/base/cpu.c 2006-05-11 04:56:24.000000000 +0300
+@@ -141,7 +141,7 @@
+ return error;
+ }
+
+-struct sys_device *get_cpu_sysdev(int cpu)
++struct sys_device *get_cpu_sysdev(unsigned cpu)
+ {
+ if (cpu < NR_CPUS)
+ return cpu_sys_devices[cpu];
+diff -Naur linux-2.6.16/drivers/base/firmware_class.c linux-2.6.16.16/drivers/base/firmware_class.c
+--- linux-2.6.16/drivers/base/firmware_class.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/base/firmware_class.c 2006-05-11 04:56:24.000000000 +0300
+@@ -211,18 +211,20 @@
+ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
+ {
+ u8 *new_data;
++ int new_size = fw_priv->alloc_size;
+
+ if (min_size <= fw_priv->alloc_size)
+ return 0;
+
+- new_data = vmalloc(fw_priv->alloc_size + PAGE_SIZE);
++ new_size = ALIGN(min_size, PAGE_SIZE);
++ new_data = vmalloc(new_size);
+ if (!new_data) {
+ printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__);
+ /* Make sure that we don't keep incomplete data */
+ fw_load_abort(fw_priv);
+ return -ENOMEM;
+ }
+- fw_priv->alloc_size += PAGE_SIZE;
++ fw_priv->alloc_size = new_size;
+ if (fw_priv->fw->data) {
+ memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size);
+ vfree(fw_priv->fw->data);
+diff -Naur linux-2.6.16/drivers/base/node.c linux-2.6.16.16/drivers/base/node.c
+--- linux-2.6.16/drivers/base/node.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/base/node.c 2006-05-11 04:56:24.000000000 +0300
+@@ -106,7 +106,7 @@
+ other_node = 0;
+ for (i = 0; i < MAX_NR_ZONES; i++) {
+ struct zone *z = &pg->node_zones[i];
+- for (cpu = 0; cpu < NR_CPUS; cpu++) {
++ for_each_online_cpu(cpu) {
+ struct per_cpu_pageset *ps = zone_pcp(z,cpu);
+ numa_hit += ps->numa_hit;
+ numa_miss += ps->numa_miss;
+diff -Naur linux-2.6.16/drivers/block/cciss.c linux-2.6.16.16/drivers/block/cciss.c
+--- linux-2.6.16/drivers/block/cciss.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/block/cciss.c 2006-05-11 04:56:24.000000000 +0300
+@@ -1181,6 +1181,53 @@
+ return 0;
+ }
+
++static inline void complete_buffers(struct bio *bio, int status)
++{
++ while (bio) {
++ struct bio *xbh = bio->bi_next;
++ int nr_sectors = bio_sectors(bio);
++
++ bio->bi_next = NULL;
++ blk_finished_io(len);
++ bio_endio(bio, nr_sectors << 9, status ? 0 : -EIO);
++ bio = xbh;
++ }
++
++}
++
++static void cciss_softirq_done(struct request *rq)
++{
++ CommandList_struct *cmd = rq->completion_data;
++ ctlr_info_t *h = hba[cmd->ctlr];
++ unsigned long flags;
++ u64bit temp64;
++ int i, ddir;
++
++ if (cmd->Request.Type.Direction == XFER_READ)
++ ddir = PCI_DMA_FROMDEVICE;
++ else
++ ddir = PCI_DMA_TODEVICE;
++
++ /* command did not need to be retried */
++ /* unmap the DMA mapping for all the scatter gather elements */
++ for(i=0; i<cmd->Header.SGList; i++) {
++ temp64.val32.lower = cmd->SG[i].Addr.lower;
++ temp64.val32.upper = cmd->SG[i].Addr.upper;
++ pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir);
++ }
++
++ complete_buffers(rq->bio, rq->errors);
++
++#ifdef CCISS_DEBUG
++ printk("Done with %p\n", rq);
++#endif /* CCISS_DEBUG */
++
++ spin_lock_irqsave(&h->lock, flags);
++ end_that_request_last(rq, rq->errors);
++ cmd_free(h, cmd,1);
++ spin_unlock_irqrestore(&h->lock, flags);
++}
++
+ /* This function will check the usage_count of the drive to be updated/added.
+ * If the usage_count is zero then the drive information will be updated and
+ * the disk will be re-registered with the kernel. If not then it will be
+@@ -1249,6 +1296,8 @@
+
+ blk_queue_max_sectors(disk->queue, 512);
+
++ blk_queue_softirq_done(disk->queue, cciss_softirq_done);
++
+ disk->queue->queuedata = hba[ctlr];
+
+ blk_queue_hardsect_size(disk->queue,
+@@ -2148,20 +2197,6 @@
+ addQ (&(h->cmpQ), c);
+ }
+ }
+-
+-static inline void complete_buffers(struct bio *bio, int status)
+-{
+- while (bio) {
+- struct bio *xbh = bio->bi_next;
+- int nr_sectors = bio_sectors(bio);
+-
+- bio->bi_next = NULL;
+- blk_finished_io(len);
+- bio_endio(bio, nr_sectors << 9, status ? 0 : -EIO);
+- bio = xbh;
+- }
+-
+-}
+ /* Assumes that CCISS_LOCK(h->ctlr) is held. */
+ /* Zeros out the error record and then resends the command back */
+ /* to the controller */
+@@ -2179,39 +2214,6 @@
+ start_io(h);
+ }
+
+-static void cciss_softirq_done(struct request *rq)
+-{
+- CommandList_struct *cmd = rq->completion_data;
+- ctlr_info_t *h = hba[cmd->ctlr];
+- unsigned long flags;
+- u64bit temp64;
+- int i, ddir;
+-
+- if (cmd->Request.Type.Direction == XFER_READ)
+- ddir = PCI_DMA_FROMDEVICE;
+- else
+- ddir = PCI_DMA_TODEVICE;
+-
+- /* command did not need to be retried */
+- /* unmap the DMA mapping for all the scatter gather elements */
+- for(i=0; i<cmd->Header.SGList; i++) {
+- temp64.val32.lower = cmd->SG[i].Addr.lower;
+- temp64.val32.upper = cmd->SG[i].Addr.upper;
+- pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir);
+- }
+-
+- complete_buffers(rq->bio, rq->errors);
+-
+-#ifdef CCISS_DEBUG
+- printk("Done with %p\n", rq);
+-#endif /* CCISS_DEBUG */
+-
+- spin_lock_irqsave(&h->lock, flags);
+- end_that_request_last(rq, rq->errors);
+- cmd_free(h, cmd,1);
+- spin_unlock_irqrestore(&h->lock, flags);
+-}
+-
+ /* checks the status of the job and calls complete buffers to mark all
+ * buffers for the completed job. Note that this function does not need
+ * to hold the hba/queue lock.
+@@ -3269,8 +3271,8 @@
+ unregister_blkdev(hba[i]->major, hba[i]->devname);
+ clean1:
+ release_io_mem(hba[i]);
+- free_hba(i);
+ hba[i]->busy_initializing = 0;
++ free_hba(i);
+ return(-1);
+ }
+
+diff -Naur linux-2.6.16/drivers/char/agp/efficeon-agp.c linux-2.6.16.16/drivers/char/agp/efficeon-agp.c
+--- linux-2.6.16/drivers/char/agp/efficeon-agp.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/char/agp/efficeon-agp.c 2006-05-11 04:56:24.000000000 +0300
+@@ -64,6 +64,12 @@
+ {.mask = 0x00000001, .type = 0}
+ };
+
++/* This function does the same thing as mask_memory() for this chipset... */
++static inline unsigned long efficeon_mask_memory(unsigned long addr)
++{
++ return addr | 0x00000001;
++}
++
+ static struct aper_size_info_lvl2 efficeon_generic_sizes[4] =
+ {
+ {256, 65536, 0},
+@@ -251,7 +257,7 @@
+ last_page = NULL;
+ for (i = 0; i < count; i++) {
+ int index = pg_start + i;
+- unsigned long insert = mem->memory[i];
++ unsigned long insert = efficeon_mask_memory(mem->memory[i]);
+
+ page = (unsigned int *) efficeon_private.l1_table[index >> 10];
+
+diff -Naur linux-2.6.16/drivers/char/cs5535_gpio.c linux-2.6.16.16/drivers/char/cs5535_gpio.c
+--- linux-2.6.16/drivers/char/cs5535_gpio.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/char/cs5535_gpio.c 2006-05-11 04:56:24.000000000 +0300
+@@ -241,9 +241,10 @@
+ static void __exit cs5535_gpio_cleanup(void)
+ {
+ dev_t dev_id = MKDEV(major, 0);
++
++ cdev_del(&cs5535_gpio_cdev);
+ unregister_chrdev_region(dev_id, CS5535_GPIO_COUNT);
+- if (gpio_base != 0)
+- release_region(gpio_base, CS5535_GPIO_SIZE);
++ release_region(gpio_base, CS5535_GPIO_SIZE);
+ }
+
+ module_init(cs5535_gpio_init);
+diff -Naur linux-2.6.16/drivers/char/ipmi/ipmi_bt_sm.c linux-2.6.16.16/drivers/char/ipmi/ipmi_bt_sm.c
+--- linux-2.6.16/drivers/char/ipmi/ipmi_bt_sm.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/char/ipmi/ipmi_bt_sm.c 2006-05-11 04:56:24.000000000 +0300
+@@ -165,7 +165,7 @@
+ {
+ unsigned int i;
+
+- if ((size < 2) || (size > IPMI_MAX_MSG_LENGTH))
++ if ((size < 2) || (size > (IPMI_MAX_MSG_LENGTH - 2)))
+ return -1;
+
+ if ((bt->state != BT_STATE_IDLE) && (bt->state != BT_STATE_HOSED))
+diff -Naur linux-2.6.16/drivers/char/Kconfig linux-2.6.16.16/drivers/char/Kconfig
+--- linux-2.6.16/drivers/char/Kconfig 2006-05-18 01:12:22.000000000 +0300
++++ linux-2.6.16.16/drivers/char/Kconfig 2006-05-17 21:41:29.000000000 +0300
+@@ -187,6 +187,7 @@
+ config ISI
+ tristate "Multi-Tech multiport card support (EXPERIMENTAL)"
+ depends on SERIAL_NONSTANDARD
++ select FW_LOADER
+ help
+ This is a driver for the Multi-Tech cards which provide several
+ serial ports. The driver is experimental and can currently only be
+diff -Naur linux-2.6.16/drivers/char/snsc.c linux-2.6.16.16/drivers/char/snsc.c
+--- linux-2.6.16/drivers/char/snsc.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/char/snsc.c 2006-05-11 04:56:24.000000000 +0300
+@@ -391,7 +391,8 @@
+ format_module_id(devnamep, geo_module(geoid),
+ MODULE_FORMAT_BRIEF);
+ devnamep = devname + strlen(devname);
+- sprintf(devnamep, "#%d", geo_slab(geoid));
++ sprintf(devnamep, "^%d#%d", geo_slot(geoid),
++ geo_slab(geoid));
+
+ /* allocate sysctl device data */
+ scd = kmalloc(sizeof (struct sysctl_data_s),
+diff -Naur linux-2.6.16/drivers/char/sonypi.c linux-2.6.16.16/drivers/char/sonypi.c
+--- linux-2.6.16/drivers/char/sonypi.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/char/sonypi.c 2006-05-11 04:56:24.000000000 +0300
+@@ -1341,6 +1341,9 @@
+ else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_ICH6_1, NULL)))
+ sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3;
++ else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
++ PCI_DEVICE_ID_INTEL_ICH7_1, NULL)))
++ sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3;
+ else
+ sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2;
+
+diff -Naur linux-2.6.16/drivers/char/tipar.c linux-2.6.16.16/drivers/char/tipar.c
+--- linux-2.6.16/drivers/char/tipar.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/char/tipar.c 2006-05-11 04:56:24.000000000 +0300
+@@ -515,7 +515,7 @@
+ err = PTR_ERR(tipar_class);
+ goto out_chrdev;
+ }
+- if (parport_register_driver(&tipar_driver) || tp_count == 0) {
++ if (parport_register_driver(&tipar_driver)) {
+ printk(KERN_ERR "tipar: unable to register with parport\n");
+ err = -EIO;
+ goto out_class;
+diff -Naur linux-2.6.16/drivers/char/tlclk.c linux-2.6.16.16/drivers/char/tlclk.c
+--- linux-2.6.16/drivers/char/tlclk.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/char/tlclk.c 2006-05-11 04:56:24.000000000 +0300
+@@ -327,7 +327,7 @@
+ return strnlen(buf, count);
+ }
+
+-static DEVICE_ATTR(received_ref_clk3a, S_IWUGO, NULL,
++static DEVICE_ATTR(received_ref_clk3a, (S_IWUSR|S_IWGRP), NULL,
+ store_received_ref_clk3a);
+
+
+@@ -349,7 +349,7 @@
+ return strnlen(buf, count);
+ }
+
+-static DEVICE_ATTR(received_ref_clk3b, S_IWUGO, NULL,
++static DEVICE_ATTR(received_ref_clk3b, (S_IWUSR|S_IWGRP), NULL,
+ store_received_ref_clk3b);
+
+
+@@ -371,7 +371,7 @@
+ return strnlen(buf, count);
+ }
+
+-static DEVICE_ATTR(enable_clk3b_output, S_IWUGO, NULL,
++static DEVICE_ATTR(enable_clk3b_output, (S_IWUSR|S_IWGRP), NULL,
+ store_enable_clk3b_output);
+
+ static ssize_t store_enable_clk3a_output(struct device *d,
+@@ -392,7 +392,7 @@
+ return strnlen(buf, count);
+ }
+
+-static DEVICE_ATTR(enable_clk3a_output, S_IWUGO, NULL,
++static DEVICE_ATTR(enable_clk3a_output, (S_IWUSR|S_IWGRP), NULL,
+ store_enable_clk3a_output);
+
+ static ssize_t store_enable_clkb1_output(struct device *d,
+@@ -413,7 +413,7 @@
+ return strnlen(buf, count);
+ }
+
+-static DEVICE_ATTR(enable_clkb1_output, S_IWUGO, NULL,
++static DEVICE_ATTR(enable_clkb1_output, (S_IWUSR|S_IWGRP), NULL,
+ store_enable_clkb1_output);
+
+
+@@ -435,7 +435,7 @@
+ return strnlen(buf, count);
+ }
+
+-static DEVICE_ATTR(enable_clka1_output, S_IWUGO, NULL,
++static DEVICE_ATTR(enable_clka1_output, (S_IWUSR|S_IWGRP), NULL,
+ store_enable_clka1_output);
+
+ static ssize_t store_enable_clkb0_output(struct device *d,
+@@ -456,7 +456,7 @@
+ return strnlen(buf, count);
+ }
+
+-static DEVICE_ATTR(enable_clkb0_output, S_IWUGO, NULL,
++static DEVICE_ATTR(enable_clkb0_output, (S_IWUSR|S_IWGRP), NULL,
+ store_enable_clkb0_output);
+
+ static ssize_t store_enable_clka0_output(struct device *d,
+@@ -477,7 +477,7 @@
+ return strnlen(buf, count);
+ }
+
+-static DEVICE_ATTR(enable_clka0_output, S_IWUGO, NULL,
++static DEVICE_ATTR(enable_clka0_output, (S_IWUSR|S_IWGRP), NULL,
+ store_enable_clka0_output);
+
+ static ssize_t store_select_amcb2_transmit_clock(struct device *d,
+@@ -519,7 +519,7 @@
+ return strnlen(buf, count);
+ }
+
+-static DEVICE_ATTR(select_amcb2_transmit_clock, S_IWUGO, NULL,
++static DEVICE_ATTR(select_amcb2_transmit_clock, (S_IWUSR|S_IWGRP), NULL,
+ store_select_amcb2_transmit_clock);
+
+ static ssize_t store_select_amcb1_transmit_clock(struct device *d,
+@@ -560,7 +560,7 @@
+ return strnlen(buf, count);
+ }
+
+-static DEVICE_ATTR(select_amcb1_transmit_clock, S_IWUGO, NULL,
++static DEVICE_ATTR(select_amcb1_transmit_clock, (S_IWUSR|S_IWGRP), NULL,
+ store_select_amcb1_transmit_clock);
+
+ static ssize_t store_select_redundant_clock(struct device *d,
+@@ -581,7 +581,7 @@
+ return strnlen(buf, count);
+ }
+
+-static DEVICE_ATTR(select_redundant_clock, S_IWUGO, NULL,
++static DEVICE_ATTR(select_redundant_clock, (S_IWUSR|S_IWGRP), NULL,
+ store_select_redundant_clock);
+
+ static ssize_t store_select_ref_frequency(struct device *d,
+@@ -602,7 +602,7 @@
+ return strnlen(buf, count);
+ }
+
+-static DEVICE_ATTR(select_ref_frequency, S_IWUGO, NULL,
++static DEVICE_ATTR(select_ref_frequency, (S_IWUSR|S_IWGRP), NULL,
+ store_select_ref_frequency);
+
+ static ssize_t store_filter_select(struct device *d,
+@@ -623,7 +623,7 @@
+ return strnlen(buf, count);
+ }
+
+-static DEVICE_ATTR(filter_select, S_IWUGO, NULL, store_filter_select);
++static DEVICE_ATTR(filter_select, (S_IWUSR|S_IWGRP), NULL, store_filter_select);
+
+ static ssize_t store_hardware_switching_mode(struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+@@ -643,7 +643,7 @@
+ return strnlen(buf, count);
+ }
+
+-static DEVICE_ATTR(hardware_switching_mode, S_IWUGO, NULL,
++static DEVICE_ATTR(hardware_switching_mode, (S_IWUSR|S_IWGRP), NULL,
+ store_hardware_switching_mode);
+
+ static ssize_t store_hardware_switching(struct device *d,
+@@ -664,7 +664,7 @@
+ return strnlen(buf, count);
+ }
+
+-static DEVICE_ATTR(hardware_switching, S_IWUGO, NULL,
++static DEVICE_ATTR(hardware_switching, (S_IWUSR|S_IWGRP), NULL,
+ store_hardware_switching);
+
+ static ssize_t store_refalign (struct device *d,
+@@ -684,7 +684,7 @@
+ return strnlen(buf, count);
+ }
+
+-static DEVICE_ATTR(refalign, S_IWUGO, NULL, store_refalign);
++static DEVICE_ATTR(refalign, (S_IWUSR|S_IWGRP), NULL, store_refalign);
+
+ static ssize_t store_mode_select (struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+@@ -704,7 +704,7 @@
+ return strnlen(buf, count);
+ }
+
+-static DEVICE_ATTR(mode_select, S_IWUGO, NULL, store_mode_select);
++static DEVICE_ATTR(mode_select, (S_IWUSR|S_IWGRP), NULL, store_mode_select);
+
+ static ssize_t store_reset (struct device *d,
+ struct device_attribute *attr, const char *buf, size_t count)
+@@ -724,7 +724,7 @@
+ return strnlen(buf, count);
+ }
+
+-static DEVICE_ATTR(reset, S_IWUGO, NULL, store_reset);
++static DEVICE_ATTR(reset, (S_IWUSR|S_IWGRP), NULL, store_reset);
+
+ static struct attribute *tlclk_sysfs_entries[] = {
+ &dev_attr_current_ref.attr,
+@@ -767,6 +767,7 @@
+ printk(KERN_ERR "tlclk: can't get major %d.\n", tlclk_major);
+ return ret;
+ }
++ tlclk_major = ret;
+ alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL);
+ if (!alarm_events)
+ goto out1;
+diff -Naur linux-2.6.16/drivers/char/tty_io.c linux-2.6.16.16/drivers/char/tty_io.c
+--- linux-2.6.16/drivers/char/tty_io.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/char/tty_io.c 2006-05-11 04:56:24.000000000 +0300
+@@ -2706,7 +2706,11 @@
+ }
+ task_lock(p);
+ if (p->files) {
+- rcu_read_lock();
++ /*
++ * We don't take a ref to the file, so we must
++ * hold ->file_lock instead.
++ */
++ spin_lock(&p->files->file_lock);
+ fdt = files_fdtable(p->files);
+ for (i=0; i < fdt->max_fds; i++) {
+ filp = fcheck_files(p->files, i);
+@@ -2721,7 +2725,7 @@
+ break;
+ }
+ }
+- rcu_read_unlock();
++ spin_unlock(&p->files->file_lock);
+ }
+ task_unlock(p);
+ } while_each_task_pid(session, PIDTYPE_SID, p);
+diff -Naur linux-2.6.16/drivers/edac/Kconfig linux-2.6.16.16/drivers/edac/Kconfig
+--- linux-2.6.16/drivers/edac/Kconfig 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/edac/Kconfig 2006-05-11 04:56:24.000000000 +0300
+@@ -71,7 +71,7 @@
+
+ config EDAC_E752X
+ tristate "Intel e752x (e7520, e7525, e7320)"
+- depends on EDAC_MM_EDAC && PCI
++ depends on EDAC_MM_EDAC && PCI && HOTPLUG
+ help
+ Support for error detection and correction on the Intel
+ E7520, E7525, E7320 server chipsets.
+diff -Naur linux-2.6.16/drivers/i2c/busses/i2c-i801.c linux-2.6.16.16/drivers/i2c/busses/i2c-i801.c
+--- linux-2.6.16/drivers/i2c/busses/i2c-i801.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/i2c/busses/i2c-i801.c 2006-05-11 04:56:24.000000000 +0300
+@@ -478,6 +478,11 @@
+ ret = i801_transaction();
+ }
+
++ /* Some BIOSes don't like it when PEC is enabled at reboot or resume
++ time, so we forcibly disable it after every transaction. */
++ if (hwpec)
++ outb_p(0, SMBAUXCTL);
++
+ if(block)
+ return ret;
+ if(ret)
+diff -Naur linux-2.6.16/drivers/i2c/chips/m41t00.c linux-2.6.16.16/drivers/i2c/chips/m41t00.c
+--- linux-2.6.16/drivers/i2c/chips/m41t00.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/i2c/chips/m41t00.c 2006-05-11 04:56:24.000000000 +0300
+@@ -129,13 +129,13 @@
+ if ((i2c_smbus_write_byte_data(save_client, 0, tm.tm_sec & 0x7f) < 0)
+ || (i2c_smbus_write_byte_data(save_client, 1, tm.tm_min & 0x7f)
+ < 0)
+- || (i2c_smbus_write_byte_data(save_client, 2, tm.tm_hour & 0x7f)
++ || (i2c_smbus_write_byte_data(save_client, 2, tm.tm_hour & 0x3f)
+ < 0)
+- || (i2c_smbus_write_byte_data(save_client, 4, tm.tm_mday & 0x7f)
++ || (i2c_smbus_write_byte_data(save_client, 4, tm.tm_mday & 0x3f)
+ < 0)
+- || (i2c_smbus_write_byte_data(save_client, 5, tm.tm_mon & 0x7f)
++ || (i2c_smbus_write_byte_data(save_client, 5, tm.tm_mon & 0x1f)
+ < 0)
+- || (i2c_smbus_write_byte_data(save_client, 6, tm.tm_year & 0x7f)
++ || (i2c_smbus_write_byte_data(save_client, 6, tm.tm_year & 0xff)
+ < 0))
+
+ dev_warn(&save_client->dev,"m41t00: can't write to rtc chip\n");
+diff -Naur linux-2.6.16/drivers/ide/pci/alim15x3.c linux-2.6.16.16/drivers/ide/pci/alim15x3.c
+--- linux-2.6.16/drivers/ide/pci/alim15x3.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/ide/pci/alim15x3.c 2006-05-11 04:56:24.000000000 +0300
+@@ -731,6 +731,8 @@
+
+ if(m5229_revision <= 0x20)
+ tmpbyte = (tmpbyte & (~0x02)) | 0x01;
++ else if (m5229_revision == 0xc7)
++ tmpbyte |= 0x03;
+ else
+ tmpbyte |= 0x01;
+
+diff -Naur linux-2.6.16/drivers/ieee1394/sbp2.c linux-2.6.16.16/drivers/ieee1394/sbp2.c
+--- linux-2.6.16/drivers/ieee1394/sbp2.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/ieee1394/sbp2.c 2006-05-11 04:56:24.000000000 +0300
+@@ -495,22 +495,17 @@
+ /*
+ * This function finds the sbp2_command for a given outstanding SCpnt.
+ * Only looks at the inuse list.
++ * Must be called with scsi_id->sbp2_command_orb_lock held.
+ */
+-static struct sbp2_command_info *sbp2util_find_command_for_SCpnt(struct scsi_id_instance_data *scsi_id, void *SCpnt)
++static struct sbp2_command_info *sbp2util_find_command_for_SCpnt(
++ struct scsi_id_instance_data *scsi_id, void *SCpnt)
+ {
+ struct sbp2_command_info *command;
+- unsigned long flags;
+
+- spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags);
+- if (!list_empty(&scsi_id->sbp2_command_orb_inuse)) {
+- list_for_each_entry(command, &scsi_id->sbp2_command_orb_inuse, list) {
+- if (command->Current_SCpnt == SCpnt) {
+- spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
++ if (!list_empty(&scsi_id->sbp2_command_orb_inuse))
++ list_for_each_entry(command, &scsi_id->sbp2_command_orb_inuse, list)
++ if (command->Current_SCpnt == SCpnt)
+ return command;
+- }
+- }
+- }
+- spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
+ return NULL;
+ }
+
+@@ -579,17 +574,15 @@
+
+ /*
+ * This function moves a command to the completed orb list.
++ * Must be called with scsi_id->sbp2_command_orb_lock held.
+ */
+-static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_id,
+- struct sbp2_command_info *command)
++static void sbp2util_mark_command_completed(
++ struct scsi_id_instance_data *scsi_id,
++ struct sbp2_command_info *command)
+ {
+- unsigned long flags;
+-
+- spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags);
+ list_del(&command->list);
+ sbp2util_free_command_dma(command);
+ list_add_tail(&command->list, &scsi_id->sbp2_command_orb_completed);
+- spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
+ }
+
+ /*
+@@ -2177,7 +2170,9 @@
+ * Matched status with command, now grab scsi command pointers and check status
+ */
+ SCpnt = command->Current_SCpnt;
++ spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags);
+ sbp2util_mark_command_completed(scsi_id, command);
++ spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
+
+ if (SCpnt) {
+
+@@ -2513,6 +2508,7 @@
+ (struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0];
+ struct sbp2scsi_host_info *hi = scsi_id->hi;
+ struct sbp2_command_info *command;
++ unsigned long flags;
+
+ SBP2_ERR("aborting sbp2 command");
+ scsi_print_command(SCpnt);
+@@ -2523,6 +2519,7 @@
+ * Right now, just return any matching command structures
+ * to the free pool.
+ */
++ spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags);
+ command = sbp2util_find_command_for_SCpnt(scsi_id, SCpnt);
+ if (command) {
+ SBP2_DEBUG("Found command to abort");
+@@ -2540,6 +2537,7 @@
+ command->Current_done(command->Current_SCpnt);
+ }
+ }
++ spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
+
+ /*
+ * Initiate a fetch agent reset.
+diff -Naur linux-2.6.16/drivers/macintosh/therm_adt746x.c linux-2.6.16.16/drivers/macintosh/therm_adt746x.c
+--- linux-2.6.16/drivers/macintosh/therm_adt746x.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/macintosh/therm_adt746x.c 2006-05-11 04:56:24.000000000 +0300
+@@ -627,8 +627,8 @@
+ if(therm_type == ADT7460)
+ device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed);
+
+-#ifndef CONFIG_I2C_KEYWEST
+- request_module("i2c-keywest");
++#ifndef CONFIG_I2C_POWERMAC
++ request_module("i2c-powermac");
+ #endif
+
+ return i2c_add_driver(&thermostat_driver);
+diff -Naur linux-2.6.16/drivers/md/dm.c linux-2.6.16.16/drivers/md/dm.c
+--- linux-2.6.16/drivers/md/dm.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/md/dm.c 2006-05-11 04:56:24.000000000 +0300
+@@ -533,30 +533,35 @@
+
+ } else {
+ /*
+- * Create two copy bios to deal with io that has
+- * been split across a target.
++ * Handle a bvec that must be split between two or more targets.
+ */
+ struct bio_vec *bv = bio->bi_io_vec + ci->idx;
++ sector_t remaining = to_sector(bv->bv_len);
++ unsigned int offset = 0;
+
+- clone = split_bvec(bio, ci->sector, ci->idx,
+- bv->bv_offset, max);
+- __map_bio(ti, clone, tio);
+-
+- ci->sector += max;
+- ci->sector_count -= max;
+- ti = dm_table_find_target(ci->map, ci->sector);
+-
+- len = to_sector(bv->bv_len) - max;
+- clone = split_bvec(bio, ci->sector, ci->idx,
+- bv->bv_offset + to_bytes(max), len);
+- tio = alloc_tio(ci->md);
+- tio->io = ci->io;
+- tio->ti = ti;
+- memset(&tio->info, 0, sizeof(tio->info));
+- __map_bio(ti, clone, tio);
++ do {
++ if (offset) {
++ ti = dm_table_find_target(ci->map, ci->sector);
++ max = max_io_len(ci->md, ci->sector, ti);
++
++ tio = alloc_tio(ci->md);
++ tio->io = ci->io;
++ tio->ti = ti;
++ memset(&tio->info, 0, sizeof(tio->info));
++ }
++
++ len = min(remaining, max);
++
++ clone = split_bvec(bio, ci->sector, ci->idx,
++ bv->bv_offset + offset, len);
++
++ __map_bio(ti, clone, tio);
++
++ ci->sector += len;
++ ci->sector_count -= len;
++ offset += to_bytes(len);
++ } while (remaining -= len);
+
+- ci->sector += len;
+- ci->sector_count -= len;
+ ci->idx++;
+ }
+ }
+@@ -1093,6 +1098,7 @@
+ {
+ struct dm_table *map = NULL;
+ DECLARE_WAITQUEUE(wait, current);
++ struct bio *def;
+ int r = -EINVAL;
+
+ down(&md->suspend_lock);
+@@ -1152,9 +1158,11 @@
+ /* were we interrupted ? */
+ r = -EINTR;
+ if (atomic_read(&md->pending)) {
++ clear_bit(DMF_BLOCK_IO, &md->flags);
++ def = bio_list_get(&md->deferred);
++ __flush_deferred_io(md, def);
+ up_write(&md->io_lock);
+ unlock_fs(md);
+- clear_bit(DMF_BLOCK_IO, &md->flags);
+ goto out;
+ }
+ up_write(&md->io_lock);
+diff -Naur linux-2.6.16/drivers/md/dm-snap.c linux-2.6.16.16/drivers/md/dm-snap.c
+--- linux-2.6.16/drivers/md/dm-snap.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/md/dm-snap.c 2006-05-11 04:56:24.000000000 +0300
+@@ -542,8 +542,12 @@
+ {
+ struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
+
++ /* Prevent further origin writes from using this snapshot. */
++ /* After this returns there can be no new kcopyd jobs. */
+ unregister_snapshot(s);
+
++ kcopyd_client_destroy(s->kcopyd_client);
++
+ exit_exception_table(&s->pending, pending_cache);
+ exit_exception_table(&s->complete, exception_cache);
+
+@@ -552,7 +556,7 @@
+
+ dm_put_device(ti, s->origin);
+ dm_put_device(ti, s->cow);
+- kcopyd_client_destroy(s->kcopyd_client);
++
+ kfree(s);
+ }
+
+diff -Naur linux-2.6.16/drivers/md/kcopyd.c linux-2.6.16.16/drivers/md/kcopyd.c
+--- linux-2.6.16/drivers/md/kcopyd.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/md/kcopyd.c 2006-05-11 04:56:24.000000000 +0300
+@@ -44,6 +44,9 @@
+ struct page_list *pages;
+ unsigned int nr_pages;
+ unsigned int nr_free_pages;
++
++ wait_queue_head_t destroyq;
++ atomic_t nr_jobs;
+ };
+
+ static struct page_list *alloc_pl(void)
+@@ -293,10 +296,15 @@
+ int read_err = job->read_err;
+ unsigned int write_err = job->write_err;
+ kcopyd_notify_fn fn = job->fn;
++ struct kcopyd_client *kc = job->kc;
+
+- kcopyd_put_pages(job->kc, job->pages);
++ kcopyd_put_pages(kc, job->pages);
+ mempool_free(job, _job_pool);
+ fn(read_err, write_err, context);
++
++ if (atomic_dec_and_test(&kc->nr_jobs))
++ wake_up(&kc->destroyq);
++
+ return 0;
+ }
+
+@@ -431,6 +439,7 @@
+ */
+ static void dispatch_job(struct kcopyd_job *job)
+ {
++ atomic_inc(&job->kc->nr_jobs);
+ push(&_pages_jobs, job);
+ wake();
+ }
+@@ -670,6 +679,9 @@
+ return r;
+ }
+
++ init_waitqueue_head(&kc->destroyq);
++ atomic_set(&kc->nr_jobs, 0);
++
+ client_add(kc);
+ *result = kc;
+ return 0;
+@@ -677,6 +689,9 @@
+
+ void kcopyd_client_destroy(struct kcopyd_client *kc)
+ {
++ /* Wait for completion of all jobs submitted by this client. */
++ wait_event(kc->destroyq, !atomic_read(&kc->nr_jobs));
++
+ dm_io_put(kc->nr_pages);
+ client_free_pages(kc);
+ client_del(kc);
+diff -Naur linux-2.6.16/drivers/media/dvb/dvb-usb/cxusb.c linux-2.6.16.16/drivers/media/dvb/dvb-usb/cxusb.c
+--- linux-2.6.16/drivers/media/dvb/dvb-usb/cxusb.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/media/dvb/dvb-usb/cxusb.c 2006-05-11 04:56:24.000000000 +0300
+@@ -149,6 +149,15 @@
+ return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
+ }
+
++static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
++{
++ u8 b = 0;
++ if (onoff)
++ return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
++ else
++ return 0;
++}
++
+ static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+ {
+ u8 buf[2] = { 0x03, 0x00 };
+@@ -505,7 +514,7 @@
+ .size_of_priv = sizeof(struct cxusb_state),
+
+ .streaming_ctrl = cxusb_streaming_ctrl,
+- .power_ctrl = cxusb_power_ctrl,
++ .power_ctrl = cxusb_bluebird_power_ctrl,
+ .frontend_attach = cxusb_lgdt3303_frontend_attach,
+ .tuner_attach = cxusb_lgh064f_tuner_attach,
+
+@@ -545,7 +554,7 @@
+ .size_of_priv = sizeof(struct cxusb_state),
+
+ .streaming_ctrl = cxusb_streaming_ctrl,
+- .power_ctrl = cxusb_power_ctrl,
++ .power_ctrl = cxusb_bluebird_power_ctrl,
+ .frontend_attach = cxusb_dee1601_frontend_attach,
+ .tuner_attach = cxusb_dee1601_tuner_attach,
+
+@@ -594,7 +603,7 @@
+ .size_of_priv = sizeof(struct cxusb_state),
+
+ .streaming_ctrl = cxusb_streaming_ctrl,
+- .power_ctrl = cxusb_power_ctrl,
++ .power_ctrl = cxusb_bluebird_power_ctrl,
+ .frontend_attach = cxusb_mt352_frontend_attach,
+ .tuner_attach = cxusb_lgz201_tuner_attach,
+
+@@ -634,7 +643,7 @@
+ .size_of_priv = sizeof(struct cxusb_state),
+
+ .streaming_ctrl = cxusb_streaming_ctrl,
+- .power_ctrl = cxusb_power_ctrl,
++ .power_ctrl = cxusb_bluebird_power_ctrl,
+ .frontend_attach = cxusb_mt352_frontend_attach,
+ .tuner_attach = cxusb_dtt7579_tuner_attach,
+
+diff -Naur linux-2.6.16/drivers/media/video/Kconfig linux-2.6.16.16/drivers/media/video/Kconfig
+--- linux-2.6.16/drivers/media/video/Kconfig 2006-05-18 01:12:22.000000000 +0300
++++ linux-2.6.16.16/drivers/media/video/Kconfig 2006-05-17 21:41:30.000000000 +0300
+@@ -349,6 +349,7 @@
+ config VIDEO_DECODER
+ tristate "Add support for additional video chipsets"
+ depends on VIDEO_DEV && I2C && EXPERIMENTAL
++ select FW_LOADER
+ ---help---
+ Say Y here to compile drivers for SAA7115, SAA7127 and CX25840
+ video decoders.
+diff -Naur linux-2.6.16/drivers/media/video/saa7127.c linux-2.6.16.16/drivers/media/video/saa7127.c
+--- linux-2.6.16/drivers/media/video/saa7127.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/media/video/saa7127.c 2006-05-11 04:56:24.000000000 +0300
+@@ -141,6 +141,7 @@
+ static const struct i2c_reg_value saa7129_init_config_extra[] = {
+ { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x38 },
+ { SAA7127_REG_VTRIG, 0xfa },
++ { 0, 0 }
+ };
+
+ static const struct i2c_reg_value saa7127_init_config_common[] = {
+diff -Naur linux-2.6.16/drivers/media/video/tuner-types.c linux-2.6.16.16/drivers/media/video/tuner-types.c
+--- linux-2.6.16/drivers/media/video/tuner-types.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/media/video/tuner-types.c 2006-05-11 04:56:24.000000000 +0300
+@@ -1087,8 +1087,8 @@
+ /* ------------ TUNER_SAMSUNG_TCPN_2121P30A - Samsung NTSC ------------ */
+
+ static struct tuner_range tuner_samsung_tcpn_2121p30a_ntsc_ranges[] = {
+- { 16 * 175.75 /*MHz*/, 0x01, },
+- { 16 * 410.25 /*MHz*/, 0x02, },
++ { 16 * 130.00 /*MHz*/, 0x01, },
++ { 16 * 364.50 /*MHz*/, 0x02, },
+ { 16 * 999.99 , 0x08, },
+ };
+
+diff -Naur linux-2.6.16/drivers/mtd/nand/Kconfig linux-2.6.16.16/drivers/mtd/nand/Kconfig
+--- linux-2.6.16/drivers/mtd/nand/Kconfig 2006-05-18 01:12:23.000000000 +0300
++++ linux-2.6.16.16/drivers/mtd/nand/Kconfig 2006-05-17 22:32:57.000000000 +0300
+@@ -184,15 +184,14 @@
+ Even if you leave this disabled, you can enable BBT writes at module
+ load time (assuming you build diskonchip as a module) with the module
+ parameter "inftl_bbt_write=1".
+-
+- config MTD_NAND_SHARPSL
+- bool "Support for NAND Flash on Sharp SL Series (C7xx + others)"
+- depends on MTD_NAND && ARCH_PXA
+-
+- config MTD_NAND_NANDSIM
+- bool "Support for NAND Flash Simulator"
+- depends on MTD_NAND && MTD_PARTITIONS
+
++config MTD_NAND_SHARPSL
++ tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)"
++ depends on MTD_NAND && ARCH_PXA
++
++config MTD_NAND_NANDSIM
++ tristate "Support for NAND Flash Simulator"
++ depends on MTD_NAND && MTD_PARTITIONS
+ help
+ The simulator may simulate verious NAND flash chips for the
+ MTD nand layer.
+@@ -200,7 +199,6 @@
+ config MTD_NAND_OMAP_HW
+ bool "OMAP HW NAND Flash controller support"
+ depends on ARM && ARCH_OMAP16XX && MTD_NAND
+-
+ help
+ Driver for TI OMAP16xx hardware NAND flash controller.
+
+diff -Naur linux-2.6.16/drivers/net/e1000/e1000_main.c linux-2.6.16.16/drivers/net/e1000/e1000_main.c
+--- linux-2.6.16/drivers/net/e1000/e1000_main.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/net/e1000/e1000_main.c 2006-05-11 04:56:24.000000000 +0300
+@@ -3851,6 +3851,7 @@
+ skb_shinfo(skb)->nr_frags++;
+ skb->len += length;
+ skb->data_len += length;
++ skb->truesize += length;
+ }
+
+ e1000_rx_checksum(adapter, staterr,
+diff -Naur linux-2.6.16/drivers/net/irda/irda-usb.c linux-2.6.16.16/drivers/net/irda/irda-usb.c
+--- linux-2.6.16/drivers/net/irda/irda-usb.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/net/irda/irda-usb.c 2006-05-11 04:56:24.000000000 +0300
+@@ -740,7 +740,7 @@
+ struct sk_buff *newskb;
+ struct sk_buff *dataskb;
+ struct urb *next_urb;
+- int docopy;
++ unsigned int len, docopy;
+
+ IRDA_DEBUG(2, "%s(), len=%d\n", __FUNCTION__, urb->actual_length);
+
+@@ -851,10 +851,11 @@
+ dataskb->dev = self->netdev;
+ dataskb->mac.raw = dataskb->data;
+ dataskb->protocol = htons(ETH_P_IRDA);
++ len = dataskb->len;
+ netif_rx(dataskb);
+
+ /* Keep stats up to date */
+- self->stats.rx_bytes += dataskb->len;
++ self->stats.rx_bytes += len;
+ self->stats.rx_packets++;
+ self->netdev->last_rx = jiffies;
+
+diff -Naur linux-2.6.16/drivers/net/sky2.c linux-2.6.16.16/drivers/net/sky2.c
+--- linux-2.6.16/drivers/net/sky2.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/net/sky2.c 2006-05-11 04:56:24.000000000 +0300
+@@ -579,8 +579,8 @@
+ reg = gma_read16(hw, port, GM_PHY_ADDR);
+ gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR);
+
+- for (i = 0; i < GM_MIB_CNT_SIZE; i++)
+- gma_read16(hw, port, GM_MIB_CNT_BASE + 8 * i);
++ for (i = GM_MIB_CNT_BASE; i <= GM_MIB_CNT_END; i += 4)
++ gma_read16(hw, port, i);
+ gma_write16(hw, port, GM_PHY_ADDR, reg);
+
+ /* transmit control */
+diff -Naur linux-2.6.16/drivers/net/sky2.h linux-2.6.16.16/drivers/net/sky2.h
+--- linux-2.6.16/drivers/net/sky2.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/net/sky2.h 2006-05-11 04:56:24.000000000 +0300
+@@ -1380,6 +1380,7 @@
+ /* MIB Counters */
+ #define GM_MIB_CNT_BASE 0x0100 /* Base Address of MIB Counters */
+ #define GM_MIB_CNT_SIZE 44 /* Number of MIB Counters */
++#define GM_MIB_CNT_END 0x025C /* Last MIB counter */
+
+ /*
+ * MIB Counters base address definitions (low word) -
+diff -Naur linux-2.6.16/drivers/net/wireless/hostap/hostap_80211_tx.c linux-2.6.16.16/drivers/net/wireless/hostap/hostap_80211_tx.c
+--- linux-2.6.16/drivers/net/wireless/hostap/hostap_80211_tx.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/net/wireless/hostap/hostap_80211_tx.c 2006-05-11 04:56:24.000000000 +0300
+@@ -469,7 +469,7 @@
+ }
+
+ if (local->ieee_802_1x && meta->ethertype == ETH_P_PAE && tx.crypt &&
+- !(fc & IEEE80211_FCTL_VERS)) {
++ !(fc & IEEE80211_FCTL_PROTECTED)) {
+ no_encrypt = 1;
+ PDEBUG(DEBUG_EXTRA2, "%s: TX: IEEE 802.1X - passing "
+ "unencrypted EAPOL frame\n", dev->name);
+diff -Naur linux-2.6.16/drivers/net/wireless/ipw2200.c linux-2.6.16.16/drivers/net/wireless/ipw2200.c
+--- linux-2.6.16/drivers/net/wireless/ipw2200.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/net/wireless/ipw2200.c 2006-05-11 04:56:24.000000000 +0300
+@@ -9956,9 +9956,8 @@
+ return -EINVAL;
+ down(&p->sem);
+ memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len);
+- for (i = IPW_EEPROM_DATA;
+- i < IPW_EEPROM_DATA + IPW_EEPROM_IMAGE_SIZE; i++)
+- ipw_write8(p, i, p->eeprom[i]);
++ for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++)
++ ipw_write8(p, i + IPW_EEPROM_DATA, p->eeprom[i]);
+ up(&p->sem);
+ return 0;
+ }
+diff -Naur linux-2.6.16/drivers/net/wireless/Kconfig linux-2.6.16.16/drivers/net/wireless/Kconfig
+--- linux-2.6.16/drivers/net/wireless/Kconfig 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/net/wireless/Kconfig 2006-05-11 04:56:24.000000000 +0300
+@@ -239,7 +239,8 @@
+
+ config AIRO
+ tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
+- depends on NET_RADIO && ISA_DMA_API && CRYPTO && (PCI || BROKEN)
++ depends on NET_RADIO && ISA_DMA_API && (PCI || BROKEN)
++ select CRYPTO
+ ---help---
+ This is the standard Linux driver to support Cisco/Aironet ISA and
+ PCI 802.11 wireless cards.
+@@ -374,6 +375,7 @@
+ config PCMCIA_SPECTRUM
+ tristate "Symbol Spectrum24 Trilogy PCMCIA card support"
+ depends on NET_RADIO && PCMCIA && HERMES
++ select FW_LOADER
+ ---help---
+
+ This is a driver for 802.11b cards using RAM-loadable Symbol
+@@ -387,6 +389,7 @@
+ config AIRO_CS
+ tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards"
+ depends on NET_RADIO && PCMCIA && (BROKEN || !M32R)
++ select CRYPTO
+ ---help---
+ This is the standard Linux driver to support Cisco/Aironet PCMCIA
+ 802.11 wireless cards. This driver is the same as the Aironet
+diff -Naur linux-2.6.16/drivers/pcmcia/ds.c linux-2.6.16.16/drivers/pcmcia/ds.c
+--- linux-2.6.16/drivers/pcmcia/ds.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/pcmcia/ds.c 2006-05-11 04:56:24.000000000 +0300
+@@ -546,7 +546,7 @@
+ tmp = vers1->str + vers1->ofs[i];
+
+ length = strlen(tmp) + 1;
+- if ((length < 3) || (length > 255))
++ if ((length < 2) || (length > 255))
+ continue;
+
+ p_dev->prod_id[i] = kmalloc(sizeof(char) * length,
+diff -Naur linux-2.6.16/drivers/scsi/3w-9xxx.c linux-2.6.16.16/drivers/scsi/3w-9xxx.c
+--- linux-2.6.16/drivers/scsi/3w-9xxx.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/scsi/3w-9xxx.c 2006-05-11 04:56:24.000000000 +0300
+@@ -85,7 +85,7 @@
+ #include "3w-9xxx.h"
+
+ /* Globals */
+-#define TW_DRIVER_VERSION "2.26.02.005"
++#define TW_DRIVER_VERSION "2.26.02.007"
+ static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
+ static unsigned int twa_device_extension_count;
+ static int twa_major = -1;
+@@ -1944,9 +1944,13 @@
+ }
+ if (tw_dev->srb[request_id]->use_sg == 1) {
+ struct scatterlist *sg = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
+- char *buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
++ char *buf;
++ unsigned long flags = 0;
++ local_irq_save(flags);
++ buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+ memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length);
+ kunmap_atomic(buf - sg->offset, KM_IRQ0);
++ local_irq_restore(flags);
+ }
+ }
+ } /* End twa_scsiop_execute_scsi_complete() */
+diff -Naur linux-2.6.16/drivers/scsi/3w-xxxx.c linux-2.6.16.16/drivers/scsi/3w-xxxx.c
+--- linux-2.6.16/drivers/scsi/3w-xxxx.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/scsi/3w-xxxx.c 2006-05-11 04:56:24.000000000 +0300
+@@ -1508,10 +1508,12 @@
+ struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+ void *buf;
+ unsigned int transfer_len;
++ unsigned long flags = 0;
+
+ if (cmd->use_sg) {
+ struct scatterlist *sg =
+ (struct scatterlist *)cmd->request_buffer;
++ local_irq_save(flags);
+ buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+ transfer_len = min(sg->length, len);
+ } else {
+@@ -1526,6 +1528,7 @@
+
+ sg = (struct scatterlist *)cmd->request_buffer;
+ kunmap_atomic(buf - sg->offset, KM_IRQ0);
++ local_irq_restore(flags);
+ }
+ }
+
+diff -Naur linux-2.6.16/drivers/scsi/sata_mv.c linux-2.6.16.16/drivers/scsi/sata_mv.c
+--- linux-2.6.16/drivers/scsi/sata_mv.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/scsi/sata_mv.c 2006-05-11 04:56:24.000000000 +0300
+@@ -1102,6 +1102,7 @@
+ void __iomem *port_mmio = mv_ap_base(ap);
+ struct mv_port_priv *pp = ap->private_data;
+ u32 out_ptr;
++ u8 ata_status;
+
+ out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
+
+@@ -1109,6 +1110,8 @@
+ assert(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) ==
+ pp->rsp_consumer);
+
++ ata_status = pp->crpb[pp->rsp_consumer].flags >> CRPB_FLAG_STATUS_SHIFT;
++
+ /* increment our consumer index... */
+ pp->rsp_consumer = mv_inc_q_index(&pp->rsp_consumer);
+
+@@ -1123,7 +1126,7 @@
+ writelfl(out_ptr, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
+
+ /* Return ATA status register for completed CRPB */
+- return (pp->crpb[pp->rsp_consumer].flags >> CRPB_FLAG_STATUS_SHIFT);
++ return ata_status;
+ }
+
+ /**
+@@ -1192,7 +1195,6 @@
+ u32 hc_irq_cause;
+ int shift, port, port0, hard_port, handled;
+ unsigned int err_mask;
+- u8 ata_status = 0;
+
+ if (hc == 0) {
+ port0 = 0;
+@@ -1210,6 +1212,7 @@
+ hc,relevant,hc_irq_cause);
+
+ for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) {
++ u8 ata_status = 0;
+ ap = host_set->ports[port];
+ hard_port = port & MV_PORT_MASK; /* range 0-3 */
+ handled = 0; /* ensure ata_status is set if handled++ */
+diff -Naur linux-2.6.16/drivers/usb/core/message.c linux-2.6.16.16/drivers/usb/core/message.c
+--- linux-2.6.16/drivers/usb/core/message.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/usb/core/message.c 2006-05-11 04:56:24.000000000 +0300
+@@ -1388,11 +1388,13 @@
+ if (dev->state != USB_STATE_ADDRESS)
+ usb_disable_device (dev, 1); // Skip ep0
+
+- i = dev->bus_mA - cp->desc.bMaxPower * 2;
+- if (i < 0)
+- dev_warn(&dev->dev, "new config #%d exceeds power "
+- "limit by %dmA\n",
+- configuration, -i);
++ if (cp) {
++ i = dev->bus_mA - cp->desc.bMaxPower * 2;
++ if (i < 0)
++ dev_warn(&dev->dev, "new config #%d exceeds power "
++ "limit by %dmA\n",
++ configuration, -i);
++ }
+
+ if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
+diff -Naur linux-2.6.16/drivers/usb/host/ehci-sched.c linux-2.6.16.16/drivers/usb/host/ehci-sched.c
+--- linux-2.6.16/drivers/usb/host/ehci-sched.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/usb/host/ehci-sched.c 2006-05-11 04:56:24.000000000 +0300
+@@ -707,6 +707,7 @@
+ } else {
+ u32 addr;
+ int think_time;
++ int hs_transfers;
+
+ addr = dev->ttport << 24;
+ if (!ehci_is_TDI(ehci)
+@@ -719,6 +720,7 @@
+ think_time = dev->tt ? dev->tt->think_time : 0;
+ stream->tt_usecs = NS_TO_US (think_time + usb_calc_bus_time (
+ dev->speed, is_input, 1, maxp));
++ hs_transfers = max (1u, (maxp + 187) / 188);
+ if (is_input) {
+ u32 tmp;
+
+@@ -727,12 +729,11 @@
+ stream->usecs = HS_USECS_ISO (1);
+ stream->raw_mask = 1;
+
+- /* pessimistic c-mask */
+- tmp = usb_calc_bus_time (USB_SPEED_FULL, 1, 0, maxp)
+- / (125 * 1000);
+- stream->raw_mask |= 3 << (tmp + 9);
++ /* c-mask as specified in USB 2.0 11.18.4 3.c */
++ tmp = (1 << (hs_transfers + 2)) - 1;
++ stream->raw_mask |= tmp << (8 + 2);
+ } else
+- stream->raw_mask = smask_out [maxp / 188];
++ stream->raw_mask = smask_out [hs_transfers - 1];
+ bandwidth = stream->usecs + stream->c_usecs;
+ bandwidth /= 1 << (interval + 2);
+
+diff -Naur linux-2.6.16/drivers/usb/serial/console.c linux-2.6.16.16/drivers/usb/serial/console.c
+--- linux-2.6.16/drivers/usb/serial/console.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/usb/serial/console.c 2006-05-11 04:56:24.000000000 +0300
+@@ -54,7 +54,7 @@
+ * serial.c code, except that the specifier is "ttyUSB" instead
+ * of "ttyS".
+ */
+-static int __init usb_console_setup(struct console *co, char *options)
++static int usb_console_setup(struct console *co, char *options)
+ {
+ struct usbcons_info *info = &usbcons_info;
+ int baud = 9600;
+diff -Naur linux-2.6.16/drivers/usb/serial/option.c linux-2.6.16.16/drivers/usb/serial/option.c
+--- linux-2.6.16/drivers/usb/serial/option.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/usb/serial/option.c 2006-05-11 04:56:24.000000000 +0300
+@@ -582,14 +582,14 @@
+ portdata = usb_get_serial_port_data(port);
+
+ /* Do indat endpoints first */
+- for (j = 0; j <= N_IN_URB; ++j) {
++ for (j = 0; j < N_IN_URB; ++j) {
+ portdata->in_urbs[j] = option_setup_urb (serial,
+ port->bulk_in_endpointAddress, USB_DIR_IN, port,
+ portdata->in_buffer[j], IN_BUFLEN, option_indat_callback);
+ }
+
+ /* outdat endpoints */
+- for (j = 0; j <= N_OUT_URB; ++j) {
++ for (j = 0; j < N_OUT_URB; ++j) {
+ portdata->out_urbs[j] = option_setup_urb (serial,
+ port->bulk_out_endpointAddress, USB_DIR_OUT, port,
+ portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback);
+diff -Naur linux-2.6.16/drivers/usb/storage/Kconfig linux-2.6.16.16/drivers/usb/storage/Kconfig
+--- linux-2.6.16/drivers/usb/storage/Kconfig 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/usb/storage/Kconfig 2006-05-11 04:56:24.000000000 +0300
+@@ -48,7 +48,8 @@
+
+ config USB_STORAGE_ISD200
+ bool "ISD-200 USB/ATA Bridge support"
+- depends on USB_STORAGE && BLK_DEV_IDE
++ depends on USB_STORAGE
++ depends on BLK_DEV_IDE=y || BLK_DEV_IDE=USB_STORAGE
+ ---help---
+ Say Y here if you want to use USB Mass Store devices based
+ on the In-Systems Design ISD-200 USB/ATA bridge.
+diff -Naur linux-2.6.16/drivers/video/cfbimgblt.c linux-2.6.16.16/drivers/video/cfbimgblt.c
+--- linux-2.6.16/drivers/video/cfbimgblt.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/video/cfbimgblt.c 2006-05-11 04:56:24.000000000 +0300
+@@ -169,7 +169,7 @@
+
+ while (j--) {
+ l--;
+- color = (*s & 1 << (FB_BIT_NR(l))) ? fgcolor : bgcolor;
++ color = (*s & (1 << l)) ? fgcolor : bgcolor;
+ val |= FB_SHIFT_HIGH(color, shift);
+
+ /* Did the bitshift spill bits to the next long? */
+diff -Naur linux-2.6.16/drivers/video/fbmem.c linux-2.6.16.16/drivers/video/fbmem.c
+--- linux-2.6.16/drivers/video/fbmem.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/video/fbmem.c 2006-05-11 04:56:24.000000000 +0300
+@@ -669,13 +669,19 @@
+ total_size = info->fix.smem_len;
+
+ if (p > total_size)
+- return 0;
++ return -EFBIG;
+
+- if (count >= total_size)
++ if (count > total_size) {
++ err = -EFBIG;
+ count = total_size;
++ }
++
++ if (count + p > total_size) {
++ if (!err)
++ err = -ENOSPC;
+
+- if (count + p > total_size)
+ count = total_size - p;
++ }
+
+ buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count,
+ GFP_KERNEL);
+@@ -717,7 +723,7 @@
+
+ kfree(buffer);
+
+- return (err) ? err : cnt;
++ return (cnt) ? cnt : err;
+ }
+
+ #ifdef CONFIG_KMOD
+diff -Naur linux-2.6.16/drivers/video/i810/i810_main.c linux-2.6.16.16/drivers/video/i810/i810_main.c
+--- linux-2.6.16/drivers/video/i810/i810_main.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/drivers/video/i810/i810_main.c 2006-05-11 04:56:24.000000000 +0300
+@@ -1508,7 +1508,7 @@
+ int size = ((cursor->image.width + 7) >> 3) *
+ cursor->image.height;
+ int i;
+- u8 *data = kmalloc(64 * 8, GFP_KERNEL);
++ u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
+
+ if (data == NULL)
+ return -ENOMEM;
+diff -Naur linux-2.6.16/fs/9p/vfs_inode.c linux-2.6.16.16/fs/9p/vfs_inode.c
+--- linux-2.6.16/fs/9p/vfs_inode.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/9p/vfs_inode.c 2006-05-11 04:56:24.000000000 +0300
+@@ -614,6 +614,7 @@
+
+ sb = dir->i_sb;
+ v9ses = v9fs_inode2v9ses(dir);
++ dentry->d_op = &v9fs_dentry_operations;
+ dirfid = v9fs_fid_lookup(dentry->d_parent);
+
+ if (!dirfid) {
+@@ -681,8 +682,6 @@
+ goto FreeFcall;
+
+ fid->qid = fcall->params.rstat.stat.qid;
+-
+- dentry->d_op = &v9fs_dentry_operations;
+ v9fs_stat2inode(&fcall->params.rstat.stat, inode, inode->i_sb);
+
+ d_add(dentry, inode);
+diff -Naur linux-2.6.16/fs/char_dev.c linux-2.6.16.16/fs/char_dev.c
+--- linux-2.6.16/fs/char_dev.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/char_dev.c 2006-05-11 04:56:24.000000000 +0300
+@@ -15,6 +15,7 @@
+ #include <linux/module.h>
+ #include <linux/smp_lock.h>
+ #include <linux/devfs_fs_kernel.h>
++#include <linux/seq_file.h>
+
+ #include <linux/kobject.h>
+ #include <linux/kobj_map.h>
+@@ -26,8 +27,6 @@
+
+ static struct kobj_map *cdev_map;
+
+-#define MAX_PROBE_HASH 255 /* random */
+-
+ static DECLARE_MUTEX(chrdevs_lock);
+
+ static struct char_device_struct {
+@@ -38,93 +37,29 @@
+ char name[64];
+ struct file_operations *fops;
+ struct cdev *cdev; /* will die */
+-} *chrdevs[MAX_PROBE_HASH];
++} *chrdevs[CHRDEV_MAJOR_HASH_SIZE];
+
+ /* index in the above */
+ static inline int major_to_index(int major)
+ {
+- return major % MAX_PROBE_HASH;
+-}
+-
+-struct chrdev_info {
+- int index;
+- struct char_device_struct *cd;
+-};
+-
+-void *get_next_chrdev(void *dev)
+-{
+- struct chrdev_info *info;
+-
+- if (dev == NULL) {
+- info = kmalloc(sizeof(*info), GFP_KERNEL);
+- if (!info)
+- goto out;
+- info->index=0;
+- info->cd = chrdevs[info->index];
+- if (info->cd)
+- goto out;
+- } else {
+- info = dev;
+- }
+-
+- while (info->index < ARRAY_SIZE(chrdevs)) {
+- if (info->cd)
+- info->cd = info->cd->next;
+- if (info->cd)
+- goto out;
+- /*
+- * No devices on this chain, move to the next
+- */
+- info->index++;
+- info->cd = (info->index < ARRAY_SIZE(chrdevs)) ?
+- chrdevs[info->index] : NULL;
+- if (info->cd)
+- goto out;
+- }
+-
+-out:
+- return info;
+-}
+-
+-void *acquire_chrdev_list(void)
+-{
+- down(&chrdevs_lock);
+- return get_next_chrdev(NULL);
+-}
+-
+-void release_chrdev_list(void *dev)
+-{
+- up(&chrdevs_lock);
+- kfree(dev);
++ return major % CHRDEV_MAJOR_HASH_SIZE;
+ }
+
++#ifdef CONFIG_PROC_FS
+
+-int count_chrdev_list(void)
++void chrdev_show(struct seq_file *f, off_t offset)
+ {
+ struct char_device_struct *cd;
+- int i, count;
+-
+- count = 0;
+
+- for (i = 0; i < ARRAY_SIZE(chrdevs) ; i++) {
+- for (cd = chrdevs[i]; cd; cd = cd->next)
+- count++;
++ if (offset < CHRDEV_MAJOR_HASH_SIZE) {
++ down(&chrdevs_lock);
++ for (cd = chrdevs[offset]; cd; cd = cd->next)
++ seq_printf(f, "%3d %s\n", cd->major, cd->name);
++ up(&chrdevs_lock);
+ }
+-
+- return count;
+ }
+
+-int get_chrdev_info(void *dev, int *major, char **name)
+-{
+- struct chrdev_info *info = dev;
+-
+- if (info->cd == NULL)
+- return 1;
+-
+- *major = info->cd->major;
+- *name = info->cd->name;
+- return 0;
+-}
++#endif /* CONFIG_PROC_FS */
+
+ /*
+ * Register a single major with a specified minor range.
+diff -Naur linux-2.6.16/fs/cifs/cifsencrypt.c linux-2.6.16.16/fs/cifs/cifsencrypt.c
+--- linux-2.6.16/fs/cifs/cifsencrypt.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/cifs/cifsencrypt.c 2006-05-11 04:56:24.000000000 +0300
+@@ -56,9 +56,6 @@
+ int rc = 0;
+ char smb_signature[20];
+
+- /* BB remember to initialize sequence number elsewhere and initialize mac_signing key elsewhere BB */
+- /* BB remember to add code to save expected sequence number in midQ entry BB */
+-
+ if((cifs_pdu == NULL) || (server == NULL))
+ return -EINVAL;
+
+@@ -85,20 +82,33 @@
+ static int cifs_calc_signature2(const struct kvec * iov, int n_vec,
+ const char * key, char * signature)
+ {
+- struct MD5Context context;
+-
+- if((iov == NULL) || (signature == NULL))
+- return -EINVAL;
++ struct MD5Context context;
++ int i;
+
+- MD5Init(&context);
+- MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16);
++ if((iov == NULL) || (signature == NULL))
++ return -EINVAL;
+
+-/* MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); */ /* BB FIXME BB */
++ MD5Init(&context);
++ MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16);
++ for(i=0;i<n_vec;i++) {
++ if(iov[i].iov_base == NULL) {
++ cERROR(1,("null iovec entry"));
++ return -EIO;
++ } else if(iov[i].iov_len == 0)
++ break; /* bail out if we are sent nothing to sign */
++ /* The first entry includes a length field (which does not get
++ signed that occupies the first 4 bytes before the header */
++ if(i==0) {
++ if (iov[0].iov_len <= 8 ) /* cmd field at offset 9 */
++ break; /* nothing to sign or corrupt header */
++ MD5Update(&context,iov[0].iov_base+4, iov[0].iov_len-4);
++ } else
++ MD5Update(&context,iov[i].iov_base, iov[i].iov_len);
++ }
+
+- MD5Final(signature,&context);
++ MD5Final(signature,&context);
+
+- return -EOPNOTSUPP;
+-/* return 0; */
++ return 0;
+ }
+
+
+diff -Naur linux-2.6.16/fs/cifs/dir.c linux-2.6.16.16/fs/cifs/dir.c
+--- linux-2.6.16/fs/cifs/dir.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/cifs/dir.c 2006-05-11 04:56:24.000000000 +0300
+@@ -441,6 +441,20 @@
+ cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
+ pTcon = cifs_sb->tcon;
+
++ /*
++ * Don't allow the separator character in a path component.
++ * The VFS will not allow "/", but "\" is allowed by posix.
++ */
++ if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
++ int i;
++ for (i = 0; i < direntry->d_name.len; i++)
++ if (direntry->d_name.name[i] == '\\') {
++ cFYI(1, ("Invalid file name"));
++ FreeXid(xid);
++ return ERR_PTR(-EINVAL);
++ }
++ }
++
+ /* can not grab the rename sem here since it would
+ deadlock in the cases (beginning of sys_rename itself)
+ in which we already have the sb rename sem */
+diff -Naur linux-2.6.16/fs/compat.c linux-2.6.16.16/fs/compat.c
+--- linux-2.6.16/fs/compat.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/compat.c 2006-05-11 04:56:24.000000000 +0300
+@@ -1215,6 +1215,10 @@
+ if (ret < 0)
+ goto out;
+
++ ret = security_file_permission(file, type == READ ? MAY_READ:MAY_WRITE);
++ if (ret)
++ goto out;
++
+ fnv = NULL;
+ if (type == READ) {
+ fn = file->f_op->read;
+diff -Naur linux-2.6.16/fs/ext3/resize.c linux-2.6.16.16/fs/ext3/resize.c
+--- linux-2.6.16/fs/ext3/resize.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/ext3/resize.c 2006-05-11 04:56:24.000000000 +0300
+@@ -974,6 +974,7 @@
+ if (o_blocks_count != le32_to_cpu(es->s_blocks_count)) {
+ ext3_warning(sb, __FUNCTION__,
+ "multiple resizers run on filesystem!");
++ unlock_super(sb);
+ err = -EBUSY;
+ goto exit_put;
+ }
+diff -Naur linux-2.6.16/fs/fuse/file.c linux-2.6.16.16/fs/fuse/file.c
+--- linux-2.6.16/fs/fuse/file.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/fuse/file.c 2006-05-11 04:56:24.000000000 +0300
+@@ -397,8 +397,12 @@
+ return -EINTR;
+
+ err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data);
+- if (!err)
+- fuse_send_readpages(data.req, file, inode);
++ if (!err) {
++ if (data.req->num_pages)
++ fuse_send_readpages(data.req, file, inode);
++ else
++ fuse_put_request(fc, data.req);
++ }
+ return err;
+ }
+
+diff -Naur linux-2.6.16/fs/locks.c linux-2.6.16.16/fs/locks.c
+--- linux-2.6.16/fs/locks.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/locks.c 2006-05-11 04:56:24.000000000 +0300
+@@ -432,15 +432,14 @@
+ */
+ static int lease_init(struct file *filp, int type, struct file_lock *fl)
+ {
++ if (assign_type(fl, type) != 0)
++ return -EINVAL;
++
+ fl->fl_owner = current->files;
+ fl->fl_pid = current->tgid;
+
+ fl->fl_file = filp;
+ fl->fl_flags = FL_LEASE;
+- if (assign_type(fl, type) != 0) {
+- locks_free_lock(fl);
+- return -EINVAL;
+- }
+ fl->fl_start = 0;
+ fl->fl_end = OFFSET_MAX;
+ fl->fl_ops = NULL;
+@@ -452,16 +451,19 @@
+ static int lease_alloc(struct file *filp, int type, struct file_lock **flp)
+ {
+ struct file_lock *fl = locks_alloc_lock();
+- int error;
++ int error = -ENOMEM;
+
+ if (fl == NULL)
+- return -ENOMEM;
++ goto out;
+
+ error = lease_init(filp, type, fl);
+- if (error)
+- return error;
++ if (error) {
++ locks_free_lock(fl);
++ fl = NULL;
++ }
++out:
+ *flp = fl;
+- return 0;
++ return error;
+ }
+
+ /* Check if two locks overlap each other.
+@@ -1337,6 +1339,7 @@
+ goto out;
+
+ if (my_before != NULL) {
++ *flp = *my_before;
+ error = lease->fl_lmops->fl_change(my_before, arg);
+ goto out;
+ }
+@@ -2212,7 +2215,12 @@
+
+ lock_kernel();
+ j = 0;
+- rcu_read_lock();
++
++ /*
++ * We are not taking a ref to the file structures, so
++ * we need to acquire ->file_lock.
++ */
++ spin_lock(&files->file_lock);
+ fdt = files_fdtable(files);
+ for (;;) {
+ unsigned long set;
+@@ -2230,7 +2238,7 @@
+ set >>= 1;
+ }
+ }
+- rcu_read_unlock();
++ spin_unlock(&files->file_lock);
+ unlock_kernel();
+ }
+ EXPORT_SYMBOL(steal_locks);
+diff -Naur linux-2.6.16/fs/nfsd/nfs3proc.c linux-2.6.16.16/fs/nfsd/nfs3proc.c
+--- linux-2.6.16/fs/nfsd/nfs3proc.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/nfsd/nfs3proc.c 2006-05-11 04:56:24.000000000 +0300
+@@ -682,7 +682,7 @@
+ PROC(lookup, dirop, dirop, fhandle2, RC_NOCACHE, ST+FH+pAT+pAT),
+ PROC(access, access, access, fhandle, RC_NOCACHE, ST+pAT+1),
+ PROC(readlink, readlink, readlink, fhandle, RC_NOCACHE, ST+pAT+1+NFS3_MAXPATHLEN/4),
+- PROC(read, read, read, fhandle, RC_NOCACHE, ST+pAT+4+NFSSVC_MAXBLKSIZE),
++ PROC(read, read, read, fhandle, RC_NOCACHE, ST+pAT+4+NFSSVC_MAXBLKSIZE/4),
+ PROC(write, write, write, fhandle, RC_REPLBUFF, ST+WC+4),
+ PROC(create, create, create, fhandle2, RC_REPLBUFF, ST+(1+FH+pAT)+WC),
+ PROC(mkdir, mkdir, create, fhandle2, RC_REPLBUFF, ST+(1+FH+pAT)+WC),
+diff -Naur linux-2.6.16/fs/nfsd/nfs4proc.c linux-2.6.16.16/fs/nfsd/nfs4proc.c
+--- linux-2.6.16/fs/nfsd/nfs4proc.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/nfsd/nfs4proc.c 2006-05-11 04:56:24.000000000 +0300
+@@ -975,7 +975,7 @@
+ */
+ static struct svc_procedure nfsd_procedures4[2] = {
+ PROC(null, void, void, void, RC_NOCACHE, 1),
+- PROC(compound, compound, compound, compound, RC_NOCACHE, NFSD_BUFSIZE)
++ PROC(compound, compound, compound, compound, RC_NOCACHE, NFSD_BUFSIZE/4)
+ };
+
+ struct svc_version nfsd_version4 = {
+diff -Naur linux-2.6.16/fs/nfsd/nfsproc.c linux-2.6.16.16/fs/nfsd/nfsproc.c
+--- linux-2.6.16/fs/nfsd/nfsproc.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/nfsd/nfsproc.c 2006-05-11 04:56:24.000000000 +0300
+@@ -553,7 +553,7 @@
+ PROC(none, void, void, none, RC_NOCACHE, ST),
+ PROC(lookup, diropargs, diropres, fhandle, RC_NOCACHE, ST+FH+AT),
+ PROC(readlink, readlinkargs, readlinkres, none, RC_NOCACHE, ST+1+NFS_MAXPATHLEN/4),
+- PROC(read, readargs, readres, fhandle, RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE),
++ PROC(read, readargs, readres, fhandle, RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE/4),
+ PROC(none, void, void, none, RC_NOCACHE, ST),
+ PROC(write, writeargs, attrstat, fhandle, RC_REPLBUFF, ST+AT),
+ PROC(create, createargs, diropres, fhandle, RC_REPLBUFF, ST+FH+AT),
+diff -Naur linux-2.6.16/fs/open.c linux-2.6.16.16/fs/open.c
+--- linux-2.6.16/fs/open.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/open.c 2006-05-11 04:56:24.000000000 +0300
+@@ -330,7 +330,10 @@
+
+ asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length)
+ {
+- return do_sys_ftruncate(fd, length, 1);
++ long ret = do_sys_ftruncate(fd, length, 1);
++ /* avoid REGPARM breakage on x86: */
++ prevent_tail_call(ret);
++ return ret;
+ }
+
+ /* LFS versions of truncate are only needed on 32 bit machines */
+@@ -342,7 +345,10 @@
+
+ asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length)
+ {
+- return do_sys_ftruncate(fd, length, 0);
++ long ret = do_sys_ftruncate(fd, length, 0);
++ /* avoid REGPARM breakage on x86: */
++ prevent_tail_call(ret);
++ return ret;
+ }
+ #endif
+
+@@ -1083,20 +1089,30 @@
+
+ asmlinkage long sys_open(const char __user *filename, int flags, int mode)
+ {
++ long ret;
++
+ if (force_o_largefile())
+ flags |= O_LARGEFILE;
+
+- return do_sys_open(AT_FDCWD, filename, flags, mode);
++ ret = do_sys_open(AT_FDCWD, filename, flags, mode);
++ /* avoid REGPARM breakage on x86: */
++ prevent_tail_call(ret);
++ return ret;
+ }
+ EXPORT_SYMBOL_GPL(sys_open);
+
+ asmlinkage long sys_openat(int dfd, const char __user *filename, int flags,
+ int mode)
+ {
++ long ret;
++
+ if (force_o_largefile())
+ flags |= O_LARGEFILE;
+
+- return do_sys_open(dfd, filename, flags, mode);
++ ret = do_sys_open(dfd, filename, flags, mode);
++ /* avoid REGPARM breakage on x86: */
++ prevent_tail_call(ret);
++ return ret;
+ }
+ EXPORT_SYMBOL_GPL(sys_openat);
+
+diff -Naur linux-2.6.16/fs/partitions/check.c linux-2.6.16.16/fs/partitions/check.c
+--- linux-2.6.16/fs/partitions/check.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/partitions/check.c 2006-05-11 04:56:24.000000000 +0300
+@@ -345,6 +345,7 @@
+ char *name;
+ static char *block_str = "block:";
+ int size;
++ char *s;
+
+ size = strlen(block_str) + strlen(disk->disk_name) + 1;
+ name = kmalloc(size, GFP_KERNEL);
+@@ -352,6 +353,10 @@
+ return NULL;
+ strcpy(name, block_str);
+ strcat(name, disk->disk_name);
++ /* ewww... some of these buggers have / in name... */
++ s = strchr(name, '/');
++ if (s)
++ *s = '!';
+ return name;
+ }
+
+diff -Naur linux-2.6.16/fs/proc/base.c linux-2.6.16.16/fs/proc/base.c
+--- linux-2.6.16/fs/proc/base.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/proc/base.c 2006-05-11 04:56:24.000000000 +0300
+@@ -294,16 +294,20 @@
+
+ files = get_files_struct(task);
+ if (files) {
+- rcu_read_lock();
++ /*
++ * We are not taking a ref to the file structure, so we must
++ * hold ->file_lock.
++ */
++ spin_lock(&files->file_lock);
+ file = fcheck_files(files, fd);
+ if (file) {
+ *mnt = mntget(file->f_vfsmnt);
+ *dentry = dget(file->f_dentry);
+- rcu_read_unlock();
++ spin_unlock(&files->file_lock);
+ put_files_struct(files);
+ return 0;
+ }
+- rcu_read_unlock();
++ spin_unlock(&files->file_lock);
+ put_files_struct(files);
+ }
+ return -ENOENT;
+@@ -1485,7 +1489,12 @@
+ if (!files)
+ goto out_unlock;
+ inode->i_mode = S_IFLNK;
+- rcu_read_lock();
++
++ /*
++ * We are not taking a ref to the file structure, so we must
++ * hold ->file_lock.
++ */
++ spin_lock(&files->file_lock);
+ file = fcheck_files(files, fd);
+ if (!file)
+ goto out_unlock2;
+@@ -1493,7 +1502,7 @@
+ inode->i_mode |= S_IRUSR | S_IXUSR;
+ if (file->f_mode & 2)
+ inode->i_mode |= S_IWUSR | S_IXUSR;
+- rcu_read_unlock();
++ spin_unlock(&files->file_lock);
+ put_files_struct(files);
+ inode->i_op = &proc_pid_link_inode_operations;
+ inode->i_size = 64;
+@@ -1503,7 +1512,7 @@
+ return NULL;
+
+ out_unlock2:
+- rcu_read_unlock();
++ spin_unlock(&files->file_lock);
+ put_files_struct(files);
+ out_unlock:
+ iput(inode);
+diff -Naur linux-2.6.16/fs/proc/proc_misc.c linux-2.6.16.16/fs/proc/proc_misc.c
+--- linux-2.6.16/fs/proc/proc_misc.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/proc/proc_misc.c 2006-05-11 04:56:24.000000000 +0300
+@@ -249,144 +249,60 @@
+ return seq_open(file, &cpuinfo_op);
+ }
+
+-enum devinfo_states {
+- CHR_HDR,
+- CHR_LIST,
+- BLK_HDR,
+- BLK_LIST,
+- DEVINFO_DONE
+-};
+-
+-struct devinfo_state {
+- void *chrdev;
+- void *blkdev;
+- unsigned int num_records;
+- unsigned int cur_record;
+- enum devinfo_states state;
++static struct file_operations proc_cpuinfo_operations = {
++ .open = cpuinfo_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release,
+ };
+
+-static void *devinfo_start(struct seq_file *f, loff_t *pos)
++static int devinfo_show(struct seq_file *f, void *v)
+ {
+- struct devinfo_state *info = f->private;
++ int i = *(loff_t *) v;
+
+- if (*pos) {
+- if ((info) && (*pos <= info->num_records))
+- return info;
+- return NULL;
++ if (i < CHRDEV_MAJOR_HASH_SIZE) {
++ if (i == 0)
++ seq_printf(f, "Character devices:\n");
++ chrdev_show(f, i);
++ } else {
++ i -= CHRDEV_MAJOR_HASH_SIZE;
++ if (i == 0)
++ seq_printf(f, "\nBlock devices:\n");
++ blkdev_show(f, i);
+ }
+- info = kmalloc(sizeof(*info), GFP_KERNEL);
+- f->private = info;
+- info->chrdev = acquire_chrdev_list();
+- info->blkdev = acquire_blkdev_list();
+- info->state = CHR_HDR;
+- info->num_records = count_chrdev_list();
+- info->num_records += count_blkdev_list();
+- info->num_records += 2; /* Character and Block headers */
+- *pos = 1;
+- info->cur_record = *pos;
+- return info;
++ return 0;
+ }
+
+-static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
++static void *devinfo_start(struct seq_file *f, loff_t *pos)
+ {
+- int idummy;
+- char *ndummy;
+- struct devinfo_state *info = f->private;
+-
+- switch (info->state) {
+- case CHR_HDR:
+- info->state = CHR_LIST;
+- (*pos)++;
+- /*fallthrough*/
+- case CHR_LIST:
+- if (get_chrdev_info(info->chrdev,&idummy,&ndummy)) {
+- /*
+- * The character dev list is complete
+- */
+- info->state = BLK_HDR;
+- } else {
+- info->chrdev = get_next_chrdev(info->chrdev);
+- }
+- (*pos)++;
+- break;
+- case BLK_HDR:
+- info->state = BLK_LIST;
+- (*pos)++;
+- break;
+- case BLK_LIST:
+- if (get_blkdev_info(info->blkdev,&idummy,&ndummy)) {
+- /*
+- * The block dev list is complete
+- */
+- info->state = DEVINFO_DONE;
+- } else {
+- info->blkdev = get_next_blkdev(info->blkdev);
+- }
+- (*pos)++;
+- break;
+- case DEVINFO_DONE:
+- (*pos)++;
+- info->cur_record = *pos;
+- info = NULL;
+- break;
+- default:
+- break;
+- }
+- if (info)
+- info->cur_record = *pos;
+- return info;
++ if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
++ return pos;
++ return NULL;
+ }
+
+-static void devinfo_stop(struct seq_file *f, void *v)
++static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
+ {
+- struct devinfo_state *info = f->private;
+-
+- if (info) {
+- release_chrdev_list(info->chrdev);
+- release_blkdev_list(info->blkdev);
+- f->private = NULL;
+- kfree(info);
+- }
++ (*pos)++;
++ if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
++ return NULL;
++ return pos;
+ }
+
+-static int devinfo_show(struct seq_file *f, void *arg)
++static void devinfo_stop(struct seq_file *f, void *v)
+ {
+- int major;
+- char *name;
+- struct devinfo_state *info = f->private;
+-
+- switch(info->state) {
+- case CHR_HDR:
+- seq_printf(f,"Character devices:\n");
+- /* fallthrough */
+- case CHR_LIST:
+- if (!get_chrdev_info(info->chrdev,&major,&name))
+- seq_printf(f,"%3d %s\n",major,name);
+- break;
+- case BLK_HDR:
+- seq_printf(f,"\nBlock devices:\n");
+- /* fallthrough */
+- case BLK_LIST:
+- if (!get_blkdev_info(info->blkdev,&major,&name))
+- seq_printf(f,"%3d %s\n",major,name);
+- break;
+- default:
+- break;
+- }
+-
+- return 0;
++ /* Nothing to do */
+ }
+
+-static struct seq_operations devinfo_op = {
+- .start = devinfo_start,
+- .next = devinfo_next,
+- .stop = devinfo_stop,
+- .show = devinfo_show,
++static struct seq_operations devinfo_ops = {
++ .start = devinfo_start,
++ .next = devinfo_next,
++ .stop = devinfo_stop,
++ .show = devinfo_show
+ };
+
+-static int devinfo_open(struct inode *inode, struct file *file)
++static int devinfo_open(struct inode *inode, struct file *filp)
+ {
+- return seq_open(file, &devinfo_op);
++ return seq_open(filp, &devinfo_ops);
+ }
+
+ static struct file_operations proc_devinfo_operations = {
+@@ -396,13 +312,6 @@
+ .release = seq_release,
+ };
+
+-static struct file_operations proc_cpuinfo_operations = {
+- .open = cpuinfo_open,
+- .read = seq_read,
+- .llseek = seq_lseek,
+- .release = seq_release,
+-};
+-
+ extern struct seq_operations vmstat_op;
+ static int vmstat_open(struct inode *inode, struct file *file)
+ {
+diff -Naur linux-2.6.16/fs/proc/vmcore.c linux-2.6.16.16/fs/proc/vmcore.c
+--- linux-2.6.16/fs/proc/vmcore.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/proc/vmcore.c 2006-05-11 04:56:24.000000000 +0300
+@@ -103,8 +103,8 @@
+ size_t buflen, loff_t *fpos)
+ {
+ ssize_t acc = 0, tmp;
+- size_t tsz, nr_bytes;
+- u64 start;
++ size_t tsz;
++ u64 start, nr_bytes;
+ struct vmcore *curr_m = NULL;
+
+ if (buflen == 0 || *fpos >= vmcore_size)
+diff -Naur linux-2.6.16/fs/reiserfs/xattr_acl.c linux-2.6.16.16/fs/reiserfs/xattr_acl.c
+--- linux-2.6.16/fs/reiserfs/xattr_acl.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/reiserfs/xattr_acl.c 2006-05-11 04:56:24.000000000 +0300
+@@ -408,8 +408,9 @@
+ acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT);
+ reiserfs_read_unlock_xattrs(inode->i_sb);
+ reiserfs_read_unlock_xattr_i(inode);
+- ret = acl ? 1 : 0;
+- posix_acl_release(acl);
++ ret = (acl && !IS_ERR(acl));
++ if (ret)
++ posix_acl_release(acl);
+ }
+
+ return ret;
+diff -Naur linux-2.6.16/fs/smbfs/dir.c linux-2.6.16.16/fs/smbfs/dir.c
+--- linux-2.6.16/fs/smbfs/dir.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/smbfs/dir.c 2006-05-11 04:56:24.000000000 +0300
+@@ -434,6 +434,11 @@
+ if (dentry->d_name.len > SMB_MAXNAMELEN)
+ goto out;
+
++ /* Do not allow lookup of names with backslashes in */
++ error = -EINVAL;
++ if (memchr(dentry->d_name.name, '\\', dentry->d_name.len))
++ goto out;
++
+ lock_kernel();
+ error = smb_proc_getattr(dentry, &finfo);
+ #ifdef SMBFS_PARANOIA
+diff -Naur linux-2.6.16/fs/sysfs/dir.c linux-2.6.16.16/fs/sysfs/dir.c
+--- linux-2.6.16/fs/sysfs/dir.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/sysfs/dir.c 2006-05-11 04:56:24.000000000 +0300
+@@ -302,6 +302,7 @@
+ * Drop reference from dget() on entrance.
+ */
+ dput(dentry);
++ kobj->dentry = NULL;
+ }
+
+ int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
+diff -Naur linux-2.6.16/fs/sysfs/file.c linux-2.6.16.16/fs/sysfs/file.c
+--- linux-2.6.16/fs/sysfs/file.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/sysfs/file.c 2006-05-11 04:56:24.000000000 +0300
+@@ -183,7 +183,7 @@
+ return -ENOMEM;
+
+ if (count >= PAGE_SIZE)
+- count = PAGE_SIZE;
++ count = PAGE_SIZE - 1;
+ error = copy_from_user(buffer->page,buf,count);
+ buffer->needs_read_fill = 1;
+ return error ? -EFAULT : count;
+diff -Naur linux-2.6.16/fs/sysfs/inode.c linux-2.6.16.16/fs/sysfs/inode.c
+--- linux-2.6.16/fs/sysfs/inode.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/sysfs/inode.c 2006-05-11 04:56:24.000000000 +0300
+@@ -227,12 +227,16 @@
+ void sysfs_hash_and_remove(struct dentry * dir, const char * name)
+ {
+ struct sysfs_dirent * sd;
+- struct sysfs_dirent * parent_sd = dir->d_fsdata;
++ struct sysfs_dirent * parent_sd;
++
++ if (!dir)
++ return;
+
+ if (dir->d_inode == NULL)
+ /* no inode means this hasn't been made visible yet */
+ return;
+
++ parent_sd = dir->d_fsdata;
+ mutex_lock(&dir->d_inode->i_mutex);
+ list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
+ if (!sd->s_element)
+diff -Naur linux-2.6.16/fs/sysfs/symlink.c linux-2.6.16.16/fs/sysfs/symlink.c
+--- linux-2.6.16/fs/sysfs/symlink.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/sysfs/symlink.c 2006-05-11 04:56:24.000000000 +0300
+@@ -66,6 +66,7 @@
+ if (!error)
+ return 0;
+
++ kobject_put(target);
+ kfree(sl->link_name);
+ exit2:
+ kfree(sl);
+diff -Naur linux-2.6.16/fs/xfs/linux-2.6/xfs_aops.c linux-2.6.16.16/fs/xfs/linux-2.6/xfs_aops.c
+--- linux-2.6.16/fs/xfs/linux-2.6/xfs_aops.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/xfs/linux-2.6/xfs_aops.c 2006-05-11 04:56:24.000000000 +0300
+@@ -616,7 +616,7 @@
+ acceptable = (type == IOMAP_UNWRITTEN);
+ else if (buffer_delay(bh))
+ acceptable = (type == IOMAP_DELAY);
+- else if (buffer_mapped(bh))
++ else if (buffer_dirty(bh) && buffer_mapped(bh))
+ acceptable = (type == 0);
+ else
+ break;
+diff -Naur linux-2.6.16/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.16.16/fs/xfs/linux-2.6/xfs_iops.c
+--- linux-2.6.16/fs/xfs/linux-2.6/xfs_iops.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/fs/xfs/linux-2.6/xfs_iops.c 2006-05-11 04:56:24.000000000 +0300
+@@ -673,8 +673,7 @@
+ if (ia_valid & ATTR_ATIME) {
+ vattr.va_mask |= XFS_AT_ATIME;
+ vattr.va_atime = attr->ia_atime;
+- if (ia_valid & ATTR_ATIME_SET)
+- inode->i_atime = attr->ia_atime;
++ inode->i_atime = attr->ia_atime;
+ }
+ if (ia_valid & ATTR_MTIME) {
+ vattr.va_mask |= XFS_AT_MTIME;
+diff -Naur linux-2.6.16/include/asm-i386/cpufeature.h linux-2.6.16.16/include/asm-i386/cpufeature.h
+--- linux-2.6.16/include/asm-i386/cpufeature.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/asm-i386/cpufeature.h 2006-05-11 04:56:24.000000000 +0300
+@@ -70,6 +70,7 @@
+ #define X86_FEATURE_P3 (3*32+ 6) /* P3 */
+ #define X86_FEATURE_P4 (3*32+ 7) /* P4 */
+ #define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */
++#define X86_FEATURE_FXSAVE_LEAK (3*32+10) /* FXSAVE leaks FOP/FIP/FOP */
+
+ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
+ #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */
+diff -Naur linux-2.6.16/include/asm-i386/i387.h linux-2.6.16.16/include/asm-i386/i387.h
+--- linux-2.6.16/include/asm-i386/i387.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/asm-i386/i387.h 2006-05-11 04:56:24.000000000 +0300
+@@ -13,6 +13,7 @@
+
+ #include <linux/sched.h>
+ #include <linux/init.h>
++#include <linux/kernel_stat.h>
+ #include <asm/processor.h>
+ #include <asm/sigcontext.h>
+ #include <asm/user.h>
+@@ -38,17 +39,38 @@
+ extern void kernel_fpu_begin(void);
+ #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
+
++/* We need a safe address that is cheap to find and that is already
++ in L1 during context switch. The best choices are unfortunately
++ different for UP and SMP */
++#ifdef CONFIG_SMP
++#define safe_address (__per_cpu_offset[0])
++#else
++#define safe_address (kstat_cpu(0).cpustat.user)
++#endif
++
+ /*
+ * These must be called with preempt disabled
+ */
+ static inline void __save_init_fpu( struct task_struct *tsk )
+ {
++ /* Use more nops than strictly needed in case the compiler
++ varies code */
+ alternative_input(
+- "fnsave %1 ; fwait ;" GENERIC_NOP2,
+- "fxsave %1 ; fnclex",
++ "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4,
++ "fxsave %[fx]\n"
++ "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:",
+ X86_FEATURE_FXSR,
+- "m" (tsk->thread.i387.fxsave)
+- :"memory");
++ [fx] "m" (tsk->thread.i387.fxsave),
++ [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory");
++ /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
++ is pending. Clear the x87 state here by setting it to fixed
++ values. safe_address is a random variable that should be in L1 */
++ alternative_input(
++ GENERIC_NOP8 GENERIC_NOP2,
++ "emms\n\t" /* clear stack tags */
++ "fildl %[addr]", /* set F?P to defined value */
++ X86_FEATURE_FXSAVE_LEAK,
++ [addr] "m" (safe_address));
+ task_thread_info(tsk)->status &= ~TS_USEDFPU;
+ }
+
+diff -Naur linux-2.6.16/include/asm-i386/pgtable-2level.h linux-2.6.16.16/include/asm-i386/pgtable-2level.h
+--- linux-2.6.16/include/asm-i386/pgtable-2level.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/asm-i386/pgtable-2level.h 2006-05-11 04:56:24.000000000 +0300
+@@ -18,6 +18,9 @@
+ #define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval)
+ #define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval))
+
++#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
++#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)
++
+ #define ptep_get_and_clear(mm,addr,xp) __pte(xchg(&(xp)->pte_low, 0))
+ #define pte_same(a, b) ((a).pte_low == (b).pte_low)
+ #define pte_page(x) pfn_to_page(pte_pfn(x))
+diff -Naur linux-2.6.16/include/asm-i386/pgtable-3level.h linux-2.6.16.16/include/asm-i386/pgtable-3level.h
+--- linux-2.6.16/include/asm-i386/pgtable-3level.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/asm-i386/pgtable-3level.h 2006-05-11 04:56:24.000000000 +0300
+@@ -85,6 +85,26 @@
+ #define pmd_offset(pud, address) ((pmd_t *) pud_page(*(pud)) + \
+ pmd_index(address))
+
++/*
++ * For PTEs and PDEs, we must clear the P-bit first when clearing a page table
++ * entry, so clear the bottom half first and enforce ordering with a compiler
++ * barrier.
++ */
++static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
++{
++ ptep->pte_low = 0;
++ smp_wmb();
++ ptep->pte_high = 0;
++}
++
++static inline void pmd_clear(pmd_t *pmd)
++{
++ u32 *tmp = (u32 *)pmd;
++ *tmp = 0;
++ smp_wmb();
++ *(tmp + 1) = 0;
++}
++
+ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+ {
+ pte_t res;
+diff -Naur linux-2.6.16/include/asm-i386/pgtable.h linux-2.6.16.16/include/asm-i386/pgtable.h
+--- linux-2.6.16/include/asm-i386/pgtable.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/asm-i386/pgtable.h 2006-05-11 04:56:24.000000000 +0300
+@@ -204,12 +204,10 @@
+ extern unsigned long pg0[];
+
+ #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
+-#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
+
+ /* To avoid harmful races, pmd_none(x) should check only the lower when PAE */
+ #define pmd_none(x) (!(unsigned long)pmd_val(x))
+ #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
+-#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)
+ #define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
+
+
+@@ -269,7 +267,7 @@
+ pte_t pte;
+ if (full) {
+ pte = *ptep;
+- *ptep = __pte(0);
++ pte_clear(mm, addr, ptep);
+ } else {
+ pte = ptep_get_and_clear(mm, addr, ptep);
+ }
+diff -Naur linux-2.6.16/include/asm-m32r/smp.h linux-2.6.16.16/include/asm-m32r/smp.h
+--- linux-2.6.16/include/asm-m32r/smp.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/asm-m32r/smp.h 2006-05-11 04:56:24.000000000 +0300
+@@ -67,7 +67,8 @@
+ #define raw_smp_processor_id() (current_thread_info()->cpu)
+
+ extern cpumask_t cpu_callout_map;
+-#define cpu_possible_map cpu_callout_map
++extern cpumask_t cpu_possible_map;
++extern cpumask_t cpu_present_map;
+
+ static __inline__ int hard_smp_processor_id(void)
+ {
+diff -Naur linux-2.6.16/include/asm-m32r/uaccess.h linux-2.6.16.16/include/asm-m32r/uaccess.h
+--- linux-2.6.16/include/asm-m32r/uaccess.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/asm-m32r/uaccess.h 2006-05-11 04:56:24.000000000 +0300
+@@ -5,17 +5,9 @@
+ * linux/include/asm-m32r/uaccess.h
+ *
+ * M32R version.
+- * Copyright (C) 2004 Hirokazu Takata <takata at linux-m32r.org>
++ * Copyright (C) 2004, 2006 Hirokazu Takata <takata at linux-m32r.org>
+ */
+
+-#undef UACCESS_DEBUG
+-
+-#ifdef UACCESS_DEBUG
+-#define UAPRINTK(args...) printk(args)
+-#else
+-#define UAPRINTK(args...)
+-#endif /* UACCESS_DEBUG */
+-
+ /*
+ * User space memory access functions
+ */
+@@ -38,27 +30,29 @@
+ #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
+
+ #ifdef CONFIG_MMU
++
+ #define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF)
+ #define USER_DS MAKE_MM_SEG(PAGE_OFFSET)
+-#else
+-#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF)
+-#define USER_DS MAKE_MM_SEG(0xFFFFFFFF)
+-#endif /* CONFIG_MMU */
+-
+ #define get_ds() (KERNEL_DS)
+-#ifdef CONFIG_MMU
+ #define get_fs() (current_thread_info()->addr_limit)
+ #define set_fs(x) (current_thread_info()->addr_limit = (x))
+-#else
++
++#else /* not CONFIG_MMU */
++
++#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF)
++#define USER_DS MAKE_MM_SEG(0xFFFFFFFF)
++#define get_ds() (KERNEL_DS)
++
+ static inline mm_segment_t get_fs(void)
+ {
+- return USER_DS;
++ return USER_DS;
+ }
+
+ static inline void set_fs(mm_segment_t s)
+ {
+ }
+-#endif /* CONFIG_MMU */
++
++#endif /* not CONFIG_MMU */
+
+ #define segment_eq(a,b) ((a).seg == (b).seg)
+
+@@ -83,9 +77,9 @@
+ " subx %0, %0\n" \
+ " cmpu %4, %1\n" \
+ " subx %0, %5\n" \
+- : "=&r"(flag), "=r"(sum) \
+- : "1"(addr), "r"((int)(size)), \
+- "r"(current_thread_info()->addr_limit.seg), "r"(0) \
++ : "=&r" (flag), "=r" (sum) \
++ : "1" (addr), "r" ((int)(size)), \
++ "r" (current_thread_info()->addr_limit.seg), "r" (0) \
+ : "cbit" ); \
+ flag; })
+
+@@ -113,10 +107,10 @@
+ #else
+ static inline int access_ok(int type, const void *addr, unsigned long size)
+ {
+- extern unsigned long memory_start, memory_end;
+- unsigned long val = (unsigned long)addr;
++ extern unsigned long memory_start, memory_end;
++ unsigned long val = (unsigned long)addr;
+
+- return ((val >= memory_start) && ((val + size) < memory_end));
++ return ((val >= memory_start) && ((val + size) < memory_end));
+ }
+ #endif /* CONFIG_MMU */
+
+@@ -155,39 +149,6 @@
+ * accesses to the same area of user memory).
+ */
+
+-extern void __get_user_1(void);
+-extern void __get_user_2(void);
+-extern void __get_user_4(void);
+-
+-#ifndef MODULE
+-#define __get_user_x(size,ret,x,ptr) \
+- __asm__ __volatile__( \
+- " mv r0, %0\n" \
+- " mv r1, %1\n" \
+- " bl __get_user_" #size "\n" \
+- " mv %0, r0\n" \
+- " mv %1, r1\n" \
+- : "=r"(ret), "=r"(x) \
+- : "0"(ptr) \
+- : "r0", "r1", "r14" )
+-#else /* MODULE */
+-/*
+- * Use "jl" instead of "bl" for MODULE
+- */
+-#define __get_user_x(size,ret,x,ptr) \
+- __asm__ __volatile__( \
+- " mv r0, %0\n" \
+- " mv r1, %1\n" \
+- " seth lr, #high(__get_user_" #size ")\n" \
+- " or3 lr, lr, #low(__get_user_" #size ")\n" \
+- " jl lr\n" \
+- " mv %0, r0\n" \
+- " mv %1, r1\n" \
+- : "=r"(ret), "=r"(x) \
+- : "0"(ptr) \
+- : "r0", "r1", "r14" )
+-#endif
+-
+ /* Careful: we have to cast the result to the type of the pointer for sign
+ reasons */
+ /**
+@@ -208,20 +169,7 @@
+ * On error, the variable @x is set to zero.
+ */
+ #define get_user(x,ptr) \
+-({ int __ret_gu; \
+- unsigned long __val_gu; \
+- __chk_user_ptr(ptr); \
+- switch(sizeof (*(ptr))) { \
+- case 1: __get_user_x(1,__ret_gu,__val_gu,ptr); break; \
+- case 2: __get_user_x(2,__ret_gu,__val_gu,ptr); break; \
+- case 4: __get_user_x(4,__ret_gu,__val_gu,ptr); break; \
+- default: __get_user_x(X,__ret_gu,__val_gu,ptr); break; \
+- } \
+- (x) = (__typeof__(*(ptr)))__val_gu; \
+- __ret_gu; \
+-})
+-
+-extern void __put_user_bad(void);
++ __get_user_check((x),(ptr),sizeof(*(ptr)))
+
+ /**
+ * put_user: - Write a simple value into user space.
+@@ -240,8 +188,7 @@
+ * Returns zero on success, or -EFAULT on error.
+ */
+ #define put_user(x,ptr) \
+- __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+-
++ __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+
+ /**
+ * __get_user: - Get a simple variable from user space, with less checking.
+@@ -264,8 +211,64 @@
+ * On error, the variable @x is set to zero.
+ */
+ #define __get_user(x,ptr) \
+- __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
++ __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+
++#define __get_user_nocheck(x,ptr,size) \
++({ \
++ long __gu_err = 0; \
++ unsigned long __gu_val; \
++ might_sleep(); \
++ __get_user_size(__gu_val,(ptr),(size),__gu_err); \
++ (x) = (__typeof__(*(ptr)))__gu_val; \
++ __gu_err; \
++})
++
++#define __get_user_check(x,ptr,size) \
++({ \
++ long __gu_err = -EFAULT; \
++ unsigned long __gu_val = 0; \
++ const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
++ might_sleep(); \
++ if (access_ok(VERIFY_READ,__gu_addr,size)) \
++ __get_user_size(__gu_val,__gu_addr,(size),__gu_err); \
++ (x) = (__typeof__(*(ptr)))__gu_val; \
++ __gu_err; \
++})
++
++extern long __get_user_bad(void);
++
++#define __get_user_size(x,ptr,size,retval) \
++do { \
++ retval = 0; \
++ __chk_user_ptr(ptr); \
++ switch (size) { \
++ case 1: __get_user_asm(x,ptr,retval,"ub"); break; \
++ case 2: __get_user_asm(x,ptr,retval,"uh"); break; \
++ case 4: __get_user_asm(x,ptr,retval,""); break; \
++ default: (x) = __get_user_bad(); \
++ } \
++} while (0)
++
++#define __get_user_asm(x, addr, err, itype) \
++ __asm__ __volatile__( \
++ " .fillinsn\n" \
++ "1: ld"itype" %1,@%2\n" \
++ " .fillinsn\n" \
++ "2:\n" \
++ ".section .fixup,\"ax\"\n" \
++ " .balign 4\n" \
++ "3: ldi %0,%3\n" \
++ " seth r14,#high(2b)\n" \
++ " or3 r14,r14,#low(2b)\n" \
++ " jmp r14\n" \
++ ".previous\n" \
++ ".section __ex_table,\"a\"\n" \
++ " .balign 4\n" \
++ " .long 1b,3b\n" \
++ ".previous" \
++ : "=&r" (err), "=&r" (x) \
++ : "r" (addr), "i" (-EFAULT), "0" (err) \
++ : "r14", "memory")
+
+ /**
+ * __put_user: - Write a simple value into user space, with less checking.
+@@ -287,11 +290,13 @@
+ * Returns zero on success, or -EFAULT on error.
+ */
+ #define __put_user(x,ptr) \
+- __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
++ __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
++
+
+ #define __put_user_nocheck(x,ptr,size) \
+ ({ \
+ long __pu_err; \
++ might_sleep(); \
+ __put_user_size((x),(ptr),(size),__pu_err); \
+ __pu_err; \
+ })
+@@ -308,28 +313,28 @@
+ })
+
+ #if defined(__LITTLE_ENDIAN__)
+-#define __put_user_u64(x, addr, err) \
+- __asm__ __volatile__( \
+- " .fillinsn\n" \
+- "1: st %L1,@%2\n" \
+- " .fillinsn\n" \
+- "2: st %H1,@(4,%2)\n" \
+- " .fillinsn\n" \
+- "3:\n" \
+- ".section .fixup,\"ax\"\n" \
+- " .balign 4\n" \
+- "4: ldi %0,%3\n" \
+- " seth r14,#high(3b)\n" \
+- " or3 r14,r14,#low(3b)\n" \
+- " jmp r14\n" \
+- ".previous\n" \
+- ".section __ex_table,\"a\"\n" \
+- " .balign 4\n" \
+- " .long 1b,4b\n" \
+- " .long 2b,4b\n" \
+- ".previous" \
+- : "=&r"(err) \
+- : "r"(x), "r"(addr), "i"(-EFAULT), "0"(err) \
++#define __put_user_u64(x, addr, err) \
++ __asm__ __volatile__( \
++ " .fillinsn\n" \
++ "1: st %L1,@%2\n" \
++ " .fillinsn\n" \
++ "2: st %H1,@(4,%2)\n" \
++ " .fillinsn\n" \
++ "3:\n" \
++ ".section .fixup,\"ax\"\n" \
++ " .balign 4\n" \
++ "4: ldi %0,%3\n" \
++ " seth r14,#high(3b)\n" \
++ " or3 r14,r14,#low(3b)\n" \
++ " jmp r14\n" \
++ ".previous\n" \
++ ".section __ex_table,\"a\"\n" \
++ " .balign 4\n" \
++ " .long 1b,4b\n" \
++ " .long 2b,4b\n" \
++ ".previous" \
++ : "=&r" (err) \
++ : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err) \
+ : "r14", "memory")
+
+ #elif defined(__BIG_ENDIAN__)
+@@ -353,13 +358,15 @@
+ " .long 1b,4b\n" \
+ " .long 2b,4b\n" \
+ ".previous" \
+- : "=&r"(err) \
+- : "r"(x), "r"(addr), "i"(-EFAULT), "0"(err) \
++ : "=&r" (err) \
++ : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err) \
+ : "r14", "memory")
+ #else
+ #error no endian defined
+ #endif
+
++extern void __put_user_bad(void);
++
+ #define __put_user_size(x,ptr,size,retval) \
+ do { \
+ retval = 0; \
+@@ -398,52 +405,8 @@
+ " .balign 4\n" \
+ " .long 1b,3b\n" \
+ ".previous" \
+- : "=&r"(err) \
+- : "r"(x), "r"(addr), "i"(-EFAULT), "0"(err) \
+- : "r14", "memory")
+-
+-#define __get_user_nocheck(x,ptr,size) \
+-({ \
+- long __gu_err; \
+- unsigned long __gu_val; \
+- __get_user_size(__gu_val,(ptr),(size),__gu_err); \
+- (x) = (__typeof__(*(ptr)))__gu_val; \
+- __gu_err; \
+-})
+-
+-extern long __get_user_bad(void);
+-
+-#define __get_user_size(x,ptr,size,retval) \
+-do { \
+- retval = 0; \
+- __chk_user_ptr(ptr); \
+- switch (size) { \
+- case 1: __get_user_asm(x,ptr,retval,"ub"); break; \
+- case 2: __get_user_asm(x,ptr,retval,"uh"); break; \
+- case 4: __get_user_asm(x,ptr,retval,""); break; \
+- default: (x) = __get_user_bad(); \
+- } \
+-} while (0)
+-
+-#define __get_user_asm(x, addr, err, itype) \
+- __asm__ __volatile__( \
+- " .fillinsn\n" \
+- "1: ld"itype" %1,@%2\n" \
+- " .fillinsn\n" \
+- "2:\n" \
+- ".section .fixup,\"ax\"\n" \
+- " .balign 4\n" \
+- "3: ldi %0,%3\n" \
+- " seth r14,#high(2b)\n" \
+- " or3 r14,r14,#low(2b)\n" \
+- " jmp r14\n" \
+- ".previous\n" \
+- ".section __ex_table,\"a\"\n" \
+- " .balign 4\n" \
+- " .long 1b,3b\n" \
+- ".previous" \
+- : "=&r"(err), "=&r"(x) \
+- : "r"(addr), "i"(-EFAULT), "0"(err) \
++ : "=&r" (err) \
++ : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err) \
+ : "r14", "memory")
+
+ /*
+@@ -453,7 +416,6 @@
+ * anything, so this is accurate.
+ */
+
+-
+ /*
+ * Copy To/From Userspace
+ */
+@@ -511,8 +473,9 @@
+ " .long 2b,9b\n" \
+ " .long 3b,9b\n" \
+ ".previous\n" \
+- : "=&r"(__dst), "=&r"(__src), "=&r"(size), "=&r"(__c) \
+- : "0"(to), "1"(from), "2"(size), "3"(size / 4) \
++ : "=&r" (__dst), "=&r" (__src), "=&r" (size), \
++ "=&r" (__c) \
++ : "0" (to), "1" (from), "2" (size), "3" (size / 4) \
+ : "r14", "memory"); \
+ } while (0)
+
+@@ -573,8 +536,9 @@
+ " .long 2b,7b\n" \
+ " .long 3b,7b\n" \
+ ".previous\n" \
+- : "=&r"(__dst), "=&r"(__src), "=&r"(size), "=&r"(__c) \
+- : "0"(to), "1"(from), "2"(size), "3"(size / 4) \
++ : "=&r" (__dst), "=&r" (__src), "=&r" (size), \
++ "=&r" (__c) \
++ : "0" (to), "1" (from), "2" (size), "3" (size / 4) \
+ : "r14", "memory"); \
+ } while (0)
+
+@@ -676,7 +640,7 @@
+ #define copy_from_user(to,from,n) \
+ ({ \
+ might_sleep(); \
+-__generic_copy_from_user((to),(from),(n)); \
++ __generic_copy_from_user((to),(from),(n)); \
+ })
+
+ long __must_check strncpy_from_user(char *dst, const char __user *src,
+diff -Naur linux-2.6.16/include/asm-mips/bitops.h linux-2.6.16.16/include/asm-mips/bitops.h
+--- linux-2.6.16/include/asm-mips/bitops.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/asm-mips/bitops.h 2006-05-11 04:56:24.000000000 +0300
+@@ -654,7 +654,12 @@
+ {
+ #ifdef CONFIG_32BIT
+ #ifdef CONFIG_CPU_MIPS32
+- __asm__ ("clz %0, %1" : "=r" (word) : "r" (word));
++ __asm__ (
++ " .set mips32 \n"
++ " clz %0, %1 \n"
++ " .set mips0 \n"
++ : "=r" (word)
++ : "r" (word));
+
+ return 32 - word;
+ #else
+@@ -678,7 +683,12 @@
+ #ifdef CONFIG_64BIT
+ #ifdef CONFIG_CPU_MIPS64
+
+- __asm__ ("dclz %0, %1" : "=r" (word) : "r" (word));
++ __asm__ (
++ " .set mips64 \n"
++ " dclz %0, %1 \n"
++ " .set mips0 \n"
++ : "=r" (word)
++ : "r" (word));
+
+ return 64 - word;
+ #else
+diff -Naur linux-2.6.16/include/asm-mips/byteorder.h linux-2.6.16.16/include/asm-mips/byteorder.h
+--- linux-2.6.16/include/asm-mips/byteorder.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/asm-mips/byteorder.h 2006-05-11 04:56:24.000000000 +0300
+@@ -19,7 +19,9 @@
+ static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
+ {
+ __asm__(
++ " .set mips32r2 \n"
+ " wsbh %0, %1 \n"
++ " .set mips0 \n"
+ : "=r" (x)
+ : "r" (x));
+
+@@ -30,8 +32,10 @@
+ static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
+ {
+ __asm__(
++ " .set mips32r2 \n"
+ " wsbh %0, %1 \n"
+ " rotr %0, %0, 16 \n"
++ " .set mips0 \n"
+ : "=r" (x)
+ : "r" (x));
+
+diff -Naur linux-2.6.16/include/asm-mips/interrupt.h linux-2.6.16.16/include/asm-mips/interrupt.h
+--- linux-2.6.16/include/asm-mips/interrupt.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/asm-mips/interrupt.h 2006-05-11 04:56:24.000000000 +0300
+@@ -20,7 +20,9 @@
+ " .set reorder \n"
+ " .set noat \n"
+ #ifdef CONFIG_CPU_MIPSR2
++ " .set mips32r2 \n"
+ " ei \n"
++ " .set mips0 \n"
+ #else
+ " mfc0 $1,$12 \n"
+ " ori $1,0x1f \n"
+@@ -63,7 +65,9 @@
+ " .set push \n"
+ " .set noat \n"
+ #ifdef CONFIG_CPU_MIPSR2
++ " .set mips32r2 \n"
+ " di \n"
++ " .set mips0 \n"
+ #else
+ " mfc0 $1,$12 \n"
+ " ori $1,0x1f \n"
+@@ -103,8 +107,10 @@
+ " .set reorder \n"
+ " .set noat \n"
+ #ifdef CONFIG_CPU_MIPSR2
++ " .set mips32r2 \n"
+ " di \\result \n"
+ " andi \\result, 1 \n"
++ " .set mips0 \n"
+ #else
+ " mfc0 \\result, $12 \n"
+ " ori $1, \\result, 0x1f \n"
+@@ -133,9 +139,11 @@
+ * Slow, but doesn't suffer from a relativly unlikely race
+ * condition we're having since days 1.
+ */
++ " .set mips32r2 \n"
+ " beqz \\flags, 1f \n"
+ " di \n"
+ " ei \n"
++ " .set mips0 \n"
+ "1: \n"
+ #elif defined(CONFIG_CPU_MIPSR2)
+ /*
+diff -Naur linux-2.6.16/include/asm-mips/r4kcache.h linux-2.6.16.16/include/asm-mips/r4kcache.h
+--- linux-2.6.16/include/asm-mips/r4kcache.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/asm-mips/r4kcache.h 2006-05-11 04:56:24.000000000 +0300
+@@ -37,7 +37,7 @@
+ " cache %0, %1 \n" \
+ " .set pop \n" \
+ : \
+- : "i" (op), "m" (*(unsigned char *)(addr)))
++ : "i" (op), "R" (*(unsigned char *)(addr)))
+
+ static inline void flush_icache_line_indexed(unsigned long addr)
+ {
+diff -Naur linux-2.6.16/include/asm-powerpc/floppy.h linux-2.6.16.16/include/asm-powerpc/floppy.h
+--- linux-2.6.16/include/asm-powerpc/floppy.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/asm-powerpc/floppy.h 2006-05-11 04:56:24.000000000 +0300
+@@ -35,6 +35,7 @@
+ #ifdef CONFIG_PCI
+
+ #include <linux/pci.h>
++#include <asm/ppc-pci.h> /* for ppc64_isabridge_dev */
+
+ #define fd_dma_setup(addr,size,mode,io) powerpc_fd_dma_setup(addr,size,mode,io)
+
+@@ -52,12 +53,12 @@
+ if (bus_addr
+ && (addr != prev_addr || size != prev_size || dir != prev_dir)) {
+ /* different from last time -- unmap prev */
+- pci_unmap_single(NULL, bus_addr, prev_size, prev_dir);
++ pci_unmap_single(ppc64_isabridge_dev, bus_addr, prev_size, prev_dir);
+ bus_addr = 0;
+ }
+
+ if (!bus_addr) /* need to map it */
+- bus_addr = pci_map_single(NULL, addr, size, dir);
++ bus_addr = pci_map_single(ppc64_isabridge_dev, addr, size, dir);
+
+ /* remember this one as prev */
+ prev_addr = addr;
+diff -Naur linux-2.6.16/include/asm-x86_64/cpufeature.h linux-2.6.16.16/include/asm-x86_64/cpufeature.h
+--- linux-2.6.16/include/asm-x86_64/cpufeature.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/asm-x86_64/cpufeature.h 2006-05-11 04:56:24.000000000 +0300
+@@ -64,6 +64,7 @@
+ #define X86_FEATURE_REP_GOOD (3*32+ 4) /* rep microcode works well on this CPU */
+ #define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */
+ #define X86_FEATURE_SYNC_RDTSC (3*32+6) /* RDTSC syncs CPU core */
++#define X86_FEATURE_FXSAVE_LEAK (3*32+7) /* FIP/FOP/FDP leaks through FXSAVE */
+
+ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
+ #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */
+diff -Naur linux-2.6.16/include/asm-x86_64/i387.h linux-2.6.16.16/include/asm-x86_64/i387.h
+--- linux-2.6.16/include/asm-x86_64/i387.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/asm-x86_64/i387.h 2006-05-11 04:56:24.000000000 +0300
+@@ -72,6 +72,23 @@
+ #define set_fpu_swd(t,val) ((t)->thread.i387.fxsave.swd = (val))
+ #define set_fpu_fxsr_twd(t,val) ((t)->thread.i387.fxsave.twd = (val))
+
++#define X87_FSW_ES (1 << 7) /* Exception Summary */
++
++/* AMD CPUs don't save/restore FDP/FIP/FOP unless an exception
++ is pending. Clear the x87 state here by setting it to fixed
++ values. The kernel data segment can be sometimes 0 and sometimes
++ new user value. Both should be ok.
++ Use the PDA as safe address because it should be already in L1. */
++static inline void clear_fpu_state(struct i387_fxsave_struct *fx)
++{
++ if (unlikely(fx->swd & X87_FSW_ES))
++ asm volatile("fnclex");
++ alternative_input(ASM_NOP8 ASM_NOP2,
++ " emms\n" /* clear stack tags */
++ " fildl %%gs:0", /* load to clear state */
++ X86_FEATURE_FXSAVE_LEAK);
++}
++
+ static inline int restore_fpu_checking(struct i387_fxsave_struct *fx)
+ {
+ int err;
+@@ -119,6 +136,7 @@
+ #endif
+ if (unlikely(err))
+ __clear_user(fx, sizeof(struct i387_fxsave_struct));
++ /* No need to clear here because the caller clears USED_MATH */
+ return err;
+ }
+
+@@ -149,7 +167,7 @@
+ "i" (offsetof(__typeof__(*tsk),
+ thread.i387.fxsave)));
+ #endif
+- __asm__ __volatile__("fnclex");
++ clear_fpu_state(&tsk->thread.i387.fxsave);
+ }
+
+ static inline void kernel_fpu_begin(void)
+diff -Naur linux-2.6.16/include/linux/cpu.h linux-2.6.16.16/include/linux/cpu.h
+--- linux-2.6.16/include/linux/cpu.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/linux/cpu.h 2006-05-11 04:56:24.000000000 +0300
+@@ -32,7 +32,7 @@
+ };
+
+ extern int register_cpu(struct cpu *, int, struct node *);
+-extern struct sys_device *get_cpu_sysdev(int cpu);
++extern struct sys_device *get_cpu_sysdev(unsigned cpu);
+ #ifdef CONFIG_HOTPLUG_CPU
+ extern void unregister_cpu(struct cpu *, struct node *);
+ #endif
+diff -Naur linux-2.6.16/include/linux/cpumask.h linux-2.6.16.16/include/linux/cpumask.h
+--- linux-2.6.16/include/linux/cpumask.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/linux/cpumask.h 2006-05-11 04:56:24.000000000 +0300
+@@ -408,6 +408,7 @@
+ })
+
+ #define for_each_cpu(cpu) for_each_cpu_mask((cpu), cpu_possible_map)
++#define for_each_possible_cpu(cpu) for_each_cpu_mask((cpu), cpu_possible_map)
+ #define for_each_online_cpu(cpu) for_each_cpu_mask((cpu), cpu_online_map)
+ #define for_each_present_cpu(cpu) for_each_cpu_mask((cpu), cpu_present_map)
+
+diff -Naur linux-2.6.16/include/linux/fb.h linux-2.6.16.16/include/linux/fb.h
+--- linux-2.6.16/include/linux/fb.h 2006-05-18 01:12:24.000000000 +0300
++++ linux-2.6.16.16/include/linux/fb.h 2006-05-17 21:41:31.000000000 +0300
+@@ -840,12 +840,10 @@
+ #define FB_LEFT_POS(bpp) (32 - bpp)
+ #define FB_SHIFT_HIGH(val, bits) ((val) >> (bits))
+ #define FB_SHIFT_LOW(val, bits) ((val) << (bits))
+-#define FB_BIT_NR(b) (7 - (b))
+ #else
+ #define FB_LEFT_POS(bpp) (0)
+ #define FB_SHIFT_HIGH(val, bits) ((val) << (bits))
+ #define FB_SHIFT_LOW(val, bits) ((val) >> (bits))
+-#define FB_BIT_NR(b) (b)
+ #endif
+
+ /*
+diff -Naur linux-2.6.16/include/linux/fs.h linux-2.6.16.16/include/linux/fs.h
+--- linux-2.6.16/include/linux/fs.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/linux/fs.h 2006-05-11 04:56:24.000000000 +0300
+@@ -1383,6 +1383,7 @@
+ extern void bd_release(struct block_device *);
+
+ /* fs/char_dev.c */
++#define CHRDEV_MAJOR_HASH_SIZE 255
+ extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *);
+ extern int register_chrdev_region(dev_t, unsigned, const char *);
+ extern int register_chrdev(unsigned int, const char *,
+@@ -1390,25 +1391,17 @@
+ extern int unregister_chrdev(unsigned int, const char *);
+ extern void unregister_chrdev_region(dev_t, unsigned);
+ extern int chrdev_open(struct inode *, struct file *);
+-extern int get_chrdev_list(char *);
+-extern void *acquire_chrdev_list(void);
+-extern int count_chrdev_list(void);
+-extern void *get_next_chrdev(void *);
+-extern int get_chrdev_info(void *, int *, char **);
+-extern void release_chrdev_list(void *);
++extern void chrdev_show(struct seq_file *,off_t);
+
+ /* fs/block_dev.c */
++#define BLKDEV_MAJOR_HASH_SIZE 255
+ #define BDEVNAME_SIZE 32 /* Largest string for a blockdev identifier */
+ extern const char *__bdevname(dev_t, char *buffer);
+ extern const char *bdevname(struct block_device *bdev, char *buffer);
+ extern struct block_device *lookup_bdev(const char *);
+ extern struct block_device *open_bdev_excl(const char *, int, void *);
+ extern void close_bdev_excl(struct block_device *);
+-extern void *acquire_blkdev_list(void);
+-extern int count_blkdev_list(void);
+-extern void *get_next_blkdev(void *);
+-extern int get_blkdev_info(void *, int *, char **);
+-extern void release_blkdev_list(void *);
++extern void blkdev_show(struct seq_file *,off_t);
+
+ extern void init_special_inode(struct inode *, umode_t, dev_t);
+
+diff -Naur linux-2.6.16/include/linux/mm.h linux-2.6.16.16/include/linux/mm.h
+--- linux-2.6.16/include/linux/mm.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/linux/mm.h 2006-05-11 04:56:24.000000000 +0300
+@@ -229,10 +229,9 @@
+ unsigned long private; /* Mapping-private opaque data:
+ * usually used for buffer_heads
+ * if PagePrivate set; used for
+- * swp_entry_t if PageSwapCache.
+- * When page is free, this
++ * swp_entry_t if PageSwapCache;
+ * indicates order in the buddy
+- * system.
++ * system if PG_buddy is set.
+ */
+ struct address_space *mapping; /* If low bit clear, points to
+ * inode address_space, or NULL.
+diff -Naur linux-2.6.16/include/linux/page-flags.h linux-2.6.16.16/include/linux/page-flags.h
+--- linux-2.6.16/include/linux/page-flags.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/linux/page-flags.h 2006-05-11 04:56:24.000000000 +0300
+@@ -74,7 +74,9 @@
+ #define PG_mappedtodisk 16 /* Has blocks allocated on-disk */
+ #define PG_reclaim 17 /* To be reclaimed asap */
+ #define PG_nosave_free 18 /* Free, should not be written */
+-#define PG_uncached 19 /* Page has been mapped as uncached */
++#define PG_buddy 19 /* Page is free, on buddy lists */
++
++#define PG_uncached 20 /* Page has been mapped as uncached */
+
+ /*
+ * Global page accounting. One instance per CPU. Only unsigned longs are
+@@ -319,6 +321,10 @@
+ #define SetPageNosaveFree(page) set_bit(PG_nosave_free, &(page)->flags)
+ #define ClearPageNosaveFree(page) clear_bit(PG_nosave_free, &(page)->flags)
+
++#define PageBuddy(page) test_bit(PG_buddy, &(page)->flags)
++#define __SetPageBuddy(page) __set_bit(PG_buddy, &(page)->flags)
++#define __ClearPageBuddy(page) __clear_bit(PG_buddy, &(page)->flags)
++
+ #define PageMappedToDisk(page) test_bit(PG_mappedtodisk, &(page)->flags)
+ #define SetPageMappedToDisk(page) set_bit(PG_mappedtodisk, &(page)->flags)
+ #define ClearPageMappedToDisk(page) clear_bit(PG_mappedtodisk, &(page)->flags)
+diff -Naur linux-2.6.16/include/linux/proc_fs.h linux-2.6.16.16/include/linux/proc_fs.h
+--- linux-2.6.16/include/linux/proc_fs.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/linux/proc_fs.h 2006-05-11 04:56:24.000000000 +0300
+@@ -78,7 +78,7 @@
+ struct vmcore {
+ struct list_head list;
+ unsigned long long paddr;
+- unsigned long size;
++ unsigned long long size;
+ loff_t offset;
+ };
+
+diff -Naur linux-2.6.16/include/linux/raid/raid1.h linux-2.6.16.16/include/linux/raid/raid1.h
+--- linux-2.6.16/include/linux/raid/raid1.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/linux/raid/raid1.h 2006-05-11 04:56:24.000000000 +0300
+@@ -130,6 +130,6 @@
+ * with failure when last write completes (and all failed).
+ * Record that bi_end_io was called with this flag...
+ */
+-#define R1BIO_Returned 4
++#define R1BIO_Returned 6
+
+ #endif
+diff -Naur linux-2.6.16/include/linux/rtc.h linux-2.6.16.16/include/linux/rtc.h
+--- linux-2.6.16/include/linux/rtc.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/linux/rtc.h 2006-05-11 04:56:24.000000000 +0300
+@@ -11,8 +11,6 @@
+ #ifndef _LINUX_RTC_H_
+ #define _LINUX_RTC_H_
+
+-#include <linux/interrupt.h>
+-
+ /*
+ * The struct used to pass data via the following ioctl. Similar to the
+ * struct tm in <time.h>, but it needs to be here so that the kernel
+@@ -95,6 +93,8 @@
+
+ #ifdef __KERNEL__
+
++#include <linux/interrupt.h>
++
+ typedef struct rtc_task {
+ void (*func)(void *private_data);
+ void *private_data;
+diff -Naur linux-2.6.16/include/net/ip.h linux-2.6.16.16/include/net/ip.h
+--- linux-2.6.16/include/net/ip.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/net/ip.h 2006-05-11 04:56:24.000000000 +0300
+@@ -95,6 +95,7 @@
+ extern int ip_mr_input(struct sk_buff *skb);
+ extern int ip_output(struct sk_buff *skb);
+ extern int ip_mc_output(struct sk_buff *skb);
++extern int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
+ extern int ip_do_nat(struct sk_buff *skb);
+ extern void ip_send_check(struct iphdr *ip);
+ extern int ip_queue_xmit(struct sk_buff *skb, int ipfragok);
+diff -Naur linux-2.6.16/include/net/sctp/structs.h linux-2.6.16.16/include/net/sctp/structs.h
+--- linux-2.6.16/include/net/sctp/structs.h 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/include/net/sctp/structs.h 2006-05-11 04:56:24.000000000 +0300
+@@ -702,6 +702,7 @@
+ __u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */
+ __s8 fast_retransmit; /* Is this chunk fast retransmitted? */
+ __u8 tsn_missing_report; /* Data chunk missing counter. */
++ __u8 data_accepted; /* At least 1 chunk in this packet accepted */
+ };
+
+ void sctp_chunk_hold(struct sctp_chunk *);
+diff -Naur linux-2.6.16/ipc/shm.c linux-2.6.16.16/ipc/shm.c
+--- linux-2.6.16/ipc/shm.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/ipc/shm.c 2006-05-11 04:56:24.000000000 +0300
+@@ -161,6 +161,8 @@
+ ret = shmem_mmap(file, vma);
+ if (ret == 0) {
+ vma->vm_ops = &shm_vm_ops;
++ if (!(vma->vm_flags & VM_WRITE))
++ vma->vm_flags &= ~VM_MAYWRITE;
+ shm_inc(file->f_dentry->d_inode->i_ino);
+ }
+
+diff -Naur linux-2.6.16/ipc/util.c linux-2.6.16.16/ipc/util.c
+--- linux-2.6.16/ipc/util.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/ipc/util.c 2006-05-11 04:56:24.000000000 +0300
+@@ -182,8 +182,7 @@
+ if(new == NULL)
+ return size;
+ new->size = newsize;
+- memcpy(new->p, ids->entries->p, sizeof(struct kern_ipc_perm *)*size +
+- sizeof(struct ipc_id_ary));
++ memcpy(new->p, ids->entries->p, sizeof(struct kern_ipc_perm *)*size);
+ for(i=size;i<newsize;i++) {
+ new->p[i] = NULL;
+ }
+diff -Naur linux-2.6.16/kernel/auditsc.c linux-2.6.16.16/kernel/auditsc.c
+--- linux-2.6.16/kernel/auditsc.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/kernel/auditsc.c 2006-05-11 04:56:24.000000000 +0300
+@@ -966,11 +966,6 @@
+ if (context->in_syscall) {
+ struct audit_context *newctx;
+
+-#if defined(__NR_vm86) && defined(__NR_vm86old)
+- /* vm86 mode should only be entered once */
+- if (major == __NR_vm86 || major == __NR_vm86old)
+- return;
+-#endif
+ #if AUDIT_DEBUG
+ printk(KERN_ERR
+ "audit(:%d) pid=%d in syscall=%d;"
+diff -Naur linux-2.6.16/kernel/exec_domain.c linux-2.6.16.16/kernel/exec_domain.c
+--- linux-2.6.16/kernel/exec_domain.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/kernel/exec_domain.c 2006-05-11 04:56:24.000000000 +0300
+@@ -140,6 +140,7 @@
+ ep = lookup_exec_domain(personality);
+ if (ep == current_thread_info()->exec_domain) {
+ current->personality = personality;
++ module_put(ep->module);
+ return 0;
+ }
+
+diff -Naur linux-2.6.16/kernel/fork.c linux-2.6.16.16/kernel/fork.c
+--- linux-2.6.16/kernel/fork.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/kernel/fork.c 2006-05-11 04:56:24.000000000 +0300
+@@ -720,7 +720,7 @@
+ free_fdset (new_fdt->open_fds, new_fdt->max_fdset);
+ free_fd_array(new_fdt->fd, new_fdt->max_fds);
+ kmem_cache_free(files_cachep, newf);
+- goto out;
++ return NULL;
+ }
+
+ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
+diff -Naur linux-2.6.16/kernel/power/process.c linux-2.6.16.16/kernel/power/process.c
+--- linux-2.6.16/kernel/power/process.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/kernel/power/process.c 2006-05-11 04:56:24.000000000 +0300
+@@ -25,8 +25,7 @@
+ (p->flags & PF_NOFREEZE) ||
+ (p->exit_state == EXIT_ZOMBIE) ||
+ (p->exit_state == EXIT_DEAD) ||
+- (p->state == TASK_STOPPED) ||
+- (p->state == TASK_TRACED))
++ (p->state == TASK_STOPPED))
+ return 0;
+ return 1;
+ }
+diff -Naur linux-2.6.16/kernel/ptrace.c linux-2.6.16.16/kernel/ptrace.c
+--- linux-2.6.16/kernel/ptrace.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/kernel/ptrace.c 2006-05-11 04:56:24.000000000 +0300
+@@ -57,10 +57,6 @@
+ signal_wake_up(child, 1);
+ }
+ }
+- if (child->signal->flags & SIGNAL_GROUP_EXIT) {
+- sigaddset(&child->pending.signal, SIGKILL);
+- signal_wake_up(child, 1);
+- }
+ spin_unlock(&child->sighand->siglock);
+ }
+
+@@ -82,7 +78,8 @@
+ SET_LINKS(child);
+ }
+
+- ptrace_untrace(child);
++ if (child->state == TASK_TRACED)
++ ptrace_untrace(child);
+ }
+
+ /*
+diff -Naur linux-2.6.16/kernel/sched.c linux-2.6.16.16/kernel/sched.c
+--- linux-2.6.16/kernel/sched.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/kernel/sched.c 2006-05-11 04:56:24.000000000 +0300
+@@ -237,6 +237,7 @@
+
+ task_t *migration_thread;
+ struct list_head migration_queue;
++ int cpu;
+ #endif
+
+ #ifdef CONFIG_SCHEDSTATS
+@@ -1660,6 +1661,9 @@
+ /*
+ * double_rq_lock - safely lock two runqueues
+ *
++ * We must take them in cpu order to match code in
++ * dependent_sleeper and wake_dependent_sleeper.
++ *
+ * Note this does not disable interrupts like task_rq_lock,
+ * you need to do so manually before calling.
+ */
+@@ -1671,7 +1675,7 @@
+ spin_lock(&rq1->lock);
+ __acquire(rq2->lock); /* Fake it out ;) */
+ } else {
+- if (rq1 < rq2) {
++ if (rq1->cpu < rq2->cpu) {
+ spin_lock(&rq1->lock);
+ spin_lock(&rq2->lock);
+ } else {
+@@ -1707,7 +1711,7 @@
+ __acquires(this_rq->lock)
+ {
+ if (unlikely(!spin_trylock(&busiest->lock))) {
+- if (busiest < this_rq) {
++ if (busiest->cpu < this_rq->cpu) {
+ spin_unlock(&this_rq->lock);
+ spin_lock(&busiest->lock);
+ spin_lock(&this_rq->lock);
+@@ -6035,6 +6039,7 @@
+ rq->push_cpu = 0;
+ rq->migration_thread = NULL;
+ INIT_LIST_HEAD(&rq->migration_queue);
++ rq->cpu = i;
+ #endif
+ atomic_set(&rq->nr_iowait, 0);
+
+diff -Naur linux-2.6.16/kernel/signal.c linux-2.6.16.16/kernel/signal.c
+--- linux-2.6.16/kernel/signal.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/kernel/signal.c 2006-05-11 04:56:24.000000000 +0300
+@@ -975,7 +975,6 @@
+ if (t == NULL)
+ /* restart balancing at this thread */
+ t = p->signal->curr_target = p;
+- BUG_ON(t->tgid != p->tgid);
+
+ while (!wants_signal(sig, t)) {
+ t = next_thread(t);
+@@ -1689,6 +1688,7 @@
+ /* Let the debugger run. */
+ set_current_state(TASK_TRACED);
+ spin_unlock_irq(&current->sighand->siglock);
++ try_to_freeze();
+ read_lock(&tasklist_lock);
+ if (likely(current->ptrace & PT_PTRACED) &&
+ likely(current->parent != current->real_parent ||
+@@ -1942,9 +1942,9 @@
+ /* Let the debugger run. */
+ ptrace_stop(signr, signr, info);
+
+- /* We're back. Did the debugger cancel the sig or group_exit? */
++ /* We're back. Did the debugger cancel the sig? */
+ signr = current->exit_code;
+- if (signr == 0 || current->signal->flags & SIGNAL_GROUP_EXIT)
++ if (signr == 0)
+ continue;
+
+ current->exit_code = 0;
+diff -Naur linux-2.6.16/kernel/sys.c linux-2.6.16.16/kernel/sys.c
+--- linux-2.6.16/kernel/sys.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/kernel/sys.c 2006-05-11 04:56:24.000000000 +0300
+@@ -1657,7 +1657,19 @@
+ (cputime_eq(current->signal->it_prof_expires, cputime_zero) ||
+ new_rlim.rlim_cur <= cputime_to_secs(
+ current->signal->it_prof_expires))) {
+- cputime_t cputime = secs_to_cputime(new_rlim.rlim_cur);
++ unsigned long rlim_cur = new_rlim.rlim_cur;
++ cputime_t cputime;
++
++ if (rlim_cur == 0) {
++ /*
++ * The caller is asking for an immediate RLIMIT_CPU
++ * expiry. But we use the zero value to mean "it was
++ * never set". So let's cheat and make it one second
++ * instead
++ */
++ rlim_cur = 1;
++ }
++ cputime = secs_to_cputime(rlim_cur);
+ read_lock(&tasklist_lock);
+ spin_lock_irq(&current->sighand->siglock);
+ set_process_cpu_timer(current, CPUCLOCK_PROF,
+diff -Naur linux-2.6.16/kernel/uid16.c linux-2.6.16.16/kernel/uid16.c
+--- linux-2.6.16/kernel/uid16.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/kernel/uid16.c 2006-05-11 04:56:24.000000000 +0300
+@@ -20,43 +20,67 @@
+
+ asmlinkage long sys_chown16(const char __user * filename, old_uid_t user, old_gid_t group)
+ {
+- return sys_chown(filename, low2highuid(user), low2highgid(group));
++ long ret = sys_chown(filename, low2highuid(user), low2highgid(group));
++ /* avoid REGPARM breakage on x86: */
++ prevent_tail_call(ret);
++ return ret;
+ }
+
+ asmlinkage long sys_lchown16(const char __user * filename, old_uid_t user, old_gid_t group)
+ {
+- return sys_lchown(filename, low2highuid(user), low2highgid(group));
++ long ret = sys_lchown(filename, low2highuid(user), low2highgid(group));
++ /* avoid REGPARM breakage on x86: */
++ prevent_tail_call(ret);
++ return ret;
+ }
+
+ asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group)
+ {
+- return sys_fchown(fd, low2highuid(user), low2highgid(group));
++ long ret = sys_fchown(fd, low2highuid(user), low2highgid(group));
++ /* avoid REGPARM breakage on x86: */
++ prevent_tail_call(ret);
++ return ret;
+ }
+
+ asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid)
+ {
+- return sys_setregid(low2highgid(rgid), low2highgid(egid));
++ long ret = sys_setregid(low2highgid(rgid), low2highgid(egid));
++ /* avoid REGPARM breakage on x86: */
++ prevent_tail_call(ret);
++ return ret;
+ }
+
+ asmlinkage long sys_setgid16(old_gid_t gid)
+ {
+- return sys_setgid(low2highgid(gid));
++ long ret = sys_setgid(low2highgid(gid));
++ /* avoid REGPARM breakage on x86: */
++ prevent_tail_call(ret);
++ return ret;
+ }
+
+ asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid)
+ {
+- return sys_setreuid(low2highuid(ruid), low2highuid(euid));
++ long ret = sys_setreuid(low2highuid(ruid), low2highuid(euid));
++ /* avoid REGPARM breakage on x86: */
++ prevent_tail_call(ret);
++ return ret;
+ }
+
+ asmlinkage long sys_setuid16(old_uid_t uid)
+ {
+- return sys_setuid(low2highuid(uid));
++ long ret = sys_setuid(low2highuid(uid));
++ /* avoid REGPARM breakage on x86: */
++ prevent_tail_call(ret);
++ return ret;
+ }
+
+ asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid)
+ {
+- return sys_setresuid(low2highuid(ruid), low2highuid(euid),
+- low2highuid(suid));
++ long ret = sys_setresuid(low2highuid(ruid), low2highuid(euid),
++ low2highuid(suid));
++ /* avoid REGPARM breakage on x86: */
++ prevent_tail_call(ret);
++ return ret;
+ }
+
+ asmlinkage long sys_getresuid16(old_uid_t __user *ruid, old_uid_t __user *euid, old_uid_t __user *suid)
+@@ -72,8 +96,11 @@
+
+ asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid)
+ {
+- return sys_setresgid(low2highgid(rgid), low2highgid(egid),
+- low2highgid(sgid));
++ long ret = sys_setresgid(low2highgid(rgid), low2highgid(egid),
++ low2highgid(sgid));
++ /* avoid REGPARM breakage on x86: */
++ prevent_tail_call(ret);
++ return ret;
+ }
+
+ asmlinkage long sys_getresgid16(old_gid_t __user *rgid, old_gid_t __user *egid, old_gid_t __user *sgid)
+@@ -89,12 +116,18 @@
+
+ asmlinkage long sys_setfsuid16(old_uid_t uid)
+ {
+- return sys_setfsuid(low2highuid(uid));
++ long ret = sys_setfsuid(low2highuid(uid));
++ /* avoid REGPARM breakage on x86: */
++ prevent_tail_call(ret);
++ return ret;
+ }
+
+ asmlinkage long sys_setfsgid16(old_gid_t gid)
+ {
+- return sys_setfsgid(low2highgid(gid));
++ long ret = sys_setfsgid(low2highgid(gid));
++ /* avoid REGPARM breakage on x86: */
++ prevent_tail_call(ret);
++ return ret;
+ }
+
+ static int groups16_to_user(old_gid_t __user *grouplist,
+diff -Naur linux-2.6.16/Makefile linux-2.6.16.16/Makefile
+--- linux-2.6.16/Makefile 2006-05-18 01:12:20.000000000 +0300
++++ linux-2.6.16.16/Makefile 2006-05-17 21:41:27.000000000 +0300
+@@ -1,7 +1,7 @@
+ VERSION = 2
+ PATCHLEVEL = 6
+ SUBLEVEL = 16
+-EXTRAVERSION =
++EXTRAVERSION = .16
+ NAME=Sliding Snow Leopard
+
+ # *DOCUMENTATION*
+diff -Naur linux-2.6.16/mm/madvise.c linux-2.6.16.16/mm/madvise.c
+--- linux-2.6.16/mm/madvise.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/mm/madvise.c 2006-05-11 04:56:24.000000000 +0300
+@@ -168,6 +168,9 @@
+ return -EINVAL;
+ }
+
++ if ((vma->vm_flags & (VM_SHARED|VM_WRITE)) != (VM_SHARED|VM_WRITE))
++ return -EACCES;
++
+ mapping = vma->vm_file->f_mapping;
+
+ offset = (loff_t)(start - vma->vm_start)
+diff -Naur linux-2.6.16/mm/page_alloc.c linux-2.6.16.16/mm/page_alloc.c
+--- linux-2.6.16/mm/page_alloc.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/mm/page_alloc.c 2006-05-11 04:56:24.000000000 +0300
+@@ -153,7 +153,8 @@
+ 1 << PG_reclaim |
+ 1 << PG_slab |
+ 1 << PG_swapcache |
+- 1 << PG_writeback );
++ 1 << PG_writeback |
++ 1 << PG_buddy );
+ set_page_count(page, 0);
+ reset_page_mapcount(page);
+ page->mapping = NULL;
+@@ -224,12 +225,12 @@
+
+ static inline void set_page_order(struct page *page, int order) {
+ set_page_private(page, order);
+- __SetPagePrivate(page);
++ __SetPageBuddy(page);
+ }
+
+ static inline void rmv_page_order(struct page *page)
+ {
+- __ClearPagePrivate(page);
++ __ClearPageBuddy(page);
+ set_page_private(page, 0);
+ }
+
+@@ -268,11 +269,13 @@
+ * This function checks whether a page is free && is the buddy
+ * we can do coalesce a page and its buddy if
+ * (a) the buddy is not in a hole &&
+- * (b) the buddy is free &&
+- * (c) the buddy is on the buddy system &&
+- * (d) a page and its buddy have the same order.
+- * for recording page's order, we use page_private(page) and PG_private.
++ * (b) the buddy is in the buddy system &&
++ * (c) a page and its buddy have the same order.
++ *
++ * For recording whether a page is in the buddy system, we use PG_buddy.
++ * Setting, clearing, and testing PG_buddy is serialized by zone->lock.
+ *
++ * For recording page's order, we use page_private(page).
+ */
+ static inline int page_is_buddy(struct page *page, int order)
+ {
+@@ -281,10 +284,10 @@
+ return 0;
+ #endif
+
+- if (PagePrivate(page) &&
+- (page_order(page) == order) &&
+- page_count(page) == 0)
++ if (PageBuddy(page) && page_order(page) == order) {
++ BUG_ON(page_count(page) != 0);
+ return 1;
++ }
+ return 0;
+ }
+
+@@ -301,7 +304,7 @@
+ * as necessary, plus some accounting needed to play nicely with other
+ * parts of the VM system.
+ * At each level, we keep a list of pages, which are heads of continuous
+- * free pages of length of (1 << order) and marked with PG_Private.Page's
++ * free pages of length of (1 << order) and marked with PG_buddy. Page's
+ * order is recorded in page_private(page) field.
+ * So when we are allocating or freeing one, we can derive the state of the
+ * other. That is, if we allocate a small block, and both were
+@@ -364,7 +367,8 @@
+ 1 << PG_slab |
+ 1 << PG_swapcache |
+ 1 << PG_writeback |
+- 1 << PG_reserved ))))
++ 1 << PG_reserved |
++ 1 << PG_buddy ))))
+ bad_page(page);
+ if (PageDirty(page))
+ __ClearPageDirty(page);
+@@ -522,7 +526,8 @@
+ 1 << PG_slab |
+ 1 << PG_swapcache |
+ 1 << PG_writeback |
+- 1 << PG_reserved ))))
++ 1 << PG_reserved |
++ 1 << PG_buddy ))))
+ bad_page(page);
+
+ /*
+diff -Naur linux-2.6.16/net/atm/clip.c linux-2.6.16.16/net/atm/clip.c
+--- linux-2.6.16/net/atm/clip.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/net/atm/clip.c 2006-05-11 04:56:24.000000000 +0300
+@@ -613,12 +613,19 @@
+
+
+ static int clip_device_event(struct notifier_block *this,unsigned long event,
+- void *dev)
++ void *arg)
+ {
++ struct net_device *dev = arg;
++
++ if (event == NETDEV_UNREGISTER) {
++ neigh_ifdown(&clip_tbl, dev);
++ return NOTIFY_DONE;
++ }
++
+ /* ignore non-CLIP devices */
+- if (((struct net_device *) dev)->type != ARPHRD_ATM ||
+- ((struct net_device *) dev)->hard_start_xmit != clip_start_xmit)
++ if (dev->type != ARPHRD_ATM || dev->hard_start_xmit != clip_start_xmit)
+ return NOTIFY_DONE;
++
+ switch (event) {
+ case NETDEV_UP:
+ DPRINTK("clip_device_event NETDEV_UP\n");
+@@ -686,14 +693,12 @@
+ static void atmarpd_close(struct atm_vcc *vcc)
+ {
+ DPRINTK("atmarpd_close\n");
+- atmarpd = NULL; /* assumed to be atomic */
+- barrier();
+- unregister_inetaddr_notifier(&clip_inet_notifier);
+- unregister_netdevice_notifier(&clip_dev_notifier);
+- if (skb_peek(&sk_atm(vcc)->sk_receive_queue))
+- printk(KERN_ERR "atmarpd_close: closing with requests "
+- "pending\n");
++
++ rtnl_lock();
++ atmarpd = NULL;
+ skb_queue_purge(&sk_atm(vcc)->sk_receive_queue);
++ rtnl_unlock();
++
+ DPRINTK("(done)\n");
+ module_put(THIS_MODULE);
+ }
+@@ -714,7 +719,12 @@
+
+ static int atm_init_atmarp(struct atm_vcc *vcc)
+ {
+- if (atmarpd) return -EADDRINUSE;
++ rtnl_lock();
++ if (atmarpd) {
++ rtnl_unlock();
++ return -EADDRINUSE;
++ }
++
+ if (start_timer) {
+ start_timer = 0;
+ init_timer(&idle_timer);
+@@ -731,10 +741,7 @@
+ vcc->push = NULL;
+ vcc->pop = NULL; /* crash */
+ vcc->push_oam = NULL; /* crash */
+- if (register_netdevice_notifier(&clip_dev_notifier))
+- printk(KERN_ERR "register_netdevice_notifier failed\n");
+- if (register_inetaddr_notifier(&clip_inet_notifier))
+- printk(KERN_ERR "register_inetaddr_notifier failed\n");
++ rtnl_unlock();
+ return 0;
+ }
+
+@@ -992,6 +999,8 @@
+
+ clip_tbl_hook = &clip_tbl;
+ register_atm_ioctl(&clip_ioctl_ops);
++ register_netdevice_notifier(&clip_dev_notifier);
++ register_inetaddr_notifier(&clip_inet_notifier);
+
+ #ifdef CONFIG_PROC_FS
+ {
+@@ -1012,6 +1021,9 @@
+
+ remove_proc_entry("arp", atm_proc_root);
+
++ unregister_inetaddr_notifier(&clip_inet_notifier);
++ unregister_netdevice_notifier(&clip_dev_notifier);
++
+ deregister_atm_ioctl(&clip_ioctl_ops);
+
+ /* First, stop the idle timer, so it stops banging
+diff -Naur linux-2.6.16/net/bridge/br_netfilter.c linux-2.6.16.16/net/bridge/br_netfilter.c
+--- linux-2.6.16/net/bridge/br_netfilter.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/net/bridge/br_netfilter.c 2006-05-11 04:56:24.000000000 +0300
+@@ -739,6 +739,15 @@
+ return NF_STOLEN;
+ }
+
++static int br_nf_dev_queue_xmit(struct sk_buff *skb)
++{
++ if (skb->protocol == htons(ETH_P_IP) &&
++ skb->len > skb->dev->mtu &&
++ !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
++ return ip_fragment(skb, br_dev_queue_push_xmit);
++ else
++ return br_dev_queue_push_xmit(skb);
++}
+
+ /* PF_BRIDGE/POST_ROUTING ********************************************/
+ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
+@@ -798,7 +807,7 @@
+ realoutdev = nf_bridge->netoutdev;
+ #endif
+ NF_HOOK(pf, NF_IP_POST_ROUTING, skb, NULL, realoutdev,
+- br_dev_queue_push_xmit);
++ br_nf_dev_queue_xmit);
+
+ return NF_STOLEN;
+
+@@ -843,7 +852,7 @@
+ if ((out->hard_start_xmit == br_dev_xmit &&
+ okfn != br_nf_forward_finish &&
+ okfn != br_nf_local_out_finish &&
+- okfn != br_dev_queue_push_xmit)
++ okfn != br_nf_dev_queue_xmit)
+ #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+ || ((out->priv_flags & IFF_802_1Q_VLAN) &&
+ VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit)
+diff -Naur linux-2.6.16/net/core/dev.c linux-2.6.16.16/net/core/dev.c
+--- linux-2.6.16/net/core/dev.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/net/core/dev.c 2006-05-11 04:56:24.000000000 +0300
+@@ -2932,11 +2932,11 @@
+
+ switch(dev->reg_state) {
+ case NETREG_REGISTERING:
++ dev->reg_state = NETREG_REGISTERED;
+ err = netdev_register_sysfs(dev);
+ if (err)
+ printk(KERN_ERR "%s: failed sysfs registration (%d)\n",
+ dev->name, err);
+- dev->reg_state = NETREG_REGISTERED;
+ break;
+
+ case NETREG_UNREGISTERING:
+diff -Naur linux-2.6.16/net/core/sock.c linux-2.6.16.16/net/core/sock.c
+--- linux-2.6.16/net/core/sock.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/net/core/sock.c 2006-05-11 04:56:24.000000000 +0300
+@@ -404,8 +404,9 @@
+ if (!valbool) {
+ sk->sk_bound_dev_if = 0;
+ } else {
+- if (optlen > IFNAMSIZ)
+- optlen = IFNAMSIZ;
++ if (optlen > IFNAMSIZ - 1)
++ optlen = IFNAMSIZ - 1;
++ memset(devname, 0, sizeof(devname));
+ if (copy_from_user(devname, optval, optlen)) {
+ ret = -EFAULT;
+ break;
+diff -Naur linux-2.6.16/net/ipv4/fib_trie.c linux-2.6.16.16/net/ipv4/fib_trie.c
+--- linux-2.6.16/net/ipv4/fib_trie.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/net/ipv4/fib_trie.c 2006-05-11 04:56:24.000000000 +0300
+@@ -314,11 +314,6 @@
+ kfree(container_of(head, struct leaf, rcu));
+ }
+
+-static inline void free_leaf(struct leaf *leaf)
+-{
+- call_rcu(&leaf->rcu, __leaf_free_rcu);
+-}
+-
+ static void __leaf_info_free_rcu(struct rcu_head *head)
+ {
+ kfree(container_of(head, struct leaf_info, rcu));
+@@ -357,7 +352,12 @@
+
+ static inline void tnode_free(struct tnode *tn)
+ {
+- call_rcu(&tn->rcu, __tnode_free_rcu);
++ if(IS_LEAF(tn)) {
++ struct leaf *l = (struct leaf *) tn;
++ call_rcu_bh(&l->rcu, __leaf_free_rcu);
++ }
++ else
++ call_rcu(&tn->rcu, __tnode_free_rcu);
+ }
+
+ static struct leaf *leaf_new(void)
+diff -Naur linux-2.6.16/net/ipv4/ip_output.c linux-2.6.16.16/net/ipv4/ip_output.c
+--- linux-2.6.16/net/ipv4/ip_output.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/net/ipv4/ip_output.c 2006-05-11 04:56:24.000000000 +0300
+@@ -86,8 +86,6 @@
+
+ int sysctl_ip_default_ttl = IPDEFTTL;
+
+-static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*));
+-
+ /* Generate a checksum for an outgoing IP datagram. */
+ __inline__ void ip_send_check(struct iphdr *iph)
+ {
+@@ -421,7 +419,7 @@
+ * single device frame, and queue such a frame for sending.
+ */
+
+-static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
++int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
+ {
+ struct iphdr *iph;
+ int raw = 0;
+@@ -673,6 +671,8 @@
+ return err;
+ }
+
++EXPORT_SYMBOL(ip_fragment);
++
+ int
+ ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb)
+ {
+@@ -1249,11 +1249,7 @@
+ iph->tos = inet->tos;
+ iph->tot_len = htons(skb->len);
+ iph->frag_off = df;
+- if (!df) {
+- __ip_select_ident(iph, &rt->u.dst, 0);
+- } else {
+- iph->id = htons(inet->id++);
+- }
++ ip_select_ident(iph, &rt->u.dst, sk);
+ iph->ttl = ttl;
+ iph->protocol = sk->sk_protocol;
+ iph->saddr = rt->rt_src;
+diff -Naur linux-2.6.16/net/ipv4/netfilter/ip_conntrack_netlink.c linux-2.6.16.16/net/ipv4/netfilter/ip_conntrack_netlink.c
+--- linux-2.6.16/net/ipv4/netfilter/ip_conntrack_netlink.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/net/ipv4/netfilter/ip_conntrack_netlink.c 2006-05-11 04:56:24.000000000 +0300
+@@ -1619,7 +1619,7 @@
+ printk("ctnetlink: unregistering from nfnetlink.\n");
+
+ #ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
+- ip_conntrack_unregister_notifier(&ctnl_notifier_exp);
++ ip_conntrack_expect_unregister_notifier(&ctnl_notifier_exp);
+ ip_conntrack_unregister_notifier(&ctnl_notifier);
+ #endif
+
+diff -Naur linux-2.6.16/net/ipv4/netfilter/ip_conntrack_proto_sctp.c linux-2.6.16.16/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
+--- linux-2.6.16/net/ipv4/netfilter/ip_conntrack_proto_sctp.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/net/ipv4/netfilter/ip_conntrack_proto_sctp.c 2006-05-11 04:56:24.000000000 +0300
+@@ -235,12 +235,15 @@
+ flag = 1;
+ }
+
+- /* Cookie Ack/Echo chunks not the first OR
+- Init / Init Ack / Shutdown compl chunks not the only chunks */
+- if ((sch->type == SCTP_CID_COOKIE_ACK
++ /*
++ * Cookie Ack/Echo chunks not the first OR
++ * Init / Init Ack / Shutdown compl chunks not the only chunks
++ * OR zero-length.
++ */
++ if (((sch->type == SCTP_CID_COOKIE_ACK
+ || sch->type == SCTP_CID_COOKIE_ECHO
+ || flag)
+- && count !=0 ) {
++ && count !=0) || !sch->length) {
+ DEBUGP("Basic checks failed\n");
+ return 1;
+ }
+diff -Naur linux-2.6.16/net/ipv4/route.c linux-2.6.16.16/net/ipv4/route.c
+--- linux-2.6.16/net/ipv4/route.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/net/ipv4/route.c 2006-05-11 04:56:24.000000000 +0300
+@@ -2750,7 +2750,10 @@
+ /* Reserve room for dummy headers, this skb can pass
+ through good chunk of routing engine.
+ */
+- skb->mac.raw = skb->data;
++ skb->mac.raw = skb->nh.raw = skb->data;
++
++ /* Bugfix: need to give ip_route_input enough of an IP header to not gag. */
++ skb->nh.iph->protocol = IPPROTO_ICMP;
+ skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr));
+
+ if (rta[RTA_SRC - 1])
+diff -Naur linux-2.6.16/net/ipv4/tcp_output.c linux-2.6.16.16/net/ipv4/tcp_output.c
+--- linux-2.6.16/net/ipv4/tcp_output.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/net/ipv4/tcp_output.c 2006-05-11 04:56:24.000000000 +0300
+@@ -537,7 +537,9 @@
+ buff = sk_stream_alloc_skb(sk, nsize, GFP_ATOMIC);
+ if (buff == NULL)
+ return -ENOMEM; /* We'll just try again later. */
+- sk_charge_skb(sk, buff);
++
++ buff->truesize = skb->len - len;
++ skb->truesize -= buff->truesize;
+
+ /* Correct the sequence numbers. */
+ TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len;
+diff -Naur linux-2.6.16/net/ipv6/exthdrs.c linux-2.6.16.16/net/ipv6/exthdrs.c
+--- linux-2.6.16/net/ipv6/exthdrs.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/net/ipv6/exthdrs.c 2006-05-11 04:56:24.000000000 +0300
+@@ -489,6 +489,18 @@
+ {
+ struct inet6_skb_parm *opt = IP6CB(skb);
+
++ /*
++ * skb->nh.raw is equal to skb->data, and
++ * skb->h.raw - skb->nh.raw is always equal to
++ * sizeof(struct ipv6hdr) by definition of
++ * hop-by-hop options.
++ */
++ if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) ||
++ !pskb_may_pull(skb, sizeof(struct ipv6hdr) + ((skb->h.raw[1] + 1) << 3))) {
++ kfree_skb(skb);
++ return -1;
++ }
++
+ opt->hop = sizeof(struct ipv6hdr);
+ if (ip6_parse_tlv(tlvprochopopt_lst, skb)) {
+ skb->h.raw += (skb->h.raw[1]+1)<<3;
+diff -Naur linux-2.6.16/net/ipv6/xfrm6_policy.c linux-2.6.16.16/net/ipv6/xfrm6_policy.c
+--- linux-2.6.16/net/ipv6/xfrm6_policy.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/net/ipv6/xfrm6_policy.c 2006-05-11 04:56:24.000000000 +0300
+@@ -191,16 +191,18 @@
+ static inline void
+ _decode_session6(struct sk_buff *skb, struct flowi *fl)
+ {
+- u16 offset = sizeof(struct ipv6hdr);
++ u16 offset = skb->h.raw - skb->nh.raw;
+ struct ipv6hdr *hdr = skb->nh.ipv6h;
+- struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+- u8 nexthdr = skb->nh.ipv6h->nexthdr;
++ struct ipv6_opt_hdr *exthdr;
++ u8 nexthdr = skb->nh.raw[IP6CB(skb)->nhoff];
+
+ memset(fl, 0, sizeof(struct flowi));
+ ipv6_addr_copy(&fl->fl6_dst, &hdr->daddr);
+ ipv6_addr_copy(&fl->fl6_src, &hdr->saddr);
+
+ while (pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data)) {
++ exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
++
+ switch (nexthdr) {
+ case NEXTHDR_ROUTING:
+ case NEXTHDR_HOP:
+diff -Naur linux-2.6.16/net/netfilter/nf_conntrack_netlink.c linux-2.6.16.16/net/netfilter/nf_conntrack_netlink.c
+--- linux-2.6.16/net/netfilter/nf_conntrack_netlink.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/net/netfilter/nf_conntrack_netlink.c 2006-05-11 04:56:24.000000000 +0300
+@@ -1641,7 +1641,7 @@
+ printk("ctnetlink: unregistering from nfnetlink.\n");
+
+ #ifdef CONFIG_NF_CONNTRACK_EVENTS
+- nf_conntrack_unregister_notifier(&ctnl_notifier_exp);
++ nf_conntrack_expect_unregister_notifier(&ctnl_notifier_exp);
+ nf_conntrack_unregister_notifier(&ctnl_notifier);
+ #endif
+
+diff -Naur linux-2.6.16/net/netfilter/nf_conntrack_proto_sctp.c linux-2.6.16.16/net/netfilter/nf_conntrack_proto_sctp.c
+--- linux-2.6.16/net/netfilter/nf_conntrack_proto_sctp.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/net/netfilter/nf_conntrack_proto_sctp.c 2006-05-11 04:56:24.000000000 +0300
+@@ -240,12 +240,15 @@
+ flag = 1;
+ }
+
+- /* Cookie Ack/Echo chunks not the first OR
+- Init / Init Ack / Shutdown compl chunks not the only chunks */
+- if ((sch->type == SCTP_CID_COOKIE_ACK
++ /*
++ * Cookie Ack/Echo chunks not the first OR
++ * Init / Init Ack / Shutdown compl chunks not the only chunks
++ * OR zero-length.
++ */
++ if (((sch->type == SCTP_CID_COOKIE_ACK
+ || sch->type == SCTP_CID_COOKIE_ECHO
+ || flag)
+- && count !=0 ) {
++ && count !=0) || !sch->length) {
+ DEBUGP("Basic checks failed\n");
+ return 1;
+ }
+diff -Naur linux-2.6.16/net/sctp/inqueue.c linux-2.6.16.16/net/sctp/inqueue.c
+--- linux-2.6.16/net/sctp/inqueue.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/net/sctp/inqueue.c 2006-05-11 04:56:24.000000000 +0300
+@@ -149,6 +149,7 @@
+ /* This is the first chunk in the packet. */
+ chunk->singleton = 1;
+ ch = (sctp_chunkhdr_t *) chunk->skb->data;
++ chunk->data_accepted = 0;
+ }
+
+ chunk->chunk_hdr = ch;
+diff -Naur linux-2.6.16/net/sctp/sm_statefuns.c linux-2.6.16.16/net/sctp/sm_statefuns.c
+--- linux-2.6.16/net/sctp/sm_statefuns.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/net/sctp/sm_statefuns.c 2006-05-11 04:56:24.000000000 +0300
+@@ -636,8 +636,9 @@
+ */
+ chunk->subh.cookie_hdr =
+ (struct sctp_signed_cookie *)chunk->skb->data;
+- skb_pull(chunk->skb,
+- ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t));
++ if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
++ sizeof(sctp_chunkhdr_t)))
++ goto nomem;
+
+ /* 5.1 D) Upon reception of the COOKIE ECHO chunk, Endpoint
+ * "Z" will reply with a COOKIE ACK chunk after building a TCB
+@@ -965,7 +966,8 @@
+ */
+ chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data;
+ paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t);
+- skb_pull(chunk->skb, paylen);
++ if (!pskb_pull(chunk->skb, paylen))
++ goto nomem;
+
+ reply = sctp_make_heartbeat_ack(asoc, chunk,
+ chunk->subh.hb_hdr, paylen);
+@@ -1860,8 +1862,9 @@
+ * are in good shape.
+ */
+ chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data;
+- skb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
+- sizeof(sctp_chunkhdr_t));
++ if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
++ sizeof(sctp_chunkhdr_t)))
++ goto nomem;
+
+ /* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie
+ * of a duplicate COOKIE ECHO match the Verification Tags of the
+@@ -5151,7 +5154,9 @@
+ int tmp;
+ __u32 tsn;
+ int account_value;
++ struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map;
+ struct sock *sk = asoc->base.sk;
++ int rcvbuf_over = 0;
+
+ data_hdr = chunk->subh.data_hdr = (sctp_datahdr_t *)chunk->skb->data;
+ skb_pull(chunk->skb, sizeof(sctp_datahdr_t));
+@@ -5162,10 +5167,16 @@
+ /* ASSERT: Now skb->data is really the user data. */
+
+ /*
+- * if we are established, and we have used up our receive
+- * buffer memory, drop the frame
++ * If we are established, and we have used up our receive buffer
++ * memory, think about droping the frame.
++ * Note that we have an opportunity to improve performance here.
++ * If we accept one chunk from an skbuff, we have to keep all the
++ * memory of that skbuff around until the chunk is read into user
++ * space. Therefore, once we accept 1 chunk we may as well accept all
++ * remaining chunks in the skbuff. The data_accepted flag helps us do
++ * that.
+ */
+- if (asoc->state == SCTP_STATE_ESTABLISHED) {
++ if ((asoc->state == SCTP_STATE_ESTABLISHED) && (!chunk->data_accepted)) {
+ /*
+ * If the receive buffer policy is 1, then each
+ * association can allocate up to sk_rcvbuf bytes
+@@ -5176,9 +5187,25 @@
+ account_value = atomic_read(&asoc->rmem_alloc);
+ else
+ account_value = atomic_read(&sk->sk_rmem_alloc);
+-
+- if (account_value > sk->sk_rcvbuf)
+- return SCTP_IERROR_IGNORE_TSN;
++ if (account_value > sk->sk_rcvbuf) {
++ /*
++ * We need to make forward progress, even when we are
++ * under memory pressure, so we always allow the
++ * next tsn after the ctsn ack point to be accepted.
++ * This lets us avoid deadlocks in which we have to
++ * drop frames that would otherwise let us drain the
++ * receive queue.
++ */
++ if ((sctp_tsnmap_get_ctsn(map) + 1) != tsn)
++ return SCTP_IERROR_IGNORE_TSN;
++
++ /*
++ * We're going to accept the frame but we should renege
++ * to make space for it. This will send us down that
++ * path later in this function.
++ */
++ rcvbuf_over = 1;
++ }
+ }
+
+ /* Process ECN based congestion.
+@@ -5226,6 +5253,7 @@
+ datalen -= sizeof(sctp_data_chunk_t);
+
+ deliver = SCTP_CMD_CHUNK_ULP;
++ chunk->data_accepted = 1;
+
+ /* Think about partial delivery. */
+ if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) {
+@@ -5242,7 +5270,8 @@
+ * large spill over.
+ */
+ if (!asoc->rwnd || asoc->rwnd_over ||
+- (datalen > asoc->rwnd + asoc->frag_point)) {
++ (datalen > asoc->rwnd + asoc->frag_point) ||
++ rcvbuf_over) {
+
+ /* If this is the next TSN, consider reneging to make
+ * room. Note: Playing nice with a confused sender. A
+@@ -5250,8 +5279,8 @@
+ * space and in the future we may want to detect and
+ * do more drastic reneging.
+ */
+- if (sctp_tsnmap_has_gap(&asoc->peer.tsn_map) &&
+- (sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + 1) == tsn) {
++ if (sctp_tsnmap_has_gap(map) &&
++ (sctp_tsnmap_get_ctsn(map) + 1) == tsn) {
+ SCTP_DEBUG_PRINTK("Reneging for tsn:%u\n", tsn);
+ deliver = SCTP_CMD_RENEGE;
+ } else {
+diff -Naur linux-2.6.16/net/sctp/sm_statetable.c linux-2.6.16.16/net/sctp/sm_statetable.c
+--- linux-2.6.16/net/sctp/sm_statetable.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/net/sctp/sm_statetable.c 2006-05-11 04:56:24.000000000 +0300
+@@ -366,9 +366,9 @@
+ /* SCTP_STATE_EMPTY */ \
+ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \
+ /* SCTP_STATE_CLOSED */ \
+- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
++ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
+ /* SCTP_STATE_COOKIE_WAIT */ \
+- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
++ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
+ /* SCTP_STATE_COOKIE_ECHOED */ \
+ {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
+ /* SCTP_STATE_ESTABLISHED */ \
+@@ -380,7 +380,7 @@
+ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
+ {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \
+ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
+- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
++ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
+ } /* TYPE_SCTP_ECN_ECNE */
+
+ #define TYPE_SCTP_ECN_CWR { \
+@@ -401,7 +401,7 @@
+ /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
+ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
+ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
+- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
++ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
+ } /* TYPE_SCTP_ECN_CWR */
+
+ #define TYPE_SCTP_SHUTDOWN_COMPLETE { \
+@@ -647,7 +647,7 @@
+ /* SCTP_STATE_EMPTY */ \
+ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
+ /* SCTP_STATE_CLOSED */ \
+- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
++ {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \
+ /* SCTP_STATE_COOKIE_WAIT */ \
+ {.fn = sctp_sf_do_prm_requestheartbeat, \
+ .name = "sctp_sf_do_prm_requestheartbeat"}, \
+diff -Naur linux-2.6.16/net/sctp/ulpqueue.c linux-2.6.16.16/net/sctp/ulpqueue.c
+--- linux-2.6.16/net/sctp/ulpqueue.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/net/sctp/ulpqueue.c 2006-05-11 04:56:24.000000000 +0300
+@@ -279,6 +279,7 @@
+ static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *queue, struct sk_buff *f_frag, struct sk_buff *l_frag)
+ {
+ struct sk_buff *pos;
++ struct sk_buff *new = NULL;
+ struct sctp_ulpevent *event;
+ struct sk_buff *pnext, *last;
+ struct sk_buff *list = skb_shinfo(f_frag)->frag_list;
+@@ -297,11 +298,33 @@
+ */
+ if (last)
+ last->next = pos;
+- else
+- skb_shinfo(f_frag)->frag_list = pos;
++ else {
++ if (skb_cloned(f_frag)) {
++ /* This is a cloned skb, we can't just modify
++ * the frag_list. We need a new skb to do that.
++ * Instead of calling skb_unshare(), we'll do it
++ * ourselves since we need to delay the free.
++ */
++ new = skb_copy(f_frag, GFP_ATOMIC);
++ if (!new)
++ return NULL; /* try again later */
++
++ new->sk = f_frag->sk;
++
++ skb_shinfo(new)->frag_list = pos;
++ } else
++ skb_shinfo(f_frag)->frag_list = pos;
++ }
+
+ /* Remove the first fragment from the reassembly queue. */
+ __skb_unlink(f_frag, queue);
++
++ /* if we did unshare, then free the old skb and re-assign */
++ if (new) {
++ kfree_skb(f_frag);
++ f_frag = new;
++ }
++
+ while (pos) {
+
+ pnext = pos->next;
+diff -Naur linux-2.6.16/security/keys/key.c linux-2.6.16.16/security/keys/key.c
+--- linux-2.6.16/security/keys/key.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/security/keys/key.c 2006-05-11 04:56:24.000000000 +0300
+@@ -785,6 +785,10 @@
+
+ key_check(keyring);
+
++ key_ref = ERR_PTR(-ENOTDIR);
++ if (keyring->type != &key_type_keyring)
++ goto error_2;
++
+ down_write(&keyring->sem);
+
+ /* if we're going to allocate a new key, we're going to have
+diff -Naur linux-2.6.16/security/keys/keyring.c linux-2.6.16.16/security/keys/keyring.c
+--- linux-2.6.16/security/keys/keyring.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/security/keys/keyring.c 2006-05-11 04:56:24.000000000 +0300
+@@ -437,6 +437,7 @@
+ /*
+ * search the given keyring only (no recursion)
+ * - keyring must be locked by caller
++ * - caller must guarantee that the keyring is a keyring
+ */
+ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
+ const struct key_type *ktype,
+diff -Naur linux-2.6.16/security/selinux/ss/mls.c linux-2.6.16.16/security/selinux/ss/mls.c
+--- linux-2.6.16/security/selinux/ss/mls.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/security/selinux/ss/mls.c 2006-05-11 04:56:24.000000000 +0300
+@@ -264,7 +264,7 @@
+
+ if (!selinux_mls_enabled) {
+ if (def_sid != SECSID_NULL && oldc)
+- *scontext += strlen(*scontext);
++ *scontext += strlen(*scontext)+1;
+ return 0;
+ }
+
+diff -Naur linux-2.6.16/sound/isa/opti9xx/opti92x-ad1848.c linux-2.6.16.16/sound/isa/opti9xx/opti92x-ad1848.c
+--- linux-2.6.16/sound/isa/opti9xx/opti92x-ad1848.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/sound/isa/opti9xx/opti92x-ad1848.c 2006-05-11 04:56:24.000000000 +0300
+@@ -2088,9 +2088,11 @@
+ int error;
+ struct platform_device *device;
+
++#ifdef CONFIG_PNP
+ pnp_register_card_driver(&opti9xx_pnpc_driver);
+ if (snd_opti9xx_pnp_is_probed)
+ return 0;
++#endif
+ if (! is_isapnp_selected()) {
+ error = platform_driver_register(&snd_opti9xx_driver);
+ if (error < 0)
+@@ -2102,7 +2104,9 @@
+ }
+ platform_driver_unregister(&snd_opti9xx_driver);
+ }
++#ifdef CONFIG_PNP
+ pnp_unregister_card_driver(&opti9xx_pnpc_driver);
++#endif
+ #ifdef MODULE
+ printk(KERN_ERR "no OPTi " CHIP_NAME " soundcard found\n");
+ #endif
+@@ -2115,7 +2119,9 @@
+ platform_device_unregister(snd_opti9xx_platform_device);
+ platform_driver_unregister(&snd_opti9xx_driver);
+ }
++#ifdef CONFIG_PNP
+ pnp_unregister_card_driver(&opti9xx_pnpc_driver);
++#endif
+ }
+
+ module_init(alsa_card_opti9xx_init)
+diff -Naur linux-2.6.16/sound/oss/dmasound/tas_common.c linux-2.6.16.16/sound/oss/dmasound/tas_common.c
+--- linux-2.6.16/sound/oss/dmasound/tas_common.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/sound/oss/dmasound/tas_common.c 2006-05-11 04:56:24.000000000 +0300
+@@ -195,8 +195,8 @@
+
+ printk(KERN_INFO "tas driver [%s])\n", driver_name);
+
+-#ifndef CONFIG_I2C_KEYWEST
+- request_module("i2c-keywest");
++#ifndef CONFIG_I2C_POWERMAC
++ request_module("i2c-powermac");
+ #endif
+ tas_node = find_devices("deq");
+ if (tas_node == NULL)
+diff -Naur linux-2.6.16/sound/pci/hda/patch_realtek.c linux-2.6.16.16/sound/pci/hda/patch_realtek.c
+--- linux-2.6.16/sound/pci/hda/patch_realtek.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/sound/pci/hda/patch_realtek.c 2006-05-11 04:56:24.000000000 +0300
+@@ -2948,6 +2948,8 @@
+ { .modelname = "basic", .config = ALC260_BASIC },
+ { .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb,
+ .config = ALC260_BASIC }, /* Sony VAIO */
++ { .pci_subvendor = 0x152d, .pci_subdevice = 0x0729,
++ .config = ALC260_BASIC }, /* CTL Travel Master U553W */
+ { .modelname = "hp", .config = ALC260_HP },
+ { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP },
+ { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP },
+diff -Naur linux-2.6.16/sound/ppc/daca.c linux-2.6.16.16/sound/ppc/daca.c
+--- linux-2.6.16/sound/ppc/daca.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/sound/ppc/daca.c 2006-05-11 04:56:24.000000000 +0300
+@@ -256,7 +256,7 @@
+
+ #ifdef CONFIG_KMOD
+ if (current->fs->root)
+- request_module("i2c-keywest");
++ request_module("i2c-powermac");
+ #endif /* CONFIG_KMOD */
+
+ mix = kmalloc(sizeof(*mix), GFP_KERNEL);
+diff -Naur linux-2.6.16/sound/ppc/tumbler.c linux-2.6.16.16/sound/ppc/tumbler.c
+--- linux-2.6.16/sound/ppc/tumbler.c 2006-03-20 07:53:29.000000000 +0200
++++ linux-2.6.16.16/sound/ppc/tumbler.c 2006-05-11 04:56:24.000000000 +0300
+@@ -1314,7 +1314,7 @@
+
+ #ifdef CONFIG_KMOD
+ if (current->fs->root)
+- request_module("i2c-keywest");
++ request_module("i2c-powermac");
+ #endif /* CONFIG_KMOD */
+
+ mix = kmalloc(sizeof(*mix), GFP_KERNEL);
diff --git a/packages/linux/linux-h6300-omap1-2.6.16.16/linux-h6300-omap2-2.6.16.16.patch b/packages/linux/linux-h6300-omap1-2.6.16.16/linux-h6300-omap2-2.6.16.16.patch
new file mode 100644
index 0000000000..98b4365f98
--- /dev/null
+++ b/packages/linux/linux-h6300-omap1-2.6.16.16/linux-h6300-omap2-2.6.16.16.patch
@@ -0,0 +1,3736 @@
+diff -Naur linux-2.6.16.16/arch/arm/Kconfig h6300_dev/arch/arm/Kconfig
+--- linux-2.6.16.16/arch/arm/Kconfig 2006-05-17 21:41:27.000000000 +0300
++++ h6300_dev/arch/arm/Kconfig 2006-04-02 00:23:01.000000000 +0300
+@@ -811,6 +811,8 @@
+
+ source "drivers/video/Kconfig"
+
++source "drivers/telephony/Kconfig"
++
+ source "sound/Kconfig"
+
+ source "drivers/usb/Kconfig"
+diff -Naur linux-2.6.16.16/arch/arm/mach-omap1/board-h6300.c h6300_dev/arch/arm/mach-omap1/board-h6300.c
+--- linux-2.6.16.16/arch/arm/mach-omap1/board-h6300.c 1970-01-01 02:00:00.000000000 +0200
++++ h6300_dev/arch/arm/mach-omap1/board-h6300.c 2006-04-24 20:53:29.000000000 +0300
+@@ -0,0 +1,424 @@
++/*
++ * Modified from board-h6300.c
++ *
++ * Code for generic OMAP board. Should work on many OMAP systems where
++ * the device drivers take care of all the necessary hardware initialization.
++ * Do not put any board specific code to this file; create a new machine
++ * type if you need custom low-level initializations.
++ *
++ * 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/kernel.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/delay.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++#include <linux/input.h>
++
++#include <asm/hardware.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++#include <asm/mach/flash.h>
++#include <asm/mach/map.h>
++
++#include <asm/arch/gpio.h>
++
++#include <asm/arch/tc.h>
++#include <asm/arch/usb.h>
++#include <asm/arch/keypad.h>
++#include <asm/arch/common.h>
++#include <asm/arch/mcbsp.h>
++#include <asm/arch/omap-alsa.h>
++#include <asm/arch/h6300_uart_info.h>
++
++#define _h6300_KEY_CALENDAR 67 // xmodmap 75 aka F9
++#define _H6300_KEY_TELEPHONE 68 // xmodmap 76 aka F10
++#define _H6300_KEY_HOMEPAGE 87 // xmodmap 87 aka Num_Lock
++#define _H6300_KEY_MAIL 88 // xmodmap 88 aka Scroll_Lock
++
++/*
++ * Following 5 keypad events are not really sent to userspace.
++ * Instead if the good combination of them is sent, then that is send.
++ * (up, right, down, left, enter)
++ */
++#define _H6300_JOYPAD_UP_RIGHT 1 // 00001
++#define _H6300_JOYPAD_DOWN_RIGHT 2 // 00010
++#define _h6300_JOYPAD_DOWN_LEFT 4 // 00100
++#define _h6300_JOYPAD_UP_LEFT 8 // 01000
++#define _H6300_JOYPAD_KEY_OK 16 // 10000
++
++static int h6300_keymap[] = {
++ KEY(2, 0, _h6300_KEY_CALENDAR), // address button in the bottom left
++ KEY(2, 3, _H6300_KEY_TELEPHONE), // start call button in the bottom
++ KEY(3, 1, _H6300_KEY_HOMEPAGE), // stop call button in the bottom
++ KEY(3, 4, _H6300_KEY_MAIL), // messaging button in the bottom right
++
++ KEY(0, 0, KEY_VOLUMEUP), // volume up button in the right side
++ KEY(0, 1, KEY_VOLUMEDOWN), // volume down button in the right side
++ KEY(3, 2, KEY_RECORD), // record button in the left side
++
++ KEY(1, 0, _h6300_JOYPAD_UP_LEFT),
++ KEY(1, 1, _h6300_JOYPAD_DOWN_LEFT),
++ KEY(1, 2, _H6300_JOYPAD_KEY_OK),
++ KEY(1, 3, _H6300_JOYPAD_DOWN_RIGHT),
++ KEY(1, 4, _H6300_JOYPAD_UP_RIGHT),
++
++ KEY(4, 0, KEY_RIGHT),
++ KEY(4, 1, KEY_DOWN),
++ KEY(4, 2, KEY_LEFT),
++ KEY(4, 3, KEY_UP),
++ KEY(4, 4, KEY_ENTER),
++
++ 0
++};
++
++/*
++ * Bluetooth - Relies on h6300_bt module,
++ * so make the calls indirectly through pointers. Requires that the
++ * h6300_bt bluetooth module be loaded before any attempt to use
++ * bluetooth (obviously).
++ */
++
++static struct h6300_uart_funcs bt_funcs;
++static struct h6300_uart_funcs gsm_funcs;
++
++static void h6300_bt_configure(struct uart_omap_port *up, int enable)
++{
++ printk(KERN_NOTICE "board-h6300.c, h6300_bt_configure() started\n");
++ if (bt_funcs.configure != NULL)
++ bt_funcs.configure(up, enable);
++ printk(KERN_NOTICE "board-h6300.c, h6300_bt_configure() done\n");
++}
++
++static void h6300_bt_set_txrx(struct uart_omap_port *up, int txrx)
++{
++ printk(KERN_NOTICE "board-h6300.c, h6300_bt_set_txrx() started\n");
++ if (bt_funcs.set_txrx != NULL)
++ {
++ printk(KERN_NOTICE "board-h6300.c, h6300_bt_set_txrx(), bt_funcs.set_txrx != NULL\n");
++ bt_funcs.set_txrx(up, txrx);
++ }
++ printk(KERN_NOTICE "board-h6300.c, h6300_bt_set_txrx() done\n");
++}
++
++static int h6300_bt_get_txrx(struct uart_omap_port *up)
++{
++ int retVal;
++
++ printk(KERN_NOTICE "board-h6300.c, h6300_bt_get_txrx() started\n");
++ if (bt_funcs.get_txrx != NULL)
++ {
++ retVal = bt_funcs.get_txrx(up);
++ printk(KERN_NOTICE "board-h6300.c, h6300_bt_get_txrx(), bt_funcs.get_trx != null, done, retVal %d\n", retVal);
++ return retVal;
++ }
++ else
++ {
++ printk(KERN_NOTICE "board-h6300.c, h6300_bt_get_txrx() done, returning 0\n");
++ return 0;
++ }
++}
++
++static struct platform_omap_serial_funcs h6300_omap_bt_funcs = {
++ .configure = h6300_bt_configure,
++ .set_txrx = h6300_bt_set_txrx,
++ .get_txrx = h6300_bt_get_txrx,
++};
++
++struct platform_device btuart_device = {
++ .name = "h6300_bt",
++ .id = 1,
++};
++EXPORT_SYMBOL(btuart_device);
++
++static void h6300_gsm_configure(struct uart_omap_port *up, int enable)
++{
++ printk(KERN_NOTICE "board-h6300.c, h6300_gsm_configure() started\n");
++ if (gsm_funcs.configure != NULL)
++ gsm_funcs.configure(up, enable);
++ printk(KERN_NOTICE "board-h6300.c, h6300_gsm_configure() done\n");
++}
++
++static void h6300_gsm_set_txrx(struct uart_omap_port *up, int txrx)
++{
++ printk(KERN_NOTICE "board-h6300.c, h6300_gsm_set_txrx() started\n");
++ if (bt_funcs.set_txrx != NULL)
++ {
++ printk(KERN_NOTICE "board-h6300.c, h6300_gsm_set_txrx(), bt_funcs.set_txrx != NULL\n");
++ gsm_funcs.set_txrx(up, txrx);
++ }
++ printk(KERN_NOTICE "board-h6300.c, h6300_gsm_set_txrx() done\n");
++}
++
++static int h6300_gsm_get_txrx(struct uart_omap_port *up)
++{
++ int retVal;
++
++ printk(KERN_NOTICE "board-h6300.c, h6300_gsm_get_txrx() started\n");
++ if (bt_funcs.get_txrx != NULL)
++ {
++ retVal = gsm_funcs.get_txrx(up);
++ printk(KERN_NOTICE "board-h6300.c, h6300_gsm_get_txrx(), bt_funcs.get_trx != null, done, retVal %d\n", retVal);
++ return retVal;
++ }
++ else
++ {
++ printk(KERN_NOTICE "board-h6300.c, h6300_gsm_get_txrx() done, returning 0\n");
++ return 0;
++ }
++}
++
++static struct platform_omap_serial_funcs h6300_omap_gsm_funcs = {
++ .configure = h6300_gsm_configure,
++ .set_txrx = h6300_gsm_set_txrx,
++ .get_txrx = h6300_gsm_get_txrx,
++};
++
++struct platform_device gsmuart_device = {
++ .name = "h6300_gsm",
++ .id = 1,
++};
++EXPORT_SYMBOL(gsmuart_device);
++
++#if 0
++static struct mtd_partition h6300_partitions[] = {
++ /* bootloader (U-Boot, etc) in first sector */
++ {
++ .name = "bootloader",
++ .offset = 0,
++ .size = SZ_128K,
++ .mask_flags = MTD_WRITEABLE, /* force read-only */
++ },
++ /* bootloader params in the next sector */
++ {
++ .name = "params",
++ .offset = MTDPART_OFS_APPEND,
++ .size = SZ_128K,
++ .mask_flags = 0,
++ },
++ /* kernel */
++ {
++ .name = "kernel",
++ .offset = MTDPART_OFS_APPEND,
++ .size = SZ_2M,
++ .mask_flags = 0
++ },
++ /* rest of flash1 is a file system */
++ {
++ .name = "rootfs",
++ .offset = MTDPART_OFS_APPEND,
++ .size = SZ_16M - SZ_2M - 2 * SZ_128K,
++ .mask_flags = 0
++ },
++ /* file system */
++ {
++ .name = "filesystem",
++ .offset = MTDPART_OFS_APPEND,
++ .size = MTDPART_SIZ_FULL,
++ .mask_flags = 0
++ }
++};
++
++static struct flash_platform_data h6300_flash_data = {
++ .map_name = "cfi_probe",
++ .width = 2,
++ .parts = h6300_partitions,
++ .nr_parts = ARRAY_SIZE(h6300_partitions),
++};
++
++static struct resource h6300_flash_resource = {
++ .start = OMAP_CS0_PHYS,
++ .end = OMAP_CS0_PHYS + SZ_32M - 1,
++ .flags = IORESOURCE_MEM,
++};
++
++static struct platform_device h6300_flash_device = {
++ .name = "omapflash",
++ .id = 0,
++ .dev = {
++ .platform_data = &h6300_flash_data,
++ },
++static struct platform_device h6300_flash_device = {
++ .name = "omapflash",
++ .id = 0,
++ .dev = {
++ .platform_data = &h6300_flash_data,
++ },
++ .num_resources = 1,
++ .resource = &h6300_flash_resource,
++};
++#endif
++
++static struct resource h6300_kp_resources[] = {
++ [0] = {
++ .start = INT_KEYBOARD,
++ .end = INT_KEYBOARD,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct omap_kp_platform_data h6300_kp_data = {
++ .rows = 8,
++ .cols = 8,
++ .keymap = h6300_keymap,
++ .rep = 1, // turns repeat bit on
++};
++
++static struct platform_device h6300_kp_device = {
++ .name = "omap-keypad",
++ .id = -1,
++ .dev = {
++ .platform_data = &h6300_kp_data,
++ },
++ .num_resources = ARRAY_SIZE(h6300_kp_resources),
++ .resource = h6300_kp_resources,
++};
++
++static struct resource h6300_wlan_resource[] = {
++ [0] = {
++ .start = OMAP_CS1_PHYS,
++ .end = OMAP_CS1_PHYS + SZ_32M -1,
++ .flags = IORESOURCE_MEM,
++ },
++
++ [1] = {
++ .start = OMAP_GPIO_IRQ(11),
++ .end = OMAP_GPIO_IRQ(11),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device h6300_wlan_device = {
++ .name = "tnetw1100b",
++ .id = 0,
++ .num_resources = 2,
++ .resource = h6300_wlan_resource,
++};
++
++static struct omap_mcbsp_reg_cfg mcbsp_regs = {
++ .spcr2 = 0x0000,
++ .spcr1 = 0x0000,
++ .rcr2 = 0x8041,
++ .rcr1 = 0x0040,
++ .xcr2 = 0x00a1,
++ .xcr1 = 0x00a0,
++ .srgr2 = 0xb000,
++ .srgr1 = 0x0000,
++ .pcr0 = 0x0081,
++};
++
++static struct omap_alsa_codec_config alsa_config = {
++ .name = "iPAQ h6300 TSC2101",
++ .mcbsp_regs_alsa = &mcbsp_regs,
++ .codec_configure_dev = NULL, //tsc2101_configure,
++ .codec_set_samplerate = NULL, //tsc2101_set_samplerate,
++ .codec_clock_setup = NULL, //tsc2101_clock_setup,
++ .codec_clock_on = NULL, //tsc2101_clock_on,
++ .codec_clock_off = NULL, //tsc2101_clock_off,
++ .get_default_samplerate = NULL, //tsc2101_get_default_samplerate,
++};
++
++static struct platform_device h6300_mcbsp1_device = {
++ .name = "omap_alsa_mcbsp",
++ .id = 1,
++ .dev = {
++ .platform_data = &alsa_config,
++ },
++};
++
++static struct platform_device h6300_lcd_device = {
++ .name = "lcd_h6300",
++ .id = -1,
++};
++
++static struct platform_device *h6300_devices[] __initdata = {
++ &h6300_lcd_device,
++ &btuart_device,
++ &gsmuart_device,
++ &h6300_kp_device,
++ &h6300_mcbsp1_device,
++ &h6300_wlan_device,
++ //&h6300_flash_device,
++};
++
++static void __init h6300_init_irq(void)
++{
++ omap1_init_common_hw();
++ omap_init_irq();
++ omap_gpio_init();
++
++ /* this is now done in the drivers/input/touschreen/omap/ts_hx.c*/
++ //omap_request_gpio(2);
++ //omap_set_gpio_direction(2, 0);
++ //omap_set_gpio_dataout(2, 1);
++}
++
++/* assume no Mini-AB port */
++
++static struct omap_usb_config h6300_usb_config __initdata = {
++ .hmc_mode = 0,
++ .register_dev = 1,
++ .pins[0] = 0,
++};
++
++static struct omap_lcd_config h6300_lcd_config __initdata = {
++ .ctrl_name = "internal",
++};
++
++static struct omap_mmc_config h6300_mmc_config __initdata = {
++ .mmc [0] = {
++ .enabled = 1,
++ .wire4 = 1,
++ .wp_pin = OMAP_GPIO_IRQ(13),
++ .power_pin = -1, // tps65010 ?
++ .switch_pin = -1, // OMAP_MPUIO(1), // = -1, // ARMIO2?
++ },
++};
++
++static struct omap_uart_config h6300_uart_config __initdata = {
++ .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
++};
++
++static struct omap_board_config_kernel h6300_config[] = {
++ { OMAP_TAG_USB, &h6300_usb_config },
++ { OMAP_TAG_MMC, &h6300_mmc_config },
++ { OMAP_TAG_UART, &h6300_uart_config },
++ { OMAP_TAG_LCD, &h6300_lcd_config },
++};
++
++static void __init h6300_init(void)
++{
++ int ret;
++
++ ret = platform_add_devices(h6300_devices, ARRAY_SIZE(h6300_devices));
++ if (ret)
++ {
++ printk(KERN_WARNING "Unable to add h6300 platform devices like bluetooth");
++ }
++ omap_board_config = h6300_config;
++ omap_board_config_size = ARRAY_SIZE(h6300_config);
++ omap_serial_init();
++}
++
++static void __init h6300_map_io(void)
++{
++ omap1_map_common_io();
++
++ btuart_device.dev.platform_data = &h6300_omap_bt_funcs;
++ gsmuart_device.dev.platform_data = &h6300_omap_gsm_funcs;
++}
++
++MACHINE_START(OMAP_H6300, "HP iPAQ h6300")
++ /* MAINTAINER("Everett Coleman II <gcc80x86@fuzzyneural.net>") */
++ .phys_io = 0xfff00000,
++ .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
++ .boot_params = 0x10000100,
++ .map_io = h6300_map_io,
++ .init_irq = h6300_init_irq,
++ .init_machine = h6300_init,
++ .timer = &omap_timer,
++MACHINE_END
+diff -Naur linux-2.6.16.16/arch/arm/mach-omap1/Kconfig h6300_dev/arch/arm/mach-omap1/Kconfig
+--- linux-2.6.16.16/arch/arm/mach-omap1/Kconfig 2006-05-17 21:41:27.000000000 +0300
++++ h6300_dev/arch/arm/mach-omap1/Kconfig 2006-04-02 20:47:24.000000000 +0300
+@@ -26,6 +26,15 @@
+ TI OMAP 1510 or 1610 Innovator board support. Say Y here if you
+ have such a board.
+
++config MACH_OMAP_H6300
++ bool "HP iPAQ h6300 series"
++ depends on ARCH_OMAP1 && ARCH_OMAP15XX
++ select I2C
++ select PCA9535
++ help
++ HP iPAQ h6315, h6340 and h6365 devices that are based
++ on the OMAP 1510. Say Y here if you have such a device.
++
+ config MACH_OMAP_H2
+ bool "TI H2 Support"
+ depends on ARCH_OMAP1 && ARCH_OMAP16XX
+diff -Naur linux-2.6.16.16/arch/arm/mach-omap1/Makefile h6300_dev/arch/arm/mach-omap1/Makefile
+--- linux-2.6.16.16/arch/arm/mach-omap1/Makefile 2006-05-17 21:41:28.000000000 +0300
++++ h6300_dev/arch/arm/mach-omap1/Makefile 2006-04-02 00:23:01.000000000 +0300
+@@ -23,6 +23,7 @@
+ obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o
+ obj-$(CONFIG_MACH_NOKIA770) += board-nokia770.o
+ obj-$(CONFIG_MACH_AMS_DELTA) += board-ams-delta.o
++obj-$(CONFIG_MACH_OMAP_H6300) += board-h6300.o
+
+ ifeq ($(CONFIG_ARCH_OMAP15XX),y)
+ # Innovator-1510 FPGA
+@@ -36,4 +37,3 @@
+ led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o
+ led-$(CONFIG_MACH_OMAP_OSK) += leds-osk.o
+ obj-$(CONFIG_LEDS) += $(led-y)
+-
+diff -Naur linux-2.6.16.16/arch/arm/mach-omap1/mux.c h6300_dev/arch/arm/mach-omap1/mux.c
+--- linux-2.6.16.16/arch/arm/mach-omap1/mux.c 2006-05-17 21:41:28.000000000 +0300
++++ h6300_dev/arch/arm/mach-omap1/mux.c 2006-02-21 23:54:33.000000000 +0200
+@@ -200,6 +200,13 @@
+ MUX_CFG("P15_1610_UWIRE_CS3", 8, 12, 1, 1, 22, 0, 1, 1, 1)
+ MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, 1, 14, 0, NA, 0, 1)
+
++/* OMAP-1510 uWire */
++MUX_CFG("P15_1510_UWIRE_CS3", 8, 12, 1, NA, 0, 0, NA, 0, 1)
++MUX_CFG("N14_1510_UWIRE_CS0", 8, 9, 1, NA, 0, 0, NA, 0, 1)
++MUX_CFG("V19_1510_UWIRE_SCLK", 8, 6, 0, NA, 0, 0, NA, 0, 1)
++MUX_CFG("W21_1510_UWIRE_SDO", 8, 3, 0, NA, 0, 0, NA, 0, 1)
++MUX_CFG("U18_1510_UWIRE_SDI", 8, 0, 0, 1, 18, 0, NA, 0, 1)
++
+ /* OMAP-1610 Flash */
+ MUX_CFG("L3_1610_FLASH_CS2B_OE",10, 6, 1, NA, 0, 0, NA, 0, 1)
+ MUX_CFG("M8_1610_FLASH_CS2B_WE",10, 3, 1, NA, 0, 0, NA, 0, 1)
+@@ -262,6 +269,7 @@
+ MUX_CFG("T20_1610_LOW_PWR", 7, 12, 1, NA, 0, 0, NA, 0, 0)
+
+ /* MCLK Settings */
++MUX_CFG("R10_1510_MCLK_ON", B, 18, 0, 2, 22, 1, NA, 1, 1)
+ MUX_CFG("V5_1710_MCLK_ON", B, 15, 0, NA, 0, 0, NA, 0, 0)
+ MUX_CFG("V5_1710_MCLK_OFF", B, 15, 6, NA, 0, 0, NA, 0, 0)
+ MUX_CFG("R10_1610_MCLK_ON", B, 18, 0, NA, 22, 0, NA, 1, 0)
+diff -Naur linux-2.6.16.16/arch/arm/plat-omap/devices.c h6300_dev/arch/arm/plat-omap/devices.c
+--- linux-2.6.16.16/arch/arm/plat-omap/devices.c 2006-05-17 21:41:28.000000000 +0300
++++ h6300_dev/arch/arm/plat-omap/devices.c 2006-05-18 00:59:02.000000000 +0300
+@@ -92,7 +92,7 @@
+
+ static void omap_init_kp(void)
+ {
+- if (machine_is_omap_h2() || machine_is_omap_h3()) {
++ if (machine_is_omap_h2() || machine_is_omap_h3() || machine_is_omap_h6300()) {
+ omap_cfg_reg(F18_1610_KBC0);
+ omap_cfg_reg(D20_1610_KBC1);
+ omap_cfg_reg(D19_1610_KBC2);
+diff -Naur linux-2.6.16.16/arch/arm/plat-omap/dma.c h6300_dev/arch/arm/plat-omap/dma.c
+--- linux-2.6.16.16/arch/arm/plat-omap/dma.c 2006-05-17 21:41:28.000000000 +0300
++++ h6300_dev/arch/arm/plat-omap/dma.c 2006-02-06 15:36:21.000000000 +0200
+@@ -30,6 +30,7 @@
+ #include <asm/hardware.h>
+ #include <asm/dma.h>
+ #include <asm/io.h>
++#include <asm/mach-types.h>
+
+ #include <asm/arch/tc.h>
+
+@@ -1086,6 +1087,10 @@
+ }
+
+ if (omap_dma_in_1510_mode()) {
++ u16 l = omap_readw(OMAP1510_DMA_LCD_CTRL);
++ l &= ~(1 << 6);
++ omap_writew (l, OMAP1510_DMA_LCD_CTRL);
++
+ omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U);
+ omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L);
+ omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U);
+diff -Naur linux-2.6.16.16/arch/arm/tools/mach-types h6300_dev/arch/arm/tools/mach-types
+--- linux-2.6.16.16/arch/arm/tools/mach-types 2006-05-11 04:56:24.000000000 +0300
++++ h6300_dev/arch/arm/tools/mach-types 2006-04-24 20:53:29.000000000 +0300
+@@ -576,7 +576,7 @@
+ s3c2460 MACH_S3C2460 S3C2460 560
+ pdm MACH_PDM PDM 561
+ h4700 MACH_H4700 H4700 562
+-h6300 MACH_H6300 H6300 563
++omap_h6300 MACH_OMAP_H6300 OMAP_H6300 563
+ rz1700 MACH_RZ1700 RZ1700 564
+ a716 MACH_A716 A716 565
+ estk2440a MACH_ESTK2440A ESTK2440A 566
+diff -Naur linux-2.6.16.16/drivers/bluetooth/Kconfig h6300_dev/drivers/bluetooth/Kconfig
+--- linux-2.6.16.16/drivers/bluetooth/Kconfig 2006-05-17 21:41:29.000000000 +0300
++++ h6300_dev/drivers/bluetooth/Kconfig 2006-02-21 23:54:33.000000000 +0200
+@@ -166,6 +166,16 @@
+
+ Say Y here to compile support for virtual HCI devices into the
+ kernel or say M to compile it as module (hci_vhci).
++
++config BT_H6300
++ tristate "H6300 BRF6100 BT DRIVER"
++ help
++ Bluetooth H6300 BRF6100 driver.
++ This driver provides the firmware loading mechanism for the BRF6100
++ bt hardware in iPAQ h6300.
++
++ Say Y here to compile support for BRF6100 BT devices into the
++ kernel or say M to compile it as module (h6300_BT).
+
+ endmenu
+
+diff -Naur linux-2.6.16.16/drivers/bluetooth/Makefile h6300_dev/drivers/bluetooth/Makefile
+--- linux-2.6.16.16/drivers/bluetooth/Makefile 2006-05-17 21:41:29.000000000 +0300
++++ h6300_dev/drivers/bluetooth/Makefile 2006-02-21 23:54:33.000000000 +0200
+@@ -13,6 +13,7 @@
+ obj-$(CONFIG_BT_HCIBLUECARD) += bluecard_cs.o
+ obj-$(CONFIG_BT_HCIBTUART) += btuart_cs.o
+ obj-$(CONFIG_BT_HCIBRF6150) += brf6150.o
++obj-$(CONFIG_BT_H6300) += omap/
+
+ hci_uart-y := hci_ldisc.o
+ hci_uart-$(CONFIG_BT_HCIUART_H4) += hci_h4.o
+diff -Naur linux-2.6.16.16/drivers/bluetooth/omap/h6300_bt_brf6100.c h6300_dev/drivers/bluetooth/omap/h6300_bt_brf6100.c
+--- linux-2.6.16.16/drivers/bluetooth/omap/h6300_bt_brf6100.c 1970-01-01 02:00:00.000000000 +0200
++++ h6300_dev/drivers/bluetooth/omap/h6300_bt_brf6100.c 2006-01-23 00:09:23.000000000 +0200
+@@ -0,0 +1,154 @@
++/*
++ * Bluetooth interface driver for TI BRF6100 on h6300
++ *
++ * Copyright (C) 2005 Mika Laitio <lamikr@cc.jyu.fi>
++ * Ideas taken from the brf6150 bt driver made by Todd Blumer for the pxa hx4700.
++ *
++ * 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/module.h>
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++
++#include <asm/hardware.h>
++#include <asm/arch/gpio.h>
++
++#include <asm/arch/h6300_uart_info.h>
++#include "h6300_bt_led.h"
++
++static void
++h6300_bt_configure(struct uart_omap_port *up, int enable)
++{
++ printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_configure() started, enable = %d\n", enable);
++
++ // printk( KERN_NOTICE "h6300 configure bluetooth: %d\n", enable );
++ if (enable == 0) {
++ omap_set_gpio_dataout(GPIO_N_BT_RST, 1); // turn off gpio, note 1 == off for negative gpios
++ mdelay(5);
++ h6300_clear_led(INDEX_BT_LED);
++ }
++ else if (enable == 1) {
++ omap_set_gpio_dataout(GPIO_N_BT_RST, 1); // turn on gpio, note 0 == on for negative gpios
++ mdelay(5);
++ }
++ else if (enable == 2) {
++ /*
++ * BRF6150's RTS goes low when firmware is ready
++ * so check for CTS=1 (nCTS=0 -> CTS=1). Typical 150ms
++ */
++/*
++ int tries = 0;
++ do
++ {
++ mdelay(10);
++ }
++ while ((BTMSR & MSR_CTS) == 0 && tries++ < 50);
++*/
++ h6300_set_led(INDEX_BT_LED, 16, 16);
++ }
++ printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_configure() done\n");
++}
++
++static void
++h6300_bt_set_txrx(struct uart_omap_port *up, int txrx)
++{
++ printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_set_txrx(), txrx = %d done\n", txrx);
++ /* do nothing */
++}
++
++static int
++h6300_bt_get_txrx(struct uart_omap_port *up)
++{
++ printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_get_txrx() done\n");
++ /* do nothing */
++ return 0;
++}
++
++static int
++h6300_bt_probe(struct platform_device *pdev)
++{
++ struct h6300_uart_funcs *funcs = (struct h6300_uart_funcs *)pdev->dev.platform_data;
++
++ omap_request_gpio(GPIO_BT_PWR_EN); // ask bt_power_en gpio, remember to release in remove_function
++ omap_set_gpio_direction(GPIO_BT_PWR_EN, 1); // set gpio direction to be output
++ omap_set_gpio_dataout(GPIO_BT_PWR_EN, 1); // turn on gpio
++
++ mdelay(200);
++
++ omap_request_gpio(GPIO_N_BT_RST); // ask bt_reset gpio, remember to release in remove_function
++ omap_set_gpio_direction(GPIO_N_BT_RST, 1); // set gpio direction to be output
++ omap_set_gpio_dataout(GPIO_N_BT_RST, 0); // turn on gpio, note 0 == on for negative gpios
++
++ /* configure bluetooth UART */
++ //h6300_gpio_mode(GPIO_NR_H6300_BT_RXD_MD);
++ //h6300_gpio_mode(GPIO_NR_H6300_BT_TXD_MD);
++ //h6300_gpio_mode(GPIO_NR_H6300_BT_UART_CTS_MD);
++ //h6300_gpio_mode(GPIO_NR_H6300_BT_UART_RTS_MD);
++
++ funcs->configure = h6300_bt_configure;
++ funcs->set_txrx = h6300_bt_set_txrx;
++ funcs->get_txrx = h6300_bt_get_txrx;
++
++ /* Make sure the LED is off */
++ h6300_clear_led(INDEX_BT_LED);
++
++ printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_probe() done\n");
++
++ return 0;
++}
++
++static int
++h6300_bt_remove(struct platform_device *pdev)
++{
++ struct h6300_uart_funcs *funcs = (struct h6300_uart_funcs *)pdev->dev.platform_data;
++
++ printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_remove() started\n");
++
++ omap_free_gpio(GPIO_BT_PWR_EN);
++ omap_free_gpio(GPIO_N_BT_RST);
++
++ funcs->configure = NULL;
++ funcs->set_txrx = NULL;
++ funcs->get_txrx = NULL;
++
++ /* Make sure the LED is off */
++ h6300_clear_led(INDEX_BT_LED);
++
++ printk(KERN_NOTICE "h6300_bt_brf6100.c, h6300_bt_remove() done\n");
++
++ return 0;
++}
++
++static struct platform_driver bt_driver = {
++ .probe = h6300_bt_probe,
++ .remove = h6300_bt_remove,
++ .driver = {
++ .name = "h6300_bt",
++ },
++};
++
++static int __init
++h6300_bt_init(void)
++{
++ printk(KERN_NOTICE "h6300 Bluetooth Driver init()\n");
++ return platform_driver_register(&bt_driver);
++}
++
++static void __exit
++h6300_bt_exit(void)
++{
++ printk(KERN_NOTICE "h6300 Bluetooth Driver exit()\n");
++ platform_driver_unregister(&bt_driver);
++}
++
++module_init(h6300_bt_init);
++module_exit(h6300_bt_exit);
++
++MODULE_AUTHOR("Mika Laitio, <lamikr@cc.jyu.fi>");
++MODULE_DESCRIPTION("iPAQ h6300 BRF6100 Bluetooth driver.");
++MODULE_LICENSE("GPL");
++
+diff -Naur linux-2.6.16.16/drivers/bluetooth/omap/h6300_bt_led.c h6300_dev/drivers/bluetooth/omap/h6300_bt_led.c
+--- linux-2.6.16.16/drivers/bluetooth/omap/h6300_bt_led.c 1970-01-01 02:00:00.000000000 +0200
++++ h6300_dev/drivers/bluetooth/omap/h6300_bt_led.c 2005-10-06 02:34:39.000000000 +0300
+@@ -0,0 +1,41 @@
++/*
++ * Bluetooth interface driver helper for controlling bluetooth leds available in iPAQ h6300.
++ *
++ * Copyright (C) 2005 Mika Laitio <lamikr@cc.jyu.fi>
++ * Ideas from the brf6150 bt driver made by Todd Blumer for the pxa hx4700.
++ *
++ * 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/module.h>
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++
++#include <asm/hardware.h>
++#include <asm/arch/gpio.h>
++
++/*
++ * Low level access for disabling h6300 bt led.
++ *
++ * TODO: implement for h6300
++ */
++void h6300_clear_led(int led_num)
++{
++ printk(KERN_NOTICE "h6300_bt_led.c h6300_clear_led() done\n");
++ //hx4700_set_led(led_num, 0, 16);
++}
++EXPORT_SYMBOL(h6300_clear_led);
++
++/*
++ * Low level access for setting up the bt led.
++ *
++ * TODO: implement for h6300
++ */
++void h6300_set_led(int led_num, int duty_time, int cycle_time)
++{
++ printk(KERN_NOTICE "h6300_bt_led.c h6300_set_led() done\n");
++}
++EXPORT_SYMBOL(h6300_set_led);
+diff -Naur linux-2.6.16.16/drivers/bluetooth/omap/h6300_bt_led.h h6300_dev/drivers/bluetooth/omap/h6300_bt_led.h
+--- linux-2.6.16.16/drivers/bluetooth/omap/h6300_bt_led.h 1970-01-01 02:00:00.000000000 +0200
++++ h6300_dev/drivers/bluetooth/omap/h6300_bt_led.h 2005-10-06 02:34:39.000000000 +0300
+@@ -0,0 +1,9 @@
++#ifndef H6300_BT_LED_H_
++#define H6300_BT_LED_H_
++
++#define INDEX_BT_LED 2
++
++void h6300_clear_led(int led_num);
++void h6300_set_led(int led_num, int duty_time, int cycle_time);
++
++#endif /*H6300_BT_LED_H_*/
+diff -Naur linux-2.6.16.16/drivers/bluetooth/omap/Makefile h6300_dev/drivers/bluetooth/omap/Makefile
+--- linux-2.6.16.16/drivers/bluetooth/omap/Makefile 1970-01-01 02:00:00.000000000 +0200
++++ h6300_dev/drivers/bluetooth/omap/Makefile 2005-10-06 02:34:39.000000000 +0300
+@@ -0,0 +1,6 @@
++#
++# Makefile for the Linux iPAQ H6300 BRF6100 Bluetooth device drivers.
++#
++
++h6300_bt-objs := h6300_bt_led.o h6300_bt_brf6100.o
++obj-$(CONFIG_BT_H6300) += h6300_bt.o
+diff -Naur linux-2.6.16.16/drivers/i2c/busses/i2c-omap.c h6300_dev/drivers/i2c/busses/i2c-omap.c
+--- linux-2.6.16.16/drivers/i2c/busses/i2c-omap.c 2006-05-17 21:41:29.000000000 +0300
++++ h6300_dev/drivers/i2c/busses/i2c-omap.c 2006-04-02 00:23:01.000000000 +0300
+@@ -163,17 +163,22 @@
+
+ static int omap_i2c_get_clocks(struct omap_i2c_dev *dev)
+ {
+- if (cpu_is_omap16xx() || cpu_is_omap24xx()) {
++ if (cpu_is_omap24xx()) {
+ dev->iclk = clk_get(dev->dev, "i2c_ick");
+- if (IS_ERR(dev->iclk))
++ if (IS_ERR(dev->iclk)) {
+ return -ENODEV;
++ }
++ dev->fclk = clk_get(dev->dev, "i2c_fck");
++ if (IS_ERR(dev->fclk)) {
++ clk_put(dev->fclk);
++ return -ENODEV;
++ }
+ }
+
+- dev->fclk = clk_get(dev->dev, "i2c_fck");
+- if (IS_ERR(dev->fclk)) {
+- if (dev->iclk != NULL)
+- clk_put(dev->iclk);
+- return -ENODEV;
++ if (cpu_class_is_omap1()) {
++ dev->fclk = clk_get(dev->dev, "i2c_fck");
++ if (IS_ERR(dev->fclk))
++ return -ENODEV;
+ }
+
+ return 0;
+diff -Naur linux-2.6.16.16/drivers/i2c/chips/Kconfig h6300_dev/drivers/i2c/chips/Kconfig
+--- linux-2.6.16.16/drivers/i2c/chips/Kconfig 2006-05-17 21:41:29.000000000 +0300
++++ h6300_dev/drivers/i2c/chips/Kconfig 2006-04-24 20:53:29.000000000 +0300
+@@ -46,6 +46,16 @@
+ This driver can also be built as a module. If so, the module
+ will be called pcf8574.
+
++config PCA9535
++ tristate "Philips PCA9535 16-bit I/O port"
++ depends on I2C
++ help
++ If you say yes here you get support for the Philips PCA9535
++ 16-bit I/O port.
++
++ This driver can also be built as a module. If so, the module
++ will be called pca9535.
++
+ config SENSORS_PCA9539
+ tristate "Philips PCA9539 16-bit I/O port"
+ depends on I2C && EXPERIMENTAL
+diff -Naur linux-2.6.16.16/drivers/i2c/chips/Makefile h6300_dev/drivers/i2c/chips/Makefile
+--- linux-2.6.16.16/drivers/i2c/chips/Makefile 2006-05-17 21:41:29.000000000 +0300
++++ h6300_dev/drivers/i2c/chips/Makefile 2006-04-24 20:53:29.000000000 +0300
+@@ -7,6 +7,7 @@
+ obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o
+ obj-$(CONFIG_SENSORS_MAX6875) += max6875.o
+ obj-$(CONFIG_SENSORS_M41T00) += m41t00.o
++obj-$(CONFIG_PCA9535) += pca9535.o
+ obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o
+ obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
+ obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
+diff -Naur linux-2.6.16.16/drivers/i2c/chips/pca9535.c h6300_dev/drivers/i2c/chips/pca9535.c
+--- linux-2.6.16.16/drivers/i2c/chips/pca9535.c 1970-01-01 02:00:00.000000000 +0200
++++ h6300_dev/drivers/i2c/chips/pca9535.c 2006-04-24 20:53:29.000000000 +0300
+@@ -0,0 +1,412 @@
++/*
++ Driver for Philips PCA9535 16-bit low power I/O port with interrupt
++
++ 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.
++
++ Copyright (C) 2005 Husam Senussi
++ Framework based on Pawel Kolodziejski's pca9535 driver in
++ handheld.org's 2.6.13 kernel. Driver updated by Mika Laitio.
++*/
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/hwmon-sysfs.h>
++#include <linux/hwmon.h>
++#include <linux/err.h>
++
++#include <asm/arch/pca9535.h>
++#include <linux/delay.h>
++
++#include <linux/interrupt.h>
++#include <asm/mach-types.h>
++#include <asm/irq.h>
++#include <asm/mach/arch.h>
++#include <asm/hardware.h>
++
++EXPORT_SYMBOL(pca9535_gpio_read);
++EXPORT_SYMBOL(pca9535_gpio_write);
++EXPORT_SYMBOL(pca9535_gpio_direction);
++
++static int pca9535_attach_adapter(struct i2c_adapter *adapter);
++static int pca9535_detach_client(struct i2c_client *client);
++static int pca9535_attach(struct i2c_adapter *adapter, int address, int zero_or_minus_one);
++static u32 pca9535_read_reg(struct i2c_client *client, u8 regaddr);
++static void pca9535_write_reg(struct i2c_client *client, u8 regaddr, u16 param);
++
++enum pca9535_cmd
++{
++ PCA9535_INPUT_0 = 0,
++ PCA9535_INPUT_1 = 1,
++ PCA9535_OUTPUT_0 = 2,
++ PCA9535_OUTPUT_1 = 3,
++ PCA9535_INVERT_0 = 4,
++ PCA9535_INVERT_1 = 5,
++ PCA9535_DIRECTION_0 = 6,
++ PCA9535_DIRECTION_1 = 7,
++};
++
++struct pca9535_data {
++ struct semaphore lock;
++ struct i2c_client client;
++};
++
++static struct i2c_driver pca9535_driver = {
++ .driver = {
++ .name = "pca9535",
++ },
++ .attach_adapter = pca9535_attach_adapter,
++ .detach_client = pca9535_detach_client,
++};
++
++static struct i2c_client *pca9535_i2c_client = NULL;
++static struct pca9535_data pca9535_inited;
++
++static unsigned short normal_i2c[] = { 0x20, I2C_CLIENT_END };
++
++#define DRIVER_VERSION "20 OCT 2005"
++#define DRIVER_NAME "PCA9535"
++
++/*
++ * sysfs callback function.
++ */
++static ssize_t pca9535_show(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ struct sensor_device_attribute *psa = to_sensor_dev_attr(attr);
++ struct i2c_client *client = to_i2c_client(dev);
++ return sprintf(buf, "%02X\n", (pca9535_read_reg(client, psa->index) >> 8));
++}
++
++/*
++ * sysfs callback function.
++ */
++static ssize_t pca9535_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct sensor_device_attribute *psa = to_sensor_dev_attr(attr);
++ struct i2c_client *client = to_i2c_client(dev);
++ unsigned long val = simple_strtoul(buf, NULL, 0);
++ unsigned long old = pca9535_read_reg(client, psa->index);
++
++ if (val > 0xff)
++ return -EINVAL;
++
++ val = (old & 0xff) | (val << 8);
++ pca9535_write_reg(client, psa->index, val);
++ return count;
++}
++
++#define PCA9535_ENTRY_RO(name, cmd_idx) \
++ static SENSOR_DEVICE_ATTR(name, S_IRUGO, pca9535_show, NULL, cmd_idx)
++
++#define PCA9535_ENTRY_RW(name, cmd_idx) \
++ static SENSOR_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, pca9535_show, \
++ pca9535_store, cmd_idx)
++
++PCA9535_ENTRY_RO(input0, PCA9535_INPUT_0);
++PCA9535_ENTRY_RO(input1, PCA9535_INPUT_1);
++PCA9535_ENTRY_RW(output0, PCA9535_OUTPUT_0);
++PCA9535_ENTRY_RW(output1, PCA9535_OUTPUT_1);
++PCA9535_ENTRY_RW(invert0, PCA9535_INVERT_0);
++PCA9535_ENTRY_RW(invert1, PCA9535_INVERT_1);
++PCA9535_ENTRY_RW(direction0, PCA9535_DIRECTION_0);
++PCA9535_ENTRY_RW(direction1, PCA9535_DIRECTION_1);
++
++static struct attribute *pca9535_attributes[] = {
++ &sensor_dev_attr_input0.dev_attr.attr,
++ &sensor_dev_attr_input1.dev_attr.attr,
++ &sensor_dev_attr_output0.dev_attr.attr,
++ &sensor_dev_attr_output1.dev_attr.attr,
++ &sensor_dev_attr_invert0.dev_attr.attr,
++ &sensor_dev_attr_invert1.dev_attr.attr,
++ &sensor_dev_attr_direction0.dev_attr.attr,
++ &sensor_dev_attr_direction1.dev_attr.attr,
++ NULL
++};
++
++static struct attribute_group pca9535_defattr_group = {
++ .attrs = pca9535_attributes,
++};
++//End of sysfs management code.
++
++I2C_CLIENT_INSMOD;
++
++u32 pca9535_read_input(void)
++{
++ return pca9535_read_reg(pca9535_i2c_client, 0);
++}
++EXPORT_SYMBOL(pca9535_read_input);
++
++void pca9535_write_output(u16 param)
++{
++ pca9535_write_reg(pca9535_i2c_client, 2, param);
++}
++EXPORT_SYMBOL(pca9535_write_output);
++
++void pca9535_set_dir(u16 param)
++{
++ pca9535_write_reg(pca9535_i2c_client, 6, param);
++}
++EXPORT_SYMBOL(pca9535_set_dir);
++
++static int pca9535_attach_adapter(struct i2c_adapter *adapter)
++{
++ return i2c_probe(adapter, &addr_data, pca9535_attach);
++}
++
++static int pca9535_attach(struct i2c_adapter *adapter, int address, int zero_or_minus_one)
++{
++ struct i2c_client *new_client;
++ int err = 0;
++
++ new_client = &(pca9535_inited.client);
++ i2c_set_clientdata(new_client, 0);
++ new_client->addr = address;
++ new_client->adapter = adapter;
++ new_client->driver = &pca9535_driver;
++ strcpy(new_client->name, DRIVER_NAME);
++
++ if ((err = i2c_attach_client(new_client)))
++ goto exit_free;
++
++ pca9535_i2c_client = new_client;
++
++ init_MUTEX(&pca9535_inited.lock);
++ i2c_set_clientdata(pca9535_i2c_client, &pca9535_inited);
++
++ sysfs_create_group(&pca9535_i2c_client->dev.kobj, &pca9535_defattr_group);
++
++ printk("pca9535_attach() ok, address = %d, zero_or_minus_one = %d\n", address, zero_or_minus_one);
++ return 0;
++
++exit_free:
++ printk("pca9535_attach() failed, error code = %d\n", err);
++ return err;
++}
++
++static int pca9535_detach_client(struct i2c_client *client)
++{
++ int err;
++
++ if ((err = i2c_detach_client(client))) {
++ dev_err(&client->dev, "Client deregistration failed, client not detached.\n");
++ return err;
++ }
++ pca9535_i2c_client = NULL;
++
++ return 0;
++}
++
++static int __init pca9535_init(void)
++{
++ return i2c_add_driver(&pca9535_driver);
++}
++
++static void __exit pca9535_exit(void)
++{
++ i2c_del_driver(&pca9535_driver);
++}
++
++/*
++ * Reads the value of GPIO available via I2C.
++ */
++int pca9535_gpio_read(int gpio){
++ unsigned char reg = 0;
++ unsigned long val = 0;
++
++ printk("9535_gpio_read() called\n");
++ if(!pca9535_i2c_client)
++ return -ENODEV;
++
++ if(gpio < GPIO0 || gpio > GPIO17)
++ return -EINVAL;
++
++ if(gpio >= GPIO0 && gpio <= GPIO7){
++ reg = PCA9535_INPUT_0;
++ gpio -= GPIO0;
++ }else if(gpio >= GPIO8 && gpio <= GPIO17){
++ reg = PCA9535_INPUT_1;
++ gpio -= GPIO8;
++ }
++
++ down(&pca9535_inited.lock);
++
++ // Read the existing values first
++ val = pca9535_read_reg(pca9535_i2c_client, reg) >> 8;
++ val = (val >> gpio) & 0x01;
++
++ up(&pca9535_inited.lock);
++
++ return val;
++}
++
++/*
++ * Set the value of I2C GPIO.
++ */
++int pca9535_gpio_write(int gpio, unsigned char value){
++ unsigned char in_reg = 0;
++ unsigned char out_reg = 0;
++ unsigned long val = 0;
++ unsigned long old = 0;
++ int ret = 0;
++
++ if(!pca9535_i2c_client)
++ return -ENODEV;
++
++ if(gpio < GPIO0 || gpio > GPIO17)
++ return -EINVAL;
++
++ if(gpio >= GPIO0 && gpio <= GPIO7){
++ in_reg = PCA9535_INPUT_0;
++ out_reg = PCA9535_OUTPUT_0;
++ gpio -= GPIO0;
++ }else if(gpio >= GPIO8 && gpio <= GPIO17){
++ in_reg = PCA9535_INPUT_1;
++ out_reg = PCA9535_OUTPUT_1;
++ gpio -= GPIO8;
++ }
++
++ down(&pca9535_inited.lock);
++
++ // Read the existing values first
++ val = pca9535_read_reg(pca9535_i2c_client, in_reg);
++ old = val >> 8;
++
++ switch(value){
++ case LOW:
++ old |= (1 << gpio);
++ break;
++ case HI:
++ old &= ~(1 << gpio);
++ break;
++ default:
++ ret = -EINVAL;
++ goto error;
++ }
++
++ val = (val & 0xff) | (old << 8);
++
++ // write the values back to the register
++ pca9535_write_reg(pca9535_i2c_client, out_reg, val);
++error:
++
++ up(&pca9535_inited.lock);
++ return ret;
++}
++
++/*
++ * Set the direction of I2C GPIO.
++ */
++int pca9535_gpio_direction(int gpio, unsigned char direction){
++ unsigned char reg = 0;
++ unsigned long val = 0;
++ unsigned long old = 0;
++ int ret = 0;
++
++ if(!pca9535_i2c_client)
++ return -ENODEV;
++
++ if(gpio < GPIO0 || gpio > GPIO17)
++ return -EINVAL;
++
++ if(gpio >= GPIO0 && gpio <= GPIO7){
++ reg = PCA9535_DIRECTION_0;
++ gpio -= GPIO0;
++ }else if(gpio >= GPIO8 && gpio <= GPIO17){
++ reg = PCA9535_DIRECTION_1;
++ gpio -= GPIO8;
++ }
++
++ down(&pca9535_inited.lock);
++
++ // Read the existing values first
++ old = pca9535_read_reg(pca9535_i2c_client, reg);
++ val = old >> 8;
++
++ switch(direction){
++ case GPIO_INPUT:
++ val |= (1 << gpio);
++ break;
++ case GPIO_OUTPUT:
++ val &= ~(1 << gpio);
++ break;
++ default:
++ ret = -EINVAL;
++ goto error;
++ }
++
++ val = (old & 0xff) | (val << 8);
++
++ // write the values back to the register
++ pca9535_write_reg(pca9535_i2c_client, reg, val);
++error:
++
++ up(&pca9535_inited.lock);
++ return ret;
++}
++
++static u32 pca9535_read_reg(struct i2c_client *client, u8 regaddr)
++{
++ char buffer[3];
++ int r;
++ u32 data;
++
++ buffer[0] = regaddr;
++ buffer[1] = 0;
++ buffer[2] = 0;
++
++ r = i2c_master_send(client, buffer, 1);
++ if (r != 1) {
++ printk(KERN_ERR "pca9535: read failed, status %d\n", r);
++ return 0xffffffff;
++ }
++
++ r = i2c_master_recv(client, buffer, 3);
++ if (r != 3) {
++ printk(KERN_ERR "pca9535: read failed, status %d\n", r);
++ return 0xffffffff;
++ }
++
++ data = buffer[1];
++ data |= buffer[2] << 8;
++ //printk(KERN_ERR "%s: reading %x in %x\n", __FUNCTION__, data, regaddr);
++
++ return data;
++}
++
++static void pca9535_write_reg(struct i2c_client *client, u8 regaddr, u16 data)
++{
++ char buffer[3];
++ int r;
++
++ //printk(KERN_ERR "%s: writing %x in %x\n", __FUNCTION__, data, regaddr);
++ buffer[0] = regaddr;
++ buffer[1] = data >> 8;
++ buffer[2] = data & 0xff;
++
++ r = i2c_master_send(client, buffer, 3);
++ if (r != 3) {
++ printk(KERN_ERR "pca9535: write failed, status %d\n", r);
++ }
++}
++
++MODULE_AUTHOR("Husam Senussi <husamsenussi@gmail.com>");
++MODULE_DESCRIPTION("PCA9535 driver");
++MODULE_LICENSE("GPL");
++
++module_init(pca9535_init);
++module_exit(pca9535_exit);
+diff -Naur linux-2.6.16.16/drivers/input/keyboard/omap-keypad.c h6300_dev/drivers/input/keyboard/omap-keypad.c
+--- linux-2.6.16.16/drivers/input/keyboard/omap-keypad.c 2006-05-17 21:41:29.000000000 +0300
++++ h6300_dev/drivers/input/keyboard/omap-keypad.c 2006-04-24 20:53:29.000000000 +0300
+@@ -4,11 +4,12 @@
+ * OMAP Keypad Driver
+ *
+ * Copyright (C) 2003 Nokia Corporation
+- * Written by Timo Ter舖 <ext-timo.teras@nokia.com>
++ * Written by Timo Terソスs <ext-timo.teras@nokia.com>
++ * iPAQ h6300 key and joypad support added by Mika Laitio. (2005)
+ *
+ * Added support for H2 & H3 Keypad
+ * Copyright (C) 2004 Texas Instruments
+- *
++ *
+ * 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
+@@ -44,6 +45,19 @@
+ #include <asm/arch/mux.h>
+
+ #undef NEW_BOARD_LEARNING_MODE
++//#define NEW_BOARD_LEARNING_MODE 1
++
++/*
++ * Following 5 keypad events are not really sent to userspace.
++ * Instead if the good combination of them is sent, then that is send.
++ * (up, right, down, left, enter)
++ */
++#define _H6300_JOYPAD_UP_RIGHT 1 // 00001
++#define _H6300_JOYPAD_DOWN_RIGHT 2 // 00010
++#define _h6300_JOYPAD_DOWN_LEFT 4 // 00100
++#define _h6300_JOYPAD_UP_LEFT 8 // 01000
++#define _H6300_JOYPAD_KEY_OK 16 // 10000
++#define _H6300_JOYPAD_REPORT_COLUMN 4
+
+ static void omap_kp_tasklet(unsigned long);
+ static void omap_kp_timer(unsigned long);
+@@ -53,6 +67,8 @@
+ static int kp_enable = 1;
+ static int kp_cur_group = -1;
+
++static int prevJoypadKeycodePressEmulated;
++
+ struct omap_kp {
+ struct input_dev *input;
+ struct timer_list timer;
+@@ -139,7 +155,7 @@
+ for (col = 0; col < omap_kp->cols; col++) {
+ omap_writew(~(1 << col) & 0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
+
+- if (machine_is_omap_osk() || machine_is_omap_h2() || machine_is_omap_h3()) {
++ if (machine_is_omap_osk() || machine_is_omap_h2() || machine_is_omap_h3() || machine_is_omap_h6300()) {
+ udelay(9);
+ } else {
+ udelay(4);
+@@ -169,17 +185,26 @@
+ return -1;
+ }
+
++int is_key_down(unsigned char new_state[],
++ int col,
++ int row)
++{
++ return (new_state[col] & (1 << row)) ? 1 : 0;
++}
++
+ static void omap_kp_tasklet(unsigned long data)
+ {
+ struct omap_kp *omap_kp_data = (struct omap_kp *) data;
+ unsigned char new_state[8], changed, key_down = 0;
+ int col, row;
+ int spurious = 0;
++ int report_key, report_col, report_row, joypad_checked; // h6300-joypad specific variables
+
+ /* check for any changes */
+ omap_kp_scan_keypad(omap_kp_data, new_state);
+
+ /* check for changes and print those */
++ joypad_checked = 0;
+ for (col = 0; col < omap_kp_data->cols; col++) {
+ changed = new_state[col] ^ keypad_state[col];
+ key_down |= new_state[col];
+@@ -201,14 +226,177 @@
+ spurious = 1;
+ continue;
+ }
+-
+- if (!(kp_cur_group == (key & GROUP_MASK) ||
+- kp_cur_group == -1))
+- continue;
+-
+- kp_cur_group = key & GROUP_MASK;
+- input_report_key(omap_kp_data->input, key & ~GROUP_MASK,
+- !!(new_state[col] & (1 << row)));
++ if (machine_is_omap_h6300() &&
++ ((col == 1) || (col == _H6300_JOYPAD_REPORT_COLUMN)))
++ {
++ if (col == _H6300_JOYPAD_REPORT_COLUMN)
++ {
++ continue;
++ }
++ if ((joypad_checked == 0) &&
++ ((key == _H6300_JOYPAD_KEY_OK) ||
++ (key == _h6300_JOYPAD_UP_LEFT) ||
++ (key == _H6300_JOYPAD_UP_RIGHT) ||
++ (key == _H6300_JOYPAD_DOWN_RIGHT) ||
++ (key == _h6300_JOYPAD_DOWN_LEFT)))
++ {
++ if (is_key_down(new_state, col, row))
++ {
++ /*
++ * only enter pressed
++ * 1 0 0 _H6300_JOYPAD_KEY_OK 0 0
++ * --> 100100 == 36
++ */
++ if (new_state[1] == 36)
++ {
++ joypad_checked = 1;
++ prevJoypadKeycodePressEmulated = KEY_ENTER;
++ new_state[_H6300_JOYPAD_REPORT_COLUMN] = 48; //110000
++ report_key = prevJoypadKeycodePressEmulated;
++ report_col = _H6300_JOYPAD_REPORT_COLUMN;
++ report_row = 4;
++ input_report_key(omap_kp_data->input,
++ report_key,
++ new_state[report_col] & (1 << report_row));
++ }
++ /*
++ * enter, up_left and up_right sensors pressed.
++ * 1 _H6300_JOYPAD_UP_RIGHT 0 _H6300_JOYPAD_KEY_OK 0 _h6300_JOYPAD_UP_LEFT
++ * --> 110101 == 53
++ * OR
++ * 1 KEY_UP_RIGHT 0 0 0 _h6300_JOYPAD_UP_LEFT
++ * --> 110001 == 42
++ * --> move to up
++ */
++ else if ((new_state[1] == 53) ||
++ (new_state[1] == 49))
++ {
++ joypad_checked = 1;
++ prevJoypadKeycodePressEmulated = KEY_UP;
++ new_state[_H6300_JOYPAD_REPORT_COLUMN] = 40; //101000
++ report_key = prevJoypadKeycodePressEmulated;
++ report_col = _H6300_JOYPAD_REPORT_COLUMN;
++ report_row = 3;
++ input_report_key(omap_kp_data->input,
++ report_key,
++ new_state[report_col] & (1 << report_row));
++ }
++ /*
++ * enter, down_left and down_right sensors pressed
++ * --> 101110 == 46
++ * OR
++ * down_left and down_right
++ * -->101010 == 42
++ * --> move to down
++ */
++ else if ((new_state[1] == 46) ||
++ (new_state[1] == 42))
++ {
++ joypad_checked = 1;
++ prevJoypadKeycodePressEmulated = KEY_DOWN;
++ new_state[_H6300_JOYPAD_REPORT_COLUMN] = 34; //100010
++ report_key = prevJoypadKeycodePressEmulated;
++ report_col = _H6300_JOYPAD_REPORT_COLUMN;
++ report_row = 1;
++ input_report_key(omap_kp_data->input,
++ report_key,
++ new_state[report_col] & (1 << report_row));
++ }
++ /*
++ * enter, up_right and down_right sensors pressed
++ * --> 111100 == 60
++ * or
++ * down_right and up_right
++ * --> 111000 == 56
++ * --> move to right
++ */
++ else if ((new_state[1] == 60) ||
++ (new_state[1] == 56))
++ {
++ joypad_checked = 1;
++ prevJoypadKeycodePressEmulated = KEY_RIGHT;
++ new_state[_H6300_JOYPAD_REPORT_COLUMN] = 33; //100001
++ report_key = prevJoypadKeycodePressEmulated;
++ report_col = _H6300_JOYPAD_REPORT_COLUMN;
++ report_row = 0;
++ input_report_key(omap_kp_data->input,
++ report_key,
++ new_state[report_col] & (1 << report_row));
++ }
++ /*
++ * enter, up_left and down_left sensors pressed
++ * --> 100111 == 39
++ * or up_left and down_left
++ * --> 100011 == 35
++ * --> move to left
++ */
++ else if ((new_state[1] == 39) ||
++ (new_state[1] == 35))
++ {
++ joypad_checked = 1;
++ prevJoypadKeycodePressEmulated = KEY_LEFT;
++ new_state[_H6300_JOYPAD_REPORT_COLUMN] = 36; //100100
++ report_key = prevJoypadKeycodePressEmulated;
++ report_col = _H6300_JOYPAD_REPORT_COLUMN;
++ report_row = 2;
++ input_report_key(omap_kp_data->input,
++ report_key,
++ new_state[report_col] & (1 << report_row));
++ }
++ else
++ {
++ //printk("missed new_state = %d\n", new_state[1]);
++ }
++ }
++ else
++ {
++ if (prevJoypadKeycodePressEmulated != 0)
++ {
++ // report key up event
++ joypad_checked = 1;
++ new_state[_H6300_JOYPAD_REPORT_COLUMN] = 32; //100000
++ report_key = prevJoypadKeycodePressEmulated;
++ report_col = _H6300_JOYPAD_REPORT_COLUMN;
++ switch(prevJoypadKeycodePressEmulated)
++ {
++ case KEY_RIGHT:
++ report_row = 0;
++ break;
++ case KEY_DOWN:
++ report_row = 1;
++ break;
++ case KEY_LEFT:
++ report_row = 2;
++ break;
++ case KEY_UP:
++ report_row = 3;
++ break;
++ case KEY_ENTER:
++ report_row = 4;
++ break;
++ default:
++ printk(KERN_WARNING "Unknown iPAQ h6300 column 1 key = %d released. This should newer happen!\n",
++ key);
++ report_row = 0;
++ }
++ input_report_key(omap_kp_data->input,
++ report_key,
++ new_state[report_col] & (1 << report_row));
++ prevJoypadKeycodePressEmulated = 0;
++ }
++ }
++ }
++ }
++ else
++ {
++ if (!(kp_cur_group == (key & GROUP_MASK) ||
++ kp_cur_group == -1))
++ continue;
++
++ kp_cur_group = key & GROUP_MASK;
++ input_report_key(omap_kp_data->input, key & ~GROUP_MASK,
++ !!(new_state[col] & (1 << row)));
++ }
+ #endif
+ }
+ }
+@@ -348,10 +536,11 @@
+ omap_set_gpio_direction(row_gpios[i], 1);
+ }
+ }
++ prevJoypadKeycodePressEmulated = 0;
+
+ init_timer(&omap_kp->timer);
+ omap_kp->timer.function = omap_kp_timer;
+- omap_kp->timer.data = (unsigned long) omap_kp;
++ omap_kp->timer.data = (unsigned long)omap_kp;
+
+ /* get the irq and init timer*/
+ tasklet_enable(&kp_tasklet);
+@@ -376,7 +565,7 @@
+ input_register_device(omap_kp->input);
+
+ if (machine_is_omap_h2() || machine_is_omap_h3() ||
+- machine_is_omap_perseus2()) {
++ machine_is_omap_perseus2() || machine_is_omap_h6300()) {
+ omap_writew(0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_DEBOUNCING);
+ }
+ /* scan current status and enable interrupt */
+@@ -447,6 +636,6 @@
+ module_init(omap_kp_init);
+ module_exit(omap_kp_exit);
+
+-MODULE_AUTHOR("Timo Ter舖");
++MODULE_AUTHOR("Timo Terソスs");
+ MODULE_DESCRIPTION("OMAP Keypad Driver");
+ MODULE_LICENSE("GPL");
+diff -Naur linux-2.6.16.16/drivers/input/touchscreen/omap/Makefile h6300_dev/drivers/input/touchscreen/omap/Makefile
+--- linux-2.6.16.16/drivers/input/touchscreen/omap/Makefile 2006-05-17 21:41:30.000000000 +0300
++++ h6300_dev/drivers/input/touchscreen/omap/Makefile 2005-10-22 03:52:45.000000000 +0300
+@@ -8,5 +8,6 @@
+ objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_H3) += ts_hx.o
+ objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += ts_inn1510.o
+ objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_OSK) += ts_osk.o
++objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_H6300) += ts_hx.o
+
+ omapts-objs := omap_ts.o $(objs-yy)
+diff -Naur linux-2.6.16.16/drivers/input/touchscreen/omap/omap_ts.c h6300_dev/drivers/input/touchscreen/omap/omap_ts.c
+--- linux-2.6.16.16/drivers/input/touchscreen/omap/omap_ts.c 2006-05-17 21:41:30.000000000 +0300
++++ h6300_dev/drivers/input/touchscreen/omap/omap_ts.c 2006-02-21 23:54:33.000000000 +0200
+@@ -46,7 +46,7 @@
+ #define OMAP_TS_NAME "omap_ts"
+
+ static struct ts_device *__initdata ts_devs[] = {
+-#if defined(CONFIG_MACH_OMAP_H2) || defined(CONFIG_MACH_OMAP_H3)
++#if defined(CONFIG_MACH_OMAP_H2) || defined(CONFIG_MACH_OMAP_H3) || defined(CONFIG_MACH_OMAP_H6300)
+ &hx_ts,
+ #endif
+ #ifdef CONFIG_MACH_OMAP_OSK
+diff -Naur linux-2.6.16.16/drivers/input/touchscreen/omap/ts_hx.c h6300_dev/drivers/input/touchscreen/omap/ts_hx.c
+--- linux-2.6.16.16/drivers/input/touchscreen/omap/ts_hx.c 2006-05-17 21:41:30.000000000 +0300
++++ h6300_dev/drivers/input/touchscreen/omap/ts_hx.c 2006-04-24 20:53:29.000000000 +0300
+@@ -39,6 +39,7 @@
+
+ #define H2_GPIO_NUM 4
+ #define H3_GPIO_NUM 48
++#define H6300_GPIO_NUM 2
+
+ #define OMAP_TSC2101_XRES 500
+ #define TOUCHSCREEN_DATA_REGISTERS_PAGE 0x0
+@@ -88,6 +89,9 @@
+ } else if (machine_is_omap_h3()) {
+ gpio = H3_GPIO_NUM;
+ omap_cfg_reg(W19_1610_GPIO48);
++ } else if (machine_is_omap_h6300 ()) {
++ gpio = H6300_GPIO_NUM;
++ omap_cfg_reg(M14_1510_GPIO2);
+ } else
+ return -ENODEV;
+
+@@ -180,5 +184,7 @@
+ omap_free_gpio(H2_GPIO_NUM);
+ else if (machine_is_omap_h3())
+ omap_free_gpio(H3_GPIO_NUM);
++ else if (machine_is_omap_h6300())
++ omap_free_gpio(H6300_GPIO_NUM);
+ }
+ #endif
+diff -Naur linux-2.6.16.16/drivers/mmc/mmc.c h6300_dev/drivers/mmc/mmc.c
+--- linux-2.6.16.16/drivers/mmc/mmc.c 2006-05-17 21:41:30.000000000 +0300
++++ h6300_dev/drivers/mmc/mmc.c 2006-03-28 10:34:39.000000000 +0300
+@@ -964,7 +964,7 @@
+ mmc_decode_scr(card);
+ }
+
+- mmc_deselect_cards(host);
++ //mmc_deselect_cards(host);
+ }
+
+ static unsigned int mmc_calculate_clock(struct mmc_host *host)
+diff -Naur linux-2.6.16.16/drivers/ssi/omap-tsc2101.c h6300_dev/drivers/ssi/omap-tsc2101.c
+--- linux-2.6.16.16/drivers/ssi/omap-tsc2101.c 2006-05-17 21:41:30.000000000 +0300
++++ h6300_dev/drivers/ssi/omap-tsc2101.c 2006-04-24 20:53:29.000000000 +0300
+@@ -36,10 +36,11 @@
+ #include <asm/arch/hardware.h>
+ #include <asm/hardware/tsc2101.h>
+ #include <asm/arch/gpioexpander.h>
++#include <asm/arch/gpio.h>
+
+ #include "omap-tsc2101.h"
+
+-#if CONFIG_ARCH_OMAP16XX
++#if CONFIG_ARCH_OMAP1
+ #include <../drivers/ssi/omap-uwire.h>
+ #else
+ #error "Unsupported configuration"
+@@ -66,27 +67,28 @@
+ if (count++ == 0) {
+ int ret = 0;
+ /* set the Mux to provide MCLK to TSC2101 */
+- if (machine_is_omap_h3()) {
++ if (machine_is_omap_h3())
+ ret = omap_cfg_reg(V5_1710_MCLK_ON);
+- } else {
+- if (machine_is_omap_h2()) {
+- ret = omap_cfg_reg(R10_1610_MCLK_ON);
++ else if (machine_is_omap_h2())
++ ret = omap_cfg_reg(R10_1610_MCLK_ON);
++ else if (machine_is_omap_h6300())
++ ret = omap_cfg_reg(R10_1510_MCLK_ON);
++
++ if (!cpu_is_omap1510 ()) {
++ /* Get the MCLK */
++ tsc2101_mclk_ck = clk_get(NULL, "mclk");
++ if (NULL == tsc2101_mclk_ck) {
++ printk(KERN_ERR "Unable to get the clock MCLK!!!\n");;
++ ret = -EPERM;
++ goto done;
+ }
+- }
+-
+- /* Get the MCLK */
+- tsc2101_mclk_ck = clk_get(NULL, "mclk");
+- if (NULL == tsc2101_mclk_ck) {
+- printk(KERN_ERR "Unable to get the clock MCLK!!!\n");;
+- ret = -EPERM;
+- goto done;
+- }
+- if (clk_set_rate(tsc2101_mclk_ck, 12000000)) {
+- printk(KERN_ERR "Unable to set rate to the MCLK!!!\n");;
+- ret = -EPERM;
+- goto done;
+- }
+- clk_enable(tsc2101_mclk_ck);
++ if (clk_set_rate(tsc2101_mclk_ck, 12000000)) {
++ printk(KERN_ERR "Unable to set rate to the MCLK!!!\n");;
++ ret = -EPERM;
++ goto done;
++ }
++ clk_enable(tsc2101_mclk_ck);
++ } /* if (!cpu_is_omap1510 ()) */
+
+ ret = omap_tsc2101_configure();
+
+@@ -116,10 +118,16 @@
+ }
+ }
+
+- /* Release the MCLK */
+- clk_disable(tsc2101_mclk_ck);
+- clk_put(tsc2101_mclk_ck);
+- tsc2101_mclk_ck = NULL;
++ if (!cpu_is_omap1510 ()) {
++ /* Release the MCLK */
++ clk_disable(tsc2101_mclk_ck);
++ clk_put(tsc2101_mclk_ck);
++ tsc2101_mclk_ck = NULL;
++ }
++
++#if defined(CONFIG_MACH_OMAP_H6300)
++ omap_free_gpio(8);
++#endif
+
+ module_put(THIS_MODULE);
+ }
+@@ -150,7 +158,10 @@
+ return;
+ }
+ }
+- if (machine_is_omap_h3()) {
++ if (machine_is_omap_h3() || machine_is_omap_h6300()) {
++
++ if (machine_is_omap_h6300())
++ omap_set_gpio_dataout (8, 0);
+
+ ret =
+ omap_uwire_data_transfer(0, ((page << 11) | (address << 5)),
+@@ -159,6 +170,8 @@
+ printk(KERN_ERR
+ "uwire-write returned error for address %x\n",
+ address);
++ if (machine_is_omap_h6300())
++ omap_set_gpio_dataout (8, 1);
+ return;
+ }
+ ret = omap_uwire_data_transfer(0, data, 16, 0, NULL, 0);
+@@ -166,10 +179,14 @@
+ printk(KERN_ERR
+ "uwire-write returned error for address %x\n",
+ address);
++ if (machine_is_omap_h6300())
++ omap_set_gpio_dataout (8, 1);
+ return;
+ }
+- }
+
++ if (machine_is_omap_h6300())
++ omap_set_gpio_dataout (8, 1);
++ }
+ }
+
+ void omap_tsc2101_reads(int page, u8 startaddress, u16 * data, int numregs)
+@@ -178,9 +195,13 @@
+ if (machine_is_omap_h2()) {
+ cs = 1;
+ }
+- if (machine_is_omap_h3()) {
++ if (machine_is_omap_h3() || machine_is_omap_h6300()) {
+ cs = 0;
+ }
++
++ if (machine_is_omap_h6300())
++ omap_set_gpio_dataout(8, 0);
++
+ (void)omap_uwire_data_transfer(cs, (0x8000 | (page << 11)
+ | (startaddress << 5)),
+ 16, 0, NULL, 1);
+@@ -188,6 +209,9 @@
+ omap_uwire_data_transfer(cs, 0, 0, 16, data, 1);
+ }
+ omap_uwire_data_transfer(cs, 0, 0, 16, data, 0);
++
++ if (machine_is_omap_h6300())
++ omap_set_gpio_dataout(8, 1);
+ }
+
+ u16 omap_tsc2101_read(int page, u8 address)
+@@ -228,9 +252,24 @@
+ omap_cfg_reg(N14_1610_UWIRE_CS0);
+ omap_uwire_configure_mode(0, uwire_flags);
+ }
++ if (machine_is_omap_h6300()) {
++ uwire_flags = UWIRE_READ_RISING_EDGE | UWIRE_WRITE_RISING_EDGE;
++ omap_cfg_reg(N14_1510_UWIRE_CS0);
++ omap_uwire_configure_mode(0, uwire_flags);
++
++ omap_request_gpio(8);
++ omap_set_gpio_dataout(8, 0);
++ omap_set_gpio_direction (8, 0);
++ }
+
+ /* Configure MCLK enable */
+- omap_writel(omap_readl(PU_PD_SEL_2) | (1 << 22), PU_PD_SEL_2);
++ if (cpu_is_omap16xx() || cpu_is_omap1710())
++ omap_writel(omap_readl(PU_PD_SEL_2) | (1 << 22), PU_PD_SEL_2);
++ if (machine_is_omap_h6300()) {
++ omap_cfg_reg(V19_1510_UWIRE_SCLK);
++ omap_cfg_reg(W21_1510_UWIRE_SDO);
++ omap_cfg_reg(U18_1510_UWIRE_SDI);
++ }
+
+ return 0;
+ }
+@@ -243,5 +282,5 @@
+
+ MODULE_AUTHOR("Texas Instruments");
+ MODULE_DESCRIPTION
+- ("Glue audio driver for the TI OMAP1610/OMAP1710 TSC2101 codec.");
++ ("Glue audio driver for the TI OMAP1510/1610/OMAP1710 TSC2101 codec.");
+ MODULE_LICENSE("GPL");
+diff -Naur linux-2.6.16.16/drivers/ssi/omap-uwire.c h6300_dev/drivers/ssi/omap-uwire.c
+--- linux-2.6.16.16/drivers/ssi/omap-uwire.c 2006-05-17 21:41:30.000000000 +0300
++++ h6300_dev/drivers/ssi/omap-uwire.c 2006-04-24 20:53:29.000000000 +0300
+@@ -10,7 +10,7 @@
+ * Ported to 2.6 uwire interface.
+ * Copyright (C) 2004 Texas Instruments.
+ *
+- * Generalization patches by Juha Yrjl <juha.yrjola@nokia.com>
++ * Generalization patches by Juha Yrjソスlソス <juha.yrjola@nokia.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
+@@ -212,6 +212,10 @@
+ omap_cfg_reg(N14_1610_UWIRE_CS0);
+ omap_cfg_reg(P15_1610_UWIRE_CS3);
+ }
++ if (machine_is_omap_h6300()) {
++ omap_cfg_reg(N14_1510_UWIRE_CS0);
++ omap_cfg_reg(P15_1510_UWIRE_CS3);
++ }
+ if (machine_is_omap_perseus2()) {
+ /* configure pins: MPU_UW_nSCS1, MPU_UW_SDO, MPU_UW_SCLK */
+ int val = omap_readl(OMAP730_IO_CONF_9) & ~0x00EEE000;
+diff -Naur linux-2.6.16.16/drivers/telephony/Kconfig h6300_dev/drivers/telephony/Kconfig
+--- linux-2.6.16.16/drivers/telephony/Kconfig 2006-05-11 04:56:24.000000000 +0300
++++ h6300_dev/drivers/telephony/Kconfig 2005-10-06 02:34:39.000000000 +0300
+@@ -41,7 +41,18 @@
+ help
+ Say Y here to configure in PCMCIA service support for the Quicknet
+ cards manufactured by Quicknet Technologies, Inc. This changes the
+- card initialization code to work with the card manager daemon.
++ card initialization code to work with the card manager daemon.
++
++config GSM_H6300
++ tristate "H6300 P5186 GSM/GPRS DRIVER"
++ depends on PHONE && I2C && PCA9535
++ help
++ Bluetooth H6300 P5186 gsm/gprs driver.
++ This driver provides the firmware loading mechanism for the P5185
++ gsm/gprs hardware in iPAQ h6300.
++
++ Say Y here to compile support for P5186 gsm/gprs devices into the
++ kernel or say M to compile it as module (h6300_gsm).
+
+ endmenu
+
+diff -Naur linux-2.6.16.16/drivers/telephony/Makefile h6300_dev/drivers/telephony/Makefile
+--- linux-2.6.16.16/drivers/telephony/Makefile 2006-05-11 04:56:24.000000000 +0300
++++ h6300_dev/drivers/telephony/Makefile 2005-10-06 02:34:39.000000000 +0300
+@@ -2,6 +2,7 @@
+ # Makefile for drivers/telephony
+ #
+
+-obj-$(CONFIG_PHONE) += phonedev.o
+-obj-$(CONFIG_PHONE_IXJ) += ixj.o
+-obj-$(CONFIG_PHONE_IXJ_PCMCIA) += ixj_pcmcia.o
++obj-$(CONFIG_PHONE) += phonedev.o
++obj-$(CONFIG_PHONE_IXJ) += ixj.o
++obj-$(CONFIG_PHONE_IXJ_PCMCIA) += ixj_pcmcia.o
++obj-$(CONFIG_GSM_H6300) += omap/
+diff -Naur linux-2.6.16.16/drivers/telephony/omap/h6300_gsm_led.c h6300_dev/drivers/telephony/omap/h6300_gsm_led.c
+--- linux-2.6.16.16/drivers/telephony/omap/h6300_gsm_led.c 1970-01-01 02:00:00.000000000 +0200
++++ h6300_dev/drivers/telephony/omap/h6300_gsm_led.c 2005-10-06 02:34:39.000000000 +0300
+@@ -0,0 +1,40 @@
++/*
++ * GSM interface driver helper for controlling bluetooth leds available in iPAQ h6300.
++ *
++ * Copyright (C) 2005 Mika Laitio <lamikr@cc.jyu.fi>
++ *
++ * 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/module.h>
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++
++#include <asm/hardware.h>
++#include <asm/arch/gpio.h>
++
++/*
++ * Low level access for disabling h6300 gsm led.
++ *
++ * TODO: implement for h6300
++ */
++void h6300_clear_gsm_led(int led_num)
++{
++ printk(KERN_NOTICE "h6300_gsm_led.c h6300_clear_gsm_led() done\n");
++ //hx4700_set_led(led_num, 0, 16);
++}
++EXPORT_SYMBOL(h6300_clear_gsm_led);
++
++/*
++ * Low level access for setting up the gsm led.
++ *
++ * TODO: implement for h6300
++ */
++void h6300_set_gsm_led(int led_num, int duty_time, int cycle_time)
++{
++ printk(KERN_NOTICE "h6300_gsm_led.c h6300_set_gsm_led() done\n");
++}
++EXPORT_SYMBOL(h6300_set_gsm_led);
+diff -Naur linux-2.6.16.16/drivers/telephony/omap/h6300_gsm_led.h h6300_dev/drivers/telephony/omap/h6300_gsm_led.h
+--- linux-2.6.16.16/drivers/telephony/omap/h6300_gsm_led.h 1970-01-01 02:00:00.000000000 +0200
++++ h6300_dev/drivers/telephony/omap/h6300_gsm_led.h 2005-10-06 02:34:39.000000000 +0300
+@@ -0,0 +1,10 @@
++#ifndef H6300_GSM_LED_H_
++#define H6300_GSM_LED_H_
++
++#define INDEX_GSM_LED 1
++
++void h6300_clear_gsm_led(int led_num);
++void h6300_set_gsm_led(int led_num, int duty_time, int cycle_time);
++
++
++#endif /*H6300_GSM_LED_H_*/
+diff -Naur linux-2.6.16.16/drivers/telephony/omap/h6300_gsm_p5186.c h6300_dev/drivers/telephony/omap/h6300_gsm_p5186.c
+--- linux-2.6.16.16/drivers/telephony/omap/h6300_gsm_p5186.c 1970-01-01 02:00:00.000000000 +0200
++++ h6300_dev/drivers/telephony/omap/h6300_gsm_p5186.c 2006-01-23 00:09:23.000000000 +0200
+@@ -0,0 +1,172 @@
++/*
++ * Wavecom P5186 GPRS and GSM module driver for iPAQ h6300.
++ *
++ * Copyright (C) 2005 Mika Laitio <lamikr@cc.jyu.fi>
++ *
++ * 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/module.h>
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++
++#include <asm/hardware.h>
++#include <asm/arch/gpio.h>
++
++#include <asm/arch/pca9535.h>
++#include <asm/arch/h6300_uart_info.h>
++#include "h6300_gsm_led.h"
++
++static void
++h6300_gsm_configure(struct uart_omap_port *up, int enable)
++{
++ printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_configure() started, enable = %d\n", enable);
++
++ // printk( KERN_NOTICE "h6300 configure bluetooth: %d\n", enable );
++ if (enable == 0) {
++ pca9535_gpio_write(GPIO_I2C_GPRS_RESET, GPIO_VALUE_OFF); // turn off gpio
++ mdelay(5);
++ h6300_clear_gsm_led(INDEX_GSM_LED);
++ }
++ else if (enable == 1) {
++ pca9535_gpio_write(GPIO_I2C_GPRS_RESET, GPIO_VALUE_ON); // turn on gpio
++ mdelay(5);
++ }
++ else if (enable == 2) {
++ h6300_set_gsm_led(INDEX_GSM_LED, 16, 16);
++ }
++ printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_configure() done\n");
++}
++
++static void
++h6300_gsm_set_txrx(struct uart_omap_port *up, int txrx)
++{
++ printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_set_txrx(), txrx = %d done\n", txrx);
++ /* do nothing */
++}
++
++static int
++h6300_gsm_get_txrx(struct uart_omap_port *up)
++{
++ printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_get_txrx() done\n");
++ /* do nothing */
++ return 0;
++}
++
++static int
++h6300_gsm_probe(struct platform_device *pdev)
++{
++ int ii;
++ int curVal;
++
++ struct h6300_uart_funcs *funcs = (struct h6300_uart_funcs *)pdev->dev.platform_data;
++/*
++ printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_probe() started\n");
++ for (ii = 0; ii < 8; ii++)
++ {
++ curVal = pca9535_gpio_read(ii);
++ printk(KERN_NOTICE "I2C[%d] = %d ", ii, curVal);
++ }
++ for (ii = 10; ii < 18; ii++)
++ {
++ curVal = pca9535_gpio_read(ii);
++ printk(KERN_NOTICE "I2C[%d] = %d ", ii, curVal);
++ }
++ printk(KERN_NOTICE "\nfirst check done\n");
++*/
++ pca9535_gpio_direction(GPIO_I2C_GPRS_RESET, GPIO_DIR_OUTPUT); // set gpio direction to be output
++ pca9535_gpio_write(GPIO_I2C_GPRS_RESET, GPIO_VALUE_ON); // turn on gpio
++ mdelay(200);
++
++ pca9535_gpio_direction(GPIO_I2C_MIC_OP_EN, GPIO_DIR_OUTPUT); // set gpio direction to be output
++ pca9535_gpio_write(GPIO_I2C_MIC_OP_EN, GPIO_VALUE_ON); // turn on gpio
++ mdelay(200);
++
++ pca9535_gpio_direction(GPIO_I2C_SPK_OP_PD, GPIO_DIR_OUTPUT); // set gpio direction to be output
++ pca9535_gpio_write(GPIO_I2C_SPK_OP_PD, GPIO_VALUE_ON); // pd = pulldown?, normal off = on
++
++ mdelay(200);
++
++ //pca9535_gpio_direction(
++ /* configure bluetooth UART */
++ //h6300_gpio_mode(GPIO_NR_H6300_BT_RXD_MD);
++ //h6300_gpio_mode(GPIO_NR_H6300_BT_TXD_MD);
++ //h6300_gpio_mode(GPIO_NR_H6300_BT_UART_CTS_MD);
++ //h6300_gpio_mode(GPIO_NR_H6300_BT_UART_RTS_MD);
++
++ funcs->configure = h6300_gsm_configure;
++ funcs->set_txrx = h6300_gsm_set_txrx;
++ funcs->get_txrx = h6300_gsm_get_txrx;
++
++ /* Make sure the LED is off */
++ h6300_clear_gsm_led(INDEX_GSM_LED);
++/*
++ for (ii = 0; ii < 8; ii++)
++ {
++ curVal = pca9535_gpio_read(ii);
++ printk(KERN_NOTICE "I2C[%d] = %d ", ii, curVal);
++ }
++ for (ii = 10; ii < 18; ii++)
++ {
++ curVal = pca9535_gpio_read(ii);
++ printk(KERN_NOTICE "I2C[%d] = %d ", ii, curVal);
++ }
++*/
++ printk(KERN_NOTICE "\nh6300_gsm_p5186.c h6300_gsm_probe() done\n");
++
++ return 0;
++}
++
++static int
++h6300_gsm_remove(struct platform_device *pdev)
++{
++ struct h6300_uart_funcs *funcs = (struct h6300_uart_funcs *)pdev->dev.platform_data;
++
++ printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_remove() started\n");
++
++ pca9535_gpio_write(GPIO_I2C_GPRS_RESET, 0); // turn off gpio
++
++ funcs->configure = NULL;
++ funcs->set_txrx = NULL;
++ funcs->get_txrx = NULL;
++
++ /* Make sure the LED is off */
++ h6300_clear_gsm_led(INDEX_GSM_LED);
++
++ printk(KERN_NOTICE "h6300_gsm_p5186.c, h6300_gsm_remove() done\n");
++
++ return 0;
++}
++
++static struct platform_driver gsm_driver = {
++ .probe = h6300_gsm_probe,
++ .remove = h6300_gsm_remove,
++ .driver = {
++ .name = "h6300_gsm",
++ },
++};
++
++static int __init
++h6300_gsm_init(void)
++{
++ printk(KERN_NOTICE "h6300 GSM Driver init()\n");
++ return platform_driver_register(&gsm_driver);
++}
++
++static void __exit
++h6300_gsm_exit(void)
++{
++ printk(KERN_NOTICE "h6300 GSM Driver exit()\n");
++ platform_driver_unregister(&gsm_driver);
++}
++
++module_init(h6300_gsm_init);
++module_exit(h6300_gsm_exit);
++
++MODULE_AUTHOR("Mika Laitio, <lamikr@cc.jyu.fi>");
++MODULE_DESCRIPTION("iPAQ h6300 Wavecom P5186 GPRS and GSM module driver.");
++MODULE_LICENSE("GPL");
++
+diff -Naur linux-2.6.16.16/drivers/telephony/omap/Makefile h6300_dev/drivers/telephony/omap/Makefile
+--- linux-2.6.16.16/drivers/telephony/omap/Makefile 1970-01-01 02:00:00.000000000 +0200
++++ h6300_dev/drivers/telephony/omap/Makefile 2005-10-06 02:34:39.000000000 +0300
+@@ -0,0 +1,6 @@
++#
++# Makefile for the Linux iPAQ H6300 BRF6100 Bluetooth device drivers.
++#
++
++h6300_gsm-objs := h6300_gsm_led.o h6300_gsm_p5186.o
++obj-$(CONFIG_GSM_H6300) += h6300_gsm.o
+diff -Naur linux-2.6.16.16/drivers/usb/gadget/omap_udc.c h6300_dev/drivers/usb/gadget/omap_udc.c
+--- linux-2.6.16.16/drivers/usb/gadget/omap_udc.c 2006-05-17 21:41:30.000000000 +0300
++++ h6300_dev/drivers/usb/gadget/omap_udc.c 2006-04-24 20:53:29.000000000 +0300
+@@ -60,7 +60,8 @@
+ #undef USB_TRACE
+
+ /* bulk DMA seems to be behaving for both IN and OUT */
+-#define USE_DMA
++//#define USE_DMA
++#undef USE_DMA
+
+ /* ISO too */
+ #define USE_ISO
+@@ -2147,7 +2148,7 @@
+ /* boards that don't have VBUS sensing can't autogate 48MHz;
+ * can't enter deep sleep while a gadget driver is active.
+ */
+- if (machine_is_omap_innovator() || machine_is_omap_osk())
++ if (machine_is_omap_innovator() || machine_is_omap_osk() || machine_is_omap_h6300())
+ omap_vbus_session(&udc->gadget, 1);
+
+ done:
+@@ -2170,7 +2171,7 @@
+ if (udc->dc_clk != NULL)
+ omap_udc_enable_clock(1);
+
+- if (machine_is_omap_innovator() || machine_is_omap_osk())
++ if (machine_is_omap_innovator() || machine_is_omap_osk() || machine_is_omap_h6300())
+ omap_vbus_session(&udc->gadget, 0);
+
+ if (udc->transceiver)
+@@ -2791,7 +2792,7 @@
+ hmc = HMC_1510;
+ type = "(unknown)";
+
+- if (machine_is_omap_innovator()) {
++ if (machine_is_omap_innovator() || machine_is_omap_h6300()) {
+ /* just set up software VBUS detect, and then
+ * later rig it so we always report VBUS.
+ * FIXME without really sensing VBUS, we can't
+diff -Naur linux-2.6.16.16/drivers/usb/host/ohci-omap.c h6300_dev/drivers/usb/host/ohci-omap.c
+--- linux-2.6.16.16/drivers/usb/host/ohci-omap.c 2006-05-17 21:41:30.000000000 +0300
++++ h6300_dev/drivers/usb/host/ohci-omap.c 2006-02-06 15:36:21.000000000 +0200
+@@ -353,11 +353,7 @@
+ if (IS_ERR(usb_host_ck))
+ return PTR_ERR(usb_host_ck);
+
+- if (!cpu_is_omap1510())
+- usb_dc_ck = clk_get(0, "usb_dc_ck");
+- else
+- usb_dc_ck = clk_get(0, "lb_ck");
+-
++ usb_dc_ck = clk_get(0, "usb_dc_ck");
+ if (IS_ERR(usb_dc_ck)) {
+ clk_put(usb_host_ck);
+ return PTR_ERR(usb_dc_ck);
+diff -Naur linux-2.6.16.16/drivers/video/omap/lcd_h6300.c h6300_dev/drivers/video/omap/lcd_h6300.c
+--- linux-2.6.16.16/drivers/video/omap/lcd_h6300.c 1970-01-01 02:00:00.000000000 +0200
++++ h6300_dev/drivers/video/omap/lcd_h6300.c 2006-04-24 20:53:29.000000000 +0300
+@@ -0,0 +1,159 @@
++/*
++ * File: drivers/video/omap_new/lcd-h6300.c
++ *
++ * LCD panel support for the TI OMAP1510 Innovator board
++ *
++ * Copyright (C) 2004 Nokia Corporation
++ * Author: Imre Deak <imre.deak@nokia.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.
++ */
++
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <asm/io.h>
++
++#include <asm/arch/pca9535.h>
++#include <asm/arch/omapfb.h>
++
++/* #define OMAPFB_DBG 1 */
++
++#include "debug.h"
++
++//static struct clk *h6300_lcd_ck;
++
++static int h6300_panel_init(struct omapfb_device *fbdev)
++{
++ DBGENTER(1);
++/*
++ if ((h6300_lcd_ck = clk_get (NULL, "lcd_ck")) == NULL) {
++ printk(KERN_ERR "Unable to get the clock LCD_CK!!!\n");
++ return -EPERM;
++ } clk_enable(h6300_lcd_ck);
++*/
++ DBGLEAVE(1);
++ printk(KERN_INFO "lcd_h6300.c: h6300_panel_init() done\n");
++ return 0;
++}
++
++static void h6300_panel_cleanup(void)
++{
++ DBGENTER(1);
++/*
++ if (h6300_lcd_ck) {
++ clk_disable(h6300_lcd_ck);
++ clk_put(h6300_lcd_ck);
++ h6300_lcd_ck = NULL;
++ }
++*/
++ DBGLEAVE(1);
++ printk(KERN_INFO "lcd_h6300.c: h6300_panel_cleanup() done\n");
++}
++
++static int h6300_panel_enable(void)
++{
++ DBGENTER(1);
++ DBGLEAVE(1);
++ printk(KERN_INFO "lcd_h6300.c: h6300_panel_enable() done\n");
++ return 0;
++}
++
++static void h6300_panel_disable(void)
++{
++ DBGENTER(1);
++ DBGLEAVE(1);
++ printk(KERN_INFO "lcd_h6300.c: h6300_panel_disable() done\n");
++}
++
++static unsigned long h6300_panel_get_caps(void)
++{
++ printk(KERN_INFO "lcd_h6300.c: h6300_panel_get_caps() called\n");
++ return 0;
++}
++
++struct lcd_panel h6300_panel = {
++ .name = "h6300",
++ .config = OMAP_LCDC_PANEL_TFT,
++
++ .bpp = 16,
++ .data_lines = 16,
++ .x_res = 240,
++ .y_res = 320,
++ .pixel_clock = 21000,
++ .hsw = 12,
++ .hfp = 10,
++ .hbp = 10,
++ .vsw = 3,
++ .vfp = 10,
++ .vbp = 3,
++ .pcd = 0,
++
++ .init = h6300_panel_init,
++ .cleanup = h6300_panel_cleanup,
++ .enable = h6300_panel_enable,
++ .disable = h6300_panel_disable,
++ .get_caps = h6300_panel_get_caps,
++};
++
++static int h6300_panel_probe(struct platform_device *pdev)
++{
++ DBGENTER(1);
++ omapfb_register_panel(&h6300_panel);
++ return 0;
++}
++
++static int h6300_panel_remove(struct platform_device *pdev)
++{
++ DBGENTER(1);
++ return 0;
++}
++
++static int h6300_panel_suspend(struct platform_device *pdev, pm_message_t mesg)
++{
++ DBGENTER(1);
++ pca9535_gpio_write(GPIO3, HI);
++ return 0;
++}
++
++static int h6300_panel_resume(struct platform_device *pdev)
++{
++ DBGENTER(1);
++ pca9535_gpio_write(GPIO3, LOW);
++ return 0;
++}
++
++struct platform_driver h6300_panel_driver = {
++ .probe = h6300_panel_probe,
++ .remove = h6300_panel_remove,
++ .suspend = h6300_panel_suspend,
++ .resume = h6300_panel_resume,
++ .driver = {
++ .name = "lcd_h6300",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int h6300_panel_drv_init(void)
++{
++ return platform_driver_register(&h6300_panel_driver);
++}
++
++static void h6300_panel_drv_cleanup(void)
++{
++ platform_driver_unregister(&h6300_panel_driver);
++}
++
++module_init(h6300_panel_drv_init);
++module_exit(h6300_panel_drv_cleanup);
+diff -Naur linux-2.6.16.16/drivers/video/omap/Makefile h6300_dev/drivers/video/omap/Makefile
+--- linux-2.6.16.16/drivers/video/omap/Makefile 2006-05-17 21:41:30.000000000 +0300
++++ h6300_dev/drivers/video/omap/Makefile 2006-02-21 23:54:33.000000000 +0200
+@@ -23,6 +23,7 @@
+ objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o
+ objs-y$(CONFIG_MACH_OMAP_PERSEUS2) += lcd_p2.o
+ objs-y$(CONFIG_MACH_OMAP_APOLLON) += lcd_apollon.o
++objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_H6300) += lcd_h6300.o
+
+ objs-y$(CONFIG_FB_OMAP_LCD_LPH8923) += lcd_lph8923.o
+
+diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/board-h6300.h h6300_dev/include/asm-arm/arch-omap/board-h6300.h
+--- linux-2.6.16.16/include/asm-arm/arch-omap/board-h6300.h 1970-01-01 02:00:00.000000000 +0200
++++ h6300_dev/include/asm-arm/arch-omap/board-h6300.h 2006-04-24 20:53:29.000000000 +0300
+@@ -0,0 +1,40 @@
++/*
++ * linux/include/asm-arm/arch-omap/board-innovator.h
++ *
++ * Copyright (C) 2001 RidgeRun, Inc.
++ *
++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * 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.
++ */
++#ifndef __ASM_ARCH_OMAP_H6300_H
++#define __ASM_ARCH_OMAP_H6300_H
++
++#ifndef OMAP_SDRAM_DEVICE
++#define OMAP_SDRAM_DEVICE D256M_1X16_4B
++#endif
++
++#define OMAP1510P1_IMIF_PRI_VALUE 0x00
++#define OMAP1510P1_EMIFS_PRI_VALUE 0x00
++#define OMAP1510P1_EMIFF_PRI_VALUE 0x00
++
++#define NR_FPGA_IRQS 24
++#define NR_IRQS IH_BOARD_BASE + NR_FPGA_IRQS
++
++#endif /* __ASM_ARCH_OMAP_H6300_H */
+diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/h6300_uart_info.h h6300_dev/include/asm-arm/arch-omap/h6300_uart_info.h
+--- linux-2.6.16.16/include/asm-arm/arch-omap/h6300_uart_info.h 1970-01-01 02:00:00.000000000 +0200
++++ h6300_dev/include/asm-arm/arch-omap/h6300_uart_info.h 2005-10-14 18:55:31.000000000 +0300
+@@ -0,0 +1,33 @@
++/*
++ * Support file for calling h6300 uart configuration functions.
++ * Used at least by h6300_bt driver.
++ *
++ * Copyright (c) 2005 SDG Systems, LLC
++ * 2005-03-29 Todd Blumer Converted basic structure to support hx4700
++ * 2005-10-03 Mika Laitio (lamikr@cc.jyu.fi) Reorganized for the iPAQ h6300 bt driver.
++ */
++
++#ifndef _H6300_UART_INFO_H
++#define _H6300_UART_INFO_H
++
++#include "omap_serial.h"
++
++#define GPIO_BT_PWR_EN 3
++#define GPIO_N_BT_RST 9
++
++#define GPIO_I2C_GPRS_RESET 16
++#define GPIO_I2C_MIC_OP_EN 10
++#define GPIO_I2C_SPK_OP_PD 11
++
++#define GPIO_VALUE_OFF 0
++#define GPIO_VALUE_ON 1
++
++#define GPIO_DIR_OUTPUT 1
++
++struct h6300_uart_funcs {
++ void (*configure)( struct uart_omap_port *up, int state);
++ void (*set_txrx)( struct uart_omap_port *up, int txrx);
++ int (*get_txrx)( struct uart_omap_port *up);
++};
++
++#endif
+diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/hardware.h h6300_dev/include/asm-arm/arch-omap/hardware.h
+--- linux-2.6.16.16/include/asm-arm/arch-omap/hardware.h 2006-05-17 21:41:31.000000000 +0300
++++ h6300_dev/include/asm-arm/arch-omap/hardware.h 2006-02-06 15:36:21.000000000 +0200
+@@ -290,6 +290,10 @@
+ #include "board-innovator.h"
+ #endif
+
++#ifdef CONFIG_MACH_OMAP_H6300
++#include "board-h6300.h"
++#endif
++
+ #ifdef CONFIG_MACH_OMAP_H2
+ #include "board-h2.h"
+ #endif
+diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/mux.h h6300_dev/include/asm-arm/arch-omap/mux.h
+--- linux-2.6.16.16/include/asm-arm/arch-omap/mux.h 2006-05-17 21:41:31.000000000 +0300
++++ h6300_dev/include/asm-arm/arch-omap/mux.h 2006-05-18 00:38:24.000000000 +0300
+@@ -320,6 +320,13 @@
+ P15_1610_UWIRE_CS3,
+ N15_1610_UWIRE_CS1,
+
++ /* OMAP-1510 uWire */
++ P15_1510_UWIRE_CS3,
++ N14_1510_UWIRE_CS0,
++ V19_1510_UWIRE_SCLK,
++ W21_1510_UWIRE_SDO,
++ U18_1510_UWIRE_SDI,
++
+ /* OMAP-1610 Flash */
+ L3_1610_FLASH_CS2B_OE,
+ M8_1610_FLASH_CS2B_WE,
+@@ -384,6 +391,7 @@
+ T20_1610_LOW_PWR,
+
+ /* MCLK Settings */
++ R10_1510_MCLK_ON,
+ V5_1710_MCLK_ON,
+ V5_1710_MCLK_OFF,
+ R10_1610_MCLK_ON,
+diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/omap-alsa.h h6300_dev/include/asm-arm/arch-omap/omap-alsa.h
+--- linux-2.6.16.16/include/asm-arm/arch-omap/omap-alsa.h 2006-05-17 21:41:31.000000000 +0300
++++ h6300_dev/include/asm-arm/arch-omap/omap-alsa.h 2006-03-08 13:28:16.000000000 +0200
+@@ -1,6 +1,6 @@
+ /*
+ * linux/include/asm-arm/arch-omap/omap-alsa.h
+- *
++ *
+ * Alsa Driver for AIC23 and TSC2101 codecs on OMAP platform boards.
+ *
+ * Copyright (C) 2006 Mika Laitio <lamikr@cc.jyu.fi>
+diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/omap_serial.h h6300_dev/include/asm-arm/arch-omap/omap_serial.h
+--- linux-2.6.16.16/include/asm-arm/arch-omap/omap_serial.h 1970-01-01 02:00:00.000000000 +0200
++++ h6300_dev/include/asm-arm/arch-omap/omap_serial.h 2005-10-04 00:58:34.000000000 +0300
+@@ -0,0 +1,62 @@
++/*
++ * Omap/h6300 serial driver private interface.
++ * Code originates from the pxa-serial.h available in the handheld org drivers
++ * for iPAQ PXA4700.
++ *
++ * Copyright (c) 2005 SDG Systems, LLC
++ * 2005-03-29 Todd Blumer Converted basic structure to support hx4700
++ * 2005-10-03 Mika Laitio (lamikr@cc.jyu.fi) Reorganized for the iPAQ h6300 bt driver.
++ */
++
++#ifndef _OMAP_SERIAL_H
++#define _OMAP_SERIAL_H
++
++#define OMAP_SERIAL_TX 1
++#define OMAP_SERIAL_RX 2
++
++#include <linux/tty.h>
++#include <linux/serial_core.h>
++
++struct platform_omap_serial_funcs;
++
++struct uart_omap_port {
++ struct uart_port port;
++ unsigned char ier;
++ unsigned char lcr;
++ unsigned char mcr;
++ unsigned int lsr_break_flag;
++ unsigned int cken;
++ char *name;
++ struct platform_omap_serial_funcs *pf;
++};
++
++/* A pointer to such a structure can be contained in the platform_data
++ * field of every PXA UART platform_device. If the field is NULL, the
++ * serial port works as usual.
++ *
++ * For the sake of simplicity/performance no one of the function pointers
++ * in the structure below can be NULL.
++ */
++struct platform_omap_serial_funcs {
++ /* Platform-specific function to initialize whatever is connected
++ to this serial port... enable=1 -> enable transceiver,
++ 0 -> disable transceiver. */
++ void (*configure) (struct uart_omap_port *up, int enable);
++ /* Platform-specific function to enable or disable the individual
++ transmitter/receiver submodules. On transceivers without echo
++ cancellation (e.g. SIR) transmitter always has priority, e.g.
++ if both bits are set, only the transmitter is enabled. */
++ void (*set_txrx) (struct uart_omap_port *up, int txrx);
++ /* Get the current state of tx/rx (see bitflags above) */
++ int (*get_txrx) (struct uart_omap_port *up);
++};
++
++/*
++ * The variables below are located in arch/arm/mach-omap/board_h6300.c
++ * Machine-specific code may want to put a pointer to a static
++ * platform_pxa_serial_funcs structure in the dev.platform_data
++ * field of the respective port device.
++ */
++extern struct platform_device btuart_device;
++
++#endif
+diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/pca9535.h h6300_dev/include/asm-arm/arch-omap/pca9535.h
+--- linux-2.6.16.16/include/asm-arm/arch-omap/pca9535.h 1970-01-01 02:00:00.000000000 +0200
++++ h6300_dev/include/asm-arm/arch-omap/pca9535.h 2005-10-25 03:24:45.000000000 +0300
+@@ -0,0 +1,39 @@
++#ifndef _PCA9535_H
++#define _PCA9535_H
++
++enum pca9535_gpios {
++ GPIO0 = 0,
++ GPIO1 = 1,
++ GPIO2 = 2,
++ GPIO3 = 3,
++ GPIO4 = 4,
++ GPIO5 = 5,
++ GPIO6 = 6,
++ GPIO7 = 7,
++ GPIO8 = 8,
++ GPIO9 = 9,
++ GPIO10 = 10,
++ GPIO11 = 11,
++ GPIO12 = 12,
++ GPIO13 = 13,
++ GPIO14 = 14,
++ GPIO15 = 15,
++ GPIO16 = 16,
++ GPIO17 = 17
++};
++
++enum gpio_values {
++ HI = 0,
++ LOW = 1
++};
++
++enum gpio_direction {
++ GPIO_INPUT = 0,
++ GPIO_OUTPUT = 1
++};
++
++extern int pca9535_gpio_read(int gpio);
++extern int pca9535_gpio_write(int gpio, unsigned char val);
++extern int pca9535_gpio_direction(int gpio, unsigned char direction);
++
++#endif
+diff -Naur linux-2.6.16.16/Makefile h6300_dev/Makefile
+--- linux-2.6.16.16/Makefile 2006-05-17 21:41:27.000000000 +0300
++++ h6300_dev/Makefile 2006-05-18 01:45:17.000000000 +0300
+@@ -11,7 +11,7 @@
+ # expect to learn how to build the kernel reading this file.
+
+ # Add custom flags here to avoid conflict with updates
+-EXTRAVERSION := $(EXTRAVERSION)-omap2
++EXTRAVERSION := $(EXTRAVERSION)-omap1-h6300
+
+ # Do not print "Entering directory ..."
+ MAKEFLAGS += --no-print-directory
+diff -Naur linux-2.6.16.16/sound/arm/omap/omap-alsa-tsc2101.c h6300_dev/sound/arm/omap/omap-alsa-tsc2101.c
+--- linux-2.6.16.16/sound/arm/omap/omap-alsa-tsc2101.c 2006-05-17 21:41:31.000000000 +0300
++++ h6300_dev/sound/arm/omap/omap-alsa-tsc2101.c 2006-03-30 23:15:31.000000000 +0300
+@@ -96,7 +96,11 @@
+ static snd_pcm_hardware_t tsc2101_snd_omap_alsa_playback = {
+ .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
+- .formats = (SNDRV_PCM_FMTBIT_S16_LE),
++#ifdef CONFIG_MACH_OMAP_H6300
++ .formats = (SNDRV_PCM_FMTBIT_S8),
++#else
++ .formats = (SNDRV_PCM_FMTBIT_S16_LE),
++#endif
+ .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
+@@ -136,7 +140,7 @@
+ };
+
+ /*
+- * Simplified write for tsc Audio
++ * Simplified write for tsc2101 audio registers.
+ */
+ inline void tsc2101_audio_write(u8 address, u16 data)
+ {
+@@ -144,7 +148,7 @@
+ }
+
+ /*
+- * Simplified read for tsc Audio
++ * Simplified read for tsc2101 audio registers.
+ */
+ inline u16 tsc2101_audio_read(u8 address)
+ {
+@@ -246,14 +250,17 @@
+ #endif /* #ifdef TSC_MASTER */
+ tsc2101_audio_write(TSC2101_AUDIO_CTRL_3, data);
+
+- /* program the PLLs */
++ /* Program the PLLs. This code assumes that the 12 Mhz MCLK is in use.
++ * If MCLK rate is something else, these values must be changed.
++ * See the tsc2101 specification for the details.
++ */
+ if (rate_reg_info[count].fs_44kHz) {
+- /* 44.1 khz - 12 MHz Mclk */
++ /* samplerate = (44.1kHZ / x), where x is int. */
+ tsc2101_audio_write(TSC2101_PLL_PROG_1, PLL1_PLLSEL |
+ PLL1_PVAL(1) | PLL1_I_VAL(7)); /* PVAL 1; I_VAL 7 */
+ tsc2101_audio_write(TSC2101_PLL_PROG_2, PLL2_D_VAL(0x1490)); /* D_VAL 5264 */
+ } else {
+- /* 48 khz - 12 Mhz Mclk */
++ /* samplerate = (48.kHZ / x), where x is int. */
+ tsc2101_audio_write(TSC2101_PLL_PROG_1, PLL1_PLLSEL |
+ PLL1_PVAL(1) | PLL1_I_VAL(8)); /* PVAL 1; I_VAL 8 */
+ tsc2101_audio_write(TSC2101_PLL_PROG_2, PLL2_D_VAL(0x780)); /* D_VAL 1920 */
+@@ -317,21 +324,14 @@
+ CODEC_CLOCK);
+ }
+ curRate = (uint)clk_get_rate(tsc2101_mclk);
+- DPRINTK("old clock rate = %d\n", curRate);
+ if (curRate != CODEC_CLOCK) {
+ err = clk_set_rate(tsc2101_mclk, CODEC_CLOCK);
+ if (err) {
+ printk(KERN_WARNING
+ "Cannot set MCLK clock rate for TSC2101 CODEC, error code = %d\n", err);
+- //return -ECANCELED;
++ return -ECANCELED;
+ }
+ }
+- else
+- {
+- printk(KERN_INFO
+- "omap_alsa_tsc2101_clock_on(), no need to change rate, no need to change clock rate, rate already %d Hz.\n",
+- CODEC_CLOCK);
+- }
+ err = clk_enable(tsc2101_mclk);
+ curRate = (uint)clk_get_rate(tsc2101_mclk);
+ curUseCount = clk_get_usecount(tsc2101_mclk);
+@@ -349,8 +349,7 @@
+ }
+
+ /*
+- * Do some sanity check, turn clock off and then turn
+- * codec audio off
++ * Do some sanity check, turn clock off and then turn codec audio off
+ */
+ int tsc2101_clock_off(void)
+ {
+@@ -374,10 +373,6 @@
+ tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL,
+ ~(CPC_SP1PWDN | CPC_SP2PWDN | CPC_BASSBC));
+ DPRINTK("audio codec off\n");
+-#ifdef DUMP_TSC2101_AUDIO_REGISTERS
+- printk("tsc2101_clock_off()\n");
+- dump_tsc2101_audio_reg();
+-#endif
+ return 0;
+ }
+
+@@ -420,18 +415,22 @@
+ };
+
+ static int __init omap_alsa_tsc2101_init(void)
+-{
+- int err;
+-
++{
+ ADEBUG();
+- err = platform_driver_register(&omap_alsa_driver);
+-
+- return err;
++#ifdef DUMP_TSC2101_AUDIO_REGISTERS
++ printk("omap_alsa_tsc2101_init()\n");
++ dump_tsc2101_audio_reg();
++#endif
++ return platform_driver_register(&omap_alsa_driver);
+ }
+
+ static void __exit omap_alsa_tsc2101_exit(void)
+ {
+ ADEBUG();
++#ifdef DUMP_TSC2101_AUDIO_REGISTERS
++ printk("omap_alsa_tsc2101_exit()\n");
++ dump_tsc2101_audio_reg();
++#endif
+ platform_driver_unregister(&omap_alsa_driver);
+ }
+
+diff -Naur linux-2.6.16.16/sound/arm/omap/omap-alsa-tsc2101-mixer.c h6300_dev/sound/arm/omap/omap-alsa-tsc2101-mixer.c
+--- linux-2.6.16.16/sound/arm/omap/omap-alsa-tsc2101-mixer.c 2006-05-17 21:41:31.000000000 +0300
++++ h6300_dev/sound/arm/omap/omap-alsa-tsc2101-mixer.c 2006-05-10 02:42:13.000000000 +0300
+@@ -50,47 +50,53 @@
+ //#define M_DPRINTK(ARGS...) printk(KERN_INFO "<%s>: ",__FUNCTION__);printk(ARGS)
+ #define M_DPRINTK(ARGS...) /* nop */
+
++#define CHECK_BIT(INDX, ARG) (((ARG) & TSC2101_BIT(INDX)) >> INDX)
++#define IS_UNMUTED(INDX, ARG) (((CHECK_BIT(INDX, ARG)) == 0))
++
+ #define DGC_DALVL_EXTRACT(ARG) ((ARG & 0x7f00) >> 8)
+ #define DGC_DARVL_EXTRACT(ARG) ((ARG & 0x007f))
+-#define GET_DGC_DALMU_BIT_VALUE(ARG) (((ARG) & TSC2101_BIT(15)) >> 15)
+-#define GET_DGC_DARMU_BIT_VALUE(ARG) (((ARG) & TSC2101_BIT(7)) >> 7)
+-#define IS_DGC_DALMU_UNMUTED(ARG) (((GET_DGC_DALMU_BIT_VALUE(ARG)) == 0))
+-#define IS_DGC_DARMU_UNMUTED(ARG) (((GET_DGC_DARMU_BIT_VALUE(ARG)) == 0))
+
+ #define HGC_ADPGA_HED_EXTRACT(ARG) ((ARG & 0x7f00) >> 8)
+-#define GET_DGC_HGCMU_BIT_VALUE(ARG) (((ARG) & TSC2101_BIT(15)) >> 15)
+-#define IS_DGC_HGCMU_UNMUTED(ARG) (((GET_DGC_HGCMU_BIT_VALUE(ARG)) == 0))
+-
+ #define HNGC_ADPGA_HND_EXTRACT(ARG) ((ARG & 0x7f00) >> 8)
+-#define GET_DGC_HNGCMU_BIT_VALUE(ARG) (((ARG) & TSC2101_BIT(15)) >> 15)
+-#define IS_DGC_HNGCMU_UNMUTED(ARG) (((GET_DGC_HNGCMU_BIT_VALUE(ARG)) == 0))
++#define BGC_ADPGA_BGC_EXTRACT(ARG) ((ARG & 0x7f00) >> 8)
+
+ static int current_playback_target = PLAYBACK_TARGET_LOUDSPEAKER;
+ static int current_rec_src = REC_SRC_SINGLE_ENDED_MICIN_HED;
+
++/*
++ * Simplified write for the tsc2101 audio registers.
++ */
++inline void omap_tsc2101_audio_write(u8 address, u16 data)
++{
++ omap_tsc2101_write(PAGE2_AUDIO_CODEC_REGISTERS, address, data);
++}
++
++/*
++ * Simplified read for the tsc2101 audio registers.
++ */
++inline u16 omap_tsc2101_audio_read(u8 address)
++{
++ return (omap_tsc2101_read(PAGE2_AUDIO_CODEC_REGISTERS, address));
++}
++
+ /*
+- * Used for switching between TSC2101 recourd sources.
+- * Logic is adjusted from the TSC2101 OSS code.
++ * For selecting tsc2101 recourd source.
+ */
+-static int set_record_source(int val)
++static void set_record_source(int val)
+ {
+ u16 data;
+- int maskedVal;
+
+- FN_IN;
+- maskedVal = 0xe0 & val;
+-
+- data = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_MIXER_PGA_CTRL);
++ /* Mute Analog Sidetone
++ * Analog sidetone gain db?
++ * Input selected by MICSEL connected to ADC
++ */
++ data = MPC_ASTMU | MPC_ASTG(0x45);
+ data &= ~MPC_MICSEL(7); /* clear all MICSEL bits */
+- data |= maskedVal;
+- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_MIXER_PGA_CTRL,
+- data);
++ data |= MPC_MICSEL(val);
++ data |= MPC_MICADC;
++ omap_tsc2101_audio_write(TSC2101_MIXER_PGA_CTRL, data);
++
+ current_rec_src = val;
+-
+- FN_OUT(0);
+- return 0;
+ }
+
+ /*
+@@ -147,32 +153,34 @@
+ volL = get_mixer_volume_as_dac_gain_control_volume(mixerVolL);
+ volR = get_mixer_volume_as_dac_gain_control_volume(mixerVolR);
+
+- val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_DAC_GAIN_CTRL);
++ val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL);
+ /* keep the old mute bit settings */
+ val &= ~(DGC_DALVL(OUTPUT_VOLUME_MIN) | DGC_DARVL(OUTPUT_VOLUME_MIN));
+ val |= DGC_DALVL(volL) | DGC_DARVL(volR);
+ retVal = 2;
+ if (retVal) {
+- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_DAC_GAIN_CTRL,
+- val);
++ omap_tsc2101_audio_write(TSC2101_DAC_GAIN_CTRL, val);
+ }
+ M_DPRINTK("to registry: left = %d, right = %d, total = %d\n", DGC_DALVL_EXTRACT(val), DGC_DARVL_EXTRACT(val), val);
+ return retVal;
+ }
+
+-int dac_gain_control_unmute_control(int muteLeft, int muteRight)
++/**
++ * If unmuteLeft/unmuteRight == 0 --> mute
++ * If unmuteLeft/unmuteRight == 1 --> unmute
++ */
++int dac_gain_control_unmute(int unmuteLeft, int unmuteRight)
+ {
+ u16 val;
+ int count;
+
+ count = 0;
+- val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_DAC_GAIN_CTRL);
++ val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL);
+ /* in alsa mixer 1 --> on, 0 == off. In tsc2101 registry 1 --> off, 0 --> on
+ * so if values are same, it's time to change the registry value.
+ */
+- if (muteLeft == GET_DGC_DALMU_BIT_VALUE(val)) {
+- if (muteLeft == 0) {
++ if (unmuteLeft != IS_UNMUTED(15, val)) {
++ if (unmuteLeft == 0) {
+ /* mute --> turn bit on */
+ val = val | DGC_DALMU;
+ }
+@@ -182,8 +190,8 @@
+ }
+ count++;
+ } /* L */
+- if (muteRight == GET_DGC_DARMU_BIT_VALUE(val)) {
+- if (muteRight == 0) {
++ if (unmuteRight != IS_UNMUTED(7, val)) {
++ if (unmuteRight == 0) {
+ /* mute --> turn bit on */
+ val = val | DGC_DARMU;
+ }
+@@ -194,14 +202,47 @@
+ count++;
+ } /* R */
+ if (count) {
+- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_DAC_GAIN_CTRL, val);
++ omap_tsc2101_audio_write(TSC2101_DAC_GAIN_CTRL, val);
+ M_DPRINTK("changed value, is_unmuted left = %d, right = %d\n",
+- IS_DGC_DALMU_UNMUTED(val),
+- IS_DGC_DARMU_UNMUTED(val));
++ IS_UNMUTED(15, val),
++ IS_UNMUTED(7, val));
+ }
+ return count;
+ }
+
++/**
++ * unmute: 0 --> mute, 1 --> unmute
++ * page2RegIndx: Registry index in tsc2101 page2.
++ * muteBitIndx: Index number for the bit in registry that indicates whether muted or unmuted.
++ */
++int adc_pga_unmute_control(int unmute, int page2regIndx, int muteBitIndx)
++{
++ int count;
++ u16 val;
++
++ count = 0;
++ val = omap_tsc2101_audio_read(page2regIndx);
++ /* in alsa mixer 1 --> on, 0 == off. In tsc2101 registry 1 --> off, 0 --> on
++ * so if the values are same, it's time to change the registry value...
++ */
++ if (unmute != IS_UNMUTED(muteBitIndx, val)) {
++ if (unmute == 0) {
++ /* mute --> turn bit on */
++ val = val | TSC2101_BIT(muteBitIndx);
++ }
++ else {
++ /* unmute --> turn bit off */
++ val = val & ~TSC2101_BIT(muteBitIndx);
++ }
++ M_DPRINTK("changed value, is_unmuted = %d\n", IS_UNMUTED(muteBitIndx, val));
++ count++;
++ }
++ if (count) {
++ omap_tsc2101_audio_write(page2regIndx, val);
++ }
++ return count;
++}
++
+ /*
+ * Converts the DGC registry value read from the TSC2101 registry to
+ * Alsa mixer volume format (0 - 100).
+@@ -271,14 +312,11 @@
+ /* Convert 0 -> 100 volume to 0x0(min) -> 0x7D(max) volume range */
+ /* NOTE: 0 is minimum volume and not mute */
+ volume = get_mixer_volume_as_headset_gain_control_volume(mixerVol);
+- val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_HEADSET_GAIN_CTRL);
++ val = omap_tsc2101_audio_read(TSC2101_HEADSET_GAIN_CTRL);
+ /* preserve the old mute settings */
+ val &= ~(HGC_ADPGA_HED(INPUT_VOLUME_MAX));
+ val |= HGC_ADPGA_HED(volume);
+- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_HEADSET_GAIN_CTRL,
+- val);
++ omap_tsc2101_audio_write(TSC2101_HEADSET_GAIN_CTRL, val);
+ retVal = 1;
+
+ M_DPRINTK("to registry = %d\n", val);
+@@ -305,71 +343,37 @@
+ * NOTE: 0 is minimum volume and not mute
+ */
+ volume = get_mixer_volume_as_headset_gain_control_volume(mixerVol);
+- val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_HANDSET_GAIN_CTRL);
++ val = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL);
+ /* preserve the old mute settigns */
+ val &= ~(HNGC_ADPGA_HND(INPUT_VOLUME_MAX));
+ val |= HNGC_ADPGA_HND(volume);
+- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_HANDSET_GAIN_CTRL,
+- val);
++ omap_tsc2101_audio_write(TSC2101_HANDSET_GAIN_CTRL, val);
+ retVal = 1;
+
+ M_DPRINTK("to registry = %d\n", val);
+ return retVal;
+ }
+
+-void init_record_sources(void)
+-{
+- /* Mute Analog Sidetone
+- * analog sidetone gain db?
+- * Cell Phone In not connected to ADC
+- * Input selected by MICSEL connected to ADC
+- */
+- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_MIXER_PGA_CTRL,
+- MPC_ASTMU | MPC_ASTG(0x40) | ~MPC_CPADC | MPC_MICADC);
+- /* Set record source, Select MIC_INHED input for headset */
+- set_record_source(REC_SRC_SINGLE_ENDED_MICIN_HED);
+-}
+-
+ void set_loudspeaker_to_playback_target(void)
+ {
+- u16 val;
+-
+- /* power down sp1, sp2 and loudspeaker */
+- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_CODEC_POWER_CTRL,
++ /* power down SPK1, SPK2 and loudspeaker */
++ omap_tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL,
+ CPC_SP1PWDN | CPC_SP2PWDN | CPC_LDAPWDF);
+ /* ADC, DAC, Analog Sidetone, cellphone, buzzer softstepping enabled
+ * 1dB AGC hysteresis
+ * MICes bias 2V
+ */
+- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_AUDIO_CTRL_4,
+- AC4_MB_HED(0));
++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_4, AC4_MB_HED(0));
+
+ /* DAC left and right routed to SPK1/SPK2
+ * SPK1/SPK2 unmuted
+- * keyclicks routed to SPK1/SPK2
+- */
+- val = AC5_DIFFIN |
++ * Keyclicks routed to SPK1/SPK2 */
++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_5,
++ AC5_DIFFIN |
+ AC5_DAC2SPK1(3) | AC5_AST2SPK1 | AC5_KCL2SPK1 |
+- AC5_DAC2SPK2(3) | AC5_AST2SPK2 | AC5_KCL2SPK2 |
+- AC5_HDSCPTC;
+- val = val & ~AC5_HDSCPTC;
+- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_AUDIO_CTRL_5,
+- val);
+-
+- /* powerdown spk1/out32n and spk2 */
+- val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_POWERDOWN_STS);
+- val = val & ~(~PS_SPK1FL | ~PS_HNDFL | PS_LSPKFL);
+- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_POWERDOWN_STS,
+- val);
+-
+- /* routing selected to SPK1 goes to OUT8P/OUT84 alsa. (loudspeaker)
++ AC5_DAC2SPK2(3) | AC5_AST2SPK2 | AC5_KCL2SPK2);
++
++ /* routing selected to SPK1 goes also to OUT8P/OUT8N. (loudspeaker)
+ * analog sidetone routed to loudspeaker
+ * buzzer pga routed to loudspeaker
+ * keyclick routing to loudspeaker
+@@ -381,43 +385,242 @@
+ * Enable loudspeaker short protection control (0 = enable protection)
+ * VGND short protection control (0 = enable protection)
+ */
+- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_AUDIO_CTRL_6,
++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_6,
+ AC6_SPL2LSK | AC6_AST2LSK | AC6_BUZ2LSK | AC6_KCL2LSK |
+- AC6_CPI2LSK | AC6_MIC2CPO | AC6_SPL2CPO |
+- ~AC6_MUTLSPK | ~AC6_MUTSPK2 | ~AC6_LDSCPTC | ~AC6_VGNDSCPTC);
++ AC6_CPI2LSK | AC6_MIC2CPO | AC6_SPL2CPO);
+ current_playback_target = PLAYBACK_TARGET_LOUDSPEAKER;
+ }
+
+ void set_headphone_to_playback_target(void)
+ {
+- /* power down sp1, sp2 and loudspeaker */
+- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_CODEC_POWER_CTRL,
++ /* power down SPK1, SPK2 and loudspeaker */
++ omap_tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL,
+ CPC_SP1PWDN | CPC_SP2PWDN | CPC_LDAPWDF);
+ /* ADC, DAC, Analog Sidetone, cellphone, buzzer softstepping enabled */
+ /* 1dB AGC hysteresis */
+ /* MICes bias 2V */
+- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_AUDIO_CTRL_4,
+- AC4_MB_HED(0));
+-
+- /* DAC left and right routed to SPK2 */
+- /* SPK1/2 unmuted */
+- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_AUDIO_CTRL_5,
++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_4, AC4_MB_HED(0));
++
++ /* DAC left and right routed to SPK1/SPK2
++ * SPK1/SPK2 unmuted
++ * Keyclicks routed to SPK1/SPK2 */
++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_5,
+ AC5_DAC2SPK1(3) | AC5_AST2SPK1 | AC5_KCL2SPK1 |
+ AC5_DAC2SPK2(3) | AC5_AST2SPK2 | AC5_KCL2SPK2 |
+ AC5_HDSCPTC);
+-
+- /* OUT8P/N muted, CPOUT muted */
+- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_AUDIO_CTRL_6,
++
++ /* OUT8P/OUT8N muted, CPOUT muted */
++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_6,
+ AC6_MUTLSPK | AC6_MUTSPK2 | AC6_LDSCPTC |
+ AC6_VGNDSCPTC);
+ current_playback_target = PLAYBACK_TARGET_HEADPHONE;
+ }
+
++void set_telephone_to_playback_target(void)
++{
++ /*
++ * 0110 1101 0101 1100
++ * power down MICBIAS_HED, Analog sidetone, SPK2, DAC,
++ * Driver virtual ground, loudspeaker. Values D2-d5 are flags.
++ */
++ omap_tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL,
++ CPC_MBIAS_HED | CPC_ASTPWD | CPC_SP2PWDN | CPC_DAPWDN |
++ CPC_VGPWDN | CPC_LSPWDN);
++
++ /*
++ * 0010 1010 0100 0000
++ * ADC, DAC, Analog Sidetone, cellphone, buzzer softstepping enabled
++ * 1dB AGC hysteresis
++ * MICes bias 2V
++ */
++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_4,
++ AC4_MB_HND | AC4_MB_HED(0) | AC4_AGCHYS(1) |
++ AC4_BISTPD | AC4_ASSTPD | AC4_DASTPD);
++ printk("set_telephone_to_playback_target(), TSC2101_AUDIO_CTRL_4 = %d\n", omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_4));
++
++ /*
++ * 1110 0010 0000 0010
++ * DAC left and right routed to SPK1/SPK2
++ * SPK1/SPK2 unmuted
++ * keyclicks routed to SPK1/SPK2
++ */
++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_5,
++ AC5_DIFFIN | AC5_DAC2SPK1(3) |
++ AC5_CPI2SPK1 | AC5_MUTSPK2);
++
++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_6,
++ AC6_MIC2CPO | AC6_MUTLSPK |
++ AC6_LDSCPTC | AC6_VGNDSCPTC | AC6_CAPINTF);
++ current_playback_target = PLAYBACK_TARGET_CELLPHONE;
++}
++
++/*
++ * 1100 0101 1101 0000
++ *
++ * #define MPC_ASTMU TSC2101_BIT(15)
++ * #define MPC_ASTG(ARG) (((ARG) & 0x7F) << 8)
++ * #define MPC_MICSEL(ARG) (((ARG) & 0x07) << 5)
++ * #define MPC_MICADC TSC2101_BIT(4)
++ * #define MPC_CPADC TSC2101_BIT(3)
++ * #define MPC_ASTGF (0x01)
++ */
++static void set_telephone_to_record_source(void)
++{
++ u16 val;
++
++ /*
++ * D0 = 0:
++ * --> AGC is off for handset input.
++ * --> ADC PGA is controlled by the ADMUT_HDN + ADPGA_HND
++ * (D15, D14-D8)
++ * D4 - D1 = 0000
++ * --> AGC time constant for handset input,
++ * attack time = 8 mc, decay time = 100 ms
++ * D7 - D5 = 000
++ * --> AGC Target gain for handset input = -5.5 db
++ * D14 - D8 = 011 1100
++ * --> ADC handset PGA settings = 60 = 30 db
++ * D15 = 0
++ * --> Handset input ON (unmuted)
++ */
++ val = 0x3c00; // 0011 1100 0000 0000 = 60 = 30
++ omap_tsc2101_audio_write(TSC2101_HANDSET_GAIN_CTRL, val);
++
++ /*
++ * D0 = 0
++ * --> AGC is off for headset/Aux input
++ * --> ADC headset/Aux PGA is contoller by ADMUT_HED + ADPGA_HED
++ * (D15, D14-D8)
++ * D4 - D1 = 0000
++ * --> Agc constant for headset/Aux input,
++ * attack time = 8 mc, decay time = 100 ms
++ * D7 - D5 = 000
++ * --> AGC target gain for headset input = -5.5 db
++ * D14 - D8 = 000 0000
++ * --> Adc headset/AUX pga settings = 0 db
++ * D15 = 1
++ * --> Headset/AUX input muted
++ *
++ * Mute headset aux input
++ */
++ val = 0x8000; // 1000 0000 0000 0000
++ omap_tsc2101_audio_write(TSC2101_HEADSET_GAIN_CTRL, val);
++ set_record_source(REC_SRC_MICIN_HND_AND_AUX1);
++
++ // hacks start
++ /* D0 = flag, Headset/Aux or handset PGA flag
++ * --> & with 1 (= 1 -->gain applied == pga register settings)
++ * D1 = 0, DAC channel PGA soft stepping control
++ * --> 0.5 db change every WCLK
++ * D2 = flag, DAC right channel PGA flag
++ * --> & with 1
++ * D3 = flag, DAC left channel PGA flag
++ * -- > & with 1
++ * D7 - D4 = 0001, keyclick length
++ * --> 4 periods key clicks
++ * D10 - D8 = 100, keyclick frequenzy
++ * --> 1 kHz,
++ * D11 = 0, Headset/Aux or handset soft stepping control
++ * --> 0,5 db change every WCLK or ADWS
++ * D14 -D12 = 100, Keyclick applitude control
++ * --> Medium amplitude
++ * D15 = 0, keyclick disabled
++ */
++ val = omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_2);
++ val = val & 0x441d;
++ val = val | 0x4410; // D14, D10, D4 bits == 1
++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_2, val);
++
++ /*
++ * D0 = 0 (reserved, write always 0)
++ * D1 = flag,
++ * --> & with 1
++ * D2 - D5 = 0000 (reserved, write always 0000)
++ * D6 = 1
++ * --> MICBIAS_HND = 2.0 v
++ * D8 - D7 = 00
++ * --> MICBIAS_HED = 3.3 v
++ * D10 - D9 = 01,
++ * --> Mic AGC hysteric selection = 2 db
++ * D11 = 1,
++ * --> Disable buzzer PGA soft stepping
++ * D12 = 0,
++ * --> Enable CELL phone PGA soft stepping control
++ * D13 = 1
++ * --> Disable analog sidetone soft stepping control
++ * D14 = 0
++ * --> Enable DAC PGA soft stepping control
++ * D15 = 0,
++ * --> Enable headset/Aux or Handset soft stepping control
++ */
++ val = omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_4);
++ val = val & 0x2a42; // 0010 1010 0100 0010
++ val = val | 0x2a40; // bits D13, D11, D9, D6 == 1
++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_4, val);
++ printk("set_telephone_to_record_source(), TSC2101_AUDIO_CTRL_4 = %d\n", omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_4));
++ /*
++ * D0 = 0
++ * --> reserved, write always = 0
++ * D1 = flag, read only
++ * --> & with 1
++ * D5 - D2 = 1111, Buzzer input PGA settings
++ * --> 0 db
++ * D6 = 1,
++ * --> power down buzzer input pga
++ * D7 = flag, read only
++ * --> & with 1
++ * D14 - D8 = 101 1101
++ * --> 12 DB
++ * D15 = 0
++ * --> power up cell phone input PGA
++ */
++ val = omap_tsc2101_audio_read(TSC2101_BUZZER_GAIN_CTRL);
++ val = val & 0x5dfe;
++ val = val | 0x5dfe; // bits, D14, D12, D11, D10, D8, D6, D5,D4,D3,D2
++ omap_tsc2101_audio_write(TSC2101_BUZZER_GAIN_CTRL, val);
++
++ /* D6 - D0 = 000 1001
++ * --> -4.5 db for DAC right channel volume control
++ * D7 = 1
++ * --> DAC right channel muted
++ * D14 - D8 = 000 1001
++ * --> -4.5 db for DAC left channel volume control
++ * D15 = 1
++ * --> DAC left channel muted
++ */
++ //val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL);
++ val = 0x8989;
++ omap_tsc2101_audio_write(TSC2101_DAC_GAIN_CTRL, val);
++
++ /* 0000 0000 0100 0000
++ *
++ * D1 - D0 = 0
++ * --> GPIO 1 pin output is three stated
++ * D2 = 0
++ * --> Disaple GPIO2 for CLKOUT mode
++ * D3 = 0
++ * --> Disable GPUI1 for interrupt detection
++ * D4 = 0
++ * --> Disable GPIO2 for headset detection interrupt
++ * D5 = reserved, always 0
++ * D7 - D6 = 01
++ * --> 8 ms clitch detection
++ * D8 = reserved, write only 0
++ * D10 -D9 = 00
++ * --> 16 ms de bouncing programmatitily
++ * for glitch detection during headset detection
++ * D11 = flag for button press
++ * D12 = flag for headset detection
++ * D14-D13 = 00
++ * --> type of headset detected = 00 == no stereo headset deected
++ * D15 = 0
++ * --> Disable headset detection
++ *
++ * */
++ val = 0x40;
++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_7, val);
++}
++
+ /*
+ * Checks whether the headset is detected.
+ * If headset is detected, the type is returned. Type can be
+@@ -433,8 +636,7 @@
+ u16 curVal;
+
+ curType = 0; /* not detected */
+- curVal = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_AUDIO_CTRL_7);
++ curVal = omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_7);
+ curDetected = curVal & AC7_HDDETFL;
+ if (curDetected) {
+ printk("headset detected, checking type from %d \n", curVal);
+@@ -461,13 +663,10 @@
+ * AGC enable for handset input
+ * Handset input not muted
+ */
+- val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_HANDSET_GAIN_CTRL);
++ val = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL);
+ val = val | HNGC_AGCEN_HND;
+ val = val & ~HNGC_ADMUT_HND;
+- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_HANDSET_GAIN_CTRL,
+- val);
++ omap_tsc2101_audio_write(TSC2101_HANDSET_GAIN_CTRL, val);
+
+ /* mic input volume control
+ * SET_MIC in the OSS driver
+@@ -479,7 +678,7 @@
+ */
+ set_mixer_volume_as_dac_gain_control_volume(DEFAULT_OUTPUT_VOLUME, DEFAULT_OUTPUT_VOLUME);
+ /* unmute */
+- dac_gain_control_unmute_control(1, 1);
++ dac_gain_control_unmute(1, 1);
+ }
+
+ /*
+@@ -490,11 +689,11 @@
+ FN_IN;
+
+ /* Headset/Hook switch detect enabled */
+- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_AUDIO_CTRL_7,
+- AC7_DETECT);
++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_7, AC7_DETECT);
+
+- init_record_sources();
++ /* Select headset to record source (MIC_INHED)*/
++ set_record_source(REC_SRC_SINGLE_ENDED_MICIN_HED);
++ /* Init loudspeaker as a default playback target*/
+ init_playback_targets();
+
+ FN_OUT(0);
+@@ -503,7 +702,7 @@
+ static int __pcm_playback_target_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+ {
+ static char *texts[PLAYBACK_TARGET_COUNT] = {
+- "Loudspeaker", "Headphone"
++ "Loudspeaker", "Headphone", "Cellphone"
+ };
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+@@ -533,12 +732,18 @@
+ if ((curVal >= 0) &&
+ (curVal < PLAYBACK_TARGET_COUNT) &&
+ (curVal != current_playback_target)) {
+- if (curVal == 0) {
+- set_loudspeaker_to_playback_target();
++ if (curVal == PLAYBACK_TARGET_LOUDSPEAKER) {
++ set_record_source(REC_SRC_SINGLE_ENDED_MICIN_HED);
++ set_loudspeaker_to_playback_target();
+ }
+- else {
++ else if (curVal == PLAYBACK_TARGET_HEADPHONE) {
++ set_record_source(REC_SRC_SINGLE_ENDED_MICIN_HND);
+ set_headphone_to_playback_target();
+ }
++ else if (curVal == PLAYBACK_TARGET_CELLPHONE) {
++ set_telephone_to_record_source();
++ set_telephone_to_playback_target();
++ }
+ retVal = 1;
+ }
+ return retVal;
+@@ -563,7 +768,7 @@
+ u16 volR;
+ u16 val;
+
+- val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_DAC_GAIN_CTRL);
++ val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL);
+ M_DPRINTK("registry value = %d!\n", val);
+ volL = DGC_DALVL_EXTRACT(val);
+ volR = DGC_DARVL_EXTRACT(val);
+@@ -603,16 +808,16 @@
+ */
+ static int __pcm_playback_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+ {
+- u16 val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_DAC_GAIN_CTRL);
++ u16 val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL);
+
+- ucontrol->value.integer.value[0] = IS_DGC_DALMU_UNMUTED(val);
+- ucontrol->value.integer.value[1] = IS_DGC_DARMU_UNMUTED(val);
++ ucontrol->value.integer.value[0] = IS_UNMUTED(15, val); // left
++ ucontrol->value.integer.value[1] = IS_UNMUTED(7, val); // right
+ return 0;
+ }
+
+ static int __pcm_playback_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+ {
+- return dac_gain_control_unmute_control(ucontrol->value.integer.value[0],
++ return dac_gain_control_unmute(ucontrol->value.integer.value[0],
+ ucontrol->value.integer.value[1]);
+ }
+
+@@ -630,8 +835,7 @@
+ u16 val;
+ u16 vol;
+
+- val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_HEADSET_GAIN_CTRL);
++ val = omap_tsc2101_audio_read(TSC2101_HEADSET_GAIN_CTRL);
+ M_DPRINTK("registry value = %d\n", val);
+ vol = HGC_ADPGA_HED_EXTRACT(val);
+ vol = vol & ~HGC_ADMUT_HED;
+@@ -662,38 +866,17 @@
+ */
+ static int __headset_playback_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+ {
+- u16 val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_HEADSET_GAIN_CTRL);
+- ucontrol->value.integer.value[0] = IS_DGC_HGCMU_UNMUTED(val);
++ u16 val = omap_tsc2101_audio_read(TSC2101_HEADSET_GAIN_CTRL);
++ ucontrol->value.integer.value[0] = IS_UNMUTED(15, val);
+ return 0;
+ }
+
+ static int __headset_playback_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+ {
+- int count = 0;
+- u16 val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_HEADSET_GAIN_CTRL);
+- /* in alsa mixer 1 --> on, 0 == off. In tsc2101 registry 1 --> off, 0 --> on
+- * so if values are same, it's time to change the registry value...
+- */
+- if (ucontrol->value.integer.value[0] == GET_DGC_HGCMU_BIT_VALUE(val)) {
+- if (ucontrol->value.integer.value[0] == 0) {
+- /* mute --> turn bit on */
+- val = val | HGC_ADMUT_HED;
+- }
+- else {
+- /* unmute --> turn bit off */
+- val = val & ~HGC_ADMUT_HED;
+- }
+- count++;
+- M_DPRINTK("changed value, is_unmuted = %d\n", IS_DGC_HGCMU_UNMUTED(val));
+- }
+- if (count) {
+- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_HEADSET_GAIN_CTRL,
+- val);
+- }
+- return count;
++ // mute/unmute headset
++ return adc_pga_unmute_control(ucontrol->value.integer.value[0],
++ TSC2101_HEADSET_GAIN_CTRL,
++ 15);
+ }
+
+ static int __handset_playback_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+@@ -710,7 +893,7 @@
+ u16 val;
+ u16 vol;
+
+- val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_HANDSET_GAIN_CTRL);
++ val = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL);
+ M_DPRINTK("registry value = %d\n", val);
+ vol = HNGC_ADPGA_HND_EXTRACT(val);
+ vol = vol & ~HNGC_ADMUT_HND;
+@@ -740,42 +923,74 @@
+ */
+ static int __handset_playback_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+ {
+- u16 val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_HANDSET_GAIN_CTRL);
+- ucontrol->value.integer.value[0] = IS_DGC_HNGCMU_UNMUTED(val);
++ u16 val = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL);
++ ucontrol->value.integer.value[0] = IS_UNMUTED(15, val);
+ return 0;
+ }
+
+ static int __handset_playback_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+ {
+- int count = 0;
+- u16 val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_HANDSET_GAIN_CTRL);
+-
+- /* in alsa mixer 1 --> on, 0 == off. In tsc2101 registry 1 --> off, 0 --> on
+- * so if values are same, it's time to change the registry value...
+- */
+- if (ucontrol->value.integer.value[0] == GET_DGC_HNGCMU_BIT_VALUE(val)) {
+- if (ucontrol->value.integer.value[0] == 0) {
+- /* mute --> turn bit on */
+- val = val | HNGC_ADMUT_HND;
+- }
+- else {
+- /* unmute --> turn bit off */
+- val = val & ~HNGC_ADMUT_HND;
+- }
+- M_DPRINTK("changed value, is_unmuted = %d\n", IS_DGC_HNGCMU_UNMUTED(val));
+- count++;
+- }
+- if (count) {
+- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
+- TSC2101_HANDSET_GAIN_CTRL,
+- val);
+- }
+- return count;
++ // handset mute/unmute
++ return adc_pga_unmute_control(ucontrol->value.integer.value[0],
++ TSC2101_HANDSET_GAIN_CTRL,
++ 15);
++}
++
++static int __cellphone_input_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
++{
++ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
++ uinfo->count = 1;
++ uinfo->value.integer.min = 0;
++ uinfo->value.integer.max = 1;
++ return 0;
++}
++
++/* When BGC_MUT_CP (bit 15) = 1, power down cellphone input pga.
++ * When BGC_MUT_CP = 0, power up cellphone input pga.
++ */
++static int __cellphone_input_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
++{
++ u16 val = omap_tsc2101_audio_read(TSC2101_BUZZER_GAIN_CTRL);
++ ucontrol->value.integer.value[0] = IS_UNMUTED(15, val);
++ return 0;
++}
++
++static int __cellphone_input_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
++{
++ return adc_pga_unmute_control(ucontrol->value.integer.value[0],
++ TSC2101_BUZZER_GAIN_CTRL,
++ 15);
++}
++
++static int __buzzer_input_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
++{
++ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
++ uinfo->count = 1;
++ uinfo->value.integer.min = 0;
++ uinfo->value.integer.max = 1;
++ return 0;
++}
++
++/* When BGC_MUT_BU (bit 6) = 1, power down cellphone input pga.
++ * When BGC_MUT_BU = 0, power up cellphone input pga.
++ */
++static int __buzzer_input_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
++{
++ u16 val = omap_tsc2101_audio_read(TSC2101_BUZZER_GAIN_CTRL);
++ ucontrol->value.integer.value[0] = IS_UNMUTED(6, val);
++ return 0;
++}
++
++static int __buzzer_input_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
++{
++ return adc_pga_unmute_control(ucontrol->value.integer.value[0],
++ TSC2101_BUZZER_GAIN_CTRL,
++ 6);
+ }
+
+ static snd_kcontrol_new_t tsc2101_control[] __devinitdata = {
+ {
+- .name = "Playback Playback Route",
++ .name = "Target Playback Route",
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .index = 0,
+ .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
+@@ -801,7 +1016,7 @@
+ }, {
+ .name = "Headset Playback Volume",
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+- .index = 1,
++ .index = 0,
+ .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = __headset_playback_volume_info,
+ .get = __headset_playback_volume_get,
+@@ -809,7 +1024,7 @@
+ }, {
+ .name = "Headset Playback Switch",
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+- .index = 1,
++ .index = 0,
+ .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = __headset_playback_switch_info,
+ .get = __headset_playback_switch_get,
+@@ -817,7 +1032,7 @@
+ }, {
+ .name = "Handset Playback Volume",
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+- .index = 2,
++ .index = 0,
+ .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = __handset_playback_volume_info,
+ .get = __handset_playback_volume_get,
+@@ -825,12 +1040,28 @@
+ }, {
+ .name = "Handset Playback Switch",
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+- .index = 2,
++ .index = 0,
+ .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = __handset_playback_switch_info,
+ .get = __handset_playback_switch_get,
+ .put = __handset_playback_switch_put,
+- }
++ }, {
++ .name = "Cellphone Input Switch",
++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
++ .index = 0,
++ .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
++ .info = __cellphone_input_switch_info,
++ .get = __cellphone_input_switch_get,
++ .put = __cellphone_input_switch_put,
++ }, {
++ .name = "Buzzer Input Switch",
++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
++ .index = 0,
++ .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
++ .info = __buzzer_input_switch_info,
++ .get = __buzzer_input_switch_get,
++ .put = __buzzer_input_switch_put,
++ }
+ };
+
+ #ifdef CONFIG_PM
+diff -Naur linux-2.6.16.16/sound/arm/omap/omap-alsa-tsc2101-mixer.h h6300_dev/sound/arm/omap/omap-alsa-tsc2101-mixer.h
+--- linux-2.6.16.16/sound/arm/omap/omap-alsa-tsc2101-mixer.h 2006-05-17 21:41:31.000000000 +0300
++++ h6300_dev/sound/arm/omap/omap-alsa-tsc2101-mixer.h 2006-03-30 23:15:31.000000000 +0300
+@@ -56,20 +56,21 @@
+ #define INPUT_VOLUME_MAX 0x7D
+ #define INPUT_VOLUME_RANGE (INPUT_VOLUME_MAX - INPUT_VOLUME_MIN)
+
+-#define PLAYBACK_TARGET_COUNT 0x02
++#define PLAYBACK_TARGET_COUNT 0x03
+ #define PLAYBACK_TARGET_LOUDSPEAKER 0x00
+ #define PLAYBACK_TARGET_HEADPHONE 0x01
++#define PLAYBACK_TARGET_CELLPHONE 0x02
+
+ /* following are used for register 03h Mixer PGA control bits D7-D5 for selecting record source */
+ #define REC_SRC_TARGET_COUNT 0x08
+-#define REC_SRC_SINGLE_ENDED_MICIN_HED MPC_MICSEL(0) // oss code referred to MIXER_LINE
+-#define REC_SRC_SINGLE_ENDED_MICIN_HND MPC_MICSEL(1) // oss code referred to MIXER_MIC
+-#define REC_SRC_SINGLE_ENDED_AUX1 MPC_MICSEL(2)
+-#define REC_SRC_SINGLE_ENDED_AUX2 MPC_MICSEL(3)
+-#define REC_SRC_MICIN_HED_AND_AUX1 MPC_MICSEL(4)
+-#define REC_SRC_MICIN_HED_AND_AUX2 MPC_MICSEL(5)
+-#define REC_SRC_MICIN_HND_AND_AUX1 MPC_MICSEL(6)
+-#define REC_SRC_MICIN_HND_AND_AUX2 MPC_MICSEL(7)
++#define REC_SRC_SINGLE_ENDED_MICIN_HED 0x00 // oss code referred to MIXER_LINE
++#define REC_SRC_SINGLE_ENDED_MICIN_HND 0x01 // oss code referred to MIXER_MIC
++#define REC_SRC_SINGLE_ENDED_AUX1 0x02
++#define REC_SRC_SINGLE_ENDED_AUX2 0x03
++#define REC_SRC_MICIN_HED_AND_AUX1 0x04
++#define REC_SRC_MICIN_HED_AND_AUX2 0x05
++#define REC_SRC_MICIN_HND_AND_AUX1 0x06
++#define REC_SRC_MICIN_HND_AND_AUX2 0x07
+
+ #define DEFAULT_OUTPUT_VOLUME 90 // default output volume to dac dgc
+ #define DEFAULT_INPUT_VOLUME 20 // default record volume
+diff -Naur linux-2.6.16.16/sound/oss/Kconfig h6300_dev/sound/oss/Kconfig
+--- linux-2.6.16.16/sound/oss/Kconfig 2006-05-17 21:41:31.000000000 +0300
++++ h6300_dev/sound/oss/Kconfig 2006-02-06 15:36:21.000000000 +0200
+@@ -13,8 +13,8 @@
+
+ config SOUND_OMAP_TSC2101
+ tristate "TSC2101 Stereo Codec"
+- depends on SOUND_OMAP && ( MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4 || MACH_OMAP_APOLLON)
+- select OMAP_TSC2101 if ( MACH_OMAP_H2 || MACH_OMAP_H3 )
++ depends on SOUND_OMAP && ( MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4 || MACH_OMAP_APOLLON || MACH_OMAP_H6300)
++ select OMAP_TSC2101 if ( MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H6300 )
+ select OMAP_UWIRE if ARCH_OMAP1
+ ---help---
+ Tsc2101 Audio Codec Driver for OMAP will be enabled.
+diff -Naur linux-2.6.16.16/sound/oss/omap-audio-tsc2101.c h6300_dev/sound/oss/omap-audio-tsc2101.c
+--- linux-2.6.16.16/sound/oss/omap-audio-tsc2101.c 2006-05-17 21:41:31.000000000 +0300
++++ h6300_dev/sound/oss/omap-audio-tsc2101.c 2006-04-02 00:23:01.000000000 +0300
+@@ -48,7 +48,7 @@
+ #include "omap-audio.h"
+ #include "omap-audio-dma-intfc.h"
+ #include <asm/arch/mcbsp.h>
+-#ifdef CONFIG_ARCH_OMAP16XX
++#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_MACH_OMAP_H6300)
+ #include <../drivers/ssi/omap-uwire.h>
+ #include <asm/arch/dsp_common.h>
+ #elif defined(CONFIG_ARCH_OMAP24XX)
+@@ -73,10 +73,16 @@
+
+ #ifdef CONFIG_ARCH_OMAP16XX
+ #define PLATFORM_NAME "OMAP16XX"
++#elif CONFIG_MACH_OMAP_H6300
++#define PLATFORM_NAME "OMAP15XX"
+ #elif defined(CONFIG_ARCH_OMAP24XX)
+ #define PLATFORM_NAME "OMAP2"
+ #endif
+
++#if CONFIG_ARCH_OMAP16XX
++#define OMAP_DSP_BASE 0xE0000000
++#endif
++
+ /* Define to set the tsc as the master w.r.t McBSP */
+ #define TSC_MASTER
+
+@@ -123,7 +129,7 @@
+ /*********** Debug Macros ********/
+ /* To Generate a rather shrill tone -test the entire path */
+ //#define TONE_GEN
+-/* To Generate a tone for each keyclick - test the tsc,spi paths*/
++///* To Generate a tone for each keyclick - test the tsc,spi paths*/
+ //#define TEST_KEYCLICK
+ /* To dump the tsc registers for debug */
+ //#define TSC_DUMP_REGISTERS
+@@ -230,6 +236,17 @@
+ };
+
+ static struct omap_mcbsp_reg_cfg initial_config = {
++#ifdef CONFIG_MACH_OMAP_H6300
++ .spcr2 = 0x0005,
++ .spcr1 = 0x0005,
++ .rcr2 = 0x8041,
++ .rcr1 = 0x8041,
++ .xcr2 = 0x00a1,
++ .xcr1 = 0x00a1,
++ .srgr2 = 0xb000,
++ .srgr1 = 0xb000,
++ .pcr0 = 0x0081,
++#else
+ .spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
+ .spcr1 = RINTM(3) | RRST,
+ .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
+@@ -253,6 +270,7 @@
+ #endif /* tsc Master defs */
+
+ #endif /* platform specific inits */
++#endif /* CONFIG_MACH_OMAP_H6300 */
+ };
+
+ /***************************** MODULES SPECIFIC FUNCTION PROTOTYPES ********************/
diff --git a/packages/linux/linux-h6300-omap1_2.6.16.16.bb b/packages/linux/linux-h6300-omap1_2.6.16.16.bb
new file mode 100644
index 0000000000..e270cd87a2
--- /dev/null
+++ b/packages/linux/linux-h6300-omap1_2.6.16.16.bb
@@ -0,0 +1,19 @@
+DESCRIPTION = "Linux kernel for HP iPAQ h6300 series OMAP1510 based phones."
+MAINTAINER = "Mika Laitio <lamikr@cc.jyu.fi>"
+SECTION = "kernel"
+LICENSE = "GPL"
+
+SRC_URI = "http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.16.tar.bz2 \
+ http://www.muru.com/linux/omap/patches/patch-2.6.16-omap2.bz2;patch=1 \
+ file://linux-2.6.16.16.patch;patch=1 \
+ file://linux-h6300-omap2-2.6.16.16.patch;patch=1 \
+ file://defconfig"
+
+S = "${WORKDIR}/linux-2.6.16"
+
+inherit kernel
+
+do_configure_prepend() {
+ install -m 0644 ${WORKDIR}/defconfig ${S}/.config
+ oe_runmake oldconfig
+}
diff --git a/packages/linux/linux-openzaurus-2.6.16/defconfig-akita b/packages/linux/linux-openzaurus-2.6.16/defconfig-akita
index c46cab31b2..967371c661 100644
--- a/packages/linux/linux-openzaurus-2.6.16/defconfig-akita
+++ b/packages/linux/linux-openzaurus-2.6.16/defconfig-akita
@@ -740,6 +740,9 @@ CONFIG_INPUT=y
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
CONFIG_INPUT_EVDEV=y
@@ -957,10 +960,7 @@ CONFIG_FONT_8x16=y
#
# Logo configuration
#
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_LOGO is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_BACKLIGHT_DEVICE=y
@@ -1379,6 +1379,10 @@ CONFIG_JFFS2_RUBIN=y
CONFIG_JFFS2_CMODE_PRIORITY=y
# CONFIG_JFFS2_CMODE_SIZE is not set
CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
diff --git a/packages/linux/linux-openzaurus-2.6.16/defconfig-c7x0 b/packages/linux/linux-openzaurus-2.6.16/defconfig-c7x0
index 522c793033..602e69ee34 100644
--- a/packages/linux/linux-openzaurus-2.6.16/defconfig-c7x0
+++ b/packages/linux/linux-openzaurus-2.6.16/defconfig-c7x0
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.16
-# Thu Mar 23 22:03:05 2006
+# Mon May 22 09:00:01 2006
#
CONFIG_ARM=y
CONFIG_MMU=y
@@ -753,6 +753,9 @@ CONFIG_INPUT=y
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
CONFIG_INPUT_EVDEV=y
@@ -1412,6 +1415,10 @@ CONFIG_JFFS2_RUBIN=y
CONFIG_JFFS2_CMODE_PRIORITY=y
# CONFIG_JFFS2_CMODE_SIZE is not set
CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
diff --git a/packages/linux/linux-openzaurus-2.6.16/defconfig-collie b/packages/linux/linux-openzaurus-2.6.16/defconfig-collie
index 1400c2ea69..20ec01ff21 100644
--- a/packages/linux/linux-openzaurus-2.6.16/defconfig-collie
+++ b/packages/linux/linux-openzaurus-2.6.16/defconfig-collie
@@ -35,7 +35,7 @@ CONFIG_SYSCTL=y
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
CONFIG_UID16=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
@@ -256,8 +256,8 @@ CONFIG_SYN_COOKIES=y
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
# CONFIG_IPV6 is not set
@@ -588,6 +588,9 @@ CONFIG_INPUT=y
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
# CONFIG_INPUT_JOYDEV is not set
CONFIG_INPUT_TSDEV=y
CONFIG_INPUT_TSDEV_SCREEN_X=240
@@ -953,7 +956,7 @@ CONFIG_INOTIFY=y
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
+# CONFIG_MSDOS_FS is not set
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
@@ -989,6 +992,10 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=y
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
diff --git a/packages/linux/linux-openzaurus-2.6.16/defconfig-ipaq-pxa270 b/packages/linux/linux-openzaurus-2.6.16/defconfig-ipaq-pxa270
index b78ee75a98..d6e3558456 100644
--- a/packages/linux/linux-openzaurus-2.6.16/defconfig-ipaq-pxa270
+++ b/packages/linux/linux-openzaurus-2.6.16/defconfig-ipaq-pxa270
@@ -578,8 +578,8 @@ CONFIG_INPUT=y
#
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_MOUSEDEV_SCREEN_X=240
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
CONFIG_INPUT_EVDEV=y
@@ -854,6 +854,10 @@ CONFIG_JFFS2_RTIME=y
CONFIG_JFFS2_SUMMARY=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=y
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
diff --git a/packages/linux/linux-openzaurus-2.6.16/defconfig-poodle b/packages/linux/linux-openzaurus-2.6.16/defconfig-poodle
index f02694d67f..a909387adc 100644
--- a/packages/linux/linux-openzaurus-2.6.16/defconfig-poodle
+++ b/packages/linux/linux-openzaurus-2.6.16/defconfig-poodle
@@ -762,6 +762,9 @@ CONFIG_INPUT=y
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
CONFIG_INPUT_EVDEV=y
@@ -1037,10 +1040,7 @@ CONFIG_FONT_MINI_4x6=y
#
# Logo configuration
#
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_LOGO is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_BACKLIGHT_DEVICE=y
@@ -1362,6 +1362,10 @@ CONFIG_JFFS2_RUBIN=y
CONFIG_JFFS2_CMODE_PRIORITY=y
# CONFIG_JFFS2_CMODE_SIZE is not set
CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
diff --git a/packages/linux/linux-openzaurus-2.6.16/defconfig-spitz b/packages/linux/linux-openzaurus-2.6.16/defconfig-spitz
index 33eae4385e..ddb8a8aeae 100644
--- a/packages/linux/linux-openzaurus-2.6.16/defconfig-spitz
+++ b/packages/linux/linux-openzaurus-2.6.16/defconfig-spitz
@@ -740,6 +740,9 @@ CONFIG_INPUT=y
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
CONFIG_INPUT_EVDEV=y
@@ -957,10 +960,7 @@ CONFIG_FONT_8x16=y
#
# Logo configuration
#
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_LOGO is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_BACKLIGHT_DEVICE=y
@@ -1379,6 +1379,10 @@ CONFIG_JFFS2_RUBIN=y
CONFIG_JFFS2_CMODE_PRIORITY=y
# CONFIG_JFFS2_CMODE_SIZE is not set
CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
diff --git a/packages/linux/linux-openzaurus-2.6.16/defconfig-tosa b/packages/linux/linux-openzaurus-2.6.16/defconfig-tosa
index a757139661..d09989c4dd 100644
--- a/packages/linux/linux-openzaurus-2.6.16/defconfig-tosa
+++ b/packages/linux/linux-openzaurus-2.6.16/defconfig-tosa
@@ -753,6 +753,9 @@ CONFIG_INPUT=y
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=480
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=640
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
CONFIG_INPUT_EVDEV=y
@@ -1412,6 +1415,10 @@ CONFIG_JFFS2_RUBIN=y
CONFIG_JFFS2_CMODE_PRIORITY=y
# CONFIG_JFFS2_CMODE_SIZE is not set
CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
diff --git a/packages/linux/linux-openzaurus-2.6.16/squashfs3.0-2.6.15.patch b/packages/linux/linux-openzaurus-2.6.16/squashfs3.0-2.6.15.patch
new file mode 100644
index 0000000000..f88dbbae8e
--- /dev/null
+++ b/packages/linux/linux-openzaurus-2.6.16/squashfs3.0-2.6.15.patch
@@ -0,0 +1,4173 @@
+diff --new-file -urp linux-2.6.15/fs/Kconfig linux-2.6.15-squashfs3.0/fs/Kconfig
+--- linux-2.6.15/fs/Kconfig 2006-03-01 22:37:27.000000000 +0000
++++ linux-2.6.15-squashfs3.0/fs/Kconfig 2006-03-07 21:12:37.000000000 +0000
+@@ -1151,6 +1151,71 @@ config CRAMFS
+
+ If unsure, say N.
+
++config SQUASHFS
++ tristate "SquashFS 3.0 - Squashed file system support"
++ select ZLIB_INFLATE
++ help
++ Saying Y here includes support for SquashFS 3.0 (a Compressed Read-Only File
++ System). Squashfs is a highly compressed read-only filesystem for Linux.
++ It uses zlib compression to compress both files, inodes and directories.
++ Inodes in the system are very small and all blocks are packed to minimise
++ data overhead. Block sizes greater than 4K are supported up to a maximum of 64K.
++ SquashFS 3.0 supports 64 bit filesystems and files (larger than 4GB), full
++ uid/gid information, hard links and timestamps.
++
++ Squashfs is intended for general read-only filesystem use, for archival
++ use (i.e. in cases where a .tar.gz file may be used), and in embedded
++ systems where low overhead is needed. Further information and filesystem tools
++ are available from http://squashfs.sourceforge.net.
++
++ If you want to compile this as a module ( = code which can be
++ inserted in and removed from the running kernel whenever you want),
++ say M here and read <file:Documentation/modules.txt>. The module
++ will be called squashfs. Note that the root file system (the one
++ containing the directory /) cannot be compiled as a module.
++
++ If unsure, say N.
++
++config SQUASHFS_EMBEDDED
++
++ bool "Additional options for memory-constrained systems"
++ depends on SQUASHFS
++ default n
++ help
++ Saying Y here allows you to specify cache sizes and how Squashfs
++ allocates memory. This is only intended for memory constrained
++ systems.
++
++ If unsure, say N.
++
++config SQUASHFS_FRAGMENT_CACHE_SIZE
++ int "Number of fragments cached" if SQUASHFS_EMBEDDED
++ depends on SQUASHFS
++ default "3"
++ help
++ By default SquashFS caches the last 3 fragments read from
++ the filesystem. Increasing this amount may mean SquashFS
++ has to re-read fragments less often from disk, at the expense
++ of extra system memory. Decreasing this amount will mean
++ SquashFS uses less memory at the expense of extra reads from disk.
++
++ Note there must be at least one cached fragment. Anything
++ much more than three will probably not make much difference.
++
++config SQUASHFS_VMALLOC
++ bool "Use Vmalloc rather than Kmalloc" if SQUASHFS_EMBEDDED
++ depends on SQUASHFS
++ default n
++ help
++ By default SquashFS uses kmalloc to obtain fragment cache memory.
++ Kmalloc memory is the standard kernel allocator, but it can fail
++ on memory constrained systems. Because of the way Vmalloc works,
++ Vmalloc can succeed when kmalloc fails. Specifying this option
++ will make SquashFS always use Vmalloc to allocate the
++ fragment cache memory.
++
++ If unsure, say N.
++
+ config VXFS_FS
+ tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)"
+ help
+diff --new-file -urp linux-2.6.15/fs/Makefile linux-2.6.15-squashfs3.0/fs/Makefile
+--- linux-2.6.15/fs/Makefile 2006-03-01 22:37:27.000000000 +0000
++++ linux-2.6.15-squashfs3.0/fs/Makefile 2006-03-07 21:12:37.000000000 +0000
+@@ -55,6 +55,7 @@ obj-$(CONFIG_EXT3_FS) += ext3/ # Before
+ obj-$(CONFIG_JBD) += jbd/
+ obj-$(CONFIG_EXT2_FS) += ext2/
+ obj-$(CONFIG_CRAMFS) += cramfs/
++obj-$(CONFIG_SQUASHFS) += squashfs/
+ obj-$(CONFIG_RAMFS) += ramfs/
+ obj-$(CONFIG_HUGETLBFS) += hugetlbfs/
+ obj-$(CONFIG_CODA_FS) += coda/
+diff --new-file -urp linux-2.6.15/fs/squashfs/inode.c linux-2.6.15-squashfs3.0/fs/squashfs/inode.c
+--- linux-2.6.15/fs/squashfs/inode.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-squashfs3.0/fs/squashfs/inode.c 2006-03-07 21:12:37.000000000 +0000
+@@ -0,0 +1,2127 @@
++/*
++ * Squashfs - a compressed read only filesystem for Linux
++ *
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006
++ * Phillip Lougher <phillip@lougher.org.uk>
++ *
++ * 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.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ *
++ * inode.c
++ */
++
++#include <linux/types.h>
++#include <linux/squashfs_fs.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/smp_lock.h>
++#include <linux/slab.h>
++#include <linux/squashfs_fs_sb.h>
++#include <linux/squashfs_fs_i.h>
++#include <linux/buffer_head.h>
++#include <linux/vfs.h>
++#include <linux/init.h>
++#include <linux/dcache.h>
++#include <linux/wait.h>
++#include <linux/zlib.h>
++#include <linux/blkdev.h>
++#include <linux/vmalloc.h>
++#include <asm/uaccess.h>
++#include <asm/semaphore.h>
++
++#include "squashfs.h"
++
++static void squashfs_put_super(struct super_block *);
++static int squashfs_statfs(struct super_block *, struct kstatfs *);
++static int squashfs_symlink_readpage(struct file *file, struct page *page);
++static int squashfs_readpage(struct file *file, struct page *page);
++static int squashfs_readpage4K(struct file *file, struct page *page);
++static int squashfs_readdir(struct file *, void *, filldir_t);
++static struct inode *squashfs_alloc_inode(struct super_block *sb);
++static void squashfs_destroy_inode(struct inode *inode);
++static int init_inodecache(void);
++static void destroy_inodecache(void);
++static struct dentry *squashfs_lookup(struct inode *, struct dentry *,
++ struct nameidata *);
++static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode);
++static long long read_blocklist(struct inode *inode, int index,
++ int readahead_blks, char *block_list,
++ unsigned short **block_p, unsigned int *bsize);
++static struct super_block *squashfs_get_sb(struct file_system_type *, int,
++ const char *, void *);
++
++
++static z_stream stream;
++
++static struct file_system_type squashfs_fs_type = {
++ .owner = THIS_MODULE,
++ .name = "squashfs",
++ .get_sb = squashfs_get_sb,
++ .kill_sb = kill_block_super,
++ .fs_flags = FS_REQUIRES_DEV
++};
++
++static unsigned char squashfs_filetype_table[] = {
++ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
++};
++
++static struct super_operations squashfs_ops = {
++ .alloc_inode = squashfs_alloc_inode,
++ .destroy_inode = squashfs_destroy_inode,
++ .statfs = squashfs_statfs,
++ .put_super = squashfs_put_super,
++};
++
++SQSH_EXTERN struct address_space_operations squashfs_symlink_aops = {
++ .readpage = squashfs_symlink_readpage
++};
++
++SQSH_EXTERN struct address_space_operations squashfs_aops = {
++ .readpage = squashfs_readpage
++};
++
++SQSH_EXTERN struct address_space_operations squashfs_aops_4K = {
++ .readpage = squashfs_readpage4K
++};
++
++static struct file_operations squashfs_dir_ops = {
++ .read = generic_read_dir,
++ .readdir = squashfs_readdir
++};
++
++SQSH_EXTERN struct inode_operations squashfs_dir_inode_ops = {
++ .lookup = squashfs_lookup
++};
++
++
++static struct buffer_head *get_block_length(struct super_block *s,
++ int *cur_index, int *offset, int *c_byte)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ unsigned short temp;
++ struct buffer_head *bh;
++
++ if (!(bh = sb_bread(s, *cur_index)))
++ goto out;
++
++ if (msblk->devblksize - *offset == 1) {
++ if (msblk->swap)
++ ((unsigned char *) &temp)[1] = *((unsigned char *)
++ (bh->b_data + *offset));
++ else
++ ((unsigned char *) &temp)[0] = *((unsigned char *)
++ (bh->b_data + *offset));
++ brelse(bh);
++ if (!(bh = sb_bread(s, ++(*cur_index))))
++ goto out;
++ if (msblk->swap)
++ ((unsigned char *) &temp)[0] = *((unsigned char *)
++ bh->b_data);
++ else
++ ((unsigned char *) &temp)[1] = *((unsigned char *)
++ bh->b_data);
++ *c_byte = temp;
++ *offset = 1;
++ } else {
++ if (msblk->swap) {
++ ((unsigned char *) &temp)[1] = *((unsigned char *)
++ (bh->b_data + *offset));
++ ((unsigned char *) &temp)[0] = *((unsigned char *)
++ (bh->b_data + *offset + 1));
++ } else {
++ ((unsigned char *) &temp)[0] = *((unsigned char *)
++ (bh->b_data + *offset));
++ ((unsigned char *) &temp)[1] = *((unsigned char *)
++ (bh->b_data + *offset + 1));
++ }
++ *c_byte = temp;
++ *offset += 2;
++ }
++
++ if (SQUASHFS_CHECK_DATA(msblk->sblk.flags)) {
++ if (*offset == msblk->devblksize) {
++ brelse(bh);
++ if (!(bh = sb_bread(s, ++(*cur_index))))
++ goto out;
++ *offset = 0;
++ }
++ if (*((unsigned char *) (bh->b_data + *offset)) !=
++ SQUASHFS_MARKER_BYTE) {
++ ERROR("Metadata block marker corrupt @ %x\n",
++ *cur_index);
++ brelse(bh);
++ goto out;
++ }
++ (*offset)++;
++ }
++ return bh;
++
++out:
++ return NULL;
++}
++
++
++SQSH_EXTERN unsigned int squashfs_read_data(struct super_block *s, char *buffer,
++ long long index, unsigned int length,
++ long long *next_index)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ struct buffer_head *bh[((SQUASHFS_FILE_MAX_SIZE - 1) >>
++ msblk->devblksize_log2) + 2];
++ unsigned int offset = index & ((1 << msblk->devblksize_log2) - 1);
++ unsigned int cur_index = index >> msblk->devblksize_log2;
++ int bytes, avail_bytes, b = 0, k;
++ char *c_buffer;
++ unsigned int compressed;
++ unsigned int c_byte = length;
++
++ if (c_byte) {
++ bytes = msblk->devblksize - offset;
++ compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte);
++ c_buffer = compressed ? msblk->read_data : buffer;
++ c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte);
++
++ TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed
++ ? "" : "un", (unsigned int) c_byte);
++
++ if (!(bh[0] = sb_getblk(s, cur_index)))
++ goto block_release;
++
++ for (b = 1; bytes < c_byte; b++) {
++ if (!(bh[b] = sb_getblk(s, ++cur_index)))
++ goto block_release;
++ bytes += msblk->devblksize;
++ }
++ ll_rw_block(READ, b, bh);
++ } else {
++ if (!(bh[0] = get_block_length(s, &cur_index, &offset,
++ &c_byte)))
++ goto read_failure;
++
++ bytes = msblk->devblksize - offset;
++ compressed = SQUASHFS_COMPRESSED(c_byte);
++ c_buffer = compressed ? msblk->read_data : buffer;
++ c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
++
++ TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed
++ ? "" : "un", (unsigned int) c_byte);
++
++ for (b = 1; bytes < c_byte; b++) {
++ if (!(bh[b] = sb_getblk(s, ++cur_index)))
++ goto block_release;
++ bytes += msblk->devblksize;
++ }
++ ll_rw_block(READ, b - 1, bh + 1);
++ }
++
++ if (compressed)
++ down(&msblk->read_data_mutex);
++
++ for (bytes = 0, k = 0; k < b; k++) {
++ avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ?
++ msblk->devblksize - offset :
++ c_byte - bytes;
++ wait_on_buffer(bh[k]);
++ if (!buffer_uptodate(bh[k]))
++ goto block_release;
++ memcpy(c_buffer + bytes, bh[k]->b_data + offset, avail_bytes);
++ bytes += avail_bytes;
++ offset = 0;
++ brelse(bh[k]);
++ }
++
++ /*
++ * uncompress block
++ */
++ if (compressed) {
++ int zlib_err;
++
++ stream.next_in = c_buffer;
++ stream.avail_in = c_byte;
++ stream.next_out = buffer;
++ stream.avail_out = msblk->read_size;
++
++ if (((zlib_err = zlib_inflateInit(&stream)) != Z_OK) ||
++ ((zlib_err = zlib_inflate(&stream, Z_FINISH))
++ != Z_STREAM_END) || ((zlib_err =
++ zlib_inflateEnd(&stream)) != Z_OK)) {
++ ERROR("zlib_fs returned unexpected result 0x%x\n",
++ zlib_err);
++ bytes = 0;
++ } else
++ bytes = stream.total_out;
++
++ up(&msblk->read_data_mutex);
++ }
++
++ if (next_index)
++ *next_index = index + c_byte + (length ? 0 :
++ (SQUASHFS_CHECK_DATA(msblk->sblk.flags)
++ ? 3 : 2));
++ return bytes;
++
++block_release:
++ while (--b >= 0)
++ brelse(bh[b]);
++
++read_failure:
++ ERROR("sb_bread failed reading block 0x%x\n", cur_index);
++ return 0;
++}
++
++
++SQSH_EXTERN int squashfs_get_cached_block(struct super_block *s, char *buffer,
++ long long block, unsigned int offset,
++ int length, long long *next_block,
++ unsigned int *next_offset)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ int n, i, bytes, return_length = length;
++ long long next_index;
++
++ TRACE("Entered squashfs_get_cached_block [%llx:%x]\n", block, offset);
++
++ while ( 1 ) {
++ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)
++ if (msblk->block_cache[i].block == block)
++ break;
++
++ down(&msblk->block_cache_mutex);
++
++ if (i == SQUASHFS_CACHED_BLKS) {
++ /* read inode header block */
++ for (i = msblk->next_cache, n = SQUASHFS_CACHED_BLKS;
++ n ; n --, i = (i + 1) %
++ SQUASHFS_CACHED_BLKS)
++ if (msblk->block_cache[i].block !=
++ SQUASHFS_USED_BLK)
++ break;
++
++ if (n == 0) {
++ wait_queue_t wait;
++
++ init_waitqueue_entry(&wait, current);
++ add_wait_queue(&msblk->waitq, &wait);
++ set_current_state(TASK_UNINTERRUPTIBLE);
++ up(&msblk->block_cache_mutex);
++ schedule();
++ set_current_state(TASK_RUNNING);
++ remove_wait_queue(&msblk->waitq, &wait);
++ continue;
++ }
++ msblk->next_cache = (i + 1) % SQUASHFS_CACHED_BLKS;
++
++ if (msblk->block_cache[i].block ==
++ SQUASHFS_INVALID_BLK) {
++ if (!(msblk->block_cache[i].data =
++ kmalloc(SQUASHFS_METADATA_SIZE,
++ GFP_KERNEL))) {
++ ERROR("Failed to allocate cache"
++ "block\n");
++ up(&msblk->block_cache_mutex);
++ goto out;
++ }
++ }
++
++ msblk->block_cache[i].block = SQUASHFS_USED_BLK;
++ up(&msblk->block_cache_mutex);
++
++ if (!(msblk->block_cache[i].length =
++ squashfs_read_data(s,
++ msblk->block_cache[i].data,
++ block, 0, &next_index))) {
++ ERROR("Unable to read cache block [%llx:%x]\n",
++ block, offset);
++ goto out;
++ }
++
++ down(&msblk->block_cache_mutex);
++ wake_up(&msblk->waitq);
++ msblk->block_cache[i].block = block;
++ msblk->block_cache[i].next_index = next_index;
++ TRACE("Read cache block [%llx:%x]\n", block, offset);
++ }
++
++ if (msblk->block_cache[i].block != block) {
++ up(&msblk->block_cache_mutex);
++ continue;
++ }
++
++ if ((bytes = msblk->block_cache[i].length - offset) >= length) {
++ if (buffer)
++ memcpy(buffer, msblk->block_cache[i].data +
++ offset, length);
++ if (msblk->block_cache[i].length - offset == length) {
++ *next_block = msblk->block_cache[i].next_index;
++ *next_offset = 0;
++ } else {
++ *next_block = block;
++ *next_offset = offset + length;
++ }
++ up(&msblk->block_cache_mutex);
++ goto finish;
++ } else {
++ if (buffer) {
++ memcpy(buffer, msblk->block_cache[i].data +
++ offset, bytes);
++ buffer += bytes;
++ }
++ block = msblk->block_cache[i].next_index;
++ up(&msblk->block_cache_mutex);
++ length -= bytes;
++ offset = 0;
++ }
++ }
++
++finish:
++ return return_length;
++out:
++ return 0;
++}
++
++
++static int get_fragment_location(struct super_block *s, unsigned int fragment,
++ long long *fragment_start_block,
++ unsigned int *fragment_size)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ long long start_block =
++ msblk->fragment_index[SQUASHFS_FRAGMENT_INDEX(fragment)];
++ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment);
++ struct squashfs_fragment_entry fragment_entry;
++
++ if (msblk->swap) {
++ struct squashfs_fragment_entry sfragment_entry;
++
++ if (!squashfs_get_cached_block(s, (char *) &sfragment_entry,
++ start_block, offset,
++ sizeof(sfragment_entry), &start_block,
++ &offset))
++ goto out;
++ SQUASHFS_SWAP_FRAGMENT_ENTRY(&fragment_entry, &sfragment_entry);
++ } else
++ if (!squashfs_get_cached_block(s, (char *) &fragment_entry,
++ start_block, offset,
++ sizeof(fragment_entry), &start_block,
++ &offset))
++ goto out;
++
++ *fragment_start_block = fragment_entry.start_block;
++ *fragment_size = fragment_entry.size;
++
++ return 1;
++
++out:
++ return 0;
++}
++
++
++SQSH_EXTERN void release_cached_fragment(struct squashfs_sb_info *msblk, struct
++ squashfs_fragment_cache *fragment)
++{
++ down(&msblk->fragment_mutex);
++ fragment->locked --;
++ wake_up(&msblk->fragment_wait_queue);
++ up(&msblk->fragment_mutex);
++}
++
++
++SQSH_EXTERN struct squashfs_fragment_cache *get_cached_fragment(struct super_block
++ *s, long long start_block,
++ int length)
++{
++ int i, n;
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++
++ while ( 1 ) {
++ down(&msblk->fragment_mutex);
++
++ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS &&
++ msblk->fragment[i].block != start_block; i++);
++
++ if (i == SQUASHFS_CACHED_FRAGMENTS) {
++ for (i = msblk->next_fragment, n =
++ SQUASHFS_CACHED_FRAGMENTS; n &&
++ msblk->fragment[i].locked; n--, i = (i + 1) %
++ SQUASHFS_CACHED_FRAGMENTS);
++
++ if (n == 0) {
++ wait_queue_t wait;
++
++ init_waitqueue_entry(&wait, current);
++ add_wait_queue(&msblk->fragment_wait_queue,
++ &wait);
++ set_current_state(TASK_UNINTERRUPTIBLE);
++ up(&msblk->fragment_mutex);
++ schedule();
++ set_current_state(TASK_RUNNING);
++ remove_wait_queue(&msblk->fragment_wait_queue,
++ &wait);
++ continue;
++ }
++ msblk->next_fragment = (msblk->next_fragment + 1) %
++ SQUASHFS_CACHED_FRAGMENTS;
++
++ if (msblk->fragment[i].data == NULL)
++ if (!(msblk->fragment[i].data = SQUASHFS_ALLOC
++ (SQUASHFS_FILE_MAX_SIZE))) {
++ ERROR("Failed to allocate fragment "
++ "cache block\n");
++ up(&msblk->fragment_mutex);
++ goto out;
++ }
++
++ msblk->fragment[i].block = SQUASHFS_INVALID_BLK;
++ msblk->fragment[i].locked = 1;
++ up(&msblk->fragment_mutex);
++
++ if (!(msblk->fragment[i].length = squashfs_read_data(s,
++ msblk->fragment[i].data,
++ start_block, length, NULL))) {
++ ERROR("Unable to read fragment cache block "
++ "[%llx]\n", start_block);
++ msblk->fragment[i].locked = 0;
++ goto out;
++ }
++
++ msblk->fragment[i].block = start_block;
++ TRACE("New fragment %d, start block %lld, locked %d\n",
++ i, msblk->fragment[i].block,
++ msblk->fragment[i].locked);
++ break;
++ }
++
++ msblk->fragment[i].locked++;
++ up(&msblk->fragment_mutex);
++ TRACE("Got fragment %d, start block %lld, locked %d\n", i,
++ msblk->fragment[i].block,
++ msblk->fragment[i].locked);
++ break;
++ }
++
++ return &msblk->fragment[i];
++
++out:
++ return NULL;
++}
++
++
++static struct inode *squashfs_new_inode(struct super_block *s,
++ struct squashfs_base_inode_header *inodeb)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ struct inode *i = new_inode(s);
++
++ if (i) {
++ i->i_ino = inodeb->inode_number;
++ i->i_mtime.tv_sec = inodeb->mtime;
++ i->i_atime.tv_sec = inodeb->mtime;
++ i->i_ctime.tv_sec = inodeb->mtime;
++ i->i_uid = msblk->uid[inodeb->uid];
++ i->i_mode = inodeb->mode;
++ i->i_size = 0;
++ if (inodeb->guid == SQUASHFS_GUIDS)
++ i->i_gid = i->i_uid;
++ else
++ i->i_gid = msblk->guid[inodeb->guid];
++ }
++
++ return i;
++}
++
++
++static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode)
++{
++ struct inode *i;
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++ long long block = SQUASHFS_INODE_BLK(inode) +
++ sblk->inode_table_start;
++ unsigned int offset = SQUASHFS_INODE_OFFSET(inode);
++ long long next_block;
++ unsigned int next_offset;
++ union squashfs_inode_header id, sid;
++ struct squashfs_base_inode_header *inodeb = &id.base,
++ *sinodeb = &sid.base;
++
++ TRACE("Entered squashfs_iget\n");
++
++ if (msblk->swap) {
++ if (!squashfs_get_cached_block(s, (char *) sinodeb, block,
++ offset, sizeof(*sinodeb), &next_block,
++ &next_offset))
++ goto failed_read;
++ SQUASHFS_SWAP_BASE_INODE_HEADER(inodeb, sinodeb,
++ sizeof(*sinodeb));
++ } else
++ if (!squashfs_get_cached_block(s, (char *) inodeb, block,
++ offset, sizeof(*inodeb), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ switch(inodeb->inode_type) {
++ case SQUASHFS_FILE_TYPE: {
++ unsigned int frag_size;
++ long long frag_blk;
++ struct squashfs_reg_inode_header *inodep = &id.reg;
++ struct squashfs_reg_inode_header *sinodep = &sid.reg;
++
++ if (msblk->swap) {
++ if (!squashfs_get_cached_block(s, (char *)
++ sinodep, block, offset,
++ sizeof(*sinodep), &next_block,
++ &next_offset))
++ goto failed_read;
++ SQUASHFS_SWAP_REG_INODE_HEADER(inodep, sinodep);
++ } else
++ if (!squashfs_get_cached_block(s, (char *)
++ inodep, block, offset,
++ sizeof(*inodep), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ frag_blk = SQUASHFS_INVALID_BLK;
++ if (inodep->fragment != SQUASHFS_INVALID_FRAG &&
++ !get_fragment_location(s,
++ inodep->fragment, &frag_blk, &frag_size))
++ goto failed_read;
++
++ if((i = squashfs_new_inode(s, inodeb)) == NULL)
++ goto failed_read1;
++
++ i->i_nlink = 1;
++ i->i_size = inodep->file_size;
++ i->i_fop = &generic_ro_fops;
++ i->i_mode |= S_IFREG;
++ i->i_blocks = ((i->i_size - 1) >> 9) + 1;
++ i->i_blksize = PAGE_CACHE_SIZE;
++ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
++ SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
++ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
++ SQUASHFS_I(i)->start_block = inodep->start_block;
++ SQUASHFS_I(i)->u.s1.block_list_start = next_block;
++ SQUASHFS_I(i)->offset = next_offset;
++ if (sblk->block_size > 4096)
++ i->i_data.a_ops = &squashfs_aops;
++ else
++ i->i_data.a_ops = &squashfs_aops_4K;
++
++ TRACE("File inode %x:%x, start_block %llx, "
++ "block_list_start %llx, offset %x\n",
++ SQUASHFS_INODE_BLK(inode), offset,
++ inodep->start_block, next_block,
++ next_offset);
++ break;
++ }
++ case SQUASHFS_LREG_TYPE: {
++ unsigned int frag_size;
++ long long frag_blk;
++ struct squashfs_lreg_inode_header *inodep = &id.lreg;
++ struct squashfs_lreg_inode_header *sinodep = &sid.lreg;
++
++ if (msblk->swap) {
++ if (!squashfs_get_cached_block(s, (char *)
++ sinodep, block, offset,
++ sizeof(*sinodep), &next_block,
++ &next_offset))
++ goto failed_read;
++ SQUASHFS_SWAP_LREG_INODE_HEADER(inodep, sinodep);
++ } else
++ if (!squashfs_get_cached_block(s, (char *)
++ inodep, block, offset,
++ sizeof(*inodep), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ frag_blk = SQUASHFS_INVALID_BLK;
++ if (inodep->fragment != SQUASHFS_INVALID_FRAG &&
++ !get_fragment_location(s,
++ inodep->fragment, &frag_blk, &frag_size))
++ goto failed_read;
++
++ if((i = squashfs_new_inode(s, inodeb)) == NULL)
++ goto failed_read1;
++
++ i->i_nlink = inodep->nlink;
++ i->i_size = inodep->file_size;
++ i->i_fop = &generic_ro_fops;
++ i->i_mode |= S_IFREG;
++ i->i_blocks = ((i->i_size - 1) >> 9) + 1;
++ i->i_blksize = PAGE_CACHE_SIZE;
++ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
++ SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
++ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
++ SQUASHFS_I(i)->start_block = inodep->start_block;
++ SQUASHFS_I(i)->u.s1.block_list_start = next_block;
++ SQUASHFS_I(i)->offset = next_offset;
++ if (sblk->block_size > 4096)
++ i->i_data.a_ops = &squashfs_aops;
++ else
++ i->i_data.a_ops = &squashfs_aops_4K;
++
++ TRACE("File inode %x:%x, start_block %llx, "
++ "block_list_start %llx, offset %x\n",
++ SQUASHFS_INODE_BLK(inode), offset,
++ inodep->start_block, next_block,
++ next_offset);
++ break;
++ }
++ case SQUASHFS_DIR_TYPE: {
++ struct squashfs_dir_inode_header *inodep = &id.dir;
++ struct squashfs_dir_inode_header *sinodep = &sid.dir;
++
++ if (msblk->swap) {
++ if (!squashfs_get_cached_block(s, (char *)
++ sinodep, block, offset,
++ sizeof(*sinodep), &next_block,
++ &next_offset))
++ goto failed_read;
++ SQUASHFS_SWAP_DIR_INODE_HEADER(inodep, sinodep);
++ } else
++ if (!squashfs_get_cached_block(s, (char *)
++ inodep, block, offset,
++ sizeof(*inodep), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ if((i = squashfs_new_inode(s, inodeb)) == NULL)
++ goto failed_read1;
++
++ i->i_nlink = inodep->nlink;
++ i->i_size = inodep->file_size;
++ i->i_op = &squashfs_dir_inode_ops;
++ i->i_fop = &squashfs_dir_ops;
++ i->i_mode |= S_IFDIR;
++ SQUASHFS_I(i)->start_block = inodep->start_block;
++ SQUASHFS_I(i)->offset = inodep->offset;
++ SQUASHFS_I(i)->u.s2.directory_index_count = 0;
++ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode;
++
++ TRACE("Directory inode %x:%x, start_block %x, offset "
++ "%x\n", SQUASHFS_INODE_BLK(inode),
++ offset, inodep->start_block,
++ inodep->offset);
++ break;
++ }
++ case SQUASHFS_LDIR_TYPE: {
++ struct squashfs_ldir_inode_header *inodep = &id.ldir;
++ struct squashfs_ldir_inode_header *sinodep = &sid.ldir;
++
++ if (msblk->swap) {
++ if (!squashfs_get_cached_block(s, (char *)
++ sinodep, block, offset,
++ sizeof(*sinodep), &next_block,
++ &next_offset))
++ goto failed_read;
++ SQUASHFS_SWAP_LDIR_INODE_HEADER(inodep,
++ sinodep);
++ } else
++ if (!squashfs_get_cached_block(s, (char *)
++ inodep, block, offset,
++ sizeof(*inodep), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ if((i = squashfs_new_inode(s, inodeb)) == NULL)
++ goto failed_read1;
++
++ i->i_nlink = inodep->nlink;
++ i->i_size = inodep->file_size;
++ i->i_op = &squashfs_dir_inode_ops;
++ i->i_fop = &squashfs_dir_ops;
++ i->i_mode |= S_IFDIR;
++ SQUASHFS_I(i)->start_block = inodep->start_block;
++ SQUASHFS_I(i)->offset = inodep->offset;
++ SQUASHFS_I(i)->u.s2.directory_index_start = next_block;
++ SQUASHFS_I(i)->u.s2.directory_index_offset =
++ next_offset;
++ SQUASHFS_I(i)->u.s2.directory_index_count =
++ inodep->i_count;
++ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode;
++
++ TRACE("Long directory inode %x:%x, start_block %x, "
++ "offset %x\n",
++ SQUASHFS_INODE_BLK(inode), offset,
++ inodep->start_block, inodep->offset);
++ break;
++ }
++ case SQUASHFS_SYMLINK_TYPE: {
++ struct squashfs_symlink_inode_header *inodep =
++ &id.symlink;
++ struct squashfs_symlink_inode_header *sinodep =
++ &sid.symlink;
++
++ if (msblk->swap) {
++ if (!squashfs_get_cached_block(s, (char *)
++ sinodep, block, offset,
++ sizeof(*sinodep), &next_block,
++ &next_offset))
++ goto failed_read;
++ SQUASHFS_SWAP_SYMLINK_INODE_HEADER(inodep,
++ sinodep);
++ } else
++ if (!squashfs_get_cached_block(s, (char *)
++ inodep, block, offset,
++ sizeof(*inodep), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ if((i = squashfs_new_inode(s, inodeb)) == NULL)
++ goto failed_read1;
++
++ i->i_nlink = inodep->nlink;
++ i->i_size = inodep->symlink_size;
++ i->i_op = &page_symlink_inode_operations;
++ i->i_data.a_ops = &squashfs_symlink_aops;
++ i->i_mode |= S_IFLNK;
++ SQUASHFS_I(i)->start_block = next_block;
++ SQUASHFS_I(i)->offset = next_offset;
++
++ TRACE("Symbolic link inode %x:%x, start_block %llx, "
++ "offset %x\n",
++ SQUASHFS_INODE_BLK(inode), offset,
++ next_block, next_offset);
++ break;
++ }
++ case SQUASHFS_BLKDEV_TYPE:
++ case SQUASHFS_CHRDEV_TYPE: {
++ struct squashfs_dev_inode_header *inodep = &id.dev;
++ struct squashfs_dev_inode_header *sinodep = &sid.dev;
++
++ if (msblk->swap) {
++ if (!squashfs_get_cached_block(s, (char *)
++ sinodep, block, offset,
++ sizeof(*sinodep), &next_block,
++ &next_offset))
++ goto failed_read;
++ SQUASHFS_SWAP_DEV_INODE_HEADER(inodep, sinodep);
++ } else
++ if (!squashfs_get_cached_block(s, (char *)
++ inodep, block, offset,
++ sizeof(*inodep), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ if ((i = squashfs_new_inode(s, inodeb)) == NULL)
++ goto failed_read1;
++
++ i->i_nlink = inodep->nlink;
++ i->i_mode |= (inodeb->inode_type ==
++ SQUASHFS_CHRDEV_TYPE) ? S_IFCHR :
++ S_IFBLK;
++ init_special_inode(i, i->i_mode,
++ old_decode_dev(inodep->rdev));
++
++ TRACE("Device inode %x:%x, rdev %x\n",
++ SQUASHFS_INODE_BLK(inode), offset,
++ inodep->rdev);
++ break;
++ }
++ case SQUASHFS_FIFO_TYPE:
++ case SQUASHFS_SOCKET_TYPE: {
++ struct squashfs_ipc_inode_header *inodep = &id.ipc;
++ struct squashfs_ipc_inode_header *sinodep = &sid.ipc;
++
++ if (msblk->swap) {
++ if (!squashfs_get_cached_block(s, (char *)
++ sinodep, block, offset,
++ sizeof(*sinodep), &next_block,
++ &next_offset))
++ goto failed_read;
++ SQUASHFS_SWAP_IPC_INODE_HEADER(inodep, sinodep);
++ } else
++ if (!squashfs_get_cached_block(s, (char *)
++ inodep, block, offset,
++ sizeof(*inodep), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ if ((i = squashfs_new_inode(s, inodeb)) == NULL)
++ goto failed_read1;
++
++ i->i_nlink = inodep->nlink;
++ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE)
++ ? S_IFIFO : S_IFSOCK;
++ init_special_inode(i, i->i_mode, 0);
++ break;
++ }
++ default:
++ ERROR("Unknown inode type %d in squashfs_iget!\n",
++ inodeb->inode_type);
++ goto failed_read1;
++ }
++
++ insert_inode_hash(i);
++ return i;
++
++failed_read:
++ ERROR("Unable to read inode [%llx:%x]\n", block, offset);
++
++failed_read1:
++ return NULL;
++}
++
++
++static int read_fragment_index_table(struct super_block *s)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++
++ /* Allocate fragment index table */
++ if (!(msblk->fragment_index = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES
++ (sblk->fragments), GFP_KERNEL))) {
++ ERROR("Failed to allocate uid/gid table\n");
++ return 0;
++ }
++
++ if (SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments) &&
++ !squashfs_read_data(s, (char *)
++ msblk->fragment_index,
++ sblk->fragment_table_start,
++ SQUASHFS_FRAGMENT_INDEX_BYTES
++ (sblk->fragments) |
++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
++ ERROR("unable to read fragment index table\n");
++ return 0;
++ }
++
++ if (msblk->swap) {
++ int i;
++ long long fragment;
++
++ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sblk->fragments);
++ i++) {
++ SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment),
++ &msblk->fragment_index[i], 1);
++ msblk->fragment_index[i] = fragment;
++ }
++ }
++
++ return 1;
++}
++
++
++static int supported_squashfs_filesystem(struct squashfs_sb_info *msblk, int silent)
++{
++ struct squashfs_super_block *sblk = &msblk->sblk;
++
++ msblk->iget = squashfs_iget;
++ msblk->read_blocklist = read_blocklist;
++ msblk->read_fragment_index_table = read_fragment_index_table;
++
++ if (sblk->s_major == 1) {
++ if (!squashfs_1_0_supported(msblk)) {
++ SERROR("Major/Minor mismatch, Squashfs 1.0 filesystems "
++ "are unsupported\n");
++ SERROR("Please recompile with "
++ "Squashfs 1.0 support enabled\n");
++ return 0;
++ }
++ } else if (sblk->s_major == 2) {
++ if (!squashfs_2_0_supported(msblk)) {
++ SERROR("Major/Minor mismatch, Squashfs 2.0 filesystems "
++ "are unsupported\n");
++ SERROR("Please recompile with "
++ "Squashfs 2.0 support enabled\n");
++ return 0;
++ }
++ } else if(sblk->s_major != SQUASHFS_MAJOR || sblk->s_minor >
++ SQUASHFS_MINOR) {
++ SERROR("Major/Minor mismatch, trying to mount newer %d.%d "
++ "filesystem\n", sblk->s_major, sblk->s_minor);
++ SERROR("Please update your kernel\n");
++ return 0;
++ }
++
++ return 1;
++}
++
++
++static int squashfs_fill_super(struct super_block *s, void *data, int silent)
++{
++ struct squashfs_sb_info *msblk;
++ struct squashfs_super_block *sblk;
++ int i;
++ char b[BDEVNAME_SIZE];
++ struct inode *root;
++
++ TRACE("Entered squashfs_read_superblock\n");
++
++ if (!(s->s_fs_info = kmalloc(sizeof(struct squashfs_sb_info),
++ GFP_KERNEL))) {
++ ERROR("Failed to allocate superblock\n");
++ goto failure;
++ }
++ memset(s->s_fs_info, 0, sizeof(struct squashfs_sb_info));
++ msblk = s->s_fs_info;
++ sblk = &msblk->sblk;
++
++ msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE);
++ msblk->devblksize_log2 = ffz(~msblk->devblksize);
++
++ init_MUTEX(&msblk->read_data_mutex);
++ init_MUTEX(&msblk->read_page_mutex);
++ init_MUTEX(&msblk->block_cache_mutex);
++ init_MUTEX(&msblk->fragment_mutex);
++ init_MUTEX(&msblk->meta_index_mutex);
++
++ init_waitqueue_head(&msblk->waitq);
++ init_waitqueue_head(&msblk->fragment_wait_queue);
++
++ if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START,
++ sizeof(struct squashfs_super_block) |
++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
++ SERROR("unable to read superblock\n");
++ goto failed_mount;
++ }
++
++ /* Check it is a SQUASHFS superblock */
++ msblk->swap = 0;
++ if ((s->s_magic = sblk->s_magic) != SQUASHFS_MAGIC) {
++ if (sblk->s_magic == SQUASHFS_MAGIC_SWAP) {
++ struct squashfs_super_block ssblk;
++
++ WARNING("Mounting a different endian SQUASHFS "
++ "filesystem on %s\n", bdevname(s->s_bdev, b));
++
++ SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk);
++ memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block));
++ msblk->swap = 1;
++ } else {
++ SERROR("Can't find a SQUASHFS superblock on %s\n",
++ bdevname(s->s_bdev, b));
++ goto failed_mount;
++ }
++ }
++
++ /* Check the MAJOR & MINOR versions */
++ if(!supported_squashfs_filesystem(msblk, silent))
++ goto failed_mount;
++
++ TRACE("Found valid superblock on %s\n", bdevname(s->s_bdev, b));
++ TRACE("Inodes are %scompressed\n",
++ SQUASHFS_UNCOMPRESSED_INODES
++ (sblk->flags) ? "un" : "");
++ TRACE("Data is %scompressed\n",
++ SQUASHFS_UNCOMPRESSED_DATA(sblk->flags)
++ ? "un" : "");
++ TRACE("Check data is %s present in the filesystem\n",
++ SQUASHFS_CHECK_DATA(sblk->flags) ?
++ "" : "not");
++ TRACE("Filesystem size %lld bytes\n", sblk->bytes_used);
++ TRACE("Block size %d\n", sblk->block_size);
++ TRACE("Number of inodes %d\n", sblk->inodes);
++ if (sblk->s_major > 1)
++ TRACE("Number of fragments %d\n", sblk->fragments);
++ TRACE("Number of uids %d\n", sblk->no_uids);
++ TRACE("Number of gids %d\n", sblk->no_guids);
++ TRACE("sblk->inode_table_start %llx\n", sblk->inode_table_start);
++ TRACE("sblk->directory_table_start %llx\n", sblk->directory_table_start);
++ if (sblk->s_major > 1)
++ TRACE("sblk->fragment_table_start %llx\n",
++ sblk->fragment_table_start);
++ TRACE("sblk->uid_start %llx\n", sblk->uid_start);
++
++ s->s_flags |= MS_RDONLY;
++ s->s_op = &squashfs_ops;
++
++ /* Init inode_table block pointer array */
++ if (!(msblk->block_cache = kmalloc(sizeof(struct squashfs_cache) *
++ SQUASHFS_CACHED_BLKS, GFP_KERNEL))) {
++ ERROR("Failed to allocate block cache\n");
++ goto failed_mount;
++ }
++
++ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)
++ msblk->block_cache[i].block = SQUASHFS_INVALID_BLK;
++
++ msblk->next_cache = 0;
++
++ /* Allocate read_data block */
++ msblk->read_size = (sblk->block_size < SQUASHFS_METADATA_SIZE) ?
++ SQUASHFS_METADATA_SIZE :
++ sblk->block_size;
++
++ if (!(msblk->read_data = kmalloc(msblk->read_size, GFP_KERNEL))) {
++ ERROR("Failed to allocate read_data block\n");
++ goto failed_mount;
++ }
++
++ /* Allocate read_page block */
++ if (!(msblk->read_page = kmalloc(sblk->block_size, GFP_KERNEL))) {
++ ERROR("Failed to allocate read_page block\n");
++ goto failed_mount;
++ }
++
++ /* Allocate uid and gid tables */
++ if (!(msblk->uid = kmalloc((sblk->no_uids + sblk->no_guids) *
++ sizeof(unsigned int), GFP_KERNEL))) {
++ ERROR("Failed to allocate uid/gid table\n");
++ goto failed_mount;
++ }
++ msblk->guid = msblk->uid + sblk->no_uids;
++
++ if (msblk->swap) {
++ unsigned int suid[sblk->no_uids + sblk->no_guids];
++
++ if (!squashfs_read_data(s, (char *) &suid, sblk->uid_start,
++ ((sblk->no_uids + sblk->no_guids) *
++ sizeof(unsigned int)) |
++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
++ ERROR("unable to read uid/gid table\n");
++ goto failed_mount;
++ }
++
++ SQUASHFS_SWAP_DATA(msblk->uid, suid, (sblk->no_uids +
++ sblk->no_guids), (sizeof(unsigned int) * 8));
++ } else
++ if (!squashfs_read_data(s, (char *) msblk->uid, sblk->uid_start,
++ ((sblk->no_uids + sblk->no_guids) *
++ sizeof(unsigned int)) |
++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
++ ERROR("unable to read uid/gid table\n");
++ goto failed_mount;
++ }
++
++
++ if (sblk->s_major == 1 && squashfs_1_0_supported(msblk))
++ goto allocate_root;
++
++ if (!(msblk->fragment = kmalloc(sizeof(struct squashfs_fragment_cache) *
++ SQUASHFS_CACHED_FRAGMENTS, GFP_KERNEL))) {
++ ERROR("Failed to allocate fragment block cache\n");
++ goto failed_mount;
++ }
++
++ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) {
++ msblk->fragment[i].locked = 0;
++ msblk->fragment[i].block = SQUASHFS_INVALID_BLK;
++ msblk->fragment[i].data = NULL;
++ }
++
++ msblk->next_fragment = 0;
++
++ /* Allocate fragment index table */
++ if (msblk->read_fragment_index_table(s) == 0)
++ goto failed_mount;
++
++allocate_root:
++ if ((root = (msblk->iget)(s, sblk->root_inode)) == NULL)
++ goto failed_mount;
++
++ if ((s->s_root = d_alloc_root(root)) == NULL) {
++ ERROR("Root inode create failed\n");
++ iput(root);
++ goto failed_mount;
++ }
++
++ TRACE("Leaving squashfs_read_super\n");
++ return 0;
++
++failed_mount:
++ kfree(msblk->fragment_index);
++ kfree(msblk->fragment);
++ kfree(msblk->uid);
++ kfree(msblk->read_page);
++ kfree(msblk->read_data);
++ kfree(msblk->block_cache);
++ kfree(msblk->fragment_index_2);
++ kfree(s->s_fs_info);
++ s->s_fs_info = NULL;
++ return -EINVAL;
++
++failure:
++ return -ENOMEM;
++}
++
++
++static int squashfs_statfs(struct super_block *s, struct kstatfs *buf)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++
++ TRACE("Entered squashfs_statfs\n");
++
++ buf->f_type = SQUASHFS_MAGIC;
++ buf->f_bsize = sblk->block_size;
++ buf->f_blocks = ((sblk->bytes_used - 1) >> sblk->block_log) + 1;
++ buf->f_bfree = buf->f_bavail = 0;
++ buf->f_files = sblk->inodes;
++ buf->f_ffree = 0;
++ buf->f_namelen = SQUASHFS_NAME_LEN;
++
++ return 0;
++}
++
++
++static int squashfs_symlink_readpage(struct file *file, struct page *page)
++{
++ struct inode *inode = page->mapping->host;
++ int index = page->index << PAGE_CACHE_SHIFT, length, bytes;
++ long long block = SQUASHFS_I(inode)->start_block;
++ int offset = SQUASHFS_I(inode)->offset;
++ void *pageaddr = kmap(page);
++
++ TRACE("Entered squashfs_symlink_readpage, page index %ld, start block "
++ "%llx, offset %x\n", page->index,
++ SQUASHFS_I(inode)->start_block,
++ SQUASHFS_I(inode)->offset);
++
++ for (length = 0; length < index; length += bytes) {
++ if (!(bytes = squashfs_get_cached_block(inode->i_sb, NULL,
++ block, offset, PAGE_CACHE_SIZE, &block,
++ &offset))) {
++ ERROR("Unable to read symbolic link [%llx:%x]\n", block,
++ offset);
++ goto skip_read;
++ }
++ }
++
++ if (length != index) {
++ ERROR("(squashfs_symlink_readpage) length != index\n");
++ bytes = 0;
++ goto skip_read;
++ }
++
++ bytes = (i_size_read(inode) - length) > PAGE_CACHE_SIZE ? PAGE_CACHE_SIZE :
++ i_size_read(inode) - length;
++
++ if (!(bytes = squashfs_get_cached_block(inode->i_sb, pageaddr, block,
++ offset, bytes, &block, &offset)))
++ ERROR("Unable to read symbolic link [%llx:%x]\n", block, offset);
++
++skip_read:
++ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
++ kunmap(page);
++ SetPageUptodate(page);
++ unlock_page(page);
++
++ return 0;
++}
++
++
++struct meta_index *locate_meta_index(struct inode *inode, int index, int offset)
++{
++ struct meta_index *meta = NULL;
++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
++ int i;
++
++ down(&msblk->meta_index_mutex);
++
++ TRACE("locate_meta_index: index %d, offset %d\n", index, offset);
++
++ if(msblk->meta_index == NULL)
++ goto not_allocated;
++
++ for (i = 0; i < SQUASHFS_META_NUMBER; i ++)
++ if (msblk->meta_index[i].inode_number == inode->i_ino &&
++ msblk->meta_index[i].offset >= offset &&
++ msblk->meta_index[i].offset <= index &&
++ msblk->meta_index[i].locked == 0) {
++ TRACE("locate_meta_index: entry %d, offset %d\n", i,
++ msblk->meta_index[i].offset);
++ meta = &msblk->meta_index[i];
++ offset = meta->offset;
++ }
++
++ if (meta)
++ meta->locked = 1;
++
++not_allocated:
++ up(&msblk->meta_index_mutex);
++
++ return meta;
++}
++
++
++struct meta_index *empty_meta_index(struct inode *inode, int offset, int skip)
++{
++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
++ struct meta_index *meta = NULL;
++ int i;
++
++ down(&msblk->meta_index_mutex);
++
++ TRACE("empty_meta_index: offset %d, skip %d\n", offset, skip);
++
++ if(msblk->meta_index == NULL) {
++ if (!(msblk->meta_index = kmalloc(sizeof(struct meta_index) *
++ SQUASHFS_META_NUMBER, GFP_KERNEL))) {
++ ERROR("Failed to allocate meta_index\n");
++ goto failed;
++ }
++ for(i = 0; i < SQUASHFS_META_NUMBER; i++) {
++ msblk->meta_index[i].inode_number = 0;
++ msblk->meta_index[i].locked = 0;
++ }
++ msblk->next_meta_index = 0;
++ }
++
++ for(i = SQUASHFS_META_NUMBER; i &&
++ msblk->meta_index[msblk->next_meta_index].locked; i --)
++ msblk->next_meta_index = (msblk->next_meta_index + 1) %
++ SQUASHFS_META_NUMBER;
++
++ if(i == 0) {
++ TRACE("empty_meta_index: failed!\n");
++ goto failed;
++ }
++
++ TRACE("empty_meta_index: returned meta entry %d, %p\n",
++ msblk->next_meta_index,
++ &msblk->meta_index[msblk->next_meta_index]);
++
++ meta = &msblk->meta_index[msblk->next_meta_index];
++ msblk->next_meta_index = (msblk->next_meta_index + 1) %
++ SQUASHFS_META_NUMBER;
++
++ meta->inode_number = inode->i_ino;
++ meta->offset = offset;
++ meta->skip = skip;
++ meta->entries = 0;
++ meta->locked = 1;
++
++failed:
++ up(&msblk->meta_index_mutex);
++ return meta;
++}
++
++
++void release_meta_index(struct inode *inode, struct meta_index *meta)
++{
++ meta->locked = 0;
++}
++
++
++static int read_block_index(struct super_block *s, int blocks, char *block_list,
++ long long *start_block, int *offset)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ unsigned int *block_listp;
++ int block = 0;
++
++ if (msblk->swap) {
++ char sblock_list[blocks << 2];
++
++ if (!squashfs_get_cached_block(s, sblock_list, *start_block,
++ *offset, blocks << 2, start_block, offset)) {
++ ERROR("Unable to read block list [%llx:%x]\n",
++ *start_block, *offset);
++ goto failure;
++ }
++ SQUASHFS_SWAP_INTS(((unsigned int *)block_list),
++ ((unsigned int *)sblock_list), blocks);
++ } else
++ if (!squashfs_get_cached_block(s, block_list, *start_block,
++ *offset, blocks << 2, start_block, offset)) {
++ ERROR("Unable to read block list [%llx:%x]\n",
++ *start_block, *offset);
++ goto failure;
++ }
++
++ for (block_listp = (unsigned int *) block_list; blocks;
++ block_listp++, blocks --)
++ block += SQUASHFS_COMPRESSED_SIZE_BLOCK(*block_listp);
++
++ return block;
++
++failure:
++ return -1;
++}
++
++
++#define SIZE 256
++
++static inline int calculate_skip(int blocks) {
++ int skip = (blocks - 1) / ((SQUASHFS_SLOTS * SQUASHFS_META_ENTRIES + 1) * SQUASHFS_META_INDEXES);
++ return skip >= 7 ? 7 : skip + 1;
++}
++
++
++static int get_meta_index(struct inode *inode, int index,
++ long long *index_block, int *index_offset,
++ long long *data_block, char *block_list)
++{
++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++ int skip = calculate_skip(i_size_read(inode) >> sblk->block_log);
++ int offset = 0;
++ struct meta_index *meta;
++ struct meta_entry *meta_entry;
++ long long cur_index_block = SQUASHFS_I(inode)->u.s1.block_list_start;
++ int cur_offset = SQUASHFS_I(inode)->offset;
++ long long cur_data_block = SQUASHFS_I(inode)->start_block;
++ int i;
++
++ index /= SQUASHFS_META_INDEXES * skip;
++
++ while ( offset < index ) {
++ meta = locate_meta_index(inode, index, offset + 1);
++
++ if (meta == NULL) {
++ if ((meta = empty_meta_index(inode, offset + 1,
++ skip)) == NULL)
++ goto all_done;
++ } else {
++ offset = index < meta->offset + meta->entries ? index :
++ meta->offset + meta->entries - 1;
++ meta_entry = &meta->meta_entry[offset - meta->offset];
++ cur_index_block = meta_entry->index_block + sblk->inode_table_start;
++ cur_offset = meta_entry->offset;
++ cur_data_block = meta_entry->data_block;
++ TRACE("get_meta_index: offset %d, meta->offset %d, "
++ "meta->entries %d\n", offset, meta->offset,
++ meta->entries);
++ TRACE("get_meta_index: index_block 0x%llx, offset 0x%x"
++ " data_block 0x%llx\n", cur_index_block,
++ cur_offset, cur_data_block);
++ }
++
++ for (i = meta->offset + meta->entries; i <= index &&
++ i < meta->offset + SQUASHFS_META_ENTRIES; i++) {
++ int blocks = skip * SQUASHFS_META_INDEXES;
++
++ while (blocks) {
++ int block = blocks > (SIZE >> 2) ? (SIZE >> 2) :
++ blocks;
++ int res = read_block_index(inode->i_sb, block,
++ block_list, &cur_index_block,
++ &cur_offset);
++
++ if (res == -1)
++ goto failed;
++
++ cur_data_block += res;
++ blocks -= block;
++ }
++
++ meta_entry = &meta->meta_entry[i - meta->offset];
++ meta_entry->index_block = cur_index_block - sblk->inode_table_start;
++ meta_entry->offset = cur_offset;
++ meta_entry->data_block = cur_data_block;
++ meta->entries ++;
++ offset ++;
++ }
++
++ TRACE("get_meta_index: meta->offset %d, meta->entries %d\n",
++ meta->offset, meta->entries);
++
++ release_meta_index(inode, meta);
++ }
++
++all_done:
++ *index_block = cur_index_block;
++ *index_offset = cur_offset;
++ *data_block = cur_data_block;
++
++ return offset * SQUASHFS_META_INDEXES * skip;
++
++failed:
++ release_meta_index(inode, meta);
++ return -1;
++}
++
++
++static long long read_blocklist(struct inode *inode, int index,
++ int readahead_blks, char *block_list,
++ unsigned short **block_p, unsigned int *bsize)
++{
++ long long block_ptr;
++ int offset;
++ long long block;
++ int res = get_meta_index(inode, index, &block_ptr, &offset, &block,
++ block_list);
++
++ TRACE("read_blocklist: res %d, index %d, block_ptr 0x%llx, offset"
++ " 0x%x, block 0x%llx\n", res, index, block_ptr, offset,
++ block);
++
++ if(res == -1)
++ goto failure;
++
++ index -= res;
++
++ while ( index ) {
++ int blocks = index > (SIZE >> 2) ? (SIZE >> 2) : index;
++ int res = read_block_index(inode->i_sb, blocks, block_list,
++ &block_ptr, &offset);
++ if (res == -1)
++ goto failure;
++ block += res;
++ index -= blocks;
++ }
++
++ if (read_block_index(inode->i_sb, 1, block_list,
++ &block_ptr, &offset) == -1)
++ goto failure;
++ *bsize = *((unsigned int *) block_list);
++
++ return block;
++
++failure:
++ return 0;
++}
++
++
++static int squashfs_readpage(struct file *file, struct page *page)
++{
++ struct inode *inode = page->mapping->host;
++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++ unsigned char block_list[SIZE];
++ long long block;
++ unsigned int bsize, i = 0, bytes = 0, byte_offset = 0;
++ int index = page->index >> (sblk->block_log - PAGE_CACHE_SHIFT);
++ void *pageaddr;
++ struct squashfs_fragment_cache *fragment = NULL;
++ char *data_ptr = msblk->read_page;
++
++ int mask = (1 << (sblk->block_log - PAGE_CACHE_SHIFT)) - 1;
++ int start_index = page->index & ~mask;
++ int end_index = start_index | mask;
++
++ TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n",
++ page->index,
++ SQUASHFS_I(inode)->start_block);
++
++ if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
++ PAGE_CACHE_SHIFT))
++ goto skip_read;
++
++ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
++ || index < (i_size_read(inode) >>
++ sblk->block_log)) {
++ if ((block = (msblk->read_blocklist)(inode, index, 1,
++ block_list, NULL, &bsize)) == 0)
++ goto skip_read;
++
++ down(&msblk->read_page_mutex);
++
++ if (!(bytes = squashfs_read_data(inode->i_sb, msblk->read_page,
++ block, bsize, NULL))) {
++ ERROR("Unable to read page, block %llx, size %x\n", block,
++ bsize);
++ up(&msblk->read_page_mutex);
++ goto skip_read;
++ }
++ } else {
++ if ((fragment = get_cached_fragment(inode->i_sb,
++ SQUASHFS_I(inode)->
++ u.s1.fragment_start_block,
++ SQUASHFS_I(inode)->u.s1.fragment_size))
++ == NULL) {
++ ERROR("Unable to read page, block %llx, size %x\n",
++ SQUASHFS_I(inode)->
++ u.s1.fragment_start_block,
++ (int) SQUASHFS_I(inode)->
++ u.s1.fragment_size);
++ goto skip_read;
++ }
++ bytes = SQUASHFS_I(inode)->u.s1.fragment_offset +
++ (i_size_read(inode) & (sblk->block_size
++ - 1));
++ byte_offset = SQUASHFS_I(inode)->u.s1.fragment_offset;
++ data_ptr = fragment->data;
++ }
++
++ for (i = start_index; i <= end_index && byte_offset < bytes;
++ i++, byte_offset += PAGE_CACHE_SIZE) {
++ struct page *push_page;
++ int available_bytes = (bytes - byte_offset) > PAGE_CACHE_SIZE ?
++ PAGE_CACHE_SIZE : bytes - byte_offset;
++
++ TRACE("bytes %d, i %d, byte_offset %d, available_bytes %d\n",
++ bytes, i, byte_offset, available_bytes);
++
++ if (i == page->index) {
++ pageaddr = kmap_atomic(page, KM_USER0);
++ memcpy(pageaddr, data_ptr + byte_offset,
++ available_bytes);
++ memset(pageaddr + available_bytes, 0,
++ PAGE_CACHE_SIZE - available_bytes);
++ kunmap_atomic(pageaddr, KM_USER0);
++ flush_dcache_page(page);
++ SetPageUptodate(page);
++ unlock_page(page);
++ } else if ((push_page =
++ grab_cache_page_nowait(page->mapping, i))) {
++ pageaddr = kmap_atomic(push_page, KM_USER0);
++
++ memcpy(pageaddr, data_ptr + byte_offset,
++ available_bytes);
++ memset(pageaddr + available_bytes, 0,
++ PAGE_CACHE_SIZE - available_bytes);
++ kunmap_atomic(pageaddr, KM_USER0);
++ flush_dcache_page(push_page);
++ SetPageUptodate(push_page);
++ unlock_page(push_page);
++ page_cache_release(push_page);
++ }
++ }
++
++ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
++ || index < (i_size_read(inode) >>
++ sblk->block_log))
++ up(&msblk->read_page_mutex);
++ else
++ release_cached_fragment(msblk, fragment);
++
++ return 0;
++
++skip_read:
++ pageaddr = kmap_atomic(page, KM_USER0);
++ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
++ kunmap_atomic(pageaddr, KM_USER0);
++ flush_dcache_page(page);
++ SetPageUptodate(page);
++ unlock_page(page);
++
++ return 0;
++}
++
++
++static int squashfs_readpage4K(struct file *file, struct page *page)
++{
++ struct inode *inode = page->mapping->host;
++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++ unsigned char block_list[SIZE];
++ long long block;
++ unsigned int bsize, bytes = 0;
++ void *pageaddr;
++
++ TRACE("Entered squashfs_readpage4K, page index %lx, start block %llx\n",
++ page->index,
++ SQUASHFS_I(inode)->start_block);
++
++ if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
++ PAGE_CACHE_SHIFT)) {
++ pageaddr = kmap_atomic(page, KM_USER0);
++ goto skip_read;
++ }
++
++ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
++ || page->index < (i_size_read(inode) >>
++ sblk->block_log)) {
++ block = (msblk->read_blocklist)(inode, page->index, 1,
++ block_list, NULL, &bsize);
++
++ down(&msblk->read_page_mutex);
++ bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block,
++ bsize, NULL);
++ pageaddr = kmap_atomic(page, KM_USER0);
++ if (bytes)
++ memcpy(pageaddr, msblk->read_page, bytes);
++ else
++ ERROR("Unable to read page, block %llx, size %x\n",
++ block, bsize);
++ up(&msblk->read_page_mutex);
++ } else {
++ struct squashfs_fragment_cache *fragment =
++ get_cached_fragment(inode->i_sb,
++ SQUASHFS_I(inode)->
++ u.s1.fragment_start_block,
++ SQUASHFS_I(inode)-> u.s1.fragment_size);
++ pageaddr = kmap_atomic(page, KM_USER0);
++ if (fragment) {
++ bytes = i_size_read(inode) & (sblk->block_size - 1);
++ memcpy(pageaddr, fragment->data + SQUASHFS_I(inode)->
++ u.s1.fragment_offset, bytes);
++ release_cached_fragment(msblk, fragment);
++ } else
++ ERROR("Unable to read page, block %llx, size %x\n",
++ SQUASHFS_I(inode)->
++ u.s1.fragment_start_block, (int)
++ SQUASHFS_I(inode)-> u.s1.fragment_size);
++ }
++
++skip_read:
++ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
++ kunmap_atomic(pageaddr, KM_USER0);
++ flush_dcache_page(page);
++ SetPageUptodate(page);
++ unlock_page(page);
++
++ return 0;
++}
++
++
++static int get_dir_index_using_offset(struct super_block *s, long long
++ *next_block, unsigned int *next_offset,
++ long long index_start,
++ unsigned int index_offset, int i_count,
++ long long f_pos)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++ int i, length = 0;
++ struct squashfs_dir_index index;
++
++ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n",
++ i_count, (unsigned int) f_pos);
++
++ f_pos =- 3;
++ if (f_pos == 0)
++ goto finish;
++
++ for (i = 0; i < i_count; i++) {
++ if (msblk->swap) {
++ struct squashfs_dir_index sindex;
++ squashfs_get_cached_block(s, (char *) &sindex,
++ index_start, index_offset,
++ sizeof(sindex), &index_start,
++ &index_offset);
++ SQUASHFS_SWAP_DIR_INDEX(&index, &sindex);
++ } else
++ squashfs_get_cached_block(s, (char *) &index,
++ index_start, index_offset,
++ sizeof(index), &index_start,
++ &index_offset);
++
++ if (index.index > f_pos)
++ break;
++
++ squashfs_get_cached_block(s, NULL, index_start, index_offset,
++ index.size + 1, &index_start,
++ &index_offset);
++
++ length = index.index;
++ *next_block = index.start_block + sblk->directory_table_start;
++ }
++
++ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
++
++finish:
++ return length + 3;
++}
++
++
++static int get_dir_index_using_name(struct super_block *s, long long
++ *next_block, unsigned int *next_offset,
++ long long index_start,
++ unsigned int index_offset, int i_count,
++ const char *name, int size)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++ int i, length = 0;
++ char buffer[sizeof(struct squashfs_dir_index) + SQUASHFS_NAME_LEN + 1];
++ struct squashfs_dir_index *index = (struct squashfs_dir_index *) buffer;
++ char str[SQUASHFS_NAME_LEN + 1];
++
++ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
++
++ strncpy(str, name, size);
++ str[size] = '\0';
++
++ for (i = 0; i < i_count; i++) {
++ if (msblk->swap) {
++ struct squashfs_dir_index sindex;
++ squashfs_get_cached_block(s, (char *) &sindex,
++ index_start, index_offset,
++ sizeof(sindex), &index_start,
++ &index_offset);
++ SQUASHFS_SWAP_DIR_INDEX(index, &sindex);
++ } else
++ squashfs_get_cached_block(s, (char *) index,
++ index_start, index_offset,
++ sizeof(struct squashfs_dir_index),
++ &index_start, &index_offset);
++
++ squashfs_get_cached_block(s, index->name, index_start,
++ index_offset, index->size + 1,
++ &index_start, &index_offset);
++
++ index->name[index->size + 1] = '\0';
++
++ if (strcmp(index->name, str) > 0)
++ break;
++
++ length = index->index;
++ *next_block = index->start_block + sblk->directory_table_start;
++ }
++
++ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
++ return length + 3;
++}
++
++
++static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir)
++{
++ struct inode *i = file->f_dentry->d_inode;
++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++ long long next_block = SQUASHFS_I(i)->start_block +
++ sblk->directory_table_start;
++ int next_offset = SQUASHFS_I(i)->offset, length = 0, dirs_read = 0,
++ dir_count;
++ struct squashfs_dir_header dirh;
++ char buffer[sizeof(struct squashfs_dir_entry) + SQUASHFS_NAME_LEN + 1];
++ struct squashfs_dir_entry *dire = (struct squashfs_dir_entry *) buffer;
++
++ TRACE("Entered squashfs_readdir [%llx:%x]\n", next_block, next_offset);
++
++ while(file->f_pos < 3) {
++ char *name;
++ int size, i_ino;
++
++ if(file->f_pos == 0) {
++ name = ".";
++ size = 1;
++ i_ino = i->i_ino;
++ } else {
++ name = "..";
++ size = 2;
++ i_ino = SQUASHFS_I(i)->u.s2.parent_inode;
++ }
++ TRACE("Calling filldir(%x, %s, %d, %d, %d, %d)\n",
++ (unsigned int) dirent, name, size, (int)
++ file->f_pos, i_ino,
++ squashfs_filetype_table[1]);
++
++ if (filldir(dirent, name, size,
++ file->f_pos, i_ino,
++ squashfs_filetype_table[1]) < 0) {
++ TRACE("Filldir returned less than 0\n");
++ goto finish;
++ }
++ file->f_pos += size;
++ dirs_read++;
++ }
++
++ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset,
++ SQUASHFS_I(i)->u.s2.directory_index_start,
++ SQUASHFS_I(i)->u.s2.directory_index_offset,
++ SQUASHFS_I(i)->u.s2.directory_index_count,
++ file->f_pos);
++
++ while (length < i_size_read(i)) {
++ /* read directory header */
++ if (msblk->swap) {
++ struct squashfs_dir_header sdirh;
++
++ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
++ next_block, next_offset, sizeof(sdirh),
++ &next_block, &next_offset))
++ goto failed_read;
++
++ length += sizeof(sdirh);
++ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh);
++ } else {
++ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
++ next_block, next_offset, sizeof(dirh),
++ &next_block, &next_offset))
++ goto failed_read;
++
++ length += sizeof(dirh);
++ }
++
++ dir_count = dirh.count + 1;
++ while (dir_count--) {
++ if (msblk->swap) {
++ struct squashfs_dir_entry sdire;
++ if (!squashfs_get_cached_block(i->i_sb, (char *)
++ &sdire, next_block, next_offset,
++ sizeof(sdire), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ length += sizeof(sdire);
++ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire);
++ } else {
++ if (!squashfs_get_cached_block(i->i_sb, (char *)
++ dire, next_block, next_offset,
++ sizeof(*dire), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ length += sizeof(*dire);
++ }
++
++ if (!squashfs_get_cached_block(i->i_sb, dire->name,
++ next_block, next_offset,
++ dire->size + 1, &next_block,
++ &next_offset))
++ goto failed_read;
++
++ length += dire->size + 1;
++
++ if (file->f_pos >= length)
++ continue;
++
++ dire->name[dire->size + 1] = '\0';
++
++ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d, %d)\n",
++ (unsigned int) dirent, dire->name,
++ dire->size + 1, (int) file->f_pos,
++ dirh.start_block, dire->offset,
++ dirh.inode_number + dire->inode_number,
++ squashfs_filetype_table[dire->type]);
++
++ if (filldir(dirent, dire->name, dire->size + 1,
++ file->f_pos,
++ dirh.inode_number + dire->inode_number,
++ squashfs_filetype_table[dire->type])
++ < 0) {
++ TRACE("Filldir returned less than 0\n");
++ goto finish;
++ }
++ file->f_pos = length;
++ dirs_read++;
++ }
++ }
++
++finish:
++ return dirs_read;
++
++failed_read:
++ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
++ next_offset);
++ return 0;
++}
++
++
++static struct dentry *squashfs_lookup(struct inode *i, struct dentry *dentry,
++ struct nameidata *nd)
++{
++ const unsigned char *name = dentry->d_name.name;
++ int len = dentry->d_name.len;
++ struct inode *inode = NULL;
++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++ long long next_block = SQUASHFS_I(i)->start_block +
++ sblk->directory_table_start;
++ int next_offset = SQUASHFS_I(i)->offset, length = 0,
++ dir_count;
++ struct squashfs_dir_header dirh;
++ char buffer[sizeof(struct squashfs_dir_entry) + SQUASHFS_NAME_LEN];
++ struct squashfs_dir_entry *dire = (struct squashfs_dir_entry *) buffer;
++
++ TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset);
++
++ if (len > SQUASHFS_NAME_LEN)
++ goto exit_loop;
++
++ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset,
++ SQUASHFS_I(i)->u.s2.directory_index_start,
++ SQUASHFS_I(i)->u.s2.directory_index_offset,
++ SQUASHFS_I(i)->u.s2.directory_index_count, name,
++ len);
++
++ while (length < i_size_read(i)) {
++ /* read directory header */
++ if (msblk->swap) {
++ struct squashfs_dir_header sdirh;
++ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
++ next_block, next_offset, sizeof(sdirh),
++ &next_block, &next_offset))
++ goto failed_read;
++
++ length += sizeof(sdirh);
++ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh);
++ } else {
++ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
++ next_block, next_offset, sizeof(dirh),
++ &next_block, &next_offset))
++ goto failed_read;
++
++ length += sizeof(dirh);
++ }
++
++ dir_count = dirh.count + 1;
++ while (dir_count--) {
++ if (msblk->swap) {
++ struct squashfs_dir_entry sdire;
++ if (!squashfs_get_cached_block(i->i_sb, (char *)
++ &sdire, next_block,next_offset,
++ sizeof(sdire), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ length += sizeof(sdire);
++ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire);
++ } else {
++ if (!squashfs_get_cached_block(i->i_sb, (char *)
++ dire, next_block,next_offset,
++ sizeof(*dire), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ length += sizeof(*dire);
++ }
++
++ if (!squashfs_get_cached_block(i->i_sb, dire->name,
++ next_block, next_offset, dire->size + 1,
++ &next_block, &next_offset))
++ goto failed_read;
++
++ length += dire->size + 1;
++
++ if (name[0] < dire->name[0])
++ goto exit_loop;
++
++ if ((len == dire->size + 1) && !strncmp(name,
++ dire->name, len)) {
++ squashfs_inode_t ino =
++ SQUASHFS_MKINODE(dirh.start_block,
++ dire->offset);
++
++ TRACE("calling squashfs_iget for directory "
++ "entry %s, inode %x:%x, %d\n", name,
++ dirh.start_block, dire->offset,
++ dirh.inode_number + dire->inode_number);
++
++ inode = (msblk->iget)(i->i_sb, ino);
++
++ goto exit_loop;
++ }
++ }
++ }
++
++exit_loop:
++ d_add(dentry, inode);
++ return ERR_PTR(0);
++
++failed_read:
++ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
++ next_offset);
++ goto exit_loop;
++}
++
++
++static void squashfs_put_super(struct super_block *s)
++{
++ int i;
++
++ if (s->s_fs_info) {
++ struct squashfs_sb_info *sbi = s->s_fs_info;
++ if (sbi->block_cache)
++ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)
++ if (sbi->block_cache[i].block !=
++ SQUASHFS_INVALID_BLK)
++ kfree(sbi->block_cache[i].data);
++ if (sbi->fragment)
++ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++)
++ SQUASHFS_FREE(sbi->fragment[i].data);
++ kfree(sbi->fragment);
++ kfree(sbi->block_cache);
++ kfree(sbi->read_data);
++ kfree(sbi->read_page);
++ kfree(sbi->uid);
++ kfree(sbi->fragment_index);
++ kfree(sbi->fragment_index_2);
++ kfree(sbi->meta_index);
++ kfree(s->s_fs_info);
++ s->s_fs_info = NULL;
++ }
++}
++
++
++static struct super_block *squashfs_get_sb(struct file_system_type *fs_type,
++ int flags, const char *dev_name, void *data)
++{
++ return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super);
++}
++
++
++static int __init init_squashfs_fs(void)
++{
++ int err = init_inodecache();
++ if (err)
++ goto out;
++
++ printk(KERN_INFO "squashfs: version 3.0 (2006/03/15) "
++ "Phillip Lougher\n");
++
++ if (!(stream.workspace = vmalloc(zlib_inflate_workspacesize()))) {
++ ERROR("Failed to allocate zlib workspace\n");
++ destroy_inodecache();
++ err = -ENOMEM;
++ goto out;
++ }
++
++ if ((err = register_filesystem(&squashfs_fs_type))) {
++ vfree(stream.workspace);
++ destroy_inodecache();
++ }
++
++out:
++ return err;
++}
++
++
++static void __exit exit_squashfs_fs(void)
++{
++ vfree(stream.workspace);
++ unregister_filesystem(&squashfs_fs_type);
++ destroy_inodecache();
++}
++
++
++static kmem_cache_t * squashfs_inode_cachep;
++
++
++static struct inode *squashfs_alloc_inode(struct super_block *sb)
++{
++ struct squashfs_inode_info *ei;
++ ei = kmem_cache_alloc(squashfs_inode_cachep, SLAB_KERNEL);
++ if (!ei)
++ return NULL;
++ return &ei->vfs_inode;
++}
++
++
++static void squashfs_destroy_inode(struct inode *inode)
++{
++ kmem_cache_free(squashfs_inode_cachep, SQUASHFS_I(inode));
++}
++
++
++static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
++{
++ struct squashfs_inode_info *ei = foo;
++
++ if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
++ SLAB_CTOR_CONSTRUCTOR)
++ inode_init_once(&ei->vfs_inode);
++}
++
++
++static int __init init_inodecache(void)
++{
++ squashfs_inode_cachep = kmem_cache_create("squashfs_inode_cache",
++ sizeof(struct squashfs_inode_info),
++ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
++ init_once, NULL);
++ if (squashfs_inode_cachep == NULL)
++ return -ENOMEM;
++ return 0;
++}
++
++
++static void destroy_inodecache(void)
++{
++ if (kmem_cache_destroy(squashfs_inode_cachep))
++ printk(KERN_INFO "squashfs_inode_cache: not all structures "
++ "were freed\n");
++}
++
++
++module_init(init_squashfs_fs);
++module_exit(exit_squashfs_fs);
++MODULE_DESCRIPTION("squashfs, a compressed read-only filesystem");
++MODULE_AUTHOR("Phillip Lougher <phillip@lougher.org.uk>");
++MODULE_LICENSE("GPL");
+diff --new-file -urp linux-2.6.15/fs/squashfs/Makefile linux-2.6.15-squashfs3.0/fs/squashfs/Makefile
+--- linux-2.6.15/fs/squashfs/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-squashfs3.0/fs/squashfs/Makefile 2006-03-07 21:12:37.000000000 +0000
+@@ -0,0 +1,7 @@
++#
++# Makefile for the linux squashfs routines.
++#
++
++obj-$(CONFIG_SQUASHFS) += squashfs.o
++squashfs-y += inode.o
++squashfs-y += squashfs2_0.o
+diff --new-file -urp linux-2.6.15/fs/squashfs/squashfs2_0.c linux-2.6.15-squashfs3.0/fs/squashfs/squashfs2_0.c
+--- linux-2.6.15/fs/squashfs/squashfs2_0.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-squashfs3.0/fs/squashfs/squashfs2_0.c 2006-03-07 21:12:37.000000000 +0000
+@@ -0,0 +1,758 @@
++/*
++ * Squashfs - a compressed read only filesystem for Linux
++ *
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006
++ * Phillip Lougher <phillip@lougher.org.uk>
++ *
++ * 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.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ *
++ * squashfs2_0.c
++ */
++
++#include <linux/types.h>
++#include <linux/squashfs_fs.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/smp_lock.h>
++#include <linux/slab.h>
++#include <linux/squashfs_fs_sb.h>
++#include <linux/squashfs_fs_i.h>
++#include <linux/buffer_head.h>
++#include <linux/vfs.h>
++#include <linux/init.h>
++#include <linux/dcache.h>
++#include <linux/wait.h>
++#include <linux/zlib.h>
++#include <linux/blkdev.h>
++#include <linux/vmalloc.h>
++#include <asm/uaccess.h>
++#include <asm/semaphore.h>
++
++#include "squashfs.h"
++static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir);
++static struct dentry *squashfs_lookup_2(struct inode *, struct dentry *,
++ struct nameidata *);
++
++static struct file_operations squashfs_dir_ops_2 = {
++ .read = generic_read_dir,
++ .readdir = squashfs_readdir_2
++};
++
++static struct inode_operations squashfs_dir_inode_ops_2 = {
++ .lookup = squashfs_lookup_2
++};
++
++static unsigned char squashfs_filetype_table[] = {
++ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
++};
++
++static int read_fragment_index_table_2(struct super_block *s)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++
++ if (!(msblk->fragment_index_2 = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES_2
++ (sblk->fragments), GFP_KERNEL))) {
++ ERROR("Failed to allocate uid/gid table\n");
++ return 0;
++ }
++
++ if (SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments) &&
++ !squashfs_read_data(s, (char *)
++ msblk->fragment_index_2,
++ sblk->fragment_table_start,
++ SQUASHFS_FRAGMENT_INDEX_BYTES_2
++ (sblk->fragments) |
++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) {
++ ERROR("unable to read fragment index table\n");
++ return 0;
++ }
++
++ if (msblk->swap) {
++ int i;
++ unsigned int fragment;
++
++ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES_2(sblk->fragments);
++ i++) {
++ SQUASHFS_SWAP_FRAGMENT_INDEXES_2((&fragment),
++ &msblk->fragment_index_2[i], 1);
++ msblk->fragment_index_2[i] = fragment;
++ }
++ }
++
++ return 1;
++}
++
++
++static int get_fragment_location_2(struct super_block *s, unsigned int fragment,
++ long long *fragment_start_block,
++ unsigned int *fragment_size)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ long long start_block =
++ msblk->fragment_index_2[SQUASHFS_FRAGMENT_INDEX_2(fragment)];
++ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET_2(fragment);
++ struct squashfs_fragment_entry_2 fragment_entry;
++
++ if (msblk->swap) {
++ struct squashfs_fragment_entry_2 sfragment_entry;
++
++ if (!squashfs_get_cached_block(s, (char *) &sfragment_entry,
++ start_block, offset,
++ sizeof(sfragment_entry), &start_block,
++ &offset))
++ goto out;
++ SQUASHFS_SWAP_FRAGMENT_ENTRY_2(&fragment_entry, &sfragment_entry);
++ } else
++ if (!squashfs_get_cached_block(s, (char *) &fragment_entry,
++ start_block, offset,
++ sizeof(fragment_entry), &start_block,
++ &offset))
++ goto out;
++
++ *fragment_start_block = fragment_entry.start_block;
++ *fragment_size = fragment_entry.size;
++
++ return 1;
++
++out:
++ return 0;
++}
++
++
++static struct inode *squashfs_new_inode(struct super_block *s,
++ struct squashfs_base_inode_header_2 *inodeb, unsigned int ino)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++ struct inode *i = new_inode(s);
++
++ if (i) {
++ i->i_ino = ino;
++ i->i_mtime.tv_sec = sblk->mkfs_time;
++ i->i_atime.tv_sec = sblk->mkfs_time;
++ i->i_ctime.tv_sec = sblk->mkfs_time;
++ i->i_uid = msblk->uid[inodeb->uid];
++ i->i_mode = inodeb->mode;
++ i->i_nlink = 1;
++ i->i_size = 0;
++ if (inodeb->guid == SQUASHFS_GUIDS)
++ i->i_gid = i->i_uid;
++ else
++ i->i_gid = msblk->guid[inodeb->guid];
++ }
++
++ return i;
++}
++
++
++static struct inode *squashfs_iget_2(struct super_block *s, squashfs_inode_t inode)
++{
++ struct inode *i;
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++ unsigned int block = SQUASHFS_INODE_BLK(inode) +
++ sblk->inode_table_start;
++ unsigned int offset = SQUASHFS_INODE_OFFSET(inode);
++ unsigned int ino = SQUASHFS_MK_VFS_INODE(block
++ - sblk->inode_table_start, offset);
++ long long next_block;
++ unsigned int next_offset;
++ union squashfs_inode_header_2 id, sid;
++ struct squashfs_base_inode_header_2 *inodeb = &id.base,
++ *sinodeb = &sid.base;
++
++ TRACE("Entered squashfs_iget\n");
++
++ if (msblk->swap) {
++ if (!squashfs_get_cached_block(s, (char *) sinodeb, block,
++ offset, sizeof(*sinodeb), &next_block,
++ &next_offset))
++ goto failed_read;
++ SQUASHFS_SWAP_BASE_INODE_HEADER_2(inodeb, sinodeb,
++ sizeof(*sinodeb));
++ } else
++ if (!squashfs_get_cached_block(s, (char *) inodeb, block,
++ offset, sizeof(*inodeb), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ switch(inodeb->inode_type) {
++ case SQUASHFS_FILE_TYPE: {
++ struct squashfs_reg_inode_header_2 *inodep = &id.reg;
++ struct squashfs_reg_inode_header_2 *sinodep = &sid.reg;
++ long long frag_blk;
++ unsigned int frag_size;
++
++ if (msblk->swap) {
++ if (!squashfs_get_cached_block(s, (char *)
++ sinodep, block, offset,
++ sizeof(*sinodep), &next_block,
++ &next_offset))
++ goto failed_read;
++ SQUASHFS_SWAP_REG_INODE_HEADER_2(inodep, sinodep);
++ } else
++ if (!squashfs_get_cached_block(s, (char *)
++ inodep, block, offset,
++ sizeof(*inodep), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ frag_blk = SQUASHFS_INVALID_BLK;
++ if (inodep->fragment != SQUASHFS_INVALID_FRAG &&
++ !get_fragment_location_2(s,
++ inodep->fragment, &frag_blk, &frag_size))
++ goto failed_read;
++
++ if((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
++ goto failed_read1;
++
++ i->i_size = inodep->file_size;
++ i->i_fop = &generic_ro_fops;
++ i->i_mode |= S_IFREG;
++ i->i_mtime.tv_sec = inodep->mtime;
++ i->i_atime.tv_sec = inodep->mtime;
++ i->i_ctime.tv_sec = inodep->mtime;
++ i->i_blocks = ((i->i_size - 1) >> 9) + 1;
++ i->i_blksize = PAGE_CACHE_SIZE;
++ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
++ SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
++ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
++ SQUASHFS_I(i)->start_block = inodep->start_block;
++ SQUASHFS_I(i)->u.s1.block_list_start = next_block;
++ SQUASHFS_I(i)->offset = next_offset;
++ if (sblk->block_size > 4096)
++ i->i_data.a_ops = &squashfs_aops;
++ else
++ i->i_data.a_ops = &squashfs_aops_4K;
++
++ TRACE("File inode %x:%x, start_block %x, "
++ "block_list_start %llx, offset %x\n",
++ SQUASHFS_INODE_BLK(inode), offset,
++ inodep->start_block, next_block,
++ next_offset);
++ break;
++ }
++ case SQUASHFS_DIR_TYPE: {
++ struct squashfs_dir_inode_header_2 *inodep = &id.dir;
++ struct squashfs_dir_inode_header_2 *sinodep = &sid.dir;
++
++ if (msblk->swap) {
++ if (!squashfs_get_cached_block(s, (char *)
++ sinodep, block, offset,
++ sizeof(*sinodep), &next_block,
++ &next_offset))
++ goto failed_read;
++ SQUASHFS_SWAP_DIR_INODE_HEADER_2(inodep, sinodep);
++ } else
++ if (!squashfs_get_cached_block(s, (char *)
++ inodep, block, offset,
++ sizeof(*inodep), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ if((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
++ goto failed_read1;
++
++ i->i_size = inodep->file_size;
++ i->i_op = &squashfs_dir_inode_ops_2;
++ i->i_fop = &squashfs_dir_ops_2;
++ i->i_mode |= S_IFDIR;
++ i->i_mtime.tv_sec = inodep->mtime;
++ i->i_atime.tv_sec = inodep->mtime;
++ i->i_ctime.tv_sec = inodep->mtime;
++ SQUASHFS_I(i)->start_block = inodep->start_block;
++ SQUASHFS_I(i)->offset = inodep->offset;
++ SQUASHFS_I(i)->u.s2.directory_index_count = 0;
++ SQUASHFS_I(i)->u.s2.parent_inode = 0;
++
++ TRACE("Directory inode %x:%x, start_block %x, offset "
++ "%x\n", SQUASHFS_INODE_BLK(inode),
++ offset, inodep->start_block,
++ inodep->offset);
++ break;
++ }
++ case SQUASHFS_LDIR_TYPE: {
++ struct squashfs_ldir_inode_header_2 *inodep = &id.ldir;
++ struct squashfs_ldir_inode_header_2 *sinodep = &sid.ldir;
++
++ if (msblk->swap) {
++ if (!squashfs_get_cached_block(s, (char *)
++ sinodep, block, offset,
++ sizeof(*sinodep), &next_block,
++ &next_offset))
++ goto failed_read;
++ SQUASHFS_SWAP_LDIR_INODE_HEADER_2(inodep,
++ sinodep);
++ } else
++ if (!squashfs_get_cached_block(s, (char *)
++ inodep, block, offset,
++ sizeof(*inodep), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ if((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
++ goto failed_read1;
++
++ i->i_size = inodep->file_size;
++ i->i_op = &squashfs_dir_inode_ops_2;
++ i->i_fop = &squashfs_dir_ops_2;
++ i->i_mode |= S_IFDIR;
++ i->i_mtime.tv_sec = inodep->mtime;
++ i->i_atime.tv_sec = inodep->mtime;
++ i->i_ctime.tv_sec = inodep->mtime;
++ SQUASHFS_I(i)->start_block = inodep->start_block;
++ SQUASHFS_I(i)->offset = inodep->offset;
++ SQUASHFS_I(i)->u.s2.directory_index_start = next_block;
++ SQUASHFS_I(i)->u.s2.directory_index_offset =
++ next_offset;
++ SQUASHFS_I(i)->u.s2.directory_index_count =
++ inodep->i_count;
++ SQUASHFS_I(i)->u.s2.parent_inode = 0;
++
++ TRACE("Long directory inode %x:%x, start_block %x, "
++ "offset %x\n",
++ SQUASHFS_INODE_BLK(inode), offset,
++ inodep->start_block, inodep->offset);
++ break;
++ }
++ case SQUASHFS_SYMLINK_TYPE: {
++ struct squashfs_symlink_inode_header_2 *inodep =
++ &id.symlink;
++ struct squashfs_symlink_inode_header_2 *sinodep =
++ &sid.symlink;
++
++ if (msblk->swap) {
++ if (!squashfs_get_cached_block(s, (char *)
++ sinodep, block, offset,
++ sizeof(*sinodep), &next_block,
++ &next_offset))
++ goto failed_read;
++ SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(inodep,
++ sinodep);
++ } else
++ if (!squashfs_get_cached_block(s, (char *)
++ inodep, block, offset,
++ sizeof(*inodep), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ if((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
++ goto failed_read1;
++
++ i->i_size = inodep->symlink_size;
++ i->i_op = &page_symlink_inode_operations;
++ i->i_data.a_ops = &squashfs_symlink_aops;
++ i->i_mode |= S_IFLNK;
++ SQUASHFS_I(i)->start_block = next_block;
++ SQUASHFS_I(i)->offset = next_offset;
++
++ TRACE("Symbolic link inode %x:%x, start_block %llx, "
++ "offset %x\n",
++ SQUASHFS_INODE_BLK(inode), offset,
++ next_block, next_offset);
++ break;
++ }
++ case SQUASHFS_BLKDEV_TYPE:
++ case SQUASHFS_CHRDEV_TYPE: {
++ struct squashfs_dev_inode_header_2 *inodep = &id.dev;
++ struct squashfs_dev_inode_header_2 *sinodep = &sid.dev;
++
++ if (msblk->swap) {
++ if (!squashfs_get_cached_block(s, (char *)
++ sinodep, block, offset,
++ sizeof(*sinodep), &next_block,
++ &next_offset))
++ goto failed_read;
++ SQUASHFS_SWAP_DEV_INODE_HEADER_2(inodep, sinodep);
++ } else
++ if (!squashfs_get_cached_block(s, (char *)
++ inodep, block, offset,
++ sizeof(*inodep), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ if ((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
++ goto failed_read1;
++
++ i->i_mode |= (inodeb->inode_type ==
++ SQUASHFS_CHRDEV_TYPE) ? S_IFCHR :
++ S_IFBLK;
++ init_special_inode(i, i->i_mode,
++ old_decode_dev(inodep->rdev));
++
++ TRACE("Device inode %x:%x, rdev %x\n",
++ SQUASHFS_INODE_BLK(inode), offset,
++ inodep->rdev);
++ break;
++ }
++ case SQUASHFS_FIFO_TYPE:
++ case SQUASHFS_SOCKET_TYPE: {
++ if ((i = squashfs_new_inode(s, inodeb, ino)) == NULL)
++ goto failed_read1;
++
++ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE)
++ ? S_IFIFO : S_IFSOCK;
++ init_special_inode(i, i->i_mode, 0);
++ break;
++ }
++ default:
++ ERROR("Unknown inode type %d in squashfs_iget!\n",
++ inodeb->inode_type);
++ goto failed_read1;
++ }
++
++ insert_inode_hash(i);
++ return i;
++
++failed_read:
++ ERROR("Unable to read inode [%x:%x]\n", block, offset);
++
++failed_read1:
++ return NULL;
++}
++
++
++static int get_dir_index_using_offset(struct super_block *s, long long
++ *next_block, unsigned int *next_offset,
++ long long index_start,
++ unsigned int index_offset, int i_count,
++ long long f_pos)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++ int i, length = 0;
++ struct squashfs_dir_index_2 index;
++
++ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n",
++ i_count, (unsigned int) f_pos);
++
++ if (f_pos == 0)
++ goto finish;
++
++ for (i = 0; i < i_count; i++) {
++ if (msblk->swap) {
++ struct squashfs_dir_index_2 sindex;
++ squashfs_get_cached_block(s, (char *) &sindex,
++ index_start, index_offset,
++ sizeof(sindex), &index_start,
++ &index_offset);
++ SQUASHFS_SWAP_DIR_INDEX_2(&index, &sindex);
++ } else
++ squashfs_get_cached_block(s, (char *) &index,
++ index_start, index_offset,
++ sizeof(index), &index_start,
++ &index_offset);
++
++ if (index.index > f_pos)
++ break;
++
++ squashfs_get_cached_block(s, NULL, index_start, index_offset,
++ index.size + 1, &index_start,
++ &index_offset);
++
++ length = index.index;
++ *next_block = index.start_block + sblk->directory_table_start;
++ }
++
++ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
++
++finish:
++ return length;
++}
++
++
++static int get_dir_index_using_name(struct super_block *s, long long
++ *next_block, unsigned int *next_offset,
++ long long index_start,
++ unsigned int index_offset, int i_count,
++ const char *name, int size)
++{
++ struct squashfs_sb_info *msblk = s->s_fs_info;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++ int i, length = 0;
++ char buffer[sizeof(struct squashfs_dir_index_2) + SQUASHFS_NAME_LEN + 1];
++ struct squashfs_dir_index_2 *index = (struct squashfs_dir_index_2 *) buffer;
++ char str[SQUASHFS_NAME_LEN + 1];
++
++ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
++
++ strncpy(str, name, size);
++ str[size] = '\0';
++
++ for (i = 0; i < i_count; i++) {
++ if (msblk->swap) {
++ struct squashfs_dir_index_2 sindex;
++ squashfs_get_cached_block(s, (char *) &sindex,
++ index_start, index_offset,
++ sizeof(sindex), &index_start,
++ &index_offset);
++ SQUASHFS_SWAP_DIR_INDEX_2(index, &sindex);
++ } else
++ squashfs_get_cached_block(s, (char *) index,
++ index_start, index_offset,
++ sizeof(struct squashfs_dir_index_2),
++ &index_start, &index_offset);
++
++ squashfs_get_cached_block(s, index->name, index_start,
++ index_offset, index->size + 1,
++ &index_start, &index_offset);
++
++ index->name[index->size + 1] = '\0';
++
++ if (strcmp(index->name, str) > 0)
++ break;
++
++ length = index->index;
++ *next_block = index->start_block + sblk->directory_table_start;
++ }
++
++ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
++ return length;
++}
++
++
++static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir)
++{
++ struct inode *i = file->f_dentry->d_inode;
++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++ long long next_block = SQUASHFS_I(i)->start_block +
++ sblk->directory_table_start;
++ int next_offset = SQUASHFS_I(i)->offset, length = 0, dirs_read = 0,
++ dir_count;
++ struct squashfs_dir_header_2 dirh;
++ char buffer[sizeof(struct squashfs_dir_entry_2) + SQUASHFS_NAME_LEN + 1];
++ struct squashfs_dir_entry_2 *dire = (struct squashfs_dir_entry_2 *) buffer;
++
++ TRACE("Entered squashfs_readdir_2 [%llx:%x]\n", next_block, next_offset);
++
++ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset,
++ SQUASHFS_I(i)->u.s2.directory_index_start,
++ SQUASHFS_I(i)->u.s2.directory_index_offset,
++ SQUASHFS_I(i)->u.s2.directory_index_count,
++ file->f_pos);
++
++ while (length < i_size_read(i)) {
++ /* read directory header */
++ if (msblk->swap) {
++ struct squashfs_dir_header_2 sdirh;
++
++ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
++ next_block, next_offset, sizeof(sdirh),
++ &next_block, &next_offset))
++ goto failed_read;
++
++ length += sizeof(sdirh);
++ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh);
++ } else {
++ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
++ next_block, next_offset, sizeof(dirh),
++ &next_block, &next_offset))
++ goto failed_read;
++
++ length += sizeof(dirh);
++ }
++
++ dir_count = dirh.count + 1;
++ while (dir_count--) {
++ if (msblk->swap) {
++ struct squashfs_dir_entry_2 sdire;
++ if (!squashfs_get_cached_block(i->i_sb, (char *)
++ &sdire, next_block, next_offset,
++ sizeof(sdire), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ length += sizeof(sdire);
++ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire);
++ } else {
++ if (!squashfs_get_cached_block(i->i_sb, (char *)
++ dire, next_block, next_offset,
++ sizeof(*dire), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ length += sizeof(*dire);
++ }
++
++ if (!squashfs_get_cached_block(i->i_sb, dire->name,
++ next_block, next_offset,
++ dire->size + 1, &next_block,
++ &next_offset))
++ goto failed_read;
++
++ length += dire->size + 1;
++
++ if (file->f_pos >= length)
++ continue;
++
++ dire->name[dire->size + 1] = '\0';
++
++ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d)\n",
++ (unsigned int) dirent, dire->name,
++ dire->size + 1, (int) file->f_pos,
++ dirh.start_block, dire->offset,
++ squashfs_filetype_table[dire->type]);
++
++ if (filldir(dirent, dire->name, dire->size + 1,
++ file->f_pos, SQUASHFS_MK_VFS_INODE(
++ dirh.start_block, dire->offset),
++ squashfs_filetype_table[dire->type])
++ < 0) {
++ TRACE("Filldir returned less than 0\n");
++ goto finish;
++ }
++ file->f_pos = length;
++ dirs_read++;
++ }
++ }
++
++finish:
++ return dirs_read;
++
++failed_read:
++ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
++ next_offset);
++ return 0;
++}
++
++
++static struct dentry *squashfs_lookup_2(struct inode *i, struct dentry *dentry,
++ struct nameidata *nd)
++{
++ const unsigned char *name = dentry->d_name.name;
++ int len = dentry->d_name.len;
++ struct inode *inode = NULL;
++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
++ struct squashfs_super_block *sblk = &msblk->sblk;
++ long long next_block = SQUASHFS_I(i)->start_block +
++ sblk->directory_table_start;
++ int next_offset = SQUASHFS_I(i)->offset, length = 0,
++ dir_count;
++ struct squashfs_dir_header_2 dirh;
++ char buffer[sizeof(struct squashfs_dir_entry_2) + SQUASHFS_NAME_LEN];
++ struct squashfs_dir_entry_2 *dire = (struct squashfs_dir_entry_2 *) buffer;
++ int sorted = sblk->s_major == 2 && sblk->s_minor >= 1;
++
++ TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset);
++
++ if (len > SQUASHFS_NAME_LEN)
++ goto exit_loop;
++
++ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset,
++ SQUASHFS_I(i)->u.s2.directory_index_start,
++ SQUASHFS_I(i)->u.s2.directory_index_offset,
++ SQUASHFS_I(i)->u.s2.directory_index_count, name,
++ len);
++
++ while (length < i_size_read(i)) {
++ /* read directory header */
++ if (msblk->swap) {
++ struct squashfs_dir_header_2 sdirh;
++ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
++ next_block, next_offset, sizeof(sdirh),
++ &next_block, &next_offset))
++ goto failed_read;
++
++ length += sizeof(sdirh);
++ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh);
++ } else {
++ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
++ next_block, next_offset, sizeof(dirh),
++ &next_block, &next_offset))
++ goto failed_read;
++
++ length += sizeof(dirh);
++ }
++
++ dir_count = dirh.count + 1;
++ while (dir_count--) {
++ if (msblk->swap) {
++ struct squashfs_dir_entry_2 sdire;
++ if (!squashfs_get_cached_block(i->i_sb, (char *)
++ &sdire, next_block,next_offset,
++ sizeof(sdire), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ length += sizeof(sdire);
++ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire);
++ } else {
++ if (!squashfs_get_cached_block(i->i_sb, (char *)
++ dire, next_block,next_offset,
++ sizeof(*dire), &next_block,
++ &next_offset))
++ goto failed_read;
++
++ length += sizeof(*dire);
++ }
++
++ if (!squashfs_get_cached_block(i->i_sb, dire->name,
++ next_block, next_offset, dire->size + 1,
++ &next_block, &next_offset))
++ goto failed_read;
++
++ length += dire->size + 1;
++
++ if (sorted && name[0] < dire->name[0])
++ goto exit_loop;
++
++ if ((len == dire->size + 1) && !strncmp(name,
++ dire->name, len)) {
++ squashfs_inode_t ino =
++ SQUASHFS_MKINODE(dirh.start_block,
++ dire->offset);
++
++ TRACE("calling squashfs_iget for directory "
++ "entry %s, inode %x:%x, %lld\n", name,
++ dirh.start_block, dire->offset, ino);
++
++ inode = (msblk->iget)(i->i_sb, ino);
++
++ goto exit_loop;
++ }
++ }
++ }
++
++exit_loop:
++ d_add(dentry, inode);
++ return ERR_PTR(0);
++
++failed_read:
++ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
++ next_offset);
++ goto exit_loop;
++}
++
++
++int squashfs_2_0_supported(struct squashfs_sb_info *msblk)
++{
++ struct squashfs_super_block *sblk = &msblk->sblk;
++
++ msblk->iget = squashfs_iget_2;
++ msblk->read_fragment_index_table = read_fragment_index_table_2;
++
++ sblk->bytes_used = sblk->bytes_used_2;
++ sblk->uid_start = sblk->uid_start_2;
++ sblk->guid_start = sblk->guid_start_2;
++ sblk->inode_table_start = sblk->inode_table_start_2;
++ sblk->directory_table_start = sblk->directory_table_start_2;
++ sblk->fragment_table_start = sblk->fragment_table_start_2;
++
++ return 1;
++}
+diff --new-file -urp linux-2.6.15/fs/squashfs/squashfs.h linux-2.6.15-squashfs3.0/fs/squashfs/squashfs.h
+--- linux-2.6.15/fs/squashfs/squashfs.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-squashfs3.0/fs/squashfs/squashfs.h 2006-03-07 21:12:37.000000000 +0000
+@@ -0,0 +1,86 @@
++/*
++ * Squashfs - a compressed read only filesystem for Linux
++ *
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006
++ * Phillip Lougher <phillip@lougher.org.uk>
++ *
++ * 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.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ *
++ * squashfs.h
++ */
++
++#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
++#undef CONFIG_SQUASHFS_1_0_COMPATIBILITY
++#endif
++
++#ifdef SQUASHFS_TRACE
++#define TRACE(s, args...) printk(KERN_NOTICE "SQUASHFS: "s, ## args)
++#else
++#define TRACE(s, args...) {}
++#endif
++
++#define ERROR(s, args...) printk(KERN_ERR "SQUASHFS error: "s, ## args)
++
++#define SERROR(s, args...) do { \
++ if (!silent) \
++ printk(KERN_ERR "SQUASHFS error: "s, ## args);\
++ } while(0)
++
++#define WARNING(s, args...) printk(KERN_WARNING "SQUASHFS: "s, ## args)
++
++static inline struct squashfs_inode_info *SQUASHFS_I(struct inode *inode)
++{
++ return list_entry(inode, struct squashfs_inode_info, vfs_inode);
++}
++
++#if defined(CONFIG_SQUASHFS_1_0_COMPATIBILITY ) || defined(CONFIG_SQUASHFS_2_0_COMPATIBILITY)
++#define SQSH_EXTERN
++extern unsigned int squashfs_read_data(struct super_block *s, char *buffer,
++ long long index, unsigned int length,
++ long long *next_index);
++extern int squashfs_get_cached_block(struct super_block *s, char *buffer,
++ long long block, unsigned int offset,
++ int length, long long *next_block,
++ unsigned int *next_offset);
++extern void release_cached_fragment(struct squashfs_sb_info *msblk, struct
++ squashfs_fragment_cache *fragment);
++extern struct squashfs_fragment_cache *get_cached_fragment(struct super_block
++ *s, long long start_block,
++ int length);
++extern struct address_space_operations squashfs_symlink_aops;
++extern struct address_space_operations squashfs_aops;
++extern struct address_space_operations squashfs_aops_4K;
++extern struct inode_operations squashfs_dir_inode_ops;
++#else
++#define SQSH_EXTERN static
++#endif
++
++#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
++extern int squashfs_1_0_supported(struct squashfs_sb_info *msblk);
++#else
++static inline int squashfs_1_0_supported(struct squashfs_sb_info *msblk)
++{
++ return 0;
++}
++#endif
++
++#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
++extern int squashfs_2_0_supported(struct squashfs_sb_info *msblk);
++#else
++static inline int squashfs_2_0_supported(struct squashfs_sb_info *msblk)
++{
++ return 0;
++}
++#endif
+diff --new-file -urp linux-2.6.15/include/linux/squashfs_fs.h linux-2.6.15-squashfs3.0/include/linux/squashfs_fs.h
+--- linux-2.6.15/include/linux/squashfs_fs.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-squashfs3.0/include/linux/squashfs_fs.h 2006-03-07 21:12:37.000000000 +0000
+@@ -0,0 +1,911 @@
++#ifndef SQUASHFS_FS
++#define SQUASHFS_FS
++
++/*
++ * Squashfs
++ *
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006
++ * Phillip Lougher <phillip@lougher.org.uk>
++ *
++ * 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.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ *
++ * squashfs_fs.h
++ */
++
++#ifndef CONFIG_SQUASHFS_2_0_COMPATIBILITY
++#define CONFIG_SQUASHFS_2_0_COMPATIBILITY
++#endif
++
++#ifdef CONFIG_SQUASHFS_VMALLOC
++#define SQUASHFS_ALLOC(a) vmalloc(a)
++#define SQUASHFS_FREE(a) vfree(a)
++#else
++#define SQUASHFS_ALLOC(a) kmalloc(a, GFP_KERNEL)
++#define SQUASHFS_FREE(a) kfree(a)
++#endif
++#define SQUASHFS_CACHED_FRAGMENTS CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE
++#define SQUASHFS_MAJOR 3
++#define SQUASHFS_MINOR 0
++#define SQUASHFS_MAGIC 0x73717368
++#define SQUASHFS_MAGIC_SWAP 0x68737173
++#define SQUASHFS_START 0
++
++/* size of metadata (inode and directory) blocks */
++#define SQUASHFS_METADATA_SIZE 8192
++#define SQUASHFS_METADATA_LOG 13
++
++/* default size of data blocks */
++#define SQUASHFS_FILE_SIZE 65536
++#define SQUASHFS_FILE_LOG 16
++
++#define SQUASHFS_FILE_MAX_SIZE 65536
++
++/* Max number of uids and gids */
++#define SQUASHFS_UIDS 256
++#define SQUASHFS_GUIDS 255
++
++/* Max length of filename (not 255) */
++#define SQUASHFS_NAME_LEN 256
++
++#define SQUASHFS_INVALID ((long long) 0xffffffffffff)
++#define SQUASHFS_INVALID_FRAG ((unsigned int) 0xffffffff)
++#define SQUASHFS_INVALID_BLK ((long long) -1)
++#define SQUASHFS_USED_BLK ((long long) -2)
++
++/* Filesystem flags */
++#define SQUASHFS_NOI 0
++#define SQUASHFS_NOD 1
++#define SQUASHFS_CHECK 2
++#define SQUASHFS_NOF 3
++#define SQUASHFS_NO_FRAG 4
++#define SQUASHFS_ALWAYS_FRAG 5
++#define SQUASHFS_DUPLICATE 6
++
++#define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1)
++
++#define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, \
++ SQUASHFS_NOI)
++
++#define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, \
++ SQUASHFS_NOD)
++
++#define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
++ SQUASHFS_NOF)
++
++#define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
++ SQUASHFS_NO_FRAG)
++
++#define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
++ SQUASHFS_ALWAYS_FRAG)
++
++#define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, \
++ SQUASHFS_DUPLICATE)
++
++#define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, \
++ SQUASHFS_CHECK)
++
++#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \
++ duplicate_checking) (noi | (nod << 1) | (check_data << 2) \
++ | (nof << 3) | (no_frag << 4) | (always_frag << 5) | \
++ (duplicate_checking << 6))
++
++/* Max number of types and file types */
++#define SQUASHFS_DIR_TYPE 1
++#define SQUASHFS_FILE_TYPE 2
++#define SQUASHFS_SYMLINK_TYPE 3
++#define SQUASHFS_BLKDEV_TYPE 4
++#define SQUASHFS_CHRDEV_TYPE 5
++#define SQUASHFS_FIFO_TYPE 6
++#define SQUASHFS_SOCKET_TYPE 7
++#define SQUASHFS_LDIR_TYPE 8
++#define SQUASHFS_LREG_TYPE 9
++
++/* 1.0 filesystem type definitions */
++#define SQUASHFS_TYPES 5
++#define SQUASHFS_IPC_TYPE 0
++
++/* Flag whether block is compressed or uncompressed, bit is set if block is
++ * uncompressed */
++#define SQUASHFS_COMPRESSED_BIT (1 << 15)
++
++#define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \
++ (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT)
++
++#define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT))
++
++#define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24)
++
++#define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) (((B) & \
++ ~SQUASHFS_COMPRESSED_BIT_BLOCK) ? (B) & \
++ ~SQUASHFS_COMPRESSED_BIT_BLOCK : SQUASHFS_COMPRESSED_BIT_BLOCK)
++
++#define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK))
++
++/*
++ * Inode number ops. Inodes consist of a compressed block number, and an
++ * uncompressed offset within that block
++ */
++#define SQUASHFS_INODE_BLK(a) ((unsigned int) ((a) >> 16))
++
++#define SQUASHFS_INODE_OFFSET(a) ((unsigned int) ((a) & 0xffff))
++
++#define SQUASHFS_MKINODE(A, B) ((squashfs_inode_t)(((squashfs_inode_t) (A)\
++ << 16) + (B)))
++
++/* Compute 32 bit VFS inode number from squashfs inode number */
++#define SQUASHFS_MK_VFS_INODE(a, b) ((unsigned int) (((a) << 8) + \
++ ((b) >> 2) + 1))
++/* XXX */
++
++/* Translate between VFS mode and squashfs mode */
++#define SQUASHFS_MODE(a) ((a) & 0xfff)
++
++/* fragment and fragment table defines */
++#define SQUASHFS_FRAGMENT_BYTES(A) (A * sizeof(struct squashfs_fragment_entry))
++
++#define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / \
++ SQUASHFS_METADATA_SIZE)
++
++#define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % \
++ SQUASHFS_METADATA_SIZE)
++
++#define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + \
++ SQUASHFS_METADATA_SIZE - 1) / \
++ SQUASHFS_METADATA_SIZE)
++
++#define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) *\
++ sizeof(long long))
++
++/* cached data constants for filesystem */
++#define SQUASHFS_CACHED_BLKS 8
++
++#define SQUASHFS_MAX_FILE_SIZE_LOG 64
++
++#define SQUASHFS_MAX_FILE_SIZE ((long long) 1 << \
++ (SQUASHFS_MAX_FILE_SIZE_LOG - 2))
++
++#define SQUASHFS_MARKER_BYTE 0xff
++
++/* meta index cache */
++#define SQUASHFS_META_INDEXES (SQUASHFS_METADATA_SIZE / sizeof(unsigned int))
++#define SQUASHFS_META_ENTRIES 31
++#define SQUASHFS_META_NUMBER 8
++#define SQUASHFS_SLOTS 4
++
++struct meta_entry {
++ long long data_block;
++ unsigned int index_block;
++ unsigned short offset;
++ unsigned short pad;
++};
++
++struct meta_index {
++ unsigned int inode_number;
++ unsigned int offset;
++ unsigned short entries;
++ unsigned short skip;
++ unsigned short locked;
++ unsigned short pad;
++ struct meta_entry meta_entry[SQUASHFS_META_ENTRIES];
++};
++
++
++/*
++ * definitions for structures on disk
++ */
++
++typedef long long squashfs_block_t;
++typedef long long squashfs_inode_t;
++
++struct squashfs_super_block {
++ unsigned int s_magic;
++ unsigned int inodes;
++ unsigned int bytes_used_2;
++ unsigned int uid_start_2;
++ unsigned int guid_start_2;
++ unsigned int inode_table_start_2;
++ unsigned int directory_table_start_2;
++ unsigned int s_major:16;
++ unsigned int s_minor:16;
++ unsigned int block_size_1:16;
++ unsigned int block_log:16;
++ unsigned int flags:8;
++ unsigned int no_uids:8;
++ unsigned int no_guids:8;
++ unsigned int mkfs_time /* time of filesystem creation */;
++ squashfs_inode_t root_inode;
++ unsigned int block_size;
++ unsigned int fragments;
++ unsigned int fragment_table_start_2;
++ long long bytes_used;
++ long long uid_start;
++ long long guid_start;
++ long long inode_table_start;
++ long long directory_table_start;
++ long long fragment_table_start;
++ long long unused;
++} __attribute__ ((packed));
++
++struct squashfs_dir_index {
++ unsigned int index;
++ unsigned int start_block;
++ unsigned char size;
++ unsigned char name[0];
++} __attribute__ ((packed));
++
++#define SQUASHFS_BASE_INODE_HEADER \
++ unsigned int inode_type:4; \
++ unsigned int mode:12; \
++ unsigned int uid:8; \
++ unsigned int guid:8; \
++ unsigned int mtime; \
++ unsigned int inode_number;
++
++struct squashfs_base_inode_header {
++ SQUASHFS_BASE_INODE_HEADER;
++} __attribute__ ((packed));
++
++struct squashfs_ipc_inode_header {
++ SQUASHFS_BASE_INODE_HEADER;
++ unsigned int nlink;
++} __attribute__ ((packed));
++
++struct squashfs_dev_inode_header {
++ SQUASHFS_BASE_INODE_HEADER;
++ unsigned int nlink;
++ unsigned short rdev;
++} __attribute__ ((packed));
++
++struct squashfs_symlink_inode_header {
++ SQUASHFS_BASE_INODE_HEADER;
++ unsigned int nlink;
++ unsigned short symlink_size;
++ char symlink[0];
++} __attribute__ ((packed));
++
++struct squashfs_reg_inode_header {
++ SQUASHFS_BASE_INODE_HEADER;
++ squashfs_block_t start_block;
++ unsigned int fragment;
++ unsigned int offset;
++ unsigned int file_size;
++ unsigned short block_list[0];
++} __attribute__ ((packed));
++
++struct squashfs_lreg_inode_header {
++ SQUASHFS_BASE_INODE_HEADER;
++ unsigned int nlink;
++ squashfs_block_t start_block;
++ unsigned int fragment;
++ unsigned int offset;
++ long long file_size;
++ unsigned short block_list[0];
++} __attribute__ ((packed));
++
++struct squashfs_dir_inode_header {
++ SQUASHFS_BASE_INODE_HEADER;
++ unsigned int nlink;
++ unsigned int file_size:19;
++ unsigned int offset:13;
++ unsigned int start_block;
++ unsigned int parent_inode;
++} __attribute__ ((packed));
++
++struct squashfs_ldir_inode_header {
++ SQUASHFS_BASE_INODE_HEADER;
++ unsigned int nlink;
++ unsigned int file_size:27;
++ unsigned int offset:13;
++ unsigned int start_block;
++ unsigned int i_count:16;
++ unsigned int parent_inode;
++ struct squashfs_dir_index index[0];
++} __attribute__ ((packed));
++
++union squashfs_inode_header {
++ struct squashfs_base_inode_header base;
++ struct squashfs_dev_inode_header dev;
++ struct squashfs_symlink_inode_header symlink;
++ struct squashfs_reg_inode_header reg;
++ struct squashfs_lreg_inode_header lreg;
++ struct squashfs_dir_inode_header dir;
++ struct squashfs_ldir_inode_header ldir;
++ struct squashfs_ipc_inode_header ipc;
++};
++
++struct squashfs_dir_entry {
++ unsigned int offset:13;
++ unsigned int type:3;
++ unsigned int size:8;
++ int inode_number:16;
++ char name[0];
++} __attribute__ ((packed));
++
++struct squashfs_dir_header {
++ unsigned int count:8;
++ unsigned int start_block;
++ unsigned int inode_number;
++} __attribute__ ((packed));
++
++struct squashfs_fragment_entry {
++ long long start_block;
++ unsigned int size;
++ unsigned int unused;
++} __attribute__ ((packed));
++
++extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen);
++extern int squashfs_uncompress_init(void);
++extern int squashfs_uncompress_exit(void);
++
++/*
++ * macros to convert each packed bitfield structure from little endian to big
++ * endian and vice versa. These are needed when creating or using a filesystem
++ * on a machine with different byte ordering to the target architecture.
++ *
++ */
++
++#define SQUASHFS_SWAP_START \
++ int bits;\
++ int b_pos;\
++ unsigned long long val;\
++ unsigned char *s;\
++ unsigned char *d;
++
++#define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_super_block));\
++ SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\
++ SQUASHFS_SWAP((s)->inodes, d, 32, 32);\
++ SQUASHFS_SWAP((s)->bytes_used_2, d, 64, 32);\
++ SQUASHFS_SWAP((s)->uid_start_2, d, 96, 32);\
++ SQUASHFS_SWAP((s)->guid_start_2, d, 128, 32);\
++ SQUASHFS_SWAP((s)->inode_table_start_2, d, 160, 32);\
++ SQUASHFS_SWAP((s)->directory_table_start_2, d, 192, 32);\
++ SQUASHFS_SWAP((s)->s_major, d, 224, 16);\
++ SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\
++ SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\
++ SQUASHFS_SWAP((s)->block_log, d, 272, 16);\
++ SQUASHFS_SWAP((s)->flags, d, 288, 8);\
++ SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\
++ SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\
++ SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\
++ SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\
++ SQUASHFS_SWAP((s)->block_size, d, 408, 32);\
++ SQUASHFS_SWAP((s)->fragments, d, 440, 32);\
++ SQUASHFS_SWAP((s)->fragment_table_start_2, d, 472, 32);\
++ SQUASHFS_SWAP((s)->bytes_used, d, 504, 64);\
++ SQUASHFS_SWAP((s)->uid_start, d, 568, 64);\
++ SQUASHFS_SWAP((s)->guid_start, d, 632, 64);\
++ SQUASHFS_SWAP((s)->inode_table_start, d, 696, 64);\
++ SQUASHFS_SWAP((s)->directory_table_start, d, 760, 64);\
++ SQUASHFS_SWAP((s)->fragment_table_start, d, 824, 64);\
++ SQUASHFS_SWAP((s)->unused, d, 888, 64);\
++}
++
++#define SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
++ SQUASHFS_MEMSET(s, d, n);\
++ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
++ SQUASHFS_SWAP((s)->mode, d, 4, 12);\
++ SQUASHFS_SWAP((s)->uid, d, 16, 8);\
++ SQUASHFS_SWAP((s)->guid, d, 24, 8);\
++ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
++ SQUASHFS_SWAP((s)->inode_number, d, 64, 32);
++
++#define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
++}
++
++#define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
++ sizeof(struct squashfs_ipc_inode_header))\
++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
++}
++
++#define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
++ sizeof(struct squashfs_dev_inode_header)); \
++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
++ SQUASHFS_SWAP((s)->rdev, d, 128, 16);\
++}
++
++#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
++ sizeof(struct squashfs_symlink_inode_header));\
++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
++ SQUASHFS_SWAP((s)->symlink_size, d, 128, 16);\
++}
++
++#define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
++ sizeof(struct squashfs_reg_inode_header));\
++ SQUASHFS_SWAP((s)->start_block, d, 96, 64);\
++ SQUASHFS_SWAP((s)->fragment, d, 160, 32);\
++ SQUASHFS_SWAP((s)->offset, d, 192, 32);\
++ SQUASHFS_SWAP((s)->file_size, d, 224, 32);\
++}
++
++#define SQUASHFS_SWAP_LREG_INODE_HEADER(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
++ sizeof(struct squashfs_lreg_inode_header));\
++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
++ SQUASHFS_SWAP((s)->start_block, d, 128, 64);\
++ SQUASHFS_SWAP((s)->fragment, d, 192, 32);\
++ SQUASHFS_SWAP((s)->offset, d, 224, 32);\
++ SQUASHFS_SWAP((s)->file_size, d, 256, 64);\
++}
++
++#define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
++ sizeof(struct squashfs_dir_inode_header));\
++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
++ SQUASHFS_SWAP((s)->file_size, d, 128, 19);\
++ SQUASHFS_SWAP((s)->offset, d, 147, 13);\
++ SQUASHFS_SWAP((s)->start_block, d, 160, 32);\
++ SQUASHFS_SWAP((s)->parent_inode, d, 192, 32);\
++}
++
++#define SQUASHFS_SWAP_LDIR_INODE_HEADER(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
++ sizeof(struct squashfs_ldir_inode_header));\
++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
++ SQUASHFS_SWAP((s)->file_size, d, 128, 27);\
++ SQUASHFS_SWAP((s)->offset, d, 155, 13);\
++ SQUASHFS_SWAP((s)->start_block, d, 168, 32);\
++ SQUASHFS_SWAP((s)->i_count, d, 200, 16);\
++ SQUASHFS_SWAP((s)->parent_inode, d, 216, 32);\
++}
++
++#define SQUASHFS_SWAP_DIR_INDEX(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index));\
++ SQUASHFS_SWAP((s)->index, d, 0, 32);\
++ SQUASHFS_SWAP((s)->start_block, d, 32, 32);\
++ SQUASHFS_SWAP((s)->size, d, 64, 8);\
++}
++
++#define SQUASHFS_SWAP_DIR_HEADER(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header));\
++ SQUASHFS_SWAP((s)->count, d, 0, 8);\
++ SQUASHFS_SWAP((s)->start_block, d, 8, 32);\
++ SQUASHFS_SWAP((s)->inode_number, d, 40, 32);\
++}
++
++#define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry));\
++ SQUASHFS_SWAP((s)->offset, d, 0, 13);\
++ SQUASHFS_SWAP((s)->type, d, 13, 3);\
++ SQUASHFS_SWAP((s)->size, d, 16, 8);\
++ SQUASHFS_SWAP((s)->inode_number, d, 24, 16);\
++}
++
++#define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry));\
++ SQUASHFS_SWAP((s)->start_block, d, 0, 64);\
++ SQUASHFS_SWAP((s)->size, d, 64, 32);\
++}
++
++#define SQUASHFS_SWAP_SHORTS(s, d, n) {\
++ int entry;\
++ int bit_position;\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_MEMSET(s, d, n * 2);\
++ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
++ 16)\
++ SQUASHFS_SWAP(s[entry], d, bit_position, 16);\
++}
++
++#define SQUASHFS_SWAP_INTS(s, d, n) {\
++ int entry;\
++ int bit_position;\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_MEMSET(s, d, n * 4);\
++ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
++ 32)\
++ SQUASHFS_SWAP(s[entry], d, bit_position, 32);\
++}
++
++#define SQUASHFS_SWAP_LONG_LONGS(s, d, n) {\
++ int entry;\
++ int bit_position;\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_MEMSET(s, d, n * 8);\
++ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
++ 64)\
++ SQUASHFS_SWAP(s[entry], d, bit_position, 64);\
++}
++
++#define SQUASHFS_SWAP_DATA(s, d, n, bits) {\
++ int entry;\
++ int bit_position;\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_MEMSET(s, d, n * bits / 8);\
++ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
++ bits)\
++ SQUASHFS_SWAP(s[entry], d, bit_position, bits);\
++}
++
++#define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n)
++
++#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
++
++struct squashfs_base_inode_header_1 {
++ unsigned int inode_type:4;
++ unsigned int mode:12; /* protection */
++ unsigned int uid:4; /* index into uid table */
++ unsigned int guid:4; /* index into guid table */
++} __attribute__ ((packed));
++
++struct squashfs_ipc_inode_header_1 {
++ unsigned int inode_type:4;
++ unsigned int mode:12; /* protection */
++ unsigned int uid:4; /* index into uid table */
++ unsigned int guid:4; /* index into guid table */
++ unsigned int type:4;
++ unsigned int offset:4;
++} __attribute__ ((packed));
++
++struct squashfs_dev_inode_header_1 {
++ unsigned int inode_type:4;
++ unsigned int mode:12; /* protection */
++ unsigned int uid:4; /* index into uid table */
++ unsigned int guid:4; /* index into guid table */
++ unsigned short rdev;
++} __attribute__ ((packed));
++
++struct squashfs_symlink_inode_header_1 {
++ unsigned int inode_type:4;
++ unsigned int mode:12; /* protection */
++ unsigned int uid:4; /* index into uid table */
++ unsigned int guid:4; /* index into guid table */
++ unsigned short symlink_size;
++ char symlink[0];
++} __attribute__ ((packed));
++
++struct squashfs_reg_inode_header_1 {
++ unsigned int inode_type:4;
++ unsigned int mode:12; /* protection */
++ unsigned int uid:4; /* index into uid table */
++ unsigned int guid:4; /* index into guid table */
++ unsigned int mtime;
++ unsigned int start_block;
++ unsigned int file_size:32;
++ unsigned short block_list[0];
++} __attribute__ ((packed));
++
++struct squashfs_dir_inode_header_1 {
++ unsigned int inode_type:4;
++ unsigned int mode:12; /* protection */
++ unsigned int uid:4; /* index into uid table */
++ unsigned int guid:4; /* index into guid table */
++ unsigned int file_size:19;
++ unsigned int offset:13;
++ unsigned int mtime;
++ unsigned int start_block:24;
++} __attribute__ ((packed));
++
++#define SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n) \
++ SQUASHFS_MEMSET(s, d, n);\
++ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
++ SQUASHFS_SWAP((s)->mode, d, 4, 12);\
++ SQUASHFS_SWAP((s)->uid, d, 16, 4);\
++ SQUASHFS_SWAP((s)->guid, d, 20, 4);
++
++#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n)\
++}
++
++#define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
++ sizeof(struct squashfs_ipc_inode_header_1));\
++ SQUASHFS_SWAP((s)->type, d, 24, 4);\
++ SQUASHFS_SWAP((s)->offset, d, 28, 4);\
++}
++
++#define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
++ sizeof(struct squashfs_dev_inode_header_1));\
++ SQUASHFS_SWAP((s)->rdev, d, 24, 16);\
++}
++
++#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
++ sizeof(struct squashfs_symlink_inode_header_1));\
++ SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\
++}
++
++#define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
++ sizeof(struct squashfs_reg_inode_header_1));\
++ SQUASHFS_SWAP((s)->mtime, d, 24, 32);\
++ SQUASHFS_SWAP((s)->start_block, d, 56, 32);\
++ SQUASHFS_SWAP((s)->file_size, d, 88, 32);\
++}
++
++#define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
++ sizeof(struct squashfs_dir_inode_header_1));\
++ SQUASHFS_SWAP((s)->file_size, d, 24, 19);\
++ SQUASHFS_SWAP((s)->offset, d, 43, 13);\
++ SQUASHFS_SWAP((s)->mtime, d, 56, 32);\
++ SQUASHFS_SWAP((s)->start_block, d, 88, 24);\
++}
++
++#endif
++
++#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
++
++struct squashfs_dir_index_2 {
++ unsigned int index:27;
++ unsigned int start_block:29;
++ unsigned char size;
++ unsigned char name[0];
++} __attribute__ ((packed));
++
++struct squashfs_base_inode_header_2 {
++ unsigned int inode_type:4;
++ unsigned int mode:12; /* protection */
++ unsigned int uid:8; /* index into uid table */
++ unsigned int guid:8; /* index into guid table */
++} __attribute__ ((packed));
++
++struct squashfs_ipc_inode_header_2 {
++ unsigned int inode_type:4;
++ unsigned int mode:12; /* protection */
++ unsigned int uid:8; /* index into uid table */
++ unsigned int guid:8; /* index into guid table */
++} __attribute__ ((packed));
++
++struct squashfs_dev_inode_header_2 {
++ unsigned int inode_type:4;
++ unsigned int mode:12; /* protection */
++ unsigned int uid:8; /* index into uid table */
++ unsigned int guid:8; /* index into guid table */
++ unsigned short rdev;
++} __attribute__ ((packed));
++
++struct squashfs_symlink_inode_header_2 {
++ unsigned int inode_type:4;
++ unsigned int mode:12; /* protection */
++ unsigned int uid:8; /* index into uid table */
++ unsigned int guid:8; /* index into guid table */
++ unsigned short symlink_size;
++ char symlink[0];
++} __attribute__ ((packed));
++
++struct squashfs_reg_inode_header_2 {
++ unsigned int inode_type:4;
++ unsigned int mode:12; /* protection */
++ unsigned int uid:8; /* index into uid table */
++ unsigned int guid:8; /* index into guid table */
++ unsigned int mtime;
++ unsigned int start_block;
++ unsigned int fragment;
++ unsigned int offset;
++ unsigned int file_size:32;
++ unsigned short block_list[0];
++} __attribute__ ((packed));
++
++struct squashfs_dir_inode_header_2 {
++ unsigned int inode_type:4;
++ unsigned int mode:12; /* protection */
++ unsigned int uid:8; /* index into uid table */
++ unsigned int guid:8; /* index into guid table */
++ unsigned int file_size:19;
++ unsigned int offset:13;
++ unsigned int mtime;
++ unsigned int start_block:24;
++} __attribute__ ((packed));
++
++struct squashfs_ldir_inode_header_2 {
++ unsigned int inode_type:4;
++ unsigned int mode:12; /* protection */
++ unsigned int uid:8; /* index into uid table */
++ unsigned int guid:8; /* index into guid table */
++ unsigned int file_size:27;
++ unsigned int offset:13;
++ unsigned int mtime;
++ unsigned int start_block:24;
++ unsigned int i_count:16;
++ struct squashfs_dir_index_2 index[0];
++} __attribute__ ((packed));
++
++union squashfs_inode_header_2 {
++ struct squashfs_base_inode_header_2 base;
++ struct squashfs_dev_inode_header_2 dev;
++ struct squashfs_symlink_inode_header_2 symlink;
++ struct squashfs_reg_inode_header_2 reg;
++ struct squashfs_dir_inode_header_2 dir;
++ struct squashfs_ldir_inode_header_2 ldir;
++ struct squashfs_ipc_inode_header_2 ipc;
++};
++
++struct squashfs_dir_header_2 {
++ unsigned int count:8;
++ unsigned int start_block:24;
++} __attribute__ ((packed));
++
++struct squashfs_dir_entry_2 {
++ unsigned int offset:13;
++ unsigned int type:3;
++ unsigned int size:8;
++ char name[0];
++} __attribute__ ((packed));
++
++struct squashfs_fragment_entry_2 {
++ unsigned int start_block;
++ unsigned int size;
++} __attribute__ ((packed));
++
++#define SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
++ SQUASHFS_MEMSET(s, d, n);\
++ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
++ SQUASHFS_SWAP((s)->mode, d, 4, 12);\
++ SQUASHFS_SWAP((s)->uid, d, 16, 8);\
++ SQUASHFS_SWAP((s)->guid, d, 24, 8);\
++
++#define SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, n) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
++}
++
++#define SQUASHFS_SWAP_IPC_INODE_HEADER_2(s, d) \
++ SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, sizeof(struct squashfs_ipc_inode_header_2))
++
++#define SQUASHFS_SWAP_DEV_INODE_HEADER_2(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
++ sizeof(struct squashfs_dev_inode_header_2)); \
++ SQUASHFS_SWAP((s)->rdev, d, 32, 16);\
++}
++
++#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
++ sizeof(struct squashfs_symlink_inode_header_2));\
++ SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\
++}
++
++#define SQUASHFS_SWAP_REG_INODE_HEADER_2(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
++ sizeof(struct squashfs_reg_inode_header_2));\
++ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
++ SQUASHFS_SWAP((s)->start_block, d, 64, 32);\
++ SQUASHFS_SWAP((s)->fragment, d, 96, 32);\
++ SQUASHFS_SWAP((s)->offset, d, 128, 32);\
++ SQUASHFS_SWAP((s)->file_size, d, 160, 32);\
++}
++
++#define SQUASHFS_SWAP_DIR_INODE_HEADER_2(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
++ sizeof(struct squashfs_dir_inode_header_2));\
++ SQUASHFS_SWAP((s)->file_size, d, 32, 19);\
++ SQUASHFS_SWAP((s)->offset, d, 51, 13);\
++ SQUASHFS_SWAP((s)->mtime, d, 64, 32);\
++ SQUASHFS_SWAP((s)->start_block, d, 96, 24);\
++}
++
++#define SQUASHFS_SWAP_LDIR_INODE_HEADER_2(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
++ sizeof(struct squashfs_ldir_inode_header_2));\
++ SQUASHFS_SWAP((s)->file_size, d, 32, 27);\
++ SQUASHFS_SWAP((s)->offset, d, 59, 13);\
++ SQUASHFS_SWAP((s)->mtime, d, 72, 32);\
++ SQUASHFS_SWAP((s)->start_block, d, 104, 24);\
++ SQUASHFS_SWAP((s)->i_count, d, 128, 16);\
++}
++
++#define SQUASHFS_SWAP_DIR_INDEX_2(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index_2));\
++ SQUASHFS_SWAP((s)->index, d, 0, 27);\
++ SQUASHFS_SWAP((s)->start_block, d, 27, 29);\
++ SQUASHFS_SWAP((s)->size, d, 56, 8);\
++}
++#define SQUASHFS_SWAP_DIR_HEADER_2(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header_2));\
++ SQUASHFS_SWAP((s)->count, d, 0, 8);\
++ SQUASHFS_SWAP((s)->start_block, d, 8, 24);\
++}
++
++#define SQUASHFS_SWAP_DIR_ENTRY_2(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry_2));\
++ SQUASHFS_SWAP((s)->offset, d, 0, 13);\
++ SQUASHFS_SWAP((s)->type, d, 13, 3);\
++ SQUASHFS_SWAP((s)->size, d, 16, 8);\
++}
++
++#define SQUASHFS_SWAP_FRAGMENT_ENTRY_2(s, d) {\
++ SQUASHFS_SWAP_START\
++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry_2));\
++ SQUASHFS_SWAP((s)->start_block, d, 0, 32);\
++ SQUASHFS_SWAP((s)->size, d, 32, 32);\
++}
++
++#define SQUASHFS_SWAP_FRAGMENT_INDEXES_2(s, d, n) SQUASHFS_SWAP_INTS(s, d, n)
++
++/* fragment and fragment table defines */
++#define SQUASHFS_FRAGMENT_BYTES_2(A) (A * sizeof(struct squashfs_fragment_entry_2))
++
++#define SQUASHFS_FRAGMENT_INDEX_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) / \
++ SQUASHFS_METADATA_SIZE)
++
++#define SQUASHFS_FRAGMENT_INDEX_OFFSET_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) % \
++ SQUASHFS_METADATA_SIZE)
++
++#define SQUASHFS_FRAGMENT_INDEXES_2(A) ((SQUASHFS_FRAGMENT_BYTES_2(A) + \
++ SQUASHFS_METADATA_SIZE - 1) / \
++ SQUASHFS_METADATA_SIZE)
++
++#define SQUASHFS_FRAGMENT_INDEX_BYTES_2(A) (SQUASHFS_FRAGMENT_INDEXES_2(A) *\
++ sizeof(int))
++
++#endif
++
++#ifdef __KERNEL__
++
++/*
++ * macros used to swap each structure entry, taking into account
++ * bitfields and different bitfield placing conventions on differing
++ * architectures
++ */
++
++#include <asm/byteorder.h>
++
++#ifdef __BIG_ENDIAN
++ /* convert from little endian to big endian */
++#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
++ tbits, b_pos)
++#else
++ /* convert from big endian to little endian */
++#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
++ tbits, 64 - tbits - b_pos)
++#endif
++
++#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\
++ b_pos = pos % 8;\
++ val = 0;\
++ s = (unsigned char *)p + (pos / 8);\
++ d = ((unsigned char *) &val) + 7;\
++ for(bits = 0; bits < (tbits + b_pos); bits += 8) \
++ *d-- = *s++;\
++ value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\
++}
++
++#define SQUASHFS_MEMSET(s, d, n) memset(s, 0, n);
++
++#endif
++#endif
+diff --new-file -urp linux-2.6.15/include/linux/squashfs_fs_i.h linux-2.6.15-squashfs3.0/include/linux/squashfs_fs_i.h
+--- linux-2.6.15/include/linux/squashfs_fs_i.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-squashfs3.0/include/linux/squashfs_fs_i.h 2006-03-07 21:12:37.000000000 +0000
+@@ -0,0 +1,45 @@
++#ifndef SQUASHFS_FS_I
++#define SQUASHFS_FS_I
++/*
++ * Squashfs
++ *
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006
++ * Phillip Lougher <phillip@lougher.org.uk>
++ *
++ * 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.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ *
++ * squashfs_fs_i.h
++ */
++
++struct squashfs_inode_info {
++ long long start_block;
++ unsigned int offset;
++ union {
++ struct {
++ long long fragment_start_block;
++ unsigned int fragment_size;
++ unsigned int fragment_offset;
++ long long block_list_start;
++ } s1;
++ struct {
++ long long directory_index_start;
++ unsigned int directory_index_offset;
++ unsigned int directory_index_count;
++ unsigned int parent_inode;
++ } s2;
++ } u;
++ struct inode vfs_inode;
++};
++#endif
+diff --new-file -urp linux-2.6.15/include/linux/squashfs_fs_sb.h linux-2.6.15-squashfs3.0/include/linux/squashfs_fs_sb.h
+--- linux-2.6.15/include/linux/squashfs_fs_sb.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-squashfs3.0/include/linux/squashfs_fs_sb.h 2006-03-07 21:12:37.000000000 +0000
+@@ -0,0 +1,74 @@
++#ifndef SQUASHFS_FS_SB
++#define SQUASHFS_FS_SB
++/*
++ * Squashfs
++ *
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006
++ * Phillip Lougher <phillip@lougher.org.uk>
++ *
++ * 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.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ *
++ * squashfs_fs_sb.h
++ */
++
++#include <linux/squashfs_fs.h>
++
++struct squashfs_cache {
++ long long block;
++ int length;
++ long long next_index;
++ char *data;
++};
++
++struct squashfs_fragment_cache {
++ long long block;
++ int length;
++ unsigned int locked;
++ char *data;
++};
++
++struct squashfs_sb_info {
++ struct squashfs_super_block sblk;
++ int devblksize;
++ int devblksize_log2;
++ int swap;
++ struct squashfs_cache *block_cache;
++ struct squashfs_fragment_cache *fragment;
++ int next_cache;
++ int next_fragment;
++ int next_meta_index;
++ unsigned int *uid;
++ unsigned int *guid;
++ long long *fragment_index;
++ unsigned int *fragment_index_2;
++ unsigned int read_size;
++ char *read_data;
++ char *read_page;
++ struct semaphore read_data_mutex;
++ struct semaphore read_page_mutex;
++ struct semaphore block_cache_mutex;
++ struct semaphore fragment_mutex;
++ struct semaphore meta_index_mutex;
++ wait_queue_head_t waitq;
++ wait_queue_head_t fragment_wait_queue;
++ struct meta_index *meta_index;
++ struct inode *(*iget)(struct super_block *s, squashfs_inode_t \
++ inode);
++ long long (*read_blocklist)(struct inode *inode, int \
++ index, int readahead_blks, char *block_list, \
++ unsigned short **block_p, unsigned int *bsize);
++ int (*read_fragment_index_table)(struct super_block *s);
++};
++#endif
+diff --new-file -urp linux-2.6.15/init/do_mounts_rd.c linux-2.6.15-squashfs3.0/init/do_mounts_rd.c
+--- linux-2.6.15/init/do_mounts_rd.c 2006-03-01 22:37:27.000000000 +0000
++++ linux-2.6.15-squashfs3.0/init/do_mounts_rd.c 2006-03-07 21:12:37.000000000 +0000
+@@ -5,6 +5,7 @@
+ #include <linux/ext2_fs.h>
+ #include <linux/romfs_fs.h>
+ #include <linux/cramfs_fs.h>
++#include <linux/squashfs_fs.h>
+ #include <linux/initrd.h>
+ #include <linux/string.h>
+
+@@ -39,6 +40,7 @@ static int __init crd_load(int in_fd, in
+ * numbers could not be found.
+ *
+ * We currently check for the following magic numbers:
++ * squashfs
+ * minix
+ * ext2
+ * romfs
+@@ -53,6 +55,7 @@ identify_ramdisk_image(int fd, int start
+ struct ext2_super_block *ext2sb;
+ struct romfs_super_block *romfsb;
+ struct cramfs_super *cramfsb;
++ struct squashfs_super_block *squashfsb;
+ int nblocks = -1;
+ unsigned char *buf;
+
+@@ -64,6 +67,7 @@ identify_ramdisk_image(int fd, int start
+ ext2sb = (struct ext2_super_block *) buf;
+ romfsb = (struct romfs_super_block *) buf;
+ cramfsb = (struct cramfs_super *) buf;
++ squashfsb = (struct squashfs_super_block *) buf;
+ memset(buf, 0xe5, size);
+
+ /*
+@@ -101,6 +105,15 @@ identify_ramdisk_image(int fd, int start
+ goto done;
+ }
+
++ /* squashfs is at block zero too */
++ if (squashfsb->s_magic == SQUASHFS_MAGIC) {
++ printk(KERN_NOTICE
++ "RAMDISK: squashfs filesystem found at block %d\n",
++ start_block);
++ nblocks = (squashfsb->bytes_used+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
++ goto done;
++ }
++
+ /*
+ * Read block 1 to test for minix and ext2 superblock
+ */
diff --git a/packages/linux/linux-openzaurus_2.6.16.bb b/packages/linux/linux-openzaurus_2.6.16.bb
index e6db465519..affecc62df 100644
--- a/packages/linux/linux-openzaurus_2.6.16.bb
+++ b/packages/linux/linux-openzaurus_2.6.16.bb
@@ -1,6 +1,6 @@
include linux-openzaurus.inc
-PR = "r31"
+PR = "r33"
# Handy URLs
# git://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git \
@@ -112,6 +112,9 @@ SRC_URI_append_collie = "file://oz-logo-240.patch.bz2;patch=1"
SRC_URI_append_poodle = "file://oz-logo-240.patch.bz2;patch=1"
SRC_URI_append_tosa = "file://oz-logo-480.patch.bz2;patch=1"
+SRC_URI += "file://squashfs3.0-2.6.15.patch;patch=1"
+
+
# Disabled until I find the reason this gives issues with cdc_subset
# ${RPSRC}/usb_rndis_tweaks-r0.patch;patch=1 \
diff --git a/packages/meta/slugos-packages.bb b/packages/meta/slugos-packages.bb
index 0baa850aa5..3618c4c2ae 100644
--- a/packages/meta/slugos-packages.bb
+++ b/packages/meta/slugos-packages.bb
@@ -134,6 +134,7 @@ SLUGOS_PACKAGES = "\
samba \
sane-backends \
sed \
+ setserial \
ssmtp \
strace \
streamripper \
diff --git a/packages/meta/task-python-everything_20060425.bb b/packages/meta/task-python-everything_20060425.bb
index fd9bbd9c36..738b823d7b 100644
--- a/packages/meta/task-python-everything_20060425.bb
+++ b/packages/meta/task-python-everything_20060425.bb
@@ -2,7 +2,7 @@ DESCRIPTION= "Everything Python"
MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>"
HOMEPAGE = "http://www.vanille.de/projects/python.spy"
LICENSE = "MIT"
-PR = "ml5"
+PR = "ml7"
BROKEN_BECAUSE_GCC4 = "\
python-egenix-mx-base"
@@ -32,6 +32,7 @@ RDEPENDS = "\
python-pexpect \
python-pychecker \
python-pycodes \
+ python-pyfits \
python-pyflakes \
python-pygame \
python-pygoogle \
@@ -41,6 +42,7 @@ RDEPENDS = "\
python-pylint \
python-pyqt \
python-pyqwt \
+ python-pyraf \
python-pyreverse \
python-pyrex \
python-pyro \
diff --git a/packages/meta/task-python-sharprom_20060425.bb b/packages/meta/task-python-sharprom_20060425.bb
index 0c6a74f10b..8ce0dcf855 100644
--- a/packages/meta/task-python-sharprom_20060425.bb
+++ b/packages/meta/task-python-sharprom_20060425.bb
@@ -2,7 +2,7 @@ DESCRIPTION = "Everything Python for SharpROM"
MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>"
HOMEPAGE = "http://www.vanille.de/projects/python.spy"
LICENSE = "MIT"
-PR = "ml2"
+PR = "ml4"
NONWORKING = "\
python-codes \
@@ -22,7 +22,6 @@ RDEPENDS = "\
python-constraint \
python-dialog \
python-egenix-mx-base \
- python-pycurl \
python-fnorb \
python-fpconst \
python-gnosis \
@@ -34,14 +33,18 @@ RDEPENDS = "\
python-mad \
python-native \
python-numeric \
+ python-numarray \
python-ogg \
python-pexpect \
python-pychecker \
+ python-pycurl \
+ python-pyfits \
python-pyflakes \
python-pygoogle \
python-pylinda \
python-pylint \
python-pyqt \
+ python-pyraf \
python-pyreverse \
python-pyro \
python-pyserial \
diff --git a/packages/meta/task-qpe.bb b/packages/meta/task-qpe.bb
index c4d8aaa965..50f42d84fa 100644
--- a/packages/meta/task-qpe.bb
+++ b/packages/meta/task-qpe.bb
@@ -3,7 +3,7 @@ SECTION = "opie/base"
ALLOW_EMPTY = 1
PACKAGE_ARCH = "all"
LICENSE = "MIT"
-PR = "r5"
+PR = "r6"
PACKAGES = "task-qpe-applets task-qpe-games task-qpe-inputmethods \
task-qpe-multimedia task-qpe-emulators task-qpe-applications \
@@ -17,6 +17,7 @@ RDEPENDS_task-qpe-applications = "\
camera-assistant \
cumulus \
dviviewer \
+ freenote \
inkwp \
iqnotes \
justreader \
diff --git a/packages/meta/unslung-image.bb b/packages/meta/unslung-image.bb
index 4a6864eefa..b21433245a 100644
--- a/packages/meta/unslung-image.bb
+++ b/packages/meta/unslung-image.bb
@@ -1,5 +1,5 @@
LICENSE = MIT
-PR = "r14"
+PR = "r15"
IMAGE_BASENAME = "unslung"
@@ -10,11 +10,15 @@ DEPENDS = "virtual/kernel \
${UNSLUNG_EXTRA_DEPENDS}"
RDEPENDS = "kernel update-modules unslung-rootfs \
- libc6-unslung slingbox ipkg cpio findutils \
+ libc6-unslung slingbox ipkg \
+ cpio \
+ findutils \
${UNSLUNG_EXTRA_RDEPENDS}"
IPKG_INSTALL = "kernel update-modules unslung-rootfs \
- libc6-unslung slingbox ipkg cpio findutils \
+ libc6-unslung slingbox ipkg \
+ cpio \
+ findutils \
${UNSLUNG_EXTRA_INSTALL}"
IMAGE_PREPROCESS_COMMAND += "unslung_clean_image; "
@@ -61,6 +65,20 @@ unslung_clean_image () {
# Strip symbols and fix permissions on the libgcc_s.so.1 library
${STRIP} ${IMAGE_ROOTFS}/lib/libgcc_s.so.1
chmod ugo+x ${IMAGE_ROOTFS}/lib/libgcc_s.so.1
+
+ # We need cpio and find, but we don't need any of the other stuff in the
+ # packages (users can install the full package with ipkg after unsling).
+ # (make sure that if the package is not included (i.e. using slingbox
+ # instead) that the files are not deleted; they might be part of slingbox)
+
+ #-- these are for cpio:
+ rm -f ${IMAGE_ROOTFS}/usr/bin/mt
+ rm -rf ${IMAGE_ROOTFS}/usr/bin/libexec
+
+ #-- and these for find:
+ rm -f ${IMAGE_ROOTFS}/usr/bin/locate
+ rm -f ${IMAGE_ROOTFS}/usr/bin/updatedb
+ rm -f ${IMAGE_ROOTFS}/usr/bin/xargs
}
python () {
diff --git a/packages/ncurses/ncurses.inc b/packages/ncurses/ncurses.inc
index 96679db0cb..030cd1034c 100644
--- a/packages/ncurses/ncurses.inc
+++ b/packages/ncurses/ncurses.inc
@@ -7,6 +7,7 @@ PACKAGES_prepend = "ncurses-tools "
PACKAGES_append = " ncurses-terminfo"
FILES_ncurses_append = " ${datadir}/tabset"
RSUGGESTS_${PN} = "ncurses-terminfo"
+RPROVIDES = "libncurses5"
inherit autotools
diff --git a/packages/nonworking/freenote/freenote-1.6.1/compile.patch b/packages/nonworking/freenote/freenote-1.6.1/compile.patch
deleted file mode 100644
index de3e93ac9c..0000000000
--- a/packages/nonworking/freenote/freenote-1.6.1/compile.patch
+++ /dev/null
@@ -1,3285 +0,0 @@
-
-#
-# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- FreeNote_1.6.1_arm/FmtEngine.cpp~compile 2003-12-23 15:53:46.000000000 +0100
-+++ FreeNote_1.6.1_arm/FmtEngine.cpp 2004-02-01 18:42:32.000000000 +0100
-@@ -1,409 +1,410 @@
--/* FreeNote for Sharp SLA300, B500, C7x0 Linux PDA
-- Copyright (C) 2003 Joe Kanemori.<kanemori@ymg.urban.ne.jp>
--
-- 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
--*/
--/*
--2003/12/16-19 FreeNote ver 1.5.5pre
--・曲線描画ロジックの改良
--
--2003/12/14 FreeNote 1.5.4pre
--・曲線描画ロジックの改良
--
--2003/11/30-2003/12/04 FreeNote 1.5.3pre
--・ベジェ関数のスペルミスを修正
--
--2003/11/16 FreeNote 1.5.2pre
--・円描画のロジックを追加
--
--2003/11/13 FreeNote 1.5.1pre
--・スムージング追加
--2003/11/10-12
--・曲線整形モード追加
--2003/11/09 追加
--*/
--#include "fmtengine.h"
--#include <qpointarray.h>
--#include <qpe/qmath.h>
--#include <math.h>
--int SNAP_SIZE = 32;
--int PHASE1_ANGLE = 30;
--int PHASE2_ANGLE = 30;
--double Surface(const QPoint& p1, const QPoint& p2)
--{
-- return 0.5 * abs(p1.x() * p2.y() - p1.y() * p2.x());
--}
--
--bool IsLinear(const QPoint& p1, const QPoint& p2, const QPoint& p3)
--{
-- double s1 = Surface(p1, p2);
-- double s2 = Surface(p2, p3);
-- double s3 = Surface(p1, p3);
-- if (s1 + s2 == s3) {
-- return true;
-- } else {
-- return false;
-- }
--}
--
--const double Angle(const QPoint& p1, const QPoint& p2)
--{
-- return qATan2((double)(p2.y() - p1.y()), (double)(p2.x() - p1.x()));
--}
--
--const double DiffAngle(const QPoint& p1, const QPoint& p2, const QPoint& p3)
--{
-- return fabs(Angle(p1, p2) - Angle(p2, p3));
--}
--
--const double ToDegree(double t)
--{
-- return t * 180 / M_PI;
--}
--
--const double ToRadian(double d)
--{
-- return d * M_PI / 180;
--}
--
--const double Distance(const QPoint& p1, const QPoint& p2)
--{
-- return hypot(p1.x() - p2.x(), p1.y() - p2.y());
--}
--
--const QPoint SnapPoint(const QPoint& p)
--{
-- int x = ((int)(p.x() + SNAP_SIZE / 2) / SNAP_SIZE) * SNAP_SIZE;
-- int y = ((int)(p.y() + SNAP_SIZE / 2) / SNAP_SIZE) * SNAP_SIZE;
-- return QPoint(x, y);
--}
--
--const QPoint ArrangePoint(const QPoint& p1, const QPoint& p2)
--{
-- int x = p2.x();
-- int y = p2.y();
-- if (p1.x() - SNAP_SIZE / 2 <= x && p1.x() + SNAP_SIZE / 2 >= x) {
-- x = p1.x();
-- }
-- if (p1.y() - SNAP_SIZE / 2 <= y && p1.y() + SNAP_SIZE / 2 >= y) {
-- y = p1.y();
-- }
-- return QPoint(x, y);
--}
--
--FNPointList ReducePoints(FNPointList& p)
--{
-- if (3 >= p.count()) {
-- return p;
-- }
-- FNPointList rt;
-- rt.append(p.first());
-- QPoint* p1 = p.first();
-- QPoint* p2 = p.at(1);
-- QPoint* p3 = NULL;
-- for (uint i = 2; i < p.count(); ++i) {
-- p3 = p.at(i);
-- if (false == IsLinear(*p1, *p2, *p3)) {
-- rt.append(p2);
-- p1 = p2;
-- }
-- p2 = p3;
-- }
-- rt.append(p3);
-- return rt;
--}
--
--FNPointList ExtractAngle2(FNPointList& p, const int deg)
--{
-- FNPointList rt;
-- rt.append(p.first());
-- QPoint* st = p.first();
-- QPoint* mp = p.at(1);
-- QPoint* ed = p.last();
-- for (uint i = 2; i < p.count(); ++i) {
-- ed = p.at(i);
-- if (ToRadian(deg) <= DiffAngle(*st, *mp, *ed)) {
-- st = mp;
-- rt.append(mp);
-- }
-- mp = ed;
-- }
-- rt.append(ed);
-- return rt;
--}
--
--FNPointList ExtractAngle(FNPointList& p, const int deg)
--{
-- FNPointList rt;
-- rt.append(p.first());
-- QPoint* st = p.first();
-- QPoint* mp = p.at(1);
-- QPoint* ed = p.last();
-- for (uint i = 2; i < p.count(); ++i) {
-- ed = p.at(i);
-- if (ToRadian(deg) <= DiffAngle(*st, *mp, *ed)) {
-- st = mp;
-- rt.append(mp);
-- }
-- mp = ed;
-- }
-- if (SNAP_SIZE / 2 > Distance(*p.first(), *p.last()) && 3 < p.count()) {
-- rt.append(p.first());
-- } else {
-- rt.append(ed);
-- }
-- return rt;
--}
--
--FNPointList SumupPoints(FNPointList& p)
--{
-- if (3 >= p.count()) {
-- return p;
-- }
-- FNPointList rt;
-- rt.append(p.first());
-- QPoint* p1 = p.first();
-- QPoint* p2 = NULL;
-- double pred = 0;
-- for (uint i = 1; i < p.count() - 1; ++i) {
-- p2 = p.at(i);
-- double d = Distance(*p1, *p2);
-- if (SNAP_SIZE / 2 < d || pred > d) {
-- rt.append(p2);
-- p1 = p2;
-- d = 0;
-- }
-- pred = d;
-- }
-- rt.append(p.last());
-- return rt;
--}
--
--FNPointList SnapPoints(FNPointList& p)
--{
-- FNPointList rt;
-- for (uint i = 0; i < p.count(); ++i) {
-- QPoint tp = SnapPoint(*p.at(i));
-- p.at(i)->setX(tp.x());
-- p.at(i)->setY(tp.y());
-- rt.append(p.at(i));
-- }
-- return rt;
--}
--
--FNPointList ArrangePoints(FNPointList& p)
--{
-- if (3 >= p.count() && 2 != p.count()) {
-- return p;
-- }
-- FNPointList rt;
-- rt.append(p.first());
-- QPoint* p1 = p.first();
-- QPoint* p2 = NULL;
-- for (uint i = 1; i < p.count(); ++i) {
-- p2 = p.at(i);
-- QPoint tp = ArrangePoint(*p1, *p2);
-- p2->setX(tp.x());
-- p2->setY(tp.y());
-- rt.append(p2);
-- p1 = p2;
-- }
-- if (*p.first() == *p.last()) {
-- QPoint tp = ArrangePoint(*p1, *p.first());
-- rt.first()->setX(tp.x());
-- rt.first()->setY(tp.y());
-- }
-- return rt;
--}
--
--FNPointList TuningPoints(FNPointList& p)
--{
-- FNPointList rt;
-- if (3 >= p.count()) {
-- for (uint i = 0; i < p.count(); ++i) {
-- rt.append(new QPoint(*p.at(i)));
-- }
-- return rt;
-- }
-- rt.append(new QPoint(*p.at(0)));
-- for (uint i = 1; i < p.count() - 1; ++i) {
-- QPoint* p1 = p.at(i);
-- QPoint* p2 = p.at(i + 1);
-- rt.append(new QPoint(*p1));
-- if (i < p.count() - 2) {
-- rt.append(new QPoint((p1->x() + p2->x())/2, (p1->y() + p2->y())/2));
-- }
-- }
-- rt.append(new QPoint(*p.at(p.count()-1)));
-- return rt;
--}
--
--FNPointList ToBezier(FNPointList& p) {
-- FNPointList rt;
-- rt.append(new QPoint(*p.at(0)));
-- for (uint i = 0; i < p.count() - 2; i += 2) {
-- int x1 = p.at(i)->x();
-- int xa = p.at(i + 1)->x();
-- int x4 = p.at(i + 2)->x();
--
-- int x2 = (x1 + xa) / 2;
-- int x3 = (xa + x4) / 2;
--
-- int y1 = p.at(i)->y();
-- int ya = p.at(i + 1)->y();
-- int y4 = p.at(i + 2)->y();
--
-- int y2 = (y1 + ya) / 2;
-- int y3 = (ya + y4) / 2;
--
-- rt.append(new QPoint(x2 ,y2));
-- rt.append(new QPoint(x3 ,y3));
-- rt.append(new QPoint(x4 ,y4));
-- }
-- return rt;
--}
--
--FNPointList ToCurves(FNPointList& p) {
-- if (3 <= p.count()) {
-- //ベジェによる補完
-- return ToBezier(p);
-- } else {
-- FNPointList rt;
-- for (uint i = 0; i < p.count(); ++i) {
-- rt.append(new QPoint(*p.at(i)));
-- }
-- return rt;
-- }
--}
--
--FNPointList AutoFormat(FNPointList& p)
--{
-- FNPointList tp = ExtractAngle(p, PHASE1_ANGLE);
-- uint n;
-- do {
-- n = tp.count();
-- tp = SumupPoints(tp);
-- tp = ExtractAngle(tp, PHASE1_ANGLE);
-- tp = ArrangePoints(tp);
-- } while (n > tp.count());
-- tp = SnapPoints(tp);
-- tp = ReducePoints(tp);
-- FNPointList rt;
-- if (2 == tp.count()) {
-- if (*tp.first() == *tp.last()) {
-- return rt;
-- }
-- }
-- for (uint i = 0; i < tp.count(); ++i) {
-- rt.append(new QPoint(*tp.at(i)));
-- }
-- return rt;
--}
--
--FNPointList ToEllipse(int x, int y, int w, int h) {
-- FNPointList rt;
-- QPointArray pa;
-- pa.makeEllipse(x, y, w, h);
-- for (uint i = 0; i < pa.count(); ++i) {
-- rt.append(new QPoint(pa.point(i)));
-- }
-- return rt;
--}
--
--FNPointList AutoCurve(FNPointList& p)
--{
-- FNPointList tp2;
-- tp2.setAutoDelete(true);
-- FNPointList tp4;
-- tp4.setAutoDelete(true);
-- QPoint sp = SnapPoint(*p.at(0));
-- QPoint ep = SnapPoint(*p.at(p.count()-1));
-- if (sp == ep) {
-- //楕円
-- int sx = p.at(0)->x();
-- int sy = p.at(0)->y();
-- int ex = sx;
-- int ey = sy;
-- for (uint i = 1; i < p.count(); ++i) {
-- QPoint tp = *p.at(i);
-- if (sx > tp.x()) {
-- sx = tp.x();
-- } else if (ex < tp.x()) {
-- ex = tp.x();
-- }
-- if (sy > tp.y()) {
-- sy = tp.y();
-- } else if (ey < tp.y()) {
-- ey = tp.y();
-- }
-- }
-- sp = SnapPoint(QPoint(sx, sy));
-- ep = SnapPoint(QPoint(ex, ey));
-- tp2.append(new QPoint(sp.x(), sp.y()));
-- tp2.append(new QPoint(ep.x(), ep.y()));
-- } else {
-- FNPointList tp = ExtractAngle2(p, PHASE2_ANGLE);
-- uint n;
-- do {
-- n = tp.count();
-- tp = SumupPoints(tp);
-- tp = ExtractAngle2(tp, PHASE2_ANGLE);
-- tp = SnapPoints(tp);
-- } while (n > tp.count());
-- tp = SumupPoints(tp);
-- tp = ReducePoints(tp);
-- tp4 = TuningPoints(tp);
-- tp2 = ToCurves(tp4);
-- }
-- FNPointList rt;
-- if (2 == tp2.count()) {
-- if (*tp2.first() == *tp2.last()) {
-- return rt;
-- }
-- }
-- for (uint i = 0; i < tp2.count(); ++i) {
-- rt.append(new QPoint(*tp2.at(i)));
-- }
-- return rt;
--}
--
--FNPointList Smoothing(FNPointList& p)
--{
-- int tsnap = SNAP_SIZE;
-- SNAP_SIZE=8;
-- FNPointList tp = ExtractAngle2(p, PHASE2_ANGLE);
-- tp = SumupPoints(tp);
-- tp = ReducePoints(tp);
-- FNPointList tp4 = TuningPoints(tp);
-- tp4.setAutoDelete(true);
-- FNPointList tp2 = ToCurves(tp4);
-- tp2.setAutoDelete(true);
-- FNPointList rt;
-- for (uint i = 0; i < tp2.count(); ++i) {
-- rt.append(new QPoint(*tp2.at(i)));
-- }
-- SNAP_SIZE = tsnap;
-- return rt;
--}
--
--FNPointList Reduce(FNPointList& p)
--{
-- FNPointList tp = ReducePoints(p);
-- FNPointList rt;
-- for (uint i = 0; i < tp.count(); ++i) {
-- rt.append(new QPoint(*tp.at(i)));
-- }
-- return rt;
--}
-+/* FreeNote for Sharp SLA300, B500, C7x0 Linux PDA
-+ Copyright (C) 2003 Joe Kanemori.<kanemori@ymg.urban.ne.jp>
-+
-+ 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
-+*/
-+/*
-+2003/12/16-19 FreeNote ver 1.5.5pre
-+・曲線描画ロジックの改良
-+
-+2003/12/14 FreeNote 1.5.4pre
-+・曲線描画ロジックの改良
-+
-+2003/11/30-2003/12/04 FreeNote 1.5.3pre
-+・ベジェ関数のスペルミスを修正
-+
-+2003/11/16 FreeNote 1.5.2pre
-+・円描画のロジックを追加
-+
-+2003/11/13 FreeNote 1.5.1pre
-+・スムージング追加
-+2003/11/10-12
-+・曲線整形モード追加
-+2003/11/09 追加
-+*/
-+#include "fmtengine.h"
-+#include <qpointarray.h>
-+#include <qpe/qmath.h>
-+#include <math.h>
-+#include <stdlib.h> // abs
-+int SNAP_SIZE = 32;
-+int PHASE1_ANGLE = 30;
-+int PHASE2_ANGLE = 30;
-+double Surface(const QPoint& p1, const QPoint& p2)
-+{
-+ return 0.5 * abs(p1.x() * p2.y() - p1.y() * p2.x());
-+}
-+
-+bool IsLinear(const QPoint& p1, const QPoint& p2, const QPoint& p3)
-+{
-+ double s1 = Surface(p1, p2);
-+ double s2 = Surface(p2, p3);
-+ double s3 = Surface(p1, p3);
-+ if (s1 + s2 == s3) {
-+ return true;
-+ } else {
-+ return false;
-+ }
-+}
-+
-+const double Angle(const QPoint& p1, const QPoint& p2)
-+{
-+ return qATan2((double)(p2.y() - p1.y()), (double)(p2.x() - p1.x()));
-+}
-+
-+const double DiffAngle(const QPoint& p1, const QPoint& p2, const QPoint& p3)
-+{
-+ return fabs(Angle(p1, p2) - Angle(p2, p3));
-+}
-+
-+const double ToDegree(double t)
-+{
-+ return t * 180 / M_PI;
-+}
-+
-+const double ToRadian(double d)
-+{
-+ return d * M_PI / 180;
-+}
-+
-+const double Distance(const QPoint& p1, const QPoint& p2)
-+{
-+ return hypot(p1.x() - p2.x(), p1.y() - p2.y());
-+}
-+
-+const QPoint SnapPoint(const QPoint& p)
-+{
-+ int x = ((int)(p.x() + SNAP_SIZE / 2) / SNAP_SIZE) * SNAP_SIZE;
-+ int y = ((int)(p.y() + SNAP_SIZE / 2) / SNAP_SIZE) * SNAP_SIZE;
-+ return QPoint(x, y);
-+}
-+
-+const QPoint ArrangePoint(const QPoint& p1, const QPoint& p2)
-+{
-+ int x = p2.x();
-+ int y = p2.y();
-+ if (p1.x() - SNAP_SIZE / 2 <= x && p1.x() + SNAP_SIZE / 2 >= x) {
-+ x = p1.x();
-+ }
-+ if (p1.y() - SNAP_SIZE / 2 <= y && p1.y() + SNAP_SIZE / 2 >= y) {
-+ y = p1.y();
-+ }
-+ return QPoint(x, y);
-+}
-+
-+FNPointList ReducePoints(FNPointList& p)
-+{
-+ if (3 >= p.count()) {
-+ return p;
-+ }
-+ FNPointList rt;
-+ rt.append(p.first());
-+ QPoint* p1 = p.first();
-+ QPoint* p2 = p.at(1);
-+ QPoint* p3 = NULL;
-+ for (uint i = 2; i < p.count(); ++i) {
-+ p3 = p.at(i);
-+ if (false == IsLinear(*p1, *p2, *p3)) {
-+ rt.append(p2);
-+ p1 = p2;
-+ }
-+ p2 = p3;
-+ }
-+ rt.append(p3);
-+ return rt;
-+}
-+
-+FNPointList ExtractAngle2(FNPointList& p, const int deg)
-+{
-+ FNPointList rt;
-+ rt.append(p.first());
-+ QPoint* st = p.first();
-+ QPoint* mp = p.at(1);
-+ QPoint* ed = p.last();
-+ for (uint i = 2; i < p.count(); ++i) {
-+ ed = p.at(i);
-+ if (ToRadian(deg) <= DiffAngle(*st, *mp, *ed)) {
-+ st = mp;
-+ rt.append(mp);
-+ }
-+ mp = ed;
-+ }
-+ rt.append(ed);
-+ return rt;
-+}
-+
-+FNPointList ExtractAngle(FNPointList& p, const int deg)
-+{
-+ FNPointList rt;
-+ rt.append(p.first());
-+ QPoint* st = p.first();
-+ QPoint* mp = p.at(1);
-+ QPoint* ed = p.last();
-+ for (uint i = 2; i < p.count(); ++i) {
-+ ed = p.at(i);
-+ if (ToRadian(deg) <= DiffAngle(*st, *mp, *ed)) {
-+ st = mp;
-+ rt.append(mp);
-+ }
-+ mp = ed;
-+ }
-+ if (SNAP_SIZE / 2 > Distance(*p.first(), *p.last()) && 3 < p.count()) {
-+ rt.append(p.first());
-+ } else {
-+ rt.append(ed);
-+ }
-+ return rt;
-+}
-+
-+FNPointList SumupPoints(FNPointList& p)
-+{
-+ if (3 >= p.count()) {
-+ return p;
-+ }
-+ FNPointList rt;
-+ rt.append(p.first());
-+ QPoint* p1 = p.first();
-+ QPoint* p2 = NULL;
-+ double pred = 0;
-+ for (uint i = 1; i < p.count() - 1; ++i) {
-+ p2 = p.at(i);
-+ double d = Distance(*p1, *p2);
-+ if (SNAP_SIZE / 2 < d || pred > d) {
-+ rt.append(p2);
-+ p1 = p2;
-+ d = 0;
-+ }
-+ pred = d;
-+ }
-+ rt.append(p.last());
-+ return rt;
-+}
-+
-+FNPointList SnapPoints(FNPointList& p)
-+{
-+ FNPointList rt;
-+ for (uint i = 0; i < p.count(); ++i) {
-+ QPoint tp = SnapPoint(*p.at(i));
-+ p.at(i)->setX(tp.x());
-+ p.at(i)->setY(tp.y());
-+ rt.append(p.at(i));
-+ }
-+ return rt;
-+}
-+
-+FNPointList ArrangePoints(FNPointList& p)
-+{
-+ if (3 >= p.count() && 2 != p.count()) {
-+ return p;
-+ }
-+ FNPointList rt;
-+ rt.append(p.first());
-+ QPoint* p1 = p.first();
-+ QPoint* p2 = NULL;
-+ for (uint i = 1; i < p.count(); ++i) {
-+ p2 = p.at(i);
-+ QPoint tp = ArrangePoint(*p1, *p2);
-+ p2->setX(tp.x());
-+ p2->setY(tp.y());
-+ rt.append(p2);
-+ p1 = p2;
-+ }
-+ if (*p.first() == *p.last()) {
-+ QPoint tp = ArrangePoint(*p1, *p.first());
-+ rt.first()->setX(tp.x());
-+ rt.first()->setY(tp.y());
-+ }
-+ return rt;
-+}
-+
-+FNPointList TuningPoints(FNPointList& p)
-+{
-+ FNPointList rt;
-+ if (3 >= p.count()) {
-+ for (uint i = 0; i < p.count(); ++i) {
-+ rt.append(new QPoint(*p.at(i)));
-+ }
-+ return rt;
-+ }
-+ rt.append(new QPoint(*p.at(0)));
-+ for (uint i = 1; i < p.count() - 1; ++i) {
-+ QPoint* p1 = p.at(i);
-+ QPoint* p2 = p.at(i + 1);
-+ rt.append(new QPoint(*p1));
-+ if (i < p.count() - 2) {
-+ rt.append(new QPoint((p1->x() + p2->x())/2, (p1->y() + p2->y())/2));
-+ }
-+ }
-+ rt.append(new QPoint(*p.at(p.count()-1)));
-+ return rt;
-+}
-+
-+FNPointList ToBezier(FNPointList& p) {
-+ FNPointList rt;
-+ rt.append(new QPoint(*p.at(0)));
-+ for (uint i = 0; i < p.count() - 2; i += 2) {
-+ int x1 = p.at(i)->x();
-+ int xa = p.at(i + 1)->x();
-+ int x4 = p.at(i + 2)->x();
-+
-+ int x2 = (x1 + xa) / 2;
-+ int x3 = (xa + x4) / 2;
-+
-+ int y1 = p.at(i)->y();
-+ int ya = p.at(i + 1)->y();
-+ int y4 = p.at(i + 2)->y();
-+
-+ int y2 = (y1 + ya) / 2;
-+ int y3 = (ya + y4) / 2;
-+
-+ rt.append(new QPoint(x2 ,y2));
-+ rt.append(new QPoint(x3 ,y3));
-+ rt.append(new QPoint(x4 ,y4));
-+ }
-+ return rt;
-+}
-+
-+FNPointList ToCurves(FNPointList& p) {
-+ if (3 <= p.count()) {
-+ //ベジェによる補完
-+ return ToBezier(p);
-+ } else {
-+ FNPointList rt;
-+ for (uint i = 0; i < p.count(); ++i) {
-+ rt.append(new QPoint(*p.at(i)));
-+ }
-+ return rt;
-+ }
-+}
-+
-+FNPointList AutoFormat(FNPointList& p)
-+{
-+ FNPointList tp = ExtractAngle(p, PHASE1_ANGLE);
-+ uint n;
-+ do {
-+ n = tp.count();
-+ tp = SumupPoints(tp);
-+ tp = ExtractAngle(tp, PHASE1_ANGLE);
-+ tp = ArrangePoints(tp);
-+ } while (n > tp.count());
-+ tp = SnapPoints(tp);
-+ tp = ReducePoints(tp);
-+ FNPointList rt;
-+ if (2 == tp.count()) {
-+ if (*tp.first() == *tp.last()) {
-+ return rt;
-+ }
-+ }
-+ for (uint i = 0; i < tp.count(); ++i) {
-+ rt.append(new QPoint(*tp.at(i)));
-+ }
-+ return rt;
-+}
-+
-+FNPointList ToEllipse(int x, int y, int w, int h) {
-+ FNPointList rt;
-+ QPointArray pa;
-+ pa.makeEllipse(x, y, w, h);
-+ for (uint i = 0; i < pa.count(); ++i) {
-+ rt.append(new QPoint(pa.point(i)));
-+ }
-+ return rt;
-+}
-+
-+FNPointList AutoCurve(FNPointList& p)
-+{
-+ FNPointList tp2;
-+ tp2.setAutoDelete(true);
-+ FNPointList tp4;
-+ tp4.setAutoDelete(true);
-+ QPoint sp = SnapPoint(*p.at(0));
-+ QPoint ep = SnapPoint(*p.at(p.count()-1));
-+ if (sp == ep) {
-+ //楕円
-+ int sx = p.at(0)->x();
-+ int sy = p.at(0)->y();
-+ int ex = sx;
-+ int ey = sy;
-+ for (uint i = 1; i < p.count(); ++i) {
-+ QPoint tp = *p.at(i);
-+ if (sx > tp.x()) {
-+ sx = tp.x();
-+ } else if (ex < tp.x()) {
-+ ex = tp.x();
-+ }
-+ if (sy > tp.y()) {
-+ sy = tp.y();
-+ } else if (ey < tp.y()) {
-+ ey = tp.y();
-+ }
-+ }
-+ sp = SnapPoint(QPoint(sx, sy));
-+ ep = SnapPoint(QPoint(ex, ey));
-+ tp2.append(new QPoint(sp.x(), sp.y()));
-+ tp2.append(new QPoint(ep.x(), ep.y()));
-+ } else {
-+ FNPointList tp = ExtractAngle2(p, PHASE2_ANGLE);
-+ uint n;
-+ do {
-+ n = tp.count();
-+ tp = SumupPoints(tp);
-+ tp = ExtractAngle2(tp, PHASE2_ANGLE);
-+ tp = SnapPoints(tp);
-+ } while (n > tp.count());
-+ tp = SumupPoints(tp);
-+ tp = ReducePoints(tp);
-+ tp4 = TuningPoints(tp);
-+ tp2 = ToCurves(tp4);
-+ }
-+ FNPointList rt;
-+ if (2 == tp2.count()) {
-+ if (*tp2.first() == *tp2.last()) {
-+ return rt;
-+ }
-+ }
-+ for (uint i = 0; i < tp2.count(); ++i) {
-+ rt.append(new QPoint(*tp2.at(i)));
-+ }
-+ return rt;
-+}
-+
-+FNPointList Smoothing(FNPointList& p)
-+{
-+ int tsnap = SNAP_SIZE;
-+ SNAP_SIZE=8;
-+ FNPointList tp = ExtractAngle2(p, PHASE2_ANGLE);
-+ tp = SumupPoints(tp);
-+ tp = ReducePoints(tp);
-+ FNPointList tp4 = TuningPoints(tp);
-+ tp4.setAutoDelete(true);
-+ FNPointList tp2 = ToCurves(tp4);
-+ tp2.setAutoDelete(true);
-+ FNPointList rt;
-+ for (uint i = 0; i < tp2.count(); ++i) {
-+ rt.append(new QPoint(*tp2.at(i)));
-+ }
-+ SNAP_SIZE = tsnap;
-+ return rt;
-+}
-+
-+FNPointList Reduce(FNPointList& p)
-+{
-+ FNPointList tp = ReducePoints(p);
-+ FNPointList rt;
-+ for (uint i = 0; i < tp.count(); ++i) {
-+ rt.append(new QPoint(*tp.at(i)));
-+ }
-+ return rt;
-+}
---- FreeNote_1.6.1_arm/FNCanvas.cpp~compile 2003-12-24 15:20:16.000000000 +0100
-+++ FreeNote_1.6.1_arm/FNCanvas.cpp 2004-02-01 18:43:35.000000000 +0100
-@@ -1,1227 +1,1228 @@
--/* FreeNote for Sharp SLA300, B500, C7x0 Linux PDA
-- Copyright (C) 2003 Joe Kanemori.<kanemori@ymg.urban.ne.jp>
--
-- 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
--*/
--/*
--2003/12/23 ver 1.6.1
--・保存情報のサイズ縮小
--
--2003/12/16-19 ver 1.5.5pre
--・ペンサイズの追加(1-8)
--・アンドゥ・リドゥの実装
--
--2003/12/14 ver 1.5.4pre
--・ペンサイズを選択可能に。
--
--2003/12/05 ver 1.5.3Apre
--・グリッドの色を修正
--
--2003/12/04 ver 1.5.3pre
--・グリッドの描画を一部修正
--
--2003/11/10 ver 1.5.1pre
--・曲線整形モード追加
--
--2003/11/09 ver 1.5.0pre
--・自動整形モード追加
--
--2003/09/03 ver 1.3.4pre
--・Use all quadrant OFF時に表示位置がリセットされる場合があるバグ対応。
--
--2003/09/01-03 ver 1.3.3pre
--・スクロールの改良
--・Use all quadrant(全象限を使用する)メニューを追加
--
--2003/08/31 FreeNote 1.3.2pre
--・全方向スクロール
--
--2003/08/23 FreeNote 1.3.0pre
--・CR動作の修正
--
--2003/08/15 FreeNote 1.2.1を公開
--・保存時のバグ修正
--・完了ダイアログの自動消去
--・PNGファイルへの出力
--
--2003/08/15 FreeNote 1.2を公開
--・オプション追加
--・スクロールガイド
--・Freeファイル関連付け
--・アイコンの変更
--
--2003/08/05 FreeNote 1.1.1preを公開
--・高速起動時に閉じた状態を保持
--・描画モード切替え時に消しゴム表示
--・保存時間短縮
--・Viewモードの挙動を変更
--・メニューの見た目を変更
--*/
--#include "fncanvas.h"
--#include <stdio.h>
--#include <qfile.h>
--#include <qmessagebox.h>
--#include <qtextstream.h>
--#include <qpen.h>
--#include <qcolor.h>
--#include <qpoint.h>
--#include <qthread.h>
--#include <qimage.h>
--#include <math.h>
--#include "fnmessagebox.h"
--#include "fmtengine.h"
--
--int snap(int v) {
-- int tv = abs(v);
-- tv = ((int)(tv + SNAP_SIZE / 2) / SNAP_SIZE) * SNAP_SIZE;
-- if (0 > v) {
-- return -tv;
-- } else {
-- return tv;
-- }
--}
--
--FNCanvas::FNCanvas(QWidget* parent = 0, const char* name = 0, WFlags f = 0)
-- :QWidget(parent, name, f),
-- _pen(black, 1, SolidLine, RoundCap, RoundJoin),
-- _asMode(AS_NONE),
-- _drawMode(MODE_DRAW),
-- _disp_offset(0),
-- _eraser_l(50),
-- _eraser_s(10),
-- _h_step(100),
-- _v_step(100),
-- _margin(5),
-- _scrollTiming(800),
-- _viewMode(false),
-- _isWaiting(false),
-- _isDragging(false),
-- _isHeadingEnables(false),
-- _isShowGuide(false),
-- _isUseAllQuadrant(false),
-- _scale_x(1.0),
-- _scale_y(1.0)
--{
-- _tracks.setAutoDelete(true);
-- this->setBackgroundMode(NoBackground);
-- _timer = new QTimer(this);
-- connect(_timer, SIGNAL(timeout()), this, SLOT(autoScroll()));
--}
--
--FNCanvas::~FNCanvas()
--{
-- _timer->stop();
-- delete _timer;
--
-- _tracks.clear();
-- clearList(_draws);
--}
--
--void FNCanvas::setScrollTiming(int v)
--{
-- _scrollTiming = v;
--}
--
--
--void FNCanvas::setVStep(int v)
--{
-- _v_step = v;
--}
--
--void FNCanvas::setHStep(int v)
--{
-- _h_step = v;
--}
--
--void FNCanvas::setSEraser(int v)
--{
-- _eraser_s = v;
--}
--
--void FNCanvas::setLEraser(int v)
--{
-- _eraser_l = v;
--}
--
--
--void FNCanvas::setMargin(int v)
--{
-- if (v < 3) {
-- v = 3;
-- }
-- _margin = v;
--}
--
--void FNCanvas::setScrollMode(int as)
--{
-- _asMode = as;
-- redraw();
--}
--
--void FNCanvas::autoScroll()
--{
-- if (AS_NONE == _asMode) {
-- if (MODE_FORMAT == _drawMode || MODE_CURVE == _drawMode || MODE_SMOOTH == _drawMode) {
-- setOrigin(_origin.x(), _origin.y());
-- }
-- return;
-- }
-- bool tmp = _isHeadingEnables;
-- int dx = 0;
-- int dy = 0;
-- if (AS_BOTH == _asMode || AS_HORIZONTAL == _asMode) {
-- if (_last.x() > width() * (_margin - 1) / _margin) {
-- dx = _h_step;
-- } else if (_last.x() < width() / _margin) {
-- dx = -_h_step;
-- }
-- }
-- if (AS_BOTH == _asMode || AS_VERTICAL == _asMode) {
-- if (_last.y() > height() * (_margin - 1) / _margin) {
-- dy = _v_step;
-- } else if (_last.y() < height() / _margin) {
-- dy = -_v_step;
-- }
-- }
-- setOrigin(_origin.x() + dx, _origin.y() + dy);
-- _isHeadingEnables = tmp;
--}
--
--void FNCanvas::mousePressEvent(QMouseEvent* evt)
--{
-- setFocus();
-- _timer->stop();
-- _tracks.clear();
-- if (_viewMode) {
-- _isWaiting = true;
-- _viewMode = false;
-- setOrigin((int)((evt->x()) / _scale_x) - width() / 2, (int)((evt->y()) / _scale_y) - height() / 2);
-- redraw();
-- emit resetViewMode();
-- } else if (MODE_ERASE != _drawMode) {
-- _last = evt->pos();
-- _tracks.append(new QPoint(_last));
-- } else {
-- redraw();
-- _last = evt->pos();
-- _tracks.append(new QPoint(_last));
--
-- QPainter pbuf;
-- QPainter pwin;
-- pbuf.begin(&_buffer);
-- pwin.begin(this);
--
-- int w = _eraser_s;
-- if (PENWIDTH_MAX / 2 < _pen.width()) {
-- w = _eraser_l;
-- }
-- pbuf.setRasterOp(XorROP);
-- pbuf.setPen(QPen(white, 1));
-- pbuf.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
--
-- pwin.setRasterOp(XorROP);
-- pwin.setPen(QPen(white, 1));
-- pwin.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
--
-- pbuf.end();
-- pwin.end();
-- }
-- _isDragging = true;
--}
--
--void FNCanvas::mouseMoveEvent(QMouseEvent* evt)
--{
-- if (_isWaiting) {
-- return;
-- }
-- if (MODE_ERASE != _drawMode) {
-- QPainter pwin;
-- QPainter pbuf;
--
-- pwin.begin(this);
-- pbuf.begin(&_buffer);
--
-- pwin.setPen(_pen);
-- pbuf.setPen(_pen);
--
-- pwin.drawLine(_last, evt->pos());
-- pbuf.drawLine(_last, evt->pos());
--
-- pwin.end();
-- pbuf.end();
-- _last = evt->pos();
-- _tracks.append(new QPoint(_last));
-- } else {
-- //redraw();
-- if (_last.x() == -1) {
-- return;
-- }
-- QPainter pbuf;
-- QPainter pwin;
--
-- pbuf.begin(&_buffer);
-- pwin.begin(this);
--
-- int w = _eraser_s;
-- if (PENWIDTH_MAX / 2 < _pen.width()) {
-- w = _eraser_l;
-- }
-- pbuf.setRasterOp(XorROP);
-- pwin.setRasterOp(XorROP);
-- pbuf.setPen(QPen(white, 1));
-- pwin.setPen(QPen(white, 1));
-- pbuf.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
-- pwin.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
--
-- _tracks.append(new QPoint(evt->pos()));
-- _last = evt->pos();
--
-- pbuf.setRasterOp(CopyROP);
-- pwin.setRasterOp(CopyROP);
-- QRect r = QRect(0, 0, width(), height());
-- for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
-- FNPolygon* p = _draws.at(i);
-- if (r.intersects(p->boundingRect())) {
-- bool f = false;
-- QRect selected(_last.x() - w / 2, _last.y() - w / 2, w, w);
-- for (uint j = 0; j < p->points().count(); ++j) {
-- QPoint& pts = p->points().at(j);
-- if (selected.contains(pts)) {
-- f = true;
-- break;
-- }
-- }
-- if (f) {
-- p->drawShape(pbuf, f);
-- p->drawShape(pwin, f);
-- }
-- }
-- }
-- pbuf.setRasterOp(XorROP);
-- pwin.setRasterOp(XorROP);
-- pbuf.setPen(QPen(white, 1));
-- pwin.setPen(QPen(white, 1));
-- pbuf.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
-- pwin.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
-- pbuf.end();
-- pwin.end();
-- }
--}
--
--void FNCanvas::mouseReleaseEvent(QMouseEvent* evt)
--{
-- _isDragging = false;
-- if (_isWaiting) {
-- _isWaiting = false;
-- return;
-- }
-- _last = evt->pos();
-- if (MODE_ERASE != _drawMode) {
-- if (1 < _tracks.count()) {
-- FNPolygon* p = NULL;
-- if (MODE_FORMAT == _drawMode) {
-- p = new FNPolygon(_pen);
-- _tracks = AutoFormat(_tracks);
-- } else if (MODE_CURVE == _drawMode) {
-- QPoint sp = SnapPoint(*_tracks.at(0));
-- QPoint ep = SnapPoint(*_tracks.at(_tracks.count()-1));
-- _tracks = AutoCurve(_tracks);
-- if (sp == ep) {
-- p = new FNEllipse(_pen);
-- } else if (2 < _tracks.count()) {
-- p = new FNBezier(_pen);
-- } else {
-- p = new FNPolygon(_pen);
-- }
-- } else if (MODE_SMOOTH == _drawMode) {
-- _tracks = Smoothing(_tracks);
-- if (2 < _tracks.count()) {
-- p = new FNBezier(_pen);
-- } else {
-- p = new FNPolygon(_pen);
-- }
-- } else {
-- _tracks = Reduce(_tracks);
-- p = new FNPolygon(_pen);
-- }
-- if (1 < _tracks.count()) {
-- p->setPoints(_tracks);
-- redobuf_flush();
-- _draws.append(p);
-- }
-- }
-- _tracks.clear();
-- _isHeadingEnables = true;
-- _timer->start(_scrollTiming, true);
-- } else {
-- _last = QPoint(-1, -1);
-- _tracks.append(new QPoint(evt->pos()));
-- redraw();
-- }
--}
--
--void FNCanvas::paintEvent(QPaintEvent* evt)
--{
-- bitBlt(this, 0, 0, &_buffer);
--}
--
--void FNCanvas::resizeEvent(QResizeEvent* evt)
--{
-- QPixmap save(_buffer);
-- _buffer.resize(evt->size());
-- _buffer.fill(white);
-- bitBlt(&_buffer, 0, 0, &save);
-- redraw();
--}
--
--void FNCanvas::setOrigin(QPoint& o)
--{
-- this->setOrigin(o.x(), o.y());
--}
--
--QPoint FNCanvas::getTopLeft()
--{
-- if (0 == _draws.count() || !_isUseAllQuadrant) {
-- return _origin;
-- }
--
-- int dx = ((FNPolygon*)_draws.at(0))->boundingRect().x();
-- int dy = ((FNPolygon*)_draws.at(0))->boundingRect().y();
-- for (uint i = 1; i < _draws.count(); ++i) {
-- FNPolygon* p = _draws.at(i);
-- if (dx > p->boundingRect().x()) {
-- dx = p->boundingRect().x();
-- }
-- if (dy > p->boundingRect().y()) {
-- dy = p->boundingRect().y();
-- }
-- }
-- return QPoint(snap(dx), snap(dy));
--}
--
--
--void FNCanvas::rebuild()
--{
-- if (0 == _draws.count() || !_isUseAllQuadrant) {
-- return;
-- }
--
-- QPoint d = getTopLeft();
-- for (uint i = 0; i < _draws.count(); ++i) {
-- FNPolygon* p = _draws.at(i);
-- p->translate(-d.x(), -d.y());
-- }
--
-- _origin = QPoint(0, 0);
--}
--
--
--void FNCanvas::setOrigin(int ox, int oy)
--{
-- ox = snap(ox);
-- oy = snap(oy);
-- _isHeadingEnables = false;
-- _timer->stop();
--
--
-- int dx = 0;
-- int dy = 0;
-- if (!_isUseAllQuadrant) {
-- if (0 > ox) {
-- ox = 0;
-- }
-- if (0 > oy) {
-- oy = 0;
-- }
-- dx = _origin.x() - ox;
-- dy = _origin.y() - oy;
-- } else {
-- dx = _origin.x() - ox;
-- dy = _origin.y() - oy;
-- if (0 > ox) {
-- ox = 0;
-- }
-- if (0 > oy) {
-- oy = 0;
-- }
-- }
-- for (uint i = 0; i < _tracks.count(); ++i) {
-- QPoint* p = _tracks.at(i);
-- p->setX(p->x() + dx);
-- p->setY(p->y() + dy);
-- }
--
-- for (uint i = 0; i < _draws.count(); ++i) {
-- FNPolygon* p = _draws.at(i);
-- p->translate(dx, dy);
-- }
-- _origin = QPoint(ox, oy);
-- emit originChanged(ox, oy);
-- redraw();
--}
--
--void FNCanvas::redraw()
--{
-- if (!this->isVisible()) {
-- return;
-- }
-- _buffer.fill(white);
-- QPainter pbuf;
-- QRect r = QRect(0, 0, width(), height());
-- pbuf.begin(&_buffer);
-- if (_viewMode) {
-- float wx = 0;
-- float wy = 0;
-- for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
-- FNPolygon* p = _draws.at(i);
-- QRect r = p->boundingRect();
-- if (wx < r.right()) {
-- wx = r.right();
-- }
-- if (wy < r.bottom()) {
-- wy = r.bottom();
-- }
-- }
-- wx += SNAP_SIZE;
-- wy += SNAP_SIZE;
-- wx = snap((int)wx);
-- wy = snap((int)wy);
-- wx = wx + _origin.x();
-- wy = wy + _origin.y();
-- _scale_x = (float)width() / wx;
-- _scale_y = (float)height() / wy;
-- if (1.0f < _scale_x) {
-- _scale_x = 1.0f;
-- }
-- if (1.0f < _scale_y) {
-- _scale_y = 1.0f;
-- }
-- if (_scale_x > _scale_y) {
-- _scale_x = _scale_y;
-- } else if (_scale_x < _scale_y) {
-- _scale_y = _scale_x;
-- }
-- for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
-- FNPolygon* p = _draws.at(i);
-- FNPolygon* t = NULL;
-- if (p->type() == FN_BEZIER) {
-- t = new FNBezier(*(FNBezier*)p);
-- } else if (p->type() == FN_ELLIPSE) {
-- t = new FNEllipse(*(FNEllipse*)p);
-- } else {
-- t = new FNPolygon(*p);
-- }
-- t->translate(-_origin.x(), -_origin.y());
-- for (uint j = 0; j < t->points().count(); ++j) {
-- QPoint& pts = t->points().at(j);
-- int x = (int)(pts.x() * _scale_x);
-- int y = (int)(pts.y() * _scale_y);
-- pts.setX(x);
-- pts.setY(y);
-- }
-- double pensize = t->pen().width();
-- if (_scale_x > _scale_y) {
-- pensize = pensize * _scale_y;
-- } else {
-- pensize = pensize * _scale_x;
-- }
-- if (0 >= pensize) {
-- pensize = 1;
-- }
-- t->pen().setWidth(pensize);
-- t->drawShape(pbuf);
-- delete t;
-- }
-- } else if (MODE_ERASE != _drawMode) {
-- if (MODE_FORMAT == _drawMode || MODE_CURVE == _drawMode) {
-- QPen pen1(QColor(0, 240, 240), 1);
-- QPen pen2(QColor(0, 0, 0), 1);
-- pbuf.setPen(QPen(QColor(0, 240, 240), 1));
-- pbuf.setPen(pen1);
-- for (int x = 0; x < width() + SNAP_SIZE; x += SNAP_SIZE) {
-- pbuf.drawLine(x - SNAP_SIZE / 2, 0, x - SNAP_SIZE / 2, height());
-- for (int y = 0; y < height() + SNAP_SIZE; y += SNAP_SIZE) {
-- pbuf.drawLine(0, y - SNAP_SIZE / 2, width(), y - SNAP_SIZE / 2);
-- pbuf.drawRect(x-1,y-1,2,2);
-- }
-- }
-- }
-- if (_isShowGuide) {
-- pbuf.setPen(QPen(cyan, 1, DashLine));
-- if (AS_HORIZONTAL == _asMode || AS_BOTH == _asMode) {
-- if (0 != _origin.x() || _isUseAllQuadrant) {
-- pbuf.drawLine(width() / _margin, 0, width() / _margin, height());
-- }
-- pbuf.drawLine(width() * (_margin - 1) / _margin, 0, width() * (_margin - 1) / _margin, height());
-- }
--
-- if (AS_VERTICAL == _asMode || AS_BOTH == _asMode) {
-- if (0 != _origin.y() || _isUseAllQuadrant) {
-- pbuf.drawLine(0, height() / _margin, width(), height() / _margin);
-- }
-- pbuf.drawLine(0, height() * (_margin - 1) / _margin, width(), height() * (_margin - 1) / _margin);
-- }
-- }
--
-- for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
-- FNPolygon* p = _draws.at(i);
-- if (r.intersects(p->boundingRect())) {
-- p->drawShape(pbuf);
-- }
-- }
-- } else {
-- int w = _eraser_s;
-- if (PENWIDTH_MAX / 2 < _pen.width()) {
-- w = _eraser_l;
-- }
-- FNPointList removes;
-- for (uint i = 0; i < _tracks.count(); ++i) {
-- removes.append(_tracks.at(i));
-- }
-- for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
-- FNPolygon* p = _draws.at(i);
-- if (r.intersects(p->boundingRect())) {
-- bool f = false;
-- for (uint j = 0; j < _tracks.count(); ++j) {
-- QPoint* pts = _tracks.at(j);
-- QRect selected(pts->x() - w / 2, pts->y() - w / 2, w, w);
-- for (uint k = 0; k < p->points().count(); ++k) {
-- QPoint& pts2 = p->points().at(k);
-- if (selected.contains(pts2)) {
-- f = true;
-- removes.remove(pts);
-- break;
-- }
-- }
-- if (f) {
-- break;
-- }
-- }
-- p->drawShape(pbuf, f);
-- }
-- }
-- for (uint i = 0; i < removes.count(); ++i) {
-- _tracks.remove(removes.at(i));
-- }
-- /*
-- if (_isDragging) {
-- pbuf.setPen(QPen(black, 1));
-- pbuf.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
-- }
-- */
-- }
-- pbuf.end();
-- repaint();
--}
--
--void FNCanvas::changeColor(QRgb c)
--{
-- _pen.setColor(QColor(c));
--}
--
--void FNCanvas::undo()
--{
-- if (MODE_ERASE != _drawMode) {
-- ++_disp_offset;
-- if (_disp_offset > _draws.count()) {
-- _disp_offset = _draws.count();
-- }
-- } else {
-- _draws = _undobuf;
-- _marks.clear();
-- }
-- redraw();
--}
--
--void FNCanvas::redo()
--{
-- if (MODE_ERASE != _drawMode) {
-- if (0 < _disp_offset) {
-- --_disp_offset;
-- }
-- }
-- redraw();
--}
--
--void FNCanvas::clearList(FNPolygonList& list)
--{
-- list.setAutoDelete(true);
-- list.clear();
-- list.setAutoDelete(false);
--}
--
--void FNCanvas::clear()
--{
-- _disp_offset = 0;
-- clearList(_draws);
-- _undobuf.clear();
-- setOrigin(0, 0);
-- redraw();
--}
--
--void FNCanvas::viewChanged(bool flg)
--{
-- _tracks.clear();
-- _viewMode = flg;
-- if (_viewMode) {
-- if (_isUseAllQuadrant) {
-- rebuild();
-- }
-- setOrigin(0, 0);
-- }
-- redraw();
--}
--
--void FNCanvas::redobuf_flush()
--{
-- for (uint i = 0; i < _disp_offset; ++i) {
-- FNPolygon* p = _draws.last();
-- _draws.remove(p);
-- delete p;
-- }
-- _disp_offset = 0;
--}
--
--void FNCanvas::modeChanged(int mode)
--{
-- _tracks.clear();
-- _drawMode = mode;
-- redobuf_flush();
-- if (MODE_ERASE == _drawMode) {
-- _marks.clear();
-- _undobuf = _draws;
-- } else {
-- if (_draws.count() != _undobuf.count()) {
-- for (uint i = 0; i < _marks.count(); ++i) {
-- FNPolygon* p = _marks.at(i);
-- _draws.remove(p);
-- }
-- clearList(_marks);
-- }
-- }
-- redraw();
--}
--
--QRect FNCanvas::getMatrix(const QRect& r) const
--{
-- int ox = _origin.x();
-- int oy = _origin.y();
-- const int wide = 100;
--
-- int left = r.left() + ox;
-- int top = r.top() + oy;
-- int right = r.right() + ox;
-- int bottom = r.bottom() + oy;
--
-- left = (int)(left / wide) * wide;
-- top = (int)(top / wide) * wide;
-- right = (right % wide == 0 && left != right) ? right : (int)((right + wide) / wide) * wide;
-- bottom = (bottom % wide == 0 && top != bottom) ? bottom : (int)((bottom + wide) / wide) * wide;
--
-- return QRect(left - ox, top - oy, right - left, bottom - top);
--}
--
--void FNCanvas::CR()
--{
-- if (MODE_ERASE == _drawMode) {
-- return;
-- }
-- if (_isHeadingEnables) {
-- //lastから、左方向に向けて探索する。
-- QRect r = getMatrix(_draws.last()->boundingRect());
-- bool isSearching = true;
-- r.moveBy(-100, 0);
-- while (isSearching) {
-- isSearching = false;
-- for (uint i = 0; i < _draws.count(); ++i) {
-- FNPolygon* p = _draws.at(i);
-- const QRect& r2 = p->boundingRect();
-- if (r.intersects(r2)) {
-- if (r.left() + 100 > r2.left()) {
-- r = getMatrix(r2);
-- r.moveBy(-100, 0);
-- isSearching = true;
-- break;
-- }
-- }
-- }
-- }
-- r.moveBy(100, 0);
-- //lastが画面の4/5以下ならば、スクロールアップする。
-- //そうでなければ、ヘッディングのみ。
-- if (_last.y() > height() * 4 / 5) {
-- setOrigin(_origin.x() + r.x(), _origin.y() + 50);
-- } else {
-- setOrigin(_origin.x() + r.x(), _origin.y());
-- }
-- _isHeadingEnables = false;
-- } else {
-- //lastの周囲に何も無い場合は、縦にスクロールする。
-- setOrigin(_origin.x(), _origin.y() + 50);
-- }
--}
--
--void FNCanvas::erase()
--{
-- if (MODE_ERASE != _drawMode) {
-- return;
-- }
-- FNPolygonList temp;
-- int w = _eraser_s;
-- if (PENWIDTH_MAX / 2 < _pen.width()) {
-- w = _eraser_l;
-- }
-- QRect r = QRect(0, 0, width(), height());
-- for (uint i = 0; i < _draws.count(); ++i) {
-- FNPolygon* p = _draws.at(i);
-- bool f = false;
-- if (r.intersects(p->boundingRect())) {
-- for (uint j = 0; j < _tracks.count(); ++j) {
-- QPoint* pts = _tracks.at(j);
-- QRect selected(pts->x() - w / 2, pts->y() - w / 2, w, w);
-- for (uint k = 0; k < p->points().count(); ++k) {
-- QPoint& pts2 = p->points().at(k);
-- if (selected.contains(pts2)) {
-- temp.append(p);
-- f = true;
-- break;
-- }
-- }
-- if (f) {
-- break;
-- }
-- }
-- }
-- }
-- for (uint i = 0; i < temp.count(); ++i) {
-- _draws.remove(temp.at(i));
-- _marks.append(temp.at(i));
-- }
-- _tracks.clear();
-- redraw();
--}
--
--void FNCanvas::setPensize(int sz)
--{
-- _pen.setWidth(sz);
--}
--
--bool FNCanvas::exportPNG(const QFileInfo& info, QPixmap& buf)
--{
-- if (0 == info.fileName().length()) {
-- QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
-- return false;
-- }
-- if (info.extension(false) != "png") {
-- QMessageBox::warning(0,"FreeNoteQt", "extension '.png' expected.");
-- return false;
-- }
--
-- bool ret = buf.save(info.absFilePath(), "PNG");
-- if (ret) {
-- FNMessageBox::information(0,"FreeNoteQt", "export PNG complete.");
-- } else {
-- QMessageBox::warning(0,"FreeNoteQt", "could not export file.");
-- }
-- return ret;
--}
--
--QString FNCanvas::mkPDFscript(FNPolygon* elm)
--{
-- QString s ="";
-- char buf[1024];
--
-- float r = (float)elm->pen().color().red() / 255.0f;
-- float g = (float)elm->pen().color().green() / 255.0f;
-- float b = (float)elm->pen().color().blue() / 255.0f;
-- s += "q\n";
-- sprintf(buf, "%f %f %f RG\n", r, g, b);
-- s += buf;
-- QPointArray points = elm->points().copy();
-- points.translate(_origin.x(), _origin.y());
-- if (elm->type() == FN_BEZIER) {
-- sprintf(buf, "%d %d m\n", points[0].x(), points[0].y());
-- s += buf;
-- for (uint j = 1; j < points.count(); j += 3) {
-- sprintf(buf, "%d %d %d %d %d %d c\n",
-- points[j].x(), points[j].y(),
-- points[j + 1].x(), points[j + 1].y(),
-- points[j + 2].x(), points[j + 2].y()
-- );
-- s += buf;
-- }
-- } else if (elm->type() == FN_ELLIPSE) {
-- int x = points[0].x();
-- int y = points[0].y();
-- int ex = points[1].x();
-- int ey = points[1].y();
-- int w = ex - x;
-- int h = ey - y;
-- int cx = x + w/2;
-- int cy = y;
-- int x1 = x + 3*w/4;
-- int y1 = y;
-- int x2 = x + w;
-- int y2 = y + h/4;
-- int x3 = x + w;
-- int y3 = y + h/2;
--
-- sprintf(buf, "%d %d m\n%d %d %d %d %d %d c\n", cx, cy, x1, y1, x2, y2, x3, y3);
-- s += buf;
-- x1 = x + w;
-- y1 = y + 3 * h / 4;
-- x2 = x + 3 * w / 4;
-- y2 = y + h;
-- x3 = x + w/2;
-- y3 = y + h;
-- sprintf(buf, "%d %d %d %d %d %d c\n", x1, y1, x2, y2, x3, y3);
-- s += buf;
--
-- x1 = x + w / 4;
-- y1 = y + h;
-- x2 = x;
-- y2 = y + 3 * h / 4;
-- x3 = x;
-- y3 = y + h / 2;
-- sprintf(buf, "%d %d %d %d %d %d c\n", x1, y1, x2, y2, x3, y3);
-- s += buf;
-- x1 = x;
-- y1 = y + h / 4;
-- x2 = x + w / 4;
-- y2 = y;
-- x3 = x + w / 2;
-- y3 = y;
-- sprintf(buf, "%d %d %d %d %d %d c\n", x1, y1, x2, y2, x3, y3);
-- s += buf;
-- } else {
-- sprintf(buf, "%d %d m\n", points[0].x(), points[0].y());
-- s += buf;
-- for (uint j = 1; j < points.count(); ++j) {
-- sprintf(buf, "%d %d l\n", points[j].x(), points[j].y());
-- s += buf;
-- }
-- }
-- sprintf(buf, "%d w\n", elm->pen().width());
-- s += buf;
-- s += "S\n";
-- s += "Q\n";
-- return s;
--}
--
--bool FNCanvas::exportPDF(const QFileInfo& info)
--{
-- if (0 == info.fileName().length()) {
-- QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
-- return false;
-- }
-- if (info.extension(false) != "pdf") {
-- QMessageBox::warning(0,"FreeNoteQt", "extension '.pdf' expected.");
-- return false;
-- }
--
-- FILE* fp = NULL;
-- if (!(fp = fopen(info.absFilePath().utf8(), "wt"))) {
-- QMessageBox::warning(0,"FreeNoteQt", "could not export file.");
-- return false;
-- }
--
-- QPoint o = getTopLeft();
-- rebuild();
-- int wx = 595;
-- int wy = 842;
-- char buf[1024];
-- for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
-- FNPolygon* p = _draws.at(i);
-- QRect r = p->boundingRect();
-- r.moveBy(_origin.x(), _origin.y());
-- if (wx < r.right()) {
-- wx =r.right();
-- }
-- if (wy < r.bottom()) {
-- wy = r.bottom();
-- }
-- }
--
-- int len = 0;
--
-- sprintf(buf, "1 0 0 -1 0 %d cm\n", wy);
-- QString cm = buf;
-- len += cm.length();
--
-- for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
-- QString s = mkPDFscript(_draws.at(i));
-- len += s.length();
-- }
--
-- QString header = "";
-- header += "%PDF-1.3\n";
-- header += "1 0 obj\n";
-- header += "<<\n";
-- header += "/Type /Page\n";
-- header += "/Parent 3 0 R\n";
-- header += "/Resources\n";
-- header += "<<\n";
-- header += "/ProcSet [ /PDF ]\n";
-- header += ">>\n";
-- sprintf(buf, "/MediaBox [ 0 0 %010d %010d ]\n", wx, wy);
-- header += buf;
-- header += "/Contents 4 0 R\n";
-- header += ">>\n";
-- header += "endobj\n";
-- header += "2 0 obj\n";
-- header += "<<\n";
-- header += "/Type /Catalog\n";
-- header += "/Pages 3 0 R\n";
-- header += "/PageLayout /OneColumn\n";
-- header += "/OpenAction [1 0 R /XYZ null null 1 ]\n";
-- header += ">>\n";
-- header += "endobj\n";
-- header += "3 0 obj\n";
-- header += "<<\n";
-- header += "/Type /Pages\n";
-- header += "/Kids [ 1 0 R ]\n";
-- header += "/Count 1\n";
-- header += ">>\n";
-- header += "endobj\n";
-- header += "4 0 obj\n";
-- sprintf(buf, "<< /Length %010d >>\n", len);
-- header += buf;
-- header += "stream\n";
--
-- QString footer = "";
-- footer += "xref\n";
-- footer += "0 5\n";
-- footer += "0000000000 65535 f \n";
-- footer += "0000000009 00000 n \n";
-- footer += "0000000147 00000 n \n";
-- footer += "0000000257 00000 n \n";
-- footer += "0000000316 00000 n \n";
-- footer += "trailer\n";
-- footer += "<<\n";
-- footer += "/Size 5\n";
-- footer += "/Root 2 0 R\n";
-- footer += ">>\n";
-- footer += "startxref\n";
--
-- len = cm.length();
-- len += header.length();
-- fputs(header, fp);
-- fputs(cm, fp);
--
-- for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
-- QString s = mkPDFscript(_draws.at(i));
-- len += s.length();
-- fputs(s, fp);
-- }
-- QString streamfooter = "endstream\nendobj\n";
-- len += streamfooter.length();
-- fputs(streamfooter, fp);
--
-- fputs(footer, fp);
-- sprintf(buf, "%d\n", len);
-- fputs(buf, fp);
-- fputs("%%EOF\n", fp);
-- fclose(fp);
-- if (_isUseAllQuadrant) {
-- setOrigin(-o.x(), -o.y());
-- }
-- FNMessageBox::information(0,"FreeNoteQt", "export PDF complete.");
-- return true;
--}
--
--bool FNCanvas::save(const QFileInfo& info)
--{
-- if (0 == info.fileName().length()) {
-- QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
-- return false;
-- }
-- if (info.extension(false) != "free") {
-- QMessageBox::warning(0,"FreeNoteQt", "extension '.free' expected.");
-- return false;
-- }
-- FILE* fp = NULL;
-- if (!(fp = fopen(info.absFilePath().utf8(), "wt"))) {
-- QMessageBox::warning(0,"FreeNoteQt", "could not save file.");
-- return false;
-- }
-- QPoint o = getTopLeft();
-- rebuild();
-- fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
-- fputs("<freenote version=\"2.0\">\n", fp);
-- char buf[1024];
-- for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
-- FNPolygon p(*_draws.at(i));
-- p.translate(_origin.x(), _origin.y());
-- if (p.type() == FN_BEZIER) {
-- sprintf(buf, "\t<bz color=\"%x\" width=\"%d\">\n", (uint)p.pen().color().rgb(), p.pen().width());
-- } else if (p.type() == FN_ELLIPSE) {
-- sprintf(buf, "\t<el color=\"%x\" width=\"%d\">\n", (uint)p.pen().color().rgb(), p.pen().width());
-- } else {
-- sprintf(buf, "\t<po color=\"%x\" width=\"%d\">\n", (uint)p.pen().color().rgb(), p.pen().width());
-- }
-- fputs(buf, fp);
-- QPointArray& points = p.points();
-- for (uint j = 0; j < points.count(); ++j) {
-- QPoint point = points.point(j);
-- sprintf(buf, "\t\t<p x=\"%d\" y=\"%d\"/>\n", point.x(), point.y());
-- fputs(buf, fp);
-- }
-- if (p.type() == FN_BEZIER) {
-- fputs("\t</bz>\n", fp);
-- } else if (p.type() == FN_ELLIPSE) {
-- fputs("\t</el>\n", fp);
-- } else {
-- fputs("\t</po>\n", fp);
-- }
-- }
-- fputs("</freenote>\n", fp);
-- fclose(fp);
-- if (_isUseAllQuadrant) {
-- setOrigin(-o.x(), -o.y());
-- }
-- FNMessageBox::information(0, "FreeNoteQt", "save complete.");
-- return true;
--}
--
--bool FNCanvas::load(const QFileInfo& info)
--{
-- if (0 == info.fileName().length()) {
-- QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
-- return false;
-- }
-- if (!info.exists()) {
-- QMessageBox::warning(0,"FreeNoteQt", "file not exists.");
-- return false;
-- }
-- FILE* fp = NULL;
-- if (!(fp = fopen(info.absFilePath().utf8(), "rt"))) {
-- QMessageBox::warning(0,"FreeNoteQt", "could not open file.");
-- return false;
-- }
-- clear();
--
-- QString line;
-- FNPointList points;
-- points.setAutoDelete(true);
-- int c;
-- int w;
-- QPen pen(Qt::black, 1);
-- FNPolygon* polygon;
--
-- char rdbuf[1024];
-- char buf[1024];
-- QString type = "";
-- while (!feof(fp)) {
-- fgets(rdbuf, sizeof(rdbuf), fp);
-- line = rdbuf;
-- if (-1 != line.find("<fnpolygon ") ||
-- -1 != line.find("<po ") ||
-- -1 != line.find("<bz ") ||
-- -1 != line.find("<el ")
-- ) {
-- if (-1 != line.find("<el ")) {
-- type = "Ellipse";
-- } else if (-1 != line.find("<bz ")) {
-- type = "Bezier";
-- } else {
-- type = "Polygon";
-- }
-- points.clear();
-- int st = line.find("color") + 7;
-- int ed = line.find("\"", st);
-- strcpy(buf, line.mid(st, ed - st).utf8());
-- sscanf(buf, "%x", &c);
-- st = line.find("width") + 7;
-- ed = line.find("\"", st);
-- strcpy(buf, line.mid(st, ed - st).utf8());
-- sscanf(buf, "%d", &w);
-- } else if (-1 != line.find("<point ") ||
-- -1 != line.find("<p ")
-- ) {
-- int st = line.find("x=") + 3;
-- int ed = line.find("\"", st);
-- strcpy(buf, line.mid(st, ed - st).utf8());
-- int x;
-- sscanf(buf, "%d", &x);
--
-- st = line.find("y=") + 3;
-- ed = line.find("\"", st);
-- strcpy(buf, line.mid(st, ed - st).utf8());
-- int y;
-- sscanf(buf, "%d", &y);
-- points.append(createPts(x, y)); //バグ対策
-- } else if (-1 != line.find("</fnpolygon") ||
-- -1 != line.find("</bz") ||
-- -1 != line.find("</el") ||
-- -1 != line.find("</po")) {
-- pen.setColor((QRgb)c);
-- pen.setWidth(w);
-- if (type == "Bezier") {
-- _draws.append(polygon = createBezier(pen)); //バグ対策
-- } else if (type == "Ellipse") {
-- _draws.append(polygon = createEllipse(pen)); //バグ対策
-- } else {
-- _draws.append(polygon = createPolygon(pen)); //バグ対策
-- }
-- polygon->setPoints(points);
-- points.clear();
-- }
-- }
-- fclose(fp);
-- int x = 0;
-- int y = 0;
-- for (uint i = 0; i < _draws.count(); ++i) {
-- if (y > _draws.at(i)->boundingRect().top()) {
-- y = _draws.at(i)->boundingRect().top();
-- }
-- if (x > _draws.at(i)->boundingRect().left()) {
-- x = _draws.at(i)->boundingRect().left();
-- }
-- }
-- for (uint i = 0; i < _draws.count(); ++i) {
-- _draws.at(i)->translate(-x, -y);
-- }
-- redraw();
-- FNMessageBox::information(0,"FreeNoteQt", "load complete.");
--
-- return true;
--}
--
--FNPolygon* FNCanvas::createPolygon(QPen& pen)
--{
-- return new FNPolygon(pen);
--}
--
--FNPolygon* FNCanvas::createBezier(QPen& pen)
--{
-- return new FNBezier(pen);
--}
--
--
--FNPolygon* FNCanvas::createEllipse(QPen& pen)
--{
-- return new FNEllipse(pen);
--}
--
--QPoint* FNCanvas::createPts(int x, int y)
--{
-- return new QPoint(x, y);
--}
--
--void FNCanvas::setGuide(bool f)
--{
-- _isShowGuide = f;
-- redraw();
--}
-+/* FreeNote for Sharp SLA300, B500, C7x0 Linux PDA
-+ Copyright (C) 2003 Joe Kanemori.<kanemori@ymg.urban.ne.jp>
-+
-+ 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
-+*/
-+/*
-+2003/12/23 ver 1.6.1
-+・保存情報のサイズ縮小
-+
-+2003/12/16-19 ver 1.5.5pre
-+・ペンサイズの追加(1-8)
-+・アンドゥ・リドゥの実装
-+
-+2003/12/14 ver 1.5.4pre
-+・ペンサイズを選択可能に。
-+
-+2003/12/05 ver 1.5.3Apre
-+・グリッドの色を修正
-+
-+2003/12/04 ver 1.5.3pre
-+・グリッドの描画を一部修正
-+
-+2003/11/10 ver 1.5.1pre
-+・曲線整形モード追加
-+
-+2003/11/09 ver 1.5.0pre
-+・自動整形モード追加
-+
-+2003/09/03 ver 1.3.4pre
-+・Use all quadrant OFF時に表示位置がリセットされる場合があるバグ対応。
-+
-+2003/09/01-03 ver 1.3.3pre
-+・スクロールの改良
-+・Use all quadrant(全象限を使用する)メニューを追加
-+
-+2003/08/31 FreeNote 1.3.2pre
-+・全方向スクロール
-+
-+2003/08/23 FreeNote 1.3.0pre
-+・CR動作の修正
-+
-+2003/08/15 FreeNote 1.2.1を公開
-+・保存時のバグ修正
-+・完了ダイアログの自動消去
-+・PNGファイルへの出力
-+
-+2003/08/15 FreeNote 1.2を公開
-+・オプション追加
-+・スクロールガイド
-+・Freeファイル関連付け
-+・アイコンの変更
-+
-+2003/08/05 FreeNote 1.1.1preを公開
-+・高速起動時に閉じた状態を保持
-+・描画モード切替え時に消しゴム表示
-+・保存時間短縮
-+・Viewモードの挙動を変更
-+・メニューの見た目を変更
-+*/
-+#include "fncanvas.h"
-+#include <stdio.h>
-+#include <qfile.h>
-+#include <qmessagebox.h>
-+#include <qtextstream.h>
-+#include <qpen.h>
-+#include <qcolor.h>
-+#include <qpoint.h>
-+#include <qthread.h>
-+#include <qimage.h>
-+#include <math.h>
-+#include <stdlib.h> // abs
-+#include "fnmessagebox.h"
-+#include "fmtengine.h"
-+
-+int snap(int v) {
-+ int tv = abs(v);
-+ tv = ((int)(tv + SNAP_SIZE / 2) / SNAP_SIZE) * SNAP_SIZE;
-+ if (0 > v) {
-+ return -tv;
-+ } else {
-+ return tv;
-+ }
-+}
-+
-+FNCanvas::FNCanvas(QWidget* parent, const char* name, WFlags f )
-+ :QWidget(parent, name, f),
-+ _pen(black, 1, SolidLine, RoundCap, RoundJoin),
-+ _asMode(AS_NONE),
-+ _drawMode(MODE_DRAW),
-+ _disp_offset(0),
-+ _eraser_l(50),
-+ _eraser_s(10),
-+ _h_step(100),
-+ _v_step(100),
-+ _margin(5),
-+ _scrollTiming(800),
-+ _viewMode(false),
-+ _isWaiting(false),
-+ _isDragging(false),
-+ _isHeadingEnables(false),
-+ _isShowGuide(false),
-+ _isUseAllQuadrant(false),
-+ _scale_x(1.0),
-+ _scale_y(1.0)
-+{
-+ _tracks.setAutoDelete(true);
-+ this->setBackgroundMode(NoBackground);
-+ _timer = new QTimer(this);
-+ connect(_timer, SIGNAL(timeout()), this, SLOT(autoScroll()));
-+}
-+
-+FNCanvas::~FNCanvas()
-+{
-+ _timer->stop();
-+ delete _timer;
-+
-+ _tracks.clear();
-+ clearList(_draws);
-+}
-+
-+void FNCanvas::setScrollTiming(int v)
-+{
-+ _scrollTiming = v;
-+}
-+
-+
-+void FNCanvas::setVStep(int v)
-+{
-+ _v_step = v;
-+}
-+
-+void FNCanvas::setHStep(int v)
-+{
-+ _h_step = v;
-+}
-+
-+void FNCanvas::setSEraser(int v)
-+{
-+ _eraser_s = v;
-+}
-+
-+void FNCanvas::setLEraser(int v)
-+{
-+ _eraser_l = v;
-+}
-+
-+
-+void FNCanvas::setMargin(int v)
-+{
-+ if (v < 3) {
-+ v = 3;
-+ }
-+ _margin = v;
-+}
-+
-+void FNCanvas::setScrollMode(int as)
-+{
-+ _asMode = as;
-+ redraw();
-+}
-+
-+void FNCanvas::autoScroll()
-+{
-+ if (AS_NONE == _asMode) {
-+ if (MODE_FORMAT == _drawMode || MODE_CURVE == _drawMode || MODE_SMOOTH == _drawMode) {
-+ setOrigin(_origin.x(), _origin.y());
-+ }
-+ return;
-+ }
-+ bool tmp = _isHeadingEnables;
-+ int dx = 0;
-+ int dy = 0;
-+ if (AS_BOTH == _asMode || AS_HORIZONTAL == _asMode) {
-+ if (_last.x() > width() * (_margin - 1) / _margin) {
-+ dx = _h_step;
-+ } else if (_last.x() < width() / _margin) {
-+ dx = -_h_step;
-+ }
-+ }
-+ if (AS_BOTH == _asMode || AS_VERTICAL == _asMode) {
-+ if (_last.y() > height() * (_margin - 1) / _margin) {
-+ dy = _v_step;
-+ } else if (_last.y() < height() / _margin) {
-+ dy = -_v_step;
-+ }
-+ }
-+ setOrigin(_origin.x() + dx, _origin.y() + dy);
-+ _isHeadingEnables = tmp;
-+}
-+
-+void FNCanvas::mousePressEvent(QMouseEvent* evt)
-+{
-+ setFocus();
-+ _timer->stop();
-+ _tracks.clear();
-+ if (_viewMode) {
-+ _isWaiting = true;
-+ _viewMode = false;
-+ setOrigin((int)((evt->x()) / _scale_x) - width() / 2, (int)((evt->y()) / _scale_y) - height() / 2);
-+ redraw();
-+ emit resetViewMode();
-+ } else if (MODE_ERASE != _drawMode) {
-+ _last = evt->pos();
-+ _tracks.append(new QPoint(_last));
-+ } else {
-+ redraw();
-+ _last = evt->pos();
-+ _tracks.append(new QPoint(_last));
-+
-+ QPainter pbuf;
-+ QPainter pwin;
-+ pbuf.begin(&_buffer);
-+ pwin.begin(this);
-+
-+ int w = _eraser_s;
-+ if (PENWIDTH_MAX / 2 < _pen.width()) {
-+ w = _eraser_l;
-+ }
-+ pbuf.setRasterOp(XorROP);
-+ pbuf.setPen(QPen(white, 1));
-+ pbuf.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
-+
-+ pwin.setRasterOp(XorROP);
-+ pwin.setPen(QPen(white, 1));
-+ pwin.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
-+
-+ pbuf.end();
-+ pwin.end();
-+ }
-+ _isDragging = true;
-+}
-+
-+void FNCanvas::mouseMoveEvent(QMouseEvent* evt)
-+{
-+ if (_isWaiting) {
-+ return;
-+ }
-+ if (MODE_ERASE != _drawMode) {
-+ QPainter pwin;
-+ QPainter pbuf;
-+
-+ pwin.begin(this);
-+ pbuf.begin(&_buffer);
-+
-+ pwin.setPen(_pen);
-+ pbuf.setPen(_pen);
-+
-+ pwin.drawLine(_last, evt->pos());
-+ pbuf.drawLine(_last, evt->pos());
-+
-+ pwin.end();
-+ pbuf.end();
-+ _last = evt->pos();
-+ _tracks.append(new QPoint(_last));
-+ } else {
-+ //redraw();
-+ if (_last.x() == -1) {
-+ return;
-+ }
-+ QPainter pbuf;
-+ QPainter pwin;
-+
-+ pbuf.begin(&_buffer);
-+ pwin.begin(this);
-+
-+ int w = _eraser_s;
-+ if (PENWIDTH_MAX / 2 < _pen.width()) {
-+ w = _eraser_l;
-+ }
-+ pbuf.setRasterOp(XorROP);
-+ pwin.setRasterOp(XorROP);
-+ pbuf.setPen(QPen(white, 1));
-+ pwin.setPen(QPen(white, 1));
-+ pbuf.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
-+ pwin.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
-+
-+ _tracks.append(new QPoint(evt->pos()));
-+ _last = evt->pos();
-+
-+ pbuf.setRasterOp(CopyROP);
-+ pwin.setRasterOp(CopyROP);
-+ QRect r = QRect(0, 0, width(), height());
-+ for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
-+ FNPolygon* p = _draws.at(i);
-+ if (r.intersects(p->boundingRect())) {
-+ bool f = false;
-+ QRect selected(_last.x() - w / 2, _last.y() - w / 2, w, w);
-+ for (uint j = 0; j < p->points().count(); ++j) {
-+ QPoint& pts = p->points().at(j);
-+ if (selected.contains(pts)) {
-+ f = true;
-+ break;
-+ }
-+ }
-+ if (f) {
-+ p->drawShape(pbuf, f);
-+ p->drawShape(pwin, f);
-+ }
-+ }
-+ }
-+ pbuf.setRasterOp(XorROP);
-+ pwin.setRasterOp(XorROP);
-+ pbuf.setPen(QPen(white, 1));
-+ pwin.setPen(QPen(white, 1));
-+ pbuf.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
-+ pwin.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
-+ pbuf.end();
-+ pwin.end();
-+ }
-+}
-+
-+void FNCanvas::mouseReleaseEvent(QMouseEvent* evt)
-+{
-+ _isDragging = false;
-+ if (_isWaiting) {
-+ _isWaiting = false;
-+ return;
-+ }
-+ _last = evt->pos();
-+ if (MODE_ERASE != _drawMode) {
-+ if (1 < _tracks.count()) {
-+ FNPolygon* p = NULL;
-+ if (MODE_FORMAT == _drawMode) {
-+ p = new FNPolygon(_pen);
-+ _tracks = AutoFormat(_tracks);
-+ } else if (MODE_CURVE == _drawMode) {
-+ QPoint sp = SnapPoint(*_tracks.at(0));
-+ QPoint ep = SnapPoint(*_tracks.at(_tracks.count()-1));
-+ _tracks = AutoCurve(_tracks);
-+ if (sp == ep) {
-+ p = new FNEllipse(_pen);
-+ } else if (2 < _tracks.count()) {
-+ p = new FNBezier(_pen);
-+ } else {
-+ p = new FNPolygon(_pen);
-+ }
-+ } else if (MODE_SMOOTH == _drawMode) {
-+ _tracks = Smoothing(_tracks);
-+ if (2 < _tracks.count()) {
-+ p = new FNBezier(_pen);
-+ } else {
-+ p = new FNPolygon(_pen);
-+ }
-+ } else {
-+ _tracks = Reduce(_tracks);
-+ p = new FNPolygon(_pen);
-+ }
-+ if (1 < _tracks.count()) {
-+ p->setPoints(_tracks);
-+ redobuf_flush();
-+ _draws.append(p);
-+ }
-+ }
-+ _tracks.clear();
-+ _isHeadingEnables = true;
-+ _timer->start(_scrollTiming, true);
-+ } else {
-+ _last = QPoint(-1, -1);
-+ _tracks.append(new QPoint(evt->pos()));
-+ redraw();
-+ }
-+}
-+
-+void FNCanvas::paintEvent(QPaintEvent* evt)
-+{
-+ bitBlt(this, 0, 0, &_buffer);
-+}
-+
-+void FNCanvas::resizeEvent(QResizeEvent* evt)
-+{
-+ QPixmap save(_buffer);
-+ _buffer.resize(evt->size());
-+ _buffer.fill(white);
-+ bitBlt(&_buffer, 0, 0, &save);
-+ redraw();
-+}
-+
-+void FNCanvas::setOrigin(QPoint& o)
-+{
-+ this->setOrigin(o.x(), o.y());
-+}
-+
-+QPoint FNCanvas::getTopLeft()
-+{
-+ if (0 == _draws.count() || !_isUseAllQuadrant) {
-+ return _origin;
-+ }
-+
-+ int dx = ((FNPolygon*)_draws.at(0))->boundingRect().x();
-+ int dy = ((FNPolygon*)_draws.at(0))->boundingRect().y();
-+ for (uint i = 1; i < _draws.count(); ++i) {
-+ FNPolygon* p = _draws.at(i);
-+ if (dx > p->boundingRect().x()) {
-+ dx = p->boundingRect().x();
-+ }
-+ if (dy > p->boundingRect().y()) {
-+ dy = p->boundingRect().y();
-+ }
-+ }
-+ return QPoint(snap(dx), snap(dy));
-+}
-+
-+
-+void FNCanvas::rebuild()
-+{
-+ if (0 == _draws.count() || !_isUseAllQuadrant) {
-+ return;
-+ }
-+
-+ QPoint d = getTopLeft();
-+ for (uint i = 0; i < _draws.count(); ++i) {
-+ FNPolygon* p = _draws.at(i);
-+ p->translate(-d.x(), -d.y());
-+ }
-+
-+ _origin = QPoint(0, 0);
-+}
-+
-+
-+void FNCanvas::setOrigin(int ox, int oy)
-+{
-+ ox = snap(ox);
-+ oy = snap(oy);
-+ _isHeadingEnables = false;
-+ _timer->stop();
-+
-+
-+ int dx = 0;
-+ int dy = 0;
-+ if (!_isUseAllQuadrant) {
-+ if (0 > ox) {
-+ ox = 0;
-+ }
-+ if (0 > oy) {
-+ oy = 0;
-+ }
-+ dx = _origin.x() - ox;
-+ dy = _origin.y() - oy;
-+ } else {
-+ dx = _origin.x() - ox;
-+ dy = _origin.y() - oy;
-+ if (0 > ox) {
-+ ox = 0;
-+ }
-+ if (0 > oy) {
-+ oy = 0;
-+ }
-+ }
-+ for (uint i = 0; i < _tracks.count(); ++i) {
-+ QPoint* p = _tracks.at(i);
-+ p->setX(p->x() + dx);
-+ p->setY(p->y() + dy);
-+ }
-+
-+ for (uint i = 0; i < _draws.count(); ++i) {
-+ FNPolygon* p = _draws.at(i);
-+ p->translate(dx, dy);
-+ }
-+ _origin = QPoint(ox, oy);
-+ emit originChanged(ox, oy);
-+ redraw();
-+}
-+
-+void FNCanvas::redraw()
-+{
-+ if (!this->isVisible()) {
-+ return;
-+ }
-+ _buffer.fill(white);
-+ QPainter pbuf;
-+ QRect r = QRect(0, 0, width(), height());
-+ pbuf.begin(&_buffer);
-+ if (_viewMode) {
-+ float wx = 0;
-+ float wy = 0;
-+ for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
-+ FNPolygon* p = _draws.at(i);
-+ QRect r = p->boundingRect();
-+ if (wx < r.right()) {
-+ wx = r.right();
-+ }
-+ if (wy < r.bottom()) {
-+ wy = r.bottom();
-+ }
-+ }
-+ wx += SNAP_SIZE;
-+ wy += SNAP_SIZE;
-+ wx = snap((int)wx);
-+ wy = snap((int)wy);
-+ wx = wx + _origin.x();
-+ wy = wy + _origin.y();
-+ _scale_x = (float)width() / wx;
-+ _scale_y = (float)height() / wy;
-+ if (1.0f < _scale_x) {
-+ _scale_x = 1.0f;
-+ }
-+ if (1.0f < _scale_y) {
-+ _scale_y = 1.0f;
-+ }
-+ if (_scale_x > _scale_y) {
-+ _scale_x = _scale_y;
-+ } else if (_scale_x < _scale_y) {
-+ _scale_y = _scale_x;
-+ }
-+ for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
-+ FNPolygon* p = _draws.at(i);
-+ FNPolygon* t = NULL;
-+ if (p->type() == FN_BEZIER) {
-+ t = new FNBezier(*(FNBezier*)p);
-+ } else if (p->type() == FN_ELLIPSE) {
-+ t = new FNEllipse(*(FNEllipse*)p);
-+ } else {
-+ t = new FNPolygon(*p);
-+ }
-+ t->translate(-_origin.x(), -_origin.y());
-+ for (uint j = 0; j < t->points().count(); ++j) {
-+ QPoint& pts = t->points().at(j);
-+ int x = (int)(pts.x() * _scale_x);
-+ int y = (int)(pts.y() * _scale_y);
-+ pts.setX(x);
-+ pts.setY(y);
-+ }
-+ double pensize = t->pen().width();
-+ if (_scale_x > _scale_y) {
-+ pensize = pensize * _scale_y;
-+ } else {
-+ pensize = pensize * _scale_x;
-+ }
-+ if (0 >= pensize) {
-+ pensize = 1;
-+ }
-+ t->pen().setWidth(pensize);
-+ t->drawShape(pbuf);
-+ delete t;
-+ }
-+ } else if (MODE_ERASE != _drawMode) {
-+ if (MODE_FORMAT == _drawMode || MODE_CURVE == _drawMode) {
-+ QPen pen1(QColor(0, 240, 240), 1);
-+ QPen pen2(QColor(0, 0, 0), 1);
-+ pbuf.setPen(QPen(QColor(0, 240, 240), 1));
-+ pbuf.setPen(pen1);
-+ for (int x = 0; x < width() + SNAP_SIZE; x += SNAP_SIZE) {
-+ pbuf.drawLine(x - SNAP_SIZE / 2, 0, x - SNAP_SIZE / 2, height());
-+ for (int y = 0; y < height() + SNAP_SIZE; y += SNAP_SIZE) {
-+ pbuf.drawLine(0, y - SNAP_SIZE / 2, width(), y - SNAP_SIZE / 2);
-+ pbuf.drawRect(x-1,y-1,2,2);
-+ }
-+ }
-+ }
-+ if (_isShowGuide) {
-+ pbuf.setPen(QPen(cyan, 1, DashLine));
-+ if (AS_HORIZONTAL == _asMode || AS_BOTH == _asMode) {
-+ if (0 != _origin.x() || _isUseAllQuadrant) {
-+ pbuf.drawLine(width() / _margin, 0, width() / _margin, height());
-+ }
-+ pbuf.drawLine(width() * (_margin - 1) / _margin, 0, width() * (_margin - 1) / _margin, height());
-+ }
-+
-+ if (AS_VERTICAL == _asMode || AS_BOTH == _asMode) {
-+ if (0 != _origin.y() || _isUseAllQuadrant) {
-+ pbuf.drawLine(0, height() / _margin, width(), height() / _margin);
-+ }
-+ pbuf.drawLine(0, height() * (_margin - 1) / _margin, width(), height() * (_margin - 1) / _margin);
-+ }
-+ }
-+
-+ for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
-+ FNPolygon* p = _draws.at(i);
-+ if (r.intersects(p->boundingRect())) {
-+ p->drawShape(pbuf);
-+ }
-+ }
-+ } else {
-+ int w = _eraser_s;
-+ if (PENWIDTH_MAX / 2 < _pen.width()) {
-+ w = _eraser_l;
-+ }
-+ FNPointList removes;
-+ for (uint i = 0; i < _tracks.count(); ++i) {
-+ removes.append(_tracks.at(i));
-+ }
-+ for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
-+ FNPolygon* p = _draws.at(i);
-+ if (r.intersects(p->boundingRect())) {
-+ bool f = false;
-+ for (uint j = 0; j < _tracks.count(); ++j) {
-+ QPoint* pts = _tracks.at(j);
-+ QRect selected(pts->x() - w / 2, pts->y() - w / 2, w, w);
-+ for (uint k = 0; k < p->points().count(); ++k) {
-+ QPoint& pts2 = p->points().at(k);
-+ if (selected.contains(pts2)) {
-+ f = true;
-+ removes.remove(pts);
-+ break;
-+ }
-+ }
-+ if (f) {
-+ break;
-+ }
-+ }
-+ p->drawShape(pbuf, f);
-+ }
-+ }
-+ for (uint i = 0; i < removes.count(); ++i) {
-+ _tracks.remove(removes.at(i));
-+ }
-+ /*
-+ if (_isDragging) {
-+ pbuf.setPen(QPen(black, 1));
-+ pbuf.drawRect(_last.x() - w / 2, _last.y() - w / 2, w, w);
-+ }
-+ */
-+ }
-+ pbuf.end();
-+ repaint();
-+}
-+
-+void FNCanvas::changeColor(QRgb c)
-+{
-+ _pen.setColor(QColor(c));
-+}
-+
-+void FNCanvas::undo()
-+{
-+ if (MODE_ERASE != _drawMode) {
-+ ++_disp_offset;
-+ if (_disp_offset > _draws.count()) {
-+ _disp_offset = _draws.count();
-+ }
-+ } else {
-+ _draws = _undobuf;
-+ _marks.clear();
-+ }
-+ redraw();
-+}
-+
-+void FNCanvas::redo()
-+{
-+ if (MODE_ERASE != _drawMode) {
-+ if (0 < _disp_offset) {
-+ --_disp_offset;
-+ }
-+ }
-+ redraw();
-+}
-+
-+void FNCanvas::clearList(FNPolygonList& list)
-+{
-+ list.setAutoDelete(true);
-+ list.clear();
-+ list.setAutoDelete(false);
-+}
-+
-+void FNCanvas::clear()
-+{
-+ _disp_offset = 0;
-+ clearList(_draws);
-+ _undobuf.clear();
-+ setOrigin(0, 0);
-+ redraw();
-+}
-+
-+void FNCanvas::viewChanged(bool flg)
-+{
-+ _tracks.clear();
-+ _viewMode = flg;
-+ if (_viewMode) {
-+ if (_isUseAllQuadrant) {
-+ rebuild();
-+ }
-+ setOrigin(0, 0);
-+ }
-+ redraw();
-+}
-+
-+void FNCanvas::redobuf_flush()
-+{
-+ for (uint i = 0; i < _disp_offset; ++i) {
-+ FNPolygon* p = _draws.last();
-+ _draws.remove(p);
-+ delete p;
-+ }
-+ _disp_offset = 0;
-+}
-+
-+void FNCanvas::modeChanged(int mode)
-+{
-+ _tracks.clear();
-+ _drawMode = mode;
-+ redobuf_flush();
-+ if (MODE_ERASE == _drawMode) {
-+ _marks.clear();
-+ _undobuf = _draws;
-+ } else {
-+ if (_draws.count() != _undobuf.count()) {
-+ for (uint i = 0; i < _marks.count(); ++i) {
-+ FNPolygon* p = _marks.at(i);
-+ _draws.remove(p);
-+ }
-+ clearList(_marks);
-+ }
-+ }
-+ redraw();
-+}
-+
-+QRect FNCanvas::getMatrix(const QRect& r) const
-+{
-+ int ox = _origin.x();
-+ int oy = _origin.y();
-+ const int wide = 100;
-+
-+ int left = r.left() + ox;
-+ int top = r.top() + oy;
-+ int right = r.right() + ox;
-+ int bottom = r.bottom() + oy;
-+
-+ left = (int)(left / wide) * wide;
-+ top = (int)(top / wide) * wide;
-+ right = (right % wide == 0 && left != right) ? right : (int)((right + wide) / wide) * wide;
-+ bottom = (bottom % wide == 0 && top != bottom) ? bottom : (int)((bottom + wide) / wide) * wide;
-+
-+ return QRect(left - ox, top - oy, right - left, bottom - top);
-+}
-+
-+void FNCanvas::CR()
-+{
-+ if (MODE_ERASE == _drawMode) {
-+ return;
-+ }
-+ if (_isHeadingEnables) {
-+ //lastから、左方向に向けて探索する。
-+ QRect r = getMatrix(_draws.last()->boundingRect());
-+ bool isSearching = true;
-+ r.moveBy(-100, 0);
-+ while (isSearching) {
-+ isSearching = false;
-+ for (uint i = 0; i < _draws.count(); ++i) {
-+ FNPolygon* p = _draws.at(i);
-+ const QRect& r2 = p->boundingRect();
-+ if (r.intersects(r2)) {
-+ if (r.left() + 100 > r2.left()) {
-+ r = getMatrix(r2);
-+ r.moveBy(-100, 0);
-+ isSearching = true;
-+ break;
-+ }
-+ }
-+ }
-+ }
-+ r.moveBy(100, 0);
-+ //lastが画面の4/5以下ならば、スクロールアップする。
-+ //そうでなければ、ヘッディングのみ。
-+ if (_last.y() > height() * 4 / 5) {
-+ setOrigin(_origin.x() + r.x(), _origin.y() + 50);
-+ } else {
-+ setOrigin(_origin.x() + r.x(), _origin.y());
-+ }
-+ _isHeadingEnables = false;
-+ } else {
-+ //lastの周囲に何も無い場合は、縦にスクロールする。
-+ setOrigin(_origin.x(), _origin.y() + 50);
-+ }
-+}
-+
-+void FNCanvas::erase()
-+{
-+ if (MODE_ERASE != _drawMode) {
-+ return;
-+ }
-+ FNPolygonList temp;
-+ int w = _eraser_s;
-+ if (PENWIDTH_MAX / 2 < _pen.width()) {
-+ w = _eraser_l;
-+ }
-+ QRect r = QRect(0, 0, width(), height());
-+ for (uint i = 0; i < _draws.count(); ++i) {
-+ FNPolygon* p = _draws.at(i);
-+ bool f = false;
-+ if (r.intersects(p->boundingRect())) {
-+ for (uint j = 0; j < _tracks.count(); ++j) {
-+ QPoint* pts = _tracks.at(j);
-+ QRect selected(pts->x() - w / 2, pts->y() - w / 2, w, w);
-+ for (uint k = 0; k < p->points().count(); ++k) {
-+ QPoint& pts2 = p->points().at(k);
-+ if (selected.contains(pts2)) {
-+ temp.append(p);
-+ f = true;
-+ break;
-+ }
-+ }
-+ if (f) {
-+ break;
-+ }
-+ }
-+ }
-+ }
-+ for (uint i = 0; i < temp.count(); ++i) {
-+ _draws.remove(temp.at(i));
-+ _marks.append(temp.at(i));
-+ }
-+ _tracks.clear();
-+ redraw();
-+}
-+
-+void FNCanvas::setPensize(int sz)
-+{
-+ _pen.setWidth(sz);
-+}
-+
-+bool FNCanvas::exportPNG(const QFileInfo& info, QPixmap& buf)
-+{
-+ if (0 == info.fileName().length()) {
-+ QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
-+ return false;
-+ }
-+ if (info.extension(false) != "png") {
-+ QMessageBox::warning(0,"FreeNoteQt", "extension '.png' expected.");
-+ return false;
-+ }
-+
-+ bool ret = buf.save(info.absFilePath(), "PNG");
-+ if (ret) {
-+ FNMessageBox::information(0,"FreeNoteQt", "export PNG complete.");
-+ } else {
-+ QMessageBox::warning(0,"FreeNoteQt", "could not export file.");
-+ }
-+ return ret;
-+}
-+
-+QString FNCanvas::mkPDFscript(FNPolygon* elm)
-+{
-+ QString s ="";
-+ char buf[1024];
-+
-+ float r = (float)elm->pen().color().red() / 255.0f;
-+ float g = (float)elm->pen().color().green() / 255.0f;
-+ float b = (float)elm->pen().color().blue() / 255.0f;
-+ s += "q\n";
-+ sprintf(buf, "%f %f %f RG\n", r, g, b);
-+ s += buf;
-+ QPointArray points = elm->points().copy();
-+ points.translate(_origin.x(), _origin.y());
-+ if (elm->type() == FN_BEZIER) {
-+ sprintf(buf, "%d %d m\n", points[0].x(), points[0].y());
-+ s += buf;
-+ for (uint j = 1; j < points.count(); j += 3) {
-+ sprintf(buf, "%d %d %d %d %d %d c\n",
-+ points[j].x(), points[j].y(),
-+ points[j + 1].x(), points[j + 1].y(),
-+ points[j + 2].x(), points[j + 2].y()
-+ );
-+ s += buf;
-+ }
-+ } else if (elm->type() == FN_ELLIPSE) {
-+ int x = points[0].x();
-+ int y = points[0].y();
-+ int ex = points[1].x();
-+ int ey = points[1].y();
-+ int w = ex - x;
-+ int h = ey - y;
-+ int cx = x + w/2;
-+ int cy = y;
-+ int x1 = x + 3*w/4;
-+ int y1 = y;
-+ int x2 = x + w;
-+ int y2 = y + h/4;
-+ int x3 = x + w;
-+ int y3 = y + h/2;
-+
-+ sprintf(buf, "%d %d m\n%d %d %d %d %d %d c\n", cx, cy, x1, y1, x2, y2, x3, y3);
-+ s += buf;
-+ x1 = x + w;
-+ y1 = y + 3 * h / 4;
-+ x2 = x + 3 * w / 4;
-+ y2 = y + h;
-+ x3 = x + w/2;
-+ y3 = y + h;
-+ sprintf(buf, "%d %d %d %d %d %d c\n", x1, y1, x2, y2, x3, y3);
-+ s += buf;
-+
-+ x1 = x + w / 4;
-+ y1 = y + h;
-+ x2 = x;
-+ y2 = y + 3 * h / 4;
-+ x3 = x;
-+ y3 = y + h / 2;
-+ sprintf(buf, "%d %d %d %d %d %d c\n", x1, y1, x2, y2, x3, y3);
-+ s += buf;
-+ x1 = x;
-+ y1 = y + h / 4;
-+ x2 = x + w / 4;
-+ y2 = y;
-+ x3 = x + w / 2;
-+ y3 = y;
-+ sprintf(buf, "%d %d %d %d %d %d c\n", x1, y1, x2, y2, x3, y3);
-+ s += buf;
-+ } else {
-+ sprintf(buf, "%d %d m\n", points[0].x(), points[0].y());
-+ s += buf;
-+ for (uint j = 1; j < points.count(); ++j) {
-+ sprintf(buf, "%d %d l\n", points[j].x(), points[j].y());
-+ s += buf;
-+ }
-+ }
-+ sprintf(buf, "%d w\n", elm->pen().width());
-+ s += buf;
-+ s += "S\n";
-+ s += "Q\n";
-+ return s;
-+}
-+
-+bool FNCanvas::exportPDF(const QFileInfo& info)
-+{
-+ if (0 == info.fileName().length()) {
-+ QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
-+ return false;
-+ }
-+ if (info.extension(false) != "pdf") {
-+ QMessageBox::warning(0,"FreeNoteQt", "extension '.pdf' expected.");
-+ return false;
-+ }
-+
-+ FILE* fp = NULL;
-+ if (!(fp = fopen(info.absFilePath().utf8(), "wt"))) {
-+ QMessageBox::warning(0,"FreeNoteQt", "could not export file.");
-+ return false;
-+ }
-+
-+ QPoint o = getTopLeft();
-+ rebuild();
-+ int wx = 595;
-+ int wy = 842;
-+ char buf[1024];
-+ for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
-+ FNPolygon* p = _draws.at(i);
-+ QRect r = p->boundingRect();
-+ r.moveBy(_origin.x(), _origin.y());
-+ if (wx < r.right()) {
-+ wx =r.right();
-+ }
-+ if (wy < r.bottom()) {
-+ wy = r.bottom();
-+ }
-+ }
-+
-+ int len = 0;
-+
-+ sprintf(buf, "1 0 0 -1 0 %d cm\n", wy);
-+ QString cm = buf;
-+ len += cm.length();
-+
-+ for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
-+ QString s = mkPDFscript(_draws.at(i));
-+ len += s.length();
-+ }
-+
-+ QString header = "";
-+ header += "%PDF-1.3\n";
-+ header += "1 0 obj\n";
-+ header += "<<\n";
-+ header += "/Type /Page\n";
-+ header += "/Parent 3 0 R\n";
-+ header += "/Resources\n";
-+ header += "<<\n";
-+ header += "/ProcSet [ /PDF ]\n";
-+ header += ">>\n";
-+ sprintf(buf, "/MediaBox [ 0 0 %010d %010d ]\n", wx, wy);
-+ header += buf;
-+ header += "/Contents 4 0 R\n";
-+ header += ">>\n";
-+ header += "endobj\n";
-+ header += "2 0 obj\n";
-+ header += "<<\n";
-+ header += "/Type /Catalog\n";
-+ header += "/Pages 3 0 R\n";
-+ header += "/PageLayout /OneColumn\n";
-+ header += "/OpenAction [1 0 R /XYZ null null 1 ]\n";
-+ header += ">>\n";
-+ header += "endobj\n";
-+ header += "3 0 obj\n";
-+ header += "<<\n";
-+ header += "/Type /Pages\n";
-+ header += "/Kids [ 1 0 R ]\n";
-+ header += "/Count 1\n";
-+ header += ">>\n";
-+ header += "endobj\n";
-+ header += "4 0 obj\n";
-+ sprintf(buf, "<< /Length %010d >>\n", len);
-+ header += buf;
-+ header += "stream\n";
-+
-+ QString footer = "";
-+ footer += "xref\n";
-+ footer += "0 5\n";
-+ footer += "0000000000 65535 f \n";
-+ footer += "0000000009 00000 n \n";
-+ footer += "0000000147 00000 n \n";
-+ footer += "0000000257 00000 n \n";
-+ footer += "0000000316 00000 n \n";
-+ footer += "trailer\n";
-+ footer += "<<\n";
-+ footer += "/Size 5\n";
-+ footer += "/Root 2 0 R\n";
-+ footer += ">>\n";
-+ footer += "startxref\n";
-+
-+ len = cm.length();
-+ len += header.length();
-+ fputs(header, fp);
-+ fputs(cm, fp);
-+
-+ for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
-+ QString s = mkPDFscript(_draws.at(i));
-+ len += s.length();
-+ fputs(s, fp);
-+ }
-+ QString streamfooter = "endstream\nendobj\n";
-+ len += streamfooter.length();
-+ fputs(streamfooter, fp);
-+
-+ fputs(footer, fp);
-+ sprintf(buf, "%d\n", len);
-+ fputs(buf, fp);
-+ fputs("%%EOF\n", fp);
-+ fclose(fp);
-+ if (_isUseAllQuadrant) {
-+ setOrigin(-o.x(), -o.y());
-+ }
-+ FNMessageBox::information(0,"FreeNoteQt", "export PDF complete.");
-+ return true;
-+}
-+
-+bool FNCanvas::save(const QFileInfo& info)
-+{
-+ if (0 == info.fileName().length()) {
-+ QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
-+ return false;
-+ }
-+ if (info.extension(false) != "free") {
-+ QMessageBox::warning(0,"FreeNoteQt", "extension '.free' expected.");
-+ return false;
-+ }
-+ FILE* fp = NULL;
-+ if (!(fp = fopen(info.absFilePath().utf8(), "wt"))) {
-+ QMessageBox::warning(0,"FreeNoteQt", "could not save file.");
-+ return false;
-+ }
-+ QPoint o = getTopLeft();
-+ rebuild();
-+ fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", fp);
-+ fputs("<freenote version=\"2.0\">\n", fp);
-+ char buf[1024];
-+ for (uint i = 0; i < _draws.count() - _disp_offset; ++i) {
-+ FNPolygon p(*_draws.at(i));
-+ p.translate(_origin.x(), _origin.y());
-+ if (p.type() == FN_BEZIER) {
-+ sprintf(buf, "\t<bz color=\"%x\" width=\"%d\">\n", (uint)p.pen().color().rgb(), p.pen().width());
-+ } else if (p.type() == FN_ELLIPSE) {
-+ sprintf(buf, "\t<el color=\"%x\" width=\"%d\">\n", (uint)p.pen().color().rgb(), p.pen().width());
-+ } else {
-+ sprintf(buf, "\t<po color=\"%x\" width=\"%d\">\n", (uint)p.pen().color().rgb(), p.pen().width());
-+ }
-+ fputs(buf, fp);
-+ QPointArray& points = p.points();
-+ for (uint j = 0; j < points.count(); ++j) {
-+ QPoint point = points.point(j);
-+ sprintf(buf, "\t\t<p x=\"%d\" y=\"%d\"/>\n", point.x(), point.y());
-+ fputs(buf, fp);
-+ }
-+ if (p.type() == FN_BEZIER) {
-+ fputs("\t</bz>\n", fp);
-+ } else if (p.type() == FN_ELLIPSE) {
-+ fputs("\t</el>\n", fp);
-+ } else {
-+ fputs("\t</po>\n", fp);
-+ }
-+ }
-+ fputs("</freenote>\n", fp);
-+ fclose(fp);
-+ if (_isUseAllQuadrant) {
-+ setOrigin(-o.x(), -o.y());
-+ }
-+ FNMessageBox::information(0, "FreeNoteQt", "save complete.");
-+ return true;
-+}
-+
-+bool FNCanvas::load(const QFileInfo& info)
-+{
-+ if (0 == info.fileName().length()) {
-+ QMessageBox::warning(0,"FreeNoteQt", "file name is empty.");
-+ return false;
-+ }
-+ if (!info.exists()) {
-+ QMessageBox::warning(0,"FreeNoteQt", "file not exists.");
-+ return false;
-+ }
-+ FILE* fp = NULL;
-+ if (!(fp = fopen(info.absFilePath().utf8(), "rt"))) {
-+ QMessageBox::warning(0,"FreeNoteQt", "could not open file.");
-+ return false;
-+ }
-+ clear();
-+
-+ QString line;
-+ FNPointList points;
-+ points.setAutoDelete(true);
-+ int c;
-+ int w;
-+ QPen pen(Qt::black, 1);
-+ FNPolygon* polygon;
-+
-+ char rdbuf[1024];
-+ char buf[1024];
-+ QString type = "";
-+ while (!feof(fp)) {
-+ fgets(rdbuf, sizeof(rdbuf), fp);
-+ line = rdbuf;
-+ if (-1 != line.find("<fnpolygon ") ||
-+ -1 != line.find("<po ") ||
-+ -1 != line.find("<bz ") ||
-+ -1 != line.find("<el ")
-+ ) {
-+ if (-1 != line.find("<el ")) {
-+ type = "Ellipse";
-+ } else if (-1 != line.find("<bz ")) {
-+ type = "Bezier";
-+ } else {
-+ type = "Polygon";
-+ }
-+ points.clear();
-+ int st = line.find("color") + 7;
-+ int ed = line.find("\"", st);
-+ strcpy(buf, line.mid(st, ed - st).utf8());
-+ sscanf(buf, "%x", &c);
-+ st = line.find("width") + 7;
-+ ed = line.find("\"", st);
-+ strcpy(buf, line.mid(st, ed - st).utf8());
-+ sscanf(buf, "%d", &w);
-+ } else if (-1 != line.find("<point ") ||
-+ -1 != line.find("<p ")
-+ ) {
-+ int st = line.find("x=") + 3;
-+ int ed = line.find("\"", st);
-+ strcpy(buf, line.mid(st, ed - st).utf8());
-+ int x;
-+ sscanf(buf, "%d", &x);
-+
-+ st = line.find("y=") + 3;
-+ ed = line.find("\"", st);
-+ strcpy(buf, line.mid(st, ed - st).utf8());
-+ int y;
-+ sscanf(buf, "%d", &y);
-+ points.append(createPts(x, y)); //バグ対策
-+ } else if (-1 != line.find("</fnpolygon") ||
-+ -1 != line.find("</bz") ||
-+ -1 != line.find("</el") ||
-+ -1 != line.find("</po")) {
-+ pen.setColor((QRgb)c);
-+ pen.setWidth(w);
-+ if (type == "Bezier") {
-+ _draws.append(polygon = createBezier(pen)); //バグ対策
-+ } else if (type == "Ellipse") {
-+ _draws.append(polygon = createEllipse(pen)); //バグ対策
-+ } else {
-+ _draws.append(polygon = createPolygon(pen)); //バグ対策
-+ }
-+ polygon->setPoints(points);
-+ points.clear();
-+ }
-+ }
-+ fclose(fp);
-+ int x = 0;
-+ int y = 0;
-+ for (uint i = 0; i < _draws.count(); ++i) {
-+ if (y > _draws.at(i)->boundingRect().top()) {
-+ y = _draws.at(i)->boundingRect().top();
-+ }
-+ if (x > _draws.at(i)->boundingRect().left()) {
-+ x = _draws.at(i)->boundingRect().left();
-+ }
-+ }
-+ for (uint i = 0; i < _draws.count(); ++i) {
-+ _draws.at(i)->translate(-x, -y);
-+ }
-+ redraw();
-+ FNMessageBox::information(0,"FreeNoteQt", "load complete.");
-+
-+ return true;
-+}
-+
-+FNPolygon* FNCanvas::createPolygon(QPen& pen)
-+{
-+ return new FNPolygon(pen);
-+}
-+
-+FNPolygon* FNCanvas::createBezier(QPen& pen)
-+{
-+ return new FNBezier(pen);
-+}
-+
-+
-+FNPolygon* FNCanvas::createEllipse(QPen& pen)
-+{
-+ return new FNEllipse(pen);
-+}
-+
-+QPoint* FNCanvas::createPts(int x, int y)
-+{
-+ return new QPoint(x, y);
-+}
-+
-+void FNCanvas::setGuide(bool f)
-+{
-+ _isShowGuide = f;
-+ redraw();
-+}
diff --git a/packages/nonworking/freenote/freenote_1.6.1.bb b/packages/nonworking/freenote/freenote_1.6.1.bb
deleted file mode 100644
index 3e4540a060..0000000000
--- a/packages/nonworking/freenote/freenote_1.6.1.bb
+++ /dev/null
@@ -1,22 +0,0 @@
-DESCRIPTION="Auto-Correction Paint Program for Opie/Qtopia"
-SECTION="base"
-PRIORITY="optional"
-LICENSE="GPL"
-
-SRC_URI = http://www.urban.ne.jp/home/kanemori/zaurus/FreeNote_${PV}_arm.tar.gz \
- file://${FILESDIR}/compile.patch;patch=1
-S = ${WORKDIR}/FreeNote_${PV}_arm
-
-inherit palmtop
-
-do_configure_prepend() {
- qmake -project -o ${PN}.pro
-}
-
-do_install() {
- install -d ${D}${palmtopdir}/{bin,apps/Applications,pics}
- install -D -m 755 freenoteeintu ${D}${palmtopdir}/bin/freenoteeintu
- install -D -m 644 ${FILESDIR}/freenoteeintu.desktop ${D}${palmtopdir}/apps/Applications/freenoteeintu.desktop
- install -d ${D}/${palmtopdir}/pics
- cp -pPR *.png ${D}${palmtopdir}/pics/
-}
diff --git a/packages/nslu2-binary-only/unslung-rootfs/NOTES b/packages/nslu2-binary-only/unslung-rootfs/NOTES
index 81cff3cb82..f4a7bf724b 100644
--- a/packages/nslu2-binary-only/unslung-rootfs/NOTES
+++ b/packages/nslu2-binary-only/unslung-rootfs/NOTES
@@ -524,3 +524,11 @@ Fix extraneous boot messages from jffs2 filesystem driver (change options
used when building the flash jffs image).
Added pl2303.c patch for TIOCMGET/MSET/MBIS/MBIC.
+
+Syntax fixes in prep for newer busybox:
+ - comments in rc.samba, "cp" in rc.sysinit
+
+Flash filesystem cleanup (regained space):
+ - replaced dupl 'date' utility with symlink, corrected 'killall' symlink
+ - removed 'mt', 'libexec' from flash
+ - adjusted 'unsling' to use common 'find' options
diff --git a/packages/nslu2-binary-only/unslung-rootfs/rc.samba-syntaxfix.patch b/packages/nslu2-binary-only/unslung-rootfs/rc.samba-syntaxfix.patch
new file mode 100644
index 0000000000..fcfc273f2b
--- /dev/null
+++ b/packages/nslu2-binary-only/unslung-rootfs/rc.samba-syntaxfix.patch
@@ -0,0 +1,23 @@
+--- nslu2-linksys-ramdisk-2.3r63/etc/rc.d/rc.samba~ 2006-05-16 14:22:33.000000000 -0500
++++ nslu2-linksys-ramdisk-2.3r63/etc/rc.d/rc.samba 2006-05-16 16:47:45.000000000 -0500
+@@ -5,16 +5,16 @@
+ if [ -n "`pidof smbd`" ] ; then
+ killall smbd 2>/dev/null
+ fi
+-if [ -n "`pidof smbd`" ] ; then
++#if [ -n "`pidof smbd`" ] ; then
+ # killall -9 smbd 2>/dev/null
+-fi
++#fi
+
+ if [ -n "`pidof nmbd`" ] ; then
+ killall nmbd 2>/dev/null
+ fi
+-if [ -n "`pidof nmbd`" ] ; then
++#if [ -n "`pidof nmbd`" ] ; then
+ # killall -9 nmbd 2>/dev/null
+-fi
++#fi
+ sleep 2
+ /usr/sbin/smbd -D;
+ /usr/sbin/nmbd -D;
diff --git a/packages/nslu2-binary-only/unslung-rootfs/rc.sysinit-cpbug.patch b/packages/nslu2-binary-only/unslung-rootfs/rc.sysinit-cpbug.patch
new file mode 100644
index 0000000000..5b908851ed
--- /dev/null
+++ b/packages/nslu2-binary-only/unslung-rootfs/rc.sysinit-cpbug.patch
@@ -0,0 +1,19 @@
+--- nslu2-linksys-ramdisk-2.3r63/etc/rc.d/rc.sysinit~ 2006-05-16 17:35:56.000000000 -0500
++++ nslu2-linksys-ramdisk-2.3r63/etc/rc.d/rc.sysinit 2006-05-16 17:36:10.000000000 -0500
+@@ -11,14 +11,14 @@
+ if ( [ ! -f /.sda1root ] && [ ! -f /.sda2root ] && [ ! -f /.sdb1root ] && [ ! -f /.sdb2root ] ) ; then
+ /bin/echo "Creating ramfs for /dev:"
+ /bin/mount -t ramfs ramfs /mnt/tmpmnt
+- /bin/cp -rp /dev/* /mnt/tmpmnt/
++ /bin/cp -a /dev/* /mnt/tmpmnt/
+ /bin/mkdir -p /dev.state
+ /bin/mount -o bind /dev /dev.state
+ /bin/mount -o bind /mnt/tmpmnt /dev
+ /bin/umount /mnt/tmpmnt
+ /bin/echo "Creating ramfs for /var:"
+ /bin/mount -t ramfs ramfs /mnt/tmpmnt -o maxsize=256
+- /bin/cp -rp /var/* /mnt/tmpmnt/
++ /bin/cp -a /var/* /mnt/tmpmnt/
+ /bin/mkdir -p /var.state
+ /bin/mount -o bind /var /var.state
+ /bin/mount -o bind /mnt/tmpmnt /var
diff --git a/packages/nslu2-binary-only/unslung-rootfs/unsling b/packages/nslu2-binary-only/unslung-rootfs/unsling
index c8b3dc8662..400c7d0ad2 100755
--- a/packages/nslu2-binary-only/unslung-rootfs/unsling
+++ b/packages/nslu2-binary-only/unslung-rootfs/unsling
@@ -162,7 +162,7 @@ fi
echo
echo "Copying the complete rootfs from / to $targ ..."
-/usr/bin/find / -print0 -mount | /usr/bin/cpio -p -0 -d -m -u $targ
+/usr/bin/find / -xdev -print | /usr/bin/cpio -p -d -m -u $targ
rm -rf $targ/dev ; mv $targ/dev.state $targ/dev
rm -rf $targ/var ; mv $targ/var.state $targ/var
diff --git a/packages/nslu2-binary-only/unslung-rootfs_2.3r63.bb b/packages/nslu2-binary-only/unslung-rootfs_2.3r63.bb
index 1c805a6975..ff0172d84d 100644
--- a/packages/nslu2-binary-only/unslung-rootfs_2.3r63.bb
+++ b/packages/nslu2-binary-only/unslung-rootfs_2.3r63.bb
@@ -1,6 +1,6 @@
SECTION = "base"
-PR = "r12"
+PR = "r13"
DEPENDS = "nslu2-linksys-libs nslu2-linksys-sambacodepages"
@@ -31,6 +31,7 @@ SRC_URI = "http://nslu.sf.net/downloads/nslu2-linksys-ramdisk-2.3r63-2.tar.bz2 \
file://rc.reset_usrgrpshare-diversion.patch;patch=1 \
file://rc.rstimezone-diversion.patch;patch=1 \
file://rc.samba-diversion.patch;patch=1 \
+ file://rc.samba-syntaxfix.patch;patch=1 \
file://rc.sysinit-diversion.patch;patch=1 \
file://rc.thttpd-diversion.patch;patch=1 \
file://rc.xinetd-diversion.patch;patch=1 \
@@ -43,6 +44,7 @@ SRC_URI = "http://nslu.sf.net/downloads/nslu2-linksys-ramdisk-2.3r63-2.tar.bz2 \
file://mount_usbdevfs.patch;patch=1 \
file://security-fixes.patch;patch=1 \
file://rc.sysinit-clean_var.patch;patch=1 \
+ file://rc.sysinit-cpbug.patch;patch=1 \
file://rc.modules-nls.patch;patch=1 \
file://telnet-passwd.patch;patch=1 \
file://upgrade.htm \
@@ -144,6 +146,19 @@ do_compile () {
# 950 (Chinese BIG-5)
rm -f ${S}/etc/samba/codepages/codepage.950
# ISO8859-1 (Latin 1) - keep
+
+ # /bin/killall and /usr/bin/killall are both symlinks to busybox. This
+ # is a problem if killall is ever replaced by slingbox or a native utility.
+ # Fix by making /bin/killall (the wrong place) a symlink to /usr/bin/killall.
+ rm -f ${S}/bin/killall
+ ln -s ../usr/bin/killall ${S}/bin/killall
+
+ # There are two identical binary copies of "date" on the image. Replace
+ # the one in /usr/sbin with a symlink to the one in /bin. This saves a
+ # bit of flash space, and makes it possible to replace the date binary with
+ # a link to busybox or slingbox at some point.
+ rm -r ${S}/usr/sbin/date
+ ln -s ../../bin/date ${S}/usr/sbin/date
}
do_install () {
diff --git a/packages/obexftp/files/i-hate-libtool.patch b/packages/obexftp/files/i-hate-libtool.patch
new file mode 100644
index 0000000000..1e31ac44b4
--- /dev/null
+++ b/packages/obexftp/files/i-hate-libtool.patch
@@ -0,0 +1,20 @@
+
+#
+# Patch managed by http://www.holgerschurig.de/patcher.html
+#
+
+--- obexftp-0.20/apps/Makefile.am~i-hate-libtool
++++ obexftp-0.20/apps/Makefile.am
+@@ -9,9 +9,9 @@
+ LDADD = ../obexftp/libobexftp.la \
+ ../multicobex/libmulticobex.la \
+ ../bfb/libbfb.la \
+- @OPENOBEX_LIBS@
+-# @BLUETOOTH_LIBS@
+-# @USB_LIBS@
++ @OPENOBEX_LIBS@ \
++ @BLUETOOTH_LIBS@
++# @USB_LIBS@
+ # need on win32:
+ # getopt.o getopt1.o libopenobex.a libwsock32.a
+
diff --git a/packages/obexftp/obexftp_0.19.bb b/packages/obexftp/obexftp_0.20.bb
index e5479c14de..aa100bab36 100644
--- a/packages/obexftp/obexftp_0.19.bb
+++ b/packages/obexftp/obexftp_0.20.bb
@@ -3,14 +3,17 @@ SECTION = "console/network"
HOMEPAGE = "http://openobex.triq.net"
LICENSE = "GPL"
DEPENDS = "openobex libgsm"
-PR = "r0"
+PR = "r2"
SRC_URI = "${SOURCEFORGE_MIRROR}/openobex/obexftp-${PV}.tar.gz \
+ file://i-hate-libtool.patch;patch=1 \
file://m4.patch;patch=1"
inherit autotools
-EXTRA_OECONF = " --enable-bluetooth --disable-swig --disable-perl --disable-python --disable-tcl --disable-builddocs"
+EXTRA_OECONF = "--enable-bluetooth --disable-swig --disable-perl --disable-python --disable-tcl --disable-builddocs"
+
+PARALLEL_MAKE = ""
do_stage() {
autotools_stage_all
diff --git a/packages/prismstumbler/prismstumbler-0.7.3/fix-includes.patch b/packages/prismstumbler/prismstumbler-0.7.3/fix-includes.patch
new file mode 100644
index 0000000000..9aef61e9d3
--- /dev/null
+++ b/packages/prismstumbler/prismstumbler-0.7.3/fix-includes.patch
@@ -0,0 +1,26 @@
+
+#
+# Patch managed by http://www.holgerschurig.de/patcher.html
+#
+
+--- prismstumbler-0.7.3/src/gpsd/Makefile.in~fix-includes
++++ prismstumbler-0.7.3/src/gpsd/Makefile.in
+@@ -92,18 +92,6 @@
+ COMPILE_AND_LINK.c = \
+ $(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(LDFLAGS)
+
+-## Where to look for X include files. (-I/usr/X11R5/include)
+-X_INCLUDE = @X_CFLAGS@
+-
+-## Where to look for include files.
+-INCLUDE = -I. $(X_INCLUDE)
+-
+-## Implicit rules.
+-.SUFFIXES: .c
+-.c.o:
+- $(COMPILE.c) $(INCLUDE) -o $@ $<
+-
+-
+ ## Libraries and object files
+ LIB_OBJECTS = netlib.o nmea_parse.o serial.o tm.o em.o $(MOTIF_OBJECTS)
+
diff --git a/packages/prismstumbler/prismstumbler_0.7.3.bb b/packages/prismstumbler/prismstumbler_0.7.3.bb
index 99f0956afd..0f78679db9 100644
--- a/packages/prismstumbler/prismstumbler_0.7.3.bb
+++ b/packages/prismstumbler/prismstumbler_0.7.3.bb
@@ -1,5 +1,5 @@
SECTION = "x11/network"
-PR = "r3"
+PR = "r4"
PACKAGES = "prismstumbler prismstumbler-frontend prismstumbler-doc"
DESCRIPTION = "Prismstumbler wireless LAN scanner"
@@ -10,6 +10,7 @@ RDEPENDS = "wireless-tools"
SRC_URI = "${SOURCEFORGE_MIRROR}/prismstumbler/${PN}-${PV}.tar.bz2 \
file://bogoconf.patch;patch=1 \
+ file://fix-includes.patch;patch=1 \
file://libz.patch;patch=1;pnum=0"
inherit autotools pkgconfig
diff --git a/packages/puzzles/puzzles_r6712.bb b/packages/puzzles/puzzles_r6712.bb
new file mode 100644
index 0000000000..fe641570e2
--- /dev/null
+++ b/packages/puzzles/puzzles_r6712.bb
@@ -0,0 +1,50 @@
+
+DEPENDS = "gtk+ perl-native"
+
+SRC_URI = "svn://ixion.tartarus.org/main;module=puzzles;rev=6712 \
+ file://game.png"
+
+S = "${WORKDIR}/puzzles/"
+
+do_configure() {
+ cd ${S} && ${STAGING_BINDIR}/perl mkfiles.pl
+}
+
+do_compile_prepend = " \
+ export XLDFLAGS='${LDFLAGS} `${STAGING_BINDIR}/pkg-config gtk+-2.0 --libs`'; \
+ export CFLAGS='${CFLAGS} -I./ `${STAGING_BINDIR}/pkg-config gtk+-2.0 --cflags`'; "
+
+FILES_${PN} = "${prefix}/games/* ${datadir}/applications/* ${datadir}/pixmaps"
+
+do_install () {
+ export prefix=${D}
+ export DESTDIR=${D}
+ install -d ${D}/${prefix}
+ install -d ${D}/${prefix}/games
+ oe_runmake install
+
+ install -d ${D}/${datadir}
+ install -d ${D}/${datadir}/applications
+ install -d ${D}/${datadir}/pixmaps
+
+ install ${WORKDIR}/game.png ${D}/${datadir}/pixmaps
+
+ cd ${D}/${prefix}/games
+ for prog in *; do
+ if [ -x $prog ]; then
+ echo "making ${D}/${datadir}/applications/$prog.desktop"
+ cat <<STOP > ${D}/${datadir}/applications/$prog.desktop
+[Desktop Entry]
+Encoding=UTF-8
+Name=$prog
+Exec=${prefix}/games/$prog
+Icon=game.png
+Terminal=false
+Type=Application
+Categories=Game
+StartupNotify=true
+SingleInstance=true
+STOP
+ fi
+ done
+}
diff --git a/packages/python/python-gammu_0.13.bb b/packages/python/python-gammu_0.13.bb
index 9ae5f9d665..755e3ec3fd 100644
--- a/packages/python/python-gammu_0.13.bb
+++ b/packages/python/python-gammu_0.13.bb
@@ -4,9 +4,9 @@ SECTION = "devel/python"
DEPENDS = "gammu"
LICENSE = "GPL"
MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>"
-PR = "r0"
+PR = "ml0"
-SRC_URI = "http://cihar.com/gammu/python/python-gammu-${PV}.tar.bz2"
+SRC_URI = "http://dl.cihar.com/python-gammu/latest/python-gammu-${PV}.tar.bz2"
inherit distutils
diff --git a/packages/python/python-pyfits_1.0.1.bb b/packages/python/python-pyfits_1.0.1.bb
new file mode 100644
index 0000000000..1d1507d406
--- /dev/null
+++ b/packages/python/python-pyfits_1.0.1.bb
@@ -0,0 +1,13 @@
+DESCRIPTION = "PyFITS provides an interface to FITS formatted files under the Python scripting language."
+HOMEPAGE = "http://www.stsci.edu/resources/software_hardware/pyfits"
+AUTHOR = "Space Telescope Science Institute"
+MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de"
+RDEPENDS = "python-numarray"
+SECTION = "devel/python"
+LICENSE = "AURA"
+PR = "ml0"
+
+SRC_URI = "ftp://ra.stsci.edu/pub/pyfits/pyfits-${PV}.tar.gz"
+S = "${WORKDIR}/pyfits-${PV}"
+
+inherit distutils
diff --git a/packages/python/python-pyraf_1.2.1.bb b/packages/python/python-pyraf_1.2.1.bb
new file mode 100644
index 0000000000..2242390853
--- /dev/null
+++ b/packages/python/python-pyraf_1.2.1.bb
@@ -0,0 +1,14 @@
+DESCRIPTION = "PyRAF is a Python-based interface to IRAF."
+HOMEPAGE = "http://www.stsci.edu/resources/software_hardware/pyfits"
+AUTHOR = "Space Telescope Science Institute"
+MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de"
+RDEPENDS = "python-numarray"
+SECTION = "devel/python"
+LICENSE = "AURA"
+PR = "ml0"
+
+SRC_URI = "ftp://ra.stsci.edu/pub/pyraf/v2.3/pyraf-${PV}.tar.gz"
+S = "${WORKDIR}/pyraf-${PV}"
+
+inherit distutils
+
diff --git a/packages/python/python-pysqlite/.mtn2git_empty b/packages/python/python-pysqlite/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/python/python-pysqlite/.mtn2git_empty
diff --git a/packages/python/python-pysqlite/no-host-includes.patch b/packages/python/python-pysqlite/no-host-includes.patch
new file mode 100644
index 0000000000..20f5c98402
--- /dev/null
+++ b/packages/python/python-pysqlite/no-host-includes.patch
@@ -0,0 +1,40 @@
+
+#
+# Patch managed by http://www.holgerschurig.de/patcher.html
+#
+
+--- pysqlite/setup.py~no-host-includes
++++ pysqlite/setup.py
+@@ -11,8 +11,8 @@
+ macros = []
+
+ if sys.platform in ("linux-i386", "linux2"): # most Linux
+- include_dirs = ['/usr/include/sqlite']
+- library_dirs = ['/usr/lib/']
++ include_dirs = []
++ library_dirs = []
+ libraries = [sqlite]
+ runtime_library_dirs = []
+ extra_objects = []
+@@ -21,8 +21,8 @@
+ LOCALBASE = os.environ.get("LOCALBASE", "/opt/local")
+ else:
+ LOCALBASE = os.environ.get("LOCALBASE", "/usr/local")
+- include_dirs = ['%s/include' % LOCALBASE]
+- library_dirs = ['%s/lib/' % LOCALBASE]
++ include_dirs = []
++ library_dirs = []
+ libraries = [sqlite]
+ runtime_library_dirs = []
+ extra_objects = []
+@@ -33,8 +33,8 @@
+ runtime_library_dirs = []
+ extra_objects = []
+ elif os.name == "posix": # most Unixish platforms
+- include_dirs = ['/usr/local/include']
+- library_dirs = ['/usr/local/lib']
++ include_dirs = []
++ library_dirs = []
+ libraries = [sqlite]
+ # On some platorms, this can be used to find the shared libraries
+ # at runtime, if they are in a non-standard location. Doesn't
diff --git a/packages/python/python-pysqlite2_2.2.2.bb b/packages/python/python-pysqlite2_2.2.2.bb
index 124a2ed5bc..72ffc39104 100644
--- a/packages/python/python-pysqlite2_2.2.2.bb
+++ b/packages/python/python-pysqlite2_2.2.2.bb
@@ -8,7 +8,7 @@ DEPENDS = "sqlite3"
SRCNAME = "pysqlite"
PR = "ml0"
-SRC_URI = "http://initd.org/pub/software/pysqlite/releases/2.0/${PV}/${SRCNAME}-${PV}.tar.gz"
+SRC_URI = "http://initd.org/pub/software/pysqlite/releases/2.2/${PV}/${SRCNAME}-${PV}.tar.gz"
S = "${WORKDIR}/${SRCNAME}-${PV}"
inherit distutils
diff --git a/packages/python/python-pysqlite_1.0.bb b/packages/python/python-pysqlite_1.0.bb
index dcabdb18a1..46ad0239ce 100644
--- a/packages/python/python-pysqlite_1.0.bb
+++ b/packages/python/python-pysqlite_1.0.bb
@@ -6,8 +6,10 @@ LICENSE = "PSF"
RDEPENDS = "python-core python-re python-lang"
DEPENDS = "sqlite"
SRCNAME = "pysqlite"
+PR = "ml0"
-SRC_URI = "${SOURCEFORGE_MIRROR}/${SRCNAME}/${SRCNAME}-${PV}.tar.gz"
+SRC_URI = "${SOURCEFORGE_MIRROR}/${SRCNAME}/${SRCNAME}-${PV}.tar.gz \
+ file://no-host-includes.patch;patch=1"
S = "${WORKDIR}/${SRCNAME}"
inherit distutils
diff --git a/packages/schroedinger/.mtn2git_empty b/packages/schroedinger/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/schroedinger/.mtn2git_empty
diff --git a/packages/schroedinger/schroedinger_0.2.0.0.bb b/packages/schroedinger/schroedinger_0.2.0.0.bb
new file mode 100644
index 0000000000..3dcc82bdff
--- /dev/null
+++ b/packages/schroedinger/schroedinger_0.2.0.0.bb
@@ -0,0 +1,11 @@
+HOMEPAGE = "http://schrodinger.sourceforge.net/
+LICENSE = "MPL/GPL/LGPL and MIT"
+DEPENDS = "liboil gstreamer gst-plugins-base"
+MAINTAINER = "Koen Kooi <koen@dominion.kabel.utwente.nl>"
+
+SRC_URI = "${SOURCEFORGE_MIRROR}/schrodinger/${P}.tar.gz"
+
+inherit autotools pkgconfig
+
+FILES_${PN} += "${libdir}/gstreamer-0.10/libgstschro.so"
+
diff --git a/packages/xmms/.mtn2git_empty b/packages/xmms/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/xmms/.mtn2git_empty
diff --git a/packages/xmms/files/.mtn2git_empty b/packages/xmms/files/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/xmms/files/.mtn2git_empty
diff --git a/packages/xmms/files/gcc4.patch b/packages/xmms/files/gcc4.patch
new file mode 100644
index 0000000000..0619803820
--- /dev/null
+++ b/packages/xmms/files/gcc4.patch
@@ -0,0 +1,20 @@
+
+#
+# Patch managed by http://www.holgerschurig.de/patcher.html
+#
+
+--- xmms-1.2.10/General/ir/ir.c~gcc4
++++ xmms-1.2.10/General/ir/ir.c
+@@ -16,10 +16,10 @@
+ #include "ir.h"
+
+ /* Important stuff to know */
+-static gboolean keepGoing = FALSE;
++extern gboolean keepGoing = FALSE;
+
+ /* The thread handle */
+-static pthread_t irapp_thread;
++extern pthread_t irapp_thread;
+
+ /* Declarations for calls that we need to mention in the plugin struct */
+ static void init(void);
diff --git a/packages/xmms/xmms_1.2.10.bb b/packages/xmms/xmms_1.2.10.bb
new file mode 100644
index 0000000000..05bfb1dc3e
--- /dev/null
+++ b/packages/xmms/xmms_1.2.10.bb
@@ -0,0 +1,23 @@
+DESCRIPTION = "The X MultiMedia System"
+HOMEPAGE = "http://www.xmms.org/"
+LICENSE = "GPL"
+SECTION = "x11/multimedia"
+# TODO add esd mikmod vorbis
+DEPENDS = "gtk+-1.2"
+
+SRC_URI = "http://www.xmms.org/files/1.2.x/xmms-${PV}.tar.bz2 \
+ file://gcc4.patch;patch=1"
+
+inherit autotools
+
+# TODO enable esd mikmod vorbis
+EXTRA_OECONF = "--disable-opengl --disable-esd --disable-mikmod --disable-vorbis"
+
+do_configure() {
+ oe_runconf
+}
+
+do_compile() {
+ oe_runmake LIBTOOL=${STAGING_BINDIR}/${TARGET_PREFIX}libtool
+}
+