From 1868f4aa5a4a72bbe0b7db6c1d4ee666824c3895 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Wed, 4 May 2005 15:29:35 -0500 Subject: JFS: fix sparse warnings by moving extern declarations to headers Signed-off-by: Dave Kleikamp --- fs/jfs/file.c | 9 +++------ fs/jfs/inode.c | 11 ++--------- fs/jfs/jfs_debug.c | 10 ---------- fs/jfs/jfs_debug.h | 15 ++++++++++---- fs/jfs/jfs_extent.c | 7 +------ fs/jfs/jfs_imap.c | 6 +----- fs/jfs/jfs_inode.c | 1 + fs/jfs/jfs_inode.h | 19 +++++++++++++++++- fs/jfs/jfs_logmgr.c | 9 +-------- fs/jfs/jfs_logmgr.h | 2 ++ fs/jfs/jfs_metapage.c | 4 ++-- fs/jfs/jfs_metapage.h | 6 ++++-- fs/jfs/jfs_superblock.h | 11 +++++++++++ fs/jfs/jfs_txnmgr.c | 40 +------------------------------------ fs/jfs/jfs_txnmgr.h | 52 +++++++++++++++++++++---------------------------- fs/jfs/namei.c | 28 ++++++-------------------- fs/jfs/super.c | 37 +---------------------------------- fs/jfs/symlink.c | 3 ++- 18 files changed, 89 insertions(+), 181 deletions(-) diff --git a/fs/jfs/file.c b/fs/jfs/file.c index a87b06fa8ff8..c2c19c9ed9a4 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c @@ -1,6 +1,6 @@ /* - * Copyright (c) International Business Machines Corp., 2000-2002 - * Portions Copyright (c) Christoph Hellwig, 2001-2002 + * Copyright (C) International Business Machines Corp., 2000-2002 + * Portions Copyright (C) Christoph Hellwig, 2001-2002 * * 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 @@ -19,16 +19,13 @@ #include #include "jfs_incore.h" +#include "jfs_inode.h" #include "jfs_dmap.h" #include "jfs_txnmgr.h" #include "jfs_xattr.h" #include "jfs_acl.h" #include "jfs_debug.h" - -extern int jfs_commit_inode(struct inode *, int); -extern void jfs_truncate(struct inode *); - int jfs_fsync(struct file *file, struct dentry *dentry, int datasync) { struct inode *inode = dentry->d_inode; diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index 24a689179af2..2137138c59b0 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c @@ -23,6 +23,7 @@ #include #include #include "jfs_incore.h" +#include "jfs_inode.h" #include "jfs_filsys.h" #include "jfs_imap.h" #include "jfs_extent.h" @@ -30,14 +31,6 @@ #include "jfs_debug.h" -extern struct inode_operations jfs_dir_inode_operations; -extern struct inode_operations jfs_file_inode_operations; -extern struct inode_operations jfs_symlink_inode_operations; -extern struct file_operations jfs_dir_operations; -extern struct file_operations jfs_file_operations; -struct address_space_operations jfs_aops; -extern int freeZeroLink(struct inode *); - void jfs_read_inode(struct inode *inode) { if (diRead(inode)) { @@ -136,7 +129,7 @@ void jfs_delete_inode(struct inode *inode) jfs_info("In jfs_delete_inode, inode = 0x%p", inode); if (test_cflag(COMMIT_Freewmap, inode)) - freeZeroLink(inode); + jfs_free_zero_link(inode); diFree(inode); diff --git a/fs/jfs/jfs_debug.c b/fs/jfs/jfs_debug.c index 91a0a889ebc5..4caea6b43b92 100644 --- a/fs/jfs/jfs_debug.c +++ b/fs/jfs/jfs_debug.c @@ -58,8 +58,6 @@ void dump_mem(char *label, void *data, int length) static struct proc_dir_entry *base; #ifdef CONFIG_JFS_DEBUG -extern read_proc_t jfs_txanchor_read; - static int loglevel_read(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -97,14 +95,6 @@ static int loglevel_write(struct file *file, const char __user *buffer, } #endif - -#ifdef CONFIG_JFS_STATISTICS -extern read_proc_t jfs_lmstats_read; -extern read_proc_t jfs_txstats_read; -extern read_proc_t jfs_xtstat_read; -extern read_proc_t jfs_mpstat_read; -#endif - static struct { const char *name; read_proc_t *read_fn; diff --git a/fs/jfs/jfs_debug.h b/fs/jfs/jfs_debug.h index a38079ae1e00..ddffbbd4d955 100644 --- a/fs/jfs/jfs_debug.h +++ b/fs/jfs/jfs_debug.h @@ -1,6 +1,6 @@ /* - * Copyright (c) International Business Machines Corp., 2000-2002 - * Portions Copyright (c) Christoph Hellwig, 2001-2002 + * Copyright (C) International Business Machines Corp., 2000-2002 + * Portions Copyright (C) Christoph Hellwig, 2001-2002 * * 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 @@ -31,7 +31,9 @@ * CONFIG_JFS_DEBUG or CONFIG_JFS_STATISTICS is defined */ #if defined(CONFIG_PROC_FS) && (defined(CONFIG_JFS_DEBUG) || defined(CONFIG_JFS_STATISTICS)) - #define PROC_FS_JFS +#define PROC_FS_JFS +extern void jfs_proc_init(void); +extern void jfs_proc_clean(void); #endif /* @@ -65,8 +67,8 @@ extern int jfsloglevel; -/* dump memory contents */ extern void dump_mem(char *label, void *data, int length); +extern int jfs_txanchor_read(char *, char **, off_t, int, int *, void *); /* information message: e.g., configuration, major event */ #define jfs_info(fmt, arg...) do { \ @@ -110,6 +112,11 @@ extern void dump_mem(char *label, void *data, int length); * ---------- */ #ifdef CONFIG_JFS_STATISTICS +extern int jfs_lmstats_read(char *, char **, off_t, int, int *, void *); +extern int jfs_txstats_read(char *, char **, off_t, int, int *, void *); +extern int jfs_mpstat_read(char *, char **, off_t, int, int *, void *); +extern int jfs_xtstat_read(char *, char **, off_t, int, int *, void *); + #define INCREMENT(x) ((x)++) #define DECREMENT(x) ((x)--) #define HIGHWATERMARK(x,y) ((x) = max((x), (y))) diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c index 1953acb79266..4879603daa1c 100644 --- a/fs/jfs/jfs_extent.c +++ b/fs/jfs/jfs_extent.c @@ -19,6 +19,7 @@ #include #include #include "jfs_incore.h" +#include "jfs_inode.h" #include "jfs_superblock.h" #include "jfs_dmap.h" #include "jfs_extent.h" @@ -33,12 +34,6 @@ static int extBrealloc(struct inode *, s64, s64, s64 *, s64 *); #endif static s64 extRoundDown(s64 nb); -/* - * external references - */ -extern int jfs_commit_inode(struct inode *, int); - - #define DPD(a) (printk("(a): %d\n",(a))) #define DPC(a) (printk("(a): %c\n",(a))) #define DPL1(a) \ diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index 7acff2ce3c80..971af2977eff 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c @@ -47,6 +47,7 @@ #include #include "jfs_incore.h" +#include "jfs_inode.h" #include "jfs_filsys.h" #include "jfs_dinode.h" #include "jfs_dmap.h" @@ -68,11 +69,6 @@ #define AG_LOCK(imap,agno) down(&imap->im_aglock[agno]) #define AG_UNLOCK(imap,agno) up(&imap->im_aglock[agno]) -/* - * external references - */ -extern struct address_space_operations jfs_aops; - /* * forward references */ diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c index 84f2459b2191..2af5efbfd06f 100644 --- a/fs/jfs/jfs_inode.c +++ b/fs/jfs/jfs_inode.c @@ -19,6 +19,7 @@ #include #include #include "jfs_incore.h" +#include "jfs_inode.h" #include "jfs_filsys.h" #include "jfs_imap.h" #include "jfs_dinode.h" diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h index 3df91fbfe781..b54bac576cb3 100644 --- a/fs/jfs/jfs_inode.h +++ b/fs/jfs/jfs_inode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) International Business Machines Corp., 2000-2001 + * Copyright (C) International Business Machines Corp., 2000-2001 * * 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 @@ -19,5 +19,22 @@ #define _H_JFS_INODE extern struct inode *ialloc(struct inode *, umode_t); +extern int jfs_fsync(struct file *, struct dentry *, int); +extern void jfs_read_inode(struct inode *); +extern int jfs_commit_inode(struct inode *, int); +extern int jfs_write_inode(struct inode*, int); +extern void jfs_delete_inode(struct inode *); +extern void jfs_dirty_inode(struct inode *); +extern void jfs_truncate(struct inode *); +extern void jfs_truncate_nolock(struct inode *, loff_t); +extern void jfs_free_zero_link(struct inode *); +extern struct dentry *jfs_get_parent(struct dentry *dentry); +extern struct address_space_operations jfs_aops; +extern struct inode_operations jfs_dir_inode_operations; +extern struct file_operations jfs_dir_operations; +extern struct inode_operations jfs_file_inode_operations; +extern struct file_operations jfs_file_operations; +extern struct inode_operations jfs_symlink_inode_operations; +extern struct dentry_operations jfs_ci_dentry_operations; #endif /* _H_JFS_INODE */ diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index dfa1200daa61..c5cc03bcae69 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -71,6 +71,7 @@ #include "jfs_incore.h" #include "jfs_filsys.h" #include "jfs_metapage.h" +#include "jfs_superblock.h" #include "jfs_txnmgr.h" #include "jfs_debug.h" @@ -166,14 +167,6 @@ static LIST_HEAD(jfs_external_logs); static struct jfs_log *dummy_log = NULL; static DECLARE_MUTEX(jfs_log_sem); -/* - * external references - */ -extern void txLazyUnlock(struct tblock * tblk); -extern int jfs_stop_threads; -extern struct completion jfsIOwait; -extern int jfs_tlocks_low; - /* * forward references */ diff --git a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h index 51291fbc420c..747114cd38b8 100644 --- a/fs/jfs/jfs_logmgr.h +++ b/fs/jfs/jfs_logmgr.h @@ -507,6 +507,8 @@ extern int lmLogClose(struct super_block *sb); extern int lmLogShutdown(struct jfs_log * log); extern int lmLogInit(struct jfs_log * log); extern int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize); +extern int lmGroupCommit(struct jfs_log *, struct tblock *); +extern int jfsIOWait(void *); extern void jfs_flush_journal(struct jfs_log * log, int wait); extern void jfs_syncpt(struct jfs_log *log); diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index 41bf078dce05..aa1cc7be3a56 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c @@ -726,12 +726,12 @@ void force_metapage(struct metapage *mp) page_cache_release(page); } -extern void hold_metapage(struct metapage *mp) +void hold_metapage(struct metapage *mp) { lock_page(mp->page); } -extern void put_metapage(struct metapage *mp) +void put_metapage(struct metapage *mp) { if (mp->count || mp->nohomeok) { /* Someone else will release this */ diff --git a/fs/jfs/jfs_metapage.h b/fs/jfs/jfs_metapage.h index 991e9fb84c75..f0b7d3282b07 100644 --- a/fs/jfs/jfs_metapage.h +++ b/fs/jfs/jfs_metapage.h @@ -1,6 +1,6 @@ /* - * Copyright (c) International Business Machines Corp., 2000-2002 - * Portions Copyright (c) Christoph Hellwig, 2001-2002 + * Copyright (C) International Business Machines Corp., 2000-2002 + * Portions Copyright (C) Christoph Hellwig, 2001-2002 * * 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 @@ -58,6 +58,8 @@ struct metapage { #define mark_metapage_dirty(mp) set_bit(META_dirty, &(mp)->flag) /* function prototypes */ +extern int metapage_init(void); +extern void metapage_exit(void); extern struct metapage *__get_metapage(struct inode *inode, unsigned long lblock, unsigned int size, int absolute, unsigned long new); diff --git a/fs/jfs/jfs_superblock.h b/fs/jfs/jfs_superblock.h index ab0566f70cfa..fcf781bf31cb 100644 --- a/fs/jfs/jfs_superblock.h +++ b/fs/jfs/jfs_superblock.h @@ -109,5 +109,16 @@ struct jfs_superblock { extern int readSuper(struct super_block *, struct buffer_head **); extern int updateSuper(struct super_block *, uint); extern void jfs_error(struct super_block *, const char *, ...); +extern int jfs_mount(struct super_block *); +extern int jfs_mount_rw(struct super_block *, int); +extern int jfs_umount(struct super_block *); +extern int jfs_umount_rw(struct super_block *); + +extern int jfs_stop_threads; +extern struct completion jfsIOwait; +extern wait_queue_head_t jfs_IO_thread_wait; +extern wait_queue_head_t jfs_commit_thread_wait; +extern wait_queue_head_t jfs_sync_thread_wait; +extern int jfs_extendfs(struct super_block *, s64, int); #endif /*_H_JFS_SUPERBLOCK */ diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index e93d01aa12c4..8cbaaff1d5fa 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c @@ -42,7 +42,6 @@ * hold on to mp+lock thru update of maps */ - #include #include #include @@ -51,6 +50,7 @@ #include #include #include "jfs_incore.h" +#include "jfs_inode.h" #include "jfs_filsys.h" #include "jfs_metapage.h" #include "jfs_dinode.h" @@ -109,7 +109,6 @@ static int TxLockHWM; /* High water mark for number of txLocks used */ static int TxLockVHWM; /* Very High water mark */ struct tlock *TxLock; /* transaction lock table */ - /* * transaction management lock */ @@ -149,7 +148,6 @@ static inline void TXN_SLEEP_DROP_LOCK(wait_queue_head_t * event) #define TXN_WAKEUP(event) wake_up_all(event) - /* * statistics */ @@ -161,16 +159,6 @@ static struct { int waitlock; /* 4: # of tlock wait */ } stattx; - -/* - * external references - */ -extern int lmGroupCommit(struct jfs_log *, struct tblock *); -extern int jfs_commit_inode(struct inode *, int); -extern int jfs_stop_threads; - -extern struct completion jfsIOwait; - /* * forward references */ @@ -358,7 +346,6 @@ void txExit(void) TxBlock = NULL; } - /* * NAME: txBegin() * @@ -460,7 +447,6 @@ tid_t txBegin(struct super_block *sb, int flag) return t; } - /* * NAME: txBeginAnon() * @@ -503,7 +489,6 @@ void txBeginAnon(struct super_block *sb) TXN_UNLOCK(); } - /* * txEnd() * @@ -592,7 +577,6 @@ wakeup: TXN_WAKEUP(&TxAnchor.freewait); } - /* * txLock() * @@ -868,7 +852,6 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp, return NULL; } - /* * NAME: txRelease() * @@ -908,7 +891,6 @@ static void txRelease(struct tblock * tblk) TXN_UNLOCK(); } - /* * NAME: txUnlock() * @@ -996,7 +978,6 @@ static void txUnlock(struct tblock * tblk) } } - /* * txMaplock() * @@ -1069,7 +1050,6 @@ struct tlock *txMaplock(tid_t tid, struct inode *ip, int type) return tlck; } - /* * txLinelock() * @@ -1103,8 +1083,6 @@ struct linelock *txLinelock(struct linelock * tlock) return linelock; } - - /* * transaction commit management * ----------------------------- @@ -1373,7 +1351,6 @@ int txCommit(tid_t tid, /* transaction identifier */ return rc; } - /* * NAME: txLog() * @@ -1437,7 +1414,6 @@ static int txLog(struct jfs_log * log, struct tblock * tblk, struct commit * cd) return rc; } - /* * diLog() * @@ -1465,7 +1441,6 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, if (tlck->type & tlckENTRY) { /* log after-image for logredo(): */ lrd->type = cpu_to_le16(LOG_REDOPAGE); -// *pxd = mp->cm_pxd; PXDaddress(pxd, mp->index); PXDlength(pxd, mp->logical_size >> tblk->sb->s_blocksize_bits); @@ -1552,7 +1527,6 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, return rc; } - /* * dataLog() * @@ -1599,7 +1573,6 @@ static int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, return 0; } - /* * dtLog() * @@ -1639,7 +1612,6 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, lrd->log.redopage.type |= cpu_to_le16(LOG_EXTEND); else lrd->log.redopage.type |= cpu_to_le16(LOG_NEW); -// *pxd = mp->cm_pxd; PXDaddress(pxd, mp->index); PXDlength(pxd, mp->logical_size >> tblk->sb->s_blocksize_bits); @@ -1704,7 +1676,6 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, return; } - /* * xtLog() * @@ -1760,7 +1731,6 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, * applying the after-image to the meta-data page. */ lrd->type = cpu_to_le16(LOG_REDOPAGE); -// *page_pxd = mp->cm_pxd; PXDaddress(page_pxd, mp->index); PXDlength(page_pxd, mp->logical_size >> tblk->sb->s_blocksize_bits); @@ -2093,7 +2063,6 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, return; } - /* * mapLog() * @@ -2180,7 +2149,6 @@ void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, } } - /* * txEA() * @@ -2233,7 +2201,6 @@ void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea) } } - /* * txForce() * @@ -2300,7 +2267,6 @@ void txForce(struct tblock * tblk) } } - /* * txUpdateMap() * @@ -2437,7 +2403,6 @@ static void txUpdateMap(struct tblock * tblk) } } - /* * txAllocPMap() * @@ -2509,7 +2474,6 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock, } } - /* * txFreeMap() * @@ -2611,7 +2575,6 @@ void txFreeMap(struct inode *ip, } } - /* * txFreelock() * @@ -2652,7 +2615,6 @@ void txFreelock(struct inode *ip) TXN_UNLOCK(); } - /* * txAbort() * diff --git a/fs/jfs/jfs_txnmgr.h b/fs/jfs/jfs_txnmgr.h index b71b82c2df04..59ad0f6b7231 100644 --- a/fs/jfs/jfs_txnmgr.h +++ b/fs/jfs/jfs_txnmgr.h @@ -285,34 +285,26 @@ struct commit { /* * external declarations */ -extern struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage *mp, - int flag); - -extern struct tlock *txMaplock(tid_t tid, struct inode *ip, int flag); - -extern int txCommit(tid_t tid, int nip, struct inode **iplist, int flag); - -extern tid_t txBegin(struct super_block *sb, int flag); - -extern void txBeginAnon(struct super_block *sb); - -extern void txEnd(tid_t tid); - -extern void txAbort(tid_t tid, int dirty); - -extern struct linelock *txLinelock(struct linelock * tlock); - -extern void txFreeMap(struct inode *ip, struct maplock * maplock, - struct tblock * tblk, int maptype); - -extern void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea); - -extern void txFreelock(struct inode *ip); - -extern int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, - struct tlock * tlck); - -extern void txQuiesce(struct super_block *sb); - -extern void txResume(struct super_block *sb); +extern int jfs_tlocks_low; + +extern int txInit(void); +extern void txExit(void); +extern struct tlock *txLock(tid_t, struct inode *, struct metapage *, int); +extern struct tlock *txMaplock(tid_t, struct inode *, int); +extern int txCommit(tid_t, int, struct inode **, int); +extern tid_t txBegin(struct super_block *, int); +extern void txBeginAnon(struct super_block *); +extern void txEnd(tid_t); +extern void txAbort(tid_t, int); +extern struct linelock *txLinelock(struct linelock *); +extern void txFreeMap(struct inode *, struct maplock *, struct tblock *, int); +extern void txEA(tid_t, struct inode *, dxd_t *, dxd_t *); +extern void txFreelock(struct inode *); +extern int lmLog(struct jfs_log *, struct tblock *, struct lrd *, + struct tlock *); +extern void txQuiesce(struct super_block *); +extern void txResume(struct super_block *); +extern void txLazyUnlock(struct tblock *); +extern int jfs_lazycommit(void *); +extern int jfs_sync(void *); #endif /* _H_JFS_TXNMGR */ diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 8413a368f449..1cae14e741eb 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -31,20 +31,9 @@ #include "jfs_acl.h" #include "jfs_debug.h" -extern struct inode_operations jfs_file_inode_operations; -extern struct inode_operations jfs_symlink_inode_operations; -extern struct file_operations jfs_file_operations; -extern struct address_space_operations jfs_aops; - -extern int jfs_fsync(struct file *, struct dentry *, int); -extern void jfs_truncate_nolock(struct inode *, loff_t); -extern int jfs_init_acl(struct inode *, struct inode *); - /* * forward references */ -struct inode_operations jfs_dir_inode_operations; -struct file_operations jfs_dir_operations; struct dentry_operations jfs_ci_dentry_operations; static s64 commitZeroLink(tid_t, struct inode *); @@ -655,7 +644,7 @@ static s64 commitZeroLink(tid_t tid, struct inode *ip) /* - * NAME: freeZeroLink() + * NAME: jfs_free_zero_link() * * FUNCTION: for non-directory, called by iClose(), * free resources of a file from cache and WORKING map @@ -663,15 +652,12 @@ static s64 commitZeroLink(tid_t tid, struct inode *ip) * while associated with a pager object, * * PARAMETER: ip - pointer to inode of file. - * - * RETURN: 0 -ok */ -int freeZeroLink(struct inode *ip) +void jfs_free_zero_link(struct inode *ip) { - int rc = 0; int type; - jfs_info("freeZeroLink: ip = 0x%p", ip); + jfs_info("jfs_free_zero_link: ip = 0x%p", ip); /* return if not reg or symbolic link or if size is * already ok. @@ -684,10 +670,10 @@ int freeZeroLink(struct inode *ip) case S_IFLNK: /* if its contained in inode nothing to do */ if (ip->i_size < IDATASIZE) - return 0; + return; break; default: - return 0; + return; } /* @@ -737,9 +723,7 @@ int freeZeroLink(struct inode *ip) * free xtree/data blocks from working block map; */ if (ip->i_size) - rc = xtTruncate(0, ip, 0, COMMIT_WMAP); - - return rc; + xtTruncate(0, ip, 0, COMMIT_WMAP); } /* diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 5e774ed7fb64..810a3653d8b3 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -28,6 +28,7 @@ #include "jfs_incore.h" #include "jfs_filsys.h" +#include "jfs_inode.h" #include "jfs_metapage.h" #include "jfs_superblock.h" #include "jfs_dmap.h" @@ -62,37 +63,6 @@ module_param(jfsloglevel, int, 0644); MODULE_PARM_DESC(jfsloglevel, "Specify JFS loglevel (0, 1 or 2)"); #endif -/* - * External declarations - */ -extern int jfs_mount(struct super_block *); -extern int jfs_mount_rw(struct super_block *, int); -extern int jfs_umount(struct super_block *); -extern int jfs_umount_rw(struct super_block *); - -extern int jfsIOWait(void *); -extern int jfs_lazycommit(void *); -extern int jfs_sync(void *); - -extern void jfs_read_inode(struct inode *inode); -extern void jfs_dirty_inode(struct inode *inode); -extern void jfs_delete_inode(struct inode *inode); -extern int jfs_write_inode(struct inode *inode, int wait); - -extern struct dentry *jfs_get_parent(struct dentry *dentry); -extern int jfs_extendfs(struct super_block *, s64, int); - -extern struct dentry_operations jfs_ci_dentry_operations; - -#ifdef PROC_FS_JFS /* see jfs_debug.h */ -extern void jfs_proc_init(void); -extern void jfs_proc_clean(void); -#endif - -extern wait_queue_head_t jfs_IO_thread_wait; -extern wait_queue_head_t jfs_commit_thread_wait; -extern wait_queue_head_t jfs_sync_thread_wait; - static void jfs_handle_error(struct super_block *sb) { struct jfs_sb_info *sbi = JFS_SBI(sb); @@ -593,11 +563,6 @@ static struct file_system_type jfs_fs_type = { .fs_flags = FS_REQUIRES_DEV, }; -extern int metapage_init(void); -extern int txInit(void); -extern void txExit(void); -extern void metapage_exit(void); - static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) { struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo; diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c index ef4c07ee92b2..287d8d6c3cfd 100644 --- a/fs/jfs/symlink.c +++ b/fs/jfs/symlink.c @@ -1,5 +1,5 @@ /* - * Copyright (c) Christoph Hellwig, 2001-2002 + * Copyright (C) Christoph Hellwig, 2001-2002 * * 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 @@ -19,6 +19,7 @@ #include #include #include "jfs_incore.h" +#include "jfs_inode.h" #include "jfs_xattr.h" static int jfs_follow_link(struct dentry *dentry, struct nameidata *nd) -- cgit v1.2.3-59-g8ed1b From dcc9871270aa3b1bbe2e61cc9c1d80e9b2e8099d Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Wed, 4 May 2005 15:30:51 -0500 Subject: JFS: cleanup - remove unneeded sanity check Signed-off-by: Dave Kleikamp --- fs/jfs/jfs_dmap.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index 69007fd546ef..cced2fed9d0f 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -272,7 +272,6 @@ int dbMount(struct inode *ipbmap) int dbUnmount(struct inode *ipbmap, int mounterror) { struct bmap *bmp = JFS_SBI(ipbmap->i_sb)->bmap; - int i; if (!(mounterror || isReadOnly(ipbmap))) dbSync(ipbmap); @@ -282,14 +281,6 @@ int dbUnmount(struct inode *ipbmap, int mounterror) */ truncate_inode_pages(ipbmap->i_mapping, 0); - /* - * Sanity Check - */ - for (i = 0; i < bmp->db_numag; i++) - if (atomic_read(&bmp->db_active[i])) - printk(KERN_ERR "dbUnmount: db_active[%d] = %d\n", - i, atomic_read(&bmp->db_active[i])); - /* free the memory for the in-memory bmap. */ kfree(bmp); -- cgit v1.2.3-59-g8ed1b From 7a694ca74958b97ae2d437c8a730bddd9e9792c3 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Wed, 4 May 2005 15:31:14 -0500 Subject: JFS: Fix sparse warning Signed-off-by: Dave Kleikamp --- fs/jfs/jfs_metapage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index aa1cc7be3a56..6c5485d16c39 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c @@ -198,7 +198,7 @@ static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) } } -static inline struct metapage *alloc_metapage(int gfp_mask) +static inline struct metapage *alloc_metapage(unsigned int gfp_mask) { return mempool_alloc(metapage_mempool, gfp_mask); } -- cgit v1.2.3-59-g8ed1b From 259692bd5a2b2c2d351dd90748ba4126bc2a21b9 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 9 May 2005 10:47:14 -0500 Subject: JFS: Remove redundant kfree() NULL pointer checks kfree() can handle a NULL pointer, don't worry about passing it one. Signed-off-by: Jesper Juhl Signed-off-by: Dave Kleikamp --- fs/jfs/acl.c | 6 ++---- fs/jfs/xattr.c | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index 8d2a9ab981d4..30a2bf9eeda5 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c @@ -70,8 +70,7 @@ static struct posix_acl *jfs_get_acl(struct inode *inode, int type) if (!IS_ERR(acl)) *p_acl = posix_acl_dup(acl); } - if (value) - kfree(value); + kfree(value); return acl; } @@ -112,8 +111,7 @@ static int jfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) } rc = __jfs_setxattr(inode, ea_name, value, size, 0); out: - if (value) - kfree(value); + kfree(value); if (!rc) { if (*p_acl && (*p_acl != JFS_ACL_NOT_CACHED)) diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index 7a9ffd5d03dc..6016373701a3 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c @@ -946,8 +946,7 @@ int __jfs_setxattr(struct inode *inode, const char *name, const void *value, out: up_write(&JFS_IP(inode)->xattr_sem); - if (os2name) - kfree(os2name); + kfree(os2name); return rc; } @@ -1042,8 +1041,7 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data, out: up_read(&JFS_IP(inode)->xattr_sem); - if (os2name) - kfree(os2name); + kfree(os2name); return size; } -- cgit v1.2.3-59-g8ed1b From c2731509cfb538b9b38feaf657fab2334ea45253 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Thu, 2 Jun 2005 12:18:20 -0500 Subject: JFS: kernel BUG at fs/jfs/jfs_txnmgr.c:859 add_missing_indices() must set tlck->type to tlckBTROOT when modifying a root btree root to avoid a trap in txRelease() Signed-off-by: Dave Kleikamp --- fs/jfs/jfs_dtree.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c index ac41f72d6d50..8676aee3ae48 100644 --- a/fs/jfs/jfs_dtree.c +++ b/fs/jfs/jfs_dtree.c @@ -2931,6 +2931,9 @@ static void add_missing_indices(struct inode *inode, s64 bn) ASSERT(p->header.flag & BT_LEAF); tlck = txLock(tid, inode, mp, tlckDTREE | tlckENTRY); + if (BT_IS_ROOT(mp)) + tlck->type |= tlckBTROOT; + dtlck = (struct dt_lock *) &tlck->lock; stbl = DT_GETSTBL(p); -- cgit v1.2.3-59-g8ed1b From 72e3148a6e987974e3e949c5668e5ca812d7c818 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Fri, 3 Jun 2005 14:09:54 -0500 Subject: JFS: Fix compiler warning in jfs_logmgr.c fs/jfs/jfs_logmgr.c: In function `jfs_flush_journal': fs/jfs/jfs_logmgr.c:1632: warning: unused variable `mp' Some debug code in jfs_flush_journal does nothing when CONFIG_JFS_DEBUG is not defined. Place the whole code segment within an ifdef to avoid unnecessary code to be compiled and the warning to be issued. Signed-off-by: Dave Kleikamp --- fs/jfs/jfs_logmgr.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index c5cc03bcae69..7c8387ed4192 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -1617,6 +1617,8 @@ void jfs_flush_journal(struct jfs_log *log, int wait) } } assert(list_empty(&log->cqueue)); + +#ifdef CONFIG_JFS_DEBUG if (!list_empty(&log->synclist)) { struct logsyncblk *lp; @@ -1631,9 +1633,8 @@ void jfs_flush_journal(struct jfs_log *log, int wait) dump_mem("orphan tblock", lp, sizeof(struct tblock)); } -// current->state = TASK_INTERRUPTIBLE; -// schedule(); } +#endif //assert(list_empty(&log->synclist)); clear_bit(log_FLUSH, &log->flag); } -- cgit v1.2.3-59-g8ed1b From b74e2159c9849fb97659c6dc47ad706f702b22b9 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Tue, 21 Jun 2005 13:21:49 +1000 Subject: [XFS] Add a get/set interface for XFS project identifiers. SGI-PV: 932952 SGI-Modid: xfs-linux:xfs-kern:21938a Signed-off-by: Nathan Scott --- fs/xfs/linux-2.6/xfs_ioctl.c | 22 ++++++++++++++++++++++ fs/xfs/linux-2.6/xfs_ioctl32.c | 2 ++ fs/xfs/linux-2.6/xfs_vnode.h | 2 +- fs/xfs/xfs_fs.h | 2 ++ fs/xfs/xfs_types.h | 2 +- 5 files changed, 28 insertions(+), 2 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index 69809eef8a54..df17d93bd096 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c @@ -777,6 +777,8 @@ xfs_ioctl( case XFS_IOC_GETVERSION: case XFS_IOC_GETXFLAGS: case XFS_IOC_SETXFLAGS: + case XFS_IOC_GETPROJID: + case XFS_IOC_SETPROJID: case XFS_IOC_FSGETXATTR: case XFS_IOC_FSSETXATTR: case XFS_IOC_FSGETXATTRA: @@ -1258,6 +1260,26 @@ xfs_ioc_xattr( return 0; } + case XFS_IOC_GETPROJID: { + va.va_mask = XFS_AT_PROJID; + VOP_GETATTR(vp, &va, 0, NULL, error); + if (error) + return -error; + if (copy_to_user(arg, &va.va_projid, sizeof(va.va_projid))) + return -XFS_ERROR(EFAULT); + return 0; + } + + case XFS_IOC_SETPROJID: { + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + va.va_mask = XFS_AT_PROJID; + if (copy_from_user(&va.va_projid, arg, sizeof(va.va_projid))) + return -XFS_ERROR(EFAULT); + VOP_SETATTR(vp, &va, 0, NULL, error); + return -error; + } + default: return -ENOTTY; } diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c index 0f8f1384eb36..be72aca59447 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl32.c +++ b/fs/xfs/linux-2.6/xfs_ioctl32.c @@ -100,6 +100,8 @@ __linvfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg) case XFS_IOC_GETBMAP: case XFS_IOC_GETBMAPA: case XFS_IOC_GETBMAPX: + case XFS_IOC_SETPROJID: + case XFS_IOC_GETPROJID: /* not handled case XFS_IOC_FD_TO_HANDLE: case XFS_IOC_PATH_TO_HANDLE: diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index 00466c3194ac..a6e57c647be4 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h @@ -426,7 +426,7 @@ typedef struct vattr { u_long va_extsize; /* file extent size */ u_long va_nextents; /* number of extents in file */ u_long va_anextents; /* number of attr extents in file */ - int va_projid; /* project id */ + prid_t va_projid; /* project id */ } vattr_t; /* diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h index 6ee8443bf9d3..a7bd4687fa50 100644 --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h @@ -477,6 +477,8 @@ typedef struct xfs_handle { /* XFS_IOC_SETBIOSIZE ---- deprecated 46 */ /* XFS_IOC_GETBIOSIZE ---- deprecated 47 */ #define XFS_IOC_GETBMAPX _IOWR('X', 56, struct getbmap) +#define XFS_IOC_SETPROJID _IOWR('X', 57, __uint32_t) +#define XFS_IOC_GETPROJID _IOWR('X', 58, __uint32_t) /* * ioctl commands that replace IRIX syssgi()'s diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h index e4bf711e48ff..16f5371ce102 100644 --- a/fs/xfs/xfs_types.h +++ b/fs/xfs/xfs_types.h @@ -55,7 +55,7 @@ typedef signed long long int __int64_t; typedef unsigned long long int __uint64_t; typedef enum { B_FALSE,B_TRUE } boolean_t; -typedef __int64_t prid_t; /* project ID */ +typedef __uint32_t prid_t; /* project ID */ typedef __uint32_t inst_t; /* an instruction */ typedef __s64 xfs_off_t; /* type */ -- cgit v1.2.3-59-g8ed1b From 6fac0cb46bc4c50d6cbc5998ad206435f39fb00f Mon Sep 17 00:00:00 2001 From: Dean Roehrich Date: Tue, 21 Jun 2005 14:07:45 +1000 Subject: [XFS] coordinate mmap calls with xfs_dm_punch_hole SGI-PV: 933551 SGI-Modid: xfs-linux:xfs-kern:190622a Signed-off-by: Dean Roehrich Signed-off-by: Nathan Scott --- fs/xfs/linux-2.6/xfs_file.c | 27 ++++++++++++++++++++++++--- fs/xfs/xfs_dmapi.h | 4 ++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 24fa3b101b93..f1ce4323f56e 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -57,7 +57,9 @@ #include static struct vm_operations_struct linvfs_file_vm_ops; - +#ifdef CONFIG_XFS_DMAPI +static struct vm_operations_struct linvfs_dmapi_file_vm_ops; +#endif STATIC inline ssize_t __linvfs_read( @@ -388,6 +390,14 @@ done: return -error; } +#ifdef CONFIG_XFS_DMAPI +STATIC void +linvfs_mmap_close( + struct vm_area_struct *vma) +{ + xfs_dm_mm_put(vma); +} +#endif /* CONFIG_XFS_DMAPI */ STATIC int linvfs_file_mmap( @@ -399,16 +409,19 @@ linvfs_file_mmap( vattr_t va = { .va_mask = XFS_AT_UPDATIME }; int error; + vma->vm_ops = &linvfs_file_vm_ops; + if (vp->v_vfsp->vfs_flag & VFS_DMI) { xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp); error = -XFS_SEND_MMAP(mp, vma, 0); if (error) return error; +#ifdef CONFIG_XFS_DMAPI + vma->vm_ops = &linvfs_dmapi_file_vm_ops; +#endif } - vma->vm_ops = &linvfs_file_vm_ops; - VOP_SETATTR(vp, &va, XFS_AT_UPDATIME, NULL, error); if (!error) vn_revalidate(vp); /* update Linux inode flags */ @@ -609,7 +622,15 @@ struct file_operations linvfs_dir_operations = { static struct vm_operations_struct linvfs_file_vm_ops = { .nopage = filemap_nopage, .populate = filemap_populate, +}; + +#ifdef CONFIG_XFS_DMAPI +static struct vm_operations_struct linvfs_dmapi_file_vm_ops = { + .close = linvfs_mmap_close, + .nopage = filemap_nopage, + .populate = filemap_populate, #ifdef HAVE_VMOP_MPROTECT .mprotect = linvfs_mprotect, #endif }; +#endif /* CONFIG_XFS_DMAPI */ diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h index 55ae3e67d245..16cf9f7a4785 100644 --- a/fs/xfs/xfs_dmapi.h +++ b/fs/xfs/xfs_dmapi.h @@ -209,4 +209,8 @@ void xfs_dm_exit(struct file_system_type *); #define XFS_DM_EXIT(fstype) #endif +#define HAVE_XFS_DM_MM +int xfs_dm_mm_get(struct vm_area_struct *vma); +void xfs_dm_mm_put(struct vm_area_struct *vma); + #endif /* __XFS_DMAPI_H__ */ -- cgit v1.2.3-59-g8ed1b -- cgit v1.2.3-59-g8ed1b -- cgit v1.2.3-59-g8ed1b -- cgit v1.2.3-59-g8ed1b From 23ea4032c875fc75c2363a9bcaba87cfb134ff68 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 21 Jun 2005 15:14:01 +1000 Subject: [XFS] rename various pagebuf symbols to xfsbuf SGI-PV: 908809 SGI-Modid: xfs-linux:xfs-kern:192348a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott --- fs/xfs/linux-2.6/xfs_buf.c | 143 ++++++++++++++++++++++++--------------------- 1 file changed, 77 insertions(+), 66 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 997963e53622..f5676ed5136d 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -61,12 +61,13 @@ * File wide globals */ -STATIC kmem_cache_t *pagebuf_cache; +STATIC kmem_cache_t *pagebuf_zone; STATIC kmem_shaker_t pagebuf_shake; -STATIC int pagebuf_daemon_wakeup(int, unsigned int); +STATIC int xfsbufd_wakeup(int, unsigned int); STATIC void pagebuf_delwri_queue(xfs_buf_t *, int); -STATIC struct workqueue_struct *pagebuf_logio_workqueue; -STATIC struct workqueue_struct *pagebuf_dataio_workqueue; + +STATIC struct workqueue_struct *xfslogd_workqueue; +STATIC struct workqueue_struct *xfsdatad_workqueue; /* * Pagebuf debugging @@ -123,9 +124,9 @@ ktrace_t *pagebuf_trace_buf; #define pagebuf_allocate(flags) \ - kmem_zone_alloc(pagebuf_cache, pb_to_km(flags)) + kmem_zone_alloc(pagebuf_zone, pb_to_km(flags)) #define pagebuf_deallocate(pb) \ - kmem_zone_free(pagebuf_cache, (pb)); + kmem_zone_free(pagebuf_zone, (pb)); /* * Page Region interfaces. @@ -425,7 +426,7 @@ _pagebuf_lookup_pages( __FUNCTION__, gfp_mask); XFS_STATS_INC(pb_page_retries); - pagebuf_daemon_wakeup(0, gfp_mask); + xfsbufd_wakeup(0, gfp_mask); blk_congestion_wait(WRITE, HZ/50); goto retry; } @@ -1136,8 +1137,8 @@ pagebuf_iodone( if ((pb->pb_iodone) || (pb->pb_flags & PBF_ASYNC)) { if (schedule) { INIT_WORK(&pb->pb_iodone_work, pagebuf_iodone_work, pb); - queue_work(dataio ? pagebuf_dataio_workqueue : - pagebuf_logio_workqueue, &pb->pb_iodone_work); + queue_work(dataio ? xfsdatad_workqueue : + xfslogd_workqueue, &pb->pb_iodone_work); } else { pagebuf_iodone_work(pb); } @@ -1742,27 +1743,27 @@ pagebuf_runall_queues( } /* Defines for pagebuf daemon */ -STATIC DECLARE_COMPLETION(pagebuf_daemon_done); -STATIC struct task_struct *pagebuf_daemon_task; -STATIC int pagebuf_daemon_active; -STATIC int force_flush; -STATIC int force_sleep; +STATIC DECLARE_COMPLETION(xfsbufd_done); +STATIC struct task_struct *xfsbufd_task; +STATIC int xfsbufd_active; +STATIC int xfsbufd_force_flush; +STATIC int xfsbufd_force_sleep; STATIC int -pagebuf_daemon_wakeup( +xfsbufd_wakeup( int priority, unsigned int mask) { - if (force_sleep) + if (xfsbufd_force_sleep) return 0; - force_flush = 1; + xfsbufd_force_flush = 1; barrier(); - wake_up_process(pagebuf_daemon_task); + wake_up_process(xfsbufd_task); return 0; } STATIC int -pagebuf_daemon( +xfsbufd( void *data) { struct list_head tmp; @@ -1774,17 +1775,17 @@ pagebuf_daemon( daemonize("xfsbufd"); current->flags |= PF_MEMALLOC; - pagebuf_daemon_task = current; - pagebuf_daemon_active = 1; + xfsbufd_task = current; + xfsbufd_active = 1; barrier(); INIT_LIST_HEAD(&tmp); do { if (unlikely(current->flags & PF_FREEZE)) { - force_sleep = 1; + xfsbufd_force_sleep = 1; refrigerator(PF_FREEZE); } else { - force_sleep = 0; + xfsbufd_force_sleep = 0; } set_current_state(TASK_INTERRUPTIBLE); @@ -1797,7 +1798,7 @@ pagebuf_daemon( ASSERT(pb->pb_flags & PBF_DELWRI); if (!pagebuf_ispin(pb) && !pagebuf_cond_lock(pb)) { - if (!force_flush && + if (!xfsbufd_force_flush && time_before(jiffies, pb->pb_queuetime + age)) { pagebuf_unlock(pb); @@ -1824,10 +1825,10 @@ pagebuf_daemon( if (as_list_len > 0) purge_addresses(); - force_flush = 0; - } while (pagebuf_daemon_active); + xfsbufd_force_flush = 0; + } while (xfsbufd_active); - complete_and_exit(&pagebuf_daemon_done, 0); + complete_and_exit(&xfsbufd_done, 0); } /* @@ -1844,8 +1845,8 @@ xfs_flush_buftarg( xfs_buf_t *pb, *n; int pincount = 0; - pagebuf_runall_queues(pagebuf_dataio_workqueue); - pagebuf_runall_queues(pagebuf_logio_workqueue); + pagebuf_runall_queues(xfsdatad_workqueue); + pagebuf_runall_queues(xfslogd_workqueue); INIT_LIST_HEAD(&tmp); spin_lock(&pbd_delwrite_lock); @@ -1898,43 +1899,43 @@ xfs_flush_buftarg( } STATIC int -pagebuf_daemon_start(void) +xfs_buf_daemons_start(void) { - int rval; + int error = -ENOMEM; - pagebuf_logio_workqueue = create_workqueue("xfslogd"); - if (!pagebuf_logio_workqueue) - return -ENOMEM; + xfslogd_workqueue = create_workqueue("xfslogd"); + if (!xfslogd_workqueue) + goto out; - pagebuf_dataio_workqueue = create_workqueue("xfsdatad"); - if (!pagebuf_dataio_workqueue) { - destroy_workqueue(pagebuf_logio_workqueue); - return -ENOMEM; - } + xfsdatad_workqueue = create_workqueue("xfsdatad"); + if (!xfsdatad_workqueue) + goto out_destroy_xfslogd_workqueue; - rval = kernel_thread(pagebuf_daemon, NULL, CLONE_FS|CLONE_FILES); - if (rval < 0) { - destroy_workqueue(pagebuf_logio_workqueue); - destroy_workqueue(pagebuf_dataio_workqueue); - } + error = kernel_thread(xfsbufd, NULL, CLONE_FS|CLONE_FILES); + if (error < 0) + goto out_destroy_xfsdatad_workqueue; + return 0; - return rval; + out_destroy_xfsdatad_workqueue: + destroy_workqueue(xfsdatad_workqueue); + out_destroy_xfslogd_workqueue: + destroy_workqueue(xfslogd_workqueue); + out: + return error; } /* - * pagebuf_daemon_stop - * * Note: do not mark as __exit, it is called from pagebuf_terminate. */ STATIC void -pagebuf_daemon_stop(void) +xfs_buf_daemons_stop(void) { - pagebuf_daemon_active = 0; + xfsbufd_active = 0; barrier(); - wait_for_completion(&pagebuf_daemon_done); + wait_for_completion(&xfsbufd_done); - destroy_workqueue(pagebuf_logio_workqueue); - destroy_workqueue(pagebuf_dataio_workqueue); + destroy_workqueue(xfslogd_workqueue); + destroy_workqueue(xfsdatad_workqueue); } /* @@ -1944,27 +1945,37 @@ pagebuf_daemon_stop(void) int __init pagebuf_init(void) { - pagebuf_cache = kmem_cache_create("xfs_buf_t", sizeof(xfs_buf_t), 0, - SLAB_HWCACHE_ALIGN, NULL, NULL); - if (pagebuf_cache == NULL) { - printk("XFS: couldn't init xfs_buf_t cache\n"); - pagebuf_terminate(); - return -ENOMEM; - } + int error = -ENOMEM; + + pagebuf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buf"); + if (!pagebuf_zone) + goto out; #ifdef PAGEBUF_TRACE pagebuf_trace_buf = ktrace_alloc(PAGEBUF_TRACE_SIZE, KM_SLEEP); #endif - pagebuf_daemon_start(); + error = xfs_buf_daemons_start(); + if (!error) + goto out_free_buf_zone; - pagebuf_shake = kmem_shake_register(pagebuf_daemon_wakeup); - if (pagebuf_shake == NULL) { - pagebuf_terminate(); - return -ENOMEM; + pagebuf_shake = kmem_shake_register(xfsbufd_wakeup); + if (!pagebuf_shake) { + error = -ENOMEM; + goto out_stop_daemons; } return 0; + + out_stop_daemons: + xfs_buf_daemons_stop(); + out_free_buf_zone: +#ifdef PAGEBUF_TRACE + ktrace_free(pagebuf_trace_buf); +#endif + kmem_zone_destroy(pagebuf_zone); + out: + return error; } @@ -1976,12 +1987,12 @@ pagebuf_init(void) void pagebuf_terminate(void) { - pagebuf_daemon_stop(); + xfs_buf_daemons_stop(); #ifdef PAGEBUF_TRACE ktrace_free(pagebuf_trace_buf); #endif - kmem_zone_destroy(pagebuf_cache); + kmem_zone_destroy(pagebuf_zone); kmem_shake_deregister(pagebuf_shake); } -- cgit v1.2.3-59-g8ed1b From 02de1f0abfc60aa4fead65eee4118d05667c93c3 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 21 Jun 2005 15:33:48 +1000 Subject: [XFS] fix some more compiler warnings in the vnode tracing code SGI-PV: 934679 SGI-Modid: xfs-linux:xfs-kern:192570a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott --- fs/xfs/linux-2.6/xfs_vnode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c index a832d165f24f..250cad54e892 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.c +++ b/fs/xfs/linux-2.6/xfs_vnode.c @@ -411,13 +411,13 @@ vn_remove( /* 0 */ (void *)(__psint_t)(vk), \ /* 1 */ (void *)(s), \ /* 2 */ (void *)(__psint_t) line, \ -/* 3 */ (void *)(vn_count(vp)), \ +/* 3 */ (void *)(__psint_t)(vn_count(vp)), \ /* 4 */ (void *)(ra), \ /* 5 */ (void *)(__psunsigned_t)(vp)->v_flag, \ /* 6 */ (void *)(__psint_t)current_cpu(), \ /* 7 */ (void *)(__psint_t)current_pid(), \ /* 8 */ (void *)__return_address, \ -/* 9 */ 0, 0, 0, 0, 0, 0, 0) +/* 9 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL) /* * Vnode tracing code. -- cgit v1.2.3-59-g8ed1b From cf9937c6c6c7edb6650411d1cf3cb57f072b1277 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 21 Jun 2005 15:35:24 +1000 Subject: [XFS] Fix pagebuf slab initialization SGI-PV: 908809 SGI-Modid: xfs-linux:xfs-kern:192756a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott --- fs/xfs/linux-2.6/xfs_buf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index f5676ed5136d..049f87116174 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -1956,7 +1956,7 @@ pagebuf_init(void) #endif error = xfs_buf_daemons_start(); - if (!error) + if (error) goto out_free_buf_zone; pagebuf_shake = kmem_shake_register(xfsbufd_wakeup); -- cgit v1.2.3-59-g8ed1b From 4372d6e10349d4e8b012588f86f15c740c73a7c4 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 21 Jun 2005 15:36:00 +1000 Subject: [XFS] Remove dead code. Patch from Adrian Bunk SGI-PV: 936255 SGI-Modid: xfs-linux:xfs-kern:192759a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott --- fs/xfs/quota/xfs_dquot.c | 62 ------------------------------------------------ fs/xfs/quota/xfs_dquot.h | 1 - fs/xfs/xfs_bmap_btree.c | 14 ----------- fs/xfs/xfs_bmap_btree.h | 8 ------- fs/xfs/xfs_fsops.c | 26 -------------------- fs/xfs/xfs_inode.c | 45 ----------------------------------- fs/xfs/xfs_rename.c | 18 -------------- fs/xfs/xfs_trans.c | 19 --------------- fs/xfs/xfs_trans.h | 3 --- fs/xfs/xfs_trans_inode.c | 18 -------------- 10 files changed, 214 deletions(-) diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 740d20d33187..c961ef7d847c 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c @@ -370,68 +370,6 @@ xfs_qm_adjust_dqtimers( } } -/* - * Increment or reset warnings of a given dquot. - */ -int -xfs_qm_dqwarn( - xfs_disk_dquot_t *d, - uint flags) -{ - int warned; - - /* - * root's limits are not real limits. - */ - if (!d->d_id) - return (0); - - warned = 0; - if (INT_GET(d->d_blk_softlimit, ARCH_CONVERT) && - (INT_GET(d->d_bcount, ARCH_CONVERT) >= - INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) { - if (flags & XFS_QMOPT_DOWARN) { - INT_MOD(d->d_bwarns, ARCH_CONVERT, +1); - warned++; - } - } else { - if (!d->d_blk_softlimit || - (INT_GET(d->d_bcount, ARCH_CONVERT) < - INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) { - d->d_bwarns = 0; - } - } - - if (INT_GET(d->d_ino_softlimit, ARCH_CONVERT) > 0 && - (INT_GET(d->d_icount, ARCH_CONVERT) >= - INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) { - if (flags & XFS_QMOPT_DOWARN) { - INT_MOD(d->d_iwarns, ARCH_CONVERT, +1); - warned++; - } - } else { - if (!d->d_ino_softlimit || - (INT_GET(d->d_icount, ARCH_CONVERT) < - INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) { - d->d_iwarns = 0; - } - } -#ifdef QUOTADEBUG - if (INT_GET(d->d_iwarns, ARCH_CONVERT)) - cmn_err(CE_DEBUG, - "--------@@Inode warnings running : %Lu >= %Lu", - INT_GET(d->d_icount, ARCH_CONVERT), - INT_GET(d->d_ino_softlimit, ARCH_CONVERT)); - if (INT_GET(d->d_bwarns, ARCH_CONVERT)) - cmn_err(CE_DEBUG, - "--------@@Blks warnings running : %Lu >= %Lu", - INT_GET(d->d_bcount, ARCH_CONVERT), - INT_GET(d->d_blk_softlimit, ARCH_CONVERT)); -#endif - return (warned); -} - - /* * initialize a buffer full of dquots and log the whole thing */ diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h index 0c3fe3175baa..35aeeafe4799 100644 --- a/fs/xfs/quota/xfs_dquot.h +++ b/fs/xfs/quota/xfs_dquot.h @@ -211,7 +211,6 @@ extern void xfs_qm_adjust_dqtimers(xfs_mount_t *, xfs_disk_dquot_t *); extern void xfs_qm_adjust_dqlimits(xfs_mount_t *, xfs_disk_dquot_t *); -extern int xfs_qm_dqwarn(xfs_disk_dquot_t *, uint); extern int xfs_qm_dqget(xfs_mount_t *, xfs_inode_t *, xfs_dqid_t, uint, uint, xfs_dquot_t **); extern void xfs_qm_dqput(xfs_dquot_t *); diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index 163305a79fcc..09c413576ba8 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c @@ -2331,20 +2331,6 @@ xfs_bmbt_lookup_ge( return xfs_bmbt_lookup(cur, XFS_LOOKUP_GE, stat); } -int /* error */ -xfs_bmbt_lookup_le( - xfs_btree_cur_t *cur, - xfs_fileoff_t off, - xfs_fsblock_t bno, - xfs_filblks_t len, - int *stat) /* success/failure */ -{ - cur->bc_rec.b.br_startoff = off; - cur->bc_rec.b.br_startblock = bno; - cur->bc_rec.b.br_blockcount = len; - return xfs_bmbt_lookup(cur, XFS_LOOKUP_LE, stat); -} - /* * Give the bmap btree a new root block. Copy the old broot contents * down into a real block and make the broot point to it. diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h index 843ff12b4bf2..0a40cf126c28 100644 --- a/fs/xfs/xfs_bmap_btree.h +++ b/fs/xfs/xfs_bmap_btree.h @@ -580,14 +580,6 @@ xfs_bmbt_lookup_ge( xfs_filblks_t, int *); -int -xfs_bmbt_lookup_le( - struct xfs_btree_cur *, - xfs_fileoff_t, - xfs_fsblock_t, - xfs_filblks_t, - int *); - /* * Give the bmap btree a new root block. Copy the old broot contents * down into a real block and make the broot point to it. diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 21213057c27f..ca535d613190 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -559,32 +559,6 @@ xfs_reserve_blocks( return(0); } -void -xfs_fs_log_dummy(xfs_mount_t *mp) -{ - xfs_trans_t *tp; - xfs_inode_t *ip; - - - tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1); - atomic_inc(&mp->m_active_trans); - if (xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0)) { - xfs_trans_cancel(tp, 0); - return; - } - - ip = mp->m_rootip; - xfs_ilock(ip, XFS_ILOCK_EXCL); - - xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); - xfs_trans_ihold(tp, ip); - xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - xfs_trans_set_sync(tp); - xfs_trans_commit(tp, 0, NULL); - - xfs_iunlock(ip, XFS_ILOCK_EXCL); -} - int xfs_fs_goingdown( xfs_mount_t *mp, diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index bc8c8c7f9039..e8274d6b7237 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -145,51 +145,6 @@ xfs_inobp_check( } #endif -/* - * called from bwrite on xfs inode buffers - */ -void -xfs_inobp_bwcheck(xfs_buf_t *bp) -{ - xfs_mount_t *mp; - int i; - int j; - xfs_dinode_t *dip; - - ASSERT(XFS_BUF_FSPRIVATE3(bp, void *) != NULL); - - mp = XFS_BUF_FSPRIVATE3(bp, xfs_mount_t *); - - - j = mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog; - - for (i = 0; i < j; i++) { - dip = (xfs_dinode_t *) xfs_buf_offset(bp, - i * mp->m_sb.sb_inodesize); - if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC) { - cmn_err(CE_WARN, -"Bad magic # 0x%x in XFS inode buffer 0x%Lx, starting blockno %Ld, offset 0x%x", - INT_GET(dip->di_core.di_magic, ARCH_CONVERT), - (__uint64_t)(__psunsigned_t) bp, - (__int64_t) XFS_BUF_ADDR(bp), - xfs_buf_offset(bp, i * mp->m_sb.sb_inodesize)); - xfs_fs_cmn_err(CE_WARN, mp, - "corrupt, unmount and run xfs_repair"); - } - if (!dip->di_next_unlinked) { - cmn_err(CE_WARN, -"Bad next_unlinked field (0) in XFS inode buffer 0x%p, starting blockno %Ld, offset 0x%x", - (__uint64_t)(__psunsigned_t) bp, - (__int64_t) XFS_BUF_ADDR(bp), - xfs_buf_offset(bp, i * mp->m_sb.sb_inodesize)); - xfs_fs_cmn_err(CE_WARN, mp, - "corrupt, unmount and run xfs_repair"); - } - } - - return; -} - /* * This routine is called to map an inode number within a file * system to the buffer containing the on-disk version of the diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c index cb13f9a1d45b..23b48ac1cb7e 100644 --- a/fs/xfs/xfs_rename.c +++ b/fs/xfs/xfs_rename.c @@ -234,9 +234,6 @@ xfs_lock_for_rename( return 0; } - -int rename_which_error_return = 0; - /* * xfs_rename */ @@ -316,7 +313,6 @@ xfs_rename( &num_inodes); if (error) { - rename_which_error_return = __LINE__; /* * We have nothing locked, no inode references, and * no transaction, so just get out. @@ -332,7 +328,6 @@ xfs_rename( */ if (target_ip == NULL && (src_dp != target_dp) && target_dp->i_d.di_nlink >= XFS_MAXLINK) { - rename_which_error_return = __LINE__; error = XFS_ERROR(EMLINK); xfs_rename_unlock4(inodes, XFS_ILOCK_SHARED); goto rele_return; @@ -359,7 +354,6 @@ xfs_rename( XFS_TRANS_PERM_LOG_RES, XFS_RENAME_LOG_COUNT); } if (error) { - rename_which_error_return = __LINE__; xfs_trans_cancel(tp, 0); goto rele_return; } @@ -369,7 +363,6 @@ xfs_rename( */ if ((error = XFS_QM_DQVOPRENAME(mp, inodes))) { xfs_trans_cancel(tp, cancel_flags); - rename_which_error_return = __LINE__; goto rele_return; } @@ -413,7 +406,6 @@ xfs_rename( if (spaceres == 0 && (error = XFS_DIR_CANENTER(mp, tp, target_dp, target_name, target_namelen))) { - rename_which_error_return = __LINE__; goto error_return; } /* @@ -425,11 +417,9 @@ xfs_rename( target_namelen, src_ip->i_ino, &first_block, &free_list, spaceres); if (error == ENOSPC) { - rename_which_error_return = __LINE__; goto error_return; } if (error) { - rename_which_error_return = __LINE__; goto abort_return; } xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); @@ -437,7 +427,6 @@ xfs_rename( if (new_parent && src_is_directory) { error = xfs_bumplink(tp, target_dp); if (error) { - rename_which_error_return = __LINE__; goto abort_return; } } @@ -455,7 +444,6 @@ xfs_rename( if (!(XFS_DIR_ISEMPTY(target_ip->i_mount, target_ip)) || (target_ip->i_d.di_nlink > 2)) { error = XFS_ERROR(EEXIST); - rename_which_error_return = __LINE__; goto error_return; } } @@ -473,7 +461,6 @@ xfs_rename( target_namelen, src_ip->i_ino, &first_block, &free_list, spaceres); if (error) { - rename_which_error_return = __LINE__; goto abort_return; } xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); @@ -484,7 +471,6 @@ xfs_rename( */ error = xfs_droplink(tp, target_ip); if (error) { - rename_which_error_return = __LINE__; goto abort_return; } target_ip_dropped = 1; @@ -495,7 +481,6 @@ xfs_rename( */ error = xfs_droplink(tp, target_ip); if (error) { - rename_which_error_return = __LINE__; goto abort_return; } } @@ -519,7 +504,6 @@ xfs_rename( &free_list, spaceres); ASSERT(error != EEXIST); if (error) { - rename_which_error_return = __LINE__; goto abort_return; } xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); @@ -550,7 +534,6 @@ xfs_rename( */ error = xfs_droplink(tp, src_dp); if (error) { - rename_which_error_return = __LINE__; goto abort_return; } } @@ -558,7 +541,6 @@ xfs_rename( error = XFS_DIR_REMOVENAME(mp, tp, src_dp, src_name, src_namelen, src_ip->i_ino, &first_block, &free_list, spaceres); if (error) { - rename_which_error_return = __LINE__; goto abort_return; } xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 3db0e2200775..a865f6035991 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -331,25 +331,6 @@ undo_blocks: } -/* - * This is called to set the a callback to be called when the given - * transaction is committed to disk. The transaction pointer and the - * argument pointer will be passed to the callback routine. - * - * Only one callback can be associated with any single transaction. - */ -void -xfs_trans_callback( - xfs_trans_t *tp, - xfs_trans_callback_t callback, - void *arg) -{ - ASSERT(tp->t_callback == NULL); - tp->t_callback = callback; - tp->t_callarg = arg; -} - - /* * Record the indicated change to the given field for application * to the file system's superblock when the transaction commits. diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index bd37ccb85e76..ec541d66fa2a 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -987,8 +987,6 @@ xfs_trans_t *_xfs_trans_alloc(struct xfs_mount *, uint); xfs_trans_t *xfs_trans_dup(xfs_trans_t *); int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, uint, uint); -void xfs_trans_callback(xfs_trans_t *, - void (*)(xfs_trans_t *, void *), void *); void xfs_trans_mod_sb(xfs_trans_t *, uint, long); struct xfs_buf *xfs_trans_get_buf(xfs_trans_t *, struct xfs_buftarg *, xfs_daddr_t, int, uint); @@ -1010,7 +1008,6 @@ int xfs_trans_iget(struct xfs_mount *, xfs_trans_t *, xfs_ino_t , uint, uint, struct xfs_inode **); void xfs_trans_ijoin(xfs_trans_t *, struct xfs_inode *, uint); void xfs_trans_ihold(xfs_trans_t *, struct xfs_inode *); -void xfs_trans_ihold_release(xfs_trans_t *, struct xfs_inode *); void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint); void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint); struct xfs_efi_log_item *xfs_trans_get_efi(xfs_trans_t *, uint); diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c index e2c3706f453d..7e7631ca4979 100644 --- a/fs/xfs/xfs_trans_inode.c +++ b/fs/xfs/xfs_trans_inode.c @@ -253,24 +253,6 @@ xfs_trans_ihold( ip->i_itemp->ili_flags |= XFS_ILI_HOLD; } -/* - * Cancel the previous inode hold request made on this inode - * for this transaction. - */ -/*ARGSUSED*/ -void -xfs_trans_ihold_release( - xfs_trans_t *tp, - xfs_inode_t *ip) -{ - ASSERT(ip->i_transp == tp); - ASSERT(ip->i_itemp != NULL); - ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); - ASSERT(ip->i_itemp->ili_flags & XFS_ILI_HOLD); - - ip->i_itemp->ili_flags &= ~XFS_ILI_HOLD; -} - /* * This is called to mark the fields indicated in fieldmask as needing -- cgit v1.2.3-59-g8ed1b From ba0f32d46049e2b625dabd33c7964f8ca2cd7651 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 21 Jun 2005 15:36:52 +1000 Subject: [XFS] mark various symbols static Patch from Adrian Bunk SGI-PV: 936255 SGI-Modid: xfs-linux:xfs-kern:192760a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott --- fs/xfs/quota/xfs_dquot.c | 2 +- fs/xfs/quota/xfs_dquot_item.c | 6 +++--- fs/xfs/quota/xfs_qm.c | 24 +++++++++++++++--------- fs/xfs/quota/xfs_qm.h | 6 ------ fs/xfs/quota/xfs_qm_bhv.c | 2 +- fs/xfs/quota/xfs_trans_dquot.c | 4 ++-- fs/xfs/xfs_alloc.c | 4 ++-- fs/xfs/xfs_attr.c | 17 ++++++++++++----- fs/xfs/xfs_attr.h | 7 ------- fs/xfs/xfs_attr_leaf.c | 28 ++++++++++++++++++++++------ fs/xfs/xfs_attr_leaf.h | 12 ------------ fs/xfs/xfs_bit.c | 2 +- fs/xfs/xfs_bmap.c | 15 ++++++++++++++- fs/xfs/xfs_bmap.h | 13 ------------- fs/xfs/xfs_btree.c | 12 +++++++++++- fs/xfs/xfs_btree.h | 10 ---------- fs/xfs/xfs_buf_item.c | 24 ++++++++++++------------ fs/xfs/xfs_da_btree.c | 9 ++++++--- fs/xfs/xfs_da_btree.h | 3 --- fs/xfs/xfs_dir2_data.c | 2 +- fs/xfs/xfs_dir2_data.h | 4 ---- fs/xfs/xfs_dir2_leaf.c | 8 ++++++-- fs/xfs/xfs_dir2_leaf.h | 7 ------- fs/xfs/xfs_dir_leaf.c | 6 +++++- fs/xfs/xfs_dir_leaf.h | 2 -- fs/xfs/xfs_error.c | 2 +- fs/xfs/xfs_error.h | 3 --- fs/xfs/xfs_extfree_item.c | 4 ++-- fs/xfs/xfs_inode.c | 6 +++--- fs/xfs/xfs_inode.h | 2 -- fs/xfs/xfs_inode_item.c | 2 +- fs/xfs/xfs_log.c | 6 +++--- fs/xfs/xfs_log_priv.h | 2 -- fs/xfs/xfs_log_recover.c | 6 +++--- fs/xfs/xfs_mount.c | 5 +++-- fs/xfs/xfs_mount.h | 1 - fs/xfs/xfs_trans.c | 2 +- fs/xfs/xfs_vfsops.c | 4 ++-- fs/xfs/xfs_vnodeops.c | 4 ++-- 39 files changed, 135 insertions(+), 143 deletions(-) diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index c961ef7d847c..9ce471430a0e 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c @@ -101,7 +101,7 @@ int xfs_dqerror_mod = 33; * is the d_id field. The idea is to fill in the entire q_core * when we read in the on disk dquot. */ -xfs_dquot_t * +STATIC xfs_dquot_t * xfs_qm_dqinit( xfs_mount_t *mp, xfs_dqid_t id, diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c index a5425ee6e7bd..f5271b7b1e84 100644 --- a/fs/xfs/quota/xfs_dquot_item.c +++ b/fs/xfs/quota/xfs_dquot_item.c @@ -428,7 +428,7 @@ xfs_qm_dquot_logitem_committing( /* * This is the ops vector for dquots */ -struct xfs_item_ops xfs_dquot_item_ops = { +STATIC struct xfs_item_ops xfs_dquot_item_ops = { .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_size, .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_qm_dquot_logitem_format, @@ -646,7 +646,7 @@ xfs_qm_qoffend_logitem_committing(xfs_qoff_logitem_t *qip, xfs_lsn_t commit_lsn) return; } -struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { +STATIC struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size, .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_qm_qoff_logitem_format, @@ -669,7 +669,7 @@ struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { /* * This is the ops vector shared by all quotaoff-start log items. */ -struct xfs_item_ops xfs_qm_qoff_logitem_ops = { +STATIC struct xfs_item_ops xfs_qm_qoff_logitem_ops = { .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size, .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_qm_qoff_logitem_format, diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 89f2cd656ebf..41bbc49d535e 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -81,12 +81,18 @@ struct xfs_qm *xfs_Gqm; kmem_zone_t *qm_dqzone; kmem_zone_t *qm_dqtrxzone; -kmem_shaker_t xfs_qm_shaker; +STATIC kmem_shaker_t xfs_qm_shaker; STATIC void xfs_qm_list_init(xfs_dqlist_t *, char *, int); STATIC void xfs_qm_list_destroy(xfs_dqlist_t *); +STATIC void xfs_qm_freelist_init(xfs_frlist_t *); +STATIC void xfs_qm_freelist_destroy(xfs_frlist_t *); +STATIC int xfs_qm_mplist_nowait(xfs_mount_t *); +STATIC int xfs_qm_dqhashlock_nowait(xfs_dquot_t *); + STATIC int xfs_qm_init_quotainos(xfs_mount_t *); +STATIC int xfs_qm_init_quotainfo(xfs_mount_t *); STATIC int xfs_qm_shake(int, unsigned int); #ifdef DEBUG @@ -184,7 +190,7 @@ xfs_Gqm_init(void) /* * Destroy the global quota manager when its reference count goes to zero. */ -void +STATIC void xfs_qm_destroy( struct xfs_qm *xqm) { @@ -509,7 +515,7 @@ out: * Flush all dquots of the given file system to disk. The dquots are * _not_ purged from memory here, just their data written to disk. */ -int +STATIC int xfs_qm_dqflush_all( xfs_mount_t *mp, int flags) @@ -1149,7 +1155,7 @@ xfs_qm_sync( * This initializes all the quota information that's kept in the * mount structure */ -int +STATIC int xfs_qm_init_quotainfo( xfs_mount_t *mp) { @@ -2751,7 +2757,7 @@ xfs_qm_vop_dqattach_and_dqmod_newinode( } /* ------------- list stuff -----------------*/ -void +STATIC void xfs_qm_freelist_init(xfs_frlist_t *ql) { ql->qh_next = ql->qh_prev = (xfs_dquot_t *) ql; @@ -2760,7 +2766,7 @@ xfs_qm_freelist_init(xfs_frlist_t *ql) ql->qh_nelems = 0; } -void +STATIC void xfs_qm_freelist_destroy(xfs_frlist_t *ql) { xfs_dquot_t *dqp, *nextdqp; @@ -2786,7 +2792,7 @@ xfs_qm_freelist_destroy(xfs_frlist_t *ql) ASSERT(ql->qh_nelems == 0); } -void +STATIC void xfs_qm_freelist_insert(xfs_frlist_t *ql, xfs_dquot_t *dq) { dq->dq_flnext = ql->qh_next; @@ -2816,7 +2822,7 @@ xfs_qm_freelist_append(xfs_frlist_t *ql, xfs_dquot_t *dq) xfs_qm_freelist_insert((xfs_frlist_t *)ql->qh_prev, dq); } -int +STATIC int xfs_qm_dqhashlock_nowait( xfs_dquot_t *dqp) { @@ -2836,7 +2842,7 @@ xfs_qm_freelist_lock_nowait( return (locked); } -int +STATIC int xfs_qm_mplist_nowait( xfs_mount_t *mp) { diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h index dcf1a7a831d8..ae626eca5aca 100644 --- a/fs/xfs/quota/xfs_qm.h +++ b/fs/xfs/quota/xfs_qm.h @@ -184,7 +184,6 @@ typedef struct xfs_dquot_acct { extern void xfs_mount_reset_sbqflags(xfs_mount_t *); -extern int xfs_qm_init_quotainfo(xfs_mount_t *); extern void xfs_qm_destroy_quotainfo(xfs_mount_t *); extern int xfs_qm_mount_quotas(xfs_mount_t *, int); extern void xfs_qm_mount_quotainit(xfs_mount_t *, uint); @@ -215,14 +214,9 @@ extern int xfs_qm_vop_chown_reserve(xfs_trans_t *, xfs_inode_t *, xfs_dquot_t *, xfs_dquot_t *, uint); /* list stuff */ -extern void xfs_qm_freelist_init(xfs_frlist_t *); -extern void xfs_qm_freelist_destroy(xfs_frlist_t *); -extern void xfs_qm_freelist_insert(xfs_frlist_t *, xfs_dquot_t *); extern void xfs_qm_freelist_append(xfs_frlist_t *, xfs_dquot_t *); extern void xfs_qm_freelist_unlink(xfs_dquot_t *); extern int xfs_qm_freelist_lock_nowait(xfs_qm_t *); -extern int xfs_qm_mplist_nowait(xfs_mount_t *); -extern int xfs_qm_dqhashlock_nowait(xfs_dquot_t *); /* system call interface */ extern int xfs_qm_quotactl(bhv_desc_t *, int, int, xfs_caddr_t); diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c index be67d9c265f8..09b1171dfb83 100644 --- a/fs/xfs/quota/xfs_qm_bhv.c +++ b/fs/xfs/quota/xfs_qm_bhv.c @@ -359,7 +359,7 @@ xfs_qm_dqrele_null( } -struct xfs_qmops xfs_qmcore_xfs = { +STATIC struct xfs_qmops xfs_qmcore_xfs = { .xfs_qminit = xfs_qm_newmount, .xfs_qmdone = xfs_qm_unmount_quotadestroy, .xfs_qmmount = xfs_qm_endmount, diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c index 149b2a1fd949..3644ca00cc82 100644 --- a/fs/xfs/quota/xfs_trans_dquot.c +++ b/fs/xfs/quota/xfs_trans_dquot.c @@ -187,7 +187,7 @@ xfs_trans_dup_dqinfo( /* * Wrap around mod_dquot to account for both user and group quotas. */ -void +STATIC void xfs_trans_mod_dquot_byino( xfs_trans_t *tp, xfs_inode_t *ip, @@ -368,7 +368,7 @@ xfs_trans_dqlockedjoin( * Unreserve just the reservations done by this transaction. * dquot is still left locked at exit. */ -void +STATIC void xfs_trans_apply_dquot_deltas( xfs_trans_t *tp) { diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 36603db10fe9..dcfe19703620 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c @@ -59,7 +59,7 @@ #define XFSA_FIXUP_BNO_OK 1 #define XFSA_FIXUP_CNT_OK 2 -int +STATIC int xfs_alloc_search_busy(xfs_trans_t *tp, xfs_agnumber_t agno, xfs_agblock_t bno, @@ -2562,7 +2562,7 @@ xfs_alloc_clear_busy(xfs_trans_t *tp, /* * returns non-zero if any of (agno,bno):len is in a busy list */ -int +STATIC int xfs_alloc_search_busy(xfs_trans_t *tp, xfs_agnumber_t agno, xfs_agblock_t bno, diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index ee8b5904ec7c..a41ad3a5e554 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c @@ -71,6 +71,11 @@ * Provide the external interfaces to manage attribute lists. */ +#define ATTR_SYSCOUNT 2 +STATIC struct attrnames posix_acl_access; +STATIC struct attrnames posix_acl_default; +STATIC struct attrnames *attr_system_names[ATTR_SYSCOUNT]; + /*======================================================================== * Function prototypes for the kernel. *========================================================================*/ @@ -83,6 +88,7 @@ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args); /* * Internal routines when attribute list is one block. */ +STATIC int xfs_attr_leaf_get(xfs_da_args_t *args); STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args); STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args); STATIC int xfs_attr_leaf_list(xfs_attr_list_context_t *context); @@ -90,6 +96,7 @@ STATIC int xfs_attr_leaf_list(xfs_attr_list_context_t *context); /* * Internal routines when attribute list is more than one block. */ +STATIC int xfs_attr_node_get(xfs_da_args_t *args); STATIC int xfs_attr_node_addname(xfs_da_args_t *args); STATIC int xfs_attr_node_removename(xfs_da_args_t *args); STATIC int xfs_attr_node_list(xfs_attr_list_context_t *context); @@ -1102,7 +1109,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) * This leaf block cannot have a "remote" value, we only call this routine * if bmap_one_block() says there is only one block (ie: no remote blks). */ -int +STATIC int xfs_attr_leaf_get(xfs_da_args_t *args) { xfs_dabuf_t *bp; @@ -1707,7 +1714,7 @@ xfs_attr_refillstate(xfs_da_state_t *state) * block, ie: both true Btree attr lists and for single-leaf-blocks with * "remote" values taking up more blocks. */ -int +STATIC int xfs_attr_node_get(xfs_da_args_t *args) { xfs_da_state_t *state; @@ -2398,7 +2405,7 @@ posix_acl_default_exists( return xfs_acl_vhasacl_default(vp); } -struct attrnames posix_acl_access = { +STATIC struct attrnames posix_acl_access = { .attr_name = "posix_acl_access", .attr_namelen = sizeof("posix_acl_access") - 1, .attr_get = posix_acl_access_get, @@ -2407,7 +2414,7 @@ struct attrnames posix_acl_access = { .attr_exists = posix_acl_access_exists, }; -struct attrnames posix_acl_default = { +STATIC struct attrnames posix_acl_default = { .attr_name = "posix_acl_default", .attr_namelen = sizeof("posix_acl_default") - 1, .attr_get = posix_acl_default_get, @@ -2416,7 +2423,7 @@ struct attrnames posix_acl_default = { .attr_exists = posix_acl_default_exists, }; -struct attrnames *attr_system_names[] = +STATIC struct attrnames *attr_system_names[] = { &posix_acl_access, &posix_acl_default }; diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h index 67cd0f5ac1a7..45ab1c542baf 100644 --- a/fs/xfs/xfs_attr.h +++ b/fs/xfs/xfs_attr.h @@ -76,11 +76,6 @@ extern struct attrnames attr_system; extern struct attrnames attr_trusted; extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT]; -#define ATTR_SYSCOUNT 2 -extern struct attrnames posix_acl_access; -extern struct attrnames posix_acl_default; -extern struct attrnames *attr_system_names[ATTR_SYSCOUNT]; - extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int); extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *); @@ -184,8 +179,6 @@ int xfs_attr_list(bhv_desc_t *, char *, int, int, struct attrlist_cursor_kern *, struct cred *); int xfs_attr_inactive(struct xfs_inode *dp); -int xfs_attr_node_get(struct xfs_da_args *); -int xfs_attr_leaf_get(struct xfs_da_args *); int xfs_attr_shortform_getvalue(struct xfs_da_args *); int xfs_attr_fetch(struct xfs_inode *, char *, int, char *, int *, int, struct cred *); diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index b11256e58bf4..1cdd574c63a9 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c @@ -79,6 +79,8 @@ /* * Routines used for growing the Btree. */ +STATIC int xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t which_block, + xfs_dabuf_t **bpp); STATIC int xfs_attr_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args, int freemap_index); STATIC void xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer); @@ -91,6 +93,16 @@ STATIC int xfs_attr_leaf_figure_balance(xfs_da_state_t *state, int *number_entries_in_blk1, int *number_usedbytes_in_blk1); +/* + * Routines used for shrinking the Btree. + */ +STATIC int xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, + xfs_dabuf_t *bp, int level); +STATIC int xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, + xfs_dabuf_t *bp); +STATIC int xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp, + xfs_dablk_t blkno, int blkcnt); + /* * Utility routines. */ @@ -99,6 +111,10 @@ STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf, xfs_attr_leafblock_t *dst_leaf, int dst_start, int move_count, xfs_mount_t *mp); +STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); +STATIC int xfs_attr_put_listent(xfs_attr_list_context_t *context, + attrnames_t *, char *name, int namelen, + int valuelen); /*======================================================================== @@ -774,7 +790,7 @@ out: * Create the initial contents of a leaf attribute list * or a leaf in a node attribute list. */ -int +STATIC int xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp) { xfs_attr_leafblock_t *leaf; @@ -2209,7 +2225,7 @@ xfs_attr_leaf_lasthash(xfs_dabuf_t *bp, int *count) * Calculate the number of bytes used to store the indicated attribute * (whether local or remote only calculate bytes in this block). */ -int +STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index) { xfs_attr_leaf_name_local_t *name_loc; @@ -2380,7 +2396,7 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) * we may be reading them directly out of a user buffer. */ /*ARGSUSED*/ -int +STATIC int xfs_attr_put_listent(xfs_attr_list_context_t *context, attrnames_t *namesp, char *name, int namelen, int valuelen) { @@ -2740,7 +2756,7 @@ xfs_attr_root_inactive(xfs_trans_t **trans, xfs_inode_t *dp) * Recurse (gasp!) through the attribute nodes until we find leaves. * We're doing a depth-first traversal in order to invalidate everything. */ -int +STATIC int xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp, int level) { @@ -2849,7 +2865,7 @@ xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp, * Note that we must release the lock on the buffer so that we are not * caught holding something that the logging code wants to flush to disk. */ -int +STATIC int xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp) { xfs_attr_leafblock_t *leaf; @@ -2934,7 +2950,7 @@ xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp) * Look at all the extents for this logical region, * invalidate any buffers that are incore/in transactions. */ -int +STATIC int xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dablk_t blkno, int blkcnt) { diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h index b1480e0b3349..0a4cfad6df91 100644 --- a/fs/xfs/xfs_attr_leaf.h +++ b/fs/xfs/xfs_attr_leaf.h @@ -261,8 +261,6 @@ int xfs_attr_leaf_flipflags(xfs_da_args_t *args); /* * Routines used for growing the Btree. */ -int xfs_attr_leaf_create(struct xfs_da_args *args, xfs_dablk_t which_block, - struct xfs_dabuf **bpp); int xfs_attr_leaf_split(struct xfs_da_state *state, struct xfs_da_state_blk *oldblk, struct xfs_da_state_blk *newblk); @@ -284,12 +282,6 @@ void xfs_attr_leaf_unbalance(struct xfs_da_state *state, struct xfs_da_state_blk *drop_blk, struct xfs_da_state_blk *save_blk); int xfs_attr_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp); -int xfs_attr_node_inactive(struct xfs_trans **trans, struct xfs_inode *dp, - struct xfs_dabuf *bp, int level); -int xfs_attr_leaf_inactive(struct xfs_trans **trans, struct xfs_inode *dp, - struct xfs_dabuf *bp); -int xfs_attr_leaf_freextent(struct xfs_trans **trans, struct xfs_inode *dp, - xfs_dablk_t blkno, int blkcnt); /* * Utility routines. @@ -299,10 +291,6 @@ int xfs_attr_leaf_order(struct xfs_dabuf *leaf1_bp, struct xfs_dabuf *leaf2_bp); int xfs_attr_leaf_newentsize(struct xfs_da_args *args, int blocksize, int *local); -int xfs_attr_leaf_entsize(struct xfs_attr_leafblock *leaf, int index); -int xfs_attr_put_listent(struct xfs_attr_list_context *context, - struct attrnames *, char *name, int namelen, - int valuelen); int xfs_attr_rolltrans(struct xfs_trans **transp, struct xfs_inode *dp); #endif /* __XFS_ATTR_LEAF_H__ */ diff --git a/fs/xfs/xfs_bit.c b/fs/xfs/xfs_bit.c index a20a6c3dc13e..76c9ad3875ef 100644 --- a/fs/xfs/xfs_bit.c +++ b/fs/xfs/xfs_bit.c @@ -45,7 +45,7 @@ /* * Index of high bit number in byte, -1 for none set, 0..7 otherwise. */ -const char xfs_highbit[256] = { +STATIC const char xfs_highbit[256] = { -1, 0, 1, 1, 2, 2, 2, 2, /* 00 .. 07 */ 3, 3, 3, 3, 3, 3, 3, 3, /* 08 .. 0f */ 4, 4, 4, 4, 4, 4, 4, 4, /* 10 .. 17 */ diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index de3162418663..f6f5ad35734c 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -301,6 +301,19 @@ xfs_bmap_search_extents( xfs_bmbt_irec_t *gotp, /* out: extent entry found */ xfs_bmbt_irec_t *prevp); /* out: previous extent entry found */ +/* + * Check the last inode extent to determine whether this allocation will result + * in blocks being allocated at the end of the file. When we allocate new data + * blocks at the end of the file which do not start at the previous data block, + * we will try to align the new blocks at stripe unit boundaries. + */ +STATIC int /* error */ +xfs_bmap_isaeof( + xfs_inode_t *ip, /* incore inode pointer */ + xfs_fileoff_t off, /* file offset in fsblocks */ + int whichfork, /* data or attribute fork */ + char *aeof); /* return value */ + #ifdef XFS_BMAP_TRACE /* * Add a bmap trace buffer entry. Base routine for the others. @@ -5714,7 +5727,7 @@ unlock_and_return: * blocks at the end of the file which do not start at the previous data block, * we will try to align the new blocks at stripe unit boundaries. */ -int /* error */ +STATIC int /* error */ xfs_bmap_isaeof( xfs_inode_t *ip, /* incore inode pointer */ xfs_fileoff_t off, /* file offset in fsblocks */ diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h index f1bc22fb26ae..e6d22ec9b2e4 100644 --- a/fs/xfs/xfs_bmap.h +++ b/fs/xfs/xfs_bmap.h @@ -331,19 +331,6 @@ xfs_getbmap( void __user *ap, /* pointer to user's array */ int iflags); /* interface flags */ -/* - * Check the last inode extent to determine whether this allocation will result - * in blocks being allocated at the end of the file. When we allocate new data - * blocks at the end of the file which do not start at the previous data block, - * we will try to align the new blocks at stripe unit boundaries. - */ -int -xfs_bmap_isaeof( - struct xfs_inode *ip, - xfs_fileoff_t off, - int whichfork, - char *aeof); - /* * Check if the endoff is outside the last extent. If so the caller will grow * the allocation to a stripe unit boundary diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index 9dd22dd95487..797f4d96cdf3 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c @@ -89,6 +89,16 @@ xfs_btree_maxrecs( * Internal routines. */ +/* + * Retrieve the block pointer from the cursor at the given level. + * This may be a bmap btree root or from a buffer. + */ +xfs_btree_block_t * /* generic btree block pointer */ +xfs_btree_get_block( + xfs_btree_cur_t *cur, /* btree cursor */ + int level, /* level in btree */ + struct xfs_buf **bpp); /* buffer containing the block */ + /* * Checking routine: return maxrecs for the block. */ @@ -497,7 +507,7 @@ xfs_btree_firstrec( * Retrieve the block pointer from the cursor at the given level. * This may be a bmap btree root or from a buffer. */ -xfs_btree_block_t * /* generic btree block pointer */ +STATIC xfs_btree_block_t * /* generic btree block pointer */ xfs_btree_get_block( xfs_btree_cur_t *cur, /* btree cursor */ int level, /* level in btree */ diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h index 93872bba41f5..09b4e1532a35 100644 --- a/fs/xfs/xfs_btree.h +++ b/fs/xfs/xfs_btree.h @@ -324,16 +324,6 @@ xfs_btree_firstrec( xfs_btree_cur_t *cur, /* btree cursor */ int level); /* level to change */ -/* - * Retrieve the block pointer from the cursor at the given level. - * This may be a bmap btree root or from a buffer. - */ -xfs_btree_block_t * /* generic btree block pointer */ -xfs_btree_get_block( - xfs_btree_cur_t *cur, /* btree cursor */ - int level, /* level in btree */ - struct xfs_buf **bpp); /* buffer containing the block */ - /* * Get a buffer for the block, return it with no data read. * Long-form addressing. diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 9ab0039f07df..30b8285ad476 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -172,7 +172,7 @@ STATIC void xfs_buf_do_callbacks(xfs_buf_t *bp, xfs_log_item_t *lip); * * If the XFS_BLI_STALE flag has been set, then log nothing. */ -uint +STATIC uint xfs_buf_item_size( xfs_buf_log_item_t *bip) { @@ -240,7 +240,7 @@ xfs_buf_item_size( * format structure, and the rest point to contiguous chunks * within the buffer. */ -void +STATIC void xfs_buf_item_format( xfs_buf_log_item_t *bip, xfs_log_iovec_t *log_vector) @@ -365,7 +365,7 @@ xfs_buf_item_format( * item in memory so it cannot be written out. Simply call bpin() * on the buffer to do this. */ -void +STATIC void xfs_buf_item_pin( xfs_buf_log_item_t *bip) { @@ -391,7 +391,7 @@ xfs_buf_item_pin( * If the XFS_BLI_STALE flag is set and we are the last reference, * then free up the buf log item and unlock the buffer. */ -void +STATIC void xfs_buf_item_unpin( xfs_buf_log_item_t *bip, int stale) @@ -446,7 +446,7 @@ xfs_buf_item_unpin( * so we need to free the item's descriptor (that points to the item) * in the transaction. */ -void +STATIC void xfs_buf_item_unpin_remove( xfs_buf_log_item_t *bip, xfs_trans_t *tp) @@ -493,7 +493,7 @@ xfs_buf_item_unpin_remove( * the lock right away, return 0. If we can get the lock, pull the * buffer from the free list, mark it busy, and return 1. */ -uint +STATIC uint xfs_buf_item_trylock( xfs_buf_log_item_t *bip) { @@ -537,7 +537,7 @@ xfs_buf_item_trylock( * This is for support of xfs_trans_bhold(). Make sure the * XFS_BLI_HOLD field is cleared if we don't free the item. */ -void +STATIC void xfs_buf_item_unlock( xfs_buf_log_item_t *bip) { @@ -635,7 +635,7 @@ xfs_buf_item_unlock( * by returning the original lsn of that transaction here rather than * the current one. */ -xfs_lsn_t +STATIC xfs_lsn_t xfs_buf_item_committed( xfs_buf_log_item_t *bip, xfs_lsn_t lsn) @@ -654,7 +654,7 @@ xfs_buf_item_committed( * and have aborted this transaction, we'll trap this buffer when it tries to * get written out. */ -void +STATIC void xfs_buf_item_abort( xfs_buf_log_item_t *bip) { @@ -674,7 +674,7 @@ xfs_buf_item_abort( * B_DELWRI set, then get it going out to disk with a call to bawrite(). * If not, then just release the buffer. */ -void +STATIC void xfs_buf_item_push( xfs_buf_log_item_t *bip) { @@ -693,7 +693,7 @@ xfs_buf_item_push( } /* ARGSUSED */ -void +STATIC void xfs_buf_item_committing(xfs_buf_log_item_t *bip, xfs_lsn_t commit_lsn) { } @@ -701,7 +701,7 @@ xfs_buf_item_committing(xfs_buf_log_item_t *bip, xfs_lsn_t commit_lsn) /* * This is the ops vector shared by all buf log items. */ -struct xfs_item_ops xfs_buf_item_ops = { +STATIC struct xfs_item_ops xfs_buf_item_ops = { .iop_size = (uint(*)(xfs_log_item_t*))xfs_buf_item_size, .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_buf_item_format, diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index d7fe28866764..8b792ddf2164 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c @@ -113,7 +113,10 @@ STATIC void xfs_da_node_unbalance(xfs_da_state_t *state, STATIC uint xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count); STATIC int xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp); STATIC xfs_dabuf_t *xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra); - +STATIC int xfs_da_blk_unlink(xfs_da_state_t *state, + xfs_da_state_blk_t *drop_blk, + xfs_da_state_blk_t *save_blk); +STATIC void xfs_da_state_kill_altpath(xfs_da_state_t *state); /*======================================================================== * Routines used for growing the Btree. @@ -1424,7 +1427,7 @@ xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count) /* * Unlink a block from a doubly linked list of blocks. */ -int /* error */ +STATIC int /* error */ xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, xfs_da_state_blk_t *save_blk) { @@ -2381,7 +2384,7 @@ xfs_da_state_alloc(void) /* * Kill the altpath contents of a da-state structure. */ -void +STATIC void xfs_da_state_kill_altpath(xfs_da_state_t *state) { int i; diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h index 9fc699d96995..3a9b9e809c60 100644 --- a/fs/xfs/xfs_da_btree.h +++ b/fs/xfs/xfs_da_btree.h @@ -296,8 +296,6 @@ int xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, /* * Utility routines. */ -int xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, - xfs_da_state_blk_t *save_blk); int xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, xfs_da_state_blk_t *new_blk); @@ -320,7 +318,6 @@ uint xfs_da_hashname(uchar_t *name_string, int name_length); uint xfs_da_log2_roundup(uint i); xfs_da_state_t *xfs_da_state_alloc(void); void xfs_da_state_free(xfs_da_state_t *state); -void xfs_da_state_kill_altpath(xfs_da_state_t *state); void xfs_da_buf_done(xfs_dabuf_t *dabuf); void xfs_da_log_buf(struct xfs_trans *tp, xfs_dabuf_t *dabuf, uint first, diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c index db9887a107de..a0aa0e44ff9d 100644 --- a/fs/xfs/xfs_dir2_data.c +++ b/fs/xfs/xfs_dir2_data.c @@ -304,7 +304,7 @@ xfs_dir2_data_freeinsert( /* * Remove a bestfree entry from the table. */ -void +STATIC void xfs_dir2_data_freeremove( xfs_dir2_data_t *d, /* data block pointer */ xfs_dir2_data_free_t *dfp, /* bestfree entry pointer */ diff --git a/fs/xfs/xfs_dir2_data.h b/fs/xfs/xfs_dir2_data.h index 3f02294ccff0..476cac920bf5 100644 --- a/fs/xfs/xfs_dir2_data.h +++ b/fs/xfs/xfs_dir2_data.h @@ -192,10 +192,6 @@ extern xfs_dir2_data_free_t * xfs_dir2_data_freeinsert(xfs_dir2_data_t *d, xfs_dir2_data_unused_t *dup, int *loghead); -extern void - xfs_dir2_data_freeremove(xfs_dir2_data_t *d, - xfs_dir2_data_free_t *dfp, int *loghead); - extern void xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d, int *loghead, char *aendp); diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index 262d1e86df30..79918df6ffea 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c @@ -77,6 +77,10 @@ static void xfs_dir2_leaf_check(xfs_inode_t *dp, xfs_dabuf_t *bp); #endif static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **lbpp, int *indexp, xfs_dabuf_t **dbpp); +static void xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp, + int first, int last); +extern void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp); + /* * Convert a block form directory to a leaf form directory. @@ -1214,7 +1218,7 @@ xfs_dir2_leaf_init( /* * Log the bests entries indicated from a leaf1 block. */ -void +static void xfs_dir2_leaf_log_bests( xfs_trans_t *tp, /* transaction pointer */ xfs_dabuf_t *bp, /* leaf buffer */ @@ -1278,7 +1282,7 @@ xfs_dir2_leaf_log_header( /* * Log the tail of the leaf1 block. */ -void +STATIC void xfs_dir2_leaf_log_tail( xfs_trans_t *tp, /* transaction pointer */ xfs_dabuf_t *bp) /* leaf buffer */ diff --git a/fs/xfs/xfs_dir2_leaf.h b/fs/xfs/xfs_dir2_leaf.h index 7f20eee56a52..3303cd6f4c00 100644 --- a/fs/xfs/xfs_dir2_leaf.h +++ b/fs/xfs/xfs_dir2_leaf.h @@ -329,16 +329,9 @@ extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_dabuf *bp, int first, int last); -extern void - xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp, - int first, int last); - extern void xfs_dir2_leaf_log_header(struct xfs_trans *tp, struct xfs_dabuf *bp); -extern void - xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp); - extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args); diff --git a/fs/xfs/xfs_dir_leaf.c b/fs/xfs/xfs_dir_leaf.c index 617018d6bbdc..c2ea6171fb0e 100644 --- a/fs/xfs/xfs_dir_leaf.c +++ b/fs/xfs/xfs_dir_leaf.c @@ -91,6 +91,10 @@ STATIC int xfs_dir_leaf_figure_balance(xfs_da_state_t *state, int *number_entries_in_blk1, int *number_namebytes_in_blk1); +STATIC int xfs_dir_leaf_create(struct xfs_da_args *args, + xfs_dablk_t which_block, + struct xfs_dabuf **bpp); + /* * Utility routines. */ @@ -781,7 +785,7 @@ xfs_dir_leaf_to_node(xfs_da_args_t *args) * Create the initial contents of a leaf directory * or a leaf in a node directory. */ -int +STATIC int xfs_dir_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp) { xfs_dir_leafblock_t *leaf; diff --git a/fs/xfs/xfs_dir_leaf.h b/fs/xfs/xfs_dir_leaf.h index 00d68d33cc7a..dd423ce1bc8d 100644 --- a/fs/xfs/xfs_dir_leaf.h +++ b/fs/xfs/xfs_dir_leaf.h @@ -202,8 +202,6 @@ int xfs_dir_leaf_to_shortform(struct xfs_da_args *args); /* * Routines used for growing the Btree. */ -int xfs_dir_leaf_create(struct xfs_da_args *args, xfs_dablk_t which_block, - struct xfs_dabuf **bpp); int xfs_dir_leaf_split(struct xfs_da_state *state, struct xfs_da_state_blk *oldblk, struct xfs_da_state_blk *newblk); diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c index bbe1dea11c08..dcd3fdd5c1f7 100644 --- a/fs/xfs/xfs_error.c +++ b/fs/xfs/xfs_error.c @@ -280,7 +280,7 @@ xfs_error_report( } } -void +STATIC void xfs_hex_dump(void *p, int length) { __uint8_t *uip = (__uint8_t*)p; diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h index 6bc0535c0a65..52ee2b90b5ed 100644 --- a/fs/xfs/xfs_error.h +++ b/fs/xfs/xfs_error.h @@ -73,9 +73,6 @@ xfs_corruption_error( int linenum, inst_t *ra); -extern void -xfs_hex_dump(void *p, int length); - #define XFS_ERROR_REPORT(e, lvl, mp) \ xfs_error_report(e, lvl, mp, __FILE__, __LINE__, __return_address) #define XFS_CORRUPTION_ERROR(e, lvl, mp, mem) \ diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index 5eafd5b63211..4b45ff739e6b 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c @@ -288,7 +288,7 @@ xfs_efi_item_committing(xfs_efi_log_item_t *efip, xfs_lsn_t lsn) /* * This is the ops vector shared by all efi log items. */ -struct xfs_item_ops xfs_efi_item_ops = { +STATIC struct xfs_item_ops xfs_efi_item_ops = { .iop_size = (uint(*)(xfs_log_item_t*))xfs_efi_item_size, .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_efi_item_format, @@ -615,7 +615,7 @@ xfs_efd_item_committing(xfs_efd_log_item_t *efip, xfs_lsn_t lsn) /* * This is the ops vector shared by all efd log items. */ -struct xfs_item_ops xfs_efd_item_ops = { +STATIC struct xfs_item_ops xfs_efd_item_ops = { .iop_size = (uint(*)(xfs_log_item_t*))xfs_efd_item_size, .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_efd_item_format, diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index e8274d6b7237..99421638e860 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -158,7 +158,7 @@ xfs_inobp_check( * Use xfs_imap() to determine the size and location of the * buffer to read from disk. */ -int +STATIC int xfs_inotobp( xfs_mount_t *mp, xfs_trans_t *tp, @@ -2111,7 +2111,7 @@ static __inline__ int xfs_inode_clean(xfs_inode_t *ip) (ip->i_update_core == 0)); } -void +STATIC void xfs_ifree_cluster( xfs_inode_t *free_ip, xfs_trans_t *tp, @@ -2830,7 +2830,7 @@ xfs_iunpin( * be subsequently pinned once someone is waiting for it to be * unpinned. */ -void +STATIC void xfs_iunpin_wait( xfs_inode_t *ip) { diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 37e1c316f3b6..2c9a7c4dabdf 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -487,8 +487,6 @@ int xfs_finish_reclaim_all(struct xfs_mount *, int); /* * xfs_inode.c prototypes. */ -int xfs_inotobp(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, - xfs_dinode_t **, struct xfs_buf **, int *); int xfs_itobp(struct xfs_mount *, struct xfs_trans *, xfs_inode_t *, xfs_dinode_t **, struct xfs_buf **, xfs_daddr_t); diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 768cb1816b8e..0eed30f5cb19 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -910,7 +910,7 @@ xfs_inode_item_committing( /* * This is the ops vector shared by all buf log items. */ -struct xfs_item_ops xfs_inode_item_ops = { +STATIC struct xfs_item_ops xfs_inode_item_ops = { .iop_size = (uint(*)(xfs_log_item_t*))xfs_inode_item_size, .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_inode_item_format, diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 092d5fb096b1..1cd2ac163877 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -134,7 +134,7 @@ STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog, #define xlog_verify_tail_lsn(a,b,c) #endif -int xlog_iclogs_empty(xlog_t *log); +STATIC int xlog_iclogs_empty(xlog_t *log); #ifdef DEBUG int xlog_do_error = 0; @@ -1857,7 +1857,7 @@ xlog_write(xfs_mount_t * mp, * * State Change: DIRTY -> ACTIVE */ -void +STATIC void xlog_state_clean_log(xlog_t *log) { xlog_in_core_t *iclog; @@ -3542,7 +3542,7 @@ xfs_log_force_umount( return (retval); } -int +STATIC int xlog_iclogs_empty(xlog_t *log) { xlog_in_core_t *iclog; diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index c31e3ce3be66..1a1d452f15f9 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -535,7 +535,6 @@ typedef struct log { /* common routines */ extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp); -extern int xlog_find_head(xlog_t *log, xfs_daddr_t *head_blk); extern int xlog_find_tail(xlog_t *log, xfs_daddr_t *head_blk, xfs_daddr_t *tail_blk, @@ -548,7 +547,6 @@ extern void xlog_recover_process_iunlinks(xlog_t *log); extern struct xfs_buf *xlog_get_bp(xlog_t *, int); extern void xlog_put_bp(struct xfs_buf *); extern int xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *); -extern xfs_caddr_t xlog_align(xlog_t *, xfs_daddr_t, int, struct xfs_buf *); /* iclog tracing */ #define XLOG_TRACE_GRAB_FLUSH 1 diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 9824b5bf0ec0..593e597c86b2 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -148,7 +148,7 @@ xlog_bread( * The buffer is kept locked across the write and is returned locked. * This can only be used for synchronous log writes. */ -int +STATIC int xlog_bwrite( xlog_t *log, xfs_daddr_t blk_no, @@ -179,7 +179,7 @@ xlog_bwrite( return error; } -xfs_caddr_t +STATIC xfs_caddr_t xlog_align( xlog_t *log, xfs_daddr_t blk_no, @@ -528,7 +528,7 @@ out: * * Return: zero if normal, non-zero if error. */ -int +STATIC int xlog_find_head( xlog_t *log, xfs_daddr_t *return_head_blk) diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 2ec967d93e5a..f618f6d6381c 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -64,6 +64,7 @@ STATIC void xfs_mount_log_sbunit(xfs_mount_t *, __int64_t); STATIC int xfs_uuid_mount(xfs_mount_t *); STATIC void xfs_uuid_unmount(xfs_mount_t *mp); +STATIC void xfs_unmountfs_wait(xfs_mount_t *); static struct { short offset; @@ -555,7 +556,7 @@ xfs_readsb(xfs_mount_t *mp) * fields from the superblock associated with the given * mount structure */ -void +STATIC void xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp) { int i; @@ -1146,7 +1147,7 @@ xfs_unmountfs_close(xfs_mount_t *mp, struct cred *cr) xfs_free_buftarg(mp->m_ddev_targp, 0); } -void +STATIC void xfs_unmountfs_wait(xfs_mount_t *mp) { if (mp->m_logdev_targp != mp->m_ddev_targp) diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 30dd08fb9f57..cd5170ec73a3 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -544,7 +544,6 @@ extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv); extern int xfs_mountfs(struct vfs *, xfs_mount_t *mp, int); extern int xfs_unmountfs(xfs_mount_t *, struct cred *); -extern void xfs_unmountfs_wait(xfs_mount_t *); extern void xfs_unmountfs_close(xfs_mount_t *, struct cred *); extern int xfs_unmountfs_writesb(xfs_mount_t *); extern int xfs_unmount_flush(xfs_mount_t *, int); diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index a865f6035991..06dfca531f79 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -532,7 +532,7 @@ xfs_trans_apply_sb_deltas( * * This is done efficiently with a single call to xfs_mod_incore_sb_batch(). */ -void +STATIC void xfs_trans_unreserve_and_mod_sb( xfs_trans_t *tp) { diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index b53736650100..fb1ae6cfb1f3 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -1681,7 +1681,7 @@ suffix_strtoul(const char *cp, char **endp, unsigned int base) return simple_strtoul(cp, endp, base) << shift_left_factor; } -int +STATIC int xfs_parseargs( struct bhv_desc *bhv, char *options, @@ -1867,7 +1867,7 @@ printk("XFS: irixsgid is now a sysctl(2) variable, option is deprecated.\n"); return 0; } -int +STATIC int xfs_showargs( struct bhv_desc *bhv, struct seq_file *m) diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 25a526629b12..5703783991fa 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -4028,7 +4028,7 @@ xfs_finish_reclaim_all(xfs_mount_t *mp, int noblock) * errno on error * */ -int +STATIC int xfs_alloc_file_space( xfs_inode_t *ip, xfs_off_t offset, -- cgit v1.2.3-59-g8ed1b From efa8027804b2bd8eb7d4b41a1f5b738c36e44e8c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 21 Jun 2005 15:37:17 +1000 Subject: [XFS] rewrite xfs_iflush_all SGI-PV: 936890 SGI-Modid: xfs-linux:xfs-kern:193349a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott --- fs/xfs/xfs_inode.c | 110 +++++++++++------------------------------------------ fs/xfs/xfs_inode.h | 7 +--- fs/xfs/xfs_mount.c | 2 +- 3 files changed, 25 insertions(+), 94 deletions(-) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 99421638e860..a2c723baff06 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -3556,107 +3556,43 @@ corrupt_out: /* - * Flush all inactive inodes in mp. Return true if no user references - * were found, false otherwise. + * Flush all inactive inodes in mp. */ -int +void xfs_iflush_all( - xfs_mount_t *mp, - int flag) + xfs_mount_t *mp) { - int busy; - int done; - int purged; xfs_inode_t *ip; - vmap_t vmap; vnode_t *vp; - busy = done = 0; - while (!done) { - purged = 0; - XFS_MOUNT_ILOCK(mp); - ip = mp->m_inodes; - if (ip == NULL) { - break; - } - do { - /* Make sure we skip markers inserted by sync */ - if (ip->i_mount == NULL) { - ip = ip->i_mnext; - continue; - } - - /* - * It's up to our caller to purge the root - * and quota vnodes later. - */ - vp = XFS_ITOV_NULL(ip); - - if (!vp) { - XFS_MOUNT_IUNLOCK(mp); - xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC); - purged = 1; - break; - } + again: + XFS_MOUNT_ILOCK(mp); + ip = mp->m_inodes; + if (ip == NULL) + goto out; - if (vn_count(vp) != 0) { - if (vn_count(vp) == 1 && - (ip == mp->m_rootip || - (mp->m_quotainfo && - (ip->i_ino == mp->m_sb.sb_uquotino || - ip->i_ino == mp->m_sb.sb_gquotino)))) { + do { + /* Make sure we skip markers inserted by sync */ + if (ip->i_mount == NULL) { + ip = ip->i_mnext; + continue; + } - ip = ip->i_mnext; - continue; - } - if (!(flag & XFS_FLUSH_ALL)) { - busy = 1; - done = 1; - break; - } - /* - * Ignore busy inodes but continue flushing - * others. - */ - ip = ip->i_mnext; - continue; - } - /* - * Sample vp mapping while holding mp locked on MP - * systems, so we don't purge a reclaimed or - * nonexistent vnode. We break from the loop - * since we know that we modify - * it by pulling ourselves from it in xfs_reclaim() - * called via vn_purge() below. Set ip to the next - * entry in the list anyway so we'll know below - * whether we reached the end or not. - */ - VMAP(vp, vmap); + vp = XFS_ITOV_NULL(ip); + if (!vp) { XFS_MOUNT_IUNLOCK(mp); + xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC); + goto again; + } - vn_purge(vp, &vmap); + ASSERT(vn_count(vp) == 0); - purged = 1; - break; - } while (ip != mp->m_inodes); - /* - * We need to distinguish between when we exit the loop - * after a purge and when we simply hit the end of the - * list. We can't use the (ip == mp->m_inodes) test, - * because when we purge an inode at the start of the list - * the next inode on the list becomes mp->m_inodes. That - * would cause such a test to bail out early. The purged - * variable tells us how we got out of the loop. - */ - if (!purged) { - done = 1; - } - } + ip = ip->i_mnext; + } while (ip != mp->m_inodes); + out: XFS_MOUNT_IUNLOCK(mp); - return !busy; } - /* * xfs_iaccess: check accessibility of inode for mode. */ diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 2c9a7c4dabdf..54d9e54c7c95 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -411,11 +411,6 @@ void xfs_ifork_next_set(xfs_inode_t *ip, int w, int n); #define XFS_IFLUSH_ASYNC 4 #define XFS_IFLUSH_DELWRI 5 -/* - * Flags for xfs_iflush_all. - */ -#define XFS_FLUSH_ALL 0x1 - /* * Flags for xfs_itruncate_start(). */ @@ -520,7 +515,7 @@ void xfs_ipin(xfs_inode_t *); void xfs_iunpin(xfs_inode_t *); int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int); int xfs_iflush(xfs_inode_t *, uint); -int xfs_iflush_all(struct xfs_mount *, int); +void xfs_iflush_all(struct xfs_mount *); int xfs_iaccess(xfs_inode_t *, mode_t, cred_t *); uint xfs_iroundup(uint); void xfs_ichgtime(xfs_inode_t *, int); diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index f618f6d6381c..5b363fcf8665 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -1082,7 +1082,7 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) int64_t fsid; #endif - xfs_iflush_all(mp, XFS_FLUSH_ALL); + xfs_iflush_all(mp); XFS_QM_DQPURGEALL(mp, XFS_QMOPT_UQUOTA | XFS_QMOPT_GQUOTA | XFS_QMOPT_UMOUNTING); -- cgit v1.2.3-59-g8ed1b From 66f58d236fd9c2676545678374d58d48206bdbfa Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 21 Jun 2005 15:37:43 +1000 Subject: [XFS] simplify XFS_PURGE_INODE SGI-PV: 936891 SGI-Modid: xfs-linux:xfs-kern:193408a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott --- fs/xfs/quota/xfs_quota_priv.h | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h index 414b6004af21..675f03f443d2 100644 --- a/fs/xfs/quota/xfs_quota_priv.h +++ b/fs/xfs/quota/xfs_quota_priv.h @@ -177,13 +177,7 @@ for ((dqp) = (qlist)->qh_next; (dqp) != (xfs_dquot_t *)(qlist); \ (!((dqp)->q_core.d_id)) #define XFS_PURGE_INODE(ip) \ - { \ - vmap_t dqvmap; \ - vnode_t *dqvp; \ - dqvp = XFS_ITOV(ip); \ - VMAP(dqvp, dqvmap); \ - VN_RELE(dqvp); \ - } + IRELE(ip); #define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \ (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : "???")) -- cgit v1.2.3-59-g8ed1b From 8401e9631c26dca9ebbc6997ac445fd49b06c79e Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 21 Jun 2005 15:38:03 +1000 Subject: [XFS] remove xfs_incore_relse SGI-PV: 936977 SGI-Modid: xfs-linux:xfs-kern:193409a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott --- fs/xfs/linux-2.6/xfs_buf.c | 10 ---------- fs/xfs/linux-2.6/xfs_buf.h | 1 - fs/xfs/xfs_mount.c | 9 --------- 3 files changed, 20 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 049f87116174..c60e69431e11 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -1563,16 +1563,6 @@ xfs_free_buftarg( kmem_free(btp, sizeof(*btp)); } -void -xfs_incore_relse( - xfs_buftarg_t *btp, - int delwri_only, - int wait) -{ - invalidate_bdev(btp->pbr_bdev, 1); - truncate_inode_pages(btp->pbr_mapping, 0LL); -} - STATIC int xfs_setsize_buftarg_flags( xfs_buftarg_t *btp, diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index 74deed8e6d90..3f8f69a66aea 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h @@ -576,7 +576,6 @@ extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *, int); extern void xfs_free_buftarg(xfs_buftarg_t *, int); extern void xfs_wait_buftarg(xfs_buftarg_t *); extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); -extern void xfs_incore_relse(xfs_buftarg_t *, int, int); extern int xfs_flush_buftarg(xfs_buftarg_t *, int); #define xfs_getsize_buftarg(buftarg) \ diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 5b363fcf8665..82e1646e6243 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -1112,15 +1112,6 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) */ ASSERT(mp->m_inodes == NULL); - /* - * We may have bufs that are in the process of getting written still. - * We must wait for the I/O completion of those. The sync flag here - * does a two pass iteration thru the bufcache. - */ - if (XFS_FORCED_SHUTDOWN(mp)) { - xfs_incore_relse(mp->m_ddev_targp, 0, 1); /* synchronous */ - } - xfs_unmountfs_close(mp, cr); if ((mp->m_flags & XFS_MOUNT_NOUUID) == 0) xfs_uuid_unmount(mp); -- cgit v1.2.3-59-g8ed1b From c8ad20ffeb592d66ea869c57f8c525a9d727c67b Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Tue, 21 Jun 2005 15:38:48 +1000 Subject: [XFS] Add support for project quota, based on Dan Knappes earlier work. SGI-PV: 932952 SGI-Modid: xfs-linux:xfs-kern:22805a Signed-off-by: Nathan Scott --- fs/xfs/linux-2.6/xfs_linux.h | 6 +- fs/xfs/linux-2.6/xfs_super.c | 6 +- fs/xfs/quota/xfs_dquot.c | 34 ++++++---- fs/xfs/quota/xfs_dquot.h | 29 ++++---- fs/xfs/quota/xfs_qm.c | 142 +++++++++++++++++++++++++------------- fs/xfs/quota/xfs_qm.h | 4 +- fs/xfs/quota/xfs_qm_bhv.c | 41 +++++++++-- fs/xfs/quota/xfs_qm_syscalls.c | 151 +++++++++++++++++++++++++---------------- fs/xfs/quota/xfs_quota_priv.h | 6 +- fs/xfs/quota/xfs_trans_dquot.c | 6 +- fs/xfs/xfs_buf_item.h | 2 +- fs/xfs/xfs_log_recover.c | 11 ++- fs/xfs/xfs_mount.h | 6 +- fs/xfs/xfs_quota.h | 61 +++++++++++------ fs/xfs/xfs_trans_buf.c | 1 + fs/xfs/xfs_utils.c | 2 +- fs/xfs/xfs_vfsops.c | 10 --- fs/xfs/xfs_vnodeops.c | 33 ++++++--- 18 files changed, 348 insertions(+), 203 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h index 71bb41019a12..44eb313f22b9 100644 --- a/fs/xfs/linux-2.6/xfs_linux.h +++ b/fs/xfs/linux-2.6/xfs_linux.h @@ -230,8 +230,10 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh) * field (see the QCMD macro in quota.h). These macros help keep the * code portable - they are not visible from the syscall interface. */ -#define Q_XSETGQLIM XQM_CMD(0x8) /* set groups disk limits */ -#define Q_XGETGQUOTA XQM_CMD(0x9) /* get groups disk limits */ +#define Q_XSETGQLIM XQM_CMD(8) /* set groups disk limits */ +#define Q_XGETGQUOTA XQM_CMD(9) /* get groups disk limits */ +#define Q_XSETPQLIM XQM_CMD(10) /* set projects disk limits */ +#define Q_XGETPQUOTA XQM_CMD(11) /* get projects disk limits */ /* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */ /* we may well need to fine-tune this if it ever becomes an issue. */ diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 455e2b2fb964..d5f0340ddcd9 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -701,7 +701,8 @@ linvfs_getxquota( struct vfs *vfsp = LINVFS_GET_VFS(sb); int error, getmode; - getmode = (type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETQUOTA; + getmode = (type == USRQUOTA) ? Q_XGETQUOTA : + ((type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETPQUOTA); VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error); return -error; } @@ -716,7 +717,8 @@ linvfs_setxquota( struct vfs *vfsp = LINVFS_GET_VFS(sb); int error, setmode; - setmode = (type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETQLIM; + setmode = (type == USRQUOTA) ? Q_XSETQLIM : + ((type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETPQLIM); VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error); return -error; } diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 9ce471430a0e..68089f56d5cd 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c @@ -399,9 +399,9 @@ xfs_qm_init_dquot_blk( for (i = 0; i < XFS_QM_DQPERBLK(mp); i++, d++, curid++) xfs_qm_dqinit_core(curid, type, d); xfs_trans_dquot_buf(tp, bp, - type & XFS_DQ_USER ? - XFS_BLI_UDQUOT_BUF : - XFS_BLI_GDQUOT_BUF); + (type & XFS_DQ_USER ? XFS_BLI_UDQUOT_BUF : + ((type & XFS_DQ_PROJ) ? XFS_BLI_PDQUOT_BUF : + XFS_BLI_GDQUOT_BUF))); xfs_trans_log_buf(tp, bp, 0, BBTOB(XFS_QI_DQCHUNKLEN(mp)) - 1); } @@ -482,8 +482,7 @@ xfs_qm_dqalloc( * the entire thing. */ xfs_qm_init_dquot_blk(tp, mp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT), - dqp->dq_flags & (XFS_DQ_USER|XFS_DQ_GROUP), - bp); + dqp->dq_flags & XFS_DQ_ALLTYPES, bp); if ((error = xfs_bmap_finish(&tp, &flist, firstblock, &committed))) { goto error1; @@ -613,8 +612,7 @@ xfs_qm_dqtobp( /* * A simple sanity check in case we got a corrupted dquot... */ - if (xfs_qm_dqcheck(ddq, id, - dqp->dq_flags & (XFS_DQ_USER|XFS_DQ_GROUP), + if (xfs_qm_dqcheck(ddq, id, dqp->dq_flags & XFS_DQ_ALLTYPES, flags & (XFS_QMOPT_DQREPAIR|XFS_QMOPT_DOWARN), "dqtobp")) { if (!(flags & XFS_QMOPT_DQREPAIR)) { @@ -891,8 +889,8 @@ int xfs_qm_dqget( xfs_mount_t *mp, xfs_inode_t *ip, /* locked inode (optional) */ - xfs_dqid_t id, /* gid or uid, depending on type */ - uint type, /* UDQUOT or GDQUOT */ + xfs_dqid_t id, /* uid/projid/gid depending on type */ + uint type, /* XFS_DQ_USER/XFS_DQ_PROJ/XFS_DQ_GROUP */ uint flags, /* DQALLOC, DQSUSER, DQREPAIR, DOWARN */ xfs_dquot_t **O_dqpp) /* OUT : locked incore dquot */ { @@ -903,7 +901,9 @@ xfs_qm_dqget( ASSERT(XFS_IS_QUOTA_RUNNING(mp)); if ((! XFS_IS_UQUOTA_ON(mp) && type == XFS_DQ_USER) || + (! XFS_IS_PQUOTA_ON(mp) && type == XFS_DQ_PROJ) || (! XFS_IS_GQUOTA_ON(mp) && type == XFS_DQ_GROUP)) { +printk("XQM: ESRCH1\n"); return (ESRCH); } h = XFS_DQ_HASH(mp, id, type); @@ -921,7 +921,9 @@ xfs_qm_dqget( again: #ifdef DEBUG - ASSERT(type == XFS_DQ_USER || type == XFS_DQ_GROUP); + ASSERT(type == XFS_DQ_USER || + type == XFS_DQ_PROJ || + type == XFS_DQ_GROUP); if (ip) { ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); if (type == XFS_DQ_USER) @@ -979,6 +981,7 @@ xfs_qm_dqget( &dqp))) { if (ip) xfs_ilock(ip, XFS_ILOCK_EXCL); +if (error == ESRCH) printk("XQM: ESRCH2\n"); return (error); } @@ -1004,6 +1007,7 @@ xfs_qm_dqget( if (! XFS_IS_DQTYPE_ON(mp, type)) { /* inode stays locked on return */ xfs_qm_dqdestroy(dqp); +printk("XQM: ESRCH3\n"); return XFS_ERROR(ESRCH); } /* @@ -1244,8 +1248,8 @@ xfs_qm_dqflush( return (error); } - if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT), 0, XFS_QMOPT_DOWARN, - "dqflush (incore copy)")) { + if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT), + 0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) { xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE); return XFS_ERROR(EIO); } @@ -1397,7 +1401,8 @@ xfs_dqlock2( { if (d1 && d2) { ASSERT(d1 != d2); - if (INT_GET(d1->q_core.d_id, ARCH_CONVERT) > INT_GET(d2->q_core.d_id, ARCH_CONVERT)) { + if (INT_GET(d1->q_core.d_id, ARCH_CONVERT) > + INT_GET(d2->q_core.d_id, ARCH_CONVERT)) { xfs_dqlock(d2); xfs_dqlock(d1); } else { @@ -1520,8 +1525,7 @@ xfs_qm_dqprint(xfs_dquot_t *dqp) cmn_err(CE_DEBUG, "-----------KERNEL DQUOT----------------"); cmn_err(CE_DEBUG, "---- dquotID = %d", (int)INT_GET(dqp->q_core.d_id, ARCH_CONVERT)); - cmn_err(CE_DEBUG, "---- type = %s", - XFS_QM_ISUDQ(dqp) ? "USR" : "GRP"); + cmn_err(CE_DEBUG, "---- type = %s", DQFLAGTO_TYPESTR(dqp)); cmn_err(CE_DEBUG, "---- fs = 0x%p", dqp->q_mount); cmn_err(CE_DEBUG, "---- blkno = 0x%x", (int) dqp->q_blkno); cmn_err(CE_DEBUG, "---- boffset = 0x%x", (int) dqp->q_bufoffset); diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h index 35aeeafe4799..39175103c8e0 100644 --- a/fs/xfs/quota/xfs_dquot.h +++ b/fs/xfs/quota/xfs_dquot.h @@ -114,25 +114,18 @@ typedef struct xfs_dquot { #define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++) /* - * Quota Accounting flags + * Quota Accounting/Enforcement flags */ -#define XFS_ALL_QUOTA_ACCT (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT) -#define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_GQUOTA_ENFD) -#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_GQUOTA_CHKD) -#define XFS_ALL_QUOTA_ACTV (XFS_UQUOTA_ACTIVE | XFS_GQUOTA_ACTIVE) -#define XFS_ALL_QUOTA_ACCT_ENFD (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\ - XFS_GQUOTA_ACCT|XFS_GQUOTA_ENFD) +#define XFS_ALL_QUOTA_ACCT \ + (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT) +#define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD) +#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD) -#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT) -#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT) -#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT) - -/* - * Quota Limit Enforcement flags - */ +#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT) #define XFS_IS_QUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD) -#define XFS_IS_UQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_UQUOTA_ENFD) -#define XFS_IS_GQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_GQUOTA_ENFD) +#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT) +#define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT) +#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT) #ifdef DEBUG static inline int @@ -167,6 +160,8 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp) #define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp)) #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) #define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) +#define XFS_QM_ISPDQ(dqp) ((dqp)->dq_flags & XFS_DQ_PROJ) +#define XFS_QM_ISGDQ(dqp) ((dqp)->dq_flags & XFS_DQ_GROUP) #define XFS_DQ_TO_QINF(dqp) ((dqp)->q_mount->m_quotainfo) #define XFS_DQ_TO_QIP(dqp) (XFS_QM_ISUDQ(dqp) ? \ XFS_DQ_TO_QINF(dqp)->qi_uquotaip : \ @@ -174,7 +169,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp) #define XFS_IS_THIS_QUOTA_OFF(d) (! (XFS_QM_ISUDQ(d) ? \ (XFS_IS_UQUOTA_ON((d)->q_mount)) : \ - (XFS_IS_GQUOTA_ON((d)->q_mount)))) + (XFS_IS_OQUOTA_ON((d)->q_mount)))) #ifdef XFS_DQUOT_TRACE /* diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 41bbc49d535e..3ea75972767c 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -310,9 +310,9 @@ xfs_qm_mount_quotainit( uint flags) { /* - * User or group quotas has to be on. + * User, projects or group quotas has to be on. */ - ASSERT(flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA)); + ASSERT(flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA)); /* * Initialize the flags in the mount structure. From this point @@ -330,7 +330,11 @@ xfs_qm_mount_quotainit( if (flags & XFSMNT_GQUOTA) { mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); if (flags & XFSMNT_GQUOTAENF) - mp->m_qflags |= XFS_GQUOTA_ENFD; + mp->m_qflags |= XFS_OQUOTA_ENFD; + } else if (flags & XFSMNT_PQUOTA) { + mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); + if (flags & XFSMNT_PQUOTAENF) + mp->m_qflags |= XFS_OQUOTA_ENFD; } } @@ -363,11 +367,11 @@ xfs_qm_mount_quotas( /* * If a file system had quotas running earlier, but decided to - * mount without -o quota/uquota/gquota options, revoke the + * mount without -o uquota/pquota/gquota options, revoke the * quotachecked license, and bail out. */ if (! XFS_IS_QUOTA_ON(mp) && - (mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT))) { + (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT)) { mp->m_qflags = 0; goto write_changes; } @@ -619,7 +623,7 @@ xfs_qm_detach_gdquots( STATIC int xfs_qm_dqpurge_int( xfs_mount_t *mp, - uint flags) /* QUOTAOFF/UMOUNTING/UQUOTA/GQUOTA */ + uint flags) /* QUOTAOFF/UMOUNTING/UQUOTA/PQUOTA/GQUOTA */ { xfs_dquot_t *dqp; uint dqtype; @@ -631,6 +635,7 @@ xfs_qm_dqpurge_int( return (0); dqtype = (flags & XFS_QMOPT_UQUOTA) ? XFS_DQ_USER : 0; + dqtype |= (flags & XFS_QMOPT_PQUOTA) ? XFS_DQ_PROJ : 0; dqtype |= (flags & XFS_QMOPT_GQUOTA) ? XFS_DQ_GROUP : 0; xfs_qm_mplist_lock(mp); @@ -740,11 +745,11 @@ xfs_qm_dqattach_one( /* * udqhint is the i_udquot field in inode, and is non-NULL only - * when the type arg is XFS_DQ_GROUP. Its purpose is to save a + * when the type arg is group/project. Its purpose is to save a * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside * the user dquot. */ - ASSERT(!udqhint || type == XFS_DQ_GROUP); + ASSERT(!udqhint || type == XFS_DQ_GROUP || type == XFS_DQ_PROJ); if (udqhint && !dolock) xfs_dqlock(udqhint); @@ -903,8 +908,8 @@ xfs_qm_dqattach_grouphint( /* - * Given a locked inode, attach dquot(s) to it, taking UQUOTAON / GQUOTAON - * in to account. + * Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON + * into account. * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed. * If XFS_QMOPT_DQLOCK, the dquot(s) will be returned locked. This option pretty * much made this code a complete mess, but it has been pretty useful. @@ -943,8 +948,13 @@ xfs_qm_dqattach( nquotas++; } ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); - if (XFS_IS_GQUOTA_ON(mp)) { - error = xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP, + if (XFS_IS_OQUOTA_ON(mp)) { + error = XFS_IS_GQUOTA_ON(mp) ? + xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP, + flags & XFS_QMOPT_DQALLOC, + flags & XFS_QMOPT_DQLOCK, + ip->i_udquot, &ip->i_gdquot) : + xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ, flags & XFS_QMOPT_DQALLOC, flags & XFS_QMOPT_DQLOCK, ip->i_udquot, &ip->i_gdquot); @@ -995,7 +1005,7 @@ xfs_qm_dqattach( } if (XFS_IS_UQUOTA_ON(mp)) ASSERT(ip->i_udquot); - if (XFS_IS_GQUOTA_ON(mp)) + if (XFS_IS_OQUOTA_ON(mp)) ASSERT(ip->i_gdquot); } #endif @@ -1024,13 +1034,13 @@ xfs_qm_dqdetach( ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_uquotino); ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_gquotino); - if (ip->i_udquot) - xfs_dqtrace_entry_ino(ip->i_udquot, "DQDETTACH", ip); if (ip->i_udquot) { + xfs_dqtrace_entry_ino(ip->i_udquot, "DQDETTACH", ip); xfs_qm_dqrele(ip->i_udquot); ip->i_udquot = NULL; } if (ip->i_gdquot) { + xfs_dqtrace_entry_ino(ip->i_gdquot, "DQDETTACH", ip); xfs_qm_dqrele(ip->i_gdquot); ip->i_gdquot = NULL; } @@ -1208,8 +1218,9 @@ xfs_qm_init_quotainfo( * and group quotas, at least not at this point. */ error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)0, - (XFS_IS_UQUOTA_RUNNING(mp)) ? - XFS_DQ_USER : XFS_DQ_GROUP, + XFS_IS_UQUOTA_RUNNING(mp) ? XFS_DQ_USER : + (XFS_IS_GQUOTA_RUNNING(mp) ? XFS_DQ_GROUP : + XFS_DQ_PROJ), XFS_QMOPT_DQSUSER|XFS_QMOPT_DOWARN, &dqp); if (! error) { @@ -1372,13 +1383,20 @@ xfs_qm_dqget_noattach( ASSERT(udqp); } - if (XFS_IS_GQUOTA_ON(mp)) { + if (XFS_IS_OQUOTA_ON(mp)) { ASSERT(ip->i_gdquot == NULL); if (udqp) xfs_dqunlock(udqp); - if ((error = xfs_qm_dqget(mp, ip, ip->i_d.di_gid, XFS_DQ_GROUP, - XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN, - &gdqp))) { + error = XFS_IS_GQUOTA_ON(mp) ? + xfs_qm_dqget(mp, ip, + ip->i_d.di_gid, XFS_DQ_GROUP, + XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN, + &gdqp) : + xfs_qm_dqget(mp, ip, + ip->i_d.di_projid, XFS_DQ_PROJ, + XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN, + &gdqp); + if (error) { if (udqp) xfs_qm_dqrele(udqp); ASSERT(error != ESRCH); @@ -1547,11 +1565,14 @@ xfs_qm_dqiter_bufs( int error; int notcommitted; int incr; + int type; ASSERT(blkcnt > 0); notcommitted = 0; incr = (blkcnt > XFS_QM_MAX_DQCLUSTER_LOGSZ) ? XFS_QM_MAX_DQCLUSTER_LOGSZ : blkcnt; + type = flags & XFS_QMOPT_UQUOTA ? XFS_DQ_USER : + (flags & XFS_QMOPT_PQUOTA ? XFS_DQ_PROJ : XFS_DQ_GROUP); error = 0; /* @@ -1570,9 +1591,7 @@ xfs_qm_dqiter_bufs( if (error) break; - (void) xfs_qm_reset_dqcounts(mp, bp, firstid, - flags & XFS_QMOPT_UQUOTA ? - XFS_DQ_USER : XFS_DQ_GROUP); + (void) xfs_qm_reset_dqcounts(mp, bp, firstid, type); xfs_bdwrite(mp, bp); /* * goto the next block. @@ -1584,7 +1603,7 @@ xfs_qm_dqiter_bufs( } /* - * Iterate over all allocated USR/GRP dquots in the system, calling a + * Iterate over all allocated USR/GRP/PRJ dquots in the system, calling a * caller supplied function for every chunk of dquots that we find. */ STATIC int @@ -1855,7 +1874,7 @@ xfs_qm_dqusage_adjust( xfs_qm_quotacheck_dqadjust(udqp, nblks, rtblks); xfs_qm_dqput(udqp); } - if (XFS_IS_GQUOTA_ON(mp)) { + if (XFS_IS_OQUOTA_ON(mp)) { ASSERT(gdqp); xfs_qm_quotacheck_dqadjust(gdqp, nblks, rtblks); xfs_qm_dqput(gdqp); @@ -1904,7 +1923,7 @@ xfs_qm_quotacheck( cmn_err(CE_NOTE, "XFS quotacheck %s: Please wait.", mp->m_fsname); /* - * First we go thru all the dquots on disk, USR and GRP, and reset + * First we go thru all the dquots on disk, USR and GRP/PRJ, and reset * their counters to zero. We need a clean slate. * We don't log our changes till later. */ @@ -1915,9 +1934,10 @@ xfs_qm_quotacheck( } if ((gip = XFS_QI_GQIP(mp))) { - if ((error = xfs_qm_dqiterate(mp, gip, XFS_QMOPT_GQUOTA))) + if ((error = xfs_qm_dqiterate(mp, gip, XFS_IS_GQUOTA_ON(mp) ? + XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA))) goto error_return; - flags |= XFS_GQUOTA_CHKD; + flags |= XFS_OQUOTA_CHKD; } do { @@ -1944,7 +1964,7 @@ xfs_qm_quotacheck( if (error) { xfs_qm_dqpurge_all(mp, XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA| - XFS_QMOPT_QUOTAOFF); + XFS_QMOPT_PQUOTA|XFS_QMOPT_QUOTAOFF); goto error_return; } /* @@ -1967,7 +1987,7 @@ xfs_qm_quotacheck( * quotachecked status, since we won't be doing accounting for * that type anymore. */ - mp->m_qflags &= ~(XFS_GQUOTA_CHKD | XFS_UQUOTA_CHKD); + mp->m_qflags &= ~(XFS_OQUOTA_CHKD | XFS_UQUOTA_CHKD); mp->m_qflags |= flags; XQM_LIST_PRINT(&(XFS_QI_MPL_LIST(mp)), MPL_NEXT, "++++ Mp list +++"); @@ -2019,7 +2039,7 @@ xfs_qm_init_quotainos( 0, 0, &uip, 0))) return XFS_ERROR(error); } - if (XFS_IS_GQUOTA_ON(mp) && + if (XFS_IS_OQUOTA_ON(mp) && mp->m_sb.sb_gquotino != NULLFSINO) { ASSERT(mp->m_sb.sb_gquotino > 0); if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, @@ -2049,10 +2069,12 @@ xfs_qm_init_quotainos( flags &= ~XFS_QMOPT_SBVERSION; } - if (XFS_IS_GQUOTA_ON(mp) && gip == NULL) { - if ((error = xfs_qm_qino_alloc(mp, &gip, - sbflags | XFS_SB_GQUOTINO, - flags | XFS_QMOPT_GQUOTA))) { + if (XFS_IS_OQUOTA_ON(mp) && gip == NULL) { + flags |= (XFS_IS_GQUOTA_ON(mp) ? + XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA); + error = xfs_qm_qino_alloc(mp, &gip, + sbflags | XFS_SB_GQUOTINO, flags); + if (error) { if (uip) VN_RELE(XFS_ITOV(uip)); @@ -2458,6 +2480,7 @@ xfs_qm_vop_dqalloc( xfs_inode_t *ip, uid_t uid, gid_t gid, + prid_t prid, uint flags, xfs_dquot_t **O_udqpp, xfs_dquot_t **O_gdqpp) @@ -2489,8 +2512,7 @@ xfs_qm_vop_dqalloc( } uq = gq = NULL; - if ((flags & XFS_QMOPT_UQUOTA) && - XFS_IS_UQUOTA_ON(mp)) { + if ((flags & XFS_QMOPT_UQUOTA) && XFS_IS_UQUOTA_ON(mp)) { if (ip->i_d.di_uid != uid) { /* * What we need is the dquot that has this uid, and @@ -2528,8 +2550,7 @@ xfs_qm_vop_dqalloc( xfs_dqunlock(uq); } } - if ((flags & XFS_QMOPT_GQUOTA) && - XFS_IS_GQUOTA_ON(mp)) { + if ((flags & XFS_QMOPT_GQUOTA) && XFS_IS_GQUOTA_ON(mp)) { if (ip->i_d.di_gid != gid) { xfs_iunlock(ip, lockflags); if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid, @@ -2552,6 +2573,29 @@ xfs_qm_vop_dqalloc( XFS_DQHOLD(gq); xfs_dqunlock(gq); } + } else if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) { + if (ip->i_d.di_projid != prid) { + xfs_iunlock(ip, lockflags); + if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid, + XFS_DQ_PROJ, + XFS_QMOPT_DQALLOC | + XFS_QMOPT_DOWARN, + &gq))) { + if (uq) + xfs_qm_dqrele(uq); + ASSERT(error != ENOENT); + return (error); + } + xfs_dqunlock(gq); + lockflags = XFS_ILOCK_SHARED; + xfs_ilock(ip, lockflags); + } else { + ASSERT(ip->i_gdquot); + gq = ip->i_gdquot; + xfs_dqlock(gq); + XFS_DQHOLD(gq); + xfs_dqunlock(gq); + } } if (uq) xfs_dqtrace_entry_ino(uq, "DQALLOC", ip); @@ -2617,7 +2661,7 @@ xfs_qm_vop_chown( } /* - * Quota reservations for setattr(AT_UID|AT_GID). + * Quota reservations for setattr(AT_UID|AT_GID|AT_PROJID). */ int xfs_qm_vop_chown_reserve( @@ -2652,12 +2696,16 @@ xfs_qm_vop_chown_reserve( unresudq = ip->i_udquot; } } - if (XFS_IS_GQUOTA_ON(ip->i_mount) && gdqp && - ip->i_d.di_gid != INT_GET(gdqp->q_core.d_id, ARCH_CONVERT)) { - delblksgdq = gdqp; - if (delblks) { - ASSERT(ip->i_gdquot); - unresgdq = ip->i_gdquot; + if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) { + if ((XFS_IS_GQUOTA_ON(ip->i_mount) && ip->i_d.di_gid != + INT_GET(gdqp->q_core.d_id, ARCH_CONVERT)) || + (XFS_IS_PQUOTA_ON(ip->i_mount) && ip->i_d.di_projid != + INT_GET(gdqp->q_core.d_id, ARCH_CONVERT))) { + delblksgdq = gdqp; + if (delblks) { + ASSERT(ip->i_gdquot); + unresgdq = ip->i_gdquot; + } } } diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h index ae626eca5aca..781968779540 100644 --- a/fs/xfs/quota/xfs_qm.h +++ b/fs/xfs/quota/xfs_qm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -202,7 +202,7 @@ extern void xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint); /* vop stuff */ extern int xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *, - uid_t, gid_t, uint, + uid_t, gid_t, prid_t, uint, xfs_dquot_t **, xfs_dquot_t **); extern void xfs_qm_vop_dqattach_and_dqmod_newinode( xfs_trans_t *, xfs_inode_t *, diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c index 09b1171dfb83..dc3c37a1e158 100644 --- a/fs/xfs/quota/xfs_qm_bhv.c +++ b/fs/xfs/quota/xfs_qm_bhv.c @@ -71,10 +71,13 @@ #define MNTOPT_NOQUOTA "noquota" /* no quotas */ #define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */ #define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */ +#define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */ #define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */ #define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */ +#define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */ #define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */ #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ +#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */ #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ STATIC int @@ -109,6 +112,14 @@ xfs_qm_parseargs( args->flags |= XFSMNT_UQUOTA; args->flags &= ~XFSMNT_UQUOTAENF; referenced = 1; + } else if (!strcmp(this_char, MNTOPT_PQUOTA) || + !strcmp(this_char, MNTOPT_PRJQUOTA)) { + args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF; + referenced = 1; + } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) { + args->flags |= XFSMNT_PQUOTA; + args->flags &= ~XFSMNT_PQUOTAENF; + referenced = 1; } else if (!strcmp(this_char, MNTOPT_GQUOTA) || !strcmp(this_char, MNTOPT_GRPQUOTA)) { args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF; @@ -127,6 +138,12 @@ xfs_qm_parseargs( *this_char++ = ','; } + if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) { + cmn_err(CE_WARN, + "XFS: cannot mount with both project and group quota"); + return XFS_ERROR(EINVAL); + } + PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error); if (!error && !referenced) bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM); @@ -148,13 +165,19 @@ xfs_qm_showargs( seq_puts(m, "," MNTOPT_UQUOTANOENF); } + if (mp->m_qflags & XFS_PQUOTA_ACCT) { + (mp->m_qflags & XFS_OQUOTA_ENFD) ? + seq_puts(m, "," MNTOPT_PRJQUOTA) : + seq_puts(m, "," MNTOPT_PQUOTANOENF); + } + if (mp->m_qflags & XFS_GQUOTA_ACCT) { - (mp->m_qflags & XFS_GQUOTA_ENFD) ? + (mp->m_qflags & XFS_OQUOTA_ENFD) ? seq_puts(m, "," MNTOPT_GRPQUOTA) : seq_puts(m, "," MNTOPT_GQUOTANOENF); } - if (!(mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT))) + if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) seq_puts(m, "," MNTOPT_NOQUOTA); PVFS_SHOWARGS(BHV_NEXT(bhv), m, error); @@ -171,7 +194,7 @@ xfs_qm_mount( struct xfs_mount *mp = XFS_VFSTOM(vfsp); int error; - if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA)) + if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA)) xfs_qm_mount_quotainit(mp, args->flags); PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error); return error; @@ -255,16 +278,17 @@ xfs_qm_newmount( uint *quotaflags) { uint quotaondisk; - uint uquotaondisk = 0, gquotaondisk = 0; + uint uquotaondisk = 0, gquotaondisk = 0, pquotaondisk = 0; *quotaflags = 0; *needquotamount = B_FALSE; quotaondisk = XFS_SB_VERSION_HASQUOTA(&mp->m_sb) && - mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT); + (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT); if (quotaondisk) { uquotaondisk = mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT; + pquotaondisk = mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT; gquotaondisk = mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT; } @@ -277,13 +301,16 @@ xfs_qm_newmount( if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) || (!uquotaondisk && XFS_IS_UQUOTA_ON(mp)) || + (pquotaondisk && !XFS_IS_PQUOTA_ON(mp)) || + (!pquotaondisk && XFS_IS_PQUOTA_ON(mp)) || (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) || - (!gquotaondisk && XFS_IS_GQUOTA_ON(mp))) && + (!gquotaondisk && XFS_IS_OQUOTA_ON(mp))) && xfs_dev_is_read_only(mp, "changing quota state")) { cmn_err(CE_WARN, - "XFS: please mount with%s%s%s.", + "XFS: please mount with%s%s%s%s.", (!quotaondisk ? "out quota" : ""), (uquotaondisk ? " usrquota" : ""), + (pquotaondisk ? " prjquota" : ""), (gquotaondisk ? " grpquota" : "")); return XFS_ERROR(EPERM); } diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 229f5b5a2d25..365a054f02d6 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c @@ -118,40 +118,41 @@ xfs_qm_quotactl( * The following commands are valid even when quotaoff. */ switch (cmd) { + case Q_XQUOTARM: /* - * truncate quota files. quota must be off. + * Truncate quota files. quota must be off. */ - case Q_XQUOTARM: if (XFS_IS_QUOTA_ON(mp) || addr == NULL) return XFS_ERROR(EINVAL); if (vfsp->vfs_flag & VFS_RDONLY) return XFS_ERROR(EROFS); return (xfs_qm_scall_trunc_qfiles(mp, xfs_qm_import_qtype_flags(*(uint *)addr))); + + case Q_XGETQSTAT: /* * Get quota status information. */ - case Q_XGETQSTAT: return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr)); + case Q_XQUOTAON: /* - * QUOTAON for root f/s and quota enforcement on others.. - * Quota accounting for non-root f/s's must be turned on - * at mount time. + * QUOTAON - enabling quota enforcement. + * Quota accounting must be turned on at mount time. */ - case Q_XQUOTAON: if (addr == NULL) return XFS_ERROR(EINVAL); if (vfsp->vfs_flag & VFS_RDONLY) return XFS_ERROR(EROFS); return (xfs_qm_scall_quotaon(mp, xfs_qm_import_flags(*(uint *)addr))); - case Q_XQUOTAOFF: + + case Q_XQUOTAOFF: if (vfsp->vfs_flag & VFS_RDONLY) return XFS_ERROR(EROFS); break; - default: + default: break; } @@ -159,7 +160,7 @@ xfs_qm_quotactl( return XFS_ERROR(ESRCH); switch (cmd) { - case Q_XQUOTAOFF: + case Q_XQUOTAOFF: if (vfsp->vfs_flag & VFS_RDONLY) return XFS_ERROR(EROFS); error = xfs_qm_scall_quotaoff(mp, @@ -167,42 +168,39 @@ xfs_qm_quotactl( B_FALSE); break; - /* - * Defaults to XFS_GETUQUOTA. - */ - case Q_XGETQUOTA: + case Q_XGETQUOTA: error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER, (fs_disk_quota_t *)addr); break; - /* - * Set limits, both hard and soft. Defaults to Q_SETUQLIM. - */ - case Q_XSETQLIM: + case Q_XGETGQUOTA: + error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, + (fs_disk_quota_t *)addr); + break; + case Q_XGETPQUOTA: + error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_PROJ, + (fs_disk_quota_t *)addr); + break; + + case Q_XSETQLIM: if (vfsp->vfs_flag & VFS_RDONLY) return XFS_ERROR(EROFS); error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER, (fs_disk_quota_t *)addr); break; - - case Q_XSETGQLIM: + case Q_XSETGQLIM: if (vfsp->vfs_flag & VFS_RDONLY) return XFS_ERROR(EROFS); error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, (fs_disk_quota_t *)addr); break; - - - case Q_XGETGQUOTA: - error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, - (fs_disk_quota_t *)addr); + case Q_XSETPQLIM: + if (vfsp->vfs_flag & VFS_RDONLY) + return XFS_ERROR(EROFS); + error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_PROJ, + (fs_disk_quota_t *)addr); break; - /* - * Quotas are entirely undefined after quotaoff in XFS quotas. - * For instance, there's no way to set limits when quotaoff. - */ - - default: + default: error = XFS_ERROR(EINVAL); break; } @@ -286,8 +284,12 @@ xfs_qm_scall_quotaoff( } if (flags & XFS_GQUOTA_ACCT) { dqtype |= XFS_QMOPT_GQUOTA; - flags |= (XFS_GQUOTA_CHKD | XFS_GQUOTA_ENFD); + flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD); inactivate_flags |= XFS_GQUOTA_ACTIVE; + } else if (flags & XFS_PQUOTA_ACCT) { + dqtype |= XFS_QMOPT_PQUOTA; + flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD); + inactivate_flags |= XFS_PQUOTA_ACTIVE; } /* @@ -364,7 +366,8 @@ xfs_qm_scall_quotaoff( /* * If quotas is completely disabled, close shop. */ - if ((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_ALL) { + if (((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_SET1) || + ((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_SET2)) { mutex_unlock(&(XFS_QI_QOFFLOCK(mp))); xfs_qm_destroy_quotainfo(mp); return (0); @@ -378,7 +381,7 @@ xfs_qm_scall_quotaoff( XFS_PURGE_INODE(XFS_QI_UQIP(mp)); XFS_QI_UQIP(mp) = NULL; } - if ((dqtype & XFS_QMOPT_GQUOTA) && XFS_QI_GQIP(mp)) { + if ((dqtype & (XFS_QMOPT_GQUOTA|XFS_QMOPT_PQUOTA)) && XFS_QI_GQIP(mp)) { XFS_PURGE_INODE(XFS_QI_GQIP(mp)); XFS_QI_GQIP(mp) = NULL; } @@ -411,7 +414,8 @@ xfs_qm_scall_trunc_qfiles( } } - if ((flags & XFS_DQ_GROUP) && mp->m_sb.sb_gquotino != NULLFSINO) { + if ((flags & (XFS_DQ_GROUP|XFS_DQ_PROJ)) && + mp->m_sb.sb_gquotino != NULLFSINO) { error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip, 0); if (! error) { (void) xfs_truncate_file(mp, qip); @@ -434,7 +438,7 @@ xfs_qm_scall_quotaon( uint flags) { int error; - unsigned long s; + unsigned long s; uint qf; uint accflags; __int64_t sbflags; @@ -468,9 +472,13 @@ xfs_qm_scall_quotaon( (mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 && (flags & XFS_UQUOTA_ENFD)) || + ((flags & XFS_PQUOTA_ACCT) == 0 && + (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 && + (flags & XFS_OQUOTA_ENFD)) + || ((flags & XFS_GQUOTA_ACCT) == 0 && (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 && - (flags & XFS_GQUOTA_ENFD))) { + (flags & XFS_OQUOTA_ENFD))) { qdprintk("Can't enforce without acct, flags=%x sbflags=%x\n", flags, mp->m_sb.sb_qflags); return XFS_ERROR(EINVAL); @@ -504,6 +512,10 @@ xfs_qm_scall_quotaon( */ if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) != (mp->m_qflags & XFS_UQUOTA_ACCT)) || + ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) != + (mp->m_qflags & XFS_PQUOTA_ACCT)) || + ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) != + (mp->m_qflags & XFS_GQUOTA_ACCT)) || (flags & XFS_ALL_QUOTA_ENFD) == 0) return (0); @@ -521,7 +533,6 @@ xfs_qm_scall_quotaon( } - /* * Return quota status information, such as uquota-off, enforcements, etc. */ @@ -776,9 +787,9 @@ xfs_qm_log_quotaoff_end( xfs_qoff_logitem_t *startqoff, uint flags) { - xfs_trans_t *tp; + xfs_trans_t *tp; int error; - xfs_qoff_logitem_t *qoffi; + xfs_qoff_logitem_t *qoffi; tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF_END); @@ -928,18 +939,26 @@ xfs_qm_export_dquot( STATIC uint xfs_qm_import_qtype_flags( - uint uflags) + uint uflags) { + uint oflags = 0; + /* - * Can't be both at the same time. + * Can't be more than one, or none. */ if (((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) == - (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) || - ((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) == 0)) + (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) || + ((uflags & (XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) == + (XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) || + ((uflags & (XFS_USER_QUOTA | XFS_PROJ_QUOTA)) == + (XFS_USER_QUOTA | XFS_PROJ_QUOTA)) || + ((uflags & (XFS_GROUP_QUOTA|XFS_USER_QUOTA|XFS_PROJ_QUOTA)) == 0)) return (0); - return (uflags & XFS_USER_QUOTA) ? - XFS_DQ_USER : XFS_DQ_GROUP; + oflags |= (uflags & XFS_USER_QUOTA) ? XFS_DQ_USER : 0; + oflags |= (uflags & XFS_PROJ_QUOTA) ? XFS_DQ_PROJ : 0; + oflags |= (uflags & XFS_GROUP_QUOTA) ? XFS_DQ_GROUP: 0; + return oflags; } STATIC uint @@ -947,14 +966,19 @@ xfs_qm_export_qtype_flags( uint flags) { /* - * Can't be both at the same time. + * Can't be more than one, or none. */ - ASSERT((flags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) != - (XFS_GROUP_QUOTA | XFS_USER_QUOTA)); - ASSERT((flags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) != 0); + ASSERT((flags & (XFS_PROJ_QUOTA | XFS_USER_QUOTA)) != + (XFS_PROJ_QUOTA | XFS_USER_QUOTA)); + ASSERT((flags & (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)) != + (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)); + ASSERT((flags & (XFS_USER_QUOTA | XFS_GROUP_QUOTA)) != + (XFS_USER_QUOTA | XFS_GROUP_QUOTA)); + ASSERT((flags & (XFS_PROJ_QUOTA|XFS_USER_QUOTA|XFS_GROUP_QUOTA)) != 0); return (flags & XFS_DQ_USER) ? - XFS_USER_QUOTA : XFS_GROUP_QUOTA; + XFS_USER_QUOTA : (flags & XFS_DQ_PROJ) ? + XFS_PROJ_QUOTA : XFS_GROUP_QUOTA; } STATIC uint @@ -965,12 +989,14 @@ xfs_qm_import_flags( if (uflags & XFS_QUOTA_UDQ_ACCT) flags |= XFS_UQUOTA_ACCT; + if (uflags & XFS_QUOTA_PDQ_ACCT) + flags |= XFS_PQUOTA_ACCT; if (uflags & XFS_QUOTA_GDQ_ACCT) flags |= XFS_GQUOTA_ACCT; if (uflags & XFS_QUOTA_UDQ_ENFD) flags |= XFS_UQUOTA_ENFD; - if (uflags & XFS_QUOTA_GDQ_ENFD) - flags |= XFS_GQUOTA_ENFD; + if (uflags & (XFS_QUOTA_PDQ_ENFD|XFS_QUOTA_GDQ_ENFD)) + flags |= XFS_OQUOTA_ENFD; return (flags); } @@ -984,12 +1010,16 @@ xfs_qm_export_flags( uflags = 0; if (flags & XFS_UQUOTA_ACCT) uflags |= XFS_QUOTA_UDQ_ACCT; + if (flags & XFS_PQUOTA_ACCT) + uflags |= XFS_QUOTA_PDQ_ACCT; if (flags & XFS_GQUOTA_ACCT) uflags |= XFS_QUOTA_GDQ_ACCT; if (flags & XFS_UQUOTA_ENFD) uflags |= XFS_QUOTA_UDQ_ENFD; - if (flags & XFS_GQUOTA_ENFD) - uflags |= XFS_QUOTA_GDQ_ENFD; + if (flags & (XFS_OQUOTA_ENFD)) { + uflags |= (flags & XFS_GQUOTA_ACCT) ? + XFS_QUOTA_GDQ_ENFD : XFS_QUOTA_PDQ_ENFD; + } return (uflags); } @@ -1070,7 +1100,7 @@ again: xfs_qm_dqrele(ip->i_udquot); ip->i_udquot = NULL; } - if ((flags & XFS_GQUOTA_ACCT) && ip->i_gdquot) { + if (flags & (XFS_PQUOTA_ACCT|XFS_GQUOTA_ACCT) && ip->i_gdquot) { xfs_qm_dqrele(ip->i_gdquot); ip->i_gdquot = NULL; } @@ -1160,7 +1190,6 @@ xfs_qm_dqtest_print( { cmn_err(CE_DEBUG, "-----------DQTEST DQUOT----------------"); cmn_err(CE_DEBUG, "---- dquot ID = %d", d->d_id); - cmn_err(CE_DEBUG, "---- type = %s", XFS_QM_ISUDQ(d)? "USR" : "GRP"); cmn_err(CE_DEBUG, "---- fs = 0x%p", d->q_mount); cmn_err(CE_DEBUG, "---- bcount = %Lu (0x%x)", d->d_bcount, (int)d->d_bcount); @@ -1231,7 +1260,7 @@ xfs_dqtest_cmp2( #ifdef QUOTADEBUG if (!err) { cmn_err(CE_DEBUG, "%d [%s] [0x%p] qchecked", - d->d_id, XFS_QM_ISUDQ(d) ? "USR" : "GRP", d->q_mount); + d->d_id, DQFLAGTO_TYPESTR(d), d->q_mount); } #endif return (err); @@ -1287,6 +1316,7 @@ STATIC void xfs_qm_internalqcheck_get_dquots( xfs_mount_t *mp, xfs_dqid_t uid, + xfs_dqid_t projid, xfs_dqid_t gid, xfs_dqtest_t **ud, xfs_dqtest_t **gd) @@ -1295,6 +1325,8 @@ xfs_qm_internalqcheck_get_dquots( xfs_qm_internalqcheck_dqget(mp, uid, XFS_DQ_USER, ud); if (XFS_IS_GQUOTA_ON(mp)) xfs_qm_internalqcheck_dqget(mp, gid, XFS_DQ_GROUP, gd); + else if (XFS_IS_PQUOTA_ON(mp)) + xfs_qm_internalqcheck_dqget(mp, projid, XFS_DQ_PROJ, gd); } @@ -1362,13 +1394,14 @@ xfs_qm_internalqcheck_adjust( } xfs_qm_internalqcheck_get_dquots(mp, (xfs_dqid_t) ip->i_d.di_uid, + (xfs_dqid_t) ip->i_d.di_projid, (xfs_dqid_t) ip->i_d.di_gid, &ud, &gd); if (XFS_IS_UQUOTA_ON(mp)) { ASSERT(ud); xfs_qm_internalqcheck_dqadjust(ip, ud); } - if (XFS_IS_GQUOTA_ON(mp)) { + if (XFS_IS_OQUOTA_ON(mp)) { ASSERT(gd); xfs_qm_internalqcheck_dqadjust(ip, gd); } diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h index 675f03f443d2..472afd3570c6 100644 --- a/fs/xfs/quota/xfs_quota_priv.h +++ b/fs/xfs/quota/xfs_quota_priv.h @@ -102,7 +102,8 @@ static inline int XQMISLCKD(struct xfs_dqhash *h) (xfs_Gqm->qm_grp_dqhtable + \ XFS_DQ_HASHVAL(mp, id))) #define XFS_IS_DQTYPE_ON(mp, type) (type == XFS_DQ_USER ? \ - XFS_IS_UQUOTA_ON(mp):XFS_IS_GQUOTA_ON(mp)) + XFS_IS_UQUOTA_ON(mp) : \ + XFS_IS_OQUOTA_ON(mp)) #define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \ !dqp->q_core.d_blk_hardlimit && \ !dqp->q_core.d_blk_softlimit && \ @@ -180,7 +181,8 @@ for ((dqp) = (qlist)->qh_next; (dqp) != (xfs_dquot_t *)(qlist); \ IRELE(ip); #define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \ - (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : "???")) + (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : \ + (((d)->dq_flags & XFS_DQ_PROJ) ? "PRJ":"???"))) #define DQFLAGTO_DIRTYSTR(d) (XFS_DQ_IS_DIRTY(d) ? "DIRTY" : "NOTDIRTY") #endif /* __XFS_QUOTA_PRIV_H__ */ diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c index 3644ca00cc82..565efb73c233 100644 --- a/fs/xfs/quota/xfs_trans_dquot.c +++ b/fs/xfs/quota/xfs_trans_dquot.c @@ -207,12 +207,10 @@ xfs_trans_mod_dquot_byino( if (tp->t_dqinfo == NULL) xfs_trans_alloc_dqinfo(tp); - if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot) { + if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot) (void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta); - } - if (XFS_IS_GQUOTA_ON(mp) && ip->i_gdquot) { + if (XFS_IS_OQUOTA_ON(mp) && ip->i_gdquot) (void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta); - } } STATIC xfs_dqtrx_t * diff --git a/fs/xfs/xfs_buf_item.h b/fs/xfs/xfs_buf_item.h index 5f1b0c9308f6..01aed5f2d579 100644 --- a/fs/xfs/xfs_buf_item.h +++ b/fs/xfs/xfs_buf_item.h @@ -80,7 +80,7 @@ typedef struct xfs_buf_log_format_t { * user or group dquots and may require special recovery handling. */ #define XFS_BLI_UDQUOT_BUF 0x4 -/* #define XFS_BLI_PDQUOT_BUF 0x8 */ +#define XFS_BLI_PDQUOT_BUF 0x8 #define XFS_BLI_GDQUOT_BUF 0x10 #define XFS_BLI_CHUNK 128 diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 593e597c86b2..91d764a5a9b2 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -1964,7 +1964,8 @@ xlog_recover_do_reg_buffer( * probably a good thing to do for other buf types also. */ error = 0; - if (buf_f->blf_flags & (XFS_BLI_UDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) { + if (buf_f->blf_flags & + (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) { error = xfs_qm_dqcheck((xfs_disk_dquot_t *) item->ri_buf[i].i_addr, -1, 0, XFS_QMOPT_DOWARN, @@ -2030,6 +2031,7 @@ xfs_qm_dqcheck( } if (INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_USER && + INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_PROJ && INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_GROUP) { if (flags & XFS_QMOPT_DOWARN) cmn_err(CE_ALERT, @@ -2135,6 +2137,8 @@ xlog_recover_do_dquot_buffer( type = 0; if (buf_f->blf_flags & XFS_BLI_UDQUOT_BUF) type |= XFS_DQ_USER; + if (buf_f->blf_flags & XFS_BLI_PDQUOT_BUF) + type |= XFS_DQ_PROJ; if (buf_f->blf_flags & XFS_BLI_GDQUOT_BUF) type |= XFS_DQ_GROUP; /* @@ -2247,7 +2251,8 @@ xlog_recover_do_buffer_trans( error = 0; if (flags & XFS_BLI_INODE_BUF) { error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f); - } else if (flags & (XFS_BLI_UDQUOT_BUF | XFS_BLI_GDQUOT_BUF)) { + } else if (flags & + (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) { xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f); } else { xlog_recover_do_reg_buffer(mp, item, bp, buf_f); @@ -2619,7 +2624,7 @@ xlog_recover_do_dquot_trans( * This type of quotas was turned off, so ignore this record. */ type = INT_GET(recddq->d_flags, ARCH_CONVERT) & - (XFS_DQ_USER | XFS_DQ_GROUP); + (XFS_DQ_USER | XFS_DQ_PROJ | XFS_DQ_GROUP); ASSERT(type); if (log->l_quotaoffs_flag & type) return (0); diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index cd5170ec73a3..5affba38a577 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -141,7 +141,7 @@ typedef int (*xfs_dqattach_t)(struct xfs_inode *, uint); typedef void (*xfs_dqdetach_t)(struct xfs_inode *); typedef int (*xfs_dqpurgeall_t)(struct xfs_mount *, uint); typedef int (*xfs_dqvopalloc_t)(struct xfs_mount *, - struct xfs_inode *, uid_t, gid_t, uint, + struct xfs_inode *, uid_t, gid_t, prid_t, uint, struct xfs_dquot **, struct xfs_dquot **); typedef void (*xfs_dqvopcreate_t)(struct xfs_trans *, struct xfs_inode *, struct xfs_dquot *, struct xfs_dquot *); @@ -185,8 +185,8 @@ typedef struct xfs_qmops { (*(mp)->m_qm_ops.xfs_dqdetach)(ip) #define XFS_QM_DQPURGEALL(mp, fl) \ (*(mp)->m_qm_ops.xfs_dqpurgeall)(mp, fl) -#define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, fl, dq1, dq2) \ - (*(mp)->m_qm_ops.xfs_dqvopalloc)(mp, ip, uid, gid, fl, dq1, dq2) +#define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, prid, fl, dq1, dq2) \ + (*(mp)->m_qm_ops.xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2) #define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \ (*(mp)->m_qm_ops.xfs_dqvopcreate)(tp, ip, dq1, dq2) #define XFS_QM_DQVOPRENAME(mp, ip) \ diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h index 703ec4efcb41..341cb4604c66 100644 --- a/fs/xfs/xfs_quota.h +++ b/fs/xfs/xfs_quota.h @@ -96,7 +96,7 @@ typedef struct xfs_dqblk { * flags for q_flags field in the dquot. */ #define XFS_DQ_USER 0x0001 /* a user quota */ -/* #define XFS_DQ_PROJ 0x0002 -- project quota (IRIX) */ +#define XFS_DQ_PROJ 0x0002 /* project quota */ #define XFS_DQ_GROUP 0x0004 /* a group quota */ #define XFS_DQ_FLOCKED 0x0008 /* flush lock taken */ #define XFS_DQ_DIRTY 0x0010 /* dquot is dirty */ @@ -104,6 +104,8 @@ typedef struct xfs_dqblk { #define XFS_DQ_INACTIVE 0x0040 /* dq off mplist & hashlist */ #define XFS_DQ_MARKER 0x0080 /* sentinel */ +#define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP) + /* * In the worst case, when both user and group quotas are on, * we can have a max of three dquots changing in a single transaction. @@ -124,7 +126,7 @@ typedef struct xfs_dqblk { typedef struct xfs_dq_logformat { __uint16_t qlf_type; /* dquot log item type */ __uint16_t qlf_size; /* size of this item */ - xfs_dqid_t qlf_id; /* usr/grp id number : 32 bits */ + xfs_dqid_t qlf_id; /* usr/grp/proj id : 32 bits */ __int64_t qlf_blkno; /* blkno of dquot buffer */ __int32_t qlf_len; /* len of dquot buffer */ __uint32_t qlf_boffset; /* off of dquot in buffer */ @@ -152,9 +154,9 @@ typedef struct xfs_qoff_logformat { #define XFS_UQUOTA_ACCT 0x0001 /* user quota accounting ON */ #define XFS_UQUOTA_ENFD 0x0002 /* user quota limits enforced */ #define XFS_UQUOTA_CHKD 0x0004 /* quotacheck run on usr quotas */ -#define XFS_PQUOTA_ACCT 0x0008 /* (IRIX) project quota accounting ON */ -#define XFS_GQUOTA_ENFD 0x0010 /* group quota limits enforced */ -#define XFS_GQUOTA_CHKD 0x0020 /* quotacheck run on grp quotas */ +#define XFS_PQUOTA_ACCT 0x0008 /* project quota accounting ON */ +#define XFS_OQUOTA_ENFD 0x0010 /* other (grp/prj) quota limits enforced */ +#define XFS_OQUOTA_CHKD 0x0020 /* quotacheck run on other (grp/prj) quotas */ #define XFS_GQUOTA_ACCT 0x0040 /* group quota accounting ON */ /* @@ -162,17 +164,22 @@ typedef struct xfs_qoff_logformat { * are in the process of getting turned off. These flags are in m_qflags but * never in sb_qflags. */ -#define XFS_UQUOTA_ACTIVE 0x0080 /* uquotas are being turned off */ -#define XFS_GQUOTA_ACTIVE 0x0100 /* gquotas are being turned off */ +#define XFS_UQUOTA_ACTIVE 0x0100 /* uquotas are being turned off */ +#define XFS_PQUOTA_ACTIVE 0x0200 /* pquotas are being turned off */ +#define XFS_GQUOTA_ACTIVE 0x0400 /* gquotas are being turned off */ /* * Checking XFS_IS_*QUOTA_ON() while holding any inode lock guarantees * quota will be not be switched off as long as that inode lock is held. */ #define XFS_IS_QUOTA_ON(mp) ((mp)->m_qflags & (XFS_UQUOTA_ACTIVE | \ - XFS_GQUOTA_ACTIVE)) + XFS_GQUOTA_ACTIVE | \ + XFS_PQUOTA_ACTIVE)) +#define XFS_IS_OQUOTA_ON(mp) ((mp)->m_qflags & (XFS_GQUOTA_ACTIVE | \ + XFS_PQUOTA_ACTIVE)) #define XFS_IS_UQUOTA_ON(mp) ((mp)->m_qflags & XFS_UQUOTA_ACTIVE) #define XFS_IS_GQUOTA_ON(mp) ((mp)->m_qflags & XFS_GQUOTA_ACTIVE) +#define XFS_IS_PQUOTA_ON(mp) ((mp)->m_qflags & XFS_PQUOTA_ACTIVE) /* * Flags to tell various functions what to do. Not all of these are meaningful @@ -182,7 +189,7 @@ typedef struct xfs_qoff_logformat { #define XFS_QMOPT_DQLOCK 0x0000001 /* dqlock */ #define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */ #define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */ -#define XFS_QMOPT_GQUOTA 0x0000008 /* group dquot requested */ +#define XFS_QMOPT_PQUOTA 0x0000008 /* project dquot requested */ #define XFS_QMOPT_FORCE_RES 0x0000010 /* ignore quota limits */ #define XFS_QMOPT_DQSUSER 0x0000020 /* don't cache super users dquot */ #define XFS_QMOPT_SBVERSION 0x0000040 /* change superblock version num */ @@ -192,6 +199,7 @@ typedef struct xfs_qoff_logformat { #define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if necessary */ #define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */ #define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot, if damaged. */ +#define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */ /* * flags to xfs_trans_mod_dquot to indicate which field needs to be @@ -231,7 +239,8 @@ typedef struct xfs_qoff_logformat { #define XFS_TRANS_DQ_DELRTBCOUNT XFS_QMOPT_DELRTBCOUNT -#define XFS_QMOPT_QUOTALL (XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA) +#define XFS_QMOPT_QUOTALL \ + (XFS_QMOPT_UQUOTA | XFS_QMOPT_PQUOTA | XFS_QMOPT_GQUOTA) #define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS) #ifdef __KERNEL__ @@ -246,21 +255,33 @@ typedef struct xfs_qoff_logformat { */ #define XFS_NOT_DQATTACHED(mp, ip) ((XFS_IS_UQUOTA_ON(mp) &&\ (ip)->i_udquot == NULL) || \ - (XFS_IS_GQUOTA_ON(mp) && \ + (XFS_IS_OQUOTA_ON(mp) && \ (ip)->i_gdquot == NULL)) -#define XFS_QM_NEED_QUOTACHECK(mp) ((XFS_IS_UQUOTA_ON(mp) && \ - (mp->m_sb.sb_qflags & \ - XFS_UQUOTA_CHKD) == 0) || \ - (XFS_IS_GQUOTA_ON(mp) && \ - (mp->m_sb.sb_qflags & \ - XFS_GQUOTA_CHKD) == 0)) +#define XFS_QM_NEED_QUOTACHECK(mp) \ + ((XFS_IS_UQUOTA_ON(mp) && \ + (mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD) == 0) || \ + (XFS_IS_GQUOTA_ON(mp) && \ + ((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \ + (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT))) || \ + (XFS_IS_PQUOTA_ON(mp) && \ + ((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \ + (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT)))) + +#define XFS_MOUNT_QUOTA_SET1 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\ + XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\ + XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD) + +#define XFS_MOUNT_QUOTA_SET2 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\ + XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\ + XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD) #define XFS_MOUNT_QUOTA_ALL (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\ - XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\ - XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD) + XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\ + XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\ + XFS_GQUOTA_ACCT) #define XFS_MOUNT_QUOTA_MASK (XFS_MOUNT_QUOTA_ALL | XFS_UQUOTA_ACTIVE | \ - XFS_GQUOTA_ACTIVE) + XFS_GQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE) /* diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index a9682b9510c1..144da7a85466 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c @@ -976,6 +976,7 @@ xfs_trans_dquot_buf( ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); ASSERT(type == XFS_BLI_UDQUOT_BUF || + type == XFS_BLI_PDQUOT_BUF || type == XFS_BLI_GDQUOT_BUF); bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c index d1f8146a06ea..11351f08d438 100644 --- a/fs/xfs/xfs_utils.c +++ b/fs/xfs/xfs_utils.c @@ -428,7 +428,7 @@ xfs_truncate_file( if (ip->i_ino != mp->m_sb.sb_uquotino) ASSERT(ip->i_udquot); } - if (XFS_IS_GQUOTA_ON(mp)) { + if (XFS_IS_OQUOTA_ON(mp)) { if (ip->i_ino != mp->m_sb.sb_gquotino) ASSERT(ip->i_gdquot); } diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index fb1ae6cfb1f3..103500498342 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -367,16 +367,6 @@ xfs_finish_flags( return XFS_ERROR(EROFS); } - /* - * disallow mount attempts with (IRIX) project quota enabled - */ - if (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) && - (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT)) { - cmn_err(CE_WARN, - "XFS: cannot mount a filesystem with IRIX project quota enabled"); - return XFS_ERROR(ENOSYS); - } - /* * check for shared mount. */ diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 5703783991fa..695978b27497 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -351,21 +351,28 @@ xfs_setattr( * If the IDs do change before we take the ilock, we're covered * because the i_*dquot fields will get updated anyway. */ - if (XFS_IS_QUOTA_ON(mp) && (mask & (XFS_AT_UID|XFS_AT_GID))) { + if (XFS_IS_QUOTA_ON(mp) && + (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID))) { uint qflags = 0; - if (mask & XFS_AT_UID) { + if ((mask & XFS_AT_UID) && XFS_IS_UQUOTA_ON(mp)) { uid = vap->va_uid; qflags |= XFS_QMOPT_UQUOTA; } else { uid = ip->i_d.di_uid; } - if (mask & XFS_AT_GID) { + if ((mask & XFS_AT_GID) && XFS_IS_GQUOTA_ON(mp)) { gid = vap->va_gid; qflags |= XFS_QMOPT_GQUOTA; } else { gid = ip->i_d.di_gid; } + if ((mask & XFS_AT_PROJID) && XFS_IS_PQUOTA_ON(mp)) { + projid = vap->va_projid; + qflags |= XFS_QMOPT_PQUOTA; + } else { + projid = ip->i_d.di_projid; + } /* * We take a reference when we initialize udqp and gdqp, * so it is important that we never blindly double trip on @@ -373,7 +380,8 @@ xfs_setattr( */ ASSERT(udqp == NULL); ASSERT(gdqp == NULL); - code = XFS_QM_DQVOPALLOC(mp, ip, uid,gid, qflags, &udqp, &gdqp); + code = XFS_QM_DQVOPALLOC(mp, ip, uid, gid, projid, qflags, + &udqp, &gdqp); if (code) return (code); } @@ -510,10 +518,11 @@ xfs_setattr( goto error_return; } /* - * Do a quota reservation only if uid or gid is actually + * Do a quota reservation only if uid/projid/gid is actually * going to change. */ if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) || + (XFS_IS_PQUOTA_ON(mp) && iprojid != projid) || (XFS_IS_GQUOTA_ON(mp) && igid != gid)) { ASSERT(tp); code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp, @@ -774,6 +783,7 @@ xfs_setattr( } if (igid != gid) { if (XFS_IS_GQUOTA_ON(mp)) { + ASSERT(!XFS_IS_PQUOTA_ON(mp)); ASSERT(mask & XFS_AT_GID); ASSERT(gdqp); olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip, @@ -782,6 +792,13 @@ xfs_setattr( ip->i_d.di_gid = gid; } if (iprojid != projid) { + if (XFS_IS_PQUOTA_ON(mp)) { + ASSERT(!XFS_IS_GQUOTA_ON(mp)); + ASSERT(mask & XFS_AT_PROJID); + ASSERT(gdqp); + olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip, + &ip->i_gdquot, gdqp); + } ip->i_d.di_projid = projid; /* * We may have to rev the inode as well as @@ -1907,7 +1924,7 @@ xfs_create( * Make sure that we have allocated dquot(s) on disk. */ error = XFS_QM_DQVOPALLOC(mp, dp, - current_fsuid(credp), current_fsgid(credp), + current_fsuid(credp), current_fsgid(credp), prid, XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp); if (error) goto std_return; @@ -2812,7 +2829,7 @@ xfs_mkdir( * Make sure that we have allocated dquot(s) on disk. */ error = XFS_QM_DQVOPALLOC(mp, dp, - current_fsuid(credp), current_fsgid(credp), + current_fsuid(credp), current_fsgid(credp), prid, XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); if (error) goto std_return; @@ -3366,7 +3383,7 @@ xfs_symlink( * Make sure that we have allocated dquot(s) on disk. */ error = XFS_QM_DQVOPALLOC(mp, dp, - current_fsuid(credp), current_fsgid(credp), + current_fsuid(credp), current_fsgid(credp), prid, XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); if (error) goto std_return; -- cgit v1.2.3-59-g8ed1b From 365ca83d509f77f2095976edb8d10ca6e9d86d58 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Tue, 21 Jun 2005 15:39:12 +1000 Subject: [XFS] Add support for project quota inheritance, a merge of Glens changes. SGI-PV: 932952 SGI-Modid: xfs-linux:xfs-kern:22806a Signed-off-by: Nathan Scott --- fs/xfs/xfs_inode.c | 24 +++++++++++++++--------- fs/xfs/xfs_vnodeops.c | 37 ++++++++++++++++++++++--------------- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index a2c723baff06..34bdf5909687 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1202,26 +1202,32 @@ xfs_ialloc( case S_IFREG: case S_IFDIR: if (unlikely(pip->i_d.di_flags & XFS_DIFLAG_ANY)) { - if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) { - if ((mode & S_IFMT) == S_IFDIR) { - ip->i_d.di_flags |= XFS_DIFLAG_RTINHERIT; - } else { - ip->i_d.di_flags |= XFS_DIFLAG_REALTIME; + uint di_flags = 0; + + if ((mode & S_IFMT) == S_IFDIR) { + if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) + di_flags |= XFS_DIFLAG_RTINHERIT; + } else { + if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) { + di_flags |= XFS_DIFLAG_REALTIME; ip->i_iocore.io_flags |= XFS_IOCORE_RT; } } if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) && xfs_inherit_noatime) - ip->i_d.di_flags |= XFS_DIFLAG_NOATIME; + di_flags |= XFS_DIFLAG_NOATIME; if ((pip->i_d.di_flags & XFS_DIFLAG_NODUMP) && xfs_inherit_nodump) - ip->i_d.di_flags |= XFS_DIFLAG_NODUMP; + di_flags |= XFS_DIFLAG_NODUMP; if ((pip->i_d.di_flags & XFS_DIFLAG_SYNC) && xfs_inherit_sync) - ip->i_d.di_flags |= XFS_DIFLAG_SYNC; + di_flags |= XFS_DIFLAG_SYNC; if ((pip->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) && xfs_inherit_nosymlinks) - ip->i_d.di_flags |= XFS_DIFLAG_NOSYMLINKS; + di_flags |= XFS_DIFLAG_NOSYMLINKS; + if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) + di_flags |= XFS_DIFLAG_PROJINHERIT; + ip->i_d.di_flags |= di_flags; } /* FALLTHROUGH */ case S_IFLNK: diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 695978b27497..96dc18b73cf0 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -507,8 +507,6 @@ xfs_setattr( * that the group ID supplied to the chown() function * shall be equal to either the group ID or one of the * supplementary group IDs of the calling process. - * - * XXX: How does restricted_chown affect projid? */ if (restricted_chown && (iuid != uid || (igid != gid && @@ -860,6 +858,8 @@ xfs_setattr( di_flags |= XFS_DIFLAG_NOATIME; if (vap->va_xflags & XFS_XFLAG_NODUMP) di_flags |= XFS_DIFLAG_NODUMP; + if (vap->va_xflags & XFS_XFLAG_PROJINHERIT) + di_flags |= XFS_DIFLAG_PROJINHERIT; if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) { if (vap->va_xflags & XFS_XFLAG_RTINHERIT) di_flags |= XFS_DIFLAG_RTINHERIT; @@ -1915,7 +1915,9 @@ xfs_create( /* Return through std_return after this point. */ udqp = gdqp = NULL; - if (vap->va_mask & XFS_AT_PROJID) + if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) + prid = dp->i_d.di_projid; + else if (vap->va_mask & XFS_AT_PROJID) prid = (xfs_prid_t)vap->va_projid; else prid = (xfs_prid_t)dfltprid; @@ -2621,17 +2623,7 @@ xfs_link( if (src_vp->v_type == VDIR) return XFS_ERROR(EPERM); - /* - * For now, manually find the XFS behavior descriptor for - * the source vnode. If it doesn't exist then something - * is wrong and we should just return an error. - * Eventually we need to figure out how link is going to - * work in the face of stacked vnodes. - */ src_bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(src_vp), &xfs_vnodeops); - if (src_bdp == NULL) { - return XFS_ERROR(EXDEV); - } sip = XFS_BHVTOI(src_bdp); tdp = XFS_BHVTOI(target_dir_bdp); mp = tdp->i_mount; @@ -2698,6 +2690,17 @@ xfs_link( goto error_return; } + /* + * If we are using project inheritance, we only allow hard link + * creation in our tree when the project IDs are the same; else + * the tree quota mechanism could be circumvented. + */ + if (unlikely((tdp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && + (tdp->i_d.di_projid != sip->i_d.di_projid))) { + error = XFS_ERROR(EPERM); + goto error_return; + } + if (resblks == 0 && (error = XFS_DIR_CANENTER(mp, tp, tdp, target_name, target_namelen))) @@ -2820,7 +2823,9 @@ xfs_mkdir( mp = dp->i_mount; udqp = gdqp = NULL; - if (vap->va_mask & XFS_AT_PROJID) + if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) + prid = dp->i_d.di_projid; + else if (vap->va_mask & XFS_AT_PROJID) prid = (xfs_prid_t)vap->va_projid; else prid = (xfs_prid_t)dfltprid; @@ -3374,7 +3379,9 @@ xfs_symlink( /* Return through std_return after this point. */ udqp = gdqp = NULL; - if (vap->va_mask & XFS_AT_PROJID) + if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) + prid = dp->i_d.di_projid; + else if (vap->va_mask & XFS_AT_PROJID) prid = (xfs_prid_t)vap->va_projid; else prid = (xfs_prid_t)dfltprid; -- cgit v1.2.3-59-g8ed1b From 6add2c4288801bd7fd0a4cc3277de7688f1f6714 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Tue, 21 Jun 2005 15:39:44 +1000 Subject: [XFS] Fix up some warning fallout from functions made static SGI-PV: 936255 SGI-Modid: xfs-linux:xfs-kern:193691a Signed-off-by: Eric Sandeen Signed-off-by: Nathan Scott --- fs/xfs/xfs_btree.c | 2 +- fs/xfs/xfs_dir2_leaf.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index 797f4d96cdf3..0cc63d657a14 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c @@ -93,7 +93,7 @@ xfs_btree_maxrecs( * Retrieve the block pointer from the cursor at the given level. * This may be a bmap btree root or from a buffer. */ -xfs_btree_block_t * /* generic btree block pointer */ +STATIC xfs_btree_block_t * /* generic btree block pointer */ xfs_btree_get_block( xfs_btree_cur_t *cur, /* btree cursor */ int level, /* level in btree */ diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index 79918df6ffea..056f5283904b 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c @@ -79,7 +79,7 @@ static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **lbpp, int *indexp, xfs_dabuf_t **dbpp); static void xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp, int first, int last); -extern void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp); +static void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp); /* -- cgit v1.2.3-59-g8ed1b From 48fab6bf5f8baf0d16b20a35e537719d14b66275 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 21 Jun 2005 15:40:20 +1000 Subject: [XFS] add XFS_INOBT_IS_FREE_DISK SGI-PV: 928382 SGI-Modid: xfs-linux:xfs-kern:193778a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott --- fs/xfs/xfs_ialloc_btree.h | 8 ++++++-- fs/xfs/xfs_macros.c | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_ialloc_btree.h b/fs/xfs/xfs_ialloc_btree.h index 803c4d17a057..44be188674a6 100644 --- a/fs/xfs/xfs_ialloc_btree.h +++ b/fs/xfs/xfs_ialloc_btree.h @@ -100,9 +100,13 @@ xfs_inofree_t xfs_inobt_mask(int i); #endif #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_IS_FREE) int xfs_inobt_is_free(xfs_inobt_rec_t *rp, int i); -#define XFS_INOBT_IS_FREE(rp,i) xfs_inobt_is_free(rp,i) +#define XFS_INOBT_IS_FREE(rp,i) xfs_inobt_is_free(rp,i) +#define XFS_INOBT_IS_FREE_DISK(rp,i) xfs_inobt_is_free_disk(rp,i) #else -#define XFS_INOBT_IS_FREE(rp,i) (((rp)->ir_free & XFS_INOBT_MASK(i)) != 0) +#define XFS_INOBT_IS_FREE(rp,i) \ + (((rp)->ir_free & XFS_INOBT_MASK(i)) != 0) +#define XFS_INOBT_IS_FREE_DISK(rp,i) \ + ((INT_GET((rp)->ir_free, ARCH_CONVERT) & XFS_INOBT_MASK(i)) != 0) #endif #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_SET_FREE) void xfs_inobt_set_free(xfs_inobt_rec_t *rp, int i); diff --git a/fs/xfs/xfs_macros.c b/fs/xfs/xfs_macros.c index ce4f46c6b3ab..698c2cd62858 100644 --- a/fs/xfs/xfs_macros.c +++ b/fs/xfs/xfs_macros.c @@ -1658,6 +1658,11 @@ xfs_inobt_is_free(xfs_inobt_rec_t *rp, int i) { return XFS_INOBT_IS_FREE(rp, i); } +int +xfs_inobt_is_free_disk(xfs_inobt_rec_t *rp, int i) +{ + return XFS_INOBT_IS_FREE_DISK(rp, i); +} #endif #if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INOBT_IS_LAST_REC) -- cgit v1.2.3-59-g8ed1b From f898d6c09caa40d82203acd72e9fda3cd5aeae74 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 21 Jun 2005 15:40:48 +1000 Subject: [XFS] quiesce the filesystem proper when freezing SGI-PV: 936977 SGI-Modid: xfs-linux:xfs-kern:193840a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott --- fs/xfs/linux-2.6/xfs_super.c | 6 +++-- fs/xfs/linux-2.6/xfs_vfs.h | 1 + fs/xfs/xfs_vfsops.c | 60 ++++++++++++++++++++++++++------------------ 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index d5f0340ddcd9..5fe9af38aa20 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -590,8 +590,10 @@ linvfs_sync_super( int error; int flags = SYNC_FSDATA; - if (wait) - flags |= SYNC_WAIT; + if (unlikely(sb->s_frozen == SB_FREEZE_WRITE)) + flags = SYNC_QUIESCE; + else + flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0); VFS_SYNC(vfsp, flags, NULL, error); sb->s_dirt = 0; diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h index 76493991578f..7ee1f714e9ba 100644 --- a/fs/xfs/linux-2.6/xfs_vfs.h +++ b/fs/xfs/linux-2.6/xfs_vfs.h @@ -107,6 +107,7 @@ typedef enum { #define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */ #define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */ #define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */ +#define SYNC_QUIESCE 0x0100 /* quiesce fileystem for a snapshot */ typedef int (*vfs_mount_t)(bhv_desc_t *, struct xfs_mount_args *, struct cred *); diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 103500498342..42bcc0215203 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -612,7 +612,34 @@ out: return XFS_ERROR(error); } -#define REMOUNT_READONLY_FLAGS (SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT) +STATIC int +xfs_quiesce_fs( + xfs_mount_t *mp) +{ + int count = 0, pincount; + + xfs_refcache_purge_mp(mp); + xfs_flush_buftarg(mp->m_ddev_targp, 0); + xfs_finish_reclaim_all(mp, 0); + + /* This loop must run at least twice. + * The first instance of the loop will flush + * most meta data but that will generate more + * meta data (typically directory updates). + * Which then must be flushed and logged before + * we can write the unmount record. + */ + do { + xfs_syncsub(mp, SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT, 0, NULL); + pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1); + if (!pincount) { + delay(50); + count++; + } + } while (count < 2); + + return 0; +} STATIC int xfs_mntupdate( @@ -622,8 +649,7 @@ xfs_mntupdate( { struct vfs *vfsp = bhvtovfs(bdp); xfs_mount_t *mp = XFS_BHVTOM(bdp); - int pincount, error; - int count = 0; + int error; if (args->flags & XFSMNT_NOATIME) mp->m_flags |= XFS_MOUNT_NOATIME; @@ -635,25 +661,7 @@ xfs_mntupdate( } if (*flags & MS_RDONLY) { - xfs_refcache_purge_mp(mp); - xfs_flush_buftarg(mp->m_ddev_targp, 0); - xfs_finish_reclaim_all(mp, 0); - - /* This loop must run at least twice. - * The first instance of the loop will flush - * most meta data but that will generate more - * meta data (typically directory updates). - * Which then must be flushed and logged before - * we can write the unmount record. - */ - do { - VFS_SYNC(vfsp, REMOUNT_READONLY_FLAGS, NULL, error); - pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1); - if (!pincount) { - delay(50); - count++; - } - } while (count < 2); + xfs_quiesce_fs(mp); /* Ok now write out an unmount record */ xfs_log_unmount_write(mp); @@ -869,10 +877,12 @@ xfs_sync( int flags, cred_t *credp) { - xfs_mount_t *mp; + xfs_mount_t *mp = XFS_BHVTOM(bdp); - mp = XFS_BHVTOM(bdp); - return (xfs_syncsub(mp, flags, 0, NULL)); + if (unlikely(flags == SYNC_QUIESCE)) + return xfs_quiesce_fs(mp); + else + return xfs_syncsub(mp, flags, 0, NULL); } /* -- cgit v1.2.3-59-g8ed1b From 7d795ca3442c7a562c45aeb7a7a808c79992a589 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 21 Jun 2005 15:41:19 +1000 Subject: [XFS] consolidate extent item freeing SGI-PV: 938062 SGI-Modid: xfs-linux:xfs-kern:194415a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott --- fs/xfs/xfs_extfree_item.c | 122 ++++++++++++---------------------------------- fs/xfs/xfs_extfree_item.h | 2 + fs/xfs/xfs_log_recover.c | 14 ++---- 3 files changed, 35 insertions(+), 103 deletions(-) diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index 4b45ff739e6b..db7cbd1bc857 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c @@ -59,6 +59,18 @@ STATIC void xfs_efi_item_abort(xfs_efi_log_item_t *); STATIC void xfs_efd_item_abort(xfs_efd_log_item_t *); +void +xfs_efi_item_free(xfs_efi_log_item_t *efip) +{ + int nexts = efip->efi_format.efi_nextents; + + if (nexts > XFS_EFI_MAX_FAST_EXTENTS) { + kmem_free(efip, sizeof(xfs_efi_log_item_t) + + (nexts - 1) * sizeof(xfs_extent_t)); + } else { + kmem_zone_free(xfs_efi_zone, efip); + } +} /* * This returns the number of iovecs needed to log the given efi item. @@ -120,8 +132,6 @@ xfs_efi_item_pin(xfs_efi_log_item_t *efip) STATIC void xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale) { - int nexts; - int size; xfs_mount_t *mp; SPLDECL(s); @@ -132,21 +142,11 @@ xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale) * xfs_trans_delete_ail() drops the AIL lock. */ xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s); - - nexts = efip->efi_format.efi_nextents; - if (nexts > XFS_EFI_MAX_FAST_EXTENTS) { - size = sizeof(xfs_efi_log_item_t); - size += (nexts - 1) * sizeof(xfs_extent_t); - kmem_free(efip, size); - } else { - kmem_zone_free(xfs_efi_zone, efip); - } + xfs_efi_item_free(efip); } else { efip->efi_flags |= XFS_EFI_COMMITTED; AIL_UNLOCK(mp, s); } - - return; } /* @@ -159,8 +159,6 @@ xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale) STATIC void xfs_efi_item_unpin_remove(xfs_efi_log_item_t *efip, xfs_trans_t *tp) { - int nexts; - int size; xfs_mount_t *mp; xfs_log_item_desc_t *lidp; SPLDECL(s); @@ -178,23 +176,11 @@ xfs_efi_item_unpin_remove(xfs_efi_log_item_t *efip, xfs_trans_t *tp) * xfs_trans_delete_ail() drops the AIL lock. */ xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s); - /* - * now free the item itself - */ - nexts = efip->efi_format.efi_nextents; - if (nexts > XFS_EFI_MAX_FAST_EXTENTS) { - size = sizeof(xfs_efi_log_item_t); - size += (nexts - 1) * sizeof(xfs_extent_t); - kmem_free(efip, size); - } else { - kmem_zone_free(xfs_efi_zone, efip); - } + xfs_efi_item_free(efip); } else { efip->efi_flags |= XFS_EFI_COMMITTED; AIL_UNLOCK(mp, s); } - - return; } /* @@ -245,18 +231,7 @@ xfs_efi_item_committed(xfs_efi_log_item_t *efip, xfs_lsn_t lsn) STATIC void xfs_efi_item_abort(xfs_efi_log_item_t *efip) { - int nexts; - int size; - - nexts = efip->efi_format.efi_nextents; - if (nexts > XFS_EFI_MAX_FAST_EXTENTS) { - size = sizeof(xfs_efi_log_item_t); - size += (nexts - 1) * sizeof(xfs_extent_t); - kmem_free(efip, size); - } else { - kmem_zone_free(xfs_efi_zone, efip); - } - return; + xfs_efi_item_free(efip); } /* @@ -355,8 +330,6 @@ xfs_efi_release(xfs_efi_log_item_t *efip, { xfs_mount_t *mp; int extents_left; - uint size; - int nexts; SPLDECL(s); mp = efip->efi_item.li_mountp; @@ -372,20 +345,10 @@ xfs_efi_release(xfs_efi_log_item_t *efip, * xfs_trans_delete_ail() drops the AIL lock. */ xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s); + xfs_efi_item_free(efip); } else { AIL_UNLOCK(mp, s); } - - if (extents_left == 0) { - nexts = efip->efi_format.efi_nextents; - if (nexts > XFS_EFI_MAX_FAST_EXTENTS) { - size = sizeof(xfs_efi_log_item_t); - size += (nexts - 1) * sizeof(xfs_extent_t); - kmem_free(efip, size); - } else { - kmem_zone_free(xfs_efi_zone, efip); - } - } } /* @@ -398,8 +361,6 @@ STATIC void xfs_efi_cancel( xfs_efi_log_item_t *efip) { - int nexts; - int size; xfs_mount_t *mp; SPLDECL(s); @@ -410,26 +371,25 @@ xfs_efi_cancel( * xfs_trans_delete_ail() drops the AIL lock. */ xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s); - - nexts = efip->efi_format.efi_nextents; - if (nexts > XFS_EFI_MAX_FAST_EXTENTS) { - size = sizeof(xfs_efi_log_item_t); - size += (nexts - 1) * sizeof(xfs_extent_t); - kmem_free(efip, size); - } else { - kmem_zone_free(xfs_efi_zone, efip); - } + xfs_efi_item_free(efip); } else { efip->efi_flags |= XFS_EFI_CANCELED; AIL_UNLOCK(mp, s); } - - return; } +STATIC void +xfs_efd_item_free(xfs_efd_log_item_t *efdp) +{ + int nexts = efdp->efd_format.efd_nextents; - - + if (nexts > XFS_EFD_MAX_FAST_EXTENTS) { + kmem_free(efdp, sizeof(xfs_efd_log_item_t) + + (nexts - 1) * sizeof(xfs_extent_t)); + } else { + kmem_zone_free(xfs_efd_zone, efdp); + } +} /* * This returns the number of iovecs needed to log the given efd item. @@ -533,9 +493,6 @@ xfs_efd_item_unlock(xfs_efd_log_item_t *efdp) STATIC xfs_lsn_t xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn) { - uint size; - int nexts; - /* * If we got a log I/O error, it's always the case that the LR with the * EFI got unpinned and freed before the EFD got aborted. @@ -543,15 +500,7 @@ xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn) if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0) xfs_efi_release(efdp->efd_efip, efdp->efd_format.efd_nextents); - nexts = efdp->efd_format.efd_nextents; - if (nexts > XFS_EFD_MAX_FAST_EXTENTS) { - size = sizeof(xfs_efd_log_item_t); - size += (nexts - 1) * sizeof(xfs_extent_t); - kmem_free(efdp, size); - } else { - kmem_zone_free(xfs_efd_zone, efdp); - } - + xfs_efd_item_free(efdp); return (xfs_lsn_t)-1; } @@ -565,9 +514,6 @@ xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn) STATIC void xfs_efd_item_abort(xfs_efd_log_item_t *efdp) { - int nexts; - int size; - /* * If we got a log I/O error, it's always the case that the LR with the * EFI got unpinned and freed before the EFD got aborted. So don't @@ -576,15 +522,7 @@ xfs_efd_item_abort(xfs_efd_log_item_t *efdp) if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0) xfs_efi_cancel(efdp->efd_efip); - nexts = efdp->efd_format.efd_nextents; - if (nexts > XFS_EFD_MAX_FAST_EXTENTS) { - size = sizeof(xfs_efd_log_item_t); - size += (nexts - 1) * sizeof(xfs_extent_t); - kmem_free(efdp, size); - } else { - kmem_zone_free(xfs_efd_zone, efdp); - } - return; + xfs_efd_item_free(efdp); } /* diff --git a/fs/xfs/xfs_extfree_item.h b/fs/xfs/xfs_extfree_item.h index 7122d6101d15..d433bac9f59d 100644 --- a/fs/xfs/xfs_extfree_item.h +++ b/fs/xfs/xfs_extfree_item.h @@ -118,6 +118,8 @@ xfs_efi_log_item_t *xfs_efi_init(struct xfs_mount *, uint); xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *, uint); +void xfs_efi_item_free(xfs_efi_log_item_t *); + #endif /* __KERNEL__ */ #endif /* __XFS_EXTFREE_ITEM_H__ */ diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 91d764a5a9b2..0aac28ddb81c 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -2747,7 +2747,6 @@ xlog_recover_do_efd_trans( xfs_efi_log_item_t *efip = NULL; xfs_log_item_t *lip; int gen; - int nexts; __uint64_t efi_id; SPLDECL(s); @@ -2782,22 +2781,15 @@ xlog_recover_do_efd_trans( } lip = xfs_trans_next_ail(mp, lip, &gen, NULL); } - if (lip == NULL) { - AIL_UNLOCK(mp, s); - } /* * If we found it, then free it up. If it wasn't there, it * must have been overwritten in the log. Oh well. */ if (lip != NULL) { - nexts = efip->efi_format.efi_nextents; - if (nexts > XFS_EFI_MAX_FAST_EXTENTS) { - kmem_free(lip, sizeof(xfs_efi_log_item_t) + - ((nexts - 1) * sizeof(xfs_extent_t))); - } else { - kmem_zone_free(xfs_efi_zone, efip); - } + xfs_efi_item_free(efip); + } else { + AIL_UNLOCK(mp, s); } } -- cgit v1.2.3-59-g8ed1b From d130c14c0310edac5ea0c6327bef7e3715f9a083 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 21 Jun 2005 15:43:22 +1000 Subject: [XFS] simplify ASSERT SGI-PV: 938063 SGI-Modid: xfs-linux:xfs-kern:194416a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott --- fs/xfs/support/debug.c | 1 - fs/xfs/support/debug.h | 7 +------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c index 7d6e1f37df10..4ed7b6928cd7 100644 --- a/fs/xfs/support/debug.c +++ b/fs/xfs/support/debug.c @@ -36,7 +36,6 @@ #include #include -int doass = 1; static char message[256]; /* keep it off the stack */ static DEFINE_SPINLOCK(xfs_err_lock); diff --git a/fs/xfs/support/debug.h b/fs/xfs/support/debug.h index 40b0f4c54d9e..c5b9365a7e2a 100644 --- a/fs/xfs/support/debug.h +++ b/fs/xfs/support/debug.h @@ -50,16 +50,11 @@ extern void cmn_err(int, char *, ...); #endif #ifdef DEBUG -# ifdef lint -# define ASSERT(EX) ((void)0) /* avoid "constant in conditional" babble */ -# else -# define ASSERT(EX) ((!doass||(EX))?((void)0):assfail(#EX, __FILE__, __LINE__)) -# endif /* lint */ +# define ASSERT(EX) ((EX) ? ((void)0) : assfail(#EX, __FILE__, __LINE__)) #else # define ASSERT(x) ((void)0) #endif -extern int doass; /* dynamically turn off asserts */ extern void assfail(char *, char *, int); #ifdef DEBUG extern unsigned long random(void); -- cgit v1.2.3-59-g8ed1b From bd5a876ac4c130e8e1986dcdbb21839ae4cd91c0 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 21 Jun 2005 15:47:39 +1000 Subject: [XFS] (mostly) remove xfs_inval_cached_pages Since the last round of direct I/O locking changes it is just a wrapper around VOP_FLUSHINVAL_PAGES, so it's not nessecary anymore. Keep a simplified version for kernels < 2.4.22, as these don't have the changed direct I/O locking. SGI-PV: 938064 SGI-Modid: xfs-linux:xfs-kern:194420a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott --- fs/xfs/linux-2.6/xfs_lrw.c | 24 ------------------------ fs/xfs/linux-2.6/xfs_lrw.h | 2 -- fs/xfs/xfs_dfrag.c | 7 ++++--- fs/xfs/xfs_vnodeops.c | 16 +++++++++++++--- 4 files changed, 17 insertions(+), 32 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index aa9daaea6c34..46b61a859af4 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c @@ -209,30 +209,6 @@ unlock: return (-status); } -/* - * xfs_inval_cached_pages - * - * This routine is responsible for keeping direct I/O and buffered I/O - * somewhat coherent. From here we make sure that we're at least - * temporarily holding the inode I/O lock exclusively and then call - * the page cache to flush and invalidate any cached pages. If there - * are no cached pages this routine will be very quick. - */ -void -xfs_inval_cached_pages( - vnode_t *vp, - xfs_iocore_t *io, - xfs_off_t offset, - int write, - int relock) -{ - if (VN_CACHED(vp)) { - xfs_inval_cached_trace(io, offset, -1, ctooff(offtoct(offset)), -1); - VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(offset)), -1, FI_REMAPF_LOCKED); - } - -} - ssize_t /* bytes read, or (-) error */ xfs_read( bhv_desc_t *bdp, diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h index d723e35254a0..f197a720e394 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.h +++ b/fs/xfs/linux-2.6/xfs_lrw.h @@ -94,8 +94,6 @@ extern int xfs_bdstrat_cb(struct xfs_buf *); extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t, xfs_fsize_t, xfs_fsize_t); -extern void xfs_inval_cached_pages(struct vnode *, struct xfs_iocore *, - xfs_off_t, int, int); extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *, const struct iovec *, unsigned int, loff_t *, int, struct cred *); diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 63abdc2ac7f4..681be5c93af5 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c @@ -180,9 +180,10 @@ xfs_swapext( goto error0; } - if (VN_CACHED(tvp) != 0) - xfs_inval_cached_pages(XFS_ITOV(tip), &(tip->i_iocore), - (xfs_off_t)0, 0, 0); + if (VN_CACHED(tvp) != 0) { + xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1); + VOP_FLUSHINVAL_PAGES(tvp, 0, -1, FI_REMAPF_LOCKED); + } /* Verify O_DIRECT for ftmp */ if (VN_CACHED(tvp) != 0) { diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 96dc18b73cf0..d64ebcfa0b6c 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -4329,6 +4329,7 @@ xfs_free_file_space( xfs_off_t len, int attr_flags) { + vnode_t *vp; int committed; int done; xfs_off_t end_dmi_offset; @@ -4349,9 +4350,11 @@ xfs_free_file_space( xfs_trans_t *tp; int need_iolock = 1; - vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); + vp = XFS_ITOV(ip); mp = ip->i_mount; + vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); + if ((error = XFS_QM_DQATTACH(mp, ip, 0))) return error; @@ -4368,7 +4371,7 @@ xfs_free_file_space( DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) { if (end_dmi_offset > ip->i_d.di_size) end_dmi_offset = ip->i_d.di_size; - error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOV(ip), + error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp, offset, end_dmi_offset - offset, AT_DELAY_FLAG(attr_flags), NULL); if (error) @@ -4387,7 +4390,14 @@ xfs_free_file_space( ioffset = offset & ~(rounding - 1); if (ilen & (rounding - 1)) ilen = (ilen + rounding) & ~(rounding - 1); - xfs_inval_cached_pages(XFS_ITOV(ip), &(ip->i_iocore), ioffset, 0, 0); + + if (VN_CACHED(vp) != 0) { + xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1, + ctooff(offtoct(ioffset)), -1); + VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(ioffset)), + -1, FI_REMAPF_LOCKED); + } + /* * Need to zero the stuff we're not freeing, on disk. * If its a realtime file & can't use unwritten extents then we -- cgit v1.2.3-59-g8ed1b From 77bc5beb5977a166e41b87c9d55d8e9cf2b3a04f Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Tue, 21 Jun 2005 15:48:04 +1000 Subject: [XFS] Makes more sense to use the fsxattr interface instead of adding new ioctls for project IDs. SGI-PV: 938145 SGI-Modid: xfs-linux:xfs-kern:22899a Signed-off-by: Nathan Scott --- fs/xfs/linux-2.6/xfs_ioctl.c | 33 ++++++++------------------------- fs/xfs/linux-2.6/xfs_ioctl32.c | 2 -- fs/xfs/xfs_fs.h | 5 ++--- 3 files changed, 10 insertions(+), 30 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index df17d93bd096..05a447e51cc0 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c @@ -777,8 +777,6 @@ xfs_ioctl( case XFS_IOC_GETVERSION: case XFS_IOC_GETXFLAGS: case XFS_IOC_SETXFLAGS: - case XFS_IOC_GETPROJID: - case XFS_IOC_SETPROJID: case XFS_IOC_FSGETXATTR: case XFS_IOC_FSSETXATTR: case XFS_IOC_FSGETXATTRA: @@ -1176,7 +1174,8 @@ xfs_ioc_xattr( switch (cmd) { case XFS_IOC_FSGETXATTR: { - va.va_mask = XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_NEXTENTS; + va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \ + XFS_AT_NEXTENTS | XFS_AT_PROJID; VOP_GETATTR(vp, &va, 0, NULL, error); if (error) return -error; @@ -1184,6 +1183,7 @@ xfs_ioc_xattr( fa.fsx_xflags = va.va_xflags; fa.fsx_extsize = va.va_extsize; fa.fsx_nextents = va.va_nextents; + fa.fsx_projid = va.va_projid; if (copy_to_user(arg, &fa, sizeof(fa))) return -XFS_ERROR(EFAULT); @@ -1198,9 +1198,10 @@ xfs_ioc_xattr( if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) attr_flags |= ATTR_NONBLOCK; - va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE; + va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | XFS_AT_PROJID; va.va_xflags = fa.fsx_xflags; va.va_extsize = fa.fsx_extsize; + va.va_projid = fa.fsx_projid; VOP_SETATTR(vp, &va, attr_flags, NULL, error); if (!error) @@ -1209,7 +1210,8 @@ xfs_ioc_xattr( } case XFS_IOC_FSGETXATTRA: { - va.va_mask = XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_ANEXTENTS; + va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \ + XFS_AT_ANEXTENTS | XFS_AT_PROJID; VOP_GETATTR(vp, &va, 0, NULL, error); if (error) return -error; @@ -1217,6 +1219,7 @@ xfs_ioc_xattr( fa.fsx_xflags = va.va_xflags; fa.fsx_extsize = va.va_extsize; fa.fsx_nextents = va.va_anextents; + fa.fsx_projid = va.va_projid; if (copy_to_user(arg, &fa, sizeof(fa))) return -XFS_ERROR(EFAULT); @@ -1260,26 +1263,6 @@ xfs_ioc_xattr( return 0; } - case XFS_IOC_GETPROJID: { - va.va_mask = XFS_AT_PROJID; - VOP_GETATTR(vp, &va, 0, NULL, error); - if (error) - return -error; - if (copy_to_user(arg, &va.va_projid, sizeof(va.va_projid))) - return -XFS_ERROR(EFAULT); - return 0; - } - - case XFS_IOC_SETPROJID: { - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - va.va_mask = XFS_AT_PROJID; - if (copy_from_user(&va.va_projid, arg, sizeof(va.va_projid))) - return -XFS_ERROR(EFAULT); - VOP_SETATTR(vp, &va, 0, NULL, error); - return -error; - } - default: return -ENOTTY; } diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c index be72aca59447..0f8f1384eb36 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl32.c +++ b/fs/xfs/linux-2.6/xfs_ioctl32.c @@ -100,8 +100,6 @@ __linvfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg) case XFS_IOC_GETBMAP: case XFS_IOC_GETBMAPA: case XFS_IOC_GETBMAPX: - case XFS_IOC_SETPROJID: - case XFS_IOC_GETPROJID: /* not handled case XFS_IOC_FD_TO_HANDLE: case XFS_IOC_PATH_TO_HANDLE: diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h index a7bd4687fa50..095af0a5cff3 100644 --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h @@ -60,7 +60,8 @@ struct fsxattr { __u32 fsx_xflags; /* xflags field value (get/set) */ __u32 fsx_extsize; /* extsize field value (get/set)*/ __u32 fsx_nextents; /* nextents field value (get) */ - unsigned char fsx_pad[16]; + __u32 fsx_projid; /* project identifier (get/set) */ + unsigned char fsx_pad[12]; }; #endif @@ -477,8 +478,6 @@ typedef struct xfs_handle { /* XFS_IOC_SETBIOSIZE ---- deprecated 46 */ /* XFS_IOC_GETBIOSIZE ---- deprecated 47 */ #define XFS_IOC_GETBMAPX _IOWR('X', 56, struct getbmap) -#define XFS_IOC_SETPROJID _IOWR('X', 57, __uint32_t) -#define XFS_IOC_GETPROJID _IOWR('X', 58, __uint32_t) /* * ioctl commands that replace IRIX syssgi()'s -- cgit v1.2.3-59-g8ed1b From 06d10dd9ca70ff1318ff2b871ff5f61a94223d9f Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Tue, 21 Jun 2005 15:48:47 +1000 Subject: [XFS] Merge fixes into realtime quota code, since one/two reported, still not enabled though. SGI-PV: 938145 SGI-Modid: xfs-linux:xfs-kern:22900a Signed-off-by: Nathan Scott --- fs/xfs/quota/xfs_qm.c | 34 +++++++------ fs/xfs/quota/xfs_qm.h | 6 ++- fs/xfs/quota/xfs_quota_priv.h | 1 + fs/xfs/quota/xfs_trans_dquot.c | 50 +++++++++--------- fs/xfs/xfs_bmap.c | 112 +++++++++++++++++++++++------------------ fs/xfs/xfs_iomap.c | 65 ++++++++++-------------- fs/xfs/xfs_quota.h | 11 +--- fs/xfs/xfs_vnodeops.c | 5 +- 8 files changed, 143 insertions(+), 141 deletions(-) diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 3ea75972767c..3254cb7b87f4 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -1251,6 +1251,10 @@ xfs_qm_init_quotainfo( INT_GET(ddqp->d_iwarns, ARCH_CONVERT) ? INT_GET(ddqp->d_iwarns, ARCH_CONVERT) : XFS_QM_IWARNLIMIT; + qinf->qi_rtbwarnlimit = + INT_GET(ddqp->d_rtbwarns, ARCH_CONVERT) ? + INT_GET(ddqp->d_rtbwarns, ARCH_CONVERT) : + XFS_QM_RTBWARNLIMIT; qinf->qi_bhardlimit = INT_GET(ddqp->d_blk_hardlimit, ARCH_CONVERT); qinf->qi_bsoftlimit = @@ -1276,6 +1280,7 @@ xfs_qm_init_quotainfo( qinf->qi_rtbtimelimit = XFS_QM_RTBTIMELIMIT; qinf->qi_bwarnlimit = XFS_QM_BWARNLIMIT; qinf->qi_iwarnlimit = XFS_QM_IWARNLIMIT; + qinf->qi_rtbwarnlimit = XFS_QM_RTBWARNLIMIT; } return (0); @@ -2624,6 +2629,9 @@ xfs_qm_vop_chown( xfs_dquot_t *newdq) { xfs_dquot_t *prevdq; + uint bfield = XFS_IS_REALTIME_INODE(ip) ? + XFS_TRANS_DQ_RTBCOUNT : XFS_TRANS_DQ_BCOUNT; + ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount)); @@ -2632,20 +2640,12 @@ xfs_qm_vop_chown( ASSERT(prevdq); ASSERT(prevdq != newdq); - xfs_trans_mod_dquot(tp, prevdq, - XFS_TRANS_DQ_BCOUNT, - -(ip->i_d.di_nblocks)); - xfs_trans_mod_dquot(tp, prevdq, - XFS_TRANS_DQ_ICOUNT, - -1); + xfs_trans_mod_dquot(tp, prevdq, bfield, -(ip->i_d.di_nblocks)); + xfs_trans_mod_dquot(tp, prevdq, XFS_TRANS_DQ_ICOUNT, -1); /* the sparkling new dquot */ - xfs_trans_mod_dquot(tp, newdq, - XFS_TRANS_DQ_BCOUNT, - ip->i_d.di_nblocks); - xfs_trans_mod_dquot(tp, newdq, - XFS_TRANS_DQ_ICOUNT, - 1); + xfs_trans_mod_dquot(tp, newdq, bfield, ip->i_d.di_nblocks); + xfs_trans_mod_dquot(tp, newdq, XFS_TRANS_DQ_ICOUNT, 1); /* * Take an extra reference, because the inode @@ -2673,7 +2673,7 @@ xfs_qm_vop_chown_reserve( { int error; xfs_mount_t *mp; - uint delblks; + uint delblks, blkflags; xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq; ASSERT(XFS_ISLOCKED_INODE(ip)); @@ -2682,6 +2682,8 @@ xfs_qm_vop_chown_reserve( delblks = ip->i_delayed_blks; delblksudq = delblksgdq = unresudq = unresgdq = NULL; + blkflags = XFS_IS_REALTIME_INODE(ip) ? + XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS; if (XFS_IS_UQUOTA_ON(mp) && udqp && ip->i_d.di_uid != (uid_t)INT_GET(udqp->q_core.d_id, ARCH_CONVERT)) { @@ -2711,7 +2713,7 @@ xfs_qm_vop_chown_reserve( if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount, delblksudq, delblksgdq, ip->i_d.di_nblocks, 1, - flags | XFS_QMOPT_RES_REGBLKS))) + flags | blkflags))) return (error); /* @@ -2728,11 +2730,11 @@ xfs_qm_vop_chown_reserve( ASSERT(unresudq || unresgdq); if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0, - flags | XFS_QMOPT_RES_REGBLKS))) + flags | blkflags))) return (error); xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0, - XFS_QMOPT_RES_REGBLKS); + blkflags); } return (0); diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h index 781968779540..b03eecf3b6cb 100644 --- a/fs/xfs/quota/xfs_qm.h +++ b/fs/xfs/quota/xfs_qm.h @@ -133,8 +133,9 @@ typedef struct xfs_quotainfo { time_t qi_btimelimit; /* limit for blks timer */ time_t qi_itimelimit; /* limit for inodes timer */ time_t qi_rtbtimelimit;/* limit for rt blks timer */ - xfs_qwarncnt_t qi_bwarnlimit; /* limit for num warnings */ - xfs_qwarncnt_t qi_iwarnlimit; /* limit for num warnings */ + xfs_qwarncnt_t qi_bwarnlimit; /* limit for blks warnings */ + xfs_qwarncnt_t qi_iwarnlimit; /* limit for inodes warnings */ + xfs_qwarncnt_t qi_rtbwarnlimit;/* limit for rt blks warnings */ mutex_t qi_quotaofflock;/* to serialize quotaoff */ xfs_filblks_t qi_dqchunklen; /* # BBs in a chunk of dqs */ uint qi_dqperchunk; /* # ondisk dqs in above chunk */ @@ -176,6 +177,7 @@ typedef struct xfs_dquot_acct { #define XFS_QM_BWARNLIMIT 5 #define XFS_QM_IWARNLIMIT 5 +#define XFS_QM_RTBWARNLIMIT 5 #define XFS_QM_LOCK(xqm) (mutex_lock(&xqm##_lock, PINOD)) #define XFS_QM_UNLOCK(xqm) (mutex_unlock(&xqm##_lock)) diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h index 472afd3570c6..bf413e70ec07 100644 --- a/fs/xfs/quota/xfs_quota_priv.h +++ b/fs/xfs/quota/xfs_quota_priv.h @@ -56,6 +56,7 @@ #define XFS_QI_RTBTIMELIMIT(mp) ((mp)->m_quotainfo->qi_rtbtimelimit) #define XFS_QI_ITIMELIMIT(mp) ((mp)->m_quotainfo->qi_itimelimit) #define XFS_QI_BWARNLIMIT(mp) ((mp)->m_quotainfo->qi_bwarnlimit) +#define XFS_QI_RTBWARNLIMIT(mp) ((mp)->m_quotainfo->qi_rtbwarnlimit) #define XFS_QI_IWARNLIMIT(mp) ((mp)->m_quotainfo->qi_iwarnlimit) #define XFS_QI_QOFFLOCK(mp) ((mp)->m_quotainfo->qi_quotaofflock) diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c index 565efb73c233..3b99daf8a640 100644 --- a/fs/xfs/quota/xfs_trans_dquot.c +++ b/fs/xfs/quota/xfs_trans_dquot.c @@ -497,7 +497,7 @@ xfs_trans_apply_dquot_deltas( * Adjust the RT reservation. */ if (qtrx->qt_rtblk_res != 0) { - if (qtrx->qt_blk_res != qtrx->qt_blk_res_used) { + if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) { if (qtrx->qt_rtblk_res > qtrx->qt_rtblk_res_used) dqp->q_res_rtbcount -= (xfs_qcnt_t) @@ -530,12 +530,6 @@ xfs_trans_apply_dquot_deltas( (xfs_qcnt_t)qtrx->qt_icount_delta; } - -#ifdef QUOTADEBUG - if (qtrx->qt_rtblk_res != 0) - cmn_err(CE_DEBUG, "RT res %d for 0x%p\n", - (int) qtrx->qt_rtblk_res, dqp); -#endif ASSERT(dqp->q_res_bcount >= INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT)); ASSERT(dqp->q_res_icount >= @@ -636,7 +630,10 @@ xfs_trans_dqresv( int error; xfs_qcnt_t hardlimit; xfs_qcnt_t softlimit; - time_t btimer; + time_t timer; + xfs_qwarncnt_t warns; + xfs_qwarncnt_t warnlimit; + xfs_qcnt_t count; xfs_qcnt_t *resbcountp; xfs_quotainfo_t *q = mp->m_quotainfo; @@ -651,7 +648,9 @@ xfs_trans_dqresv( softlimit = INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT); if (!softlimit) softlimit = q->qi_bsoftlimit; - btimer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT); + timer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT); + warns = INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT); + warnlimit = XFS_QI_BWARNLIMIT(dqp->q_mount); resbcountp = &dqp->q_res_bcount; } else { ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); @@ -661,7 +660,9 @@ xfs_trans_dqresv( softlimit = INT_GET(dqp->q_core.d_rtb_softlimit, ARCH_CONVERT); if (!softlimit) softlimit = q->qi_rtbsoftlimit; - btimer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT); + timer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT); + warns = INT_GET(dqp->q_core.d_rtbwarns, ARCH_CONVERT); + warnlimit = XFS_QI_RTBWARNLIMIT(dqp->q_mount); resbcountp = &dqp->q_res_rtbcount; } error = 0; @@ -691,37 +692,36 @@ xfs_trans_dqresv( * If timer or warnings has expired, * return EDQUOT */ - if ((btimer != 0 && get_seconds() > btimer) || - (dqp->q_core.d_bwarns && - INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT) >= - XFS_QI_BWARNLIMIT(dqp->q_mount))) { + if ((timer != 0 && get_seconds() > timer) || + (warns != 0 && warns >= warnlimit)) { error = EDQUOT; goto error_return; } } } if (ninos > 0) { - hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT); + count = INT_GET(dqp->q_core.d_icount, ARCH_CONVERT); + timer = INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT); + warns = INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT); + warnlimit = XFS_QI_IWARNLIMIT(dqp->q_mount); + hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit, + ARCH_CONVERT); if (!hardlimit) hardlimit = q->qi_ihardlimit; - softlimit = INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT); + softlimit = INT_GET(dqp->q_core.d_ino_softlimit, + ARCH_CONVERT); if (!softlimit) softlimit = q->qi_isoftlimit; - if (hardlimit > 0ULL && - INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= hardlimit) { + if (hardlimit > 0ULL && count >= hardlimit) { error = EDQUOT; goto error_return; - } else if (softlimit > 0ULL && - INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= softlimit) { + } else if (softlimit > 0ULL && count >= softlimit) { /* * If timer or warnings has expired, * return EDQUOT */ - if ((dqp->q_core.d_itimer && - get_seconds() > INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT)) || - (dqp->q_core.d_iwarns && - INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT) >= - XFS_QI_IWARNLIMIT(dqp->q_mount))) { + if ((timer != 0 && get_seconds() > timer) || + (warns != 0 && warns >= warnlimit)) { error = EDQUOT; goto error_return; } diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index f6f5ad35734c..6f5d283888aa 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -4545,18 +4545,17 @@ xfs_bmapi( xfs_extlen_t alen; /* allocated extent length */ xfs_fileoff_t aoff; /* allocated file offset */ xfs_bmalloca_t bma; /* args for xfs_bmap_alloc */ - char contig; /* allocation must be one extent */ xfs_btree_cur_t *cur; /* bmap btree cursor */ - char delay; /* this request is for delayed alloc */ xfs_fileoff_t end; /* end of mapped file region */ int eof; /* we've hit the end of extent list */ + char contig; /* allocation must be one extent */ + char delay; /* this request is for delayed alloc */ + char exact; /* don't do all of wasdelayed extent */ xfs_bmbt_rec_t *ep; /* extent list entry pointer */ int error; /* error return */ - char exact; /* don't do all of wasdelayed extent */ xfs_bmbt_irec_t got; /* current extent list record */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_extlen_t indlen; /* indirect blocks length */ - char inhole; /* current location is hole in file */ xfs_extnum_t lastx; /* last useful extent number */ int logflags; /* flags for transaction logging */ xfs_extlen_t minleft; /* min blocks left after allocation */ @@ -4567,13 +4566,15 @@ xfs_bmapi( xfs_extnum_t nextents; /* number of extents in file */ xfs_fileoff_t obno; /* old block number (offset) */ xfs_bmbt_irec_t prev; /* previous extent list record */ - char stateless; /* ignore state flag set */ int tmp_logflags; /* temp flags holder */ + int whichfork; /* data or attr fork */ + char inhole; /* current location is hole in file */ + char stateless; /* ignore state flag set */ char trim; /* output trimmed to match range */ char userdata; /* allocating non-metadata */ char wasdelay; /* old extent was delayed */ - int whichfork; /* data or attr fork */ char wr; /* this is a write request */ + char rt; /* this is a realtime file */ char rsvd; /* OK to allocate reserved blocks */ #ifdef DEBUG xfs_fileoff_t orig_bno; /* original block number value */ @@ -4603,6 +4604,7 @@ xfs_bmapi( } if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); + rt = XFS_IS_REALTIME_INODE(ip); ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT(ifp->if_ext_max == XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); @@ -4707,9 +4709,16 @@ xfs_bmapi( } minlen = contig ? alen : 1; if (delay) { - indlen = (xfs_extlen_t) - xfs_bmap_worst_indlen(ip, alen); - ASSERT(indlen > 0); + xfs_extlen_t extsz = 0; + + /* Figure out the extent size, adjust alen */ + if (rt) { + if (!(extsz = ip->i_d.di_extsize)) + extsz = mp->m_sb.sb_rextsize; + alen = roundup(alen, extsz); + extsz = alen / mp->m_sb.sb_rextsize; + } + /* * Make a transaction-less quota reservation for * delayed allocation blocks. This number gets @@ -4717,8 +4726,10 @@ xfs_bmapi( * We return EDQUOT if we haven't allocated * blks already inside this loop; */ - if (XFS_TRANS_RESERVE_BLKQUOTA( - mp, NULL, ip, (long)alen)) { + if (XFS_TRANS_RESERVE_QUOTA_NBLKS( + mp, NULL, ip, (long)alen, 0, + rt ? XFS_QMOPT_RES_RTBLKS : + XFS_QMOPT_RES_REGBLKS)) { if (n == 0) { *nmap = 0; ASSERT(cur == NULL); @@ -4731,40 +4742,34 @@ xfs_bmapi( * Split changing sb for alen and indlen since * they could be coming from different places. */ - if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) { - xfs_extlen_t extsz; - xfs_extlen_t ralen; - if (!(extsz = ip->i_d.di_extsize)) - extsz = mp->m_sb.sb_rextsize; - ralen = roundup(alen, extsz); - ralen = ralen / mp->m_sb.sb_rextsize; - if (xfs_mod_incore_sb(mp, - XFS_SBS_FREXTENTS, - -(ralen), rsvd)) { - if (XFS_IS_QUOTA_ON(ip->i_mount)) - XFS_TRANS_UNRESERVE_BLKQUOTA( - mp, NULL, ip, - (long)alen); - break; - } - } else { - if (xfs_mod_incore_sb(mp, - XFS_SBS_FDBLOCKS, - -(alen), rsvd)) { - if (XFS_IS_QUOTA_ON(ip->i_mount)) - XFS_TRANS_UNRESERVE_BLKQUOTA( - mp, NULL, ip, - (long)alen); - break; - } - } + indlen = (xfs_extlen_t) + xfs_bmap_worst_indlen(ip, alen); + ASSERT(indlen > 0); - if (xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, - -(indlen), rsvd)) { - XFS_TRANS_UNRESERVE_BLKQUOTA( - mp, NULL, ip, (long)alen); + if (rt) + error = xfs_mod_incore_sb(mp, + XFS_SBS_FREXTENTS, + -(extsz), rsvd); + else + error = xfs_mod_incore_sb(mp, + XFS_SBS_FDBLOCKS, + -(alen), rsvd); + if (!error) + error = xfs_mod_incore_sb(mp, + XFS_SBS_FDBLOCKS, + -(indlen), rsvd); + + if (error) { + if (XFS_IS_QUOTA_ON(ip->i_mount)) + /* unreserve the blocks now */ + XFS_TRANS_UNRESERVE_QUOTA_NBLKS( + mp, NULL, ip, + (long)alen, 0, rt ? + XFS_QMOPT_RES_RTBLKS : + XFS_QMOPT_RES_REGBLKS); break; } + ip->i_delayed_blks += alen; abno = NULLSTARTBLOCK(indlen); } else { @@ -5389,13 +5394,24 @@ xfs_bunmapi( } if (wasdel) { ASSERT(STARTBLOCKVAL(del.br_startblock) > 0); - xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, - (int)del.br_blockcount, rsvd); - /* Unreserve our quota space */ - XFS_TRANS_RESERVE_QUOTA_NBLKS( - mp, NULL, ip, -((long)del.br_blockcount), 0, - isrt ? XFS_QMOPT_RES_RTBLKS : + /* Update realtim/data freespace, unreserve quota */ + if (isrt) { + xfs_filblks_t rtexts; + + rtexts = XFS_FSB_TO_B(mp, del.br_blockcount); + do_div(rtexts, mp->m_sb.sb_rextsize); + xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, + (int)rtexts, rsvd); + XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip, + -((long)del.br_blockcount), 0, + XFS_QMOPT_RES_RTBLKS); + } else { + xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, + (int)del.br_blockcount, rsvd); + XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip, + -((long)del.br_blockcount), 0, XFS_QMOPT_RES_REGBLKS); + } ip->i_delayed_blks -= del.br_blockcount; if (cur) cur->bc_private.b.flags |= diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 469e1a7939d4..2edd6769e5d3 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -385,15 +385,15 @@ xfs_iomap_write_direct( int nimaps, maps; int error; int bmapi_flag; + int quota_flag; int rt; xfs_trans_t *tp; xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS], *imapp; xfs_bmap_free_t free_list; int aeof; - xfs_filblks_t datablocks; + xfs_filblks_t datablocks, qblocks, resblks; int committed; int numrtextents; - uint resblks; /* * Make sure that the dquots are there. This doesn't hold @@ -419,7 +419,6 @@ xfs_iomap_write_direct( xfs_fileoff_t map_last_fsb; map_last_fsb = ret_imap->br_blockcount + ret_imap->br_startoff; - if (map_last_fsb < last_fsb) { last_fsb = map_last_fsb; count_fsb = last_fsb - offset_fsb; @@ -428,56 +427,47 @@ xfs_iomap_write_direct( } /* - * determine if reserving space on - * the data or realtime partition. + * Determine if reserving space on the data or realtime partition. */ if ((rt = XFS_IS_REALTIME_INODE(ip))) { - int sbrtextsize, iprtextsize; + xfs_extlen_t extsz; - sbrtextsize = mp->m_sb.sb_rextsize; - iprtextsize = - ip->i_d.di_extsize ? ip->i_d.di_extsize : sbrtextsize; - numrtextents = (count_fsb + iprtextsize - 1); - do_div(numrtextents, sbrtextsize); + if (!(extsz = ip->i_d.di_extsize)) + extsz = mp->m_sb.sb_rextsize; + numrtextents = qblocks = (count_fsb + extsz - 1); + do_div(numrtextents, mp->m_sb.sb_rextsize); + quota_flag = XFS_QMOPT_RES_RTBLKS; datablocks = 0; } else { - datablocks = count_fsb; + datablocks = qblocks = count_fsb; + quota_flag = XFS_QMOPT_RES_REGBLKS; numrtextents = 0; } /* - * allocate and setup the transaction + * Allocate and setup the transaction */ xfs_iunlock(ip, XFS_ILOCK_EXCL); tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); - resblks = XFS_DIOSTRAT_SPACE_RES(mp, datablocks); - error = xfs_trans_reserve(tp, resblks, XFS_WRITE_LOG_RES(mp), numrtextents, XFS_TRANS_PERM_LOG_RES, XFS_WRITE_LOG_COUNT); /* - * check for running out of space + * Check for running out of space, note: need lock to return */ if (error) - /* - * Free the transaction structure. - */ xfs_trans_cancel(tp, 0); - xfs_ilock(ip, XFS_ILOCK_EXCL); - if (error) - goto error_out; /* Don't return in above if .. trans .., - need lock to return */ + goto error_out; - if (XFS_TRANS_RESERVE_BLKQUOTA(mp, tp, ip, resblks)) { + if (XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag)) { error = (EDQUOT); goto error1; } - nimaps = 1; bmapi_flag = XFS_BMAPI_WRITE; xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); @@ -487,31 +477,29 @@ xfs_iomap_write_direct( bmapi_flag |= XFS_BMAPI_PREALLOC; /* - * issue the bmapi() call to allocate the blocks + * Issue the bmapi() call to allocate the blocks */ XFS_BMAP_INIT(&free_list, &firstfsb); + nimaps = 1; imapp = &imap[0]; error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, bmapi_flag, &firstfsb, 0, imapp, &nimaps, &free_list); - if (error) { + if (error) goto error0; - } /* - * complete the transaction + * Complete the transaction */ - error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed); - if (error) { + if (error) goto error0; - } - error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); - if (error) { + if (error) goto error_out; - } - /* copy any maps to caller's array and return any error. */ + /* + * Copy any maps to caller's array and return any error. + */ if (nimaps == 0) { error = (ENOSPC); goto error_out; @@ -530,10 +518,11 @@ xfs_iomap_write_direct( } return 0; - error0: /* Cancel bmap, unlock inode, and cancel trans */ +error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ xfs_bmap_cancel(&free_list); + XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag); - error1: /* Just cancel transaction */ +error1: /* Just cancel transaction */ xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); *nmaps = 0; /* nothing set-up here */ diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h index 341cb4604c66..7134576ae7fa 100644 --- a/fs/xfs/xfs_quota.h +++ b/fs/xfs/xfs_quota.h @@ -352,15 +352,8 @@ typedef struct xfs_dqtrxops { #define XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp) \ XFS_DQTRXOP_VOID(mp, tp, qo_unreserve_and_mod_dquots) -#define XFS_TRANS_RESERVE_BLKQUOTA(mp, tp, ip, nblks) \ - XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, 0, \ - XFS_QMOPT_RES_REGBLKS) -#define XFS_TRANS_RESERVE_BLKQUOTA_FORCE(mp, tp, ip, nblks) \ - XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, 0, \ - XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES) -#define XFS_TRANS_UNRESERVE_BLKQUOTA(mp, tp, ip, nblks) \ - XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, -(nblks), 0, \ - XFS_QMOPT_RES_REGBLKS) +#define XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, ninos, flags) \ + XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, -(nblks), -(ninos), flags) #define XFS_TRANS_RESERVE_QUOTA(mp, tp, ud, gd, nb, ni, f) \ XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, ud, gd, nb, ni, \ f | XFS_QMOPT_RES_REGBLKS) diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index d64ebcfa0b6c..1377c868f3f4 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -4175,9 +4175,8 @@ retry: break; } xfs_ilock(ip, XFS_ILOCK_EXCL); - error = XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, - ip->i_udquot, ip->i_gdquot, resblks, 0, rt ? - XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS); + error = XFS_TRANS_RESERVE_QUOTA(mp, tp, + ip->i_udquot, ip->i_gdquot, resblks, 0, 0); if (error) goto error1; -- cgit v1.2.3-59-g8ed1b From 754002b4fb1b553bd8f978bb6f5aca7af46fde67 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Tue, 21 Jun 2005 15:49:06 +1000 Subject: [XFS] Merge a few minor fixes to the quota warning code. SGI-PV: 938145 SGI-Modid: xfs-linux:xfs-kern:22901a Signed-off-by: Nathan Scott --- fs/xfs/quota/xfs_dquot.c | 10 +++++++++- fs/xfs/quota/xfs_qm.c | 2 ++ fs/xfs/quota/xfs_qm_syscalls.c | 24 +++++++++++++++++++++--- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 68089f56d5cd..32ec7f4467d7 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c @@ -286,7 +286,9 @@ xfs_qm_adjust_dqlimits( * We also return 0 as the values of the timers in Q_GETQUOTA calls, when * enforcement's off. * In contrast, warnings are a little different in that they don't - * 'automatically' get started when limits get exceeded. + * 'automatically' get started when limits get exceeded. They do + * get reset to zero, however, when we find the count to be under + * the soft limit (they are only ever set non-zero via userspace). */ void xfs_qm_adjust_dqtimers( @@ -315,6 +317,8 @@ xfs_qm_adjust_dqtimers( INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) { INT_SET(d->d_btimer, ARCH_CONVERT, get_seconds() + XFS_QI_BTIMELIMIT(mp)); + } else { + d->d_bwarns = 0; } } else { if ((!d->d_blk_softlimit || @@ -336,6 +340,8 @@ xfs_qm_adjust_dqtimers( INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) { INT_SET(d->d_itimer, ARCH_CONVERT, get_seconds() + XFS_QI_ITIMELIMIT(mp)); + } else { + d->d_iwarns = 0; } } else { if ((!d->d_ino_softlimit || @@ -357,6 +363,8 @@ xfs_qm_adjust_dqtimers( INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT)))) { INT_SET(d->d_rtbtimer, ARCH_CONVERT, get_seconds() + XFS_QI_RTBTIMELIMIT(mp)); + } else { + d->d_rtbwarns = 0; } } else { if ((!d->d_rtb_softlimit || diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 3254cb7b87f4..f665ca8f9e96 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -1550,8 +1550,10 @@ xfs_qm_reset_dqcounts( INT_SET(ddq->d_rtbcount, ARCH_CONVERT, 0ULL); INT_SET(ddq->d_btimer, ARCH_CONVERT, (time_t)0); INT_SET(ddq->d_itimer, ARCH_CONVERT, (time_t)0); + INT_SET(ddq->d_rtbtimer, ARCH_CONVERT, (time_t)0); INT_SET(ddq->d_bwarns, ARCH_CONVERT, 0UL); INT_SET(ddq->d_iwarns, ARCH_CONVERT, 0UL); + INT_SET(ddq->d_rtbwarns, ARCH_CONVERT, 0UL); ddq = (xfs_disk_dquot_t *) ((xfs_dqblk_t *)ddq + 1); } diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 365a054f02d6..68e98962dbef 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c @@ -617,7 +617,8 @@ xfs_qm_scall_setqlim( if (!capable(CAP_SYS_ADMIN)) return XFS_ERROR(EPERM); - if ((newlim->d_fieldmask & (FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK)) == 0) + if ((newlim->d_fieldmask & + (FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK|FS_DQ_WARNS_MASK)) == 0) return (0); tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM); @@ -702,12 +703,23 @@ xfs_qm_scall_setqlim( qdprintk("ihard %Ld < isoft %Ld\n", hard, soft); } + /* + * Update warnings counter(s) if requested + */ + if (newlim->d_fieldmask & FS_DQ_BWARNS) + INT_SET(ddq->d_bwarns, ARCH_CONVERT, newlim->d_bwarns); + if (newlim->d_fieldmask & FS_DQ_IWARNS) + INT_SET(ddq->d_iwarns, ARCH_CONVERT, newlim->d_iwarns); + if (newlim->d_fieldmask & FS_DQ_RTBWARNS) + INT_SET(ddq->d_rtbwarns, ARCH_CONVERT, newlim->d_rtbwarns); + if (id == 0) { /* * Timelimits for the super user set the relative time * the other users can be over quota for this file system. * If it is zero a default is used. Ditto for the default - * soft and hard limit values (already done, above). + * soft and hard limit values (already done, above), and + * for warnings. */ if (newlim->d_fieldmask & FS_DQ_BTIMER) { mp->m_quotainfo->qi_btimelimit = newlim->d_btimer; @@ -721,7 +733,13 @@ xfs_qm_scall_setqlim( mp->m_quotainfo->qi_rtbtimelimit = newlim->d_rtbtimer; INT_SET(ddq->d_rtbtimer, ARCH_CONVERT, newlim->d_rtbtimer); } - } else /* if (XFS_IS_QUOTA_ENFORCED(mp)) */ { + if (newlim->d_fieldmask & FS_DQ_BWARNS) + mp->m_quotainfo->qi_bwarnlimit = newlim->d_bwarns; + if (newlim->d_fieldmask & FS_DQ_IWARNS) + mp->m_quotainfo->qi_iwarnlimit = newlim->d_iwarns; + if (newlim->d_fieldmask & FS_DQ_RTBWARNS) + mp->m_quotainfo->qi_rtbwarnlimit = newlim->d_rtbwarns; + } else { /* * If the user is now over quota, start the timelimit. * The user will not be 'warned'. -- cgit v1.2.3-59-g8ed1b From ad89d0212e32c5cf27dfcbad67b91a32b9878529 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Tue, 21 Jun 2005 15:57:57 +1000 Subject: [XFS] Remove some debugging code from quota syscalls. SGI-PV: 932952 SGI-Modid: xfs-linux-melb:xfs-kern:22929a Signed-off-by: Nathan Scott --- fs/xfs/quota/xfs_dquot.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 32ec7f4467d7..46ce1e3ce1d6 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c @@ -911,7 +911,6 @@ xfs_qm_dqget( if ((! XFS_IS_UQUOTA_ON(mp) && type == XFS_DQ_USER) || (! XFS_IS_PQUOTA_ON(mp) && type == XFS_DQ_PROJ) || (! XFS_IS_GQUOTA_ON(mp) && type == XFS_DQ_GROUP)) { -printk("XQM: ESRCH1\n"); return (ESRCH); } h = XFS_DQ_HASH(mp, id, type); @@ -989,7 +988,6 @@ printk("XQM: ESRCH1\n"); &dqp))) { if (ip) xfs_ilock(ip, XFS_ILOCK_EXCL); -if (error == ESRCH) printk("XQM: ESRCH2\n"); return (error); } @@ -1015,7 +1013,6 @@ if (error == ESRCH) printk("XQM: ESRCH2\n"); if (! XFS_IS_DQTYPE_ON(mp, type)) { /* inode stays locked on return */ xfs_qm_dqdestroy(dqp); -printk("XQM: ESRCH3\n"); return XFS_ERROR(ESRCH); } /* -- cgit v1.2.3-59-g8ed1b From 18b504e25fd617bee8830d2cdcaff7fb7b5931bb Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Tue, 21 Jun 2005 12:38:48 -0700 Subject: [NETLINK]: netlink_callback structure needs 5 args not 4 net/ipv4/tcp_diag.c uses up to ->args[4] Signed-off-by: David S. Miller --- include/linux/netlink.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 561d4dc75836..3029cad63a01 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -147,7 +147,7 @@ struct netlink_callback int (*dump)(struct sk_buff * skb, struct netlink_callback *cb); int (*done)(struct netlink_callback *cb); int family; - long args[4]; + long args[5]; }; struct netlink_notify -- cgit v1.2.3-59-g8ed1b From 19baf839ff4a8daa1f2a7400897094fc18e4f5e9 Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Tue, 21 Jun 2005 12:43:18 -0700 Subject: [IPV4]: Add LC-Trie FIB lookup algorithm. Signed-off-by: Robert Olsson Signed-off-by: David S. Miller --- net/ipv4/Kconfig | 26 + net/ipv4/Makefile | 4 +- net/ipv4/af_inet.c | 12 + net/ipv4/fib_trie.c | 2454 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 2495 insertions(+), 1 deletion(-) create mode 100644 net/ipv4/fib_trie.c diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 6d3e8b1bd1f2..05107e0dc145 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig @@ -1,6 +1,32 @@ # # IP configuration # +choice + prompt "Choose IP: FIB lookup"" + depends on INET + default IP_FIB_HASH + +config IP_FIB_HASH + bool "FIB_HASH" + ---help--- + Current FIB is very proven and good enough for most users. + +config IP_FIB_TRIE + bool "FIB_TRIE" + ---help--- + Use new experimental LC-trie as FIB lookup algoritm. + This improves lookup performance + + LC-trie is described in: + + IP-address lookup using LC-tries. Stefan Nilsson and Gunnar Karlsson + IEEE Journal on Selected Areas in Communications, 17(6):1083-1092, June 1999 + An experimental study of compression methods for dynamic tries + Stefan Nilsson and Matti Tikkanen. Algorithmica, 33(1):19-33, 2002. + http://www.nada.kth.se/~snilsson/public/papers/dyntrie2/ + +endchoice + config IP_MULTICAST bool "IP: multicasting" depends on INET diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile index 8b379627ebb6..65d57d8e1add 100644 --- a/net/ipv4/Makefile +++ b/net/ipv4/Makefile @@ -7,8 +7,10 @@ obj-y := utils.o route.o inetpeer.o protocol.o \ ip_output.o ip_sockglue.o \ tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o tcp_minisocks.o \ datagram.o raw.o udp.o arp.o icmp.o devinet.o af_inet.o igmp.o \ - sysctl_net_ipv4.o fib_frontend.o fib_semantics.o fib_hash.o + sysctl_net_ipv4.o fib_frontend.o fib_semantics.o +obj-$(CONFIG_IP_FIB_HASH) += fib_hash.o +obj-$(CONFIG_IP_FIB_TRIE) += fib_trie.o obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o obj-$(CONFIG_IP_MROUTE) += ipmr.o diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 03942f133944..658e7977924d 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1119,6 +1119,10 @@ module_init(inet_init); #ifdef CONFIG_PROC_FS extern int fib_proc_init(void); extern void fib_proc_exit(void); +#ifdef CONFIG_IP_FIB_TRIE +extern int fib_stat_proc_init(void); +extern void fib_stat_proc_exit(void); +#endif extern int ip_misc_proc_init(void); extern int raw_proc_init(void); extern void raw_proc_exit(void); @@ -1139,11 +1143,19 @@ static int __init ipv4_proc_init(void) goto out_udp; if (fib_proc_init()) goto out_fib; +#ifdef CONFIG_IP_FIB_TRIE + if (fib_stat_proc_init()) + goto out_fib_stat; + #endif if (ip_misc_proc_init()) goto out_misc; out: return rc; out_misc: +#ifdef CONFIG_IP_FIB_TRIE + fib_stat_proc_exit(); +out_fib_stat: +#endif fib_proc_exit(); out_fib: udp4_proc_exit(); diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c new file mode 100644 index 000000000000..c0ece94fc63e --- /dev/null +++ b/net/ipv4/fib_trie.c @@ -0,0 +1,2454 @@ +/* + * 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. + * + * Robert Olsson Uppsala Universitet + * & Swedish University of Agricultural Sciences. + * + * Jens Laas Swedish University of + * Agricultural Sciences. + * + * Hans Liss Uppsala Universitet + * + * This work is based on the LPC-trie which is originally descibed in: + * + * An experimental study of compression methods for dynamic tries + * Stefan Nilsson and Matti Tikkanen. Algorithmica, 33(1):19-33, 2002. + * http://www.nada.kth.se/~snilsson/public/papers/dyntrie2/ + * + * + * IP-address lookup using LC-tries. Stefan Nilsson and Gunnar Karlsson + * IEEE Journal on Selected Areas in Communications, 17(6):1083-1092, June 1999 + * + * Version: $Id: fib_trie.c,v 1.3 2005/06/08 14:20:01 robert Exp $ + * + * + * Code from fib_hash has been reused which includes the following header: + * + * + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * IPv4 FIB: lookup engine and maintenance routines. + * + * + * Authors: Alexey Kuznetsov, + * + * 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. + */ + +#define VERSION "0.323" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fib_lookup.h" + +#undef CONFIG_IP_FIB_TRIE_STATS +#define MAX_CHILDS 16384 + +#define EXTRACT(p, n, str) ((str)<<(p)>>(32-(n))) +#define KEYLENGTH (8*sizeof(t_key)) +#define MASK_PFX(k, l) (((l)==0)?0:(k >> (KEYLENGTH-l)) << (KEYLENGTH-l)) +#define TKEY_GET_MASK(offset, bits) (((bits)==0)?0:((t_key)(-1) << (KEYLENGTH - bits) >> offset)) + +static DEFINE_RWLOCK(fib_lock); + +typedef unsigned int t_key; + +#define T_TNODE 0 +#define T_LEAF 1 +#define NODE_TYPE_MASK 0x1UL +#define NODE_PARENT(_node) \ +((struct tnode *)((_node)->_parent & ~NODE_TYPE_MASK)) +#define NODE_SET_PARENT(_node, _ptr) \ +((_node)->_parent = (((unsigned long)(_ptr)) | \ + ((_node)->_parent & NODE_TYPE_MASK))) +#define NODE_INIT_PARENT(_node, _type) \ +((_node)->_parent = (_type)) +#define NODE_TYPE(_node) \ +((_node)->_parent & NODE_TYPE_MASK) + +#define IS_TNODE(n) (!(n->_parent & T_LEAF)) +#define IS_LEAF(n) (n->_parent & T_LEAF) + +struct node { + t_key key; + unsigned long _parent; +}; + +struct leaf { + t_key key; + unsigned long _parent; + struct hlist_head list; +}; + +struct leaf_info { + struct hlist_node hlist; + int plen; + struct list_head falh; +}; + +struct tnode { + t_key key; + unsigned long _parent; + unsigned short pos:5; /* 2log(KEYLENGTH) bits needed */ + unsigned short bits:5; /* 2log(KEYLENGTH) bits needed */ + unsigned short full_children; /* KEYLENGTH bits needed */ + unsigned short empty_children; /* KEYLENGTH bits needed */ + struct node *child[0]; +}; + +#ifdef CONFIG_IP_FIB_TRIE_STATS +struct trie_use_stats { + unsigned int gets; + unsigned int backtrack; + unsigned int semantic_match_passed; + unsigned int semantic_match_miss; + unsigned int null_node_hit; +}; +#endif + +struct trie_stat { + unsigned int totdepth; + unsigned int maxdepth; + unsigned int tnodes; + unsigned int leaves; + unsigned int nullpointers; + unsigned int nodesizes[MAX_CHILDS]; +}; + +struct trie { + struct node *trie; +#ifdef CONFIG_IP_FIB_TRIE_STATS + struct trie_use_stats stats; +#endif + int size; + unsigned int revision; +}; + +static int trie_debug = 0; + +static int tnode_full(struct tnode *tn, struct node *n); +static void put_child(struct trie *t, struct tnode *tn, int i, struct node *n); +static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int wasfull); +static int tnode_child_length(struct tnode *tn); +static struct node *resize(struct trie *t, struct tnode *tn); +static struct tnode *inflate(struct trie *t, struct tnode *tn); +static struct tnode *halve(struct trie *t, struct tnode *tn); +static void tnode_free(struct tnode *tn); +static void trie_dump_seq(struct seq_file *seq, struct trie *t); +extern struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio); +extern int fib_detect_death(struct fib_info *fi, int order, + struct fib_info **last_resort, int *last_idx, int *dflt); + +extern void rtmsg_fib(int event, u32 key, struct fib_alias *fa, int z, int tb_id, + struct nlmsghdr *n, struct netlink_skb_parms *req); + +static kmem_cache_t *fn_alias_kmem; +static struct trie *trie_local = NULL, *trie_main = NULL; + +static void trie_bug(char *err) +{ + printk("Trie Bug: %s\n", err); + BUG(); +} + +static inline struct node *tnode_get_child(struct tnode *tn, int i) +{ + if (i >= 1<bits) + trie_bug("tnode_get_child"); + + return tn->child[i]; +} + +static inline int tnode_child_length(struct tnode *tn) +{ + return 1<bits; +} + +/* + _________________________________________________________________ + | i | i | i | i | i | i | i | N | N | N | S | S | S | S | S | C | + ---------------------------------------------------------------- + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + + _________________________________________________________________ + | C | C | C | u | u | u | u | u | u | u | u | u | u | u | u | u | + ----------------------------------------------------------------- + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + + tp->pos = 7 + tp->bits = 3 + n->pos = 15 + n->bits=4 + KEYLENGTH=32 +*/ + +static inline t_key tkey_extract_bits(t_key a, int offset, int bits) +{ + if (offset < KEYLENGTH) + return ((t_key)(a << offset)) >> (KEYLENGTH - bits); + else + return 0; +} + +static inline int tkey_equals(t_key a, t_key b) +{ + return a == b; +} + +static inline int tkey_sub_equals(t_key a, int offset, int bits, t_key b) +{ + if (bits == 0 || offset >= KEYLENGTH) + return 1; + bits = bits > KEYLENGTH ? KEYLENGTH : bits; + return ((a ^ b) << offset) >> (KEYLENGTH - bits) == 0; +} + +static inline int tkey_mismatch(t_key a, int offset, t_key b) +{ + t_key diff = a ^ b; + int i = offset; + + if(!diff) + return 0; + while((diff << i) >> (KEYLENGTH-1) == 0) + i++; + return i; +} + +/* Candiate for fib_semantics */ + +static void fn_free_alias(struct fib_alias *fa) +{ + fib_release_info(fa->fa_info); + kmem_cache_free(fn_alias_kmem, fa); +} + +/* + To understand this stuff, an understanding of keys and all their bits is + necessary. Every node in the trie has a key associated with it, but not + all of the bits in that key are significant. + + Consider a node 'n' and its parent 'tp'. + + If n is a leaf, every bit in its key is significant. Its presence is + necessitaded by path compression, since during a tree traversal (when + searching for a leaf - unless we are doing an insertion) we will completely + ignore all skipped bits we encounter. Thus we need to verify, at the end of + a potentially successful search, that we have indeed been walking the + correct key path. + + Note that we can never "miss" the correct key in the tree if present by + following the wrong path. Path compression ensures that segments of the key + that are the same for all keys with a given prefix are skipped, but the + skipped part *is* identical for each node in the subtrie below the skipped + bit! trie_insert() in this implementation takes care of that - note the + call to tkey_sub_equals() in trie_insert(). + + if n is an internal node - a 'tnode' here, the various parts of its key + have many different meanings. + + Example: + _________________________________________________________________ + | i | i | i | i | i | i | i | N | N | N | S | S | S | S | S | C | + ----------------------------------------------------------------- + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + + _________________________________________________________________ + | C | C | C | u | u | u | u | u | u | u | u | u | u | u | u | u | + ----------------------------------------------------------------- + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + + tp->pos = 7 + tp->bits = 3 + n->pos = 15 + n->bits=4 + + First, let's just ignore the bits that come before the parent tp, that is + the bits from 0 to (tp->pos-1). They are *known* but at this point we do + not use them for anything. + + The bits from (tp->pos) to (tp->pos + tp->bits - 1) - "N", above - are the + index into the parent's child array. That is, they will be used to find + 'n' among tp's children. + + The bits from (tp->pos + tp->bits) to (n->pos - 1) - "S" - are skipped bits + for the node n. + + All the bits we have seen so far are significant to the node n. The rest + of the bits are really not needed or indeed known in n->key. + + The bits from (n->pos) to (n->pos + n->bits - 1) - "C" - are the index into + n's child array, and will of course be different for each child. + + The rest of the bits, from (n->pos + n->bits) onward, are completely unknown + at this point. + +*/ + +static void check_tnode(struct tnode *tn) +{ + if(tn && tn->pos+tn->bits > 32) { + printk("TNODE ERROR tn=%p, pos=%d, bits=%d\n", tn, tn->pos, tn->bits); + } +} + +static int halve_threshold = 25; +static int inflate_threshold = 50; + +static struct leaf *leaf_new(void) +{ + struct leaf *l = kmalloc(sizeof(struct leaf), GFP_KERNEL); + if(l) { + NODE_INIT_PARENT(l, T_LEAF); + INIT_HLIST_HEAD(&l->list); + } + return l; +} + +static struct leaf_info *leaf_info_new(int plen) +{ + struct leaf_info *li = kmalloc(sizeof(struct leaf_info), GFP_KERNEL); + li->plen = plen; + INIT_LIST_HEAD(&li->falh); + return li; +} + +static inline void free_leaf(struct leaf *l) +{ + kfree(l); +} + +static inline void free_leaf_info(struct leaf_info *li) +{ + kfree(li); +} + +static struct tnode* tnode_new(t_key key, int pos, int bits) +{ + int nchildren = 1<pos = pos; + tn->bits = bits; + tn->key = key; + tn->full_children = 0; + tn->empty_children = 1< 0) + printk("AT %p s=%u %u\n", tn, (unsigned int) sizeof(struct tnode), + (unsigned int) (sizeof(struct node) * 1< 0 ) + printk("FL %p \n", tn); + } + else if(IS_TNODE(tn)) { + kfree(tn); + if(trie_debug > 0 ) + printk("FT %p \n", tn); + } + else { + trie_bug("tnode_free\n"); + } +} + +/* + * Check whether a tnode 'n' is "full", i.e. it is an internal node + * and no bits are skipped. See discussion in dyntree paper p. 6 + */ + +static inline int tnode_full(struct tnode *tn, struct node *n) +{ + if(n == NULL || IS_LEAF(n)) + return 0; + + return ((struct tnode *) n)->pos == tn->pos + tn->bits; +} + +static inline void put_child(struct trie *t, struct tnode *tn, int i, struct node *n) +{ + tnode_put_child_reorg(tn, i, n, -1); +} + + /* + * Add a child at position i overwriting the old value. + * Update the value of full_children and empty_children. + */ + +static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int wasfull) +{ + struct node *chi; + int isfull; + + if(i >= 1<bits) { + printk("bits=%d, i=%d\n", tn->bits, i); + trie_bug("tnode_put_child_reorg bits"); + } + write_lock_bh(&fib_lock); + chi = tn->child[i]; + + /* update emptyChildren */ + if (n == NULL && chi != NULL) + tn->empty_children++; + else if (n != NULL && chi == NULL) + tn->empty_children--; + + /* update fullChildren */ + if (wasfull == -1) + wasfull = tnode_full(tn, chi); + + isfull = tnode_full(tn, n); + if (wasfull && !isfull) + tn->full_children--; + + else if (!wasfull && isfull) + tn->full_children++; + if(n) + NODE_SET_PARENT(n, tn); + + tn->child[i] = n; + write_unlock_bh(&fib_lock); +} + +static struct node *resize(struct trie *t, struct tnode *tn) +{ + int i; + + if (!tn) + return NULL; + + if(trie_debug) + printk("In tnode_resize %p inflate_threshold=%d threshold=%d\n", + tn, inflate_threshold, halve_threshold); + + /* No children */ + if (tn->empty_children == tnode_child_length(tn)) { + tnode_free(tn); + return NULL; + } + /* One child */ + if (tn->empty_children == tnode_child_length(tn) - 1) + for (i = 0; i < tnode_child_length(tn); i++) { + + write_lock_bh(&fib_lock); + if (tn->child[i] != NULL) { + + /* compress one level */ + struct node *n = tn->child[i]; + if(n) + NODE_INIT_PARENT(n, NODE_TYPE(n)); + + write_unlock_bh(&fib_lock); + tnode_free(tn); + return n; + } + write_unlock_bh(&fib_lock); + } + /* + * Double as long as the resulting node has a number of + * nonempty nodes that are above the threshold. + */ + + /* + * From "Implementing a dynamic compressed trie" by Stefan Nilsson of + * the Helsinki University of Technology and Matti Tikkanen of Nokia + * Telecommunications, page 6: + * "A node is doubled if the ratio of non-empty children to all + * children in the *doubled* node is at least 'high'." + * + * 'high' in this instance is the variable 'inflate_threshold'. It + * is expressed as a percentage, so we multiply it with + * tnode_child_length() and instead of multiplying by 2 (since the + * child array will be doubled by inflate()) and multiplying + * the left-hand side by 100 (to handle the percentage thing) we + * multiply the left-hand side by 50. + * + * The left-hand side may look a bit weird: tnode_child_length(tn) + * - tn->empty_children is of course the number of non-null children + * in the current node. tn->full_children is the number of "full" + * children, that is non-null tnodes with a skip value of 0. + * All of those will be doubled in the resulting inflated tnode, so + * we just count them one extra time here. + * + * A clearer way to write this would be: + * + * to_be_doubled = tn->full_children; + * not_to_be_doubled = tnode_child_length(tn) - tn->empty_children - + * tn->full_children; + * + * new_child_length = tnode_child_length(tn) * 2; + * + * new_fill_factor = 100 * (not_to_be_doubled + 2*to_be_doubled) / + * new_child_length; + * if (new_fill_factor >= inflate_threshold) + * + * ...and so on, tho it would mess up the while() loop. + * + * anyway, + * 100 * (not_to_be_doubled + 2*to_be_doubled) / new_child_length >= + * inflate_threshold + * + * avoid a division: + * 100 * (not_to_be_doubled + 2*to_be_doubled) >= + * inflate_threshold * new_child_length + * + * expand not_to_be_doubled and to_be_doubled, and shorten: + * 100 * (tnode_child_length(tn) - tn->empty_children + + * tn->full_children ) >= inflate_threshold * new_child_length + * + * expand new_child_length: + * 100 * (tnode_child_length(tn) - tn->empty_children + + * tn->full_children ) >= + * inflate_threshold * tnode_child_length(tn) * 2 + * + * shorten again: + * 50 * (tn->full_children + tnode_child_length(tn) - + * tn->empty_children ) >= inflate_threshold * + * tnode_child_length(tn) + * + */ + + check_tnode(tn); + + while ((tn->full_children > 0 && + 50 * (tn->full_children + tnode_child_length(tn) - tn->empty_children) >= + inflate_threshold * tnode_child_length(tn))) { + + tn = inflate(t, tn); + } + + check_tnode(tn); + + /* + * Halve as long as the number of empty children in this + * node is above threshold. + */ + while (tn->bits > 1 && + 100 * (tnode_child_length(tn) - tn->empty_children) < + halve_threshold * tnode_child_length(tn)) + + tn = halve(t, tn); + + /* Only one child remains */ + + if (tn->empty_children == tnode_child_length(tn) - 1) + for (i = 0; i < tnode_child_length(tn); i++) { + + write_lock_bh(&fib_lock); + if (tn->child[i] != NULL) { + /* compress one level */ + struct node *n = tn->child[i]; + + if(n) + NODE_INIT_PARENT(n, NODE_TYPE(n)); + + write_unlock_bh(&fib_lock); + tnode_free(tn); + return n; + } + write_unlock_bh(&fib_lock); + } + + return (struct node *) tn; +} + +static struct tnode *inflate(struct trie *t, struct tnode *tn) +{ + struct tnode *inode; + struct tnode *oldtnode = tn; + int olen = tnode_child_length(tn); + int i; + + if(trie_debug) + printk("In inflate\n"); + + tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits + 1); + + if (!tn) + trie_bug("tnode_new failed"); + + for(i = 0; i < olen; i++) { + struct node *node = tnode_get_child(oldtnode, i); + + /* An empty child */ + if (node == NULL) + continue; + + /* A leaf or an internal node with skipped bits */ + + if(IS_LEAF(node) || ((struct tnode *) node)->pos > + tn->pos + tn->bits - 1) { + if(tkey_extract_bits(node->key, tn->pos + tn->bits - 1, + 1) == 0) + put_child(t, tn, 2*i, node); + else + put_child(t, tn, 2*i+1, node); + continue; + } + + /* An internal node with two children */ + inode = (struct tnode *) node; + + if (inode->bits == 1) { + put_child(t, tn, 2*i, inode->child[0]); + put_child(t, tn, 2*i+1, inode->child[1]); + + tnode_free(inode); + } + + /* An internal node with more than two children */ + else { + struct tnode *left, *right; + int size, j; + + /* We will replace this node 'inode' with two new + * ones, 'left' and 'right', each with half of the + * original children. The two new nodes will have + * a position one bit further down the key and this + * means that the "significant" part of their keys + * (see the discussion near the top of this file) + * will differ by one bit, which will be "0" in + * left's key and "1" in right's key. Since we are + * moving the key position by one step, the bit that + * we are moving away from - the bit at position + * (inode->pos) - is the one that will differ between + * left and right. So... we synthesize that bit in the + * two new keys. + * The mask 'm' below will be a single "one" bit at + * the position (inode->pos) + */ + + t_key m = TKEY_GET_MASK(inode->pos, 1); + + /* Use the old key, but set the new significant + * bit to zero. + */ + left = tnode_new(inode->key&(~m), inode->pos + 1, + inode->bits - 1); + + if(!left) + trie_bug("tnode_new failed"); + + + /* Use the old key, but set the new significant + * bit to one. + */ + right = tnode_new(inode->key|m, inode->pos + 1, + inode->bits - 1); + + if(!right) + trie_bug("tnode_new failed"); + + size = tnode_child_length(left); + for(j = 0; j < size; j++) { + put_child(t, left, j, inode->child[j]); + put_child(t, right, j, inode->child[j + size]); + } + put_child(t, tn, 2*i, resize(t, left)); + put_child(t, tn, 2*i+1, resize(t, right)); + + tnode_free(inode); + } + } + tnode_free(oldtnode); + return tn; +} + +static struct tnode *halve(struct trie *t, struct tnode *tn) +{ + struct tnode *oldtnode = tn; + struct node *left, *right; + int i; + int olen = tnode_child_length(tn); + + if(trie_debug) printk("In halve\n"); + + tn=tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits - 1); + + if(!tn) + trie_bug("tnode_new failed"); + + for(i = 0; i < olen; i += 2) { + left = tnode_get_child(oldtnode, i); + right = tnode_get_child(oldtnode, i+1); + + /* At least one of the children is empty */ + if (left == NULL) { + if (right == NULL) /* Both are empty */ + continue; + put_child(t, tn, i/2, right); + } else if (right == NULL) + put_child(t, tn, i/2, left); + + /* Two nonempty children */ + else { + struct tnode *newBinNode = + tnode_new(left->key, tn->pos + tn->bits, 1); + + if(!newBinNode) + trie_bug("tnode_new failed"); + + put_child(t, newBinNode, 0, left); + put_child(t, newBinNode, 1, right); + put_child(t, tn, i/2, resize(t, newBinNode)); + } + } + tnode_free(oldtnode); + return tn; +} + +static void *trie_init(struct trie *t) +{ + if(t) { + t->size = 0; + t->trie = NULL; + t->revision = 0; +#ifdef CONFIG_IP_FIB_TRIE_STATS + memset(&t->stats, 0, sizeof(struct trie_use_stats)); +#endif + } + return t; +} + +static struct leaf_info *find_leaf_info(struct hlist_head *head, int plen) +{ + struct hlist_node *node; + struct leaf_info *li; + + hlist_for_each_entry(li, node, head, hlist) { + + if ( li->plen == plen ) + return li; + } + return NULL; +} + +static inline struct list_head * get_fa_head(struct leaf *l, int plen) +{ + struct list_head *fa_head=NULL; + struct leaf_info *li = find_leaf_info(&l->list, plen); + + if(li) + fa_head = &li->falh; + + return fa_head; +} + +static void insert_leaf_info(struct hlist_head *head, struct leaf_info *new) +{ + struct leaf_info *li=NULL, *last=NULL; + struct hlist_node *node, *tmp; + + write_lock_bh(&fib_lock); + + if(hlist_empty(head)) + hlist_add_head(&new->hlist, head); + else { + hlist_for_each_entry_safe(li, node, tmp, head, hlist) { + + if (new->plen > li->plen) + break; + + last = li; + } + if(last) + hlist_add_after(&last->hlist, &new->hlist); + else + hlist_add_before(&new->hlist, &li->hlist); + } + write_unlock_bh(&fib_lock); +} + +static struct leaf * +fib_find_node(struct trie *t, u32 key) +{ + int pos; + struct tnode *tn; + struct node *n; + + pos = 0; + n=t->trie; + + while (n != NULL && NODE_TYPE(n) == T_TNODE) { + tn = (struct tnode *) n; + + check_tnode(tn); + + if(tkey_sub_equals(tn->key, pos, tn->pos-pos, key)) { + pos=tn->pos + tn->bits; + n = tnode_get_child(tn, tkey_extract_bits(key, tn->pos, tn->bits)); + } + else + break; + } + /* Case we have found a leaf. Compare prefixes */ + + if (n != NULL && IS_LEAF(n) && tkey_equals(key, n->key)) { + struct leaf *l = (struct leaf *) n; + return l; + } + return NULL; +} + +static struct node *trie_rebalance(struct trie *t, struct tnode *tn) +{ + int i = 0; + int wasfull; + t_key cindex, key; + struct tnode *tp = NULL; + + if(!tn) + BUG(); + + key = tn->key; + i = 0; + + while (tn != NULL && NODE_PARENT(tn) != NULL) { + + if( i > 10 ) { + printk("Rebalance tn=%p \n", tn); + if(tn) printk("tn->parent=%p \n", NODE_PARENT(tn)); + + printk("Rebalance tp=%p \n", tp); + if(tp) printk("tp->parent=%p \n", NODE_PARENT(tp)); + } + + if( i > 12 ) BUG(); + i++; + + tp = NODE_PARENT(tn); + cindex = tkey_extract_bits(key, tp->pos, tp->bits); + wasfull = tnode_full(tp, tnode_get_child(tp, cindex)); + tn = (struct tnode *) resize (t, (struct tnode *)tn); + tnode_put_child_reorg((struct tnode *)tp, cindex,(struct node*)tn, wasfull); + + if(!NODE_PARENT(tn)) + break; + + tn = NODE_PARENT(tn); + } + /* Handle last (top) tnode */ + if (IS_TNODE(tn)) + tn = (struct tnode*) resize(t, (struct tnode *)tn); + + return (struct node*) tn; +} + +static struct list_head * +fib_insert_node(struct trie *t, u32 key, int plen) +{ + int pos, newpos; + struct tnode *tp = NULL, *tn = NULL; + struct node *n; + struct leaf *l; + int missbit; + struct list_head *fa_head=NULL; + struct leaf_info *li; + t_key cindex; + + pos = 0; + n=t->trie; + + /* If we point to NULL, stop. Either the tree is empty and we should + * just put a new leaf in if, or we have reached an empty child slot, + * and we should just put our new leaf in that. + * If we point to a T_TNODE, check if it matches our key. Note that + * a T_TNODE might be skipping any number of bits - its 'pos' need + * not be the parent's 'pos'+'bits'! + * + * If it does match the current key, get pos/bits from it, extract + * the index from our key, push the T_TNODE and walk the tree. + * + * If it doesn't, we have to replace it with a new T_TNODE. + * + * If we point to a T_LEAF, it might or might not have the same key + * as we do. If it does, just change the value, update the T_LEAF's + * value, and return it. + * If it doesn't, we need to replace it with a T_TNODE. + */ + + while (n != NULL && NODE_TYPE(n) == T_TNODE) { + tn = (struct tnode *) n; + + check_tnode(tn); + + if(tkey_sub_equals(tn->key, pos, tn->pos-pos, key)) { + tp = tn; + pos=tn->pos + tn->bits; + n = tnode_get_child(tn, tkey_extract_bits(key, tn->pos, tn->bits)); + + if(n && NODE_PARENT(n) != tn) { + printk("BUG tn=%p, n->parent=%p\n", tn, NODE_PARENT(n)); + BUG(); + } + } + else + break; + } + + /* + * n ----> NULL, LEAF or TNODE + * + * tp is n's (parent) ----> NULL or TNODE + */ + + if(tp && IS_LEAF(tp)) + BUG(); + + t->revision++; + + /* Case 1: n is a leaf. Compare prefixes */ + + if (n != NULL && IS_LEAF(n) && tkey_equals(key, n->key)) { + struct leaf *l = ( struct leaf *) n; + + li = leaf_info_new(plen); + + if(! li) + BUG(); + + fa_head = &li->falh; + insert_leaf_info(&l->list, li); + goto done; + } + t->size++; + l = leaf_new(); + + if(! l) + BUG(); + + l->key = key; + li = leaf_info_new(plen); + + if(! li) + BUG(); + + fa_head = &li->falh; + insert_leaf_info(&l->list, li); + + /* Case 2: n is NULL, and will just insert a new leaf */ + if (t->trie && n == NULL) { + + NODE_SET_PARENT(l, tp); + + if (!tp) + BUG(); + + else { + cindex = tkey_extract_bits(key, tp->pos, tp->bits); + put_child(t, (struct tnode *)tp, cindex, (struct node *)l); + } + } + /* Case 3: n is a LEAF or a TNODE and the key doesn't match. */ + else { + /* + * Add a new tnode here + * first tnode need some special handling + */ + + if (tp) + pos=tp->pos+tp->bits; + else + pos=0; + if(n) { + newpos = tkey_mismatch(key, pos, n->key); + tn = tnode_new(n->key, newpos, 1); + } + else { + newpos = 0; + tn = tnode_new(key, newpos, 1); /* First tnode */ + } + if(!tn) + trie_bug("tnode_pfx_new failed"); + + NODE_SET_PARENT(tn, tp); + + missbit=tkey_extract_bits(key, newpos, 1); + put_child(t, tn, missbit, (struct node *)l); + put_child(t, tn, 1-missbit, n); + + if(tp) { + cindex = tkey_extract_bits(key, tp->pos, tp->bits); + put_child(t, (struct tnode *)tp, cindex, (struct node *)tn); + } + else { + t->trie = (struct node*) tn; /* First tnode */ + tp = tn; + } + } + if(tp && tp->pos+tp->bits > 32) { + printk("ERROR tp=%p pos=%d, bits=%d, key=%0x plen=%d\n", + tp, tp->pos, tp->bits, key, plen); + } + /* Rebalance the trie */ + t->trie = trie_rebalance(t, tp); +done:; + return fa_head; +} + +static int +fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, + struct nlmsghdr *nlhdr, struct netlink_skb_parms *req) +{ + struct trie *t = (struct trie *) tb->tb_data; + struct fib_alias *fa, *new_fa; + struct list_head *fa_head=NULL; + struct fib_info *fi; + int plen = r->rtm_dst_len; + int type = r->rtm_type; + u8 tos = r->rtm_tos; + u32 key, mask; + int err; + struct leaf *l; + + if (plen > 32) + return -EINVAL; + + key = 0; + if (rta->rta_dst) + memcpy(&key, rta->rta_dst, 4); + + key = ntohl(key); + + if(trie_debug) + printk("Insert table=%d %08x/%d\n", tb->tb_id, key, plen); + + mask = ntohl( inet_make_mask(plen) ); + + if(key & ~mask) + return -EINVAL; + + key = key & mask; + + if ((fi = fib_create_info(r, rta, nlhdr, &err)) == NULL) + goto err; + + l = fib_find_node(t, key); + fa = NULL; + + if(l) { + fa_head = get_fa_head(l, plen); + fa = fib_find_alias(fa_head, tos, fi->fib_priority); + } + + /* Now fa, if non-NULL, points to the first fib alias + * with the same keys [prefix,tos,priority], if such key already + * exists or to the node before which we will insert new one. + * + * If fa is NULL, we will need to allocate a new one and + * insert to the head of f. + * + * If f is NULL, no fib node matched the destination key + * and we need to allocate a new one of those as well. + */ + + if (fa && + fa->fa_info->fib_priority == fi->fib_priority) { + struct fib_alias *fa_orig; + + err = -EEXIST; + if (nlhdr->nlmsg_flags & NLM_F_EXCL) + goto out; + + if (nlhdr->nlmsg_flags & NLM_F_REPLACE) { + struct fib_info *fi_drop; + u8 state; + + write_lock_bh(&fib_lock); + + fi_drop = fa->fa_info; + fa->fa_info = fi; + fa->fa_type = type; + fa->fa_scope = r->rtm_scope; + state = fa->fa_state; + fa->fa_state &= ~FA_S_ACCESSED; + + write_unlock_bh(&fib_lock); + + fib_release_info(fi_drop); + if (state & FA_S_ACCESSED) + rt_cache_flush(-1); + + goto succeeded; + } + /* Error if we find a perfect match which + * uses the same scope, type, and nexthop + * information. + */ + fa_orig = fa; + list_for_each_entry(fa, fa_orig->fa_list.prev, fa_list) { + if (fa->fa_tos != tos) + break; + if (fa->fa_info->fib_priority != fi->fib_priority) + break; + if (fa->fa_type == type && + fa->fa_scope == r->rtm_scope && + fa->fa_info == fi) { + goto out; + } + } + if (!(nlhdr->nlmsg_flags & NLM_F_APPEND)) + fa = fa_orig; + } + err = -ENOENT; + if (!(nlhdr->nlmsg_flags&NLM_F_CREATE)) + goto out; + + err = -ENOBUFS; + new_fa = kmem_cache_alloc(fn_alias_kmem, SLAB_KERNEL); + if (new_fa == NULL) + goto out; + + new_fa->fa_info = fi; + new_fa->fa_tos = tos; + new_fa->fa_type = type; + new_fa->fa_scope = r->rtm_scope; + new_fa->fa_state = 0; +#if 0 + new_fa->dst = NULL; +#endif + /* + * Insert new entry to the list. + */ + + if(!fa_head) + fa_head = fib_insert_node(t, key, plen); + + write_lock_bh(&fib_lock); + + list_add_tail(&new_fa->fa_list, + (fa ? &fa->fa_list : fa_head)); + + write_unlock_bh(&fib_lock); + + rt_cache_flush(-1); + rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, nlhdr, req); +succeeded: + return 0; +out: + fib_release_info(fi); +err:; + return err; +} + +static inline int check_leaf(struct trie *t, struct leaf *l, t_key key, int *plen, const struct flowi *flp, + struct fib_result *res, int *err) +{ + int i; + t_key mask; + struct leaf_info *li; + struct hlist_head *hhead = &l->list; + struct hlist_node *node; + + hlist_for_each_entry(li, node, hhead, hlist) { + + i = li->plen; + mask = ntohl(inet_make_mask(i)); + if (l->key != (key & mask)) + continue; + + if (((*err) = fib_semantic_match(&li->falh, flp, res, l->key, mask, i)) == 0) { + *plen = i; +#ifdef CONFIG_IP_FIB_TRIE_STATS + t->stats.semantic_match_passed++; +#endif + return 1; + } +#ifdef CONFIG_IP_FIB_TRIE_STATS + t->stats.semantic_match_miss++; +#endif + } + return 0; +} + +static int +fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result *res) +{ + struct trie *t = (struct trie *) tb->tb_data; + int plen, ret = 0; + struct node *n; + struct tnode *pn; + int pos, bits; + t_key key=ntohl(flp->fl4_dst); + int chopped_off; + t_key cindex = 0; + int current_prefix_length = KEYLENGTH; + n = t->trie; + + read_lock(&fib_lock); + if(!n) + goto failed; + +#ifdef CONFIG_IP_FIB_TRIE_STATS + t->stats.gets++; +#endif + + /* Just a leaf? */ + if (IS_LEAF(n)) { + if( check_leaf(t, (struct leaf *)n, key, &plen, flp, res, &ret) ) + goto found; + goto failed; + } + pn = (struct tnode *) n; + chopped_off = 0; + + while (pn) { + + pos = pn->pos; + bits = pn->bits; + + if(!chopped_off) + cindex = tkey_extract_bits(MASK_PFX(key, current_prefix_length), pos, bits); + + n = tnode_get_child(pn, cindex); + + if (n == NULL) { +#ifdef CONFIG_IP_FIB_TRIE_STATS + t->stats.null_node_hit++; +#endif + goto backtrace; + } + + if (IS_TNODE(n)) { +#define HL_OPTIMIZE +#ifdef HL_OPTIMIZE + struct tnode *cn = (struct tnode *)n; + t_key node_prefix, key_prefix, pref_mismatch; + int mp; + + /* + * It's a tnode, and we can do some extra checks here if we + * like, to avoid descending into a dead-end branch. + * This tnode is in the parent's child array at index + * key[p_pos..p_pos+p_bits] but potentially with some bits + * chopped off, so in reality the index may be just a + * subprefix, padded with zero at the end. + * We can also take a look at any skipped bits in this + * tnode - everything up to p_pos is supposed to be ok, + * and the non-chopped bits of the index (se previous + * paragraph) are also guaranteed ok, but the rest is + * considered unknown. + * + * The skipped bits are key[pos+bits..cn->pos]. + */ + + /* If current_prefix_length < pos+bits, we are already doing + * actual prefix matching, which means everything from + * pos+(bits-chopped_off) onward must be zero along some + * branch of this subtree - otherwise there is *no* valid + * prefix present. Here we can only check the skipped + * bits. Remember, since we have already indexed into the + * parent's child array, we know that the bits we chopped of + * *are* zero. + */ + + /* NOTA BENE: CHECKING ONLY SKIPPED BITS FOR THE NEW NODE HERE */ + + if (current_prefix_length < pos+bits) { + if (tkey_extract_bits(cn->key, current_prefix_length, + cn->pos - current_prefix_length) != 0 || + !(cn->child[0])) + goto backtrace; + } + + /* + * If chopped_off=0, the index is fully validated and we + * only need to look at the skipped bits for this, the new, + * tnode. What we actually want to do is to find out if + * these skipped bits match our key perfectly, or if we will + * have to count on finding a matching prefix further down, + * because if we do, we would like to have some way of + * verifying the existence of such a prefix at this point. + */ + + /* The only thing we can do at this point is to verify that + * any such matching prefix can indeed be a prefix to our + * key, and if the bits in the node we are inspecting that + * do not match our key are not ZERO, this cannot be true. + * Thus, find out where there is a mismatch (before cn->pos) + * and verify that all the mismatching bits are zero in the + * new tnode's key. + */ + + /* Note: We aren't very concerned about the piece of the key + * that precede pn->pos+pn->bits, since these have already been + * checked. The bits after cn->pos aren't checked since these are + * by definition "unknown" at this point. Thus, what we want to + * see is if we are about to enter the "prefix matching" state, + * and in that case verify that the skipped bits that will prevail + * throughout this subtree are zero, as they have to be if we are + * to find a matching prefix. + */ + + node_prefix = MASK_PFX(cn->key, cn->pos); + key_prefix = MASK_PFX(key, cn->pos); + pref_mismatch = key_prefix^node_prefix; + mp = 0; + + /* In short: If skipped bits in this node do not match the search + * key, enter the "prefix matching" state.directly. + */ + if (pref_mismatch) { + while (!(pref_mismatch & (1<<(KEYLENGTH-1)))) { + mp++; + pref_mismatch = pref_mismatch <<1; + } + key_prefix = tkey_extract_bits(cn->key, mp, cn->pos-mp); + + if (key_prefix != 0) + goto backtrace; + + if (current_prefix_length >= cn->pos) + current_prefix_length=mp; + } +#endif + pn = (struct tnode *)n; /* Descend */ + chopped_off = 0; + continue; + } + if (IS_LEAF(n)) { + if( check_leaf(t, (struct leaf *)n, key, &plen, flp, res, &ret)) + goto found; + } +backtrace: + chopped_off++; + + /* As zero don't change the child key (cindex) */ + while ((chopped_off <= pn->bits) && !(cindex & (1<<(chopped_off-1)))) { + chopped_off++; + } + + /* Decrease current_... with bits chopped off */ + if (current_prefix_length > pn->pos + pn->bits - chopped_off) + current_prefix_length = pn->pos + pn->bits - chopped_off; + + /* + * Either we do the actual chop off according or if we have + * chopped off all bits in this tnode walk up to our parent. + */ + + if(chopped_off <= pn->bits) + cindex &= ~(1 << (chopped_off-1)); + else { + if( NODE_PARENT(pn) == NULL) + goto failed; + + /* Get Child's index */ + cindex = tkey_extract_bits(pn->key, NODE_PARENT(pn)->pos, NODE_PARENT(pn)->bits); + pn = NODE_PARENT(pn); + chopped_off = 0; + +#ifdef CONFIG_IP_FIB_TRIE_STATS + t->stats.backtrack++; +#endif + goto backtrace; + } + } +failed: + ret = 1; +found: + read_unlock(&fib_lock); + return ret; +} + +static int trie_leaf_remove(struct trie *t, t_key key) +{ + t_key cindex; + struct tnode *tp = NULL; + struct node *n = t->trie; + struct leaf *l; + + if(trie_debug) + printk("entering trie_leaf_remove(%p)\n", n); + + /* Note that in the case skipped bits, those bits are *not* checked! + * When we finish this, we will have NULL or a T_LEAF, and the + * T_LEAF may or may not match our key. + */ + + while (n != NULL && IS_TNODE(n)) { + struct tnode *tn = (struct tnode *) n; + check_tnode(tn); + n = tnode_get_child(tn ,tkey_extract_bits(key, tn->pos, tn->bits)); + + if(n && NODE_PARENT(n) != tn) { + printk("BUG tn=%p, n->parent=%p\n", tn, NODE_PARENT(n)); + BUG(); + } + } + l = (struct leaf *) n; + + if(!n || !tkey_equals(l->key, key)) + return 0; + + /* + * Key found. + * Remove the leaf and rebalance the tree + */ + + t->revision++; + t->size--; + + tp = NODE_PARENT(n); + tnode_free((struct tnode *) n); + + if(tp) { + cindex = tkey_extract_bits(key, tp->pos, tp->bits); + put_child(t, (struct tnode *)tp, cindex, NULL); + t->trie = trie_rebalance(t, tp); + } + else + t->trie = NULL; + + return 1; +} + +static int +fn_trie_delete(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, + struct nlmsghdr *nlhdr, struct netlink_skb_parms *req) +{ + struct trie *t = (struct trie *) tb->tb_data; + u32 key, mask; + int plen = r->rtm_dst_len; + u8 tos = r->rtm_tos; + struct fib_alias *fa, *fa_to_delete; + struct list_head *fa_head; + struct leaf *l; + + if (plen > 32) + return -EINVAL; + + key = 0; + if (rta->rta_dst) + memcpy(&key, rta->rta_dst, 4); + + key = ntohl(key); + mask = ntohl( inet_make_mask(plen) ); + + if(key & ~mask) + return -EINVAL; + + key = key & mask; + l = fib_find_node(t, key); + + if(!l) + return -ESRCH; + + fa_head = get_fa_head(l, plen); + fa = fib_find_alias(fa_head, tos, 0); + + if (!fa) + return -ESRCH; + + if (trie_debug) + printk("Deleting %08x/%d tos=%d t=%p\n", key, plen, tos, t); + + fa_to_delete = NULL; + fa_head = fa->fa_list.prev; + list_for_each_entry(fa, fa_head, fa_list) { + struct fib_info *fi = fa->fa_info; + + if (fa->fa_tos != tos) + break; + + if ((!r->rtm_type || + fa->fa_type == r->rtm_type) && + (r->rtm_scope == RT_SCOPE_NOWHERE || + fa->fa_scope == r->rtm_scope) && + (!r->rtm_protocol || + fi->fib_protocol == r->rtm_protocol) && + fib_nh_match(r, nlhdr, rta, fi) == 0) { + fa_to_delete = fa; + break; + } + } + + if (fa_to_delete) { + int kill_li = 0; + struct leaf_info *li; + + fa = fa_to_delete; + rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id, nlhdr, req); + + l = fib_find_node(t, key); + li = find_leaf_info(&l->list, plen); + + write_lock_bh(&fib_lock); + + list_del(&fa->fa_list); + + if(list_empty(fa_head)) { + hlist_del(&li->hlist); + kill_li = 1; + } + write_unlock_bh(&fib_lock); + + if(kill_li) + free_leaf_info(li); + + if(hlist_empty(&l->list)) + trie_leaf_remove(t, key); + + if (fa->fa_state & FA_S_ACCESSED) + rt_cache_flush(-1); + + fn_free_alias(fa); + return 0; + } + return -ESRCH; +} + +static int trie_flush_list(struct trie *t, struct list_head *head) +{ + struct fib_alias *fa, *fa_node; + int found = 0; + + list_for_each_entry_safe(fa, fa_node, head, fa_list) { + struct fib_info *fi = fa->fa_info; + + if (fi && (fi->fib_flags&RTNH_F_DEAD)) { + + write_lock_bh(&fib_lock); + list_del(&fa->fa_list); + write_unlock_bh(&fib_lock); + + fn_free_alias(fa); + found++; + } + } + return found; +} + +static int trie_flush_leaf(struct trie *t, struct leaf *l) +{ + int found = 0; + struct hlist_head *lih = &l->list; + struct hlist_node *node, *tmp; + struct leaf_info *li = NULL; + + hlist_for_each_entry_safe(li, node, tmp, lih, hlist) { + + found += trie_flush_list(t, &li->falh); + + if (list_empty(&li->falh)) { + + write_lock_bh(&fib_lock); + hlist_del(&li->hlist); + write_unlock_bh(&fib_lock); + + free_leaf_info(li); + } + } + return found; +} + +static struct leaf *nextleaf(struct trie *t, struct leaf *thisleaf) +{ + struct node *c = (struct node *) thisleaf; + struct tnode *p; + int idx; + + if(c == NULL) { + if(t->trie == NULL) + return NULL; + + if (IS_LEAF(t->trie)) /* trie w. just a leaf */ + return (struct leaf *) t->trie; + + p = (struct tnode*) t->trie; /* Start */ + } + else + p = (struct tnode *) NODE_PARENT(c); + while (p) { + int pos, last; + + /* Find the next child of the parent */ + if(c) + pos = 1 + tkey_extract_bits(c->key, p->pos, p->bits); + else + pos = 0; + + last = 1 << p->bits; + for(idx = pos; idx < last ; idx++) { + if( p->child[idx]) { + + /* Decend if tnode */ + + while (IS_TNODE(p->child[idx])) { + p = (struct tnode*) p->child[idx]; + idx = 0; + + /* Rightmost non-NULL branch */ + if( p && IS_TNODE(p) ) + while ( p->child[idx] == NULL && idx < (1 << p->bits) ) idx++; + + /* Done with this tnode? */ + if( idx >= (1 << p->bits) || p->child[idx] == NULL ) + goto up; + } + return (struct leaf*) p->child[idx]; + } + } +up: + /* No more children go up one step */ + c = (struct node*) p; + p = (struct tnode *) NODE_PARENT(p); + } + return NULL; /* Ready. Root of trie */ +} + +static int fn_trie_flush(struct fib_table *tb) +{ + struct trie *t = (struct trie *) tb->tb_data; + struct leaf *ll = NULL, *l = NULL; + int found = 0, h; + + t->revision++; + + for (h=0; (l = nextleaf(t, l)) != NULL; h++) { + found += trie_flush_leaf(t, l); + + if (ll && hlist_empty(&ll->list)) + trie_leaf_remove(t, ll->key); + ll = l; + } + + if (ll && hlist_empty(&ll->list)) + trie_leaf_remove(t, ll->key); + + if(trie_debug) + printk("trie_flush found=%d\n", found); + return found; +} + +static int trie_last_dflt=-1; + +static void +fn_trie_select_default(struct fib_table *tb, const struct flowi *flp, struct fib_result *res) +{ + struct trie *t = (struct trie *) tb->tb_data; + int order, last_idx; + struct fib_info *fi = NULL; + struct fib_info *last_resort; + struct fib_alias *fa = NULL; + struct list_head *fa_head; + struct leaf *l; + + last_idx = -1; + last_resort = NULL; + order = -1; + + read_lock(&fib_lock); + + l = fib_find_node(t, 0); + if(!l) + goto out; + + fa_head = get_fa_head(l, 0); + if(!fa_head) + goto out; + + if (list_empty(fa_head)) + goto out; + + list_for_each_entry(fa, fa_head, fa_list) { + struct fib_info *next_fi = fa->fa_info; + + if (fa->fa_scope != res->scope || + fa->fa_type != RTN_UNICAST) + continue; + + if (next_fi->fib_priority > res->fi->fib_priority) + break; + if (!next_fi->fib_nh[0].nh_gw || + next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK) + continue; + fa->fa_state |= FA_S_ACCESSED; + + if (fi == NULL) { + if (next_fi != res->fi) + break; + } else if (!fib_detect_death(fi, order, &last_resort, + &last_idx, &trie_last_dflt)) { + if (res->fi) + fib_info_put(res->fi); + res->fi = fi; + atomic_inc(&fi->fib_clntref); + trie_last_dflt = order; + goto out; + } + fi = next_fi; + order++; + } + if (order <= 0 || fi == NULL) { + trie_last_dflt = -1; + goto out; + } + + if (!fib_detect_death(fi, order, &last_resort, &last_idx, &trie_last_dflt)) { + if (res->fi) + fib_info_put(res->fi); + res->fi = fi; + atomic_inc(&fi->fib_clntref); + trie_last_dflt = order; + goto out; + } + if (last_idx >= 0) { + if (res->fi) + fib_info_put(res->fi); + res->fi = last_resort; + if (last_resort) + atomic_inc(&last_resort->fib_clntref); + } + trie_last_dflt = last_idx; + out:; + read_unlock(&fib_lock); +} + +static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, struct fib_table *tb, + struct sk_buff *skb, struct netlink_callback *cb) +{ + int i, s_i; + struct fib_alias *fa; + + u32 xkey=htonl(key); + + s_i=cb->args[3]; + i = 0; + + list_for_each_entry(fa, fah, fa_list) { + if (i < s_i) { + i++; + continue; + } + if (fa->fa_info->fib_nh == NULL) { + printk("Trie error _fib_nh=NULL in fa[%d] k=%08x plen=%d\n", i, key, plen); + i++; + continue; + } + if (fa->fa_info == NULL) { + printk("Trie error fa_info=NULL in fa[%d] k=%08x plen=%d\n", i, key, plen); + i++; + continue; + } + + if (fib_dump_info(skb, NETLINK_CB(cb->skb).pid, + cb->nlh->nlmsg_seq, + RTM_NEWROUTE, + tb->tb_id, + fa->fa_type, + fa->fa_scope, + &xkey, + plen, + fa->fa_tos, + fa->fa_info) < 0) { + cb->args[3] = i; + return -1; + } + i++; + } + cb->args[3]=i; + return skb->len; +} + +static int fn_trie_dump_plen(struct trie *t, int plen, struct fib_table *tb, struct sk_buff *skb, + struct netlink_callback *cb) +{ + int h, s_h; + struct list_head *fa_head; + struct leaf *l = NULL; + s_h=cb->args[2]; + + for (h=0; (l = nextleaf(t, l)) != NULL; h++) { + + if (h < s_h) + continue; + if (h > s_h) + memset(&cb->args[3], 0, + sizeof(cb->args) - 3*sizeof(cb->args[0])); + + fa_head = get_fa_head(l, plen); + + if(!fa_head) + continue; + + if(list_empty(fa_head)) + continue; + + if (fn_trie_dump_fa(l->key, plen, fa_head, tb, skb, cb)<0) { + cb->args[2]=h; + return -1; + } + } + cb->args[2]=h; + return skb->len; +} + +static int fn_trie_dump(struct fib_table *tb, struct sk_buff *skb, struct netlink_callback *cb) +{ + int m, s_m; + struct trie *t = (struct trie *) tb->tb_data; + + s_m = cb->args[1]; + + read_lock(&fib_lock); + for (m=0; m<=32; m++) { + + if (m < s_m) + continue; + if (m > s_m) + memset(&cb->args[2], 0, + sizeof(cb->args) - 2*sizeof(cb->args[0])); + + if (fn_trie_dump_plen(t, 32-m, tb, skb, cb)<0) { + cb->args[1] = m; + goto out; + } + } + read_unlock(&fib_lock); + cb->args[1] = m; + return skb->len; + out: + read_unlock(&fib_lock); + return -1; +} + +/* Fix more generic FIB names for init later */ + +#ifdef CONFIG_IP_MULTIPLE_TABLES +struct fib_table * fib_hash_init(int id) +#else +struct fib_table * __init fib_hash_init(int id) +#endif +{ + struct fib_table *tb; + struct trie *t; + + if (fn_alias_kmem == NULL) + fn_alias_kmem = kmem_cache_create("ip_fib_alias", + sizeof(struct fib_alias), + 0, SLAB_HWCACHE_ALIGN, + NULL, NULL); + + tb = kmalloc(sizeof(struct fib_table) + sizeof(struct trie), + GFP_KERNEL); + if (tb == NULL) + return NULL; + + tb->tb_id = id; + tb->tb_lookup = fn_trie_lookup; + tb->tb_insert = fn_trie_insert; + tb->tb_delete = fn_trie_delete; + tb->tb_flush = fn_trie_flush; + tb->tb_select_default = fn_trie_select_default; + tb->tb_dump = fn_trie_dump; + memset(tb->tb_data, 0, sizeof(struct trie)); + + t = (struct trie *) tb->tb_data; + + trie_init(t); + + if (id == RT_TABLE_LOCAL) + trie_local=t; + else if (id == RT_TABLE_MAIN) + trie_main=t; + + if (id == RT_TABLE_LOCAL) + printk("IPv4 FIB: Using LC-trie version %s\n", VERSION); + + return tb; +} + +/* Trie dump functions */ + +static void putspace_seq(struct seq_file *seq, int n) +{ + while (n--) seq_printf(seq, " "); +} + +static void printbin_seq(struct seq_file *seq, unsigned int v, int bits) +{ + while (bits--) + seq_printf(seq, "%s", (v & (1<: "); + seq_printf(seq, "%s:%p ", IS_LEAF(n)?"Leaf":"Internal node", n); + + if (IS_LEAF(n)) + seq_printf(seq, "key=%d.%d.%d.%d\n", + n->key >> 24, (n->key >> 16) % 256, (n->key >> 8) % 256, n->key % 256); + else { + int plen=((struct tnode *)n)->pos; + t_key prf=MASK_PFX(n->key, plen); + seq_printf(seq, "key=%d.%d.%d.%d/%d\n", + prf >> 24, (prf >> 16) % 256, (prf >> 8) % 256, prf % 256, plen); + } + if (IS_LEAF(n)) { + struct leaf *l=(struct leaf *)n; + struct fib_alias *fa; + int i; + for (i=32; i>=0; i--) + if(find_leaf_info(&l->list, i)) { + + struct list_head *fa_head = get_fa_head(l, i); + + if(!fa_head) + continue; + + if(list_empty(fa_head)) + continue; + + putspace_seq(seq, indent+2); + seq_printf(seq, "{/%d...dumping}\n", i); + + + list_for_each_entry(fa, fa_head, fa_list) { + putspace_seq(seq, indent+2); + if (fa->fa_info->fib_nh == NULL) { + seq_printf(seq, "Error _fib_nh=NULL\n"); + continue; + } + if (fa->fa_info == NULL) { + seq_printf(seq, "Error fa_info=NULL\n"); + continue; + } + + seq_printf(seq, "{type=%d scope=%d TOS=%d}\n", + fa->fa_type, + fa->fa_scope, + fa->fa_tos); + } + } + } + else if (IS_TNODE(n)) { + struct tnode *tn=(struct tnode *)n; + putspace_seq(seq, indent); seq_printf(seq, "| "); + seq_printf(seq, "{key prefix=%08x/", tn->key&TKEY_GET_MASK(0, tn->pos)); + printbin_seq(seq, tkey_extract_bits(tn->key, 0, tn->pos), tn->pos); + seq_printf(seq, "}\n"); + putspace_seq(seq, indent); seq_printf(seq, "| "); + seq_printf(seq, "{pos=%d", tn->pos); + seq_printf(seq, " (skip=%d bits)", tn->pos - pend); + seq_printf(seq, " bits=%d (%u children)}\n", tn->bits, (1 << tn->bits)); + putspace_seq(seq, indent); seq_printf(seq, "| "); + seq_printf(seq, "{empty=%d full=%d}\n", tn->empty_children, tn->full_children); + } +} + +static void trie_dump_seq(struct seq_file *seq, struct trie *t) +{ + struct node *n=t->trie; + int cindex=0; + int indent=1; + int pend=0; + int depth = 0; + + read_lock(&fib_lock); + + seq_printf(seq, "------ trie_dump of t=%p ------\n", t); + if (n) { + printnode_seq(seq, indent, n, pend, cindex, 0); + if (IS_TNODE(n)) { + struct tnode *tn=(struct tnode *)n; + pend = tn->pos+tn->bits; + putspace_seq(seq, indent); seq_printf(seq, "\\--\n"); + indent += 3; + depth++; + + while (tn && cindex < (1 << tn->bits)) { + if (tn->child[cindex]) { + + /* Got a child */ + + printnode_seq(seq, indent, tn->child[cindex], pend, cindex, tn->bits); + if (IS_LEAF(tn->child[cindex])) { + cindex++; + + } + else { + /* + * New tnode. Decend one level + */ + + depth++; + n=tn->child[cindex]; + tn=(struct tnode *)n; + pend=tn->pos+tn->bits; + putspace_seq(seq, indent); seq_printf(seq, "\\--\n"); + indent+=3; + cindex=0; + } + } + else + cindex++; + + /* + * Test if we are done + */ + + while (cindex >= (1 << tn->bits)) { + + /* + * Move upwards and test for root + * pop off all traversed nodes + */ + + if (NODE_PARENT(tn) == NULL) { + tn = NULL; + n = NULL; + break; + } + else { + cindex = tkey_extract_bits(tn->key, NODE_PARENT(tn)->pos, NODE_PARENT(tn)->bits); + tn = NODE_PARENT(tn); + cindex++; + n=(struct node *)tn; + pend=tn->pos+tn->bits; + indent-=3; + depth--; + } + } + } + } + else n = NULL; + } + else seq_printf(seq, "------ trie is empty\n"); + + read_unlock(&fib_lock); +} + +static struct trie_stat *trie_stat_new(void) +{ + struct trie_stat *s = kmalloc(sizeof(struct trie_stat), GFP_KERNEL); + int i; + + if(s) { + s->totdepth = 0; + s->maxdepth = 0; + s->tnodes = 0; + s->leaves = 0; + s->nullpointers = 0; + + for(i=0; i< MAX_CHILDS; i++) + s->nodesizes[i] = 0; + } + return s; +} + +static struct trie_stat *trie_collect_stats(struct trie *t) +{ + struct node *n=t->trie; + struct trie_stat *s = trie_stat_new(); + int cindex = 0; + int indent = 1; + int pend = 0; + int depth = 0; + + read_lock(&fib_lock); + + if (s) { + if (n) { + if (IS_TNODE(n)) { + struct tnode *tn = (struct tnode *)n; + pend=tn->pos+tn->bits; + indent += 3; + s->nodesizes[tn->bits]++; + depth++; + + while (tn && cindex < (1 << tn->bits)) { + if (tn->child[cindex]) { + /* Got a child */ + + if (IS_LEAF(tn->child[cindex])) { + cindex++; + + /* stats */ + if (depth > s->maxdepth) + s->maxdepth = depth; + s->totdepth += depth; + s->leaves++; + } + + else { + /* + * New tnode. Decend one level + */ + + s->tnodes++; + s->nodesizes[tn->bits]++; + depth++; + + n = tn->child[cindex]; + tn = (struct tnode *)n; + pend = tn->pos+tn->bits; + + indent += 3; + cindex = 0; + } + } + else { + cindex++; + s->nullpointers++; + } + + /* + * Test if we are done + */ + + while (cindex >= (1 << tn->bits)) { + + /* + * Move upwards and test for root + * pop off all traversed nodes + */ + + + if (NODE_PARENT(tn) == NULL) { + tn = NULL; + n = NULL; + break; + } + else { + cindex = tkey_extract_bits(tn->key, NODE_PARENT(tn)->pos, NODE_PARENT(tn)->bits); + tn = NODE_PARENT(tn); + cindex++; + n = (struct node *)tn; + pend=tn->pos+tn->bits; + indent -= 3; + depth--; + } + } + } + } + else n = NULL; + } + } + + read_unlock(&fib_lock); + return s; +} + +#ifdef CONFIG_PROC_FS + +static struct fib_alias *fib_triestat_get_first(struct seq_file *seq) +{ + return NULL; +} + +static struct fib_alias *fib_triestat_get_next(struct seq_file *seq) +{ + return NULL; +} + +static void *fib_triestat_seq_start(struct seq_file *seq, loff_t *pos) +{ + void *v = NULL; + + if (ip_fib_main_table) + v = *pos ? fib_triestat_get_next(seq) : SEQ_START_TOKEN; + return v; +} + +static void *fib_triestat_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + ++*pos; + return v == SEQ_START_TOKEN ? fib_triestat_get_first(seq) : fib_triestat_get_next(seq); +} + +static void fib_triestat_seq_stop(struct seq_file *seq, void *v) +{ + +} + +/* + * This outputs /proc/net/fib_triestats + * + * It always works in backward compatibility mode. + * The format of the file is not supposed to be changed. + */ + +static void collect_and_show(struct trie *t, struct seq_file *seq) +{ + int bytes = 0; /* How many bytes are used, a ref is 4 bytes */ + int i, max, pointers; + struct trie_stat *stat; + int avdepth; + + stat = trie_collect_stats(t); + + bytes=0; + seq_printf(seq, "trie=%p\n", t); + + if (stat) { + if (stat->leaves) + avdepth=stat->totdepth*100 / stat->leaves; + else + avdepth=0; + seq_printf(seq, "Aver depth: %d.%02d\n", avdepth / 100, avdepth % 100 ); + seq_printf(seq, "Max depth: %4d\n", stat->maxdepth); + + seq_printf(seq, "Leaves: %d\n", stat->leaves); + bytes += sizeof(struct leaf) * stat->leaves; + seq_printf(seq, "Internal nodes: %d\n", stat->tnodes); + bytes += sizeof(struct tnode) * stat->tnodes; + + max = MAX_CHILDS-1; + + while (max >= 0 && stat->nodesizes[max] == 0) + max--; + pointers = 0; + + for (i = 1; i <= max; i++) + if (stat->nodesizes[i] != 0) { + seq_printf(seq, " %d: %d", i, stat->nodesizes[i]); + pointers += (1<nodesizes[i]; + } + seq_printf(seq, "\n"); + seq_printf(seq, "Pointers: %d\n", pointers); + bytes += sizeof(struct node *) * pointers; + seq_printf(seq, "Null ptrs: %d\n", stat->nullpointers); + seq_printf(seq, "Total size: %d kB\n", bytes / 1024); + + kfree(stat); + } + +#ifdef CONFIG_IP_FIB_TRIE_STATS + seq_printf(seq, "Counters:\n---------\n"); + seq_printf(seq,"gets = %d\n", t->stats.gets); + seq_printf(seq,"backtracks = %d\n", t->stats.backtrack); + seq_printf(seq,"semantic match passed = %d\n", t->stats.semantic_match_passed); + seq_printf(seq,"semantic match miss = %d\n", t->stats.semantic_match_miss); + seq_printf(seq,"null node hit= %d\n", t->stats.null_node_hit); +#ifdef CLEAR_STATS + memset(&(t->stats), 0, sizeof(t->stats)); +#endif +#endif /* CONFIG_IP_FIB_TRIE_STATS */ +} + +static int fib_triestat_seq_show(struct seq_file *seq, void *v) +{ + char bf[128]; + + if (v == SEQ_START_TOKEN) { + seq_printf(seq, "Basic info: size of leaf: %Zd bytes, size of tnode: %Zd bytes.\n", + sizeof(struct leaf), sizeof(struct tnode)); + if (trie_local) + collect_and_show(trie_local, seq); + + if (trie_main) + collect_and_show(trie_main, seq); + } + else { + snprintf(bf, sizeof(bf), + "*\t%08X\t%08X", 200, 400); + + seq_printf(seq, "%-127s\n", bf); + } + return 0; +} + +static struct seq_operations fib_triestat_seq_ops = { + .start = fib_triestat_seq_start, + .next = fib_triestat_seq_next, + .stop = fib_triestat_seq_stop, + .show = fib_triestat_seq_show, +}; + +static int fib_triestat_seq_open(struct inode *inode, struct file *file) +{ + struct seq_file *seq; + int rc = -ENOMEM; + + rc = seq_open(file, &fib_triestat_seq_ops); + if (rc) + goto out_kfree; + + seq = file->private_data; +out: + return rc; +out_kfree: + goto out; +} + +static struct file_operations fib_triestat_seq_fops = { + .owner = THIS_MODULE, + .open = fib_triestat_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_private, +}; + +int __init fib_stat_proc_init(void) +{ + if (!proc_net_fops_create("fib_triestat", S_IRUGO, &fib_triestat_seq_fops)) + return -ENOMEM; + return 0; +} + +void __init fib_stat_proc_exit(void) +{ + proc_net_remove("fib_triestat"); +} + +static struct fib_alias *fib_trie_get_first(struct seq_file *seq) +{ + return NULL; +} + +static struct fib_alias *fib_trie_get_next(struct seq_file *seq) +{ + return NULL; +} + +static void *fib_trie_seq_start(struct seq_file *seq, loff_t *pos) +{ + void *v = NULL; + + if (ip_fib_main_table) + v = *pos ? fib_trie_get_next(seq) : SEQ_START_TOKEN; + return v; +} + +static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + ++*pos; + return v == SEQ_START_TOKEN ? fib_trie_get_first(seq) : fib_trie_get_next(seq); +} + +static void fib_trie_seq_stop(struct seq_file *seq, void *v) +{ + +} + +/* + * This outputs /proc/net/fib_trie. + * + * It always works in backward compatibility mode. + * The format of the file is not supposed to be changed. + */ + +static int fib_trie_seq_show(struct seq_file *seq, void *v) +{ + char bf[128]; + + if (v == SEQ_START_TOKEN) { + if (trie_local) + trie_dump_seq(seq, trie_local); + + if (trie_main) + trie_dump_seq(seq, trie_main); + } + + else { + snprintf(bf, sizeof(bf), + "*\t%08X\t%08X", 200, 400); + seq_printf(seq, "%-127s\n", bf); + } + + return 0; +} + +static struct seq_operations fib_trie_seq_ops = { + .start = fib_trie_seq_start, + .next = fib_trie_seq_next, + .stop = fib_trie_seq_stop, + .show = fib_trie_seq_show, +}; + +static int fib_trie_seq_open(struct inode *inode, struct file *file) +{ + struct seq_file *seq; + int rc = -ENOMEM; + + rc = seq_open(file, &fib_trie_seq_ops); + if (rc) + goto out_kfree; + + seq = file->private_data; +out: + return rc; +out_kfree: + goto out; +} + +static struct file_operations fib_trie_seq_fops = { + .owner = THIS_MODULE, + .open = fib_trie_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_private, +}; + +int __init fib_proc_init(void) +{ + if (!proc_net_fops_create("fib_trie", S_IRUGO, &fib_trie_seq_fops)) + return -ENOMEM; + return 0; +} + +void __init fib_proc_exit(void) +{ + proc_net_remove("fib_trie"); +} + +#endif /* CONFIG_PROC_FS */ -- cgit v1.2.3-59-g8ed1b From 0d51aa80a9b1db43920c0770c3bb842dd823c005 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Tue, 21 Jun 2005 13:51:04 -0700 Subject: [IPV6]: V6 route events reported with wrong netlink PID and seq number Essentially netlink at the moment always reports a pid and sequence of 0 always for v6 route activities. To understand the repurcassions of this look at: http://lists.quagga.net/pipermail/quagga-dev/2005-June/003507.html While fixing this, i took the liberty to resolve the outstanding issue of IPV6 routes inserted via ioctls to have the correct pids as well. This patch tries to behave as close as possible to the v4 routes i.e maintains whatever PID the socket issuing the command owns as opposed to the process. That made the patch a little bulky. I have tested against both netlink derived utility to add/del routes as well as ioctl derived one. The Quagga folks have tested against quagga. This fixes the problem and so far hasnt been detected to introduce any new issues. Signed-off-by: Jamal Hadi Salim Acked-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- include/net/ip6_fib.h | 9 ++++-- include/net/ip6_route.h | 9 ++++-- net/ipv6/addrconf.c | 14 ++++----- net/ipv6/anycast.c | 4 +-- net/ipv6/ip6_fib.c | 19 ++++++------ net/ipv6/ndisc.c | 4 +-- net/ipv6/route.c | 78 ++++++++++++++++++++++++++----------------------- 7 files changed, 74 insertions(+), 63 deletions(-) diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 319904518194..a66e9de16a6c 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -167,14 +167,17 @@ extern int fib6_walk_continue(struct fib6_walker_t *w); extern int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nlmsghdr *nlh, - void *rtattr); + void *rtattr, + struct netlink_skb_parms *req); extern int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, - void *rtattr); + void *rtattr, + struct netlink_skb_parms *req); extern void inet6_rt_notify(int event, struct rt6_info *rt, - struct nlmsghdr *nlh); + struct nlmsghdr *nlh, + struct netlink_skb_parms *req); extern void fib6_run_gc(unsigned long dummy); diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index d5d1dd10cdb8..f920706d526b 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -41,13 +41,16 @@ extern int ipv6_route_ioctl(unsigned int cmd, void __user *arg); extern int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *, - void *rtattr); + void *rtattr, + struct netlink_skb_parms *req); extern int ip6_ins_rt(struct rt6_info *, struct nlmsghdr *, - void *rtattr); + void *rtattr, + struct netlink_skb_parms *req); extern int ip6_del_rt(struct rt6_info *, struct nlmsghdr *, - void *rtattr); + void *rtattr, + struct netlink_skb_parms *req); extern int ip6_rt_addr_add(struct in6_addr *addr, struct net_device *dev, diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 47a30c3188ea..14f5c53235fe 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -695,7 +695,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { if (onlink == 0) { - ip6_del_rt(rt, NULL, NULL); + ip6_del_rt(rt, NULL, NULL, NULL); rt = NULL; } else if (!(rt->rt6i_flags & RTF_EXPIRES)) { rt->rt6i_expires = expires; @@ -1340,7 +1340,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev, if (dev->type == ARPHRD_SIT && (dev->flags&IFF_POINTOPOINT)) rtmsg.rtmsg_flags |= RTF_NONEXTHOP; - ip6_route_add(&rtmsg, NULL, NULL); + ip6_route_add(&rtmsg, NULL, NULL, NULL); } /* Create "default" multicast route to the interface */ @@ -1357,7 +1357,7 @@ static void addrconf_add_mroute(struct net_device *dev) rtmsg.rtmsg_ifindex = dev->ifindex; rtmsg.rtmsg_flags = RTF_UP; rtmsg.rtmsg_type = RTMSG_NEWROUTE; - ip6_route_add(&rtmsg, NULL, NULL); + ip6_route_add(&rtmsg, NULL, NULL, NULL); } static void sit_route_add(struct net_device *dev) @@ -1374,7 +1374,7 @@ static void sit_route_add(struct net_device *dev) rtmsg.rtmsg_flags = RTF_UP|RTF_NONEXTHOP; rtmsg.rtmsg_ifindex = dev->ifindex; - ip6_route_add(&rtmsg, NULL, NULL); + ip6_route_add(&rtmsg, NULL, NULL, NULL); } static void addrconf_add_lroute(struct net_device *dev) @@ -1467,7 +1467,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { if (rt->rt6i_flags&RTF_EXPIRES) { if (valid_lft == 0) { - ip6_del_rt(rt, NULL, NULL); + ip6_del_rt(rt, NULL, NULL, NULL); rt = NULL; } else { rt->rt6i_expires = rt_expires; @@ -3094,7 +3094,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) switch (event) { case RTM_NEWADDR: dst_hold(&ifp->rt->u.dst); - if (ip6_ins_rt(ifp->rt, NULL, NULL)) + if (ip6_ins_rt(ifp->rt, NULL, NULL, NULL)) dst_release(&ifp->rt->u.dst); if (ifp->idev->cnf.forwarding) addrconf_join_anycast(ifp); @@ -3104,7 +3104,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) addrconf_leave_anycast(ifp); addrconf_leave_solict(ifp->idev, &ifp->addr); dst_hold(&ifp->rt->u.dst); - if (ip6_del_rt(ifp->rt, NULL, NULL)) + if (ip6_del_rt(ifp->rt, NULL, NULL, NULL)) dst_free(&ifp->rt->u.dst); else dst_release(&ifp->rt->u.dst); diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index 5d22ca3cca2e..6b7294047238 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c @@ -337,7 +337,7 @@ int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr) write_unlock_bh(&idev->lock); dst_hold(&rt->u.dst); - if (ip6_ins_rt(rt, NULL, NULL)) + if (ip6_ins_rt(rt, NULL, NULL, NULL)) dst_release(&rt->u.dst); addrconf_join_solict(dev, &aca->aca_addr); @@ -380,7 +380,7 @@ int __ipv6_dev_ac_dec(struct inet6_dev *idev, struct in6_addr *addr) addrconf_leave_solict(idev, &aca->aca_addr); dst_hold(&aca->aca_rt->u.dst); - if (ip6_del_rt(aca->aca_rt, NULL, NULL)) + if (ip6_del_rt(aca->aca_rt, NULL, NULL, NULL)) dst_free(&aca->aca_rt->u.dst); else dst_release(&aca->aca_rt->u.dst); diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 405740b75abb..1b354aa97934 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -394,7 +394,7 @@ insert_above: */ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, - struct nlmsghdr *nlh) + struct nlmsghdr *nlh, struct netlink_skb_parms *req) { struct rt6_info *iter = NULL; struct rt6_info **ins; @@ -449,7 +449,7 @@ out: *ins = rt; rt->rt6i_node = fn; atomic_inc(&rt->rt6i_ref); - inet6_rt_notify(RTM_NEWROUTE, rt, nlh); + inet6_rt_notify(RTM_NEWROUTE, rt, nlh, req); rt6_stats.fib_rt_entries++; if ((fn->fn_flags & RTN_RTINFO) == 0) { @@ -479,7 +479,8 @@ void fib6_force_start_gc(void) * with source addr info in sub-trees */ -int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr) +int fib6_add(struct fib6_node *root, struct rt6_info *rt, + struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req) { struct fib6_node *fn; int err = -ENOMEM; @@ -552,7 +553,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nlmsghdr *nlh, } #endif - err = fib6_add_rt2node(fn, rt, nlh); + err = fib6_add_rt2node(fn, rt, nlh, req); if (err == 0) { fib6_start_gc(rt); @@ -859,7 +860,7 @@ static struct fib6_node * fib6_repair_tree(struct fib6_node *fn) } static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, - struct nlmsghdr *nlh, void *_rtattr) + struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req) { struct fib6_walker_t *w; struct rt6_info *rt = *rtp; @@ -915,11 +916,11 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, if (atomic_read(&rt->rt6i_ref) != 1) BUG(); } - inet6_rt_notify(RTM_DELROUTE, rt, nlh); + inet6_rt_notify(RTM_DELROUTE, rt, nlh, req); rt6_release(rt); } -int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr) +int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req) { struct fib6_node *fn = rt->rt6i_node; struct rt6_info **rtp; @@ -944,7 +945,7 @@ int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr) for (rtp = &fn->leaf; *rtp; rtp = &(*rtp)->u.next) { if (*rtp == rt) { - fib6_del_route(fn, rtp, nlh, _rtattr); + fib6_del_route(fn, rtp, nlh, _rtattr, req); return 0; } } @@ -1073,7 +1074,7 @@ static int fib6_clean_node(struct fib6_walker_t *w) res = c->func(rt, c->arg); if (res < 0) { w->leaf = rt; - res = fib6_del(rt, NULL, NULL); + res = fib6_del(rt, NULL, NULL, NULL); if (res) { #if RT6_DEBUG >= 2 printk(KERN_DEBUG "fib6_clean_node: del failed: rt=%p@%p err=%d\n", rt, rt->rt6i_node, res); diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 7c291f4e9edc..7ae72d4c9bd2 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -955,7 +955,7 @@ static void ndisc_recv_na(struct sk_buff *skb) struct rt6_info *rt; rt = rt6_get_dflt_router(saddr, dev); if (rt) - ip6_del_rt(rt, NULL, NULL); + ip6_del_rt(rt, NULL, NULL, NULL); } out: @@ -1096,7 +1096,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) if (rt && lifetime == 0) { neigh_clone(neigh); - ip6_del_rt(rt, NULL, NULL); + ip6_del_rt(rt, NULL, NULL, NULL); rt = NULL; } diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 1f5b226c3573..878789b3122d 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -384,12 +384,13 @@ struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr, be destroyed. */ -int ip6_ins_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr) +int ip6_ins_rt(struct rt6_info *rt, struct nlmsghdr *nlh, + void *_rtattr, struct netlink_skb_parms *req) { int err; write_lock_bh(&rt6_lock); - err = fib6_add(&ip6_routing_table, rt, nlh, _rtattr); + err = fib6_add(&ip6_routing_table, rt, nlh, _rtattr, req); write_unlock_bh(&rt6_lock); return err; @@ -400,7 +401,7 @@ int ip6_ins_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr) */ static struct rt6_info *rt6_cow(struct rt6_info *ort, struct in6_addr *daddr, - struct in6_addr *saddr) + struct in6_addr *saddr, struct netlink_skb_parms *req) { int err; struct rt6_info *rt; @@ -432,7 +433,7 @@ static struct rt6_info *rt6_cow(struct rt6_info *ort, struct in6_addr *daddr, dst_hold(&rt->u.dst); - err = ip6_ins_rt(rt, NULL, NULL); + err = ip6_ins_rt(rt, NULL, NULL, req); if (err == 0) return rt; @@ -491,7 +492,8 @@ restart: read_unlock_bh(&rt6_lock); nrt = rt6_cow(rt, &skb->nh.ipv6h->daddr, - &skb->nh.ipv6h->saddr); + &skb->nh.ipv6h->saddr, + &NETLINK_CB(skb)); dst_release(&rt->u.dst); rt = nrt; @@ -551,7 +553,7 @@ restart: dst_hold(&rt->u.dst); read_unlock_bh(&rt6_lock); - nrt = rt6_cow(rt, &fl->fl6_dst, &fl->fl6_src); + nrt = rt6_cow(rt, &fl->fl6_dst, &fl->fl6_src, NULL); dst_release(&rt->u.dst); rt = nrt; @@ -598,7 +600,7 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst) if (rt) { if (rt->rt6i_flags & RTF_CACHE) - ip6_del_rt(rt, NULL, NULL); + ip6_del_rt(rt, NULL, NULL, NULL); else dst_release(dst); } @@ -787,7 +789,8 @@ int ipv6_get_hoplimit(struct net_device *dev) * */ -int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr) +int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, + void *_rtattr, struct netlink_skb_parms *req) { int err; struct rtmsg *r; @@ -974,7 +977,7 @@ install_route: rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst)); rt->u.dst.dev = dev; rt->rt6i_idev = idev; - return ip6_ins_rt(rt, nlh, _rtattr); + return ip6_ins_rt(rt, nlh, _rtattr, req); out: if (dev) @@ -986,7 +989,7 @@ out: return err; } -int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr) +int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req) { int err; @@ -994,7 +997,7 @@ int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr) rt6_reset_dflt_pointer(NULL); - err = fib6_del(rt, nlh, _rtattr); + err = fib6_del(rt, nlh, _rtattr, req); dst_release(&rt->u.dst); write_unlock_bh(&rt6_lock); @@ -1002,7 +1005,7 @@ int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr) return err; } -static int ip6_route_del(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr) +static int ip6_route_del(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req) { struct fib6_node *fn; struct rt6_info *rt; @@ -1029,7 +1032,7 @@ static int ip6_route_del(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_r dst_hold(&rt->u.dst); read_unlock_bh(&rt6_lock); - return ip6_del_rt(rt, nlh, _rtattr); + return ip6_del_rt(rt, nlh, _rtattr, req); } } read_unlock_bh(&rt6_lock); @@ -1136,11 +1139,11 @@ source_ok: nrt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(neigh->dev); nrt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&nrt->u.dst)); - if (ip6_ins_rt(nrt, NULL, NULL)) + if (ip6_ins_rt(nrt, NULL, NULL, NULL)) goto out; if (rt->rt6i_flags&RTF_CACHE) { - ip6_del_rt(rt, NULL, NULL); + ip6_del_rt(rt, NULL, NULL, NULL); return; } @@ -1204,7 +1207,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, 2. It is gatewayed route or NONEXTHOP route. Action: clone it. */ if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) { - nrt = rt6_cow(rt, daddr, saddr); + nrt = rt6_cow(rt, daddr, saddr, NULL); if (!nrt->u.dst.error) { nrt->u.dst.metrics[RTAX_MTU-1] = pmtu; if (allfrag) @@ -1232,7 +1235,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, nrt->u.dst.metrics[RTAX_MTU-1] = pmtu; if (allfrag) nrt->u.dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG; - ip6_ins_rt(nrt, NULL, NULL); + ip6_ins_rt(nrt, NULL, NULL, NULL); } out: @@ -1305,7 +1308,7 @@ struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr, rtmsg.rtmsg_ifindex = dev->ifindex; - ip6_route_add(&rtmsg, NULL, NULL); + ip6_route_add(&rtmsg, NULL, NULL, NULL); return rt6_get_dflt_router(gwaddr, dev); } @@ -1323,7 +1326,7 @@ restart: read_unlock_bh(&rt6_lock); - ip6_del_rt(rt, NULL, NULL); + ip6_del_rt(rt, NULL, NULL, NULL); goto restart; } @@ -1349,10 +1352,10 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg) rtnl_lock(); switch (cmd) { case SIOCADDRT: - err = ip6_route_add(&rtmsg, NULL, NULL); + err = ip6_route_add(&rtmsg, NULL, NULL, NULL); break; case SIOCDELRT: - err = ip6_route_del(&rtmsg, NULL, NULL); + err = ip6_route_del(&rtmsg, NULL, NULL, NULL); break; default: err = -EINVAL; @@ -1546,7 +1549,7 @@ int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) if (inet6_rtm_to_rtmsg(r, arg, &rtmsg)) return -EINVAL; - return ip6_route_del(&rtmsg, nlh, arg); + return ip6_route_del(&rtmsg, nlh, arg, &NETLINK_CB(skb)); } int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) @@ -1556,7 +1559,7 @@ int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) if (inet6_rtm_to_rtmsg(r, arg, &rtmsg)) return -EINVAL; - return ip6_route_add(&rtmsg, nlh, arg); + return ip6_route_add(&rtmsg, nlh, arg, &NETLINK_CB(skb)); } struct rt6_rtnl_dump_arg @@ -1566,12 +1569,9 @@ struct rt6_rtnl_dump_arg }; static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, - struct in6_addr *dst, - struct in6_addr *src, - int iif, - int type, u32 pid, u32 seq, - struct nlmsghdr *in_nlh, int prefix, - unsigned int flags) + struct in6_addr *dst, struct in6_addr *src, + int iif, int type, u32 pid, u32 seq, + int prefix, unsigned int flags) { struct rtmsg *rtm; struct nlmsghdr *nlh; @@ -1585,10 +1585,6 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, } } - if (!pid && in_nlh) { - pid = in_nlh->nlmsg_pid; - } - nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*rtm), flags); rtm = NLMSG_DATA(nlh); rtm->rtm_family = AF_INET6; @@ -1675,7 +1671,7 @@ static int rt6_dump_route(struct rt6_info *rt, void *p_arg) return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE, NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq, - NULL, prefix, NLM_F_MULTI); + prefix, NLM_F_MULTI); } static int fib6_dump_node(struct fib6_walker_t *w) @@ -1823,7 +1819,7 @@ int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) &fl.fl6_dst, &fl.fl6_src, iif, RTM_NEWROUTE, NETLINK_CB(in_skb).pid, - nlh->nlmsg_seq, nlh, 0, 0); + nlh->nlmsg_seq, 0, 0); if (err < 0) { err = -EMSGSIZE; goto out_free; @@ -1839,17 +1835,25 @@ out_free: goto out; } -void inet6_rt_notify(int event, struct rt6_info *rt, struct nlmsghdr *nlh) +void inet6_rt_notify(int event, struct rt6_info *rt, struct nlmsghdr *nlh, + struct netlink_skb_parms *req) { struct sk_buff *skb; int size = NLMSG_SPACE(sizeof(struct rtmsg)+256); + u32 pid = current->pid; + u32 seq = 0; + if (req) + pid = req->pid; + if (nlh) + seq = nlh->nlmsg_seq; + skb = alloc_skb(size, gfp_any()); if (!skb) { netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, ENOBUFS); return; } - if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, 0, 0, nlh, 0, 0) < 0) { + if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0) < 0) { kfree_skb(skb); netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, EINVAL); return; -- cgit v1.2.3-59-g8ed1b From c9e3e8b6958e02230079e6817862ea2968509866 Mon Sep 17 00:00:00 2001 From: David L Stevens Date: Tue, 21 Jun 2005 13:58:25 -0700 Subject: [IPV6]: multicast join and misc Here is a simplified version of the patch to fix a bug in IPv6 multicasting. It: 1) adds existence check & EADDRINUSE error for regular joins 2) adds an exception for EADDRINUSE in the source-specific multicast join (where a prior join is ok) 3) adds a missing/needed read_lock on sock_mc_list; would've raced with destroying the socket on interface down without 4) adds a "leave group" in the (INCLUDE, empty) source filter case. This frees unneeded socket buffer memory, but also prevents an inappropriate interaction among the 8 socket options that mess with this. Some would fail as if in the group when you aren't really. Item #4 had a locking bug in the last version of this patch; rather than removing the idev->lock read lock only, I've simplified it to remove all lock state in the path and treat it as a direct "leave group" call for the (INCLUDE,empty) case it covers. Tested on an MP machine. :-) Much thanks to HoerdtMickael who reported the original bug. Signed-off-by: David L Stevens Signed-off-by: David S. Miller --- net/ipv6/ipv6_sockglue.c | 5 +++-- net/ipv6/mcast.c | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 279ab86be662..f3ef4c38d315 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -423,11 +423,12 @@ done: psin6 = (struct sockaddr_in6 *)&greqs.gsr_group; retv = ipv6_sock_mc_join(sk, greqs.gsr_interface, &psin6->sin6_addr); - if (retv) + /* prior join w/ different source is ok */ + if (retv && retv != -EADDRINUSE) break; omode = MCAST_INCLUDE; add = 1; - } else /*IP_DROP_SOURCE_MEMBERSHIP */ { + } else /* MCAST_LEAVE_SOURCE_GROUP */ { omode = MCAST_INCLUDE; add = 0; } diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 393b6e6f50a9..c0ca92e8230b 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -188,6 +188,16 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr) if (!ipv6_addr_is_multicast(addr)) return -EINVAL; + read_lock_bh(&ipv6_sk_mc_lock); + for (mc_lst=np->ipv6_mc_list; mc_lst; mc_lst=mc_lst->next) { + if ((ifindex == 0 || mc_lst->ifindex == ifindex) && + ipv6_addr_equal(&mc_lst->addr, addr)) { + read_unlock_bh(&ipv6_sk_mc_lock); + return -EADDRINUSE; + } + } + read_unlock_bh(&ipv6_sk_mc_lock); + mc_lst = sock_kmalloc(sk, sizeof(struct ipv6_mc_socklist), GFP_KERNEL); if (mc_lst == NULL) @@ -349,6 +359,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk, struct ipv6_pinfo *inet6 = inet6_sk(sk); struct ip6_sf_socklist *psl; int i, j, rv; + int leavegroup = 0; int err; if (pgsr->gsr_group.ss_family != AF_INET6 || @@ -368,6 +379,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk, err = -EADDRNOTAVAIL; + read_lock_bh(&ipv6_sk_mc_lock); for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) { if (pgsr->gsr_interface && pmc->ifindex != pgsr->gsr_interface) continue; @@ -401,6 +413,12 @@ int ip6_mc_source(int add, int omode, struct sock *sk, if (rv) /* source not found */ goto done; + /* special case - (INCLUDE, empty) == LEAVE_GROUP */ + if (psl->sl_count == 1 && omode == MCAST_INCLUDE) { + leavegroup = 1; + goto done; + } + /* update the interface filter */ ip6_mc_del_src(idev, group, omode, 1, source, 1); @@ -453,9 +471,12 @@ int ip6_mc_source(int add, int omode, struct sock *sk, /* update the interface list */ ip6_mc_add_src(idev, group, omode, 1, source, 1); done: + read_unlock_bh(&ipv6_sk_mc_lock); read_unlock_bh(&idev->lock); in6_dev_put(idev); dev_put(dev); + if (leavegroup) + return ipv6_sock_mc_drop(sk, pgsr->gsr_interface, group); return err; } -- cgit v1.2.3-59-g8ed1b From e45b1be8bcb3643808975a426fa3e201a2588e87 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 21 Jun 2005 14:01:30 -0700 Subject: [NETFILTER]: Kill lockhelp.h Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter_ipv4/ip_conntrack_core.h | 3 +- include/linux/netfilter_ipv4/ip_nat.h | 3 +- include/linux/netfilter_ipv4/listhelp.h | 1 - include/linux/netfilter_ipv4/lockhelp.h | 129 ----------------------- net/ipv4/netfilter/arp_tables.c | 1 - net/ipv4/netfilter/ip_conntrack_amanda.c | 7 +- net/ipv4/netfilter/ip_conntrack_core.c | 84 +++++++-------- net/ipv4/netfilter/ip_conntrack_ftp.c | 7 +- net/ipv4/netfilter/ip_conntrack_irc.c | 7 +- net/ipv4/netfilter/ip_conntrack_proto_sctp.c | 23 ++-- net/ipv4/netfilter/ip_conntrack_proto_tcp.c | 27 +++-- net/ipv4/netfilter/ip_conntrack_standalone.c | 22 ++-- net/ipv4/netfilter/ip_nat_core.c | 32 +++--- net/ipv4/netfilter/ip_nat_helper.c | 10 +- net/ipv4/netfilter/ip_nat_rule.c | 4 +- net/ipv4/netfilter/ip_nat_standalone.c | 5 +- net/ipv4/netfilter/ip_tables.c | 1 - net/ipv4/netfilter/ipt_CLUSTERIP.c | 49 ++++----- net/ipv4/netfilter/ipt_MASQUERADE.c | 10 +- net/ipv4/netfilter/ipt_ULOG.c | 15 ++- net/ipv4/netfilter/ipt_hashlimit.c | 17 ++- net/ipv4/netfilter/ipt_helper.c | 4 +- net/ipv6/netfilter/ip6_tables.c | 1 - 23 files changed, 160 insertions(+), 302 deletions(-) delete mode 100644 include/linux/netfilter_ipv4/lockhelp.h diff --git a/include/linux/netfilter_ipv4/ip_conntrack_core.h b/include/linux/netfilter_ipv4/ip_conntrack_core.h index d84be02cb4fc..694aec9b4784 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack_core.h +++ b/include/linux/netfilter_ipv4/ip_conntrack_core.h @@ -1,7 +1,6 @@ #ifndef _IP_CONNTRACK_CORE_H #define _IP_CONNTRACK_CORE_H #include -#include /* This header is used to share core functionality between the standalone connection tracking module, and the compatibility layer's use @@ -47,6 +46,6 @@ static inline int ip_conntrack_confirm(struct sk_buff **pskb) extern struct list_head *ip_conntrack_hash; extern struct list_head ip_conntrack_expect_list; -DECLARE_RWLOCK_EXTERN(ip_conntrack_lock); +extern rwlock_t ip_conntrack_lock; #endif /* _IP_CONNTRACK_CORE_H */ diff --git a/include/linux/netfilter_ipv4/ip_nat.h b/include/linux/netfilter_ipv4/ip_nat.h index 2b72b86176f0..e201ec6e9905 100644 --- a/include/linux/netfilter_ipv4/ip_nat.h +++ b/include/linux/netfilter_ipv4/ip_nat.h @@ -50,10 +50,9 @@ struct ip_nat_multi_range_compat #ifdef __KERNEL__ #include -#include /* Protects NAT hash tables, and NAT-private part of conntracks. */ -DECLARE_RWLOCK_EXTERN(ip_nat_lock); +extern rwlock_t ip_nat_lock; /* The structure embedded in the conntrack structure. */ struct ip_nat_info diff --git a/include/linux/netfilter_ipv4/listhelp.h b/include/linux/netfilter_ipv4/listhelp.h index f2ae7c5e57bb..360429f48737 100644 --- a/include/linux/netfilter_ipv4/listhelp.h +++ b/include/linux/netfilter_ipv4/listhelp.h @@ -2,7 +2,6 @@ #define _LISTHELP_H #include #include -#include /* Header to do more comprehensive job than linux/list.h; assume list is first entry in structure. */ diff --git a/include/linux/netfilter_ipv4/lockhelp.h b/include/linux/netfilter_ipv4/lockhelp.h deleted file mode 100644 index a3288633ab46..000000000000 --- a/include/linux/netfilter_ipv4/lockhelp.h +++ /dev/null @@ -1,129 +0,0 @@ -#ifndef _LOCKHELP_H -#define _LOCKHELP_H -#include - -#include -#include -#include -#include - -/* Header to do help in lock debugging. */ - -#ifdef CONFIG_NETFILTER_DEBUG -struct spinlock_debug -{ - spinlock_t l; - atomic_t locked_by; -}; - -struct rwlock_debug -{ - rwlock_t l; - long read_locked_map; - long write_locked_map; -}; - -#define DECLARE_LOCK(l) \ -struct spinlock_debug l = { SPIN_LOCK_UNLOCKED, ATOMIC_INIT(-1) } -#define DECLARE_LOCK_EXTERN(l) \ -extern struct spinlock_debug l -#define DECLARE_RWLOCK(l) \ -struct rwlock_debug l = { RW_LOCK_UNLOCKED, 0, 0 } -#define DECLARE_RWLOCK_EXTERN(l) \ -extern struct rwlock_debug l - -#define MUST_BE_LOCKED(l) \ -do { if (atomic_read(&(l)->locked_by) != smp_processor_id()) \ - printk("ASSERT %s:%u %s unlocked\n", __FILE__, __LINE__, #l); \ -} while(0) - -#define MUST_BE_UNLOCKED(l) \ -do { if (atomic_read(&(l)->locked_by) == smp_processor_id()) \ - printk("ASSERT %s:%u %s locked\n", __FILE__, __LINE__, #l); \ -} while(0) - -/* Write locked OK as well. */ -#define MUST_BE_READ_LOCKED(l) \ -do { if (!((l)->read_locked_map & (1UL << smp_processor_id())) \ - && !((l)->write_locked_map & (1UL << smp_processor_id()))) \ - printk("ASSERT %s:%u %s not readlocked\n", __FILE__, __LINE__, #l); \ -} while(0) - -#define MUST_BE_WRITE_LOCKED(l) \ -do { if (!((l)->write_locked_map & (1UL << smp_processor_id()))) \ - printk("ASSERT %s:%u %s not writelocked\n", __FILE__, __LINE__, #l); \ -} while(0) - -#define MUST_BE_READ_WRITE_UNLOCKED(l) \ -do { if ((l)->read_locked_map & (1UL << smp_processor_id())) \ - printk("ASSERT %s:%u %s readlocked\n", __FILE__, __LINE__, #l); \ - else if ((l)->write_locked_map & (1UL << smp_processor_id())) \ - printk("ASSERT %s:%u %s writelocked\n", __FILE__, __LINE__, #l); \ -} while(0) - -#define LOCK_BH(lk) \ -do { \ - MUST_BE_UNLOCKED(lk); \ - spin_lock_bh(&(lk)->l); \ - atomic_set(&(lk)->locked_by, smp_processor_id()); \ -} while(0) - -#define UNLOCK_BH(lk) \ -do { \ - MUST_BE_LOCKED(lk); \ - atomic_set(&(lk)->locked_by, -1); \ - spin_unlock_bh(&(lk)->l); \ -} while(0) - -#define READ_LOCK(lk) \ -do { \ - MUST_BE_READ_WRITE_UNLOCKED(lk); \ - read_lock_bh(&(lk)->l); \ - set_bit(smp_processor_id(), &(lk)->read_locked_map); \ -} while(0) - -#define WRITE_LOCK(lk) \ -do { \ - MUST_BE_READ_WRITE_UNLOCKED(lk); \ - write_lock_bh(&(lk)->l); \ - set_bit(smp_processor_id(), &(lk)->write_locked_map); \ -} while(0) - -#define READ_UNLOCK(lk) \ -do { \ - if (!((lk)->read_locked_map & (1UL << smp_processor_id()))) \ - printk("ASSERT: %s:%u %s not readlocked\n", \ - __FILE__, __LINE__, #lk); \ - clear_bit(smp_processor_id(), &(lk)->read_locked_map); \ - read_unlock_bh(&(lk)->l); \ -} while(0) - -#define WRITE_UNLOCK(lk) \ -do { \ - MUST_BE_WRITE_LOCKED(lk); \ - clear_bit(smp_processor_id(), &(lk)->write_locked_map); \ - write_unlock_bh(&(lk)->l); \ -} while(0) - -#else -#define DECLARE_LOCK(l) spinlock_t l = SPIN_LOCK_UNLOCKED -#define DECLARE_LOCK_EXTERN(l) extern spinlock_t l -#define DECLARE_RWLOCK(l) rwlock_t l = RW_LOCK_UNLOCKED -#define DECLARE_RWLOCK_EXTERN(l) extern rwlock_t l - -#define MUST_BE_LOCKED(l) -#define MUST_BE_UNLOCKED(l) -#define MUST_BE_READ_LOCKED(l) -#define MUST_BE_WRITE_LOCKED(l) -#define MUST_BE_READ_WRITE_UNLOCKED(l) - -#define LOCK_BH(l) spin_lock_bh(l) -#define UNLOCK_BH(l) spin_unlock_bh(l) - -#define READ_LOCK(l) read_lock_bh(l) -#define WRITE_LOCK(l) write_lock_bh(l) -#define READ_UNLOCK(l) read_unlock_bh(l) -#define WRITE_UNLOCK(l) write_unlock_bh(l) -#endif /*CONFIG_NETFILTER_DEBUG*/ - -#endif /* _LOCKHELP_H */ diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index df79f5ed6a0a..fa1634256680 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -60,7 +60,6 @@ static DECLARE_MUTEX(arpt_mutex); #define ASSERT_READ_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0) #define ASSERT_WRITE_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0) -#include #include struct arpt_table_info { diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c index 3dbddd062605..a78a320eee08 100644 --- a/net/ipv4/netfilter/ip_conntrack_amanda.c +++ b/net/ipv4/netfilter/ip_conntrack_amanda.c @@ -26,7 +26,6 @@ #include #include -#include #include #include @@ -42,7 +41,7 @@ static char *conns[] = { "DATA ", "MESG ", "INDEX " }; /* This is slow, but it's simple. --RR */ static char amanda_buffer[65536]; -static DECLARE_LOCK(amanda_buffer_lock); +static DEFINE_SPINLOCK(amanda_buffer_lock); unsigned int (*ip_nat_amanda_hook)(struct sk_buff **pskb, enum ip_conntrack_info ctinfo, @@ -76,7 +75,7 @@ static int help(struct sk_buff **pskb, return NF_ACCEPT; } - LOCK_BH(&amanda_buffer_lock); + spin_lock_bh(&amanda_buffer_lock); skb_copy_bits(*pskb, dataoff, amanda_buffer, (*pskb)->len - dataoff); data = amanda_buffer; data_limit = amanda_buffer + (*pskb)->len - dataoff; @@ -134,7 +133,7 @@ static int help(struct sk_buff **pskb, } out: - UNLOCK_BH(&amanda_buffer_lock); + spin_unlock_bh(&amanda_buffer_lock); return ret; } diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index 09e824622977..a7377a331ade 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c @@ -38,10 +38,10 @@ #include #include -/* This rwlock protects the main hash table, protocol/helper/expected +/* ip_conntrack_lock protects the main hash table, protocol/helper/expected registrations, conntrack timers*/ -#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_conntrack_lock) -#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_conntrack_lock) +#define ASSERT_READ_LOCK(x) +#define ASSERT_WRITE_LOCK(x) #include #include @@ -57,7 +57,7 @@ #define DEBUGP(format, args...) #endif -DECLARE_RWLOCK(ip_conntrack_lock); +DEFINE_RWLOCK(ip_conntrack_lock); /* ip_conntrack_standalone needs this */ atomic_t ip_conntrack_count = ATOMIC_INIT(0); @@ -147,7 +147,7 @@ static void destroy_expect(struct ip_conntrack_expect *exp) static void unlink_expect(struct ip_conntrack_expect *exp) { - MUST_BE_WRITE_LOCKED(&ip_conntrack_lock); + ASSERT_WRITE_LOCK(&ip_conntrack_lock); list_del(&exp->list); /* Logically in destroy_expect, but we hold the lock here. */ exp->master->expecting--; @@ -157,9 +157,9 @@ static void expectation_timed_out(unsigned long ul_expect) { struct ip_conntrack_expect *exp = (void *)ul_expect; - WRITE_LOCK(&ip_conntrack_lock); + write_lock_bh(&ip_conntrack_lock); unlink_expect(exp); - WRITE_UNLOCK(&ip_conntrack_lock); + write_unlock_bh(&ip_conntrack_lock); destroy_expect(exp); } @@ -209,7 +209,7 @@ clean_from_lists(struct ip_conntrack *ct) unsigned int ho, hr; DEBUGP("clean_from_lists(%p)\n", ct); - MUST_BE_WRITE_LOCKED(&ip_conntrack_lock); + ASSERT_WRITE_LOCK(&ip_conntrack_lock); ho = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); hr = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); @@ -240,7 +240,7 @@ destroy_conntrack(struct nf_conntrack *nfct) if (ip_conntrack_destroyed) ip_conntrack_destroyed(ct); - WRITE_LOCK(&ip_conntrack_lock); + write_lock_bh(&ip_conntrack_lock); /* Expectations will have been removed in clean_from_lists, * except TFTP can create an expectation on the first packet, * before connection is in the list, so we need to clean here, @@ -254,7 +254,7 @@ destroy_conntrack(struct nf_conntrack *nfct) } CONNTRACK_STAT_INC(delete); - WRITE_UNLOCK(&ip_conntrack_lock); + write_unlock_bh(&ip_conntrack_lock); if (ct->master) ip_conntrack_put(ct->master); @@ -268,12 +268,12 @@ static void death_by_timeout(unsigned long ul_conntrack) { struct ip_conntrack *ct = (void *)ul_conntrack; - WRITE_LOCK(&ip_conntrack_lock); + write_lock_bh(&ip_conntrack_lock); /* Inside lock so preempt is disabled on module removal path. * Otherwise we can get spurious warnings. */ CONNTRACK_STAT_INC(delete_list); clean_from_lists(ct); - WRITE_UNLOCK(&ip_conntrack_lock); + write_unlock_bh(&ip_conntrack_lock); ip_conntrack_put(ct); } @@ -282,7 +282,7 @@ conntrack_tuple_cmp(const struct ip_conntrack_tuple_hash *i, const struct ip_conntrack_tuple *tuple, const struct ip_conntrack *ignored_conntrack) { - MUST_BE_READ_LOCKED(&ip_conntrack_lock); + ASSERT_READ_LOCK(&ip_conntrack_lock); return tuplehash_to_ctrack(i) != ignored_conntrack && ip_ct_tuple_equal(tuple, &i->tuple); } @@ -294,7 +294,7 @@ __ip_conntrack_find(const struct ip_conntrack_tuple *tuple, struct ip_conntrack_tuple_hash *h; unsigned int hash = hash_conntrack(tuple); - MUST_BE_READ_LOCKED(&ip_conntrack_lock); + ASSERT_READ_LOCK(&ip_conntrack_lock); list_for_each_entry(h, &ip_conntrack_hash[hash], list) { if (conntrack_tuple_cmp(h, tuple, ignored_conntrack)) { CONNTRACK_STAT_INC(found); @@ -313,11 +313,11 @@ ip_conntrack_find_get(const struct ip_conntrack_tuple *tuple, { struct ip_conntrack_tuple_hash *h; - READ_LOCK(&ip_conntrack_lock); + read_lock_bh(&ip_conntrack_lock); h = __ip_conntrack_find(tuple, ignored_conntrack); if (h) atomic_inc(&tuplehash_to_ctrack(h)->ct_general.use); - READ_UNLOCK(&ip_conntrack_lock); + read_unlock_bh(&ip_conntrack_lock); return h; } @@ -352,7 +352,7 @@ __ip_conntrack_confirm(struct sk_buff **pskb) IP_NF_ASSERT(!is_confirmed(ct)); DEBUGP("Confirming conntrack %p\n", ct); - WRITE_LOCK(&ip_conntrack_lock); + write_lock_bh(&ip_conntrack_lock); /* See if there's one in the list already, including reverse: NAT could have grabbed it without realizing, since we're @@ -380,12 +380,12 @@ __ip_conntrack_confirm(struct sk_buff **pskb) atomic_inc(&ct->ct_general.use); set_bit(IPS_CONFIRMED_BIT, &ct->status); CONNTRACK_STAT_INC(insert); - WRITE_UNLOCK(&ip_conntrack_lock); + write_unlock_bh(&ip_conntrack_lock); return NF_ACCEPT; } CONNTRACK_STAT_INC(insert_failed); - WRITE_UNLOCK(&ip_conntrack_lock); + write_unlock_bh(&ip_conntrack_lock); return NF_DROP; } @@ -398,9 +398,9 @@ ip_conntrack_tuple_taken(const struct ip_conntrack_tuple *tuple, { struct ip_conntrack_tuple_hash *h; - READ_LOCK(&ip_conntrack_lock); + read_lock_bh(&ip_conntrack_lock); h = __ip_conntrack_find(tuple, ignored_conntrack); - READ_UNLOCK(&ip_conntrack_lock); + read_unlock_bh(&ip_conntrack_lock); return h != NULL; } @@ -419,13 +419,13 @@ static int early_drop(struct list_head *chain) struct ip_conntrack *ct = NULL; int dropped = 0; - READ_LOCK(&ip_conntrack_lock); + read_lock_bh(&ip_conntrack_lock); h = LIST_FIND_B(chain, unreplied, struct ip_conntrack_tuple_hash *); if (h) { ct = tuplehash_to_ctrack(h); atomic_inc(&ct->ct_general.use); } - READ_UNLOCK(&ip_conntrack_lock); + read_unlock_bh(&ip_conntrack_lock); if (!ct) return dropped; @@ -508,7 +508,7 @@ init_conntrack(const struct ip_conntrack_tuple *tuple, conntrack->timeout.data = (unsigned long)conntrack; conntrack->timeout.function = death_by_timeout; - WRITE_LOCK(&ip_conntrack_lock); + write_lock_bh(&ip_conntrack_lock); exp = find_expectation(tuple); if (exp) { @@ -532,7 +532,7 @@ init_conntrack(const struct ip_conntrack_tuple *tuple, list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed); atomic_inc(&ip_conntrack_count); - WRITE_UNLOCK(&ip_conntrack_lock); + write_unlock_bh(&ip_conntrack_lock); if (exp) { if (exp->expectfn) @@ -723,17 +723,17 @@ void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp) { struct ip_conntrack_expect *i; - WRITE_LOCK(&ip_conntrack_lock); + write_lock_bh(&ip_conntrack_lock); /* choose the the oldest expectation to evict */ list_for_each_entry_reverse(i, &ip_conntrack_expect_list, list) { if (expect_matches(i, exp) && del_timer(&i->timeout)) { unlink_expect(i); - WRITE_UNLOCK(&ip_conntrack_lock); + write_unlock_bh(&ip_conntrack_lock); destroy_expect(i); return; } } - WRITE_UNLOCK(&ip_conntrack_lock); + write_unlock_bh(&ip_conntrack_lock); } struct ip_conntrack_expect *ip_conntrack_expect_alloc(void) @@ -808,7 +808,7 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect) DEBUGP("tuple: "); DUMP_TUPLE(&expect->tuple); DEBUGP("mask: "); DUMP_TUPLE(&expect->mask); - WRITE_LOCK(&ip_conntrack_lock); + write_lock_bh(&ip_conntrack_lock); list_for_each_entry(i, &ip_conntrack_expect_list, list) { if (expect_matches(i, expect)) { /* Refresh timer: if it's dying, ignore.. */ @@ -832,7 +832,7 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect) ip_conntrack_expect_insert(expect); ret = 0; out: - WRITE_UNLOCK(&ip_conntrack_lock); + write_unlock_bh(&ip_conntrack_lock); return ret; } @@ -841,7 +841,7 @@ out: void ip_conntrack_alter_reply(struct ip_conntrack *conntrack, const struct ip_conntrack_tuple *newreply) { - WRITE_LOCK(&ip_conntrack_lock); + write_lock_bh(&ip_conntrack_lock); /* Should be unconfirmed, so not in hash table yet */ IP_NF_ASSERT(!is_confirmed(conntrack)); @@ -851,15 +851,15 @@ void ip_conntrack_alter_reply(struct ip_conntrack *conntrack, conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply; if (!conntrack->master && conntrack->expecting == 0) conntrack->helper = ip_ct_find_helper(newreply); - WRITE_UNLOCK(&ip_conntrack_lock); + write_unlock_bh(&ip_conntrack_lock); } int ip_conntrack_helper_register(struct ip_conntrack_helper *me) { BUG_ON(me->timeout == 0); - WRITE_LOCK(&ip_conntrack_lock); + write_lock_bh(&ip_conntrack_lock); list_prepend(&helpers, me); - WRITE_UNLOCK(&ip_conntrack_lock); + write_unlock_bh(&ip_conntrack_lock); return 0; } @@ -878,7 +878,7 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me) struct ip_conntrack_expect *exp, *tmp; /* Need write lock here, to delete helper. */ - WRITE_LOCK(&ip_conntrack_lock); + write_lock_bh(&ip_conntrack_lock); LIST_DELETE(&helpers, me); /* Get rid of expectations */ @@ -893,7 +893,7 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me) for (i = 0; i < ip_conntrack_htable_size; i++) LIST_FIND_W(&ip_conntrack_hash[i], unhelp, struct ip_conntrack_tuple_hash *, me); - WRITE_UNLOCK(&ip_conntrack_lock); + write_unlock_bh(&ip_conntrack_lock); /* Someone could be still looking at the helper in a bh. */ synchronize_net(); @@ -925,14 +925,14 @@ void ip_ct_refresh_acct(struct ip_conntrack *ct, ct->timeout.expires = extra_jiffies; ct_add_counters(ct, ctinfo, skb); } else { - WRITE_LOCK(&ip_conntrack_lock); + write_lock_bh(&ip_conntrack_lock); /* Need del_timer for race avoidance (may already be dying). */ if (del_timer(&ct->timeout)) { ct->timeout.expires = jiffies + extra_jiffies; add_timer(&ct->timeout); } ct_add_counters(ct, ctinfo, skb); - WRITE_UNLOCK(&ip_conntrack_lock); + write_unlock_bh(&ip_conntrack_lock); } } @@ -997,7 +997,7 @@ get_next_corpse(int (*iter)(struct ip_conntrack *i, void *data), { struct ip_conntrack_tuple_hash *h = NULL; - WRITE_LOCK(&ip_conntrack_lock); + write_lock_bh(&ip_conntrack_lock); for (; *bucket < ip_conntrack_htable_size; (*bucket)++) { h = LIST_FIND_W(&ip_conntrack_hash[*bucket], do_iter, struct ip_conntrack_tuple_hash *, iter, data); @@ -1009,7 +1009,7 @@ get_next_corpse(int (*iter)(struct ip_conntrack *i, void *data), struct ip_conntrack_tuple_hash *, iter, data); if (h) atomic_inc(&tuplehash_to_ctrack(h)->ct_general.use); - WRITE_UNLOCK(&ip_conntrack_lock); + write_unlock_bh(&ip_conntrack_lock); return h; } @@ -1201,14 +1201,14 @@ int __init ip_conntrack_init(void) } /* Don't NEED lock here, but good form anyway. */ - WRITE_LOCK(&ip_conntrack_lock); + write_lock_bh(&ip_conntrack_lock); for (i = 0; i < MAX_IP_CT_PROTO; i++) ip_ct_protos[i] = &ip_conntrack_generic_protocol; /* Sew in builtin protocols. */ ip_ct_protos[IPPROTO_TCP] = &ip_conntrack_protocol_tcp; ip_ct_protos[IPPROTO_UDP] = &ip_conntrack_protocol_udp; ip_ct_protos[IPPROTO_ICMP] = &ip_conntrack_protocol_icmp; - WRITE_UNLOCK(&ip_conntrack_lock); + write_unlock_bh(&ip_conntrack_lock); for (i = 0; i < ip_conntrack_htable_size; i++) INIT_LIST_HEAD(&ip_conntrack_hash[i]); diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c index dd86503aa788..fea6dd2a00b6 100644 --- a/net/ipv4/netfilter/ip_conntrack_ftp.c +++ b/net/ipv4/netfilter/ip_conntrack_ftp.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -28,7 +27,7 @@ MODULE_DESCRIPTION("ftp connection tracking helper"); /* This is slow, but it's simple. --RR */ static char ftp_buffer[65536]; -static DECLARE_LOCK(ip_ftp_lock); +static DEFINE_SPINLOCK(ip_ftp_lock); #define MAX_PORTS 8 static int ports[MAX_PORTS]; @@ -319,7 +318,7 @@ static int help(struct sk_buff **pskb, } datalen = (*pskb)->len - dataoff; - LOCK_BH(&ip_ftp_lock); + spin_lock_bh(&ip_ftp_lock); fb_ptr = skb_header_pointer(*pskb, dataoff, (*pskb)->len - dataoff, ftp_buffer); BUG_ON(fb_ptr == NULL); @@ -442,7 +441,7 @@ out_update_nl: if (ends_in_nl) update_nl_seq(seq, ct_ftp_info,dir); out: - UNLOCK_BH(&ip_ftp_lock); + spin_unlock_bh(&ip_ftp_lock); return ret; } diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c index 33cc7348b6ee..cd98772cc332 100644 --- a/net/ipv4/netfilter/ip_conntrack_irc.c +++ b/net/ipv4/netfilter/ip_conntrack_irc.c @@ -29,7 +29,6 @@ #include #include -#include #include #include #include @@ -41,7 +40,7 @@ static int max_dcc_channels = 8; static unsigned int dcc_timeout = 300; /* This is slow, but it's simple. --RR */ static char irc_buffer[65536]; -static DECLARE_LOCK(irc_buffer_lock); +static DEFINE_SPINLOCK(irc_buffer_lock); unsigned int (*ip_nat_irc_hook)(struct sk_buff **pskb, enum ip_conntrack_info ctinfo, @@ -141,7 +140,7 @@ static int help(struct sk_buff **pskb, if (dataoff >= (*pskb)->len) return NF_ACCEPT; - LOCK_BH(&irc_buffer_lock); + spin_lock_bh(&irc_buffer_lock); ib_ptr = skb_header_pointer(*pskb, dataoff, (*pskb)->len - dataoff, irc_buffer); BUG_ON(ib_ptr == NULL); @@ -237,7 +236,7 @@ static int help(struct sk_buff **pskb, } /* while data < ... */ out: - UNLOCK_BH(&irc_buffer_lock); + spin_unlock_bh(&irc_buffer_lock); return ret; } diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c index ff8c34a860ff..31d75390bf12 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c @@ -26,7 +26,6 @@ #include #include -#include #if 0 #define DEBUGP(format, ...) printk(format, ## __VA_ARGS__) @@ -35,7 +34,7 @@ #endif /* Protects conntrack->proto.sctp */ -static DECLARE_RWLOCK(sctp_lock); +static DEFINE_RWLOCK(sctp_lock); /* FIXME: Examine ipfilter's timeouts and conntrack transitions more closely. They're more complex. --RR @@ -199,9 +198,9 @@ static int sctp_print_conntrack(struct seq_file *s, DEBUGP(__FUNCTION__); DEBUGP("\n"); - READ_LOCK(&sctp_lock); + read_lock_bh(&sctp_lock); state = conntrack->proto.sctp.state; - READ_UNLOCK(&sctp_lock); + read_unlock_bh(&sctp_lock); return seq_printf(s, "%s ", sctp_conntrack_names[state]); } @@ -343,13 +342,13 @@ static int sctp_packet(struct ip_conntrack *conntrack, oldsctpstate = newconntrack = SCTP_CONNTRACK_MAX; for_each_sctp_chunk (skb, sch, _sch, offset, count) { - WRITE_LOCK(&sctp_lock); + write_lock_bh(&sctp_lock); /* Special cases of Verification tag check (Sec 8.5.1) */ if (sch->type == SCTP_CID_INIT) { /* Sec 8.5.1 (A) */ if (sh->vtag != 0) { - WRITE_UNLOCK(&sctp_lock); + write_unlock_bh(&sctp_lock); return -1; } } else if (sch->type == SCTP_CID_ABORT) { @@ -357,7 +356,7 @@ static int sctp_packet(struct ip_conntrack *conntrack, if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)]) && !(sh->vtag == conntrack->proto.sctp.vtag [1 - CTINFO2DIR(ctinfo)])) { - WRITE_UNLOCK(&sctp_lock); + write_unlock_bh(&sctp_lock); return -1; } } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) { @@ -366,13 +365,13 @@ static int sctp_packet(struct ip_conntrack *conntrack, && !(sh->vtag == conntrack->proto.sctp.vtag [1 - CTINFO2DIR(ctinfo)] && (sch->flags & 1))) { - WRITE_UNLOCK(&sctp_lock); + write_unlock_bh(&sctp_lock); return -1; } } else if (sch->type == SCTP_CID_COOKIE_ECHO) { /* Sec 8.5.1 (D) */ if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) { - WRITE_UNLOCK(&sctp_lock); + write_unlock_bh(&sctp_lock); return -1; } } @@ -384,7 +383,7 @@ static int sctp_packet(struct ip_conntrack *conntrack, if (newconntrack == SCTP_CONNTRACK_MAX) { DEBUGP("ip_conntrack_sctp: Invalid dir=%i ctype=%u conntrack=%u\n", CTINFO2DIR(ctinfo), sch->type, oldsctpstate); - WRITE_UNLOCK(&sctp_lock); + write_unlock_bh(&sctp_lock); return -1; } @@ -396,7 +395,7 @@ static int sctp_packet(struct ip_conntrack *conntrack, ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t), sizeof(_inithdr), &_inithdr); if (ih == NULL) { - WRITE_UNLOCK(&sctp_lock); + write_unlock_bh(&sctp_lock); return -1; } DEBUGP("Setting vtag %x for dir %d\n", @@ -405,7 +404,7 @@ static int sctp_packet(struct ip_conntrack *conntrack, } conntrack->proto.sctp.state = newconntrack; - WRITE_UNLOCK(&sctp_lock); + write_unlock_bh(&sctp_lock); } ip_ct_refresh_acct(conntrack, ctinfo, skb, *sctp_timeouts[newconntrack]); diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c index 721ddbf522b4..809dfed766d4 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c @@ -36,7 +36,6 @@ #include #include #include -#include #if 0 #define DEBUGP printk @@ -46,7 +45,7 @@ #endif /* Protects conntrack->proto.tcp */ -static DECLARE_RWLOCK(tcp_lock); +static DEFINE_RWLOCK(tcp_lock); /* "Be conservative in what you do, be liberal in what you accept from others." @@ -330,9 +329,9 @@ static int tcp_print_conntrack(struct seq_file *s, { enum tcp_conntrack state; - READ_LOCK(&tcp_lock); + read_lock_bh(&tcp_lock); state = conntrack->proto.tcp.state; - READ_UNLOCK(&tcp_lock); + read_unlock_bh(&tcp_lock); return seq_printf(s, "%s ", tcp_conntrack_names[state]); } @@ -738,14 +737,14 @@ void ip_conntrack_tcp_update(struct sk_buff *skb, end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, iph, tcph); - WRITE_LOCK(&tcp_lock); + write_lock_bh(&tcp_lock); /* * We have to worry for the ack in the reply packet only... */ if (after(end, conntrack->proto.tcp.seen[dir].td_end)) conntrack->proto.tcp.seen[dir].td_end = end; conntrack->proto.tcp.last_end = end; - WRITE_UNLOCK(&tcp_lock); + write_unlock_bh(&tcp_lock); DEBUGP("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i " "receiver end=%u maxend=%u maxwin=%u scale=%i\n", sender->td_end, sender->td_maxend, sender->td_maxwin, @@ -857,7 +856,7 @@ static int tcp_packet(struct ip_conntrack *conntrack, sizeof(_tcph), &_tcph); BUG_ON(th == NULL); - WRITE_LOCK(&tcp_lock); + write_lock_bh(&tcp_lock); old_state = conntrack->proto.tcp.state; dir = CTINFO2DIR(ctinfo); index = get_conntrack_index(th); @@ -879,7 +878,7 @@ static int tcp_packet(struct ip_conntrack *conntrack, * that the client cannot but retransmit its SYN and * thus initiate a clean new session. */ - WRITE_UNLOCK(&tcp_lock); + write_unlock_bh(&tcp_lock); if (LOG_INVALID(IPPROTO_TCP)) nf_log_packet(PF_INET, 0, skb, NULL, NULL, "ip_ct_tcp: killing out of sync session "); @@ -894,7 +893,7 @@ static int tcp_packet(struct ip_conntrack *conntrack, conntrack->proto.tcp.last_end = segment_seq_plus_len(ntohl(th->seq), skb->len, iph, th); - WRITE_UNLOCK(&tcp_lock); + write_unlock_bh(&tcp_lock); if (LOG_INVALID(IPPROTO_TCP)) nf_log_packet(PF_INET, 0, skb, NULL, NULL, "ip_ct_tcp: invalid packet ignored "); @@ -904,7 +903,7 @@ static int tcp_packet(struct ip_conntrack *conntrack, DEBUGP("ip_ct_tcp: Invalid dir=%i index=%u ostate=%u\n", dir, get_conntrack_index(th), old_state); - WRITE_UNLOCK(&tcp_lock); + write_unlock_bh(&tcp_lock); if (LOG_INVALID(IPPROTO_TCP)) nf_log_packet(PF_INET, 0, skb, NULL, NULL, "ip_ct_tcp: invalid state "); @@ -918,13 +917,13 @@ static int tcp_packet(struct ip_conntrack *conntrack, conntrack->proto.tcp.seen[dir].td_end)) { /* Attempt to reopen a closed connection. * Delete this connection and look up again. */ - WRITE_UNLOCK(&tcp_lock); + write_unlock_bh(&tcp_lock); if (del_timer(&conntrack->timeout)) conntrack->timeout.function((unsigned long) conntrack); return -NF_REPEAT; } else { - WRITE_UNLOCK(&tcp_lock); + write_unlock_bh(&tcp_lock); if (LOG_INVALID(IPPROTO_TCP)) nf_log_packet(PF_INET, 0, skb, NULL, NULL, "ip_ct_tcp: invalid SYN"); @@ -949,7 +948,7 @@ static int tcp_packet(struct ip_conntrack *conntrack, if (!tcp_in_window(&conntrack->proto.tcp, dir, index, skb, iph, th)) { - WRITE_UNLOCK(&tcp_lock); + write_unlock_bh(&tcp_lock); return -NF_ACCEPT; } in_window: @@ -972,7 +971,7 @@ static int tcp_packet(struct ip_conntrack *conntrack, timeout = conntrack->proto.tcp.retrans >= ip_ct_tcp_max_retrans && *tcp_timeouts[new_state] > ip_ct_tcp_timeout_max_retrans ? ip_ct_tcp_timeout_max_retrans : *tcp_timeouts[new_state]; - WRITE_UNLOCK(&tcp_lock); + write_unlock_bh(&tcp_lock); if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) { /* If only reply is a RST, we can consider ourselves not to diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index bc59f7b39805..42dc95102873 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c @@ -28,8 +28,8 @@ #include #include -#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_conntrack_lock) -#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_conntrack_lock) +#define ASSERT_READ_LOCK(x) +#define ASSERT_WRITE_LOCK(x) #include #include @@ -119,7 +119,7 @@ static struct list_head *ct_get_idx(struct seq_file *seq, loff_t pos) static void *ct_seq_start(struct seq_file *seq, loff_t *pos) { - READ_LOCK(&ip_conntrack_lock); + read_lock_bh(&ip_conntrack_lock); return ct_get_idx(seq, *pos); } @@ -131,7 +131,7 @@ static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos) static void ct_seq_stop(struct seq_file *s, void *v) { - READ_UNLOCK(&ip_conntrack_lock); + read_unlock_bh(&ip_conntrack_lock); } static int ct_seq_show(struct seq_file *s, void *v) @@ -140,7 +140,7 @@ static int ct_seq_show(struct seq_file *s, void *v) const struct ip_conntrack *conntrack = tuplehash_to_ctrack(hash); struct ip_conntrack_protocol *proto; - MUST_BE_READ_LOCKED(&ip_conntrack_lock); + ASSERT_READ_LOCK(&ip_conntrack_lock); IP_NF_ASSERT(conntrack); /* we only want to print DIR_ORIGINAL */ @@ -239,7 +239,7 @@ static void *exp_seq_start(struct seq_file *s, loff_t *pos) /* strange seq_file api calls stop even if we fail, * thus we need to grab lock since stop unlocks */ - READ_LOCK(&ip_conntrack_lock); + read_lock_bh(&ip_conntrack_lock); if (list_empty(e)) return NULL; @@ -267,7 +267,7 @@ static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos) static void exp_seq_stop(struct seq_file *s, void *v) { - READ_UNLOCK(&ip_conntrack_lock); + read_unlock_bh(&ip_conntrack_lock); } static int exp_seq_show(struct seq_file *s, void *v) @@ -921,22 +921,22 @@ int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto) { int ret = 0; - WRITE_LOCK(&ip_conntrack_lock); + write_lock_bh(&ip_conntrack_lock); if (ip_ct_protos[proto->proto] != &ip_conntrack_generic_protocol) { ret = -EBUSY; goto out; } ip_ct_protos[proto->proto] = proto; out: - WRITE_UNLOCK(&ip_conntrack_lock); + write_unlock_bh(&ip_conntrack_lock); return ret; } void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto) { - WRITE_LOCK(&ip_conntrack_lock); + write_lock_bh(&ip_conntrack_lock); ip_ct_protos[proto->proto] = &ip_conntrack_generic_protocol; - WRITE_UNLOCK(&ip_conntrack_lock); + write_unlock_bh(&ip_conntrack_lock); /* Somebody could be still looking at the proto in bh. */ synchronize_net(); diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c index 9fc6f93af0dd..739b6dde1c82 100644 --- a/net/ipv4/netfilter/ip_nat_core.c +++ b/net/ipv4/netfilter/ip_nat_core.c @@ -22,8 +22,8 @@ #include #include -#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock) -#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock) +#define ASSERT_READ_LOCK(x) +#define ASSERT_WRITE_LOCK(x) #include #include @@ -41,7 +41,7 @@ #define DEBUGP(format, args...) #endif -DECLARE_RWLOCK(ip_nat_lock); +DEFINE_RWLOCK(ip_nat_lock); /* Calculated at init based on memory size */ static unsigned int ip_nat_htable_size; @@ -65,9 +65,9 @@ static void ip_nat_cleanup_conntrack(struct ip_conntrack *conn) if (!(conn->status & IPS_NAT_DONE_MASK)) return; - WRITE_LOCK(&ip_nat_lock); + write_lock_bh(&ip_nat_lock); list_del(&conn->nat.info.bysource); - WRITE_UNLOCK(&ip_nat_lock); + write_unlock_bh(&ip_nat_lock); } /* We do checksum mangling, so if they were wrong before they're still @@ -142,7 +142,7 @@ find_appropriate_src(const struct ip_conntrack_tuple *tuple, unsigned int h = hash_by_src(tuple); struct ip_conntrack *ct; - READ_LOCK(&ip_nat_lock); + read_lock_bh(&ip_nat_lock); list_for_each_entry(ct, &bysource[h], nat.info.bysource) { if (same_src(ct, tuple)) { /* Copy source part from reply tuple. */ @@ -151,12 +151,12 @@ find_appropriate_src(const struct ip_conntrack_tuple *tuple, result->dst = tuple->dst; if (in_range(result, range)) { - READ_UNLOCK(&ip_nat_lock); + read_unlock_bh(&ip_nat_lock); return 1; } } } - READ_UNLOCK(&ip_nat_lock); + read_unlock_bh(&ip_nat_lock); return 0; } @@ -297,9 +297,9 @@ ip_nat_setup_info(struct ip_conntrack *conntrack, unsigned int srchash = hash_by_src(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL] .tuple); - WRITE_LOCK(&ip_nat_lock); + write_lock_bh(&ip_nat_lock); list_add(&info->bysource, &bysource[srchash]); - WRITE_UNLOCK(&ip_nat_lock); + write_unlock_bh(&ip_nat_lock); } /* It's done. */ @@ -474,23 +474,23 @@ int ip_nat_protocol_register(struct ip_nat_protocol *proto) { int ret = 0; - WRITE_LOCK(&ip_nat_lock); + write_lock_bh(&ip_nat_lock); if (ip_nat_protos[proto->protonum] != &ip_nat_unknown_protocol) { ret = -EBUSY; goto out; } ip_nat_protos[proto->protonum] = proto; out: - WRITE_UNLOCK(&ip_nat_lock); + write_unlock_bh(&ip_nat_lock); return ret; } /* Noone stores the protocol anywhere; simply delete it. */ void ip_nat_protocol_unregister(struct ip_nat_protocol *proto) { - WRITE_LOCK(&ip_nat_lock); + write_lock_bh(&ip_nat_lock); ip_nat_protos[proto->protonum] = &ip_nat_unknown_protocol; - WRITE_UNLOCK(&ip_nat_lock); + write_unlock_bh(&ip_nat_lock); /* Someone could be still looking at the proto in a bh. */ synchronize_net(); @@ -509,13 +509,13 @@ int __init ip_nat_init(void) return -ENOMEM; /* Sew in builtin protocols. */ - WRITE_LOCK(&ip_nat_lock); + write_lock_bh(&ip_nat_lock); for (i = 0; i < MAX_IP_NAT_PROTO; i++) ip_nat_protos[i] = &ip_nat_unknown_protocol; ip_nat_protos[IPPROTO_TCP] = &ip_nat_protocol_tcp; ip_nat_protos[IPPROTO_UDP] = &ip_nat_protocol_udp; ip_nat_protos[IPPROTO_ICMP] = &ip_nat_protocol_icmp; - WRITE_UNLOCK(&ip_nat_lock); + write_unlock_bh(&ip_nat_lock); for (i = 0; i < ip_nat_htable_size; i++) { INIT_LIST_HEAD(&bysource[i]); diff --git a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c index 1637b96d8c01..9cd51f180dcf 100644 --- a/net/ipv4/netfilter/ip_nat_helper.c +++ b/net/ipv4/netfilter/ip_nat_helper.c @@ -28,8 +28,8 @@ #include #include -#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock) -#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock) +#define ASSERT_READ_LOCK(x) +#define ASSERT_WRITE_LOCK(x) #include #include @@ -47,7 +47,7 @@ #define DUMP_OFFSET(x) #endif -static DECLARE_LOCK(ip_nat_seqofs_lock); +static DEFINE_SPINLOCK(ip_nat_seqofs_lock); /* Setup TCP sequence correction given this change at this sequence */ static inline void @@ -70,7 +70,7 @@ adjust_tcp_sequence(u32 seq, DEBUGP("ip_nat_resize_packet: Seq_offset before: "); DUMP_OFFSET(this_way); - LOCK_BH(&ip_nat_seqofs_lock); + spin_lock_bh(&ip_nat_seqofs_lock); /* SYN adjust. If it's uninitialized, or this is after last * correction, record it: we don't handle more than one @@ -82,7 +82,7 @@ adjust_tcp_sequence(u32 seq, this_way->offset_before = this_way->offset_after; this_way->offset_after += sizediff; } - UNLOCK_BH(&ip_nat_seqofs_lock); + spin_unlock_bh(&ip_nat_seqofs_lock); DEBUGP("ip_nat_resize_packet: Seq_offset after: "); DUMP_OFFSET(this_way); diff --git a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c index 581f097f5a24..60d70fa41a15 100644 --- a/net/ipv4/netfilter/ip_nat_rule.c +++ b/net/ipv4/netfilter/ip_nat_rule.c @@ -19,8 +19,8 @@ #include #include -#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock) -#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock) +#define ASSERT_READ_LOCK(x) +#define ASSERT_WRITE_LOCK(x) #include #include diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 79f56f662b33..bc59d0d6e89e 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c @@ -31,8 +31,8 @@ #include #include -#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock) -#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock) +#define ASSERT_READ_LOCK(x) +#define ASSERT_WRITE_LOCK(x) #include #include @@ -373,7 +373,6 @@ static int init_or_cleanup(int init) cleanup_rule_init: ip_nat_rule_cleanup(); cleanup_nothing: - MUST_BE_READ_WRITE_UNLOCKED(&ip_nat_lock); return ret; } diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 8a54f92b8496..c88dfcd38c56 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -67,7 +67,6 @@ static DECLARE_MUTEX(ipt_mutex); /* Must have mutex */ #define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0) #define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0) -#include #include #if 0 diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 0f12e3a3dc73..dc4362b57cfa 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -29,7 +29,6 @@ #include #include #include -#include #define CLUSTERIP_VERSION "0.6" @@ -41,6 +40,8 @@ #define DEBUGP #endif +#define ASSERT_READ_LOCK(x) + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Harald Welte "); MODULE_DESCRIPTION("iptables target for CLUSTERIP"); @@ -67,7 +68,7 @@ static LIST_HEAD(clusterip_configs); /* clusterip_lock protects the clusterip_configs list _AND_ the configurable * data within all structurses (num_local_nodes, local_nodes[]) */ -static DECLARE_RWLOCK(clusterip_lock); +static DEFINE_RWLOCK(clusterip_lock); #ifdef CONFIG_PROC_FS static struct file_operations clusterip_proc_fops; @@ -82,9 +83,9 @@ clusterip_config_get(struct clusterip_config *c) { static inline void clusterip_config_put(struct clusterip_config *c) { if (atomic_dec_and_test(&c->refcount)) { - WRITE_LOCK(&clusterip_lock); + write_lock_bh(&clusterip_lock); list_del(&c->list); - WRITE_UNLOCK(&clusterip_lock); + write_unlock_bh(&clusterip_lock); dev_mc_delete(c->dev, c->clustermac, ETH_ALEN, 0); dev_put(c->dev); kfree(c); @@ -97,7 +98,7 @@ __clusterip_config_find(u_int32_t clusterip) { struct list_head *pos; - MUST_BE_READ_LOCKED(&clusterip_lock); + ASSERT_READ_LOCK(&clusterip_lock); list_for_each(pos, &clusterip_configs) { struct clusterip_config *c = list_entry(pos, struct clusterip_config, list); @@ -114,14 +115,14 @@ clusterip_config_find_get(u_int32_t clusterip) { struct clusterip_config *c; - READ_LOCK(&clusterip_lock); + read_lock_bh(&clusterip_lock); c = __clusterip_config_find(clusterip); if (!c) { - READ_UNLOCK(&clusterip_lock); + read_unlock_bh(&clusterip_lock); return NULL; } atomic_inc(&c->refcount); - READ_UNLOCK(&clusterip_lock); + read_unlock_bh(&clusterip_lock); return c; } @@ -160,9 +161,9 @@ clusterip_config_init(struct ipt_clusterip_tgt_info *i, u_int32_t ip, c->pde->data = c; #endif - WRITE_LOCK(&clusterip_lock); + write_lock_bh(&clusterip_lock); list_add(&c->list, &clusterip_configs); - WRITE_UNLOCK(&clusterip_lock); + write_unlock_bh(&clusterip_lock); return c; } @@ -172,25 +173,25 @@ clusterip_add_node(struct clusterip_config *c, u_int16_t nodenum) { int i; - WRITE_LOCK(&clusterip_lock); + write_lock_bh(&clusterip_lock); if (c->num_local_nodes >= CLUSTERIP_MAX_NODES || nodenum > CLUSTERIP_MAX_NODES) { - WRITE_UNLOCK(&clusterip_lock); + write_unlock_bh(&clusterip_lock); return 1; } /* check if we alrady have this number in our array */ for (i = 0; i < c->num_local_nodes; i++) { if (c->local_nodes[i] == nodenum) { - WRITE_UNLOCK(&clusterip_lock); + write_unlock_bh(&clusterip_lock); return 1; } } c->local_nodes[c->num_local_nodes++] = nodenum; - WRITE_UNLOCK(&clusterip_lock); + write_unlock_bh(&clusterip_lock); return 0; } @@ -199,10 +200,10 @@ clusterip_del_node(struct clusterip_config *c, u_int16_t nodenum) { int i; - WRITE_LOCK(&clusterip_lock); + write_lock_bh(&clusterip_lock); if (c->num_local_nodes <= 1 || nodenum > CLUSTERIP_MAX_NODES) { - WRITE_UNLOCK(&clusterip_lock); + write_unlock_bh(&clusterip_lock); return 1; } @@ -211,12 +212,12 @@ clusterip_del_node(struct clusterip_config *c, u_int16_t nodenum) int size = sizeof(u_int16_t)*(c->num_local_nodes-(i+1)); memmove(&c->local_nodes[i], &c->local_nodes[i+1], size); c->num_local_nodes--; - WRITE_UNLOCK(&clusterip_lock); + write_unlock_bh(&clusterip_lock); return 0; } } - WRITE_UNLOCK(&clusterip_lock); + write_unlock_bh(&clusterip_lock); return 1; } @@ -286,21 +287,21 @@ clusterip_responsible(struct clusterip_config *config, u_int32_t hash) { int i; - READ_LOCK(&clusterip_lock); + read_lock_bh(&clusterip_lock); if (config->num_local_nodes == 0) { - READ_UNLOCK(&clusterip_lock); + read_unlock_bh(&clusterip_lock); return 0; } for (i = 0; i < config->num_local_nodes; i++) { if (config->local_nodes[i] == hash) { - READ_UNLOCK(&clusterip_lock); + read_unlock_bh(&clusterip_lock); return 1; } } - READ_UNLOCK(&clusterip_lock); + read_unlock_bh(&clusterip_lock); return 0; } @@ -578,7 +579,7 @@ static void *clusterip_seq_start(struct seq_file *s, loff_t *pos) struct clusterip_config *c = pde->data; unsigned int *nodeidx; - READ_LOCK(&clusterip_lock); + read_lock_bh(&clusterip_lock); if (*pos >= c->num_local_nodes) return NULL; @@ -608,7 +609,7 @@ static void clusterip_seq_stop(struct seq_file *s, void *v) { kfree(v); - READ_UNLOCK(&clusterip_lock); + read_unlock_bh(&clusterip_lock); } static int clusterip_seq_show(struct seq_file *s, void *v) diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c index 57e9f6cf1c36..91e74502c3d3 100644 --- a/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c @@ -33,7 +33,7 @@ MODULE_DESCRIPTION("iptables MASQUERADE target module"); #endif /* Lock protects masq region inside conntrack */ -static DECLARE_RWLOCK(masq_lock); +static DEFINE_RWLOCK(masq_lock); /* FIXME: Multiple targets. --RR */ static int @@ -103,9 +103,9 @@ masquerade_target(struct sk_buff **pskb, return NF_DROP; } - WRITE_LOCK(&masq_lock); + write_lock_bh(&masq_lock); ct->nat.masq_index = out->ifindex; - WRITE_UNLOCK(&masq_lock); + write_unlock_bh(&masq_lock); /* Transfer from original range. */ newrange = ((struct ip_nat_range) @@ -122,9 +122,9 @@ device_cmp(struct ip_conntrack *i, void *ifindex) { int ret; - READ_LOCK(&masq_lock); + read_lock_bh(&masq_lock); ret = (i->nat.masq_index == (int)(long)ifindex); - READ_UNLOCK(&masq_lock); + read_unlock_bh(&masq_lock); return ret; } diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index 6f2cefbe16cd..52a0076302a7 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c @@ -56,7 +56,6 @@ #include #include #include -#include #include #include @@ -99,8 +98,8 @@ typedef struct { static ulog_buff_t ulog_buffers[ULOG_MAXNLGROUPS]; /* array of buffers */ -static struct sock *nflognl; /* our socket */ -static DECLARE_LOCK(ulog_lock); /* spinlock */ +static struct sock *nflognl; /* our socket */ +static DEFINE_SPINLOCK(ulog_lock); /* spinlock */ /* send one ulog_buff_t to userspace */ static void ulog_send(unsigned int nlgroupnum) @@ -135,9 +134,9 @@ static void ulog_timer(unsigned long data) /* lock to protect against somebody modifying our structure * from ipt_ulog_target at the same time */ - LOCK_BH(&ulog_lock); + spin_lock_bh(&ulog_lock); ulog_send(data); - UNLOCK_BH(&ulog_lock); + spin_unlock_bh(&ulog_lock); } static struct sk_buff *ulog_alloc_skb(unsigned int size) @@ -193,7 +192,7 @@ static void ipt_ulog_packet(unsigned int hooknum, ub = &ulog_buffers[groupnum]; - LOCK_BH(&ulog_lock); + spin_lock_bh(&ulog_lock); if (!ub->skb) { if (!(ub->skb = ulog_alloc_skb(size))) @@ -278,7 +277,7 @@ static void ipt_ulog_packet(unsigned int hooknum, ulog_send(groupnum); } - UNLOCK_BH(&ulog_lock); + spin_unlock_bh(&ulog_lock); return; @@ -288,7 +287,7 @@ nlmsg_failure: alloc_failure: PRINTR("ipt_ULOG: Error building netlink message\n"); - UNLOCK_BH(&ulog_lock); + spin_unlock_bh(&ulog_lock); } static unsigned int ipt_ulog_target(struct sk_buff **pskb, diff --git a/net/ipv4/netfilter/ipt_hashlimit.c b/net/ipv4/netfilter/ipt_hashlimit.c index f1937190cd77..564b49bfebcf 100644 --- a/net/ipv4/netfilter/ipt_hashlimit.c +++ b/net/ipv4/netfilter/ipt_hashlimit.c @@ -37,7 +37,6 @@ #include #include -#include /* FIXME: this is just for IP_NF_ASSERRT */ #include @@ -92,7 +91,7 @@ struct ipt_hashlimit_htable { struct hlist_head hash[0]; /* hashtable itself */ }; -static DECLARE_LOCK(hashlimit_lock); /* protects htables list */ +static DEFINE_SPINLOCK(hashlimit_lock); /* protects htables list */ static DECLARE_MUTEX(hlimit_mutex); /* additional checkentry protection */ static HLIST_HEAD(hashlimit_htables); static kmem_cache_t *hashlimit_cachep; @@ -233,9 +232,9 @@ static int htable_create(struct ipt_hashlimit_info *minfo) hinfo->timer.function = htable_gc; add_timer(&hinfo->timer); - LOCK_BH(&hashlimit_lock); + spin_lock_bh(&hashlimit_lock); hlist_add_head(&hinfo->node, &hashlimit_htables); - UNLOCK_BH(&hashlimit_lock); + spin_unlock_bh(&hashlimit_lock); return 0; } @@ -301,15 +300,15 @@ static struct ipt_hashlimit_htable *htable_find_get(char *name) struct ipt_hashlimit_htable *hinfo; struct hlist_node *pos; - LOCK_BH(&hashlimit_lock); + spin_lock_bh(&hashlimit_lock); hlist_for_each_entry(hinfo, pos, &hashlimit_htables, node) { if (!strcmp(name, hinfo->pde->name)) { atomic_inc(&hinfo->use); - UNLOCK_BH(&hashlimit_lock); + spin_unlock_bh(&hashlimit_lock); return hinfo; } } - UNLOCK_BH(&hashlimit_lock); + spin_unlock_bh(&hashlimit_lock); return NULL; } @@ -317,9 +316,9 @@ static struct ipt_hashlimit_htable *htable_find_get(char *name) static void htable_put(struct ipt_hashlimit_htable *hinfo) { if (atomic_dec_and_test(&hinfo->use)) { - LOCK_BH(&hashlimit_lock); + spin_lock_bh(&hashlimit_lock); hlist_del(&hinfo->node); - UNLOCK_BH(&hashlimit_lock); + spin_unlock_bh(&hashlimit_lock); htable_destroy(hinfo); } } diff --git a/net/ipv4/netfilter/ipt_helper.c b/net/ipv4/netfilter/ipt_helper.c index 33fdf364d3d3..3e7dd014de43 100644 --- a/net/ipv4/netfilter/ipt_helper.c +++ b/net/ipv4/netfilter/ipt_helper.c @@ -53,7 +53,7 @@ match(const struct sk_buff *skb, return ret; } - READ_LOCK(&ip_conntrack_lock); + read_lock_bh(&ip_conntrack_lock); if (!ct->master->helper) { DEBUGP("ipt_helper: master ct %p has no helper\n", exp->expectant); @@ -69,7 +69,7 @@ match(const struct sk_buff *skb, ret ^= !strncmp(ct->master->helper->name, info->name, strlen(ct->master->helper->name)); out_unlock: - READ_UNLOCK(&ip_conntrack_lock); + read_unlock_bh(&ip_conntrack_lock); return ret; } diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index c735276fdd5f..73034511c8db 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -71,7 +71,6 @@ static DECLARE_MUTEX(ip6t_mutex); /* Must have mutex */ #define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0) #define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0) -#include #include #if 0 -- cgit v1.2.3-59-g8ed1b From 18b8afc771102b1b6af97962808291a7d27f52af Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 21 Jun 2005 14:01:57 -0700 Subject: [NETFILTER]: Kill nf_debug Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter_ipv4.h | 6 -- include/linux/skbuff.h | 13 ---- net/bridge/br_forward.c | 3 - net/bridge/br_input.c | 4 - net/bridge/br_netfilter.c | 38 --------- net/core/netfilter.c | 138 --------------------------------- net/core/skbuff.c | 6 -- net/ipv4/ip_input.c | 4 - net/ipv4/ip_output.c | 11 --- net/ipv4/ipvs/ip_vs_xmit.c | 1 - net/ipv4/netfilter/ip_conntrack_core.c | 9 --- net/ipv4/netfilter/ip_nat_helper.c | 3 - net/ipv6/ip6_output.c | 3 - 13 files changed, 239 deletions(-) diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h index 9e5750079e09..3ebc36afae1a 100644 --- a/include/linux/netfilter_ipv4.h +++ b/include/linux/netfilter_ipv4.h @@ -75,12 +75,6 @@ enum nf_ip_hook_priorities { #define SO_ORIGINAL_DST 80 #ifdef __KERNEL__ -#ifdef CONFIG_NETFILTER_DEBUG -void nf_debug_ip_local_deliver(struct sk_buff *skb); -void nf_debug_ip_loopback_xmit(struct sk_buff *newskb); -void nf_debug_ip_finish_output2(struct sk_buff *skb); -#endif /*CONFIG_NETFILTER_DEBUG*/ - extern int ip_route_me_harder(struct sk_buff **pskb); /* Call this before modifying an existing IP packet: ensures it is diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index cc04f5cd2286..d7c839a21842 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -193,7 +193,6 @@ struct skb_shared_info { * @nfcache: Cache info * @nfct: Associated connection, if any * @nfctinfo: Relationship of this skb to the connection - * @nf_debug: Netfilter debugging * @nf_bridge: Saved data about a bridged frame - see br_netfilter.c * @private: Data which is private to the HIPPI implementation * @tc_index: Traffic control index @@ -264,9 +263,6 @@ struct sk_buff { __u32 nfcache; __u32 nfctinfo; struct nf_conntrack *nfct; -#ifdef CONFIG_NETFILTER_DEBUG - unsigned int nf_debug; -#endif #ifdef CONFIG_BRIDGE_NETFILTER struct nf_bridge_info *nf_bridge; #endif @@ -1219,15 +1215,6 @@ static inline void nf_reset(struct sk_buff *skb) { nf_conntrack_put(skb->nfct); skb->nfct = NULL; -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug = 0; -#endif -} -static inline void nf_reset_debug(struct sk_buff *skb) -{ -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug = 0; -#endif } #ifdef CONFIG_BRIDGE_NETFILTER diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index ef9f2095f96e..069253f830c1 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -57,9 +57,6 @@ int br_forward_finish(struct sk_buff *skb) static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb) { skb->dev = to->dev; -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug = 0; -#endif NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, br_forward_finish); } diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 8f5f2e730992..9a45e6279c57 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -23,11 +23,7 @@ const unsigned char bridge_ula[6] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; static int br_pass_frame_up_finish(struct sk_buff *skb) { -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug = 0; -#endif netif_receive_skb(skb); - return 0; } diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index be03d3ad2648..03ae4edddac3 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -102,10 +102,6 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb) { struct nf_bridge_info *nf_bridge = skb->nf_bridge; -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug ^= (1 << NF_BR_PRE_ROUTING); -#endif - if (nf_bridge->mask & BRNF_PKT_TYPE) { skb->pkt_type = PACKET_OTHERHOST; nf_bridge->mask ^= BRNF_PKT_TYPE; @@ -182,10 +178,6 @@ static void __br_dnat_complain(void) * --Bart, 20021007 (updated) */ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb) { -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug |= (1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_FORWARD); -#endif - if (skb->pkt_type == PACKET_OTHERHOST) { skb->pkt_type = PACKET_HOST; skb->nf_bridge->mask |= BRNF_PKT_TYPE; @@ -207,10 +199,6 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb) struct iphdr *iph = skb->nh.iph; struct nf_bridge_info *nf_bridge = skb->nf_bridge; -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug ^= (1 << NF_BR_PRE_ROUTING); -#endif - if (nf_bridge->mask & BRNF_PKT_TYPE) { skb->pkt_type = PACKET_OTHERHOST; nf_bridge->mask ^= BRNF_PKT_TYPE; @@ -382,9 +370,6 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook, if (hdr->nexthdr == NEXTHDR_HOP && check_hbh_len(skb)) goto inhdr_error; -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug ^= (1 << NF_IP6_PRE_ROUTING); -#endif if ((nf_bridge = nf_bridge_alloc(skb)) == NULL) return NF_DROP; setup_pre_routing(skb); @@ -468,9 +453,6 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb, skb->ip_summed = CHECKSUM_NONE; } -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug ^= (1 << NF_IP_PRE_ROUTING); -#endif if ((nf_bridge = nf_bridge_alloc(skb)) == NULL) return NF_DROP; setup_pre_routing(skb); @@ -517,10 +499,6 @@ static int br_nf_forward_finish(struct sk_buff *skb) struct net_device *in; struct vlan_ethhdr *hdr = vlan_eth_hdr(skb); -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug ^= (1 << NF_BR_FORWARD); -#endif - if (skb->protocol != __constant_htons(ETH_P_ARP) && !IS_VLAN_ARP) { in = nf_bridge->physindev; if (nf_bridge->mask & BRNF_PKT_TYPE) { @@ -566,9 +544,6 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb, (*pskb)->nh.raw += VLAN_HLEN; } -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug ^= (1 << NF_BR_FORWARD); -#endif nf_bridge = skb->nf_bridge; if (skb->pkt_type == PACKET_OTHERHOST) { skb->pkt_type = PACKET_HOST; @@ -605,10 +580,6 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb, (*pskb)->nh.raw += VLAN_HLEN; } -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug ^= (1 << NF_BR_FORWARD); -#endif - if (skb->nh.arph->ar_pln != 4) { if (IS_VLAN_ARP) { skb_push(*pskb, VLAN_HLEN); @@ -627,9 +598,6 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb, /* PF_BRIDGE/LOCAL_OUT ***********************************************/ static int br_nf_local_out_finish(struct sk_buff *skb) { -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug &= ~(1 << NF_BR_LOCAL_OUT); -#endif if (skb->protocol == __constant_htons(ETH_P_8021Q)) { skb_push(skb, VLAN_HLEN); skb->nh.raw -= VLAN_HLEN; @@ -731,10 +699,6 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb, realoutdev, br_nf_local_out_finish, NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD + 1); } else { -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug ^= (1 << NF_IP_LOCAL_OUT); -#endif - NF_HOOK_THRESH(pf, NF_IP_LOCAL_OUT, skb, realindev, realoutdev, br_nf_local_out_finish, NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT + 1); @@ -779,8 +743,6 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, printk(KERN_CRIT "br_netfilter: skb->dst == NULL."); goto print_error; } - - skb->nf_debug ^= (1 << NF_IP_POST_ROUTING); #endif /* We assume any code from br_dev_queue_push_xmit onwards doesn't care diff --git a/net/core/netfilter.c b/net/core/netfilter.c index 22a8f127c4aa..076c156d5eda 100644 --- a/net/core/netfilter.c +++ b/net/core/netfilter.c @@ -141,136 +141,6 @@ void nf_unregister_sockopt(struct nf_sockopt_ops *reg) up(&nf_sockopt_mutex); } -#ifdef CONFIG_NETFILTER_DEBUG -#include -#include -#include - -static void debug_print_hooks_ip(unsigned int nf_debug) -{ - if (nf_debug & (1 << NF_IP_PRE_ROUTING)) { - printk("PRE_ROUTING "); - nf_debug ^= (1 << NF_IP_PRE_ROUTING); - } - if (nf_debug & (1 << NF_IP_LOCAL_IN)) { - printk("LOCAL_IN "); - nf_debug ^= (1 << NF_IP_LOCAL_IN); - } - if (nf_debug & (1 << NF_IP_FORWARD)) { - printk("FORWARD "); - nf_debug ^= (1 << NF_IP_FORWARD); - } - if (nf_debug & (1 << NF_IP_LOCAL_OUT)) { - printk("LOCAL_OUT "); - nf_debug ^= (1 << NF_IP_LOCAL_OUT); - } - if (nf_debug & (1 << NF_IP_POST_ROUTING)) { - printk("POST_ROUTING "); - nf_debug ^= (1 << NF_IP_POST_ROUTING); - } - if (nf_debug) - printk("Crap bits: 0x%04X", nf_debug); - printk("\n"); -} - -static void nf_dump_skb(int pf, struct sk_buff *skb) -{ - printk("skb: pf=%i %s dev=%s len=%u\n", - pf, - skb->sk ? "(owned)" : "(unowned)", - skb->dev ? skb->dev->name : "(no dev)", - skb->len); - switch (pf) { - case PF_INET: { - const struct iphdr *ip = skb->nh.iph; - __u32 *opt = (__u32 *) (ip + 1); - int opti; - __u16 src_port = 0, dst_port = 0; - - if (ip->protocol == IPPROTO_TCP - || ip->protocol == IPPROTO_UDP) { - struct tcphdr *tcp=(struct tcphdr *)((__u32 *)ip+ip->ihl); - src_port = ntohs(tcp->source); - dst_port = ntohs(tcp->dest); - } - - printk("PROTO=%d %u.%u.%u.%u:%hu %u.%u.%u.%u:%hu" - " L=%hu S=0x%2.2hX I=%hu F=0x%4.4hX T=%hu", - ip->protocol, NIPQUAD(ip->saddr), - src_port, NIPQUAD(ip->daddr), - dst_port, - ntohs(ip->tot_len), ip->tos, ntohs(ip->id), - ntohs(ip->frag_off), ip->ttl); - - for (opti = 0; opti < (ip->ihl - sizeof(struct iphdr) / 4); opti++) - printk(" O=0x%8.8X", *opt++); - printk("\n"); - } - } -} - -void nf_debug_ip_local_deliver(struct sk_buff *skb) -{ - /* If it's a loopback packet, it must have come through - * NF_IP_LOCAL_OUT, NF_IP_RAW_INPUT, NF_IP_PRE_ROUTING and - * NF_IP_LOCAL_IN. Otherwise, must have gone through - * NF_IP_RAW_INPUT and NF_IP_PRE_ROUTING. */ - if (!skb->dev) { - printk("ip_local_deliver: skb->dev is NULL.\n"); - } else { - if (skb->nf_debug != ((1<nf_debug); - nf_dump_skb(PF_INET, skb); - } - } -} - -void nf_debug_ip_loopback_xmit(struct sk_buff *newskb) -{ - if (newskb->nf_debug != ((1 << NF_IP_LOCAL_OUT) - | (1 << NF_IP_POST_ROUTING))) { - printk("ip_dev_loopback_xmit: bad owned skb = %p: ", - newskb); - debug_print_hooks_ip(newskb->nf_debug); - nf_dump_skb(PF_INET, newskb); - } -} - -void nf_debug_ip_finish_output2(struct sk_buff *skb) -{ - /* If it's owned, it must have gone through the - * NF_IP_LOCAL_OUT and NF_IP_POST_ROUTING. - * Otherwise, must have gone through - * NF_IP_PRE_ROUTING, NF_IP_FORWARD and NF_IP_POST_ROUTING. - */ - if (skb->sk) { - if (skb->nf_debug != ((1 << NF_IP_LOCAL_OUT) - | (1 << NF_IP_POST_ROUTING))) { - printk("ip_finish_output: bad owned skb = %p: ", skb); - debug_print_hooks_ip(skb->nf_debug); - nf_dump_skb(PF_INET, skb); - } - } else { - if (skb->nf_debug != ((1 << NF_IP_PRE_ROUTING) - | (1 << NF_IP_FORWARD) - | (1 << NF_IP_POST_ROUTING))) { - /* Fragments, entunnelled packets, TCP RSTs - generated by ipt_REJECT will have no - owners, but still may be local */ - if (skb->nf_debug != ((1 << NF_IP_LOCAL_OUT) - | (1 << NF_IP_POST_ROUTING))){ - printk("ip_finish_output:" - " bad unowned skb = %p: ",skb); - debug_print_hooks_ip(skb->nf_debug); - nf_dump_skb(PF_INET, skb); - } - } - } -} -#endif /*CONFIG_NETFILTER_DEBUG*/ - /* Call get/setsockopt() */ static int nf_sockopt(struct sock *sk, int pf, int val, char __user *opt, int *len, int get) @@ -488,14 +358,6 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb, /* We may already have this, but read-locks nest anyway */ rcu_read_lock(); -#ifdef CONFIG_NETFILTER_DEBUG - if (unlikely((*pskb)->nf_debug & (1 << hook))) { - printk("nf_hook: hook %i already set.\n", hook); - nf_dump_skb(pf, *pskb); - } - (*pskb)->nf_debug |= (1 << hook); -#endif - elem = &nf_hooks[pf][hook]; next_hook: verdict = nf_iterate(&nf_hooks[pf][hook], pskb, hook, indev, diff --git a/net/core/skbuff.c b/net/core/skbuff.c index f65b3de590a9..6d68c03bc051 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -365,9 +365,6 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask) C(nfct); nf_conntrack_get(skb->nfct); C(nfctinfo); -#ifdef CONFIG_NETFILTER_DEBUG - C(nf_debug); -#endif #ifdef CONFIG_BRIDGE_NETFILTER C(nf_bridge); nf_bridge_get(skb->nf_bridge); @@ -432,9 +429,6 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) new->nfct = old->nfct; nf_conntrack_get(old->nfct); new->nfctinfo = old->nfctinfo; -#ifdef CONFIG_NETFILTER_DEBUG - new->nf_debug = old->nf_debug; -#endif #ifdef CONFIG_BRIDGE_NETFILTER new->nf_bridge = old->nf_bridge; nf_bridge_get(old->nf_bridge); diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 4e47a2658c7c..2b7485e65040 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -200,10 +200,6 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb) { int ihl = skb->nh.iph->ihl*4; -#ifdef CONFIG_NETFILTER_DEBUG - nf_debug_ip_local_deliver(skb); -#endif /*CONFIG_NETFILTER_DEBUG*/ - __skb_pull(skb, ihl); /* Free reference early: we don't need it any more, and it may diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 760dc8238d65..ee07aec215a0 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -107,10 +107,6 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb) newskb->pkt_type = PACKET_LOOPBACK; newskb->ip_summed = CHECKSUM_UNNECESSARY; BUG_TRAP(newskb->dst); - -#ifdef CONFIG_NETFILTER_DEBUG - nf_debug_ip_loopback_xmit(newskb); -#endif nf_reset(newskb); netif_rx(newskb); return 0; @@ -192,10 +188,6 @@ static inline int ip_finish_output2(struct sk_buff *skb) skb = skb2; } -#ifdef CONFIG_NETFILTER_DEBUG - nf_debug_ip_finish_output2(skb); -#endif /*CONFIG_NETFILTER_DEBUG*/ - nf_reset(skb); if (hh) { @@ -415,9 +407,6 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from) to->nf_bridge = from->nf_bridge; nf_bridge_get(to->nf_bridge); #endif -#ifdef CONFIG_NETFILTER_DEBUG - to->nf_debug = from->nf_debug; -#endif #endif } diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c index de21da00057f..a8512a3fd08a 100644 --- a/net/ipv4/ipvs/ip_vs_xmit.c +++ b/net/ipv4/ipvs/ip_vs_xmit.c @@ -127,7 +127,6 @@ ip_vs_dst_reset(struct ip_vs_dest *dest) #define IP_VS_XMIT(skb, rt) \ do { \ - nf_reset_debug(skb); \ (skb)->nfcache |= NFC_IPVS_PROPERTY; \ (skb)->ip_summed = CHECKSUM_NONE; \ NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, (skb), NULL, \ diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index a7377a331ade..ffba0ad3c880 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c @@ -940,10 +940,6 @@ void ip_ct_refresh_acct(struct ip_conntrack *ct, struct sk_buff * ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user) { -#ifdef CONFIG_NETFILTER_DEBUG - unsigned int olddebug = skb->nf_debug; -#endif - skb_orphan(skb); local_bh_disable(); @@ -953,12 +949,7 @@ ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user) if (skb) { ip_send_check(skb->nh.iph); skb->nfcache |= NFC_ALTERED; -#ifdef CONFIG_NETFILTER_DEBUG - /* Packet path as if nothing had happened. */ - skb->nf_debug = olddebug; -#endif } - return skb; } diff --git a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c index 9cd51f180dcf..158f34f32c04 100644 --- a/net/ipv4/netfilter/ip_nat_helper.c +++ b/net/ipv4/netfilter/ip_nat_helper.c @@ -142,9 +142,6 @@ static int enlarge_skb(struct sk_buff **pskb, unsigned int extra) /* Transfer socket to new skb. */ if ((*pskb)->sk) skb_set_owner_w(nskb, (*pskb)->sk); -#ifdef CONFIG_NETFILTER_DEBUG - nskb->nf_debug = (*pskb)->nf_debug; -#endif kfree_skb(*pskb); *pskb = nskb; return 1; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index b78a53586804..06e7cdaeedc5 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -484,9 +484,6 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from) to->nf_bridge = from->nf_bridge; nf_bridge_get(to->nf_bridge); #endif -#ifdef CONFIG_NETFILTER_DEBUG - to->nf_debug = from->nf_debug; -#endif #endif } -- cgit v1.2.3-59-g8ed1b From e98231858bbfd2aca42f93d55133c2fca6df00f9 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 21 Jun 2005 14:02:15 -0700 Subject: [NETFILTER]: Restore netfilter assumptions in IPv6 multicast Netfilter assumes that skb->data == skb->nh.ipv6h Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv6/mcast.c | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index c0ca92e8230b..562fcd14fdea 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -1301,15 +1301,6 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) return NULL; skb_reserve(skb, LL_RESERVED_SPACE(dev)); - if (dev->hard_header) { - unsigned char ha[MAX_ADDR_LEN]; - - ndisc_mc_map(&mld2_all_mcr, ha, dev, 1); - if (dev->hard_header(skb, dev, ETH_P_IPV6,ha,NULL,size) < 0) { - kfree_skb(skb); - return NULL; - } - } if (ipv6_get_lladdr(dev, &addr_buf)) { /* : @@ -1333,6 +1324,30 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) return skb; } +static inline int mld_dev_queue_xmit2(struct sk_buff *skb) +{ + struct net_device *dev = skb->dev; + + if (dev->hard_header) { + unsigned char ha[MAX_ADDR_LEN]; + int err; + + ndisc_mc_map(&skb->nh.ipv6h->daddr, ha, dev, 1); + err = dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, skb->len); + if (err < 0) { + kfree_skb(skb); + return err; + } + } + return dev_queue_xmit(skb); +} + +static inline int mld_dev_queue_xmit(struct sk_buff *skb) +{ + return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dev, + mld_dev_queue_xmit2); +} + static void mld_sendpack(struct sk_buff *skb) { struct ipv6hdr *pip6 = skb->nh.ipv6h; @@ -1350,7 +1365,7 @@ static void mld_sendpack(struct sk_buff *skb) pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen, IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0)); err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev, - dev_queue_xmit); + mld_dev_queue_xmit); if (!err) { ICMP6_INC_STATS(idev,ICMP6_MIB_OUTMSGS); IP6_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS); @@ -1656,12 +1671,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) } skb_reserve(skb, LL_RESERVED_SPACE(dev)); - if (dev->hard_header) { - unsigned char ha[MAX_ADDR_LEN]; - ndisc_mc_map(snd_addr, ha, dev, 1); - if (dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, full_len) < 0) - goto out; - } if (ipv6_get_lladdr(dev, &addr_buf)) { /* : @@ -1689,7 +1698,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) idev = in6_dev_get(skb->dev); err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev, - dev_queue_xmit); + mld_dev_queue_xmit); if (!err) { if (type == ICMPV6_MGM_REDUCTION) ICMP6_INC_STATS(idev, ICMP6_MIB_OUTGROUPMEMBREDUCTIONS); @@ -1703,10 +1712,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) if (likely(idev != NULL)) in6_dev_put(idev); return; - -out: - IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); - kfree_skb(skb); } static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode, -- cgit v1.2.3-59-g8ed1b From 1d3cdb41f52e299f70b66cbb569bff5216f3643a Mon Sep 17 00:00:00 2001 From: Phil Oester Date: Tue, 21 Jun 2005 14:02:42 -0700 Subject: [NETFILTER]: expectation timeouts are compulsory Since expectation timeouts were made compulsory [1], there is no need to check for them in ip_conntrack_expect_insert. [1] https://lists.netfilter.org/pipermail/netfilter-devel/2005-January/018143.html Signed-off-by: Phil Oester Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/ip_conntrack_core.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index ffba0ad3c880..4b78ebeb6635 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c @@ -760,15 +760,11 @@ static void ip_conntrack_expect_insert(struct ip_conntrack_expect *exp) exp->master->expecting++; list_add(&exp->list, &ip_conntrack_expect_list); - if (exp->master->helper->timeout) { - init_timer(&exp->timeout); - exp->timeout.data = (unsigned long)exp; - exp->timeout.function = expectation_timed_out; - exp->timeout.expires - = jiffies + exp->master->helper->timeout * HZ; - add_timer(&exp->timeout); - } else - exp->timeout.function = NULL; + init_timer(&exp->timeout); + exp->timeout.data = (unsigned long)exp; + exp->timeout.function = expectation_timed_out; + exp->timeout.expires = jiffies + exp->master->helper->timeout * HZ; + add_timer(&exp->timeout); CONNTRACK_STAT_INC(expect_create); } -- cgit v1.2.3-59-g8ed1b From 97216c799a6496163be8c81c9ceed297d92956c5 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 21 Jun 2005 14:03:01 -0700 Subject: [NETFILTER]: Missing owner-field initialization in ip6table_raw I missed this one when fixing up iptable_raw. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv6/netfilter/ip6table_raw.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c index 71407beaf790..c2982efd14af 100644 --- a/net/ipv6/netfilter/ip6table_raw.c +++ b/net/ipv6/netfilter/ip6table_raw.c @@ -129,13 +129,15 @@ static struct nf_hook_ops ip6t_ops[] = { .hook = ip6t_hook, .pf = PF_INET6, .hooknum = NF_IP6_PRE_ROUTING, - .priority = NF_IP6_PRI_FIRST + .priority = NF_IP6_PRI_FIRST, + .owner = THIS_MODULE, }, { .hook = ip6t_hook, .pf = PF_INET6, .hooknum = NF_IP6_LOCAL_OUT, - .priority = NF_IP6_PRI_FIRST + .priority = NF_IP6_PRI_FIRST, + .owner = THIS_MODULE, }, }; -- cgit v1.2.3-59-g8ed1b From e3be8ba79294df5de96692411e122506b40c5aa4 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 21 Jun 2005 14:03:23 -0700 Subject: [NETFILTER]: Avoid unncessary checksum validation in UDP connection tracking Signed-off-by: Keir Fraser Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/ip_conntrack_proto_udp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/netfilter/ip_conntrack_proto_udp.c b/net/ipv4/netfilter/ip_conntrack_proto_udp.c index 5bc28a224623..8c1eaba098d4 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_udp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_udp.c @@ -120,6 +120,7 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo, * and moreover root might send raw packets. * FIXME: Source route IP option packets --RR */ if (hooknum == NF_IP_PRE_ROUTING + && skb->ip_summed != CHECKSUM_UNNECESSARY && csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP, skb->ip_summed == CHECKSUM_HW ? skb->csum : skb_checksum(skb, iph->ihl*4, udplen, 0))) { -- cgit v1.2.3-59-g8ed1b From 6150bacfec95c7042678667561664efcf10d4508 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 21 Jun 2005 14:03:46 -0700 Subject: [NETFILTER]: Check TCP checksum in ipt_REJECT Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/ipt_REJECT.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 266d64979286..915696446020 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c @@ -104,10 +104,12 @@ static inline struct rtable *route_reverse(struct sk_buff *skb, static void send_reset(struct sk_buff *oldskb, int hook) { struct sk_buff *nskb; + struct iphdr *iph = oldskb->nh.iph; struct tcphdr _otcph, *oth, *tcph; struct rtable *rt; u_int16_t tmp_port; u_int32_t tmp_addr; + unsigned int tcplen; int needs_ack; int hh_len; @@ -124,7 +126,16 @@ static void send_reset(struct sk_buff *oldskb, int hook) if (oth->rst) return; - /* FIXME: Check checksum --RR */ + /* Check checksum */ + tcplen = oldskb->len - iph->ihl * 4; + if (((hook != NF_IP_LOCAL_IN && oldskb->ip_summed != CHECKSUM_HW) || + (hook == NF_IP_LOCAL_IN && + oldskb->ip_summed != CHECKSUM_UNNECESSARY)) && + csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP, + oldskb->ip_summed == CHECKSUM_HW ? oldskb->csum : + skb_checksum(oldskb, iph->ihl * 4, tcplen, 0))) + return; + if ((rt = route_reverse(oldskb, oth, hook)) == NULL) return; -- cgit v1.2.3-59-g8ed1b From 2715bcf9efc34063e05009f188eb896c462ae925 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 21 Jun 2005 14:06:24 -0700 Subject: [NETFILTER]: Drop conntrack reference in ip_call_ra_chain()/ip_mr_input() Drop reference before handing the packets to raw_rcv() Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/ip_input.c | 1 + net/ipv4/ipmr.c | 1 + 2 files changed, 2 insertions(+) diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 2b7485e65040..af2ec88bbb2f 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -184,6 +184,7 @@ int ip_call_ra_chain(struct sk_buff *skb) raw_rcv(last, skb2); } last = sk; + nf_reset(skb); } } diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index e21c049ec62a..e4f809a93f47 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -1350,6 +1350,7 @@ int ip_mr_input(struct sk_buff *skb) */ read_lock(&mrt_lock); if (mroute_socket) { + nf_reset(skb); raw_rcv(mroute_socket, skb); read_unlock(&mrt_lock); return 0; -- cgit v1.2.3-59-g8ed1b From 047601bf7c803724bbab9a4fdbad9481cecc12e0 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 21 Jun 2005 14:07:13 -0700 Subject: [NETFILTER]: Fix ip6t_LOG sit tunnel logging Sit tunnel logging is currently broken: MAC=01:23:45:67:89:ab->01:23:45:47:89:ac TUNNEL=123.123. 0.123-> 12.123. 6.123 Apart from the broken IP address, MAC addresses are printed differently for sit tunnels than for everything else. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv6/netfilter/ip6t_LOG.c | 54 +++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c index bfc3d0185d19..c44685e391b7 100644 --- a/net/ipv6/netfilter/ip6t_LOG.c +++ b/net/ipv6/netfilter/ip6t_LOG.c @@ -366,8 +366,6 @@ ip6t_log_packet(unsigned int hooknum, const char *level_string, const char *prefix) { - struct ipv6hdr *ipv6h = skb->nh.ipv6h; - spin_lock_bh(&log_lock); printk(level_string); printk("%sIN=%s OUT=%s ", @@ -377,39 +375,25 @@ ip6t_log_packet(unsigned int hooknum, if (in && !out) { /* MAC logging for input chain only. */ printk("MAC="); - if (skb->dev && skb->dev->hard_header_len && skb->mac.raw != (void*)ipv6h) { - if (skb->dev->type != ARPHRD_SIT){ - int i; - unsigned char *p = skb->mac.raw; - for (i = 0; i < skb->dev->hard_header_len; i++,p++) - printk("%02x%c", *p, - i==skb->dev->hard_header_len - 1 - ? ' ':':'); - } else { - int i; - unsigned char *p = skb->mac.raw; - if ( p - (ETH_ALEN*2+2) > skb->head ){ - p -= (ETH_ALEN+2); - for (i = 0; i < (ETH_ALEN); i++,p++) - printk("%02x%s", *p, - i == ETH_ALEN-1 ? "->" : ":"); - p -= (ETH_ALEN*2); - for (i = 0; i < (ETH_ALEN); i++,p++) - printk("%02x%c", *p, - i == ETH_ALEN-1 ? ' ' : ':'); - } - - if ((skb->dev->addr_len == 4) && - skb->dev->hard_header_len > 20){ - printk("TUNNEL="); - p = skb->mac.raw + 12; - for (i = 0; i < 4; i++,p++) - printk("%3d%s", *p, - i == 3 ? "->" : "."); - for (i = 0; i < 4; i++,p++) - printk("%3d%c", *p, - i == 3 ? ' ' : '.'); - } + if (skb->dev && skb->dev->hard_header_len && + skb->mac.raw != skb->nh.raw) { + unsigned char *p = skb->mac.raw; + int i; + + if (skb->dev->type == ARPHRD_SIT && + (p -= ETH_HLEN) < skb->head) + p = NULL; + + if (p != NULL) + for (i = 0; i < skb->dev->hard_header_len; i++) + printk("%02x", p[i]); + printk(" "); + + if (skb->dev->type == ARPHRD_SIT) { + struct iphdr *iph = (struct iphdr *)skb->mac.raw; + printk("TUNNEL=%u.%u.%u.%u->%u.%u.%u.%u ", + NIPQUAD(iph->saddr), + NIPQUAD(iph->daddr)); } } else printk(" "); -- cgit v1.2.3-59-g8ed1b From 90f66914c89b0be63548d4387d1211280aa7bc8e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 21 Jun 2005 14:43:28 -0700 Subject: [IPV4]: Fix fib_trie.c's args to fib_dump_info(). Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index c0ece94fc63e..0671569ee6f0 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1786,7 +1786,7 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, struct fi &xkey, plen, fa->fa_tos, - fa->fa_info) < 0) { + fa->fa_info, 0) < 0) { cb->args[3] = i; return -1; } -- cgit v1.2.3-59-g8ed1b From 8005aba69a6440a535a4cc2aed99ffca580847e0 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 21 Jun 2005 15:39:22 -0700 Subject: [SPARC64]: Fix cmsg length checks in Solaris emulation layer. Signed-off-by: David S. Miller --- arch/sparc64/solaris/socket.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/sparc64/solaris/socket.c b/arch/sparc64/solaris/socket.c index ec8e074c4eac..06740582717e 100644 --- a/arch/sparc64/solaris/socket.c +++ b/arch/sparc64/solaris/socket.c @@ -317,8 +317,10 @@ asmlinkage int solaris_sendmsg(int fd, struct sol_nmsghdr __user *user_msg, unsi unsigned long *kcmsg; compat_size_t cmlen; - if(kern_msg.msg_controllen > sizeof(ctl) && - kern_msg.msg_controllen <= 256) { + if (kern_msg.msg_controllen <= sizeof(compat_size_t)) + return -EINVAL; + + if(kern_msg.msg_controllen > sizeof(ctl)) { err = -ENOBUFS; ctl_buf = kmalloc(kern_msg.msg_controllen, GFP_KERNEL); if(!ctl_buf) -- cgit v1.2.3-59-g8ed1b From 2c6e5a839f92591a4bc6cac4a575d42151645af3 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Tue, 21 Jun 2005 15:24:19 -0700 Subject: [PATCH] devfs: remove devfs from Kconfig preventing it from being built Here's a much smaller patch to simply disable devfs from the build. If this goes well, and there are no complaints for a few weeks, I'll resend my big "devfs-die-die-die" series of patches that rip the whole thing out of the kernel tree. Signed-off-by: Greg Kroah-Hartman Signed-off-by: Linus Torvalds --- fs/Kconfig | 50 -------------------------------------------------- 1 file changed, 50 deletions(-) diff --git a/fs/Kconfig b/fs/Kconfig index 6a4ad4bb7a54..178e27494b74 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -741,56 +741,6 @@ config SYSFS Designers of embedded systems may wish to say N here to conserve space. -config DEVFS_FS - bool "/dev file system support (OBSOLETE)" - depends on EXPERIMENTAL - help - This is support for devfs, a virtual file system (like /proc) which - provides the file system interface to device drivers, normally found - in /dev. Devfs does not depend on major and minor number - allocations. Device drivers register entries in /dev which then - appear automatically, which means that the system administrator does - not have to create character and block special device files in the - /dev directory using the mknod command (or MAKEDEV script) anymore. - - This is work in progress. If you want to use this, you *must* read - the material in , especially - the file README there. - - Note that devfs no longer manages /dev/pts! If you are using UNIX98 - ptys, you will also need to mount the /dev/pts filesystem (devpts). - - Note that devfs has been obsoleted by udev, - . - It has been stripped down to a bare minimum and is only provided for - legacy installations that use its naming scheme which is - unfortunately different from the names normal Linux installations - use. - - If unsure, say N. - -config DEVFS_MOUNT - bool "Automatically mount at boot" - depends on DEVFS_FS - help - This option appears if you have CONFIG_DEVFS_FS enabled. Setting - this to 'Y' will make the kernel automatically mount devfs onto /dev - when the system is booted, before the init thread is started. - You can override this with the "devfs=nomount" boot option. - - If unsure, say N. - -config DEVFS_DEBUG - bool "Debug devfs" - depends on DEVFS_FS - help - If you say Y here, then the /dev file system code will generate - debugging messages. See the file - for more - details. - - If unsure, say N. - config DEVPTS_FS_XATTR bool "/dev/pts Extended Attributes" depends on UNIX98_PTYS -- cgit v1.2.3-59-g8ed1b From 7049e6800f40046c384c522a990669024d5f5836 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 21 Jun 2005 16:20:28 -0700 Subject: [SPARC64]: Add prefetch support. The implementation is optimal for UltraSPARC-III and later. It will work, however suboptimally, on UltraSPARC-II and be treated as a NOP on UltraSPARC-I. It is not worth code patching this thing as the highest cost is the code space, and code patching cannot eliminate that. Signed-off-by: David S. Miller --- include/asm-sparc64/processor.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h index bc1445b904ef..d0bee2413560 100644 --- a/include/asm-sparc64/processor.h +++ b/include/asm-sparc64/processor.h @@ -192,6 +192,40 @@ extern unsigned long get_wchan(struct task_struct *task); #define cpu_relax() barrier() +/* Prefetch support. This is tuned for UltraSPARC-III and later. + * UltraSPARC-I will treat these as nops, and UltraSPARC-II has + * a shallower prefetch queue than later chips. + */ +#define ARCH_HAS_PREFETCH +#define ARCH_HAS_PREFETCHW +#define ARCH_HAS_SPINLOCK_PREFETCH + +static inline void prefetch(const void *x) +{ + /* We do not use the read prefetch mnemonic because that + * prefetches into the prefetch-cache which only is accessible + * by floating point operations in UltraSPARC-III and later. + * By contrast, "#one_write" prefetches into the L2 cache + * in shared state. + */ + __asm__ __volatile__("prefetch [%0], #one_write" + : /* no outputs */ + : "r" (x)); +} + +static inline void prefetchw(const void *x) +{ + /* The most optimal prefetch to use for writes is + * "#n_writes". This brings the cacheline into the + * L2 cache in "owned" state. + */ + __asm__ __volatile__("prefetch [%0], #n_writes" + : /* no outputs */ + : "r" (x)); +} + +#define spin_lock_prefetch(x) prefetchw(x) + #endif /* !(__ASSEMBLY__) */ #endif /* !(__ASM_SPARC64_PROCESSOR_H) */ -- cgit v1.2.3-59-g8ed1b From e1a40fa907498030b6e432c0dbcb06d7a9f14ee3 Mon Sep 17 00:00:00 2001 From: Dean Roehrich Date: Wed, 22 Jun 2005 10:20:44 +1000 Subject: [XFS] Handle inode semaphores properly for dmapi queues SGI-PV: 931572 SGI-Modid: xfs-linux-melb:xfs-kern:189560a Signed-off-by: Dean Roehrich Signed-off-by: Nathan Scott --- fs/xfs/linux-2.6/xfs_lrw.c | 10 ++++++++-- fs/xfs/xfs_dmapi.h | 23 ++++++++++++----------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 46b61a859af4..acab58c48043 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c @@ -280,10 +280,11 @@ xfs_read( if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && !(ioflags & IO_INVIS)) { vrwlock_t locktype = VRWLOCK_READ; + int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags); ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), *offset, size, - FILP_DELAY_FLAG(file), &locktype); + dmflags, &locktype); if (ret) { xfs_iunlock(ip, XFS_IOLOCK_SHARED); goto unlock_isem; @@ -843,11 +844,15 @@ retry: !(ioflags & IO_INVIS)) { xfs_rwunlock(bdp, locktype); + if (need_isem) + up(&inode->i_sem); error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp, DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL, 0, 0, 0); /* Delay flag intentionally unused */ if (error) - goto out_unlock_isem; + goto out_nounlocks; + if (need_isem) + down(&inode->i_sem); xfs_rwlock(bdp, locktype); pos = xip->i_d.di_size; ret = 0; @@ -962,6 +967,7 @@ retry: out_unlock_isem: if (need_isem) up(&inode->i_sem); + out_nounlocks: return -error; } diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h index 16cf9f7a4785..55c17adaaa37 100644 --- a/fs/xfs/xfs_dmapi.h +++ b/fs/xfs/xfs_dmapi.h @@ -166,27 +166,32 @@ typedef enum { #define DM_FLAGS_NDELAY 0x001 /* return EAGAIN after dm_pending() */ #define DM_FLAGS_UNWANTED 0x002 /* event not in fsys dm_eventset_t */ #define DM_FLAGS_ISEM 0x004 /* thread holds i_sem */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21) -/* i_alloc_sem was added in 2.4.22-pre1 */ #define DM_FLAGS_IALLOCSEM_RD 0x010 /* thread holds i_alloc_sem rd */ #define DM_FLAGS_IALLOCSEM_WR 0x020 /* thread holds i_alloc_sem wr */ -#endif -#endif /* * Based on IO_ISDIRECT, decide which i_ flag is set. */ -#ifdef DM_FLAGS_IALLOCSEM_RD +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) +#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ + DM_FLAGS_ISEM : 0) +#define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_ISEM) +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) && \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)) #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ DM_FLAGS_IALLOCSEM_RD : DM_FLAGS_ISEM) #define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_ISEM) -#else +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,21) #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ 0 : DM_FLAGS_ISEM) #define DM_SEM_FLAG_WR (DM_FLAGS_ISEM) #endif + /* * Macros to turn caller specified delay/block flags into * dm_send_xxxx_event flag DM_FLAGS_NDELAY. @@ -209,8 +214,4 @@ void xfs_dm_exit(struct file_system_type *); #define XFS_DM_EXIT(fstype) #endif -#define HAVE_XFS_DM_MM -int xfs_dm_mm_get(struct vm_area_struct *vma); -void xfs_dm_mm_put(struct vm_area_struct *vma); - #endif /* __XFS_DMAPI_H__ */ -- cgit v1.2.3-59-g8ed1b From 9a558cb4ec43ccbe82e2cf899ced37f29ac017df Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 21 Jun 2005 17:14:28 -0700 Subject: [PATCH] arm: irqs_disabled() type fix kernel/sched.c: In function `__might_sleep': kernel/sched.c:5461: warning: int format, long unsigned int arg (arg 3) We expect irqs_disabled() to return an int (poor man's bool). Acked-by: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-arm/system.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index 8405eb6558ed..39dd7008013c 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h @@ -308,7 +308,7 @@ do { \ ({ \ unsigned long flags; \ local_save_flags(flags); \ - flags & PSR_I_BIT; \ + (int)(flags & PSR_I_BIT); \ }) #ifdef CONFIG_SMP -- cgit v1.2.3-59-g8ed1b From 7f20b6a4792c1b5033583c23b5594887dd3867b9 Mon Sep 17 00:00:00 2001 From: bobl Date: Tue, 21 Jun 2005 17:14:29 -0700 Subject: [PATCH] megaraid build fix Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/scsi/megaraid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 80b0c40c522b..ec81532eb845 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -1975,7 +1975,7 @@ __megaraid_reset(Scsi_Cmnd *cmd) static int megaraid_reset(Scsi_Cmnd *cmd) { - adapter = (adapter_t *)cmd->device->host->hostdata; + adapter_t *adapter = (adapter_t *)cmd->device->host->hostdata; int rc; spin_lock_irq(&adapter->lock); -- cgit v1.2.3-59-g8ed1b From 3a845099b20e81fb678521f034bbdcd69208da4e Mon Sep 17 00:00:00 2001 From: Zaur Kambarov Date: Tue, 21 Jun 2005 17:14:30 -0700 Subject: [PATCH] coverity: ipmi: avoid overrun of ipmi_interfaces[] Fix overrun of static array "ipmi_interfaces" of size 4 at position 4 with index variable "if_num". Definitions involved: 297 #define MAX_IPMI_INTERFACES 4 298 static ipmi_smi_t ipmi_interfaces[MAX_IPMI_INTERFACES]; Signed-off-by: Zaur Kambarov Cc: Corey Minyard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_msghandler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index d7fb452af7f9..0c81652eaba6 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -641,7 +641,7 @@ int ipmi_create_user(unsigned int if_num, return -ENOMEM; down_read(&interfaces_sem); - if ((if_num > MAX_IPMI_INTERFACES) || ipmi_interfaces[if_num] == NULL) + if ((if_num >= MAX_IPMI_INTERFACES) || ipmi_interfaces[if_num] == NULL) { rv = -EINVAL; goto out_unlock; -- cgit v1.2.3-59-g8ed1b From 589777eab7360894b7ca1c4ba9d252e03b51225b Mon Sep 17 00:00:00 2001 From: Zaur Kambarov Date: Tue, 21 Jun 2005 17:14:31 -0700 Subject: [PATCH] coverity: idr_get_new_above_int() overrun fix This patch fixes overrun of array pa: 92 struct idr_layer *pa[MAX_LEVEL]; in 98 l = idp->layers; 99 pa[l--] = NULL; by passing idp->layers, set in 202 idp->layers = layers; to function sub_alloc in 203 v = sub_alloc(idp, ptr, &id); Signed-off-by: Zaur Kambarov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/idr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/idr.c b/lib/idr.c index 81fc430602ee..c5be889de449 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -175,7 +175,7 @@ build_up: * Add a new layer to the top of the tree if the requested * id is larger than the currently allocated space. */ - while ((layers < MAX_LEVEL) && (id >= (1 << (layers*IDR_BITS)))) { + while ((layers < (MAX_LEVEL - 1)) && (id >= (1 << (layers*IDR_BITS)))) { layers++; if (!p->count) continue; -- cgit v1.2.3-59-g8ed1b From 84929801e14d968caeb84795bfbb88f04283fbd9 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Tue, 21 Jun 2005 17:14:32 -0700 Subject: [PATCH] x86_64: TASK_SIZE fixes for compatibility mode processes Appended patch will setup compatibility mode TASK_SIZE properly. This will fix atleast three known bugs that can be encountered while running compatibility mode apps. a) A malicious 32bit app can have an elf section at 0xffffe000. During exec of this app, we will have a memory leak as insert_vm_struct() is not checking for return value in syscall32_setup_pages() and thus not freeing the vma allocated for the vsyscall page. And instead of exec failing (as it has addresses > TASK_SIZE), we were allowing it to succeed previously. b) With a 32bit app, hugetlb_get_unmapped_area/arch_get_unmapped_area may return addresses beyond 32bits, ultimately causing corruption because of wrap-around and resulting in SEGFAULT, instead of returning ENOMEM. c) 32bit app doing this below mmap will now fail. mmap((void *)(0xFFFFE000UL), 0x10000UL, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_PRIVATE|MAP_ANON, 0, 0); Signed-off-by: Zou Nan hai Signed-off-by: Suresh Siddha Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/ia32/ia32_binfmt.c | 5 +---- arch/x86_64/kernel/process.c | 4 ++-- arch/x86_64/kernel/ptrace.c | 17 ++++++++++------- arch/x86_64/kernel/sys_x86_64.c | 14 ++++---------- arch/x86_64/mm/fault.c | 2 +- include/asm-x86_64/a.out.h | 2 +- include/asm-x86_64/processor.h | 11 ++++++----- 7 files changed, 25 insertions(+), 30 deletions(-) diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c index 99b522052d16..c8131f342cfc 100644 --- a/arch/x86_64/ia32/ia32_binfmt.c +++ b/arch/x86_64/ia32/ia32_binfmt.c @@ -46,7 +46,7 @@ struct elf_phdr; #define IA32_EMULATOR 1 -#define ELF_ET_DYN_BASE (TASK_UNMAPPED_32 + 0x1000000) +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000) #undef ELF_ARCH #define ELF_ARCH EM_386 @@ -307,9 +307,6 @@ MODULE_AUTHOR("Eric Youngdale, Andi Kleen"); #define elf_addr_t __u32 -#undef TASK_SIZE -#define TASK_SIZE 0xffffffff - static void elf32_init(struct pt_regs *); #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 761b6d35e338..dce8bab4306c 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c @@ -656,7 +656,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) switch (code) { case ARCH_SET_GS: - if (addr >= TASK_SIZE) + if (addr >= TASK_SIZE_OF(task)) return -EPERM; cpu = get_cpu(); /* handle small bases via the GDT because that's faster to @@ -682,7 +682,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) case ARCH_SET_FS: /* Not strictly needed for fs, but do it for symmetry with gs */ - if (addr >= TASK_SIZE) + if (addr >= TASK_SIZE_OF(task)) return -EPERM; cpu = get_cpu(); /* handle small bases via the GDT because that's faster to diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c index 525f6a128a27..bbf64b59a21e 100644 --- a/arch/x86_64/kernel/ptrace.c +++ b/arch/x86_64/kernel/ptrace.c @@ -257,12 +257,12 @@ static int putreg(struct task_struct *child, value &= 0xffff; return 0; case offsetof(struct user_regs_struct,fs_base): - if (value >= TASK_SIZE) + if (value >= TASK_SIZE_OF(child)) return -EIO; child->thread.fs = value; return 0; case offsetof(struct user_regs_struct,gs_base): - if (value >= TASK_SIZE) + if (value >= TASK_SIZE_OF(child)) return -EIO; child->thread.gs = value; return 0; @@ -279,7 +279,7 @@ static int putreg(struct task_struct *child, break; case offsetof(struct user_regs_struct, rip): /* Check if the new RIP address is canonical */ - if (value >= TASK_SIZE) + if (value >= TASK_SIZE_OF(child)) return -EIO; break; } @@ -419,6 +419,8 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data break; case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ + { + int dsize = test_tsk_thread_flag(child, TIF_IA32) ? 3 : 7; ret = -EIO; if ((addr & 7) || addr > sizeof(struct user) - 7) @@ -430,22 +432,22 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data break; /* Disallows to set a breakpoint into the vsyscall */ case offsetof(struct user, u_debugreg[0]): - if (data >= TASK_SIZE-7) break; + if (data >= TASK_SIZE_OF(child) - dsize) break; child->thread.debugreg0 = data; ret = 0; break; case offsetof(struct user, u_debugreg[1]): - if (data >= TASK_SIZE-7) break; + if (data >= TASK_SIZE_OF(child) - dsize) break; child->thread.debugreg1 = data; ret = 0; break; case offsetof(struct user, u_debugreg[2]): - if (data >= TASK_SIZE-7) break; + if (data >= TASK_SIZE_OF(child) - dsize) break; child->thread.debugreg2 = data; ret = 0; break; case offsetof(struct user, u_debugreg[3]): - if (data >= TASK_SIZE-7) break; + if (data >= TASK_SIZE_OF(child) - dsize) break; child->thread.debugreg3 = data; ret = 0; break; @@ -469,6 +471,7 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data break; } break; + } case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ case PTRACE_CONT: /* restart after signal. */ diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c index dbebd5ccba6b..d9798dd433fc 100644 --- a/arch/x86_64/kernel/sys_x86_64.c +++ b/arch/x86_64/kernel/sys_x86_64.c @@ -68,13 +68,7 @@ out: static void find_start_end(unsigned long flags, unsigned long *begin, unsigned long *end) { -#ifdef CONFIG_IA32_EMULATION - if (test_thread_flag(TIF_IA32)) { - *begin = TASK_UNMAPPED_32; - *end = IA32_PAGE_OFFSET; - } else -#endif - if (flags & MAP_32BIT) { + if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) { /* This is usually used needed to map code in small model, so it needs to be in the first 31bit. Limit it to that. This means we need to move the @@ -84,10 +78,10 @@ static void find_start_end(unsigned long flags, unsigned long *begin, of playground for now. -AK */ *begin = 0x40000000; *end = 0x80000000; - } else { - *begin = TASK_UNMAPPED_64; + } else { + *begin = TASK_UNMAPPED_BASE; *end = TASK_SIZE; - } + } } unsigned long diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index 5d6b2114cc9a..57d3ab15a5c7 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c @@ -350,7 +350,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) * (error_code & 4) == 0, and that the fault was not a * protection error (error_code & 1) == 0. */ - if (unlikely(address >= TASK_SIZE)) { + if (unlikely(address >= TASK_SIZE64)) { if (!(error_code & 5) && ((address >= VMALLOC_START && address < VMALLOC_END) || (address >= MODULES_VADDR && address < MODULES_END))) { diff --git a/include/asm-x86_64/a.out.h b/include/asm-x86_64/a.out.h index 5952914f4121..7255cde06538 100644 --- a/include/asm-x86_64/a.out.h +++ b/include/asm-x86_64/a.out.h @@ -21,7 +21,7 @@ struct exec #ifdef __KERNEL__ #include -#define STACK_TOP (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE) +#define STACK_TOP TASK_SIZE #endif #endif /* __A_OUT_GNU_H__ */ diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h index d641b19f6da5..8b55f139968f 100644 --- a/include/asm-x86_64/processor.h +++ b/include/asm-x86_64/processor.h @@ -160,16 +160,17 @@ static inline void clear_in_cr4 (unsigned long mask) /* * User space process size. 47bits minus one guard page. */ -#define TASK_SIZE (0x800000000000UL - 4096) +#define TASK_SIZE64 (0x800000000000UL - 4096) /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000) -#define TASK_UNMAPPED_32 PAGE_ALIGN(IA32_PAGE_OFFSET/3) -#define TASK_UNMAPPED_64 PAGE_ALIGN(TASK_SIZE/3) -#define TASK_UNMAPPED_BASE \ - (test_thread_flag(TIF_IA32) ? TASK_UNMAPPED_32 : TASK_UNMAPPED_64) + +#define TASK_SIZE (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE64) +#define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_IA32)) ? IA32_PAGE_OFFSET : TASK_SIZE64) + +#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE/3) /* * Size of io_bitmap. -- cgit v1.2.3-59-g8ed1b From 39c715b71740c4a78ba4769fb54826929bac03cb Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 21 Jun 2005 17:14:34 -0700 Subject: [PATCH] smp_processor_id() cleanup This patch implements a number of smp_processor_id() cleanup ideas that Arjan van de Ven and I came up with. The previous __smp_processor_id/_smp_processor_id/smp_processor_id API spaghetti was hard to follow both on the implementational and on the usage side. Some of the complexity arose from picking wrong names, some of the complexity comes from the fact that not all architectures defined __smp_processor_id. In the new code, there are two externally visible symbols: - smp_processor_id(): debug variant. - raw_smp_processor_id(): nondebug variant. Replaces all existing uses of _smp_processor_id() and __smp_processor_id(). Defined by every SMP architecture in include/asm-*/smp.h. There is one new internal symbol, dependent on DEBUG_PREEMPT: - debug_smp_processor_id(): internal debug variant, mapped to smp_processor_id(). Also, i moved debug_smp_processor_id() from lib/kernel_lock.c into a new lib/smp_processor_id.c file. All related comments got updated and/or clarified. I have build/boot tested the following 8 .config combinations on x86: {SMP,UP} x {PREEMPT,!PREEMPT} x {DEBUG_PREEMPT,!DEBUG_PREEMPT} I have also build/boot tested x64 on UP/PREEMPT/DEBUG_PREEMPT. (Other architectures are untested, but should work just fine.) Signed-off-by: Ingo Molnar Signed-off-by: Arjan van de Ven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/traps.c | 2 +- arch/i386/lib/delay.c | 2 +- arch/ppc/lib/locks.c | 4 +-- arch/ppc64/kernel/idle.c | 2 +- arch/sh/lib/delay.c | 2 +- arch/sparc64/lib/delay.c | 2 +- arch/x86_64/lib/delay.c | 2 +- drivers/acpi/processor_idle.c | 2 +- drivers/input/gameport/gameport.c | 2 +- drivers/oprofile/buffer_sync.c | 4 +-- fs/xfs/linux-2.6/xfs_linux.h | 6 ++--- include/asm-alpha/smp.h | 2 +- include/asm-arm/smp.h | 2 +- include/asm-i386/smp.h | 2 +- include/asm-ia64/smp.h | 2 +- include/asm-m32r/smp.h | 2 +- include/asm-mips/smp.h | 2 +- include/asm-parisc/smp.h | 2 +- include/asm-ppc/smp.h | 2 +- include/asm-ppc64/smp.h | 2 +- include/asm-s390/smp.h | 2 +- include/asm-sh/smp.h | 2 +- include/asm-sparc/smp.h | 2 +- include/asm-sparc64/smp.h | 2 +- include/asm-um/smp.h | 3 ++- include/asm-x86_64/smp.h | 2 +- include/linux/mmzone.h | 2 +- include/linux/smp.h | 40 ++++++++++++---------------- include/net/route.h | 2 +- include/net/snmp.h | 14 +++++----- kernel/module.c | 2 +- kernel/power/smp.c | 4 +-- kernel/sched.c | 4 +-- kernel/stop_machine.c | 4 +-- lib/Makefile | 1 + lib/kernel_lock.c | 55 --------------------------------------- lib/smp_processor_id.c | 55 +++++++++++++++++++++++++++++++++++++++ 37 files changed, 119 insertions(+), 125 deletions(-) create mode 100644 lib/smp_processor_id.c diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 00c63419c06f..83c579e82a81 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -306,7 +306,7 @@ void die(const char * str, struct pt_regs * regs, long err) }; static int die_counter; - if (die.lock_owner != _smp_processor_id()) { + if (die.lock_owner != raw_smp_processor_id()) { console_verbose(); spin_lock_irq(&die.lock); die.lock_owner = smp_processor_id(); diff --git a/arch/i386/lib/delay.c b/arch/i386/lib/delay.c index 080639f262b1..eb0cdfe9280f 100644 --- a/arch/i386/lib/delay.c +++ b/arch/i386/lib/delay.c @@ -34,7 +34,7 @@ inline void __const_udelay(unsigned long xloops) xloops *= 4; __asm__("mull %0" :"=d" (xloops), "=&a" (d0) - :"1" (xloops),"0" (cpu_data[_smp_processor_id()].loops_per_jiffy * (HZ/4))); + :"1" (xloops),"0" (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (HZ/4))); __delay(++xloops); } diff --git a/arch/ppc/lib/locks.c b/arch/ppc/lib/locks.c index 694163d696d8..c450dc4b766e 100644 --- a/arch/ppc/lib/locks.c +++ b/arch/ppc/lib/locks.c @@ -130,7 +130,7 @@ void _raw_read_lock(rwlock_t *rw) while (!read_can_lock(rw)) { if (--stuck == 0) { printk("_read_lock(%p) CPU#%d lock %d\n", - rw, _smp_processor_id(), rw->lock); + rw, raw_smp_processor_id(), rw->lock); stuck = INIT_STUCK; } } @@ -158,7 +158,7 @@ void _raw_write_lock(rwlock_t *rw) while (!write_can_lock(rw)) { if (--stuck == 0) { printk("write_lock(%p) CPU#%d lock %d)\n", - rw, _smp_processor_id(), rw->lock); + rw, raw_smp_processor_id(), rw->lock); stuck = INIT_STUCK; } } diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index f24ce2b87200..ff8a7db142d3 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c @@ -292,7 +292,7 @@ static int native_idle(void) if (need_resched()) schedule(); - if (cpu_is_offline(_smp_processor_id()) && + if (cpu_is_offline(raw_smp_processor_id()) && system_state == SYSTEM_RUNNING) cpu_die(); } diff --git a/arch/sh/lib/delay.c b/arch/sh/lib/delay.c index 50b36037d86b..351714694d6d 100644 --- a/arch/sh/lib/delay.c +++ b/arch/sh/lib/delay.c @@ -24,7 +24,7 @@ inline void __const_udelay(unsigned long xloops) __asm__("dmulu.l %0, %2\n\t" "sts mach, %0" : "=r" (xloops) - : "0" (xloops), "r" (cpu_data[_smp_processor_id()].loops_per_jiffy) + : "0" (xloops), "r" (cpu_data[raw_smp_processor_id()].loops_per_jiffy) : "macl", "mach"); __delay(xloops * HZ); } diff --git a/arch/sparc64/lib/delay.c b/arch/sparc64/lib/delay.c index f6b4c784d53e..e8808727617a 100644 --- a/arch/sparc64/lib/delay.c +++ b/arch/sparc64/lib/delay.c @@ -31,7 +31,7 @@ void __const_udelay(unsigned long n) { n *= 4; - n *= (cpu_data(_smp_processor_id()).udelay_val * (HZ/4)); + n *= (cpu_data(raw_smp_processor_id()).udelay_val * (HZ/4)); n >>= 32; __delay(n + 1); diff --git a/arch/x86_64/lib/delay.c b/arch/x86_64/lib/delay.c index 6e2d66472eb1..aed61a668a1b 100644 --- a/arch/x86_64/lib/delay.c +++ b/arch/x86_64/lib/delay.c @@ -34,7 +34,7 @@ void __delay(unsigned long loops) inline void __const_udelay(unsigned long xloops) { - __delay(((xloops * cpu_data[_smp_processor_id()].loops_per_jiffy) >> 32) * HZ); + __delay(((xloops * cpu_data[raw_smp_processor_id()].loops_per_jiffy) >> 32) * HZ); } void __udelay(unsigned long usecs) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index ff64d333e95f..c9d671cf7857 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -171,7 +171,7 @@ static void acpi_processor_idle (void) int sleep_ticks = 0; u32 t1, t2 = 0; - pr = processors[_smp_processor_id()]; + pr = processors[raw_smp_processor_id()]; if (!pr) return; diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index 9b8ff396e6f8..e152d0fa0cdd 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -134,7 +134,7 @@ static int gameport_measure_speed(struct gameport *gameport) } gameport_close(gameport); - return (cpu_data[_smp_processor_id()].loops_per_jiffy * (unsigned long)HZ / (1000 / 50)) / (tx < 1 ? 1 : tx); + return (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (unsigned long)HZ / (1000 / 50)) / (tx < 1 ? 1 : tx); #else diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c index 55720dc6ec43..745a14183634 100644 --- a/drivers/oprofile/buffer_sync.c +++ b/drivers/oprofile/buffer_sync.c @@ -62,7 +62,7 @@ static int task_exit_notify(struct notifier_block * self, unsigned long val, voi /* To avoid latency problems, we only process the current CPU, * hoping that most samples for the task are on this CPU */ - sync_buffer(_smp_processor_id()); + sync_buffer(raw_smp_processor_id()); return 0; } @@ -86,7 +86,7 @@ static int munmap_notify(struct notifier_block * self, unsigned long val, void * /* To avoid latency problems, we only process the current CPU, * hoping that most samples for the task are on this CPU */ - sync_buffer(_smp_processor_id()); + sync_buffer(raw_smp_processor_id()); return 0; } diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h index 71bb41019a12..7d7c8788ea75 100644 --- a/fs/xfs/linux-2.6/xfs_linux.h +++ b/fs/xfs/linux-2.6/xfs_linux.h @@ -145,10 +145,10 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh) #define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val #define xfs_rotorstep xfs_params.rotorstep.val -#ifndef __smp_processor_id -#define __smp_processor_id() smp_processor_id() +#ifndef raw_smp_processor_id +#define raw_smp_processor_id() smp_processor_id() #endif -#define current_cpu() __smp_processor_id() +#define current_cpu() raw_smp_processor_id() #define current_pid() (current->pid) #define current_fsuid(cred) (current->fsuid) #define current_fsgid(cred) (current->fsgid) diff --git a/include/asm-alpha/smp.h b/include/asm-alpha/smp.h index cbc173ae45aa..9950706abdf8 100644 --- a/include/asm-alpha/smp.h +++ b/include/asm-alpha/smp.h @@ -43,7 +43,7 @@ extern struct cpuinfo_alpha cpu_data[NR_CPUS]; #define PROC_CHANGE_PENALTY 20 #define hard_smp_processor_id() __hard_smp_processor_id() -#define smp_processor_id() (current_thread_info()->cpu) +#define raw_smp_processor_id() (current_thread_info()->cpu) extern cpumask_t cpu_present_mask; extern cpumask_t cpu_online_map; diff --git a/include/asm-arm/smp.h b/include/asm-arm/smp.h index bd44f894690f..6c6c60adbbaa 100644 --- a/include/asm-arm/smp.h +++ b/include/asm-arm/smp.h @@ -21,7 +21,7 @@ # error " included in non-SMP build" #endif -#define smp_processor_id() (current_thread_info()->cpu) +#define raw_smp_processor_id() (current_thread_info()->cpu) extern cpumask_t cpu_present_mask; #define cpu_possible_map cpu_present_mask diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h index e03a206dfa36..55ef31f66bbe 100644 --- a/include/asm-i386/smp.h +++ b/include/asm-i386/smp.h @@ -51,7 +51,7 @@ extern u8 x86_cpu_to_apicid[]; * from the initial startup. We map APIC_BASE very early in page_setup(), * so this is correct in the x86 case. */ -#define __smp_processor_id() (current_thread_info()->cpu) +#define raw_smp_processor_id() (current_thread_info()->cpu) extern cpumask_t cpu_callout_map; extern cpumask_t cpu_callin_map; diff --git a/include/asm-ia64/smp.h b/include/asm-ia64/smp.h index 3ba1a061e4ae..a3914352c995 100644 --- a/include/asm-ia64/smp.h +++ b/include/asm-ia64/smp.h @@ -46,7 +46,7 @@ ia64_get_lid (void) #define SMP_IRQ_REDIRECTION (1 << 0) #define SMP_IPI_REDIRECTION (1 << 1) -#define smp_processor_id() (current_thread_info()->cpu) +#define raw_smp_processor_id() (current_thread_info()->cpu) extern struct smp_boot_data { int cpu_count; diff --git a/include/asm-m32r/smp.h b/include/asm-m32r/smp.h index 8cd4d0da4be1..b9a20cdad65f 100644 --- a/include/asm-m32r/smp.h +++ b/include/asm-m32r/smp.h @@ -66,7 +66,7 @@ extern volatile int cpu_2_physid[NR_CPUS]; #define physid_to_cpu(physid) physid_2_cpu[physid] #define cpu_to_physid(cpu_id) cpu_2_physid[cpu_id] -#define smp_processor_id() (current_thread_info()->cpu) +#define raw_smp_processor_id() (current_thread_info()->cpu) extern cpumask_t cpu_callout_map; #define cpu_possible_map cpu_callout_map diff --git a/include/asm-mips/smp.h b/include/asm-mips/smp.h index 8ba370ecfd4c..5618f1e12f40 100644 --- a/include/asm-mips/smp.h +++ b/include/asm-mips/smp.h @@ -21,7 +21,7 @@ #include #include -#define smp_processor_id() (current_thread_info()->cpu) +#define raw_smp_processor_id() (current_thread_info()->cpu) /* Map from cpu id to sequential logical cpu number. This will only not be idempotent when cpus failed to come on-line. */ diff --git a/include/asm-parisc/smp.h b/include/asm-parisc/smp.h index fde77ac35463..9413f67a540b 100644 --- a/include/asm-parisc/smp.h +++ b/include/asm-parisc/smp.h @@ -51,7 +51,7 @@ extern void smp_send_reschedule(int cpu); extern unsigned long cpu_present_mask; -#define smp_processor_id() (current_thread_info()->cpu) +#define raw_smp_processor_id() (current_thread_info()->cpu) #endif /* CONFIG_SMP */ diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h index ebfb614f55f6..17530c232c76 100644 --- a/include/asm-ppc/smp.h +++ b/include/asm-ppc/smp.h @@ -44,7 +44,7 @@ extern void smp_message_recv(int, struct pt_regs *); #define NO_PROC_ID 0xFF /* No processor magic marker */ #define PROC_CHANGE_PENALTY 20 -#define smp_processor_id() (current_thread_info()->cpu) +#define raw_smp_processor_id() (current_thread_info()->cpu) extern int __cpu_up(unsigned int cpu); diff --git a/include/asm-ppc64/smp.h b/include/asm-ppc64/smp.h index c8646fa999c2..8115ecb8feee 100644 --- a/include/asm-ppc64/smp.h +++ b/include/asm-ppc64/smp.h @@ -45,7 +45,7 @@ void generic_cpu_die(unsigned int cpu); void generic_mach_cpu_die(void); #endif -#define __smp_processor_id() (get_paca()->paca_index) +#define raw_smp_processor_id() (get_paca()->paca_index) #define hard_smp_processor_id() (get_paca()->hw_cpu_id) extern cpumask_t cpu_sibling_map[NR_CPUS]; diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h index 9473786387a3..dd50e57a928f 100644 --- a/include/asm-s390/smp.h +++ b/include/asm-s390/smp.h @@ -47,7 +47,7 @@ extern int smp_call_function_on(void (*func) (void *info), void *info, #define PROC_CHANGE_PENALTY 20 /* Schedule penalty */ -#define smp_processor_id() (S390_lowcore.cpu_data.cpu_nr) +#define raw_smp_processor_id() (S390_lowcore.cpu_data.cpu_nr) extern int smp_get_cpu(cpumask_t cpu_map); extern void smp_put_cpu(int cpu); diff --git a/include/asm-sh/smp.h b/include/asm-sh/smp.h index 38b54469d7d1..f19a8b3b69a6 100644 --- a/include/asm-sh/smp.h +++ b/include/asm-sh/smp.h @@ -25,7 +25,7 @@ extern cpumask_t cpu_possible_map; #define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) -#define smp_processor_id() (current_thread_info()->cpu) +#define raw_smp_processor_id() (current_thread_info()->cpu) /* I've no idea what the real meaning of this is */ #define PROC_CHANGE_PENALTY 20 diff --git a/include/asm-sparc/smp.h b/include/asm-sparc/smp.h index f986c0d0922a..4f96d8333a12 100644 --- a/include/asm-sparc/smp.h +++ b/include/asm-sparc/smp.h @@ -148,7 +148,7 @@ extern __inline__ int hard_smp_processor_id(void) } #endif -#define smp_processor_id() (current_thread_info()->cpu) +#define raw_smp_processor_id() (current_thread_info()->cpu) #define prof_multiplier(__cpu) cpu_data(__cpu).multiplier #define prof_counter(__cpu) cpu_data(__cpu).counter diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h index 5e3e06d908fe..110a2de89123 100644 --- a/include/asm-sparc64/smp.h +++ b/include/asm-sparc64/smp.h @@ -64,7 +64,7 @@ static __inline__ int hard_smp_processor_id(void) } } -#define smp_processor_id() (current_thread_info()->cpu) +#define raw_smp_processor_id() (current_thread_info()->cpu) #endif /* !(__ASSEMBLY__) */ diff --git a/include/asm-um/smp.h b/include/asm-um/smp.h index 4412d5d9c26b..d879eba2b52c 100644 --- a/include/asm-um/smp.h +++ b/include/asm-um/smp.h @@ -8,7 +8,8 @@ #include "asm/current.h" #include "linux/cpumask.h" -#define smp_processor_id() (current_thread->cpu) +#define raw_smp_processor_id() (current_thread->cpu) + #define cpu_logical_map(n) (n) #define cpu_number_map(n) (n) #define PROC_CHANGE_PENALTY 15 /* Pick a number, any number */ diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h index 96844fecbde8..a7425aa5a3b7 100644 --- a/include/asm-x86_64/smp.h +++ b/include/asm-x86_64/smp.h @@ -68,7 +68,7 @@ static inline int num_booting_cpus(void) return cpus_weight(cpu_callout_map); } -#define __smp_processor_id() read_pda(cpunumber) +#define raw_smp_processor_id() read_pda(cpunumber) extern __inline int hard_smp_processor_id(void) { diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index e530c6c092f1..beacd931b606 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -381,7 +381,7 @@ int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *, int, struct file *, #include /* Returns the number of the current Node. */ -#define numa_node_id() (cpu_to_node(_smp_processor_id())) +#define numa_node_id() (cpu_to_node(raw_smp_processor_id())) #ifndef CONFIG_DISCONTIGMEM diff --git a/include/linux/smp.h b/include/linux/smp.h index dcf1db3b35d3..9dfa3ee769ae 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -92,10 +92,7 @@ void smp_prepare_boot_cpu(void); /* * These macros fold the SMP functionality into a single CPU system */ - -#if !defined(__smp_processor_id) || !defined(CONFIG_PREEMPT) -# define smp_processor_id() 0 -#endif +#define raw_smp_processor_id() 0 #define hard_smp_processor_id() 0 #define smp_call_function(func,info,retry,wait) ({ 0; }) #define on_each_cpu(func,info,retry,wait) ({ func(info); 0; }) @@ -106,30 +103,25 @@ static inline void smp_send_reschedule(int cpu) { } #endif /* !SMP */ /* - * DEBUG_PREEMPT support: check whether smp_processor_id() is being - * used in a preemption-safe way. + * smp_processor_id(): get the current CPU ID. * - * An architecture has to enable this debugging code explicitly. - * It can do so by renaming the smp_processor_id() macro to - * __smp_processor_id(). This should only be done after some minimal - * testing, because usually there are a number of false positives - * that an architecture will trigger. + * if DEBUG_PREEMPT is enabled the we check whether it is + * used in a preemption-safe way. (smp_processor_id() is safe + * if it's used in a preemption-off critical section, or in + * a thread that is bound to the current CPU.) * - * To fix a false positive (i.e. smp_processor_id() use that the - * debugging code reports but which use for some reason is legal), - * change the smp_processor_id() reference to _smp_processor_id(), - * which is the nondebug variant. NOTE: don't use this to hack around - * real bugs. + * NOTE: raw_smp_processor_id() is for internal use only + * (smp_processor_id() is the preferred variant), but in rare + * instances it might also be used to turn off false positives + * (i.e. smp_processor_id() use that the debugging code reports but + * which use for some reason is legal). Don't use this to hack around + * the warning message, as your code might not work under PREEMPT. */ -#ifdef __smp_processor_id -# if defined(CONFIG_PREEMPT) && defined(CONFIG_DEBUG_PREEMPT) - extern unsigned int smp_processor_id(void); -# else -# define smp_processor_id() __smp_processor_id() -# endif -# define _smp_processor_id() __smp_processor_id() +#ifdef CONFIG_DEBUG_PREEMPT + extern unsigned int debug_smp_processor_id(void); +# define smp_processor_id() debug_smp_processor_id() #else -# define _smp_processor_id() smp_processor_id() +# define smp_processor_id() raw_smp_processor_id() #endif #define get_cpu() ({ preempt_disable(); smp_processor_id(); }) diff --git a/include/net/route.h b/include/net/route.h index d34ca8fc6756..c3cd069a9aca 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -107,7 +107,7 @@ struct rt_cache_stat extern struct rt_cache_stat *rt_cache_stat; #define RT_CACHE_STAT_INC(field) \ - (per_cpu_ptr(rt_cache_stat, _smp_processor_id())->field++) + (per_cpu_ptr(rt_cache_stat, raw_smp_processor_id())->field++) extern struct ip_rt_acct *ip_rt_acct; diff --git a/include/net/snmp.h b/include/net/snmp.h index a15ab256276e..a36bed8ea210 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h @@ -128,18 +128,18 @@ struct linux_mib { #define SNMP_STAT_USRPTR(name) (name[1]) #define SNMP_INC_STATS_BH(mib, field) \ - (per_cpu_ptr(mib[0], _smp_processor_id())->mibs[field]++) + (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field]++) #define SNMP_INC_STATS_OFFSET_BH(mib, field, offset) \ - (per_cpu_ptr(mib[0], _smp_processor_id())->mibs[field + (offset)]++) + (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field + (offset)]++) #define SNMP_INC_STATS_USER(mib, field) \ - (per_cpu_ptr(mib[1], _smp_processor_id())->mibs[field]++) + (per_cpu_ptr(mib[1], raw_smp_processor_id())->mibs[field]++) #define SNMP_INC_STATS(mib, field) \ - (per_cpu_ptr(mib[!in_softirq()], _smp_processor_id())->mibs[field]++) + (per_cpu_ptr(mib[!in_softirq()], raw_smp_processor_id())->mibs[field]++) #define SNMP_DEC_STATS(mib, field) \ - (per_cpu_ptr(mib[!in_softirq()], _smp_processor_id())->mibs[field]--) + (per_cpu_ptr(mib[!in_softirq()], raw_smp_processor_id())->mibs[field]--) #define SNMP_ADD_STATS_BH(mib, field, addend) \ - (per_cpu_ptr(mib[0], _smp_processor_id())->mibs[field] += addend) + (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field] += addend) #define SNMP_ADD_STATS_USER(mib, field, addend) \ - (per_cpu_ptr(mib[1], _smp_processor_id())->mibs[field] += addend) + (per_cpu_ptr(mib[1], raw_smp_processor_id())->mibs[field] += addend) #endif diff --git a/kernel/module.c b/kernel/module.c index 83b3d376708c..a566745dde62 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -379,7 +379,7 @@ static void module_unload_init(struct module *mod) for (i = 0; i < NR_CPUS; i++) local_set(&mod->ref[i].count, 0); /* Hold reference count during initialization. */ - local_set(&mod->ref[_smp_processor_id()].count, 1); + local_set(&mod->ref[raw_smp_processor_id()].count, 1); /* Backwards compatibility macros put refcount during init. */ mod->waiter = current; } diff --git a/kernel/power/smp.c b/kernel/power/smp.c index cba3584b80fe..457c2302ed42 100644 --- a/kernel/power/smp.c +++ b/kernel/power/smp.c @@ -48,11 +48,11 @@ void disable_nonboot_cpus(void) { oldmask = current->cpus_allowed; set_cpus_allowed(current, cpumask_of_cpu(0)); - printk("Freezing CPUs (at %d)", _smp_processor_id()); + printk("Freezing CPUs (at %d)", raw_smp_processor_id()); current->state = TASK_INTERRUPTIBLE; schedule_timeout(HZ); printk("..."); - BUG_ON(_smp_processor_id() != 0); + BUG_ON(raw_smp_processor_id() != 0); /* FIXME: for this to work, all the CPUs must be running * "idle" thread (or we deadlock). Is that guaranteed? */ diff --git a/kernel/sched.c b/kernel/sched.c index f12a0c8a7d98..deca041fc364 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -3814,7 +3814,7 @@ EXPORT_SYMBOL(yield); */ void __sched io_schedule(void) { - struct runqueue *rq = &per_cpu(runqueues, _smp_processor_id()); + struct runqueue *rq = &per_cpu(runqueues, raw_smp_processor_id()); atomic_inc(&rq->nr_iowait); schedule(); @@ -3825,7 +3825,7 @@ EXPORT_SYMBOL(io_schedule); long __sched io_schedule_timeout(long timeout) { - struct runqueue *rq = &per_cpu(runqueues, _smp_processor_id()); + struct runqueue *rq = &per_cpu(runqueues, raw_smp_processor_id()); long ret; atomic_inc(&rq->nr_iowait); diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c index 6116b25aa7cf..84a9d18aa8da 100644 --- a/kernel/stop_machine.c +++ b/kernel/stop_machine.c @@ -100,7 +100,7 @@ static int stop_machine(void) stopmachine_state = STOPMACHINE_WAIT; for_each_online_cpu(i) { - if (i == _smp_processor_id()) + if (i == raw_smp_processor_id()) continue; ret = kernel_thread(stopmachine, (void *)(long)i,CLONE_KERNEL); if (ret < 0) @@ -182,7 +182,7 @@ struct task_struct *__stop_machine_run(int (*fn)(void *), void *data, /* If they don't care which CPU fn runs on, bind to any online one. */ if (cpu == NR_CPUS) - cpu = _smp_processor_id(); + cpu = raw_smp_processor_id(); p = kthread_create(do_stop, &smdata, "kstopmachine"); if (!IS_ERR(p)) { diff --git a/lib/Makefile b/lib/Makefile index 9eccea9429a7..5f10cb898407 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -20,6 +20,7 @@ lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o +obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o ifneq ($(CONFIG_HAVE_DEC_LOCK),y) lib-y += dec_and_lock.o diff --git a/lib/kernel_lock.c b/lib/kernel_lock.c index 99b0ae3d51dd..bd2bc5d887b8 100644 --- a/lib/kernel_lock.c +++ b/lib/kernel_lock.c @@ -9,61 +9,6 @@ #include #include -#if defined(CONFIG_PREEMPT) && defined(__smp_processor_id) && \ - defined(CONFIG_DEBUG_PREEMPT) - -/* - * Debugging check. - */ -unsigned int smp_processor_id(void) -{ - unsigned long preempt_count = preempt_count(); - int this_cpu = __smp_processor_id(); - cpumask_t this_mask; - - if (likely(preempt_count)) - goto out; - - if (irqs_disabled()) - goto out; - - /* - * Kernel threads bound to a single CPU can safely use - * smp_processor_id(): - */ - this_mask = cpumask_of_cpu(this_cpu); - - if (cpus_equal(current->cpus_allowed, this_mask)) - goto out; - - /* - * It is valid to assume CPU-locality during early bootup: - */ - if (system_state != SYSTEM_RUNNING) - goto out; - - /* - * Avoid recursion: - */ - preempt_disable(); - - if (!printk_ratelimit()) - goto out_enable; - - printk(KERN_ERR "BUG: using smp_processor_id() in preemptible [%08x] code: %s/%d\n", preempt_count(), current->comm, current->pid); - print_symbol("caller is %s\n", (long)__builtin_return_address(0)); - dump_stack(); - -out_enable: - preempt_enable_no_resched(); -out: - return this_cpu; -} - -EXPORT_SYMBOL(smp_processor_id); - -#endif /* PREEMPT && __smp_processor_id && DEBUG_PREEMPT */ - #ifdef CONFIG_PREEMPT_BKL /* * The 'big kernel semaphore' diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c new file mode 100644 index 000000000000..42c08ef828c5 --- /dev/null +++ b/lib/smp_processor_id.c @@ -0,0 +1,55 @@ +/* + * lib/smp_processor_id.c + * + * DEBUG_PREEMPT variant of smp_processor_id(). + */ +#include +#include + +unsigned int debug_smp_processor_id(void) +{ + unsigned long preempt_count = preempt_count(); + int this_cpu = raw_smp_processor_id(); + cpumask_t this_mask; + + if (likely(preempt_count)) + goto out; + + if (irqs_disabled()) + goto out; + + /* + * Kernel threads bound to a single CPU can safely use + * smp_processor_id(): + */ + this_mask = cpumask_of_cpu(this_cpu); + + if (cpus_equal(current->cpus_allowed, this_mask)) + goto out; + + /* + * It is valid to assume CPU-locality during early bootup: + */ + if (system_state != SYSTEM_RUNNING) + goto out; + + /* + * Avoid recursion: + */ + preempt_disable(); + + if (!printk_ratelimit()) + goto out_enable; + + printk(KERN_ERR "BUG: using smp_processor_id() in preemptible [%08x] code: %s/%d\n", preempt_count(), current->comm, current->pid); + print_symbol("caller is %s\n", (long)__builtin_return_address(0)); + dump_stack(); + +out_enable: + preempt_enable_no_resched(); +out: + return this_cpu; +} + +EXPORT_SYMBOL(debug_smp_processor_id); + -- cgit v1.2.3-59-g8ed1b From b15e0905f2b9964fc7426fecab57445e96021b61 Mon Sep 17 00:00:00 2001 From: "akpm@osdl.org" Date: Tue, 21 Jun 2005 17:14:35 -0700 Subject: [PATCH] vmscan: notice slab shrinking Fix a problem identified by Andrea Arcangeli kswapd will set a zone into all_unreclaimable state if it sees that we're not successfully reclaiming LRU pages. But that fails to notice that we're successfully reclaiming slab obects, so we can set all_unreclaimable too soon. So change shrink_slab() to return a success indication if it actually reclaimed some objects, and don't assume that the zone is all_unreclaimable if that is true. This means that we won't enter all_unreclaimable state if we are successfully freeing slab objects but we're not yet actually freeing slab pages, due to internal fragmentation. (hm, this has a shortcoming. We could be successfully freeing ZONE_NORMAL slab objects while being really oom on ZONE_DMA. If that happens then kswapd might burn a lot of CPU. But given that there might be some slab objects in ZONE_DMA, perhaps that is appropriate.) Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 269eded9b459..c62cadce0426 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -180,17 +180,20 @@ EXPORT_SYMBOL(remove_shrinker); * `lru_pages' represents the number of on-LRU pages in all the zones which * are eligible for the caller's allocation attempt. It is used for balancing * slab reclaim versus page reclaim. + * + * Returns the number of slab objects which we shrunk. */ static int shrink_slab(unsigned long scanned, unsigned int gfp_mask, unsigned long lru_pages) { struct shrinker *shrinker; + int ret = 0; if (scanned == 0) scanned = SWAP_CLUSTER_MAX; if (!down_read_trylock(&shrinker_rwsem)) - return 0; + return 1; /* Assume we'll be able to shrink next time */ list_for_each_entry(shrinker, &shrinker_list, list) { unsigned long long delta; @@ -209,10 +212,14 @@ static int shrink_slab(unsigned long scanned, unsigned int gfp_mask, while (total_scan >= SHRINK_BATCH) { long this_scan = SHRINK_BATCH; int shrink_ret; + int nr_before; + nr_before = (*shrinker->shrinker)(0, gfp_mask); shrink_ret = (*shrinker->shrinker)(this_scan, gfp_mask); if (shrink_ret == -1) break; + if (shrink_ret < nr_before) + ret += nr_before - shrink_ret; mod_page_state(slabs_scanned, this_scan); total_scan -= this_scan; @@ -222,7 +229,7 @@ static int shrink_slab(unsigned long scanned, unsigned int gfp_mask, shrinker->nr += total_scan; } up_read(&shrinker_rwsem); - return 0; + return ret; } /* Called without lock on whether page is mapped, so answer is unstable */ @@ -1079,6 +1086,7 @@ scan: */ for (i = 0; i <= end_zone; i++) { struct zone *zone = pgdat->node_zones + i; + int nr_slab; if (zone->present_pages == 0) continue; @@ -1100,14 +1108,15 @@ scan: sc.swap_cluster_max = nr_pages? nr_pages : SWAP_CLUSTER_MAX; shrink_zone(zone, &sc); reclaim_state->reclaimed_slab = 0; - shrink_slab(sc.nr_scanned, GFP_KERNEL, lru_pages); + nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL, + lru_pages); sc.nr_reclaimed += reclaim_state->reclaimed_slab; total_reclaimed += sc.nr_reclaimed; total_scanned += sc.nr_scanned; if (zone->all_unreclaimable) continue; - if (zone->pages_scanned >= (zone->nr_active + - zone->nr_inactive) * 4) + if (nr_slab == 0 && zone->pages_scanned >= + (zone->nr_active + zone->nr_inactive) * 4) zone->all_unreclaimable = 1; /* * If we've done a decent amount of scanning and -- cgit v1.2.3-59-g8ed1b From e798c6e87b64d9fdbd5e9f757b1c033223763d9f Mon Sep 17 00:00:00 2001 From: Prasanna Meda Date: Tue, 21 Jun 2005 17:14:36 -0700 Subject: [PATCH] madvise: do not split the maps This attempts to avoid splittings when it is not needed, that is when vm_flags are same as new flags. The idea is from the <2.6.11 mlock_fixup and others. This will provide base for the next madvise merging patch. Signed-off-by: Prasanna Meda Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/madvise.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/mm/madvise.c b/mm/madvise.c index 944b5e52d812..75b81ad1f98c 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -19,6 +19,21 @@ static long madvise_behavior(struct vm_area_struct * vma, unsigned long start, { struct mm_struct * mm = vma->vm_mm; int error = 0; + int new_flags = vma->vm_flags & ~VM_READHINTMASK; + + switch (behavior) { + case MADV_SEQUENTIAL: + new_flags |= VM_SEQ_READ; + break; + case MADV_RANDOM: + new_flags |= VM_RAND_READ; + break; + default: + break; + } + + if (new_flags == vma->vm_flags) + goto out; if (start != vma->vm_start) { error = split_vma(mm, vma, start, 1); @@ -36,17 +51,7 @@ static long madvise_behavior(struct vm_area_struct * vma, unsigned long start, * vm_flags is protected by the mmap_sem held in write mode. */ VM_ClearReadHint(vma); - - switch (behavior) { - case MADV_SEQUENTIAL: - vma->vm_flags |= VM_SEQ_READ; - break; - case MADV_RANDOM: - vma->vm_flags |= VM_RAND_READ; - break; - default: - break; - } + vma->vm_flags = new_flags; out: if (error == -ENOMEM) -- cgit v1.2.3-59-g8ed1b From 05b7438475ddbac47e75506913d44550f0e75938 Mon Sep 17 00:00:00 2001 From: Prasanna Meda Date: Tue, 21 Jun 2005 17:14:37 -0700 Subject: [PATCH] madvise: merge the maps This attempts to merge back the split maps. This code is mostly copied from Chrisw's mlock merging from post 2.6.11 trees. The only difference is in munmapped_error handling. Also passed prev to willneed/dontneed, eventhogh they do not handle it now, since I felt it will be cleaner, instead of handling prev in madvise_vma in some cases and in subfunction in some cases. Signed-off-by: Prasanna Meda Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/madvise.c | 80 ++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 29 deletions(-) diff --git a/mm/madvise.c b/mm/madvise.c index 75b81ad1f98c..e3108054733c 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -8,17 +8,20 @@ #include #include #include +#include #include /* * We can potentially split a vm area into separate * areas, each area with its own behavior. */ -static long madvise_behavior(struct vm_area_struct * vma, unsigned long start, - unsigned long end, int behavior) +static long madvise_behavior(struct vm_area_struct * vma, + struct vm_area_struct **prev, + unsigned long start, unsigned long end, int behavior) { struct mm_struct * mm = vma->vm_mm; int error = 0; + pgoff_t pgoff; int new_flags = vma->vm_flags & ~VM_READHINTMASK; switch (behavior) { @@ -32,8 +35,20 @@ static long madvise_behavior(struct vm_area_struct * vma, unsigned long start, break; } - if (new_flags == vma->vm_flags) - goto out; + if (new_flags == vma->vm_flags) { + *prev = vma; + goto success; + } + + pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT); + *prev = vma_merge(mm, *prev, start, end, new_flags, vma->anon_vma, + vma->vm_file, pgoff, vma_policy(vma)); + if (*prev) { + vma = *prev; + goto success; + } + + *prev = vma; if (start != vma->vm_start) { error = split_vma(mm, vma, start, 1); @@ -56,6 +71,7 @@ static long madvise_behavior(struct vm_area_struct * vma, unsigned long start, out: if (error == -ENOMEM) error = -EAGAIN; +success: return error; } @@ -63,6 +79,7 @@ out: * Schedule all required I/O operations. Do not wait for completion. */ static long madvise_willneed(struct vm_area_struct * vma, + struct vm_area_struct ** prev, unsigned long start, unsigned long end) { struct file *file = vma->vm_file; @@ -70,6 +87,7 @@ static long madvise_willneed(struct vm_area_struct * vma, if (!file) return -EBADF; + *prev = vma; start = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; if (end > vma->vm_end) end = vma->vm_end; @@ -100,8 +118,10 @@ static long madvise_willneed(struct vm_area_struct * vma, * dirty pages is already available as msync(MS_INVALIDATE). */ static long madvise_dontneed(struct vm_area_struct * vma, + struct vm_area_struct ** prev, unsigned long start, unsigned long end) { + *prev = vma; if ((vma->vm_flags & VM_LOCKED) || is_vm_hugetlb_page(vma)) return -EINVAL; @@ -116,8 +136,8 @@ static long madvise_dontneed(struct vm_area_struct * vma, return 0; } -static long madvise_vma(struct vm_area_struct * vma, unsigned long start, - unsigned long end, int behavior) +static long madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev, + unsigned long start, unsigned long end, int behavior) { long error = -EBADF; @@ -125,15 +145,15 @@ static long madvise_vma(struct vm_area_struct * vma, unsigned long start, case MADV_NORMAL: case MADV_SEQUENTIAL: case MADV_RANDOM: - error = madvise_behavior(vma, start, end, behavior); + error = madvise_behavior(vma, prev, start, end, behavior); break; case MADV_WILLNEED: - error = madvise_willneed(vma, start, end); + error = madvise_willneed(vma, prev, start, end); break; case MADV_DONTNEED: - error = madvise_dontneed(vma, start, end); + error = madvise_dontneed(vma, prev, start, end); break; default: @@ -180,8 +200,8 @@ static long madvise_vma(struct vm_area_struct * vma, unsigned long start, */ asmlinkage long sys_madvise(unsigned long start, size_t len_in, int behavior) { - unsigned long end; - struct vm_area_struct * vma; + unsigned long end, tmp; + struct vm_area_struct * vma, *prev; int unmapped_error = 0; int error = -EINVAL; size_t len; @@ -207,40 +227,42 @@ asmlinkage long sys_madvise(unsigned long start, size_t len_in, int behavior) /* * If the interval [start,end) covers some unmapped address * ranges, just ignore them, but return -ENOMEM at the end. + * - different from the way of handling in mlock etc. */ - vma = find_vma(current->mm, start); + vma = find_vma_prev(current->mm, start, &prev); + if (!vma && prev) + vma = prev->vm_next; for (;;) { /* Still start < end. */ error = -ENOMEM; if (!vma) goto out; - /* Here start < vma->vm_end. */ + /* Here start < (end|vma->vm_end). */ if (start < vma->vm_start) { unmapped_error = -ENOMEM; start = vma->vm_start; + if (start >= end) + goto out; } - /* Here vma->vm_start <= start < vma->vm_end. */ - if (end <= vma->vm_end) { - if (start < end) { - error = madvise_vma(vma, start, end, - behavior); - if (error) - goto out; - } - error = unmapped_error; - goto out; - } + /* Here vma->vm_start <= start < (end|vma->vm_end) */ + tmp = vma->vm_end; + if (end < tmp) + tmp = end; - /* Here vma->vm_start <= start < vma->vm_end < end. */ - error = madvise_vma(vma, start, vma->vm_end, behavior); + /* Here vma->vm_start <= start < tmp <= (end|vma->vm_end). */ + error = madvise_vma(vma, &prev, start, tmp, behavior); if (error) goto out; - start = vma->vm_end; - vma = vma->vm_next; + start = tmp; + if (start < prev->vm_end) + start = prev->vm_end; + error = unmapped_error; + if (start >= end) + goto out; + vma = prev->vm_next; } - out: up_write(¤t->mm->mmap_sem); return error; -- cgit v1.2.3-59-g8ed1b From 295ab93497ec703f7d6eaf0787dd9768b83035fe Mon Sep 17 00:00:00 2001 From: Nikita Danilov Date: Tue, 21 Jun 2005 17:14:38 -0700 Subject: [PATCH] mm: add /proc/zoneinfo Add /proc/zoneinfo file to display information about memory zones. Useful to analyze VM behaviour. Signed-off-by: Nikita Danilov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/proc_misc.c | 14 +++++++ mm/page_alloc.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 125 insertions(+), 2 deletions(-) diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index a60a3b3d8a7b..63a9fbf1ac51 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c @@ -219,6 +219,19 @@ static struct file_operations fragmentation_file_operations = { .release = seq_release, }; +extern struct seq_operations zoneinfo_op; +static int zoneinfo_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &zoneinfo_op); +} + +static struct file_operations proc_zoneinfo_file_operations = { + .open = zoneinfo_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + static int version_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -589,6 +602,7 @@ void __init proc_misc_init(void) create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations); create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations); create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations); + create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations); create_seq_entry("diskstats", 0, &proc_diskstats_operations); #ifdef CONFIG_MODULES create_seq_entry("modules", 0, &proc_modules_operations); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index b1061b1962f8..40169f0b7e9e 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1853,6 +1853,115 @@ struct seq_operations fragmentation_op = { .show = frag_show, }; +/* + * Output information about zones in @pgdat. + */ +static int zoneinfo_show(struct seq_file *m, void *arg) +{ + pg_data_t *pgdat = arg; + struct zone *zone; + struct zone *node_zones = pgdat->node_zones; + unsigned long flags; + + for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; zone++) { + int i; + + if (!zone->present_pages) + continue; + + spin_lock_irqsave(&zone->lock, flags); + seq_printf(m, "Node %d, zone %8s", pgdat->node_id, zone->name); + seq_printf(m, + "\n pages free %lu" + "\n min %lu" + "\n low %lu" + "\n high %lu" + "\n active %lu" + "\n inactive %lu" + "\n scanned %lu (a: %lu i: %lu)" + "\n spanned %lu" + "\n present %lu", + zone->free_pages, + zone->pages_min, + zone->pages_low, + zone->pages_high, + zone->nr_active, + zone->nr_inactive, + zone->pages_scanned, + zone->nr_scan_active, zone->nr_scan_inactive, + zone->spanned_pages, + zone->present_pages); + seq_printf(m, + "\n protection: (%lu", + zone->lowmem_reserve[0]); + for (i = 1; i < ARRAY_SIZE(zone->lowmem_reserve); i++) + seq_printf(m, ", %lu", zone->lowmem_reserve[i]); + seq_printf(m, + ")" + "\n pagesets"); + for (i = 0; i < ARRAY_SIZE(zone->pageset); i++) { + struct per_cpu_pageset *pageset; + int j; + + pageset = &zone->pageset[i]; + for (j = 0; j < ARRAY_SIZE(pageset->pcp); j++) { + if (pageset->pcp[j].count) + break; + } + if (j == ARRAY_SIZE(pageset->pcp)) + continue; + for (j = 0; j < ARRAY_SIZE(pageset->pcp); j++) { + seq_printf(m, + "\n cpu: %i pcp: %i" + "\n count: %i" + "\n low: %i" + "\n high: %i" + "\n batch: %i", + i, j, + pageset->pcp[j].count, + pageset->pcp[j].low, + pageset->pcp[j].high, + pageset->pcp[j].batch); + } +#ifdef CONFIG_NUMA + seq_printf(m, + "\n numa_hit: %lu" + "\n numa_miss: %lu" + "\n numa_foreign: %lu" + "\n interleave_hit: %lu" + "\n local_node: %lu" + "\n other_node: %lu", + pageset->numa_hit, + pageset->numa_miss, + pageset->numa_foreign, + pageset->interleave_hit, + pageset->local_node, + pageset->other_node); +#endif + } + seq_printf(m, + "\n all_unreclaimable: %u" + "\n prev_priority: %i" + "\n temp_priority: %i" + "\n start_pfn: %lu", + zone->all_unreclaimable, + zone->prev_priority, + zone->temp_priority, + zone->zone_start_pfn); + spin_unlock_irqrestore(&zone->lock, flags); + seq_putc(m, '\n'); + } + return 0; +} + +struct seq_operations zoneinfo_op = { + .start = frag_start, /* iterate over all zones. The same as in + * fragmentation. */ + .next = frag_next, + .stop = frag_stop, + .show = zoneinfo_show, +}; + static char *vmstat_text[] = { "nr_dirty", "nr_writeback", @@ -2058,10 +2167,10 @@ static void setup_per_zone_pages_min(void) min_pages = 128; zone->pages_min = min_pages; } else { - /* if it's a lowmem zone, reserve a number of pages + /* if it's a lowmem zone, reserve a number of pages * proportionate to the zone's size. */ - zone->pages_min = (pages_min * zone->present_pages) / + zone->pages_min = (pages_min * zone->present_pages) / lowmem_pages; } -- cgit v1.2.3-59-g8ed1b From bfbb38fb808ac23ef44472d05d9bb36edfb49ed0 Mon Sep 17 00:00:00 2001 From: Martin Hicks Date: Tue, 21 Jun 2005 17:14:40 -0700 Subject: [PATCH] VM: add may_swap flag to scan_control Here's the next round of these patches. These are totally different in an attempt to meet the "simpler" request after the last patches. For reference the earlier threads are: http://marc.theaimsgroup.com/?l=linux-kernel&m=110839604924587&w=2 http://marc.theaimsgroup.com/?l=linux-mm&m=111461480721249&w=2 This set of patches replaces my other vm- patches that are currently in -mm. So they're against 2.6.12-rc5-mm1 about half way through the -mm patchset. As I said already this patch is a lot simpler. The reclaim is turned on or off on a per-zone basis using a syscall. I haven't tested the x86 syscall, so it might be wrong. It uses the existing reclaim/pageout code with the small addition of a may_swap flag to scan_control (patch 1/4). I also added __GFP_NORECLAIM (patch 3/4) so that certain allocation types can be flagged to never cause reclaim. This was a deficiency that was in all of my earlier patch sets. Previously, doing a big buffered read would fill one zone with page cache and then start to reclaim from that same zone, leaving the other zones untouched. Adding some extra throttling on the reclaim was also required (patch 4/4). Without the machine would grind to a crawl when doing a "make -j" kernel build. Even with this patch the System Time is higher on average, but it seems tolerable. Here are some numbers for kernbench runs on a 2-node, 4cpu, 8Gig RAM Altix in the "make -j" run: wall user sys %cpu ctx sw. sleeps ---- ---- --- ---- ------ ------ No patch 1009 1384 847 258 298170 504402 w/patch, no reclaim 880 1376 667 288 254064 396745 w/patch & reclaim 1079 1385 926 252 291625 548873 These numbers are the average of 2 runs of 3 "make -j" runs done right after system boot. Run-to-run variability for "make -j" is huge, so these numbers aren't terribly useful except to seee that with reclaim the benchmark still finishes in a reasonable amount of time. I also looked at the NUMA hit/miss stats for the "make -j" runs and the reclaim doesn't make any difference when the machine is thrashing away. Doing a "make -j8" on a single node that is filled with page cache pages takes 700 seconds with reclaim turned on and 735 seconds without reclaim (due to remote memory accesses). The simple zone_reclaim syscall program is at http://www.bork.org/~mort/sgi/zone_reclaim.c This patch: This adds an extra switch to the scan_control struct. It simply lets the reclaim code know if its allowed to swap pages out. This was required for a simple per-zone reclaimer. Without this addition pages would be swapped out as soon as a zone ran out of memory and the early reclaim kicked in. Signed-off-by: Martin Hicks Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index c62cadce0426..6379ddbffd9b 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -74,6 +74,9 @@ struct scan_control { int may_writepage; + /* Can pages be swapped as part of reclaim? */ + int may_swap; + /* This context's SWAP_CLUSTER_MAX. If freeing memory for * suspend, we effectively ignore SWAP_CLUSTER_MAX. * In this context, it doesn't matter that we scan the @@ -414,7 +417,7 @@ static int shrink_list(struct list_head *page_list, struct scan_control *sc) * Anonymous process memory has backing store? * Try to allocate it some swap space here. */ - if (PageAnon(page) && !PageSwapCache(page)) { + if (PageAnon(page) && !PageSwapCache(page) && sc->may_swap) { if (!add_to_swap(page)) goto activate_locked; } @@ -927,6 +930,7 @@ int try_to_free_pages(struct zone **zones, sc.gfp_mask = gfp_mask; sc.may_writepage = 0; + sc.may_swap = 1; inc_page_state(allocstall); @@ -1027,6 +1031,7 @@ loop_again: total_reclaimed = 0; sc.gfp_mask = GFP_KERNEL; sc.may_writepage = 0; + sc.may_swap = 1; sc.nr_mapped = read_page_state(nr_mapped); inc_page_state(pageoutrun); -- cgit v1.2.3-59-g8ed1b From 753ee728964e5afb80c17659cc6c3a6fd0a42fe0 Mon Sep 17 00:00:00 2001 From: Martin Hicks Date: Tue, 21 Jun 2005 17:14:41 -0700 Subject: [PATCH] VM: early zone reclaim This is the core of the (much simplified) early reclaim. The goal of this patch is to reclaim some easily-freed pages from a zone before falling back onto another zone. One of the major uses of this is NUMA machines. With the default allocator behavior the allocator would look for memory in another zone, which might be off-node, before trying to reclaim from the current zone. This adds a zone tuneable to enable early zone reclaim. It is selected on a per-zone basis and is turned on/off via syscall. Adding some extra throttling on the reclaim was also required (patch 4/4). Without the machine would grind to a crawl when doing a "make -j" kernel build. Even with this patch the System Time is higher on average, but it seems tolerable. Here are some numbers for kernbench runs on a 2-node, 4cpu, 8Gig RAM Altix in the "make -j" run: wall user sys %cpu ctx sw. sleeps ---- ---- --- ---- ------ ------ No patch 1009 1384 847 258 298170 504402 w/patch, no reclaim 880 1376 667 288 254064 396745 w/patch & reclaim 1079 1385 926 252 291625 548873 These numbers are the average of 2 runs of 3 "make -j" runs done right after system boot. Run-to-run variability for "make -j" is huge, so these numbers aren't terribly useful except to seee that with reclaim the benchmark still finishes in a reasonable amount of time. I also looked at the NUMA hit/miss stats for the "make -j" runs and the reclaim doesn't make any difference when the machine is thrashing away. Doing a "make -j8" on a single node that is filled with page cache pages takes 700 seconds with reclaim turned on and 735 seconds without reclaim (due to remote memory accesses). The simple zone_reclaim syscall program is at http://www.bork.org/~mort/sgi/zone_reclaim.c Signed-off-by: Martin Hicks Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/syscall_table.S | 2 +- arch/ia64/kernel/entry.S | 2 +- include/asm-i386/unistd.h | 2 +- include/asm-ia64/unistd.h | 1 + include/linux/mmzone.h | 6 ++++ include/linux/swap.h | 1 + kernel/sys_ni.c | 1 + mm/page_alloc.c | 33 +++++++++++++++++---- mm/vmscan.c | 64 ++++++++++++++++++++++++++++++++++++++++ 9 files changed, 104 insertions(+), 8 deletions(-) diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S index 6cd1ed311f02..d408afaf6495 100644 --- a/arch/i386/kernel/syscall_table.S +++ b/arch/i386/kernel/syscall_table.S @@ -251,7 +251,7 @@ ENTRY(sys_call_table) .long sys_io_submit .long sys_io_cancel .long sys_fadvise64 /* 250 */ - .long sys_ni_syscall + .long sys_set_zone_reclaim .long sys_exit_group .long sys_lookup_dcookie .long sys_epoll_create diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index d99316c9be28..b1d5d3d5276c 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -1579,7 +1579,7 @@ sys_call_table: data8 sys_keyctl data8 sys_ni_syscall data8 sys_ni_syscall // 1275 - data8 sys_ni_syscall + data8 sys_set_zone_reclaim data8 sys_ni_syscall data8 sys_ni_syscall data8 sys_ni_syscall diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h index 61bcc1b1e3f4..176413fb9ae3 100644 --- a/include/asm-i386/unistd.h +++ b/include/asm-i386/unistd.h @@ -256,7 +256,7 @@ #define __NR_io_submit 248 #define __NR_io_cancel 249 #define __NR_fadvise64 250 - +#define __NR_set_zone_reclaim 251 #define __NR_exit_group 252 #define __NR_lookup_dcookie 253 #define __NR_epoll_create 254 diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h index 33e26c557c5c..f7f43ec2483a 100644 --- a/include/asm-ia64/unistd.h +++ b/include/asm-ia64/unistd.h @@ -263,6 +263,7 @@ #define __NR_add_key 1271 #define __NR_request_key 1272 #define __NR_keyctl 1273 +#define __NR_set_zone_reclaim 1276 #ifdef __KERNEL__ diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index beacd931b606..dfc2452ccb10 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -144,6 +144,12 @@ struct zone { unsigned long pages_scanned; /* since last reclaim */ int all_unreclaimable; /* All pages pinned */ + /* + * Does the allocator try to reclaim pages from the zone as soon + * as it fails a watermark_ok() in __alloc_pages? + */ + int reclaim_pages; + /* * prev_priority holds the scanning priority for this zone. It is * defined as the scanning priority at which we achieved our reclaim diff --git a/include/linux/swap.h b/include/linux/swap.h index 3bbc41be9bd0..0d21e682d99d 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -173,6 +173,7 @@ extern void swap_setup(void); /* linux/mm/vmscan.c */ extern int try_to_free_pages(struct zone **, unsigned int, unsigned int); +extern int zone_reclaim(struct zone *, unsigned int, unsigned int); extern int shrink_all_memory(int); extern int vm_swappiness; diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 0dda70ed1f98..6f15bea7d1a8 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c @@ -77,6 +77,7 @@ cond_syscall(sys_request_key); cond_syscall(sys_keyctl); cond_syscall(compat_sys_keyctl); cond_syscall(compat_sys_socketcall); +cond_syscall(sys_set_zone_reclaim); /* arch-specific weak syscall entries */ cond_syscall(sys_pciconfig_read); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 40169f0b7e9e..3c0f69ded6b5 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -724,6 +724,14 @@ int zone_watermark_ok(struct zone *z, int order, unsigned long mark, return 1; } +static inline int +should_reclaim_zone(struct zone *z, unsigned int gfp_mask) +{ + if (!z->reclaim_pages) + return 0; + return 1; +} + /* * This is the 'heart' of the zoned buddy allocator. */ @@ -760,17 +768,32 @@ __alloc_pages(unsigned int __nocast gfp_mask, unsigned int order, classzone_idx = zone_idx(zones[0]); - restart: +restart: /* Go through the zonelist once, looking for a zone with enough free */ for (i = 0; (z = zones[i]) != NULL; i++) { - - if (!zone_watermark_ok(z, order, z->pages_low, - classzone_idx, 0, 0)) - continue; + int do_reclaim = should_reclaim_zone(z, gfp_mask); if (!cpuset_zone_allowed(z)) continue; + /* + * If the zone is to attempt early page reclaim then this loop + * will try to reclaim pages and check the watermark a second + * time before giving up and falling back to the next zone. + */ +zone_reclaim_retry: + if (!zone_watermark_ok(z, order, z->pages_low, + classzone_idx, 0, 0)) { + if (!do_reclaim) + continue; + else { + zone_reclaim(z, gfp_mask, order); + /* Only try reclaim once */ + do_reclaim = 0; + goto zone_reclaim_retry; + } + } + page = buffered_rmqueue(z, order, gfp_mask); if (page) goto got_pg; diff --git a/mm/vmscan.c b/mm/vmscan.c index 6379ddbffd9b..7da846960d8a 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1323,3 +1323,67 @@ static int __init kswapd_init(void) } module_init(kswapd_init) + + +/* + * Try to free up some pages from this zone through reclaim. + */ +int zone_reclaim(struct zone *zone, unsigned int gfp_mask, unsigned int order) +{ + struct scan_control sc; + int nr_pages = 1 << order; + int total_reclaimed = 0; + + /* The reclaim may sleep, so don't do it if sleep isn't allowed */ + if (!(gfp_mask & __GFP_WAIT)) + return 0; + if (zone->all_unreclaimable) + return 0; + + sc.gfp_mask = gfp_mask; + sc.may_writepage = 0; + sc.may_swap = 0; + sc.nr_mapped = read_page_state(nr_mapped); + sc.nr_scanned = 0; + sc.nr_reclaimed = 0; + /* scan at the highest priority */ + sc.priority = 0; + + if (nr_pages > SWAP_CLUSTER_MAX) + sc.swap_cluster_max = nr_pages; + else + sc.swap_cluster_max = SWAP_CLUSTER_MAX; + + shrink_zone(zone, &sc); + total_reclaimed = sc.nr_reclaimed; + + return total_reclaimed; +} + +asmlinkage long sys_set_zone_reclaim(unsigned int node, unsigned int zone, + unsigned int state) +{ + struct zone *z; + int i; + + if (node >= MAX_NUMNODES || !node_online(node)) + return -EINVAL; + + /* This will break if we ever add more zones */ + if (!(zone & (1<node_zones[i]; + + if (state) + z->reclaim_pages = 1; + else + z->reclaim_pages = 0; + } + + return 0; +} -- cgit v1.2.3-59-g8ed1b From 0c35bbadc59f5ed105c34471143eceb4c0dd9c95 Mon Sep 17 00:00:00 2001 From: Martin Hicks Date: Tue, 21 Jun 2005 17:14:42 -0700 Subject: [PATCH] VM: add __GFP_NORECLAIM When using the early zone reclaim, it was noticed that allocating new pages that should be spread across the whole system caused eviction of local pages. This adds a new GFP flag to prevent early reclaim from happening during certain allocation attempts. The example that is implemented here is for page cache pages. We want page cache pages to be spread across the whole system, and we don't want page cache pages to evict other pages to get local memory. Signed-off-by: Martin Hicks Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/gfp.h | 3 ++- include/linux/pagemap.h | 4 ++-- mm/page_alloc.c | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/linux/gfp.h b/include/linux/gfp.h index af7407e8cfc5..208535fd4832 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -39,6 +39,7 @@ struct vm_area_struct; #define __GFP_COMP 0x4000u /* Add compound page metadata */ #define __GFP_ZERO 0x8000u /* Return zeroed page on success */ #define __GFP_NOMEMALLOC 0x10000u /* Don't use emergency reserves */ +#define __GFP_NORECLAIM 0x20000u /* No realy zone reclaim during allocation */ #define __GFP_BITS_SHIFT 20 /* Room for 20 __GFP_FOO bits */ #define __GFP_BITS_MASK ((1 << __GFP_BITS_SHIFT) - 1) @@ -47,7 +48,7 @@ struct vm_area_struct; #define GFP_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS| \ __GFP_COLD|__GFP_NOWARN|__GFP_REPEAT| \ __GFP_NOFAIL|__GFP_NORETRY|__GFP_NO_GROW|__GFP_COMP| \ - __GFP_NOMEMALLOC) + __GFP_NOMEMALLOC|__GFP_NORECLAIM) #define GFP_ATOMIC (__GFP_HIGH) #define GFP_NOIO (__GFP_WAIT) diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 0422031161ba..d9a25647a295 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -52,12 +52,12 @@ void release_pages(struct page **pages, int nr, int cold); static inline struct page *page_cache_alloc(struct address_space *x) { - return alloc_pages(mapping_gfp_mask(x), 0); + return alloc_pages(mapping_gfp_mask(x)|__GFP_NORECLAIM, 0); } static inline struct page *page_cache_alloc_cold(struct address_space *x) { - return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD, 0); + return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD|__GFP_NORECLAIM, 0); } typedef int filler_t(void *, struct page *); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 3c0f69ded6b5..a9da20bc2ed0 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -729,6 +729,8 @@ should_reclaim_zone(struct zone *z, unsigned int gfp_mask) { if (!z->reclaim_pages) return 0; + if (gfp_mask & __GFP_NORECLAIM) + return 0; return 1; } -- cgit v1.2.3-59-g8ed1b From 1e7e5a9048b30c57ba1ddaa6cdf59b21b65cde99 Mon Sep 17 00:00:00 2001 From: Martin Hicks Date: Tue, 21 Jun 2005 17:14:43 -0700 Subject: [PATCH] VM: rate limit early reclaim When early zone reclaim is turned on the LRU is scanned more frequently when a zone is low on memory. This limits when the zone reclaim can be called by skipping the scan if another thread (either via kswapd or sync reclaim) is already reclaiming from the zone. Signed-off-by: Martin Hicks Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 2 ++ mm/page_alloc.c | 1 + mm/vmscan.c | 10 ++++++++++ 3 files changed, 13 insertions(+) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index dfc2452ccb10..18fed8b67943 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -149,6 +149,8 @@ struct zone { * as it fails a watermark_ok() in __alloc_pages? */ int reclaim_pages; + /* A count of how many reclaimers are scanning this zone */ + atomic_t reclaim_in_progress; /* * prev_priority holds the scanning priority for this zone. It is diff --git a/mm/page_alloc.c b/mm/page_alloc.c index a9da20bc2ed0..2019c1b19254 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1738,6 +1738,7 @@ static void __init free_area_init_core(struct pglist_data *pgdat, zone->nr_scan_inactive = 0; zone->nr_active = 0; zone->nr_inactive = 0; + atomic_set(&zone->reclaim_in_progress, -1); if (!size) continue; diff --git a/mm/vmscan.c b/mm/vmscan.c index 7da846960d8a..24da725a30f0 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -900,7 +900,9 @@ shrink_caches(struct zone **zones, struct scan_control *sc) if (zone->all_unreclaimable && sc->priority != DEF_PRIORITY) continue; /* Let kswapd poll it */ + atomic_inc(&zone->reclaim_in_progress); shrink_zone(zone, sc); + atomic_dec(&zone->reclaim_in_progress); } } @@ -1111,7 +1113,9 @@ scan: sc.nr_reclaimed = 0; sc.priority = priority; sc.swap_cluster_max = nr_pages? nr_pages : SWAP_CLUSTER_MAX; + atomic_inc(&zone->reclaim_in_progress); shrink_zone(zone, &sc); + atomic_dec(&zone->reclaim_in_progress); reclaim_state->reclaimed_slab = 0; nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL, lru_pages); @@ -1354,9 +1358,15 @@ int zone_reclaim(struct zone *zone, unsigned int gfp_mask, unsigned int order) else sc.swap_cluster_max = SWAP_CLUSTER_MAX; + /* Don't reclaim the zone if there are other reclaimers active */ + if (!atomic_inc_and_test(&zone->reclaim_in_progress)) + goto out; + shrink_zone(zone, &sc); total_reclaimed = sc.nr_reclaimed; + out: + atomic_dec(&zone->reclaim_in_progress); return total_reclaimed; } -- cgit v1.2.3-59-g8ed1b From 63551ae0feaaa23807ebea60de1901564bbef32e Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 21 Jun 2005 17:14:44 -0700 Subject: [PATCH] Hugepage consolidation A lot of the code in arch/*/mm/hugetlbpage.c is quite similar. This patch attempts to consolidate a lot of the code across the arch's, putting the combined version in mm/hugetlb.c. There are a couple of uglyish hacks in order to covert all the hugepage archs, but the result is a very large reduction in the total amount of code. It also means things like hugepage lazy allocation could be implemented in one place, instead of six. Tested, at least a little, on ppc64, i386 and x86_64. Notes: - this patch changes the meaning of set_huge_pte() to be more analagous to set_pte() - does SH4 need s special huge_ptep_get_and_clear()?? Acked-by: William Lee Irwin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/mm/hugetlbpage.c | 170 ++---------------------------------- arch/ia64/mm/hugetlbpage.c | 158 +--------------------------------- arch/ppc64/mm/hugetlbpage.c | 180 +------------------------------------- arch/sh/mm/hugetlbpage.c | 196 ++++++------------------------------------ arch/sh64/mm/hugetlbpage.c | 18 +++- arch/sparc64/mm/hugetlbpage.c | 195 ++++++----------------------------------- include/asm-i386/page.h | 1 + include/asm-i386/pgtable.h | 2 +- include/asm-ia64/pgtable.h | 1 + include/asm-sh/page.h | 1 + include/asm-sh/pgtable.h | 1 + include/asm-sh64/page.h | 1 + include/asm-sh64/pgtable.h | 2 + include/asm-sparc64/page.h | 2 + include/asm-sparc64/pgtable.h | 1 + include/asm-x86_64/page.h | 1 + include/asm-x86_64/pgtable.h | 3 +- include/linux/hugetlb.h | 40 +++++++-- mm/hugetlb.c | 177 +++++++++++++++++++++++++++++++++++++- 19 files changed, 300 insertions(+), 850 deletions(-) diff --git a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c index 171fc925e1e4..5aa06001a4bd 100644 --- a/arch/i386/mm/hugetlbpage.c +++ b/arch/i386/mm/hugetlbpage.c @@ -18,7 +18,7 @@ #include #include -static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) +pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) { pgd_t *pgd; pud_t *pud; @@ -30,7 +30,7 @@ static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) return (pte_t *) pmd; } -static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) +pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) { pgd_t *pgd; pud_t *pud; @@ -42,21 +42,6 @@ static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) return (pte_t *) pmd; } -static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, struct page *page, pte_t * page_table, int write_access) -{ - pte_t entry; - - add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE); - if (write_access) { - entry = - pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot))); - } else - entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot)); - entry = pte_mkyoung(entry); - mk_pte_huge(entry); - set_pte(page_table, entry); -} - /* * This function checks for proper alignment of input addr and len parameters. */ @@ -69,77 +54,6 @@ int is_aligned_hugepage_range(unsigned long addr, unsigned long len) return 0; } -int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, - struct vm_area_struct *vma) -{ - pte_t *src_pte, *dst_pte, entry; - struct page *ptepage; - unsigned long addr = vma->vm_start; - unsigned long end = vma->vm_end; - - while (addr < end) { - dst_pte = huge_pte_alloc(dst, addr); - if (!dst_pte) - goto nomem; - src_pte = huge_pte_offset(src, addr); - entry = *src_pte; - ptepage = pte_page(entry); - get_page(ptepage); - set_pte(dst_pte, entry); - add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE); - addr += HPAGE_SIZE; - } - return 0; - -nomem: - return -ENOMEM; -} - -int -follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, - struct page **pages, struct vm_area_struct **vmas, - unsigned long *position, int *length, int i) -{ - unsigned long vpfn, vaddr = *position; - int remainder = *length; - - WARN_ON(!is_vm_hugetlb_page(vma)); - - vpfn = vaddr/PAGE_SIZE; - while (vaddr < vma->vm_end && remainder) { - - if (pages) { - pte_t *pte; - struct page *page; - - pte = huge_pte_offset(mm, vaddr); - - /* hugetlb should be locked, and hence, prefaulted */ - WARN_ON(!pte || pte_none(*pte)); - - page = &pte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)]; - - WARN_ON(!PageCompound(page)); - - get_page(page); - pages[i] = page; - } - - if (vmas) - vmas[i] = vma; - - vaddr += PAGE_SIZE; - ++vpfn; - --remainder; - ++i; - } - - *length = remainder; - *position = vaddr; - - return i; -} - #if 0 /* This is just for testing */ struct page * follow_huge_addr(struct mm_struct *mm, unsigned long address, int write) @@ -204,83 +118,15 @@ follow_huge_pmd(struct mm_struct *mm, unsigned long address, } #endif -void unmap_hugepage_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) +void hugetlb_clean_stale_pgtable(pte_t *pte) { - struct mm_struct *mm = vma->vm_mm; - unsigned long address; - pte_t pte, *ptep; + pmd_t *pmd = (pmd_t *) pte; struct page *page; - BUG_ON(start & (HPAGE_SIZE - 1)); - BUG_ON(end & (HPAGE_SIZE - 1)); - - for (address = start; address < end; address += HPAGE_SIZE) { - ptep = huge_pte_offset(mm, address); - if (!ptep) - continue; - pte = ptep_get_and_clear(mm, address, ptep); - if (pte_none(pte)) - continue; - page = pte_page(pte); - put_page(page); - } - add_mm_counter(mm ,rss, -((end - start) >> PAGE_SHIFT)); - flush_tlb_range(vma, start, end); -} - -int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma) -{ - struct mm_struct *mm = current->mm; - unsigned long addr; - int ret = 0; - - BUG_ON(vma->vm_start & ~HPAGE_MASK); - BUG_ON(vma->vm_end & ~HPAGE_MASK); - - spin_lock(&mm->page_table_lock); - for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) { - unsigned long idx; - pte_t *pte = huge_pte_alloc(mm, addr); - struct page *page; - - if (!pte) { - ret = -ENOMEM; - goto out; - } - - if (!pte_none(*pte)) - continue; - - idx = ((addr - vma->vm_start) >> HPAGE_SHIFT) - + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT)); - page = find_get_page(mapping, idx); - if (!page) { - /* charge the fs quota first */ - if (hugetlb_get_quota(mapping)) { - ret = -ENOMEM; - goto out; - } - page = alloc_huge_page(); - if (!page) { - hugetlb_put_quota(mapping); - ret = -ENOMEM; - goto out; - } - ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC); - if (! ret) { - unlock_page(page); - } else { - hugetlb_put_quota(mapping); - free_huge_page(page); - goto out; - } - } - set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE); - } -out: - spin_unlock(&mm->page_table_lock); - return ret; + page = pmd_page(*pmd); + pmd_clear(pmd); + dec_page_state(nr_page_table_pages); + page_cache_release(page); } /* x86_64 also uses this file */ diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c index df08ae7634b6..e0a776a3044c 100644 --- a/arch/ia64/mm/hugetlbpage.c +++ b/arch/ia64/mm/hugetlbpage.c @@ -24,7 +24,7 @@ unsigned int hpage_shift=HPAGE_SHIFT_DEFAULT; -static pte_t * +pte_t * huge_pte_alloc (struct mm_struct *mm, unsigned long addr) { unsigned long taddr = htlbpage_to_page(addr); @@ -43,7 +43,7 @@ huge_pte_alloc (struct mm_struct *mm, unsigned long addr) return pte; } -static pte_t * +pte_t * huge_pte_offset (struct mm_struct *mm, unsigned long addr) { unsigned long taddr = htlbpage_to_page(addr); @@ -67,23 +67,6 @@ huge_pte_offset (struct mm_struct *mm, unsigned long addr) #define mk_pte_huge(entry) { pte_val(entry) |= _PAGE_P; } -static void -set_huge_pte (struct mm_struct *mm, struct vm_area_struct *vma, - struct page *page, pte_t * page_table, int write_access) -{ - pte_t entry; - - add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE); - if (write_access) { - entry = - pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot))); - } else - entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot)); - entry = pte_mkyoung(entry); - mk_pte_huge(entry); - set_pte(page_table, entry); - return; -} /* * This function checks for proper alignment of input addr and len parameters. */ @@ -99,68 +82,6 @@ int is_aligned_hugepage_range(unsigned long addr, unsigned long len) return 0; } -int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, - struct vm_area_struct *vma) -{ - pte_t *src_pte, *dst_pte, entry; - struct page *ptepage; - unsigned long addr = vma->vm_start; - unsigned long end = vma->vm_end; - - while (addr < end) { - dst_pte = huge_pte_alloc(dst, addr); - if (!dst_pte) - goto nomem; - src_pte = huge_pte_offset(src, addr); - entry = *src_pte; - ptepage = pte_page(entry); - get_page(ptepage); - set_pte(dst_pte, entry); - add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE); - addr += HPAGE_SIZE; - } - return 0; -nomem: - return -ENOMEM; -} - -int -follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, - struct page **pages, struct vm_area_struct **vmas, - unsigned long *st, int *length, int i) -{ - pte_t *ptep, pte; - unsigned long start = *st; - unsigned long pstart; - int len = *length; - struct page *page; - - do { - pstart = start & HPAGE_MASK; - ptep = huge_pte_offset(mm, start); - pte = *ptep; - -back1: - page = pte_page(pte); - if (pages) { - page += ((start & ~HPAGE_MASK) >> PAGE_SHIFT); - get_page(page); - pages[i] = page; - } - if (vmas) - vmas[i] = vma; - i++; - len--; - start += PAGE_SIZE; - if (((start & HPAGE_MASK) == pstart) && len && - (start < vma->vm_end)) - goto back1; - } while (len && start < vma->vm_end); - *length = len; - *st = start; - return i; -} - struct page *follow_huge_addr(struct mm_struct *mm, unsigned long addr, int write) { struct page *page; @@ -212,81 +133,6 @@ void hugetlb_free_pgd_range(struct mmu_gather **tlb, free_pgd_range(tlb, addr, end, floor, ceiling); } -void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long address; - pte_t *pte; - struct page *page; - - BUG_ON(start & (HPAGE_SIZE - 1)); - BUG_ON(end & (HPAGE_SIZE - 1)); - - for (address = start; address < end; address += HPAGE_SIZE) { - pte = huge_pte_offset(mm, address); - if (pte_none(*pte)) - continue; - page = pte_page(*pte); - put_page(page); - pte_clear(mm, address, pte); - } - add_mm_counter(mm, rss, - ((end - start) >> PAGE_SHIFT)); - flush_tlb_range(vma, start, end); -} - -int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma) -{ - struct mm_struct *mm = current->mm; - unsigned long addr; - int ret = 0; - - BUG_ON(vma->vm_start & ~HPAGE_MASK); - BUG_ON(vma->vm_end & ~HPAGE_MASK); - - spin_lock(&mm->page_table_lock); - for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) { - unsigned long idx; - pte_t *pte = huge_pte_alloc(mm, addr); - struct page *page; - - if (!pte) { - ret = -ENOMEM; - goto out; - } - if (!pte_none(*pte)) - continue; - - idx = ((addr - vma->vm_start) >> HPAGE_SHIFT) - + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT)); - page = find_get_page(mapping, idx); - if (!page) { - /* charge the fs quota first */ - if (hugetlb_get_quota(mapping)) { - ret = -ENOMEM; - goto out; - } - page = alloc_huge_page(); - if (!page) { - hugetlb_put_quota(mapping); - ret = -ENOMEM; - goto out; - } - ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC); - if (! ret) { - unlock_page(page); - } else { - hugetlb_put_quota(mapping); - page_cache_release(page); - goto out; - } - } - set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE); - } -out: - spin_unlock(&mm->page_table_lock); - return ret; -} - unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) { diff --git a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c index d3bf86a5c1ad..b4ab766f5980 100644 --- a/arch/ppc64/mm/hugetlbpage.c +++ b/arch/ppc64/mm/hugetlbpage.c @@ -121,7 +121,7 @@ static pte_t *hugepte_alloc(struct mm_struct *mm, pud_t *dir, unsigned long addr return hugepte_offset(dir, addr); } -static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) +pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) { pud_t *pud; @@ -134,7 +134,7 @@ static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) return hugepte_offset(pud, addr); } -static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) +pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) { pud_t *pud; @@ -147,25 +147,6 @@ static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) return hugepte_alloc(mm, pud, addr); } -static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long addr, struct page *page, - pte_t *ptep, int write_access) -{ - pte_t entry; - - add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE); - if (write_access) { - entry = - pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot))); - } else { - entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot)); - } - entry = pte_mkyoung(entry); - entry = pte_mkhuge(entry); - - set_pte_at(mm, addr, ptep, entry); -} - /* * This function checks for proper alignment of input addr and len parameters. */ @@ -259,80 +240,6 @@ int prepare_hugepage_range(unsigned long addr, unsigned long len) return -EINVAL; } -int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, - struct vm_area_struct *vma) -{ - pte_t *src_pte, *dst_pte, entry; - struct page *ptepage; - unsigned long addr = vma->vm_start; - unsigned long end = vma->vm_end; - int err = -ENOMEM; - - while (addr < end) { - dst_pte = huge_pte_alloc(dst, addr); - if (!dst_pte) - goto out; - - src_pte = huge_pte_offset(src, addr); - entry = *src_pte; - - ptepage = pte_page(entry); - get_page(ptepage); - add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE); - set_pte_at(dst, addr, dst_pte, entry); - - addr += HPAGE_SIZE; - } - - err = 0; - out: - return err; -} - -int -follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, - struct page **pages, struct vm_area_struct **vmas, - unsigned long *position, int *length, int i) -{ - unsigned long vpfn, vaddr = *position; - int remainder = *length; - - WARN_ON(!is_vm_hugetlb_page(vma)); - - vpfn = vaddr/PAGE_SIZE; - while (vaddr < vma->vm_end && remainder) { - if (pages) { - pte_t *pte; - struct page *page; - - pte = huge_pte_offset(mm, vaddr); - - /* hugetlb should be locked, and hence, prefaulted */ - WARN_ON(!pte || pte_none(*pte)); - - page = &pte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)]; - - WARN_ON(!PageCompound(page)); - - get_page(page); - pages[i] = page; - } - - if (vmas) - vmas[i] = vma; - - vaddr += PAGE_SIZE; - ++vpfn; - --remainder; - ++i; - } - - *length = remainder; - *position = vaddr; - - return i; -} - struct page * follow_huge_addr(struct mm_struct *mm, unsigned long address, int write) { @@ -363,89 +270,6 @@ follow_huge_pmd(struct mm_struct *mm, unsigned long address, return NULL; } -void unmap_hugepage_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long addr; - pte_t *ptep; - struct page *page; - - WARN_ON(!is_vm_hugetlb_page(vma)); - BUG_ON((start % HPAGE_SIZE) != 0); - BUG_ON((end % HPAGE_SIZE) != 0); - - for (addr = start; addr < end; addr += HPAGE_SIZE) { - pte_t pte; - - ptep = huge_pte_offset(mm, addr); - if (!ptep || pte_none(*ptep)) - continue; - - pte = *ptep; - page = pte_page(pte); - pte_clear(mm, addr, ptep); - - put_page(page); - } - add_mm_counter(mm, rss, -((end - start) >> PAGE_SHIFT)); - flush_tlb_pending(); -} - -int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma) -{ - struct mm_struct *mm = current->mm; - unsigned long addr; - int ret = 0; - - WARN_ON(!is_vm_hugetlb_page(vma)); - BUG_ON((vma->vm_start % HPAGE_SIZE) != 0); - BUG_ON((vma->vm_end % HPAGE_SIZE) != 0); - - spin_lock(&mm->page_table_lock); - for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) { - unsigned long idx; - pte_t *pte = huge_pte_alloc(mm, addr); - struct page *page; - - if (!pte) { - ret = -ENOMEM; - goto out; - } - if (! pte_none(*pte)) - continue; - - idx = ((addr - vma->vm_start) >> HPAGE_SHIFT) - + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT)); - page = find_get_page(mapping, idx); - if (!page) { - /* charge the fs quota first */ - if (hugetlb_get_quota(mapping)) { - ret = -ENOMEM; - goto out; - } - page = alloc_huge_page(); - if (!page) { - hugetlb_put_quota(mapping); - ret = -ENOMEM; - goto out; - } - ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC); - if (! ret) { - unlock_page(page); - } else { - hugetlb_put_quota(mapping); - free_huge_page(page); - goto out; - } - } - set_huge_pte(mm, vma, addr, page, pte, vma->vm_flags & VM_WRITE); - } -out: - spin_unlock(&mm->page_table_lock); - return ret; -} - /* Because we have an exclusive hugepage region which lies within the * normal user address space, we have to take special measures to make * non-huge mmap()s evade the hugepage reserved regions. */ diff --git a/arch/sh/mm/hugetlbpage.c b/arch/sh/mm/hugetlbpage.c index 1f897bab2318..95bb1a6c6060 100644 --- a/arch/sh/mm/hugetlbpage.c +++ b/arch/sh/mm/hugetlbpage.c @@ -24,7 +24,7 @@ #include #include -static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) +pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) { pgd_t *pgd; pmd_t *pmd; @@ -39,7 +39,7 @@ static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) return pte; } -static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) +pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) { pgd_t *pgd; pmd_t *pmd; @@ -56,28 +56,34 @@ static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) #define mk_pte_huge(entry) do { pte_val(entry) |= _PAGE_SZHUGE; } while (0) -static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, - struct page *page, pte_t * page_table, int write_access) +void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t entry) { - unsigned long i; - pte_t entry; + int i; - add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE); + for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { + set_pte_at(mm, addr, ptep, entry); + ptep++; + addr += PAGE_SIZE; + pte_val(entry) += PAGE_SIZE; + } +} - if (write_access) - entry = pte_mkwrite(pte_mkdirty(mk_pte(page, - vma->vm_page_prot))); - else - entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot)); - entry = pte_mkyoung(entry); - mk_pte_huge(entry); +pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, + pte_t *ptep) +{ + pte_t entry; + int i; - for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { - set_pte(page_table, entry); - page_table++; + entry = *ptep; - pte_val(entry) += PAGE_SIZE; + for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { + pte_clear(mm, addr, ptep); + addr += PAGE_SIZE; + ptep++; } + + return entry; } /* @@ -92,79 +98,6 @@ int is_aligned_hugepage_range(unsigned long addr, unsigned long len) return 0; } -int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, - struct vm_area_struct *vma) -{ - pte_t *src_pte, *dst_pte, entry; - struct page *ptepage; - unsigned long addr = vma->vm_start; - unsigned long end = vma->vm_end; - int i; - - while (addr < end) { - dst_pte = huge_pte_alloc(dst, addr); - if (!dst_pte) - goto nomem; - src_pte = huge_pte_offset(src, addr); - BUG_ON(!src_pte || pte_none(*src_pte)); - entry = *src_pte; - ptepage = pte_page(entry); - get_page(ptepage); - for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { - set_pte(dst_pte, entry); - pte_val(entry) += PAGE_SIZE; - dst_pte++; - } - add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE); - addr += HPAGE_SIZE; - } - return 0; - -nomem: - return -ENOMEM; -} - -int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, - struct page **pages, struct vm_area_struct **vmas, - unsigned long *position, int *length, int i) -{ - unsigned long vaddr = *position; - int remainder = *length; - - WARN_ON(!is_vm_hugetlb_page(vma)); - - while (vaddr < vma->vm_end && remainder) { - if (pages) { - pte_t *pte; - struct page *page; - - pte = huge_pte_offset(mm, vaddr); - - /* hugetlb should be locked, and hence, prefaulted */ - BUG_ON(!pte || pte_none(*pte)); - - page = pte_page(*pte); - - WARN_ON(!PageCompound(page)); - - get_page(page); - pages[i] = page; - } - - if (vmas) - vmas[i] = vma; - - vaddr += PAGE_SIZE; - --remainder; - ++i; - } - - *length = remainder; - *position = vaddr; - - return i; -} - struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address, int write) { @@ -181,84 +114,3 @@ struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address, { return NULL; } - -void unmap_hugepage_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long address; - pte_t *pte; - struct page *page; - int i; - - BUG_ON(start & (HPAGE_SIZE - 1)); - BUG_ON(end & (HPAGE_SIZE - 1)); - - for (address = start; address < end; address += HPAGE_SIZE) { - pte = huge_pte_offset(mm, address); - BUG_ON(!pte); - if (pte_none(*pte)) - continue; - page = pte_page(*pte); - put_page(page); - for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { - pte_clear(mm, address+(i*PAGE_SIZE), pte); - pte++; - } - } - add_mm_counter(mm, rss, -((end - start) >> PAGE_SHIFT)); - flush_tlb_range(vma, start, end); -} - -int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma) -{ - struct mm_struct *mm = current->mm; - unsigned long addr; - int ret = 0; - - BUG_ON(vma->vm_start & ~HPAGE_MASK); - BUG_ON(vma->vm_end & ~HPAGE_MASK); - - spin_lock(&mm->page_table_lock); - for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) { - unsigned long idx; - pte_t *pte = huge_pte_alloc(mm, addr); - struct page *page; - - if (!pte) { - ret = -ENOMEM; - goto out; - } - if (!pte_none(*pte)) - continue; - - idx = ((addr - vma->vm_start) >> HPAGE_SHIFT) - + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT)); - page = find_get_page(mapping, idx); - if (!page) { - /* charge the fs quota first */ - if (hugetlb_get_quota(mapping)) { - ret = -ENOMEM; - goto out; - } - page = alloc_huge_page(); - if (!page) { - hugetlb_put_quota(mapping); - ret = -ENOMEM; - goto out; - } - ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC); - if (! ret) { - unlock_page(page); - } else { - hugetlb_put_quota(mapping); - free_huge_page(page); - goto out; - } - } - set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE); - } -out: - spin_unlock(&mm->page_table_lock); - return ret; -} diff --git a/arch/sh64/mm/hugetlbpage.c b/arch/sh64/mm/hugetlbpage.c index bcad2aefa4ee..dcd9c8a8baf8 100644 --- a/arch/sh64/mm/hugetlbpage.c +++ b/arch/sh64/mm/hugetlbpage.c @@ -24,7 +24,7 @@ #include #include -static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) +pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) { pgd_t *pgd; pmd_t *pmd; @@ -39,7 +39,7 @@ static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) return pte; } -static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) +pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) { pgd_t *pgd; pmd_t *pmd; @@ -80,6 +80,20 @@ static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, } } +pte_t huge_ptep_get_and_clear(pte_t *ptep) +{ + pte_t entry; + + entry = *ptep; + + for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { + pte_clear(pte); + pte++; + } + + return entry; +} + /* * This function checks for proper alignment of input addr and len parameters. */ diff --git a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c index 5a1f831b2de1..625cbb336a23 100644 --- a/arch/sparc64/mm/hugetlbpage.c +++ b/arch/sparc64/mm/hugetlbpage.c @@ -22,7 +22,7 @@ #include #include -static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) +pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) { pgd_t *pgd; pud_t *pud; @@ -41,7 +41,7 @@ static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) return pte; } -static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) +pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) { pgd_t *pgd; pud_t *pud; @@ -62,30 +62,34 @@ static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) #define mk_pte_huge(entry) do { pte_val(entry) |= _PAGE_SZHUGE; } while (0) -static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long addr, - struct page *page, pte_t * page_table, int write_access) +void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t entry) { - unsigned long i; - pte_t entry; + int i; + + for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { + set_pte_at(mm, addr, ptep, entry); + ptep++; + addr += PAGE_SIZE; + pte_val(entry) += PAGE_SIZE; + } +} - add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE); +pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, + pte_t *ptep) +{ + pte_t entry; + int i; - if (write_access) - entry = pte_mkwrite(pte_mkdirty(mk_pte(page, - vma->vm_page_prot))); - else - entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot)); - entry = pte_mkyoung(entry); - mk_pte_huge(entry); + entry = *ptep; for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { - set_pte_at(mm, addr, page_table, entry); - page_table++; + pte_clear(mm, addr, ptep); addr += PAGE_SIZE; - - pte_val(entry) += PAGE_SIZE; + ptep++; } + + return entry; } /* @@ -100,79 +104,6 @@ int is_aligned_hugepage_range(unsigned long addr, unsigned long len) return 0; } -int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, - struct vm_area_struct *vma) -{ - pte_t *src_pte, *dst_pte, entry; - struct page *ptepage; - unsigned long addr = vma->vm_start; - unsigned long end = vma->vm_end; - int i; - - while (addr < end) { - dst_pte = huge_pte_alloc(dst, addr); - if (!dst_pte) - goto nomem; - src_pte = huge_pte_offset(src, addr); - BUG_ON(!src_pte || pte_none(*src_pte)); - entry = *src_pte; - ptepage = pte_page(entry); - get_page(ptepage); - for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { - set_pte_at(dst, addr, dst_pte, entry); - pte_val(entry) += PAGE_SIZE; - dst_pte++; - addr += PAGE_SIZE; - } - add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE); - } - return 0; - -nomem: - return -ENOMEM; -} - -int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, - struct page **pages, struct vm_area_struct **vmas, - unsigned long *position, int *length, int i) -{ - unsigned long vaddr = *position; - int remainder = *length; - - WARN_ON(!is_vm_hugetlb_page(vma)); - - while (vaddr < vma->vm_end && remainder) { - if (pages) { - pte_t *pte; - struct page *page; - - pte = huge_pte_offset(mm, vaddr); - - /* hugetlb should be locked, and hence, prefaulted */ - BUG_ON(!pte || pte_none(*pte)); - - page = pte_page(*pte); - - WARN_ON(!PageCompound(page)); - - get_page(page); - pages[i] = page; - } - - if (vmas) - vmas[i] = vma; - - vaddr += PAGE_SIZE; - --remainder; - ++i; - } - - *length = remainder; - *position = vaddr; - - return i; -} - struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address, int write) { @@ -190,34 +121,6 @@ struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address, return NULL; } -void unmap_hugepage_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long address; - pte_t *pte; - struct page *page; - int i; - - BUG_ON(start & (HPAGE_SIZE - 1)); - BUG_ON(end & (HPAGE_SIZE - 1)); - - for (address = start; address < end; address += HPAGE_SIZE) { - pte = huge_pte_offset(mm, address); - BUG_ON(!pte); - if (pte_none(*pte)) - continue; - page = pte_page(*pte); - put_page(page); - for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { - pte_clear(mm, address+(i*PAGE_SIZE), pte); - pte++; - } - } - add_mm_counter(mm, rss, -((end - start) >> PAGE_SHIFT)); - flush_tlb_range(vma, start, end); -} - static void context_reload(void *__data) { struct mm_struct *mm = __data; @@ -226,12 +129,8 @@ static void context_reload(void *__data) load_secondary_context(mm); } -int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma) +void hugetlb_prefault_arch_hook(struct mm_struct *mm) { - struct mm_struct *mm = current->mm; - unsigned long addr; - int ret = 0; - /* On UltraSPARC-III+ and later, configure the second half of * the Data-TLB for huge pages. */ @@ -261,50 +160,4 @@ int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma) } spin_unlock(&ctx_alloc_lock); } - - BUG_ON(vma->vm_start & ~HPAGE_MASK); - BUG_ON(vma->vm_end & ~HPAGE_MASK); - - spin_lock(&mm->page_table_lock); - for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) { - unsigned long idx; - pte_t *pte = huge_pte_alloc(mm, addr); - struct page *page; - - if (!pte) { - ret = -ENOMEM; - goto out; - } - if (!pte_none(*pte)) - continue; - - idx = ((addr - vma->vm_start) >> HPAGE_SHIFT) - + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT)); - page = find_get_page(mapping, idx); - if (!page) { - /* charge the fs quota first */ - if (hugetlb_get_quota(mapping)) { - ret = -ENOMEM; - goto out; - } - page = alloc_huge_page(); - if (!page) { - hugetlb_put_quota(mapping); - ret = -ENOMEM; - goto out; - } - ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC); - if (! ret) { - unlock_page(page); - } else { - hugetlb_put_quota(mapping); - free_huge_page(page); - goto out; - } - } - set_huge_pte(mm, vma, addr, page, pte, vma->vm_flags & VM_WRITE); - } -out: - spin_unlock(&mm->page_table_lock); - return ret; } diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h index ed13969fa2d6..41400d342d44 100644 --- a/include/asm-i386/page.h +++ b/include/asm-i386/page.h @@ -68,6 +68,7 @@ typedef struct { unsigned long pgprot; } pgprot_t; #define HPAGE_MASK (~(HPAGE_SIZE - 1)) #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA +#define ARCH_HAS_HUGETLB_CLEAN_STALE_PGTABLE #endif #define pgd_val(x) ((x).pgd) diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index 8d60c2b4b003..e9efe148fdf7 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h @@ -236,6 +236,7 @@ static inline pte_t pte_mkexec(pte_t pte) { (pte).pte_low |= _PAGE_USER; return static inline pte_t pte_mkdirty(pte_t pte) { (pte).pte_low |= _PAGE_DIRTY; return pte; } static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte_low |= _PAGE_ACCESSED; return pte; } static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte_low |= _PAGE_RW; return pte; } +static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PRESENT | _PAGE_PSE; return pte; } #ifdef CONFIG_X86_PAE # include @@ -275,7 +276,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, */ #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) -#define mk_pte_huge(entry) ((entry).pte_low |= _PAGE_PRESENT | _PAGE_PSE) static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h index fcc9c3344ab4..48586e08f432 100644 --- a/include/asm-ia64/pgtable.h +++ b/include/asm-ia64/pgtable.h @@ -283,6 +283,7 @@ ia64_phys_addr_valid (unsigned long addr) #define pte_mkyoung(pte) (__pte(pte_val(pte) | _PAGE_A)) #define pte_mkclean(pte) (__pte(pte_val(pte) & ~_PAGE_D)) #define pte_mkdirty(pte) (__pte(pte_val(pte) | _PAGE_D)) +#define pte_mkhuge(pte) (__pte(pte_val(pte) | _PAGE_P)) /* * Macro to a page protection value as "uncacheable". Note that "protection" is really a diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h index 4c6d129e7d91..180467be8e7b 100644 --- a/include/asm-sh/page.h +++ b/include/asm-sh/page.h @@ -31,6 +31,7 @@ #define HPAGE_SIZE (1UL << HPAGE_SHIFT) #define HPAGE_MASK (~(HPAGE_SIZE-1)) #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT-PAGE_SHIFT) +#define ARCH_HAS_SETCLEAR_HUGE_PTE #endif #ifdef __KERNEL__ diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h index cd847a47a9aa..ecb909572d3f 100644 --- a/include/asm-sh/pgtable.h +++ b/include/asm-sh/pgtable.h @@ -196,6 +196,7 @@ static inline pte_t pte_mkexec(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _ static inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; } static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; } static inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; } +static inline pte_t pte_mkhuge(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_SZHUGE)); return pte; } /* * Macro and implementation to make a page protection as uncachable. diff --git a/include/asm-sh64/page.h b/include/asm-sh64/page.h index e1f7f5a41210..d6167f1c0e99 100644 --- a/include/asm-sh64/page.h +++ b/include/asm-sh64/page.h @@ -41,6 +41,7 @@ #define HPAGE_SIZE (1UL << HPAGE_SHIFT) #define HPAGE_MASK (~(HPAGE_SIZE-1)) #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT-PAGE_SHIFT) +#define ARCH_HAS_SETCLEAR_HUGE_PTE #endif #ifdef __KERNEL__ diff --git a/include/asm-sh64/pgtable.h b/include/asm-sh64/pgtable.h index 525e1523ef5f..78ac6be2d9ef 100644 --- a/include/asm-sh64/pgtable.h +++ b/include/asm-sh64/pgtable.h @@ -430,6 +430,8 @@ extern inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | extern inline pte_t pte_mkexec(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_EXECUTE)); return pte; } extern inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; } extern inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; } +extern inline pte_t pte_mkhuge(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_SZHUGE)); return pte; } + /* * Conversion functions: convert a page and protection to a page entry. diff --git a/include/asm-sparc64/page.h b/include/asm-sparc64/page.h index 219ea043a14a..b87dbbd64bc9 100644 --- a/include/asm-sparc64/page.h +++ b/include/asm-sparc64/page.h @@ -95,6 +95,8 @@ typedef unsigned long pgprot_t; #define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT) #define HPAGE_MASK (~(HPAGE_SIZE - 1UL)) #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) +#define ARCH_HAS_SETCLEAR_HUGE_PTE +#define ARCH_HAS_HUGETLB_PREFAULT_HOOK #endif #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_32BIT) ? \ diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index ae2cd5b09a7c..1ae00c5087f1 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -286,6 +286,7 @@ static inline pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot) #define pte_mkyoung(pte) (__pte(pte_val(pte) | _PAGE_ACCESSED | _PAGE_R)) #define pte_mkwrite(pte) (__pte(pte_val(pte) | _PAGE_WRITE)) #define pte_mkdirty(pte) (__pte(pte_val(pte) | _PAGE_MODIFIED | _PAGE_W)) +#define pte_mkhuge(pte) (__pte(pte_val(pte) | _PAGE_SZHUGE)) /* to find an entry in a page-table-directory. */ #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) diff --git a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h index f43048035a03..9ce338c3a71e 100644 --- a/include/asm-x86_64/page.h +++ b/include/asm-x86_64/page.h @@ -28,6 +28,7 @@ #define HPAGE_SIZE ((1UL) << HPAGE_SHIFT) #define HPAGE_MASK (~(HPAGE_SIZE - 1)) #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) +#define ARCH_HAS_HUGETLB_CLEAN_STALE_PGTABLE #ifdef __KERNEL__ #ifndef __ASSEMBLY__ diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h index db2a0efbf573..4eec176c3c39 100644 --- a/include/asm-x86_64/pgtable.h +++ b/include/asm-x86_64/pgtable.h @@ -253,6 +253,7 @@ extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } +#define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT) extern inline pte_t pte_rdprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; } extern inline pte_t pte_exprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; } extern inline pte_t pte_mkclean(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; } @@ -263,6 +264,7 @@ extern inline pte_t pte_mkexec(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _ extern inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; } extern inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; } extern inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; } +extern inline pte_t pte_mkhuge(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | __LARGE_PTE)); return pte; } struct vm_area_struct; @@ -290,7 +292,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, */ #define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_PCD | _PAGE_PWT)) -#define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT) static inline int pmd_large(pmd_t pte) { return (pmd_val(pte) & __LARGE_PTE) == __LARGE_PTE; } diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 6af1ae4a8211..f529d1442815 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -4,6 +4,7 @@ #ifdef CONFIG_HUGETLB_PAGE #include +#include struct ctl_table; @@ -22,12 +23,6 @@ int hugetlb_report_meminfo(char *); int hugetlb_report_node_meminfo(int, char *); int is_hugepage_mem_enough(size_t); unsigned long hugetlb_total_pages(void); -struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address, - int write); -struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address, - pmd_t *pmd, int write); -int is_aligned_hugepage_range(unsigned long addr, unsigned long len); -int pmd_huge(pmd_t pmd); struct page *alloc_huge_page(void); void free_huge_page(struct page *); @@ -35,6 +30,17 @@ extern unsigned long max_huge_pages; extern const unsigned long hugetlb_zero, hugetlb_infinity; extern int sysctl_hugetlb_shm_group; +/* arch callbacks */ + +pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr); +pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr); +struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address, + int write); +struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address, + pmd_t *pmd, int write); +int is_aligned_hugepage_range(unsigned long addr, unsigned long len); +int pmd_huge(pmd_t pmd); + #ifndef ARCH_HAS_HUGEPAGE_ONLY_RANGE #define is_hugepage_only_range(mm, addr, len) 0 #define hugetlb_free_pgd_range(tlb, addr, end, floor, ceiling) \ @@ -48,6 +54,28 @@ extern int sysctl_hugetlb_shm_group; int prepare_hugepage_range(unsigned long addr, unsigned long len); #endif +#ifndef ARCH_HAS_SETCLEAR_HUGE_PTE +#define set_huge_pte_at(mm, addr, ptep, pte) set_pte_at(mm, addr, ptep, pte) +#define huge_ptep_get_and_clear(mm, addr, ptep) ptep_get_and_clear(mm, addr, ptep) +#else +void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte); +pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, + pte_t *ptep); +#endif + +#ifndef ARCH_HAS_HUGETLB_PREFAULT_HOOK +#define hugetlb_prefault_arch_hook(mm) do { } while (0) +#else +void hugetlb_prefault_arch_hook(struct mm_struct *mm); +#endif + +#ifndef ARCH_HAS_HUGETLB_CLEAN_STALE_PGTABLE +#define hugetlb_clean_stale_pgtable(pte) BUG() +#else +void hugetlb_clean_stale_pgtable(pte_t *pte); +#endif + #else /* !CONFIG_HUGETLB_PAGE */ static inline int is_vm_hugetlb_page(struct vm_area_struct *vma) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 4eb5ae3fbe10..fbd1111ea119 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -7,10 +7,14 @@ #include #include #include -#include #include #include #include +#include +#include +#include + +#include const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL; static unsigned long nr_huge_pages, free_huge_pages; @@ -249,6 +253,72 @@ struct vm_operations_struct hugetlb_vm_ops = { .nopage = hugetlb_nopage, }; +static pte_t make_huge_pte(struct vm_area_struct *vma, struct page *page) +{ + pte_t entry; + + if (vma->vm_flags & VM_WRITE) { + entry = + pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot))); + } else { + entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot)); + } + entry = pte_mkyoung(entry); + entry = pte_mkhuge(entry); + + return entry; +} + +int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, + struct vm_area_struct *vma) +{ + pte_t *src_pte, *dst_pte, entry; + struct page *ptepage; + unsigned long addr = vma->vm_start; + unsigned long end = vma->vm_end; + + while (addr < end) { + dst_pte = huge_pte_alloc(dst, addr); + if (!dst_pte) + goto nomem; + src_pte = huge_pte_offset(src, addr); + BUG_ON(!src_pte || pte_none(*src_pte)); /* prefaulted */ + entry = *src_pte; + ptepage = pte_page(entry); + get_page(ptepage); + add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE); + set_huge_pte_at(dst, addr, dst_pte, entry); + addr += HPAGE_SIZE; + } + return 0; + +nomem: + return -ENOMEM; +} + +void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + unsigned long address; + pte_t pte; + struct page *page; + + WARN_ON(!is_vm_hugetlb_page(vma)); + BUG_ON(start & ~HPAGE_MASK); + BUG_ON(end & ~HPAGE_MASK); + + for (address = start; address < end; address += HPAGE_SIZE) { + pte = huge_ptep_get_and_clear(mm, address, huge_pte_offset(mm, address)); + if (pte_none(pte)) + continue; + page = pte_page(pte); + put_page(page); + } + add_mm_counter(mm, rss, -((end - start) >> PAGE_SHIFT)); + flush_tlb_range(vma, start, end); +} + void zap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long length) { @@ -258,3 +328,108 @@ void zap_hugepage_range(struct vm_area_struct *vma, unmap_hugepage_range(vma, start, start + length); spin_unlock(&mm->page_table_lock); } + +int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma) +{ + struct mm_struct *mm = current->mm; + unsigned long addr; + int ret = 0; + + WARN_ON(!is_vm_hugetlb_page(vma)); + BUG_ON(vma->vm_start & ~HPAGE_MASK); + BUG_ON(vma->vm_end & ~HPAGE_MASK); + + hugetlb_prefault_arch_hook(mm); + + spin_lock(&mm->page_table_lock); + for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) { + unsigned long idx; + pte_t *pte = huge_pte_alloc(mm, addr); + struct page *page; + + if (!pte) { + ret = -ENOMEM; + goto out; + } + if (! pte_none(*pte)) + hugetlb_clean_stale_pgtable(pte); + + idx = ((addr - vma->vm_start) >> HPAGE_SHIFT) + + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT)); + page = find_get_page(mapping, idx); + if (!page) { + /* charge the fs quota first */ + if (hugetlb_get_quota(mapping)) { + ret = -ENOMEM; + goto out; + } + page = alloc_huge_page(); + if (!page) { + hugetlb_put_quota(mapping); + ret = -ENOMEM; + goto out; + } + ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC); + if (! ret) { + unlock_page(page); + } else { + hugetlb_put_quota(mapping); + free_huge_page(page); + goto out; + } + } + add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE); + set_huge_pte_at(mm, addr, pte, make_huge_pte(vma, page)); + } +out: + spin_unlock(&mm->page_table_lock); + return ret; +} + +int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, + struct page **pages, struct vm_area_struct **vmas, + unsigned long *position, int *length, int i) +{ + unsigned long vpfn, vaddr = *position; + int remainder = *length; + + BUG_ON(!is_vm_hugetlb_page(vma)); + + vpfn = vaddr/PAGE_SIZE; + while (vaddr < vma->vm_end && remainder) { + + if (pages) { + pte_t *pte; + struct page *page; + + /* Some archs (sparc64, sh*) have multiple + * pte_ts to each hugepage. We have to make + * sure we get the first, for the page + * indexing below to work. */ + pte = huge_pte_offset(mm, vaddr & HPAGE_MASK); + + /* hugetlb should be locked, and hence, prefaulted */ + WARN_ON(!pte || pte_none(*pte)); + + page = &pte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)]; + + WARN_ON(!PageCompound(page)); + + get_page(page); + pages[i] = page; + } + + if (vmas) + vmas[i] = vma; + + vaddr += PAGE_SIZE; + ++vpfn; + --remainder; + ++i; + } + + *length = remainder; + *position = vaddr; + + return i; +} -- cgit v1.2.3-59-g8ed1b From e7c8d5c9955a4d2e88e36b640563f5d6d5aba48a Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Tue, 21 Jun 2005 17:14:47 -0700 Subject: [PATCH] node local per-cpu-pages This patch modifies the way pagesets in struct zone are managed. Each zone has a per-cpu array of pagesets. So any particular CPU has some memory in each zone structure which belongs to itself. Even if that CPU is not local to that zone. So the patch relocates the pagesets for each cpu to the node that is nearest to the cpu instead of allocating the pagesets in the (possibly remote) target zone. This means that the operations to manage pages on remote zone can be done with information available locally. We play a macro trick so that non-NUMA pmachines avoid the additional pointer chase on the page allocator fastpath. AIM7 benchmark on a 32 CPU SGI Altix w/o patches: Tasks jobs/min jti jobs/min/task real cpu 1 484.68 100 484.6769 12.01 1.97 Fri Mar 25 11:01:42 2005 100 27140.46 89 271.4046 21.44 148.71 Fri Mar 25 11:02:04 2005 200 30792.02 82 153.9601 37.80 296.72 Fri Mar 25 11:02:42 2005 300 32209.27 81 107.3642 54.21 451.34 Fri Mar 25 11:03:37 2005 400 34962.83 78 87.4071 66.59 588.97 Fri Mar 25 11:04:44 2005 500 31676.92 75 63.3538 91.87 742.71 Fri Mar 25 11:06:16 2005 600 36032.69 73 60.0545 96.91 885.44 Fri Mar 25 11:07:54 2005 700 35540.43 77 50.7720 114.63 1024.28 Fri Mar 25 11:09:49 2005 800 33906.70 74 42.3834 137.32 1181.65 Fri Mar 25 11:12:06 2005 900 34120.67 73 37.9119 153.51 1325.26 Fri Mar 25 11:14:41 2005 1000 34802.37 74 34.8024 167.23 1465.26 Fri Mar 25 11:17:28 2005 with slab API changes and pageset patch: Tasks jobs/min jti jobs/min/task real cpu 1 485.00 100 485.0000 12.00 1.96 Fri Mar 25 11:46:18 2005 100 28000.96 89 280.0096 20.79 150.45 Fri Mar 25 11:46:39 2005 200 32285.80 79 161.4290 36.05 293.37 Fri Mar 25 11:47:16 2005 300 40424.15 84 134.7472 43.19 438.42 Fri Mar 25 11:47:59 2005 400 39155.01 79 97.8875 59.46 590.05 Fri Mar 25 11:48:59 2005 500 37881.25 82 75.7625 76.82 730.19 Fri Mar 25 11:50:16 2005 600 39083.14 78 65.1386 89.35 872.79 Fri Mar 25 11:51:46 2005 700 38627.83 77 55.1826 105.47 1022.46 Fri Mar 25 11:53:32 2005 800 39631.94 78 49.5399 117.48 1169.94 Fri Mar 25 11:55:30 2005 900 36903.70 79 41.0041 141.94 1310.78 Fri Mar 25 11:57:53 2005 1000 36201.23 77 36.2012 160.77 1458.31 Fri Mar 25 12:00:34 2005 Signed-off-by: Christoph Lameter Signed-off-by: Shobhit Dayal Signed-off-by: Shai Fultheim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/base/node.c | 2 +- include/linux/mm.h | 6 ++ include/linux/mmzone.h | 11 ++- init/main.c | 1 + mm/mempolicy.c | 2 +- mm/page_alloc.c | 211 +++++++++++++++++++++++++++++++++++++++++-------- 6 files changed, 195 insertions(+), 38 deletions(-) diff --git a/drivers/base/node.c b/drivers/base/node.c index 5d4517ccc422..904b27caf697 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -87,7 +87,7 @@ static ssize_t node_read_numastat(struct sys_device * dev, char * buf) for (i = 0; i < MAX_NR_ZONES; i++) { struct zone *z = &pg->node_zones[i]; for (cpu = 0; cpu < NR_CPUS; cpu++) { - struct per_cpu_pageset *ps = &z->pageset[cpu]; + struct per_cpu_pageset *ps = zone_pcp(z,cpu); numa_hit += ps->numa_hit; numa_miss += ps->numa_miss; numa_foreign += ps->numa_foreign; diff --git a/include/linux/mm.h b/include/linux/mm.h index 17518fe0b311..1813b162b0a8 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -691,6 +691,12 @@ extern void show_mem(void); extern void si_meminfo(struct sysinfo * val); extern void si_meminfo_node(struct sysinfo *val, int nid); +#ifdef CONFIG_NUMA +extern void setup_per_cpu_pageset(void); +#else +static inline void setup_per_cpu_pageset(void) {} +#endif + /* prio_tree.c */ void vma_prio_tree_add(struct vm_area_struct *, struct vm_area_struct *old); void vma_prio_tree_insert(struct vm_area_struct *, struct prio_tree_root *); diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 18fed8b67943..4733d35d8223 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -63,6 +63,12 @@ struct per_cpu_pageset { #endif } ____cacheline_aligned_in_smp; +#ifdef CONFIG_NUMA +#define zone_pcp(__z, __cpu) ((__z)->pageset[(__cpu)]) +#else +#define zone_pcp(__z, __cpu) (&(__z)->pageset[(__cpu)]) +#endif + #define ZONE_DMA 0 #define ZONE_NORMAL 1 #define ZONE_HIGHMEM 2 @@ -122,8 +128,11 @@ struct zone { */ unsigned long lowmem_reserve[MAX_NR_ZONES]; +#ifdef CONFIG_NUMA + struct per_cpu_pageset *pageset[NR_CPUS]; +#else struct per_cpu_pageset pageset[NR_CPUS]; - +#endif /* * free areas of different sizes */ diff --git a/init/main.c b/init/main.c index 40bf367ffdf1..d324801729ba 100644 --- a/init/main.c +++ b/init/main.c @@ -490,6 +490,7 @@ asmlinkage void __init start_kernel(void) vfs_caches_init_early(); mem_init(); kmem_cache_init(); + setup_per_cpu_pageset(); numa_policy_init(); if (late_time_init) late_time_init(); diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 08c41da429cf..39252c732db2 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -721,7 +721,7 @@ static struct page *alloc_page_interleave(unsigned int __nocast gfp, unsigned or zl = NODE_DATA(nid)->node_zonelists + (gfp & GFP_ZONEMASK); page = __alloc_pages(gfp, order, zl); if (page && page_zone(page) == zl->zones[0]) { - zl->zones[0]->pageset[get_cpu()].interleave_hit++; + zone_pcp(zl->zones[0],get_cpu())->interleave_hit++; put_cpu(); } return page; diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 2019c1b19254..95cbd30a67b8 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -71,6 +71,11 @@ EXPORT_SYMBOL(nr_swap_pages); struct zone *zone_table[1 << (ZONES_SHIFT + NODES_SHIFT)]; EXPORT_SYMBOL(zone_table); +#ifdef CONFIG_NUMA +static struct per_cpu_pageset + pageset_table[MAX_NR_ZONES*MAX_NUMNODES*NR_CPUS] __initdata; +#endif + static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" }; int min_free_kbytes = 1024; @@ -520,7 +525,7 @@ static void __drain_pages(unsigned int cpu) for_each_zone(zone) { struct per_cpu_pageset *pset; - pset = &zone->pageset[cpu]; + pset = zone_pcp(zone, cpu); for (i = 0; i < ARRAY_SIZE(pset->pcp); i++) { struct per_cpu_pages *pcp; @@ -583,12 +588,12 @@ static void zone_statistics(struct zonelist *zonelist, struct zone *z) local_irq_save(flags); cpu = smp_processor_id(); - p = &z->pageset[cpu]; + p = zone_pcp(z,cpu); if (pg == orig) { - z->pageset[cpu].numa_hit++; + p->numa_hit++; } else { p->numa_miss++; - zonelist->zones[0]->pageset[cpu].numa_foreign++; + zone_pcp(zonelist->zones[0], cpu)->numa_foreign++; } if (pg == NODE_DATA(numa_node_id())) p->local_node++; @@ -615,7 +620,7 @@ static void fastcall free_hot_cold_page(struct page *page, int cold) if (PageAnon(page)) page->mapping = NULL; free_pages_check(__FUNCTION__, page); - pcp = &zone->pageset[get_cpu()].pcp[cold]; + pcp = &zone_pcp(zone, get_cpu())->pcp[cold]; local_irq_save(flags); if (pcp->count >= pcp->high) pcp->count -= free_pages_bulk(zone, pcp->batch, &pcp->list, 0); @@ -659,7 +664,7 @@ buffered_rmqueue(struct zone *zone, int order, unsigned int __nocast gfp_flags) if (order == 0) { struct per_cpu_pages *pcp; - pcp = &zone->pageset[get_cpu()].pcp[cold]; + pcp = &zone_pcp(zone, get_cpu())->pcp[cold]; local_irq_save(flags); if (pcp->count <= pcp->low) pcp->count += rmqueue_bulk(zone, 0, @@ -1262,7 +1267,7 @@ void show_free_areas(void) if (!cpu_possible(cpu)) continue; - pageset = zone->pageset + cpu; + pageset = zone_pcp(zone, cpu); for (temperature = 0; temperature < 2; temperature++) printk("cpu %d %s: low %d, high %d, batch %d\n", @@ -1645,6 +1650,157 @@ void zone_init_free_lists(struct pglist_data *pgdat, struct zone *zone, memmap_init_zone((size), (nid), (zone), (start_pfn)) #endif +static int __devinit zone_batchsize(struct zone *zone) +{ + int batch; + + /* + * The per-cpu-pages pools are set to around 1000th of the + * size of the zone. But no more than 1/4 of a meg - there's + * no point in going beyond the size of L2 cache. + * + * OK, so we don't know how big the cache is. So guess. + */ + batch = zone->present_pages / 1024; + if (batch * PAGE_SIZE > 256 * 1024) + batch = (256 * 1024) / PAGE_SIZE; + batch /= 4; /* We effectively *= 4 below */ + if (batch < 1) + batch = 1; + + /* + * Clamp the batch to a 2^n - 1 value. Having a power + * of 2 value was found to be more likely to have + * suboptimal cache aliasing properties in some cases. + * + * For example if 2 tasks are alternately allocating + * batches of pages, one task can end up with a lot + * of pages of one half of the possible page colors + * and the other with pages of the other colors. + */ + batch = (1 << fls(batch + batch/2)) - 1; + return batch; +} + +#ifdef CONFIG_NUMA +/* + * Dynamicaly allocate memory for the + * per cpu pageset array in struct zone. + */ +static int __devinit process_zones(int cpu) +{ + struct zone *zone, *dzone; + int i; + + for_each_zone(zone) { + struct per_cpu_pageset *npageset = NULL; + + npageset = kmalloc_node(sizeof(struct per_cpu_pageset), + GFP_KERNEL, cpu_to_node(cpu)); + if (!npageset) { + zone->pageset[cpu] = NULL; + goto bad; + } + + if (zone->pageset[cpu]) { + memcpy(npageset, zone->pageset[cpu], + sizeof(struct per_cpu_pageset)); + + /* Relocate lists */ + for (i = 0; i < 2; i++) { + INIT_LIST_HEAD(&npageset->pcp[i].list); + list_splice(&zone->pageset[cpu]->pcp[i].list, + &npageset->pcp[i].list); + } + } else { + struct per_cpu_pages *pcp; + unsigned long batch; + + batch = zone_batchsize(zone); + + pcp = &npageset->pcp[0]; /* hot */ + pcp->count = 0; + pcp->low = 2 * batch; + pcp->high = 6 * batch; + pcp->batch = 1 * batch; + INIT_LIST_HEAD(&pcp->list); + + pcp = &npageset->pcp[1]; /* cold*/ + pcp->count = 0; + pcp->low = 0; + pcp->high = 2 * batch; + pcp->batch = 1 * batch; + INIT_LIST_HEAD(&pcp->list); + } + zone->pageset[cpu] = npageset; + } + + return 0; +bad: + for_each_zone(dzone) { + if (dzone == zone) + break; + kfree(dzone->pageset[cpu]); + dzone->pageset[cpu] = NULL; + } + return -ENOMEM; +} + +static inline void free_zone_pagesets(int cpu) +{ +#ifdef CONFIG_NUMA + struct zone *zone; + + for_each_zone(zone) { + struct per_cpu_pageset *pset = zone_pcp(zone, cpu); + + zone_pcp(zone, cpu) = NULL; + kfree(pset); + } +#endif +} + +static int __devinit pageset_cpuup_callback(struct notifier_block *nfb, + unsigned long action, + void *hcpu) +{ + int cpu = (long)hcpu; + int ret = NOTIFY_OK; + + switch (action) { + case CPU_UP_PREPARE: + if (process_zones(cpu)) + ret = NOTIFY_BAD; + break; +#ifdef CONFIG_HOTPLUG_CPU + case CPU_DEAD: + free_zone_pagesets(cpu); + break; +#endif + default: + break; + } + return ret; +} + +static struct notifier_block pageset_notifier = + { &pageset_cpuup_callback, NULL, 0 }; + +void __init setup_per_cpu_pageset() +{ + int err; + + /* Initialize per_cpu_pageset for cpu 0. + * A cpuup callback will do this for every cpu + * as it comes online + */ + err = process_zones(smp_processor_id()); + BUG_ON(err); + register_cpu_notifier(&pageset_notifier); +} + +#endif + /* * Set up the zone data structures: * - mark all pages reserved @@ -1687,43 +1843,28 @@ static void __init free_area_init_core(struct pglist_data *pgdat, zone->temp_priority = zone->prev_priority = DEF_PRIORITY; - /* - * The per-cpu-pages pools are set to around 1000th of the - * size of the zone. But no more than 1/4 of a meg - there's - * no point in going beyond the size of L2 cache. - * - * OK, so we don't know how big the cache is. So guess. - */ - batch = zone->present_pages / 1024; - if (batch * PAGE_SIZE > 256 * 1024) - batch = (256 * 1024) / PAGE_SIZE; - batch /= 4; /* We effectively *= 4 below */ - if (batch < 1) - batch = 1; - - /* - * Clamp the batch to a 2^n - 1 value. Having a power - * of 2 value was found to be more likely to have - * suboptimal cache aliasing properties in some cases. - * - * For example if 2 tasks are alternately allocating - * batches of pages, one task can end up with a lot - * of pages of one half of the possible page colors - * and the other with pages of the other colors. - */ - batch = (1 << fls(batch + batch/2)) - 1; + batch = zone_batchsize(zone); for (cpu = 0; cpu < NR_CPUS; cpu++) { struct per_cpu_pages *pcp; +#ifdef CONFIG_NUMA + struct per_cpu_pageset *pgset; + pgset = &pageset_table[nid*MAX_NR_ZONES*NR_CPUS + + (j * NR_CPUS) + cpu]; + + zone->pageset[cpu] = pgset; +#else + struct per_cpu_pageset *pgset = zone_pcp(zone, cpu); +#endif - pcp = &zone->pageset[cpu].pcp[0]; /* hot */ + pcp = &pgset->pcp[0]; /* hot */ pcp->count = 0; pcp->low = 2 * batch; pcp->high = 6 * batch; pcp->batch = 1 * batch; INIT_LIST_HEAD(&pcp->list); - pcp = &zone->pageset[cpu].pcp[1]; /* cold */ + pcp = &pgset->pcp[1]; /* cold */ pcp->count = 0; pcp->low = 0; pcp->high = 2 * batch; @@ -1929,7 +2070,7 @@ static int zoneinfo_show(struct seq_file *m, void *arg) struct per_cpu_pageset *pageset; int j; - pageset = &zone->pageset[i]; + pageset = zone_pcp(zone, i); for (j = 0; j < ARRAY_SIZE(pageset->pcp); j++) { if (pageset->pcp[j].count) break; -- cgit v1.2.3-59-g8ed1b From 1363c3cd8603a913a27e2995dccbd70d5312d8e6 Mon Sep 17 00:00:00 2001 From: Wolfgang Wander Date: Tue, 21 Jun 2005 17:14:49 -0700 Subject: [PATCH] Avoiding mmap fragmentation Ingo recently introduced a great speedup for allocating new mmaps using the free_area_cache pointer which boosts the specweb SSL benchmark by 4-5% and causes huge performance increases in thread creation. The downside of this patch is that it does lead to fragmentation in the mmap-ed areas (visible via /proc/self/maps), such that some applications that work fine under 2.4 kernels quickly run out of memory on any 2.6 kernel. The problem is twofold: 1) the free_area_cache is used to continue a search for memory where the last search ended. Before the change new areas were always searched from the base address on. So now new small areas are cluttering holes of all sizes throughout the whole mmap-able region whereas before small holes tended to close holes near the base leaving holes far from the base large and available for larger requests. 2) the free_area_cache also is set to the location of the last munmap-ed area so in scenarios where we allocate e.g. five regions of 1K each, then free regions 4 2 3 in this order the next request for 1K will be placed in the position of the old region 3, whereas before we appended it to the still active region 1, placing it at the location of the old region 2. Before we had 1 free region of 2K, now we only get two free regions of 1K -> fragmentation. The patch addresses thes issues by introducing yet another cache descriptor cached_hole_size that contains the largest known hole size below the current free_area_cache. If a new request comes in the size is compared against the cached_hole_size and if the request can be filled with a hole below free_area_cache the search is started from the base instead. The results look promising: Whereas 2.6.12-rc4 fragments quickly and my (earlier posted) leakme.c test program terminates after 50000+ iterations with 96 distinct and fragmented maps in /proc/self/maps it performs nicely (as expected) with thread creation, Ingo's test_str02 with 20000 threads requires 0.7s system time. Taking out Ingo's patch (un-patch available per request) by basically deleting all mentions of free_area_cache from the kernel and starting the search for new memory always at the respective bases we observe: leakme terminates successfully with 11 distinctive hardly fragmented areas in /proc/self/maps but thread creating is gringdingly slow: 30+s(!) system time for Ingo's test_str02 with 20000 threads. Now - drumroll ;-) the appended patch works fine with leakme: it ends with only 7 distinct areas in /proc/self/maps and also thread creation seems sufficiently fast with 0.71s for 20000 threads. Signed-off-by: Wolfgang Wander Credit-to: "Richard Purdie" Signed-off-by: Ken Chen Acked-by: Ingo Molnar (partly) Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/mm/mmap.c | 10 +++++++- arch/i386/mm/hugetlbpage.c | 34 ++++++++++++++++++++++---- arch/ppc64/mm/hugetlbpage.c | 34 ++++++++++++++++++++++---- arch/sh/kernel/sys_sh.c | 8 +++++++ arch/sparc64/kernel/sys_sparc.c | 8 +++++++ arch/x86_64/ia32/ia32_aout.c | 1 + arch/x86_64/kernel/sys_x86_64.c | 9 +++++++ fs/binfmt_aout.c | 1 + fs/binfmt_elf.c | 1 + fs/hugetlbfs/inode.c | 3 +++ include/linux/sched.h | 11 +++++---- kernel/fork.c | 2 ++ mm/mmap.c | 53 +++++++++++++++++++++++++++++++---------- mm/nommu.c | 2 +- 14 files changed, 147 insertions(+), 30 deletions(-) diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index 32c4b0e35b37..3de7f84b53c2 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -73,7 +73,12 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, (!vma || addr + len <= vma->vm_start)) return addr; } - start_addr = addr = mm->free_area_cache; + if (len > mm->cached_hole_size) { + start_addr = addr = mm->free_area_cache; + } else { + start_addr = addr = TASK_UNMAPPED_BASE; + mm->cached_hole_size = 0; + } full_search: if (do_align) @@ -90,6 +95,7 @@ full_search: */ if (start_addr != TASK_UNMAPPED_BASE) { start_addr = addr = TASK_UNMAPPED_BASE; + mm->cached_hole_size = 0; goto full_search; } return -ENOMEM; @@ -101,6 +107,8 @@ full_search: mm->free_area_cache = addr + len; return addr; } + if (addr + mm->cached_hole_size < vma->vm_start) + mm->cached_hole_size = vma->vm_start - addr; addr = vma->vm_end; if (do_align) addr = COLOUR_ALIGN(addr, pgoff); diff --git a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c index 5aa06001a4bd..3b099f32b948 100644 --- a/arch/i386/mm/hugetlbpage.c +++ b/arch/i386/mm/hugetlbpage.c @@ -140,7 +140,12 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file, struct vm_area_struct *vma; unsigned long start_addr; - start_addr = mm->free_area_cache; + if (len > mm->cached_hole_size) { + start_addr = mm->free_area_cache; + } else { + start_addr = TASK_UNMAPPED_BASE; + mm->cached_hole_size = 0; + } full_search: addr = ALIGN(start_addr, HPAGE_SIZE); @@ -154,6 +159,7 @@ full_search: */ if (start_addr != TASK_UNMAPPED_BASE) { start_addr = TASK_UNMAPPED_BASE; + mm->cached_hole_size = 0; goto full_search; } return -ENOMEM; @@ -162,6 +168,8 @@ full_search: mm->free_area_cache = addr + len; return addr; } + if (addr + mm->cached_hole_size < vma->vm_start) + mm->cached_hole_size = vma->vm_start - addr; addr = ALIGN(vma->vm_end, HPAGE_SIZE); } } @@ -173,12 +181,17 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file, struct mm_struct *mm = current->mm; struct vm_area_struct *vma, *prev_vma; unsigned long base = mm->mmap_base, addr = addr0; + unsigned long largest_hole = mm->cached_hole_size; int first_time = 1; /* don't allow allocations above current base */ if (mm->free_area_cache > base) mm->free_area_cache = base; + if (len <= largest_hole) { + largest_hole = 0; + mm->free_area_cache = base; + } try_again: /* make sure it can fit in the remaining address space */ if (mm->free_area_cache < len) @@ -199,13 +212,21 @@ try_again: * vma->vm_start, use it: */ if (addr + len <= vma->vm_start && - (!prev_vma || (addr >= prev_vma->vm_end))) + (!prev_vma || (addr >= prev_vma->vm_end))) { /* remember the address as a hint for next time */ - return (mm->free_area_cache = addr); - else + mm->cached_hole_size = largest_hole; + return (mm->free_area_cache = addr); + } else { /* pull free_area_cache down to the first hole */ - if (mm->free_area_cache == vma->vm_end) + if (mm->free_area_cache == vma->vm_end) { mm->free_area_cache = vma->vm_start; + mm->cached_hole_size = largest_hole; + } + } + + /* remember the largest hole we saw so far */ + if (addr + largest_hole < vma->vm_start) + largest_hole = vma->vm_start - addr; /* try just below the current vma->vm_start */ addr = (vma->vm_start - len) & HPAGE_MASK; @@ -218,6 +239,7 @@ fail: */ if (first_time) { mm->free_area_cache = base; + largest_hole = 0; first_time = 0; goto try_again; } @@ -228,6 +250,7 @@ fail: * allocations. */ mm->free_area_cache = TASK_UNMAPPED_BASE; + mm->cached_hole_size = ~0UL; addr = hugetlb_get_unmapped_area_bottomup(file, addr0, len, pgoff, flags); @@ -235,6 +258,7 @@ fail: * Restore the topdown base: */ mm->free_area_cache = base; + mm->cached_hole_size = ~0UL; return addr; } diff --git a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c index b4ab766f5980..fdcfe97c75c1 100644 --- a/arch/ppc64/mm/hugetlbpage.c +++ b/arch/ppc64/mm/hugetlbpage.c @@ -292,7 +292,12 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, && !is_hugepage_only_range(mm, addr,len)) return addr; } - start_addr = addr = mm->free_area_cache; + if (len > mm->cached_hole_size) { + start_addr = addr = mm->free_area_cache; + } else { + start_addr = addr = TASK_UNMAPPED_BASE; + mm->cached_hole_size = 0; + } full_search: vma = find_vma(mm, addr); @@ -316,6 +321,8 @@ full_search: mm->free_area_cache = addr + len; return addr; } + if (addr + mm->cached_hole_size < vma->vm_start) + mm->cached_hole_size = vma->vm_start - addr; addr = vma->vm_end; vma = vma->vm_next; } @@ -323,6 +330,7 @@ full_search: /* Make sure we didn't miss any holes */ if (start_addr != TASK_UNMAPPED_BASE) { start_addr = addr = TASK_UNMAPPED_BASE; + mm->cached_hole_size = 0; goto full_search; } return -ENOMEM; @@ -344,6 +352,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, struct vm_area_struct *vma, *prev_vma; struct mm_struct *mm = current->mm; unsigned long base = mm->mmap_base, addr = addr0; + unsigned long largest_hole = mm->cached_hole_size; int first_time = 1; /* requested length too big for entire address space */ @@ -364,6 +373,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, return addr; } + if (len <= largest_hole) { + largest_hole = 0; + mm->free_area_cache = base; + } try_again: /* make sure it can fit in the remaining address space */ if (mm->free_area_cache < len) @@ -392,13 +405,21 @@ hugepage_recheck: * vma->vm_start, use it: */ if (addr+len <= vma->vm_start && - (!prev_vma || (addr >= prev_vma->vm_end))) + (!prev_vma || (addr >= prev_vma->vm_end))) { /* remember the address as a hint for next time */ - return (mm->free_area_cache = addr); - else + mm->cached_hole_size = largest_hole; + return (mm->free_area_cache = addr); + } else { /* pull free_area_cache down to the first hole */ - if (mm->free_area_cache == vma->vm_end) + if (mm->free_area_cache == vma->vm_end) { mm->free_area_cache = vma->vm_start; + mm->cached_hole_size = largest_hole; + } + } + + /* remember the largest hole we saw so far */ + if (addr + largest_hole < vma->vm_start) + largest_hole = vma->vm_start - addr; /* try just below the current vma->vm_start */ addr = vma->vm_start-len; @@ -411,6 +432,7 @@ fail: */ if (first_time) { mm->free_area_cache = base; + largest_hole = 0; first_time = 0; goto try_again; } @@ -421,11 +443,13 @@ fail: * allocations. */ mm->free_area_cache = TASK_UNMAPPED_BASE; + mm->cached_hole_size = ~0UL; addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags); /* * Restore the topdown base: */ mm->free_area_cache = base; + mm->cached_hole_size = ~0UL; return addr; } diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c index df5ac294c379..917b2f32f260 100644 --- a/arch/sh/kernel/sys_sh.c +++ b/arch/sh/kernel/sys_sh.c @@ -79,6 +79,10 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, (!vma || addr + len <= vma->vm_start)) return addr; } + if (len <= mm->cached_hole_size) { + mm->cached_hole_size = 0; + mm->free_area_cache = TASK_UNMAPPED_BASE; + } if (flags & MAP_PRIVATE) addr = PAGE_ALIGN(mm->free_area_cache); else @@ -95,6 +99,7 @@ full_search: */ if (start_addr != TASK_UNMAPPED_BASE) { start_addr = addr = TASK_UNMAPPED_BASE; + mm->cached_hole_size = 0; goto full_search; } return -ENOMEM; @@ -106,6 +111,9 @@ full_search: mm->free_area_cache = addr + len; return addr; } + if (addr + mm->cached_hole_size < vma->vm_start) + mm->cached_hole_size = vma->vm_start - addr; + addr = vma->vm_end; if (!(flags & MAP_PRIVATE)) addr = COLOUR_ALIGN(addr); diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index 0077f02f4b37..5f8c822a2b4a 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -84,6 +84,10 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi return addr; } + if (len <= mm->cached_hole_size) { + mm->cached_hole_size = 0; + mm->free_area_cache = TASK_UNMAPPED_BASE; + } start_addr = addr = mm->free_area_cache; task_size -= len; @@ -103,6 +107,7 @@ full_search: if (task_size < addr) { if (start_addr != TASK_UNMAPPED_BASE) { start_addr = addr = TASK_UNMAPPED_BASE; + mm->cached_hole_size = 0; goto full_search; } return -ENOMEM; @@ -114,6 +119,9 @@ full_search: mm->free_area_cache = addr + len; return addr; } + if (addr + mm->cached_hole_size < vma->vm_start) + mm->cached_hole_size = vma->vm_start - addr; + addr = vma->vm_end; if (do_color_align) addr = COLOUR_ALIGN(addr, pgoff); diff --git a/arch/x86_64/ia32/ia32_aout.c b/arch/x86_64/ia32/ia32_aout.c index 1965efc974dc..c12edf5d97f0 100644 --- a/arch/x86_64/ia32/ia32_aout.c +++ b/arch/x86_64/ia32/ia32_aout.c @@ -312,6 +312,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) current->mm->brk = ex.a_bss + (current->mm->start_brk = N_BSSADDR(ex)); current->mm->free_area_cache = TASK_UNMAPPED_BASE; + current->mm->cached_hole_size = 0; set_mm_counter(current->mm, rss, 0); current->mm->mmap = NULL; diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c index d9798dd433fc..cc7821c68851 100644 --- a/arch/x86_64/kernel/sys_x86_64.c +++ b/arch/x86_64/kernel/sys_x86_64.c @@ -105,6 +105,11 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, (!vma || addr + len <= vma->vm_start)) return addr; } + if (((flags & MAP_32BIT) || test_thread_flag(TIF_IA32)) + && len <= mm->cached_hole_size) { + mm->cached_hole_size = 0; + mm->free_area_cache = begin; + } addr = mm->free_area_cache; if (addr < begin) addr = begin; @@ -120,6 +125,7 @@ full_search: */ if (start_addr != begin) { start_addr = addr = begin; + mm->cached_hole_size = 0; goto full_search; } return -ENOMEM; @@ -131,6 +137,9 @@ full_search: mm->free_area_cache = addr + len; return addr; } + if (addr + mm->cached_hole_size < vma->vm_start) + mm->cached_hole_size = vma->vm_start - addr; + addr = vma->vm_end; } } diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index 009b8920c1ff..dd9baabaf016 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c @@ -316,6 +316,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) current->mm->brk = ex.a_bss + (current->mm->start_brk = N_BSSADDR(ex)); current->mm->free_area_cache = current->mm->mmap_base; + current->mm->cached_hole_size = 0; set_mm_counter(current->mm, rss, 0); current->mm->mmap = NULL; diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index f8f6b6b76179..7976a238f0a3 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -775,6 +775,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) change some of these later */ set_mm_counter(current->mm, rss, 0); current->mm->free_area_cache = current->mm->mmap_base; + current->mm->cached_hole_size = 0; retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP), executable_stack); if (retval < 0) { diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 2af3338f891b..3a9b6d179cbd 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -122,6 +122,9 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, start_addr = mm->free_area_cache; + if (len <= mm->cached_hole_size) + start_addr = TASK_UNMAPPED_BASE; + full_search: addr = ALIGN(start_addr, HPAGE_SIZE); diff --git a/include/linux/sched.h b/include/linux/sched.h index 4dbb109022f3..b58afd97a180 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -201,8 +201,8 @@ extern unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags); -extern void arch_unmap_area(struct vm_area_struct *area); -extern void arch_unmap_area_topdown(struct vm_area_struct *area); +extern void arch_unmap_area(struct mm_struct *, unsigned long); +extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long); #define set_mm_counter(mm, member, value) (mm)->_##member = (value) #define get_mm_counter(mm, member) ((mm)->_##member) @@ -218,9 +218,10 @@ struct mm_struct { unsigned long (*get_unmapped_area) (struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags); - void (*unmap_area) (struct vm_area_struct *area); - unsigned long mmap_base; /* base of mmap area */ - unsigned long free_area_cache; /* first hole */ + void (*unmap_area) (struct mm_struct *mm, unsigned long addr); + unsigned long mmap_base; /* base of mmap area */ + unsigned long cached_hole_size; /* if non-zero, the largest hole below free_area_cache */ + unsigned long free_area_cache; /* first hole of size cached_hole_size or larger */ pgd_t * pgd; atomic_t mm_users; /* How many users with user space? */ atomic_t mm_count; /* How many references to "struct mm_struct" (users count as 1) */ diff --git a/kernel/fork.c b/kernel/fork.c index f42a17f88699..876b31cd822d 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -194,6 +194,7 @@ static inline int dup_mmap(struct mm_struct * mm, struct mm_struct * oldmm) mm->mmap = NULL; mm->mmap_cache = NULL; mm->free_area_cache = oldmm->mmap_base; + mm->cached_hole_size = ~0UL; mm->map_count = 0; set_mm_counter(mm, rss, 0); set_mm_counter(mm, anon_rss, 0); @@ -322,6 +323,7 @@ static struct mm_struct * mm_init(struct mm_struct * mm) mm->ioctx_list = NULL; mm->default_kioctx = (struct kioctx)INIT_KIOCTX(mm->default_kioctx, *mm); mm->free_area_cache = TASK_UNMAPPED_BASE; + mm->cached_hole_size = ~0UL; if (likely(!mm_alloc_pgd(mm))) { mm->def_flags = 0; diff --git a/mm/mmap.c b/mm/mmap.c index de54acd9942f..9da23c1ef9dc 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1175,7 +1175,12 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, (!vma || addr + len <= vma->vm_start)) return addr; } - start_addr = addr = mm->free_area_cache; + if (len > mm->cached_hole_size) { + start_addr = addr = mm->free_area_cache; + } else { + start_addr = addr = TASK_UNMAPPED_BASE; + mm->cached_hole_size = 0; + } full_search: for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { @@ -1186,7 +1191,9 @@ full_search: * some holes. */ if (start_addr != TASK_UNMAPPED_BASE) { - start_addr = addr = TASK_UNMAPPED_BASE; + addr = TASK_UNMAPPED_BASE; + start_addr = addr; + mm->cached_hole_size = 0; goto full_search; } return -ENOMEM; @@ -1198,19 +1205,22 @@ full_search: mm->free_area_cache = addr + len; return addr; } + if (addr + mm->cached_hole_size < vma->vm_start) + mm->cached_hole_size = vma->vm_start - addr; addr = vma->vm_end; } } #endif -void arch_unmap_area(struct vm_area_struct *area) +void arch_unmap_area(struct mm_struct *mm, unsigned long addr) { /* * Is this a new hole at the lowest possible address? */ - if (area->vm_start >= TASK_UNMAPPED_BASE && - area->vm_start < area->vm_mm->free_area_cache) - area->vm_mm->free_area_cache = area->vm_start; + if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) { + mm->free_area_cache = addr; + mm->cached_hole_size = ~0UL; + } } /* @@ -1240,6 +1250,12 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, return addr; } + /* check if free_area_cache is useful for us */ + if (len <= mm->cached_hole_size) { + mm->cached_hole_size = 0; + mm->free_area_cache = mm->mmap_base; + } + /* either no address requested or can't fit in requested address hole */ addr = mm->free_area_cache; @@ -1264,6 +1280,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, /* remember the address as a hint for next time */ return (mm->free_area_cache = addr); + /* remember the largest hole we saw so far */ + if (addr + mm->cached_hole_size < vma->vm_start) + mm->cached_hole_size = vma->vm_start - addr; + /* try just below the current vma->vm_start */ addr = vma->vm_start-len; } while (len < vma->vm_start); @@ -1274,28 +1294,30 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, * can happen with large stack limits and large mmap() * allocations. */ - mm->free_area_cache = TASK_UNMAPPED_BASE; + mm->cached_hole_size = ~0UL; + mm->free_area_cache = TASK_UNMAPPED_BASE; addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags); /* * Restore the topdown base: */ mm->free_area_cache = mm->mmap_base; + mm->cached_hole_size = ~0UL; return addr; } #endif -void arch_unmap_area_topdown(struct vm_area_struct *area) +void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr) { /* * Is this a new hole at the highest possible address? */ - if (area->vm_end > area->vm_mm->free_area_cache) - area->vm_mm->free_area_cache = area->vm_end; + if (addr > mm->free_area_cache) + mm->free_area_cache = addr; /* dont allow allocations above current base */ - if (area->vm_mm->free_area_cache > area->vm_mm->mmap_base) - area->vm_mm->free_area_cache = area->vm_mm->mmap_base; + if (mm->free_area_cache > mm->mmap_base) + mm->free_area_cache = mm->mmap_base; } unsigned long @@ -1595,7 +1617,6 @@ static void unmap_vma(struct mm_struct *mm, struct vm_area_struct *area) if (area->vm_flags & VM_LOCKED) area->vm_mm->locked_vm -= len >> PAGE_SHIFT; vm_stat_unaccount(area); - area->vm_mm->unmap_area(area); remove_vm_struct(area); } @@ -1649,6 +1670,7 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, { struct vm_area_struct **insertion_point; struct vm_area_struct *tail_vma = NULL; + unsigned long addr; insertion_point = (prev ? &prev->vm_next : &mm->mmap); do { @@ -1659,6 +1681,11 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, } while (vma && vma->vm_start < end); *insertion_point = vma; tail_vma->vm_next = NULL; + if (mm->unmap_area == arch_unmap_area) + addr = prev ? prev->vm_end : mm->mmap_base; + else + addr = vma ? vma->vm_start : mm->mmap_base; + mm->unmap_area(mm, addr); mm->mmap_cache = NULL; /* Kill the cache. */ } diff --git a/mm/nommu.c b/mm/nommu.c index c53e9c8f6b4a..ce74452c02d9 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1067,7 +1067,7 @@ unsigned long arch_get_unmapped_area(struct file *file, unsigned long addr, return -ENOMEM; } -void arch_unmap_area(struct vm_area_struct *area) +void arch_unmap_area(struct mm_struct *mm, unsigned long addr) { } -- cgit v1.2.3-59-g8ed1b From 73219d178051691a56d57184d8c7f6d0cbe3c5c1 Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Tue, 21 Jun 2005 17:14:52 -0700 Subject: [PATCH] mmap topdown fix for large stack limit, large allocation The topdown changes in 2.6.12-rc1 can cause large allocations with large stack limit to fail, despite there being space available. The mmap_base-len is only valid when len >= mmap_base. However, nothing in topdown allocator checks this. It's only (now) caught at higher level, which will cause allocation to simply fail. The following change restores the fallback to bottom-up path, which will allow large allocations with large stack limit to potentially still succeed. Signed-off-by: Chris Wright Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/mmap.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mm/mmap.c b/mm/mmap.c index 9da23c1ef9dc..da3fa90a0aae 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1267,6 +1267,9 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, return (mm->free_area_cache = addr-len); } + if (mm->mmap_base < len) + goto bottomup; + addr = mm->mmap_base-len; do { @@ -1288,6 +1291,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, addr = vma->vm_start-len; } while (len < vma->vm_start); +bottomup: /* * A failed mmap() very likely causes application failure, * so fall back to the bottom-up function here. This scenario -- cgit v1.2.3-59-g8ed1b From cbe37d093707762fc0abb280781e6a82a9d8d568 Mon Sep 17 00:00:00 2001 From: Badari Pulavarty Date: Tue, 21 Jun 2005 17:14:52 -0700 Subject: [PATCH] mm: remove PG_highmem Remove PG_highmem, to save a page flag. Use is_highmem() instead. It'll generate a little more code, but we don't use PageHigheMem() in many places. Signed-off-by: Badari Pulavarty Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/frv/mm/init.c | 1 - arch/i386/mm/init.c | 1 - arch/mips/mm/init.c | 1 - arch/ppc/mm/init.c | 1 - arch/sparc/mm/init.c | 1 - arch/um/kernel/mem.c | 1 - include/linux/page-flags.h | 31 +++++++++++++++---------------- 7 files changed, 15 insertions(+), 22 deletions(-) diff --git a/arch/frv/mm/init.c b/arch/frv/mm/init.c index 41958f57c838..79433159b5f0 100644 --- a/arch/frv/mm/init.c +++ b/arch/frv/mm/init.c @@ -169,7 +169,6 @@ void __init mem_init(void) struct page *page = &mem_map[pfn]; ClearPageReserved(page); - set_bit(PG_highmem, &page->flags); set_page_count(page, 1); __free_page(page); totalram_pages++; diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 7a7ea3737265..8766c771bb45 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -269,7 +269,6 @@ void __init one_highpage_init(struct page *page, int pfn, int bad_ppro) { if (page_is_ram(pfn) && !(bad_ppro && page_kills_ppro(pfn))) { ClearPageReserved(page); - set_bit(PG_highmem, &page->flags); set_page_count(page, 1); __free_page(page); totalhigh_pages++; diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index b027ce7efbc6..73843c528778 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -232,7 +232,6 @@ void __init mem_init(void) #ifdef CONFIG_LIMITED_DMA set_page_address(page, lowmem_page_address(page)); #endif - set_bit(PG_highmem, &page->flags); set_page_count(page, 1); __free_page(page); totalhigh_pages++; diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index 363c157e3617..c8529d004cfa 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -469,7 +469,6 @@ void __init mem_init(void) struct page *page = mem_map + pfn; ClearPageReserved(page); - set_bit(PG_highmem, &page->flags); set_page_count(page, 1); __free_page(page); totalhigh_pages++; diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index a2dea69b2f07..ec2e05028a10 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c @@ -384,7 +384,6 @@ void map_high_region(unsigned long start_pfn, unsigned long end_pfn) struct page *page = pfn_to_page(tmp); ClearPageReserved(page); - set_bit(PG_highmem, &page->flags); set_page_count(page, 1); __free_page(page); totalhigh_pages++; diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index c22825f13e40..5597bd39e6b5 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -53,7 +53,6 @@ static void setup_highmem(unsigned long highmem_start, for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){ page = &mem_map[highmem_pfn + i]; ClearPageReserved(page); - set_bit(PG_highmem, &page->flags); set_page_count(page, 1); __free_page(page); } diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 39ab8c6b5652..df313891db10 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -61,21 +61,20 @@ #define PG_active 6 #define PG_slab 7 /* slab debug (Suparna wants this) */ -#define PG_highmem 8 -#define PG_checked 9 /* kill me in 2.5.. */ -#define PG_arch_1 10 -#define PG_reserved 11 - -#define PG_private 12 /* Has something at ->private */ -#define PG_writeback 13 /* Page is under writeback */ -#define PG_nosave 14 /* Used for system suspend/resume */ -#define PG_compound 15 /* Part of a compound page */ - -#define PG_swapcache 16 /* Swap page: swp_entry_t in private */ -#define PG_mappedtodisk 17 /* Has blocks allocated on-disk */ -#define PG_reclaim 18 /* To be reclaimed asap */ -#define PG_nosave_free 19 /* Free, should not be written */ -#define PG_uncached 20 /* Page has been mapped as uncached */ +#define PG_checked 8 /* kill me in 2.5.. */ +#define PG_arch_1 9 +#define PG_reserved 10 +#define PG_private 11 /* Has something at ->private */ + +#define PG_writeback 12 /* Page is under writeback */ +#define PG_nosave 13 /* Used for system suspend/resume */ +#define PG_compound 14 /* Part of a compound page */ +#define PG_swapcache 15 /* Swap page: swp_entry_t in private */ + +#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 */ /* * Global page accounting. One instance per CPU. Only unsigned longs are @@ -215,7 +214,7 @@ extern void __mod_page_state(unsigned offset, unsigned long delta); #define TestSetPageSlab(page) test_and_set_bit(PG_slab, &(page)->flags) #ifdef CONFIG_HIGHMEM -#define PageHighMem(page) test_bit(PG_highmem, &(page)->flags) +#define PageHighMem(page) is_highmem(page_zone(page)) #else #define PageHighMem(page) 0 /* needed to optimize away at compile time */ #endif -- cgit v1.2.3-59-g8ed1b From 1ad539b2bd89bf2e129123eb24d5bcc4484a35de Mon Sep 17 00:00:00 2001 From: Darren Hart Date: Tue, 21 Jun 2005 17:14:53 -0700 Subject: [PATCH] vm: try_to_free_pages unused argument try_to_free_pages accepts a third argument, order, but hasn't used it since before 2.6.0. The following patch removes the argument and updates all the calls to try_to_free_pages. Signed-off-by: Darren Hart Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/buffer.c | 2 +- include/linux/swap.h | 2 +- mm/page_alloc.c | 2 +- mm/vmscan.c | 3 +-- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/fs/buffer.c b/fs/buffer.c index 7e9e409feaa7..0befa724ab98 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -528,7 +528,7 @@ static void free_more_memory(void) for_each_pgdat(pgdat) { zones = pgdat->node_zonelists[GFP_NOFS&GFP_ZONEMASK].zones; if (*zones) - try_to_free_pages(zones, GFP_NOFS, 0); + try_to_free_pages(zones, GFP_NOFS); } } diff --git a/include/linux/swap.h b/include/linux/swap.h index 0d21e682d99d..2343f999e6e1 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -172,7 +172,7 @@ extern int rotate_reclaimable_page(struct page *page); extern void swap_setup(void); /* linux/mm/vmscan.c */ -extern int try_to_free_pages(struct zone **, unsigned int, unsigned int); +extern int try_to_free_pages(struct zone **, unsigned int); extern int zone_reclaim(struct zone *, unsigned int, unsigned int); extern int shrink_all_memory(int); extern int vm_swappiness; diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 95cbd30a67b8..70f710286ced 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -859,7 +859,7 @@ rebalance: reclaim_state.reclaimed_slab = 0; p->reclaim_state = &reclaim_state; - did_some_progress = try_to_free_pages(zones, gfp_mask, order); + did_some_progress = try_to_free_pages(zones, gfp_mask); p->reclaim_state = NULL; p->flags &= ~PF_MEMALLOC; diff --git a/mm/vmscan.c b/mm/vmscan.c index 24da725a30f0..4b8e62a19370 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -919,8 +919,7 @@ shrink_caches(struct zone **zones, struct scan_control *sc) * holds filesystem locks which prevent writeout this might not work, and the * allocation attempt will fail. */ -int try_to_free_pages(struct zone **zones, - unsigned int gfp_mask, unsigned int order) +int try_to_free_pages(struct zone **zones, unsigned int gfp_mask) { int priority; int ret = 0; -- cgit v1.2.3-59-g8ed1b From 83e5d8f7253cb7b14472385a6d57df1e9f848e8e Mon Sep 17 00:00:00 2001 From: Benjamin LaHaise Date: Tue, 21 Jun 2005 17:14:54 -0700 Subject: [PATCH] __mod_page_state(): pass unsigned long instead of unsigned By making the offset argument of __mod_page_state an unsigned long instead of unsigned, we can avoid forcing the compiler to sign extend a usually constant argument. This saves 1 instruction on x86-64. Signed-off-by: Benjamin LaHaise Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/page-flags.h | 2 +- mm/page_alloc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index df313891db10..f2ee9b2332e3 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -136,7 +136,7 @@ struct page_state { extern void get_page_state(struct page_state *ret); extern void get_full_page_state(struct page_state *ret); extern unsigned long __read_page_state(unsigned offset); -extern void __mod_page_state(unsigned offset, unsigned long delta); +extern void __mod_page_state(unsigned long offset, unsigned long delta); #define read_page_state(member) \ __read_page_state(offsetof(struct page_state, member)) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 70f710286ced..c976628f9d95 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1158,7 +1158,7 @@ unsigned long __read_page_state(unsigned offset) return ret; } -void __mod_page_state(unsigned offset, unsigned long delta) +void __mod_page_state(unsigned long offset, unsigned long delta) { unsigned long flags; void* ptr; -- cgit v1.2.3-59-g8ed1b From c2f29ea111e3344ed48257c2a142c3db514e1529 Mon Sep 17 00:00:00 2001 From: Benjamin LaHaise Date: Tue, 21 Jun 2005 17:14:55 -0700 Subject: [PATCH] __read_page_state(): pass unsigned long instead of unsigned By making the offset argument of __read_page_state an unsigned long instead of unsigned, we can avoid forcing the compiler to sign extend a usually constant argument. This saves 1 instruction on x86-64. Signed-off-by: Benjamin LaHaise Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/page-flags.h | 2 +- mm/page_alloc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index f2ee9b2332e3..f5a6695d4d21 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -135,7 +135,7 @@ struct page_state { extern void get_page_state(struct page_state *ret); extern void get_full_page_state(struct page_state *ret); -extern unsigned long __read_page_state(unsigned offset); +extern unsigned long __read_page_state(unsigned long offset); extern void __mod_page_state(unsigned long offset, unsigned long delta); #define read_page_state(member) \ diff --git a/mm/page_alloc.c b/mm/page_alloc.c index c976628f9d95..10446a646374 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1144,7 +1144,7 @@ void get_full_page_state(struct page_state *ret) __get_page_state(ret, sizeof(*ret) / sizeof(unsigned long)); } -unsigned long __read_page_state(unsigned offset) +unsigned long __read_page_state(unsigned long offset) { unsigned long ret = 0; int cpu; -- cgit v1.2.3-59-g8ed1b From 578c2fd6a7f378434655e5c480e23152a3994404 Mon Sep 17 00:00:00 2001 From: Janet Morgan Date: Tue, 21 Jun 2005 17:14:56 -0700 Subject: [PATCH] add OOM debug This patch provides more debug info when the system is OOM. It displays memory stats (basically sysrq-m info) from __alloc_pages() when page allocation fails and during OOM kill. Thanks to Dave Jones for coming up with the idea. Signed-off-by: Janet Morgan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/oom_kill.c | 7 ++++--- mm/page_alloc.c | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 4bbb1cb10495..59666d905f19 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -258,6 +258,10 @@ void out_of_memory(unsigned int __nocast gfp_mask) struct mm_struct *mm = NULL; task_t * p; + printk("oom-killer: gfp_mask=0x%x\n", gfp_mask); + /* print memory stats */ + show_mem(); + read_lock(&tasklist_lock); retry: p = select_bad_process(); @@ -268,12 +272,9 @@ retry: /* Found nothing?!?! Either we hang forever, or we panic. */ if (!p) { read_unlock(&tasklist_lock); - show_free_areas(); panic("Out of memory and no killable processes...\n"); } - printk("oom-killer: gfp_mask=0x%x\n", gfp_mask); - show_free_areas(); mm = oom_kill_process(p); if (!mm) goto retry; diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 10446a646374..be05d17bd7df 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -935,6 +935,7 @@ nopage: " order:%d, mode:0x%x\n", p->comm, order, gfp_mask); dump_stack(); + show_mem(); } return NULL; got_pg: -- cgit v1.2.3-59-g8ed1b From 4ae7c03943fca73f23bc0cdb938070f41b98101f Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Tue, 21 Jun 2005 17:14:57 -0700 Subject: [PATCH] Periodically drain non local pagesets The pageset array can potentially acquire a huge amount of memory on large NUMA systems. F.e. on a system with 512 processors and 256 nodes there will be 256*512 pagesets. If each pageset only holds 5 pages then we are talking about 655360 pages.With a 16K page size on IA64 this results in potentially 10 Gigabytes of memory being trapped in pagesets. The typical cases are much less for smaller systems but there is still the potential of memory being trapped in off node pagesets. Off node memory may be rarely used if local memory is available and so we may potentially have memory in seldom used pagesets without this patch. The slab allocator flushes its per cpu caches every 2 seconds. The following patch flushes the off node pageset caches in the same way by tying into the slab flush. The patch also changes /proc/zoneinfo to include the number of pages currently in each pageset. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/gfp.h | 5 +++++ mm/page_alloc.c | 35 +++++++++++++++++++++++++++++++++-- mm/slab.c | 1 + 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 208535fd4832..8d6bf608b199 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -133,5 +133,10 @@ extern void FASTCALL(free_cold_page(struct page *page)); #define free_page(addr) free_pages((addr),0) void page_alloc_init(void); +#ifdef CONFIG_NUMA +void drain_remote_pages(void); +#else +static inline void drain_remote_pages(void) { }; +#endif #endif /* __LINUX_GFP_H */ diff --git a/mm/page_alloc.c b/mm/page_alloc.c index be05d17bd7df..a95e72d7f945 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -516,6 +516,36 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order, return allocated; } +#ifdef CONFIG_NUMA +/* Called from the slab reaper to drain remote pagesets */ +void drain_remote_pages(void) +{ + struct zone *zone; + int i; + unsigned long flags; + + local_irq_save(flags); + for_each_zone(zone) { + struct per_cpu_pageset *pset; + + /* Do not drain local pagesets */ + if (zone->zone_pgdat->node_id == numa_node_id()) + continue; + + pset = zone->pageset[smp_processor_id()]; + for (i = 0; i < ARRAY_SIZE(pset->pcp); i++) { + struct per_cpu_pages *pcp; + + pcp = &pset->pcp[i]; + if (pcp->count) + pcp->count -= free_pages_bulk(zone, pcp->count, + &pcp->list, 0); + } + } + local_irq_restore(flags); +} +#endif + #if defined(CONFIG_PM) || defined(CONFIG_HOTPLUG_CPU) static void __drain_pages(unsigned int cpu) { @@ -1271,12 +1301,13 @@ void show_free_areas(void) pageset = zone_pcp(zone, cpu); for (temperature = 0; temperature < 2; temperature++) - printk("cpu %d %s: low %d, high %d, batch %d\n", + printk("cpu %d %s: low %d, high %d, batch %d used:%d\n", cpu, temperature ? "cold" : "hot", pageset->pcp[temperature].low, pageset->pcp[temperature].high, - pageset->pcp[temperature].batch); + pageset->pcp[temperature].batch, + pageset->pcp[temperature].count); } } diff --git a/mm/slab.c b/mm/slab.c index c78d343b3c5f..93cbbbb39f42 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -2851,6 +2851,7 @@ next: } check_irq_on(); up(&cache_chain_sem); + drain_remote_pages(); /* Setup the next iteration */ schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC + smp_processor_id()); } -- cgit v1.2.3-59-g8ed1b From 2caaad41e4aa8f5dd999695b4ddeaa0e7f3912a4 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Tue, 21 Jun 2005 17:15:00 -0700 Subject: [PATCH] Reduce size of huge boot per_cpu_pageset Reduce size of the huge per_cpu_pageset structure in __initdata introduced into mm1 with the pageset localization patchset. Use one specially configured pageset per cpu for all zones and nodes during bootup. - Avoid duplication of pageset initialization code. - do the adding to the pageset list before potential free_pages_bulk in free_hot_cold_page (otherwise we would have to hold a page in a pageset during the period that the boot pagesets are in use). - remove mistaken __cpuinitdata attribute and revert back to __initdata for the boot pageset. A boot pageset is not necessary for cpu hotplug. Tested for UP SMP NUMA on x86_64 (2.6.12-rc6-mm1): UP SMP NUMA Tested on IA64 (2.6.12-rc5-mm2): NUMA (2.6.12-rc6-mm1 broken for IA64 because of sparsemem patches) Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_alloc.c | 108 ++++++++++++++++++++++---------------------------------- 1 file changed, 42 insertions(+), 66 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index a95e72d7f945..418102a02921 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -71,11 +71,6 @@ EXPORT_SYMBOL(nr_swap_pages); struct zone *zone_table[1 << (ZONES_SHIFT + NODES_SHIFT)]; EXPORT_SYMBOL(zone_table); -#ifdef CONFIG_NUMA -static struct per_cpu_pageset - pageset_table[MAX_NR_ZONES*MAX_NUMNODES*NR_CPUS] __initdata; -#endif - static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" }; int min_free_kbytes = 1024; @@ -652,10 +647,10 @@ static void fastcall free_hot_cold_page(struct page *page, int cold) free_pages_check(__FUNCTION__, page); pcp = &zone_pcp(zone, get_cpu())->pcp[cold]; local_irq_save(flags); - if (pcp->count >= pcp->high) - pcp->count -= free_pages_bulk(zone, pcp->batch, &pcp->list, 0); list_add(&page->lru, &pcp->list); pcp->count++; + if (pcp->count >= pcp->high) + pcp->count -= free_pages_bulk(zone, pcp->batch, &pcp->list, 0); local_irq_restore(flags); put_cpu(); } @@ -1714,57 +1709,55 @@ static int __devinit zone_batchsize(struct zone *zone) return batch; } +inline void setup_pageset(struct per_cpu_pageset *p, unsigned long batch) +{ + struct per_cpu_pages *pcp; + + pcp = &p->pcp[0]; /* hot */ + pcp->count = 0; + pcp->low = 2 * batch; + pcp->high = 6 * batch; + pcp->batch = max(1UL, 1 * batch); + INIT_LIST_HEAD(&pcp->list); + + pcp = &p->pcp[1]; /* cold*/ + pcp->count = 0; + pcp->low = 0; + pcp->high = 2 * batch; + pcp->batch = max(1UL, 1 * batch); + INIT_LIST_HEAD(&pcp->list); +} + #ifdef CONFIG_NUMA /* - * Dynamicaly allocate memory for the + * Boot pageset table. One per cpu which is going to be used for all + * zones and all nodes. The parameters will be set in such a way + * that an item put on a list will immediately be handed over to + * the buddy list. This is safe since pageset manipulation is done + * with interrupts disabled. + * + * Some NUMA counter updates may also be caught by the boot pagesets. + * These will be discarded when bootup is complete. + */ +static struct per_cpu_pageset + boot_pageset[NR_CPUS] __initdata; + +/* + * Dynamically allocate memory for the * per cpu pageset array in struct zone. */ static int __devinit process_zones(int cpu) { struct zone *zone, *dzone; - int i; for_each_zone(zone) { - struct per_cpu_pageset *npageset = NULL; - npageset = kmalloc_node(sizeof(struct per_cpu_pageset), + zone->pageset[cpu] = kmalloc_node(sizeof(struct per_cpu_pageset), GFP_KERNEL, cpu_to_node(cpu)); - if (!npageset) { - zone->pageset[cpu] = NULL; + if (!zone->pageset[cpu]) goto bad; - } - if (zone->pageset[cpu]) { - memcpy(npageset, zone->pageset[cpu], - sizeof(struct per_cpu_pageset)); - - /* Relocate lists */ - for (i = 0; i < 2; i++) { - INIT_LIST_HEAD(&npageset->pcp[i].list); - list_splice(&zone->pageset[cpu]->pcp[i].list, - &npageset->pcp[i].list); - } - } else { - struct per_cpu_pages *pcp; - unsigned long batch; - - batch = zone_batchsize(zone); - - pcp = &npageset->pcp[0]; /* hot */ - pcp->count = 0; - pcp->low = 2 * batch; - pcp->high = 6 * batch; - pcp->batch = 1 * batch; - INIT_LIST_HEAD(&pcp->list); - - pcp = &npageset->pcp[1]; /* cold*/ - pcp->count = 0; - pcp->low = 0; - pcp->high = 2 * batch; - pcp->batch = 1 * batch; - INIT_LIST_HEAD(&pcp->list); - } - zone->pageset[cpu] = npageset; + setup_pageset(zone->pageset[cpu], zone_batchsize(zone)); } return 0; @@ -1878,30 +1871,13 @@ static void __init free_area_init_core(struct pglist_data *pgdat, batch = zone_batchsize(zone); for (cpu = 0; cpu < NR_CPUS; cpu++) { - struct per_cpu_pages *pcp; #ifdef CONFIG_NUMA - struct per_cpu_pageset *pgset; - pgset = &pageset_table[nid*MAX_NR_ZONES*NR_CPUS + - (j * NR_CPUS) + cpu]; - - zone->pageset[cpu] = pgset; + /* Early boot. Slab allocator not functional yet */ + zone->pageset[cpu] = &boot_pageset[cpu]; + setup_pageset(&boot_pageset[cpu],0); #else - struct per_cpu_pageset *pgset = zone_pcp(zone, cpu); + setup_pageset(zone_pcp(zone,cpu), batch); #endif - - pcp = &pgset->pcp[0]; /* hot */ - pcp->count = 0; - pcp->low = 2 * batch; - pcp->high = 6 * batch; - pcp->batch = 1 * batch; - INIT_LIST_HEAD(&pcp->list); - - pcp = &pgset->pcp[1]; /* cold */ - pcp->count = 0; - pcp->low = 0; - pcp->high = 2 * batch; - pcp->batch = 1 * batch; - INIT_LIST_HEAD(&pcp->list); } printk(KERN_DEBUG " %s zone: %lu pages, LIFO batch:%lu\n", zone_names[j], realsize, batch); -- cgit v1.2.3-59-g8ed1b From f14f75b81187cdbe10cc53a521bf9fdf97b59f8c Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Tue, 21 Jun 2005 17:15:02 -0700 Subject: [PATCH] ia64 uncached alloc This patch contains the ia64 uncached page allocator and the generic allocator (genalloc). The uncached allocator was formerly part of the SN2 mspec driver but there are several other users of it so it has been split off from the driver. The generic allocator can be used by device driver to manage special memory etc. The generic allocator is based on the allocator from the sym53c8xx_2 driver. Various users on ia64 needs uncached memory. The SGI SN architecture requires it for inter-partition communication between partitions within a large NUMA cluster. The specific user for this is the XPC code. Another application is large MPI style applications which use it for synchronization, on SN this can be done using special 'fetchop' operations but it also benefits non SN hardware which may use regular uncached memory for this purpose. Performance of doing this through uncached vs cached memory is pretty substantial. This is handled by the mspec driver which I will push out in a seperate patch. Rather than creating a specific allocator for just uncached memory I came up with genalloc which is a generic purpose allocator that can be used by device drivers and other subsystems as they please. For instance to handle onboard device memory. It was derived from the sym53c7xx_2 driver's allocator which is also an example of a potential user (I am refraining from modifying sym2 right now as it seems to have been under fairly heavy development recently). On ia64 memory has various properties within a granule, ie. it isn't safe to access memory as uncached within the same granule as currently has memory accessed in cached mode. The regular system therefore doesn't utilize memory in the lower granules which is mixed in with device PAL code etc. The uncached driver walks the EFI memmap and pulls out the spill uncached pages and sticks them into the uncached pool. Only after these chunks have been utilized, will it start converting regular cached memory into uncached memory. Hence the reason for the EFI related code additions. Signed-off-by: Jes Sorensen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/Kconfig | 4 + arch/ia64/kernel/Makefile | 1 + arch/ia64/kernel/efi.c | 32 ++++++ arch/ia64/kernel/uncached.c | 246 ++++++++++++++++++++++++++++++++++++++++++++ include/asm-ia64/uncached.h | 12 +++ include/linux/genalloc.h | 40 +++++++ lib/Kconfig | 6 ++ lib/Makefile | 1 + lib/genalloc.c | 188 +++++++++++++++++++++++++++++++++ 9 files changed, 530 insertions(+) create mode 100644 arch/ia64/kernel/uncached.c create mode 100644 include/asm-ia64/uncached.h create mode 100644 include/linux/genalloc.h create mode 100644 lib/genalloc.c diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 3ad2c4af099c..295b5abee72f 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -50,6 +50,10 @@ config SCHED_NO_NO_OMIT_FRAME_POINTER bool default y +config IA64_UNCACHED_ALLOCATOR + bool + select GENERIC_ALLOCATOR + choice prompt "System type" default IA64_GENERIC diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index c1a02bbc252c..4c73d8ba2e3d 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_SMP) += smp.o smpboot.o domain.o obj-$(CONFIG_PERFMON) += perfmon_default_smpl.o obj-$(CONFIG_IA64_CYCLONE) += cyclone.o obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o +obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o mca_recovery-y += mca_drv.o mca_drv_asm.o # The gate DSO image is built using a special linker script. diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index 4a3b1aac43e7..179f230816ed 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -409,6 +409,38 @@ efi_memmap_walk (efi_freemem_callback_t callback, void *arg) } } +/* + * Walk the EFI memory map to pull out leftover pages in the lower + * memory regions which do not end up in the regular memory map and + * stick them into the uncached allocator + * + * The regular walk function is significantly more complex than the + * uncached walk which means it really doesn't make sense to try and + * marge the two. + */ +void __init +efi_memmap_walk_uc (efi_freemem_callback_t callback) +{ + void *efi_map_start, *efi_map_end, *p; + efi_memory_desc_t *md; + u64 efi_desc_size, start, end; + + efi_map_start = __va(ia64_boot_param->efi_memmap); + efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; + efi_desc_size = ia64_boot_param->efi_memdesc_size; + + for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { + md = p; + if (md->attribute == EFI_MEMORY_UC) { + start = PAGE_ALIGN(md->phys_addr); + end = PAGE_ALIGN((md->phys_addr+(md->num_pages << EFI_PAGE_SHIFT)) & PAGE_MASK); + if ((*callback)(start, end, NULL) < 0) + return; + } + } +} + + /* * Look for the PAL_CODE region reported by EFI and maps it using an * ITR to enable safe PAL calls in virtual mode. See IA-64 Processor diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c new file mode 100644 index 000000000000..490dfc9ab47f --- /dev/null +++ b/arch/ia64/kernel/uncached.c @@ -0,0 +1,246 @@ +/* + * Copyright (C) 2001-2005 Silicon Graphics, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + * + * A simple uncached page allocator using the generic allocator. This + * allocator first utilizes the spare (spill) pages found in the EFI + * memmap and will then start converting cached pages to uncached ones + * at a granule at a time. Node awareness is implemented by having a + * pool of pages per node. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG 0 + +#if DEBUG +#define dprintk printk +#else +#define dprintk(x...) do { } while (0) +#endif + +void __init efi_memmap_walk_uc (efi_freemem_callback_t callback); + +#define MAX_UNCACHED_GRANULES 5 +static int allocated_granules; + +struct gen_pool *uncached_pool[MAX_NUMNODES]; + + +static void uncached_ipi_visibility(void *data) +{ + int status; + + status = ia64_pal_prefetch_visibility(PAL_VISIBILITY_PHYSICAL); + if ((status != PAL_VISIBILITY_OK) && + (status != PAL_VISIBILITY_OK_REMOTE_NEEDED)) + printk(KERN_DEBUG "pal_prefetch_visibility() returns %i on " + "CPU %i\n", status, get_cpu()); +} + + +static void uncached_ipi_mc_drain(void *data) +{ + int status; + status = ia64_pal_mc_drain(); + if (status) + printk(KERN_WARNING "ia64_pal_mc_drain() failed with %i on " + "CPU %i\n", status, get_cpu()); +} + + +static unsigned long +uncached_get_new_chunk(struct gen_pool *poolp) +{ + struct page *page; + void *tmp; + int status, i; + unsigned long addr, node; + + if (allocated_granules >= MAX_UNCACHED_GRANULES) + return 0; + + node = poolp->private; + page = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, + IA64_GRANULE_SHIFT-PAGE_SHIFT); + + dprintk(KERN_INFO "get_new_chunk page %p, addr %lx\n", + page, (unsigned long)(page-vmem_map) << PAGE_SHIFT); + + /* + * Do magic if no mem on local node! XXX + */ + if (!page) + return 0; + tmp = page_address(page); + + /* + * There's a small race here where it's possible for someone to + * access the page through /dev/mem halfway through the conversion + * to uncached - not sure it's really worth bothering about + */ + for (i = 0; i < (IA64_GRANULE_SIZE / PAGE_SIZE); i++) + SetPageUncached(&page[i]); + + flush_tlb_kernel_range(tmp, tmp + IA64_GRANULE_SIZE); + + status = ia64_pal_prefetch_visibility(PAL_VISIBILITY_PHYSICAL); + + dprintk(KERN_INFO "pal_prefetch_visibility() returns %i on cpu %i\n", + status, get_cpu()); + + if (!status) { + status = smp_call_function(uncached_ipi_visibility, NULL, 0, 1); + if (status) + printk(KERN_WARNING "smp_call_function failed for " + "uncached_ipi_visibility! (%i)\n", status); + } + + if (ia64_platform_is("sn2")) + sn_flush_all_caches((unsigned long)tmp, IA64_GRANULE_SIZE); + else + flush_icache_range((unsigned long)tmp, + (unsigned long)tmp+IA64_GRANULE_SIZE); + + ia64_pal_mc_drain(); + status = smp_call_function(uncached_ipi_mc_drain, NULL, 0, 1); + if (status) + printk(KERN_WARNING "smp_call_function failed for " + "uncached_ipi_mc_drain! (%i)\n", status); + + addr = (unsigned long)tmp - PAGE_OFFSET + __IA64_UNCACHED_OFFSET; + + allocated_granules++; + return addr; +} + + +/* + * uncached_alloc_page + * + * Allocate 1 uncached page. Allocates on the requested node. If no + * uncached pages are available on the requested node, roundrobin starting + * with higher nodes. + */ +unsigned long +uncached_alloc_page(int nid) +{ + unsigned long maddr; + + maddr = gen_pool_alloc(uncached_pool[nid], PAGE_SIZE); + + dprintk(KERN_DEBUG "uncached_alloc_page returns %lx on node %i\n", + maddr, nid); + + /* + * If no memory is availble on our local node, try the + * remaining nodes in the system. + */ + if (!maddr) { + int i; + + for (i = MAX_NUMNODES - 1; i >= 0; i--) { + if (i == nid || !node_online(i)) + continue; + maddr = gen_pool_alloc(uncached_pool[i], PAGE_SIZE); + dprintk(KERN_DEBUG "uncached_alloc_page alternate search " + "returns %lx on node %i\n", maddr, i); + if (maddr) { + break; + } + } + } + + return maddr; +} +EXPORT_SYMBOL(uncached_alloc_page); + + +/* + * uncached_free_page + * + * Free a single uncached page. + */ +void +uncached_free_page(unsigned long maddr) +{ + int node; + + node = nasid_to_cnodeid(NASID_GET(maddr)); + + dprintk(KERN_DEBUG "uncached_free_page(%lx) on node %i\n", maddr, node); + + if ((maddr & (0XFUL << 60)) != __IA64_UNCACHED_OFFSET) + panic("uncached_free_page invalid address %lx\n", maddr); + + gen_pool_free(uncached_pool[node], maddr, PAGE_SIZE); +} +EXPORT_SYMBOL(uncached_free_page); + + +/* + * uncached_build_memmap, + * + * Called at boot time to build a map of pages that can be used for + * memory special operations. + */ +static int __init +uncached_build_memmap(unsigned long start, unsigned long end, void *arg) +{ + long length; + unsigned long vstart, vend; + int node; + + length = end - start; + vstart = start + __IA64_UNCACHED_OFFSET; + vend = end + __IA64_UNCACHED_OFFSET; + + dprintk(KERN_ERR "uncached_build_memmap(%lx %lx)\n", start, end); + + memset((char *)vstart, 0, length); + + node = nasid_to_cnodeid(NASID_GET(start)); + + for (; vstart < vend ; vstart += PAGE_SIZE) { + dprintk(KERN_INFO "sticking %lx into the pool!\n", vstart); + gen_pool_free(uncached_pool[node], vstart, PAGE_SIZE); + } + + return 0; +} + + +static int __init uncached_init(void) { + int i; + + for (i = 0; i < MAX_NUMNODES; i++) { + if (!node_online(i)) + continue; + uncached_pool[i] = gen_pool_create(0, IA64_GRANULE_SHIFT, + &uncached_get_new_chunk, i); + } + + efi_memmap_walk_uc(uncached_build_memmap); + + return 0; +} + +__initcall(uncached_init); diff --git a/include/asm-ia64/uncached.h b/include/asm-ia64/uncached.h new file mode 100644 index 000000000000..b82d923b73c1 --- /dev/null +++ b/include/asm-ia64/uncached.h @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2001-2005 Silicon Graphics, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + * + * Prototypes for the uncached page allocator + */ + +extern unsigned long uncached_alloc_page(int nid); +extern void uncached_free_page(unsigned long); diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h new file mode 100644 index 000000000000..7fd0576a4454 --- /dev/null +++ b/include/linux/genalloc.h @@ -0,0 +1,40 @@ +/* + * Basic general purpose allocator for managing special purpose memory + * not managed by the regular kmalloc/kfree interface. + * Uses for this includes on-device special memory, uncached memory + * etc. + * + * This code is based on the buddy allocator found in the sym53c8xx_2 + * driver, adapted for general purpose use. + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#include + +#define ALLOC_MIN_SHIFT 5 /* 32 bytes minimum */ +/* + * Link between free memory chunks of a given size. + */ +struct gen_pool_link { + struct gen_pool_link *next; +}; + +/* + * Memory pool descriptor. + */ +struct gen_pool { + spinlock_t lock; + unsigned long (*get_new_chunk)(struct gen_pool *); + struct gen_pool *next; + struct gen_pool_link *h; + unsigned long private; + int max_chunk_shift; +}; + +unsigned long gen_pool_alloc(struct gen_pool *poolp, int size); +void gen_pool_free(struct gen_pool *mp, unsigned long ptr, int size); +struct gen_pool *gen_pool_create(int nr_chunks, int max_chunk_shift, + unsigned long (*fp)(struct gen_pool *), + unsigned long data); diff --git a/lib/Kconfig b/lib/Kconfig index eeb45225248f..2d4d4e3bc4aa 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -39,6 +39,12 @@ config ZLIB_INFLATE config ZLIB_DEFLATE tristate +# +# Generic allocator support is selected if needed +# +config GENERIC_ALLOCATOR + boolean + # # reed solomon support is select'ed if needed # diff --git a/lib/Makefile b/lib/Makefile index 5f10cb898407..dcb4231916e2 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o obj-$(CONFIG_CRC32) += crc32.o obj-$(CONFIG_LIBCRC32C) += libcrc32c.o obj-$(CONFIG_GENERIC_IOMAP) += iomap.o +obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/ obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/ diff --git a/lib/genalloc.c b/lib/genalloc.c new file mode 100644 index 000000000000..d6d30d2e7166 --- /dev/null +++ b/lib/genalloc.c @@ -0,0 +1,188 @@ +/* + * Basic general purpose allocator for managing special purpose memory + * not managed by the regular kmalloc/kfree interface. + * Uses for this includes on-device special memory, uncached memory + * etc. + * + * This code is based on the buddy allocator found in the sym53c8xx_2 + * driver Copyright (C) 1999-2001 Gerard Roudier , + * and adapted for general purpose use. + * + * Copyright 2005 (C) Jes Sorensen + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +struct gen_pool *gen_pool_create(int nr_chunks, int max_chunk_shift, + unsigned long (*fp)(struct gen_pool *), + unsigned long data) +{ + struct gen_pool *poolp; + unsigned long tmp; + int i; + + /* + * This is really an arbitrary limit, +10 is enough for + * IA64_GRANULE_SHIFT, aka 16MB. If anyone needs a large limit + * this can be increased without problems. + */ + if ((max_chunk_shift > (PAGE_SHIFT + 10)) || + ((max_chunk_shift < ALLOC_MIN_SHIFT) && max_chunk_shift)) + return NULL; + + if (!max_chunk_shift) + max_chunk_shift = PAGE_SHIFT; + + poolp = kmalloc(sizeof(struct gen_pool), GFP_KERNEL); + if (!poolp) + return NULL; + memset(poolp, 0, sizeof(struct gen_pool)); + poolp->h = kmalloc(sizeof(struct gen_pool_link) * + (max_chunk_shift - ALLOC_MIN_SHIFT + 1), + GFP_KERNEL); + if (!poolp->h) { + printk(KERN_WARNING "gen_pool_alloc() failed to allocate\n"); + kfree(poolp); + return NULL; + } + memset(poolp->h, 0, sizeof(struct gen_pool_link) * + (max_chunk_shift - ALLOC_MIN_SHIFT + 1)); + + spin_lock_init(&poolp->lock); + poolp->get_new_chunk = fp; + poolp->max_chunk_shift = max_chunk_shift; + poolp->private = data; + + for (i = 0; i < nr_chunks; i++) { + tmp = poolp->get_new_chunk(poolp); + printk(KERN_INFO "allocated %lx\n", tmp); + if (!tmp) + break; + gen_pool_free(poolp, tmp, (1 << poolp->max_chunk_shift)); + } + + return poolp; +} +EXPORT_SYMBOL(gen_pool_create); + + +/* + * Simple power of two buddy-like generic allocator. + * Provides naturally aligned memory chunks. + */ +unsigned long gen_pool_alloc(struct gen_pool *poolp, int size) +{ + int j, i, s, max_chunk_size; + unsigned long a, flags; + struct gen_pool_link *h = poolp->h; + + max_chunk_size = 1 << poolp->max_chunk_shift; + + if (size > max_chunk_size) + return 0; + + i = 0; + + size = max(size, 1 << ALLOC_MIN_SHIFT); + s = roundup_pow_of_two(size); + + j = i; + + spin_lock_irqsave(&poolp->lock, flags); + while (!h[j].next) { + if (s == max_chunk_size) { + struct gen_pool_link *ptr; + spin_unlock_irqrestore(&poolp->lock, flags); + ptr = (struct gen_pool_link *)poolp->get_new_chunk(poolp); + spin_lock_irqsave(&poolp->lock, flags); + h[j].next = ptr; + if (h[j].next) + h[j].next->next = NULL; + break; + } + j++; + s <<= 1; + } + a = (unsigned long) h[j].next; + if (a) { + h[j].next = h[j].next->next; + /* + * This should be split into a seperate function doing + * the chunk split in order to support custom + * handling memory not physically accessible by host + */ + while (j > i) { + j -= 1; + s >>= 1; + h[j].next = (struct gen_pool_link *) (a + s); + h[j].next->next = NULL; + } + } + spin_unlock_irqrestore(&poolp->lock, flags); + return a; +} +EXPORT_SYMBOL(gen_pool_alloc); + + +/* + * Counter-part of the generic allocator. + */ +void gen_pool_free(struct gen_pool *poolp, unsigned long ptr, int size) +{ + struct gen_pool_link *q; + struct gen_pool_link *h = poolp->h; + unsigned long a, b, flags; + int i, s, max_chunk_size; + + max_chunk_size = 1 << poolp->max_chunk_shift; + + if (size > max_chunk_size) + return; + + i = 0; + + size = max(size, 1 << ALLOC_MIN_SHIFT); + s = roundup_pow_of_two(size); + + a = ptr; + + spin_lock_irqsave(&poolp->lock, flags); + while (1) { + if (s == max_chunk_size) { + ((struct gen_pool_link *)a)->next = h[i].next; + h[i].next = (struct gen_pool_link *)a; + break; + } + b = a ^ s; + q = &h[i]; + + while (q->next && q->next != (struct gen_pool_link *)b) + q = q->next; + + if (!q->next) { + ((struct gen_pool_link *)a)->next = h[i].next; + h[i].next = (struct gen_pool_link *)a; + break; + } + q->next = q->next->next; + a = a & b; + s <<= 1; + i++; + } + spin_unlock_irqrestore(&poolp->lock, flags); +} +EXPORT_SYMBOL(gen_pool_free); -- cgit v1.2.3-59-g8ed1b From 65ed0b337bd2b47097cf6c772f024772513b7b0d Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Tue, 21 Jun 2005 17:15:03 -0700 Subject: [PATCH] SN2 XPC build patches This patch contains the bits to make the XPC code use the uncached allocator rather than calling into the mspec driver. It also includes the mspec.h header which is required to build the XPC modules. Signed-off-by: Jes Sorensen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/Kconfig | 2 +- arch/ia64/sn/kernel/xpc_partition.c | 6 ++-- include/asm-ia64/sn/mspec.h | 59 +++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 include/asm-ia64/sn/mspec.h diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 295b5abee72f..34e603cc1716 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -227,7 +227,7 @@ config IA64_SGI_SN_SIM config IA64_SGI_SN_XP tristate "Support communication between SGI SSIs" - depends on MSPEC + select IA64_UNCACHED_ALLOCATOR help An SGI machine can be divided into multiple Single System Images which act independently of each other and have diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c index 2c3c4a8af553..cd7ed73f0e7a 100644 --- a/arch/ia64/sn/kernel/xpc_partition.c +++ b/arch/ia64/sn/kernel/xpc_partition.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -183,7 +184,7 @@ xpc_rsvd_page_init(void) * memory protections are never restricted. */ if ((amos_page = xpc_vars->amos_page) == NULL) { - amos_page = (AMO_t *) mspec_kalloc_page(0); + amos_page = (AMO_t *) TO_AMO(uncached_alloc_page(0)); if (amos_page == NULL) { dev_err(xpc_part, "can't allocate page of AMOs\n"); return NULL; @@ -200,7 +201,8 @@ xpc_rsvd_page_init(void) if (ret != 0) { dev_err(xpc_part, "can't change memory " "protections\n"); - mspec_kfree_page((unsigned long) amos_page); + uncached_free_page(__IA64_UNCACHED_OFFSET | + TO_PHYS((u64) amos_page)); return NULL; } } diff --git a/include/asm-ia64/sn/mspec.h b/include/asm-ia64/sn/mspec.h new file mode 100644 index 000000000000..dbe13c6121a8 --- /dev/null +++ b/include/asm-ia64/sn/mspec.h @@ -0,0 +1,59 @@ +/* + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 2001-2004 Silicon Graphics, Inc. All rights reserved. + */ + +#ifndef _ASM_IA64_SN_MSPEC_H +#define _ASM_IA64_SN_MSPEC_H + +#define FETCHOP_VAR_SIZE 64 /* 64 byte per fetchop variable */ + +#define FETCHOP_LOAD 0 +#define FETCHOP_INCREMENT 8 +#define FETCHOP_DECREMENT 16 +#define FETCHOP_CLEAR 24 + +#define FETCHOP_STORE 0 +#define FETCHOP_AND 24 +#define FETCHOP_OR 32 + +#define FETCHOP_CLEAR_CACHE 56 + +#define FETCHOP_LOAD_OP(addr, op) ( \ + *(volatile long *)((char*) (addr) + (op))) + +#define FETCHOP_STORE_OP(addr, op, x) ( \ + *(volatile long *)((char*) (addr) + (op)) = (long) (x)) + +#ifdef __KERNEL__ + +/* + * Each Atomic Memory Operation (AMO formerly known as fetchop) + * variable is 64 bytes long. The first 8 bytes are used. The + * remaining 56 bytes are unaddressable due to the operation taking + * that portion of the address. + * + * NOTE: The AMO_t _MUST_ be placed in either the first or second half + * of the cache line. The cache line _MUST NOT_ be used for anything + * other than additional AMO_t entries. This is because there are two + * addresses which reference the same physical cache line. One will + * be a cached entry with the memory type bits all set. This address + * may be loaded into processor cache. The AMO_t will be referenced + * uncached via the memory special memory type. If any portion of the + * cached cache-line is modified, when that line is flushed, it will + * overwrite the uncached value in physical memory and lead to + * inconsistency. + */ +typedef struct { + u64 variable; + u64 unused[7]; +} AMO_t; + + +#endif /* __KERNEL__ */ + +#endif /* _ASM_IA64_SN_MSPEC_H */ -- cgit v1.2.3-59-g8ed1b From 0edd73b33426df61b1d8a0a50d1f2ec097500abb Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Tue, 21 Jun 2005 17:15:04 -0700 Subject: [PATCH] shmem: restore superblock info To improve shmem scalability, we allowed tmpfs instances which don't need their blocks or inodes limited not to count them, and not to allocate any sbinfo. Which was okay when the only use for the sbinfo was accounting blocks and inodes; but since then a couple of unrelated projects extending tmpfs want to store other data in the sbinfo. Whether either extension reaches mainline is beside the point: I'm guilty of a bad design decision, and should restore sbinfo to make any such future extensions easier. So, once again allocate a shmem_sb_info for every shmem/tmpfs instance, and now let max_blocks 0 indicate unlimited blocks, and max_inodes 0 unlimited inodes. Brent Casavant verified (many months ago) that this does not perceptibly impact the scalability (since the unlimited sbinfo cacheline is repeatedly accessed but only once dirtied). And merge shmem_set_size into its sole caller shmem_remount_fs. Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/filesystems/tmpfs.txt | 6 +- mm/shmem.c | 143 ++++++++++++++++++------------------ 2 files changed, 73 insertions(+), 76 deletions(-) diff --git a/Documentation/filesystems/tmpfs.txt b/Documentation/filesystems/tmpfs.txt index 417e3095fe39..0d783c504ead 100644 --- a/Documentation/filesystems/tmpfs.txt +++ b/Documentation/filesystems/tmpfs.txt @@ -71,8 +71,8 @@ can be changed on remount. The size parameter also accepts a suffix % to limit this tmpfs instance to that percentage of your physical RAM: the default, when neither size nor nr_blocks is specified, is size=50% -If both nr_blocks (or size) and nr_inodes are set to 0, neither blocks -nor inodes will be limited in that instance. It is generally unwise to +If nr_blocks=0 (or size=0), blocks will not be limited in that instance; +if nr_inodes=0, inodes will not be limited. It is generally unwise to mount with such options, since it allows any user with write access to use up all the memory on the machine; but enhances the scalability of that instance in a system with many cpus making intensive use of it. @@ -97,4 +97,4 @@ RAM/SWAP in 10240 inodes and it is only accessible by root. Author: Christoph Rohland , 1.12.01 Updated: - Hugh Dickins , 01 September 2004 + Hugh Dickins , 13 March 2005 diff --git a/mm/shmem.c b/mm/shmem.c index 61574b81d979..e64fa726a790 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -6,8 +6,8 @@ * 2000-2001 Christoph Rohland * 2000-2001 SAP AG * 2002 Red Hat Inc. - * Copyright (C) 2002-2004 Hugh Dickins. - * Copyright (C) 2002-2004 VERITAS Software Corporation. + * Copyright (C) 2002-2005 Hugh Dickins. + * Copyright (C) 2002-2005 VERITAS Software Corporation. * Copyright (C) 2004 Andi Kleen, SuSE Labs * * Extended attribute support for tmpfs: @@ -194,7 +194,7 @@ static DEFINE_SPINLOCK(shmem_swaplist_lock); static void shmem_free_blocks(struct inode *inode, long pages) { struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); - if (sbinfo) { + if (sbinfo->max_blocks) { spin_lock(&sbinfo->stat_lock); sbinfo->free_blocks += pages; inode->i_blocks -= pages*BLOCKS_PER_PAGE; @@ -357,7 +357,7 @@ static swp_entry_t *shmem_swp_alloc(struct shmem_inode_info *info, unsigned long * page (and perhaps indirect index pages) yet to allocate: * a waste to allocate index if we cannot allocate data. */ - if (sbinfo) { + if (sbinfo->max_blocks) { spin_lock(&sbinfo->stat_lock); if (sbinfo->free_blocks <= 1) { spin_unlock(&sbinfo->stat_lock); @@ -677,8 +677,8 @@ static void shmem_delete_inode(struct inode *inode) spin_unlock(&shmem_swaplist_lock); } } - if (sbinfo) { - BUG_ON(inode->i_blocks); + BUG_ON(inode->i_blocks); + if (sbinfo->max_inodes) { spin_lock(&sbinfo->stat_lock); sbinfo->free_inodes++; spin_unlock(&sbinfo->stat_lock); @@ -1080,7 +1080,7 @@ repeat: } else { shmem_swp_unmap(entry); sbinfo = SHMEM_SB(inode->i_sb); - if (sbinfo) { + if (sbinfo->max_blocks) { spin_lock(&sbinfo->stat_lock); if (sbinfo->free_blocks == 0 || shmem_acct_block(info->flags)) { @@ -1269,7 +1269,7 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev) struct shmem_inode_info *info; struct shmem_sb_info *sbinfo = SHMEM_SB(sb); - if (sbinfo) { + if (sbinfo->max_inodes) { spin_lock(&sbinfo->stat_lock); if (!sbinfo->free_inodes) { spin_unlock(&sbinfo->stat_lock); @@ -1319,7 +1319,7 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev) mpol_shared_policy_init(&info->policy); break; } - } else if (sbinfo) { + } else if (sbinfo->max_inodes) { spin_lock(&sbinfo->stat_lock); sbinfo->free_inodes++; spin_unlock(&sbinfo->stat_lock); @@ -1328,31 +1328,6 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev) } #ifdef CONFIG_TMPFS - -static int shmem_set_size(struct shmem_sb_info *sbinfo, - unsigned long max_blocks, unsigned long max_inodes) -{ - int error; - unsigned long blocks, inodes; - - spin_lock(&sbinfo->stat_lock); - blocks = sbinfo->max_blocks - sbinfo->free_blocks; - inodes = sbinfo->max_inodes - sbinfo->free_inodes; - error = -EINVAL; - if (max_blocks < blocks) - goto out; - if (max_inodes < inodes) - goto out; - error = 0; - sbinfo->max_blocks = max_blocks; - sbinfo->free_blocks = max_blocks - blocks; - sbinfo->max_inodes = max_inodes; - sbinfo->free_inodes = max_inodes - inodes; -out: - spin_unlock(&sbinfo->stat_lock); - return error; -} - static struct inode_operations shmem_symlink_inode_operations; static struct inode_operations shmem_symlink_inline_operations; @@ -1607,15 +1582,17 @@ static int shmem_statfs(struct super_block *sb, struct kstatfs *buf) buf->f_type = TMPFS_MAGIC; buf->f_bsize = PAGE_CACHE_SIZE; buf->f_namelen = NAME_MAX; - if (sbinfo) { - spin_lock(&sbinfo->stat_lock); + spin_lock(&sbinfo->stat_lock); + if (sbinfo->max_blocks) { buf->f_blocks = sbinfo->max_blocks; buf->f_bavail = buf->f_bfree = sbinfo->free_blocks; + } + if (sbinfo->max_inodes) { buf->f_files = sbinfo->max_inodes; buf->f_ffree = sbinfo->free_inodes; - spin_unlock(&sbinfo->stat_lock); } /* else leave those fields 0 like simple_statfs */ + spin_unlock(&sbinfo->stat_lock); return 0; } @@ -1672,7 +1649,7 @@ static int shmem_link(struct dentry *old_dentry, struct inode *dir, struct dentr * but each new link needs a new dentry, pinning lowmem, and * tmpfs dentries cannot be pruned until they are unlinked. */ - if (sbinfo) { + if (sbinfo->max_inodes) { spin_lock(&sbinfo->stat_lock); if (!sbinfo->free_inodes) { spin_unlock(&sbinfo->stat_lock); @@ -1697,7 +1674,7 @@ static int shmem_unlink(struct inode *dir, struct dentry *dentry) if (inode->i_nlink > 1 && !S_ISDIR(inode->i_mode)) { struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); - if (sbinfo) { + if (sbinfo->max_inodes) { spin_lock(&sbinfo->stat_lock); sbinfo->free_inodes++; spin_unlock(&sbinfo->stat_lock); @@ -1921,22 +1898,42 @@ bad_val: static int shmem_remount_fs(struct super_block *sb, int *flags, char *data) { struct shmem_sb_info *sbinfo = SHMEM_SB(sb); - unsigned long max_blocks = 0; - unsigned long max_inodes = 0; + unsigned long max_blocks = sbinfo->max_blocks; + unsigned long max_inodes = sbinfo->max_inodes; + unsigned long blocks; + unsigned long inodes; + int error = -EINVAL; + + if (shmem_parse_options(data, NULL, NULL, NULL, + &max_blocks, &max_inodes)) + return error; - if (sbinfo) { - max_blocks = sbinfo->max_blocks; - max_inodes = sbinfo->max_inodes; - } - if (shmem_parse_options(data, NULL, NULL, NULL, &max_blocks, &max_inodes)) - return -EINVAL; - /* Keep it simple: disallow limited <-> unlimited remount */ - if ((max_blocks || max_inodes) == !sbinfo) - return -EINVAL; - /* But allow the pointless unlimited -> unlimited remount */ - if (!sbinfo) - return 0; - return shmem_set_size(sbinfo, max_blocks, max_inodes); + spin_lock(&sbinfo->stat_lock); + blocks = sbinfo->max_blocks - sbinfo->free_blocks; + inodes = sbinfo->max_inodes - sbinfo->free_inodes; + if (max_blocks < blocks) + goto out; + if (max_inodes < inodes) + goto out; + /* + * Those tests also disallow limited->unlimited while any are in + * use, so i_blocks will always be zero when max_blocks is zero; + * but we must separately disallow unlimited->limited, because + * in that case we have no record of how much is already in use. + */ + if (max_blocks && !sbinfo->max_blocks) + goto out; + if (max_inodes && !sbinfo->max_inodes) + goto out; + + error = 0; + sbinfo->max_blocks = max_blocks; + sbinfo->free_blocks = max_blocks - blocks; + sbinfo->max_inodes = max_inodes; + sbinfo->free_inodes = max_inodes - inodes; +out: + spin_unlock(&sbinfo->stat_lock); + return error; } #endif @@ -1961,11 +1958,11 @@ static int shmem_fill_super(struct super_block *sb, uid_t uid = current->fsuid; gid_t gid = current->fsgid; int err = -ENOMEM; - -#ifdef CONFIG_TMPFS + struct shmem_sb_info *sbinfo; unsigned long blocks = 0; unsigned long inodes = 0; +#ifdef CONFIG_TMPFS /* * Per default we only allow half of the physical ram per * tmpfs instance, limiting inodes to one per page of lowmem; @@ -1976,34 +1973,34 @@ static int shmem_fill_super(struct super_block *sb, inodes = totalram_pages - totalhigh_pages; if (inodes > blocks) inodes = blocks; - - if (shmem_parse_options(data, &mode, - &uid, &gid, &blocks, &inodes)) + if (shmem_parse_options(data, &mode, &uid, &gid, + &blocks, &inodes)) return -EINVAL; } - - if (blocks || inodes) { - struct shmem_sb_info *sbinfo; - sbinfo = kmalloc(sizeof(struct shmem_sb_info), GFP_KERNEL); - if (!sbinfo) - return -ENOMEM; - sb->s_fs_info = sbinfo; - spin_lock_init(&sbinfo->stat_lock); - sbinfo->max_blocks = blocks; - sbinfo->free_blocks = blocks; - sbinfo->max_inodes = inodes; - sbinfo->free_inodes = inodes; - } - sb->s_xattr = shmem_xattr_handlers; #else sb->s_flags |= MS_NOUSER; #endif + /* Round up to L1_CACHE_BYTES to resist false sharing */ + sbinfo = kmalloc(max((int)sizeof(struct shmem_sb_info), + L1_CACHE_BYTES), GFP_KERNEL); + if (!sbinfo) + return -ENOMEM; + + spin_lock_init(&sbinfo->stat_lock); + sbinfo->max_blocks = blocks; + sbinfo->free_blocks = blocks; + sbinfo->max_inodes = inodes; + sbinfo->free_inodes = inodes; + + sb->s_fs_info = sbinfo; sb->s_maxbytes = SHMEM_MAX_BYTES; sb->s_blocksize = PAGE_CACHE_SIZE; sb->s_blocksize_bits = PAGE_CACHE_SHIFT; sb->s_magic = TMPFS_MAGIC; sb->s_op = &shmem_ops; + sb->s_xattr = shmem_xattr_handlers; + inode = shmem_get_inode(sb, S_IFDIR | mode, 0); if (!inode) goto failed; -- cgit v1.2.3-59-g8ed1b From 400e65146c428d2ef677a927786fda2cec545a76 Mon Sep 17 00:00:00 2001 From: Bob Picco Date: Tue, 21 Jun 2005 17:15:05 -0700 Subject: [PATCH] ia64: pfn_to_nid() implementation pfn_to_nid is undefined. We haven't had this interface on ia64. The sys_mbind patches need it. Oh, the paddr_to_nid call could fail when DISCONTIG+NUMA is configured because there isn't any ACPI SRAT NUMA information. Signed-off-by: Bob Picco Acked-by: Tony Luck Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-ia64/mmzone.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/asm-ia64/mmzone.h b/include/asm-ia64/mmzone.h index 9491dacc89cf..83ca4043fc11 100644 --- a/include/asm-ia64/mmzone.h +++ b/include/asm-ia64/mmzone.h @@ -15,6 +15,20 @@ #include #include +static inline int pfn_to_nid(unsigned long pfn) +{ +#ifdef CONFIG_NUMA + extern int paddr_to_nid(unsigned long); + int nid = paddr_to_nid(pfn << PAGE_SHIFT); + if (nid < 0) + return 0; + else + return nid; +#else + return 0; +#endif +} + #ifdef CONFIG_DISCONTIGMEM #ifdef CONFIG_IA64_DIG /* DIG systems are small */ -- cgit v1.2.3-59-g8ed1b From 941150a326be88af245034ef4b3e9fa00229aa2d Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Tue, 21 Jun 2005 17:15:06 -0700 Subject: [PATCH] mbind: fix verify_pages pte_page Strict mbind's check that pages already mapped are on right node has been using pte_page without checking if pfn_valid, and without page_table_lock to prevent spurious failures when try_to_unmap_one intervenes between the pte_present and the pte_page. Signed-off-by: Hugh Dickins Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/mempolicy.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 39252c732db2..c512cc911e22 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -242,6 +242,9 @@ static int verify_pages(struct mm_struct *mm, unsigned long addr, unsigned long end, unsigned long *nodes) { + int err = 0; + + spin_lock(&mm->page_table_lock); while (addr < end) { struct page *p; pte_t *pte; @@ -268,17 +271,23 @@ verify_pages(struct mm_struct *mm, } p = NULL; pte = pte_offset_map(pmd, addr); - if (pte_present(*pte)) - p = pte_page(*pte); + if (pte_present(*pte)) { + unsigned long pfn = pte_pfn(*pte); + if (pfn_valid(pfn)) + p = pfn_to_page(pfn); + } pte_unmap(pte); if (p) { unsigned nid = page_to_nid(p); - if (!test_bit(nid, nodes)) - return -EIO; + if (!test_bit(nid, nodes)) { + err = -EIO; + break; + } } addr += PAGE_SIZE; } - return 0; + spin_unlock(&mm->page_table_lock); + return err; } /* Step 1: check the range */ -- cgit v1.2.3-59-g8ed1b From 91612e0df20a52f61db3cac280c153311b36df7a Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Tue, 21 Jun 2005 17:15:07 -0700 Subject: [PATCH] mbind: check_range use standard ptwalk Strict mbind's check for currently mapped pages being on node has been using a slow loop which re-evaluates pgd, pud, pmd, pte for each entry: replace that by a standard four-level page table walk like others in mm. Since mmap_sem is held for writing, page_table_lock can be taken at the inner level to limit latency. Signed-off-by: Hugh Dickins Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/mempolicy.c | 115 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 70 insertions(+), 45 deletions(-) diff --git a/mm/mempolicy.c b/mm/mempolicy.c index c512cc911e22..cb41c31e7c87 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -238,56 +238,81 @@ static struct mempolicy *mpol_new(int mode, unsigned long *nodes) } /* Ensure all existing pages follow the policy. */ -static int -verify_pages(struct mm_struct *mm, - unsigned long addr, unsigned long end, unsigned long *nodes) +static int check_pte_range(struct mm_struct *mm, pmd_t *pmd, + unsigned long addr, unsigned long end, unsigned long *nodes) { - int err = 0; + pte_t *orig_pte; + pte_t *pte; spin_lock(&mm->page_table_lock); - while (addr < end) { - struct page *p; - pte_t *pte; - pmd_t *pmd; - pud_t *pud; - pgd_t *pgd; - pgd = pgd_offset(mm, addr); - if (pgd_none(*pgd)) { - unsigned long next = (addr + PGDIR_SIZE) & PGDIR_MASK; - if (next > addr) - break; - addr = next; - continue; - } - pud = pud_offset(pgd, addr); - if (pud_none(*pud)) { - addr = (addr + PUD_SIZE) & PUD_MASK; + orig_pte = pte = pte_offset_map(pmd, addr); + do { + unsigned long pfn; + unsigned int nid; + + if (!pte_present(*pte)) continue; - } - pmd = pmd_offset(pud, addr); - if (pmd_none(*pmd)) { - addr = (addr + PMD_SIZE) & PMD_MASK; + pfn = pte_pfn(*pte); + if (!pfn_valid(pfn)) continue; - } - p = NULL; - pte = pte_offset_map(pmd, addr); - if (pte_present(*pte)) { - unsigned long pfn = pte_pfn(*pte); - if (pfn_valid(pfn)) - p = pfn_to_page(pfn); - } - pte_unmap(pte); - if (p) { - unsigned nid = page_to_nid(p); - if (!test_bit(nid, nodes)) { - err = -EIO; - break; - } - } - addr += PAGE_SIZE; - } + nid = pfn_to_nid(pfn); + if (!test_bit(nid, nodes)) + break; + } while (pte++, addr += PAGE_SIZE, addr != end); + pte_unmap(orig_pte); spin_unlock(&mm->page_table_lock); - return err; + return addr != end; +} + +static inline int check_pmd_range(struct mm_struct *mm, pud_t *pud, + unsigned long addr, unsigned long end, unsigned long *nodes) +{ + pmd_t *pmd; + unsigned long next; + + pmd = pmd_offset(pud, addr); + do { + next = pmd_addr_end(addr, end); + if (pmd_none_or_clear_bad(pmd)) + continue; + if (check_pte_range(mm, pmd, addr, next, nodes)) + return -EIO; + } while (pmd++, addr = next, addr != end); + return 0; +} + +static inline int check_pud_range(struct mm_struct *mm, pgd_t *pgd, + unsigned long addr, unsigned long end, unsigned long *nodes) +{ + pud_t *pud; + unsigned long next; + + pud = pud_offset(pgd, addr); + do { + next = pud_addr_end(addr, end); + if (pud_none_or_clear_bad(pud)) + continue; + if (check_pmd_range(mm, pud, addr, next, nodes)) + return -EIO; + } while (pud++, addr = next, addr != end); + return 0; +} + +static inline int check_pgd_range(struct mm_struct *mm, + unsigned long addr, unsigned long end, unsigned long *nodes) +{ + pgd_t *pgd; + unsigned long next; + + pgd = pgd_offset(mm, addr); + do { + next = pgd_addr_end(addr, end); + if (pgd_none_or_clear_bad(pgd)) + continue; + if (check_pud_range(mm, pgd, addr, next, nodes)) + return -EIO; + } while (pgd++, addr = next, addr != end); + return 0; } /* Step 1: check the range */ @@ -308,7 +333,7 @@ check_range(struct mm_struct *mm, unsigned long start, unsigned long end, if (prev && prev->vm_end < vma->vm_start) return ERR_PTR(-EFAULT); if ((flags & MPOL_MF_STRICT) && !is_vm_hugetlb_page(vma)) { - err = verify_pages(vma->vm_mm, + err = check_pgd_range(vma->vm_mm, vma->vm_start, vma->vm_end, nodes); if (err) { first = ERR_PTR(err); -- cgit v1.2.3-59-g8ed1b From 45918e1a8bfcabc1cb4570b8df276655020eac45 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Tue, 21 Jun 2005 17:15:08 -0700 Subject: [PATCH] dup_mmap: update comment on new vma Remove part of comment on linking new vma in dup_mmap: since anon_vma rmap came in, try_to_unmap_one knows the vma without needing find_vma. But add a comment to note that here vma is inserted without mmap_sem. Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/fork.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kernel/fork.c b/kernel/fork.c index 876b31cd822d..a28d11e10877 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -250,8 +250,9 @@ static inline int dup_mmap(struct mm_struct * mm, struct mm_struct * oldmm) /* * Link in the new vma and copy the page table entries: - * link in first so that swapoff can see swap entries, - * and try_to_unmap_one's find_vma find the new vma. + * link in first so that swapoff can see swap entries. + * Note that, exceptionally, here the vma is inserted + * without holding mm->mmap_sem. */ spin_lock(&mm->page_table_lock); *pprev = tmp; -- cgit v1.2.3-59-g8ed1b From 334795eca421287c41c257992027d29659dc0f97 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Tue, 21 Jun 2005 17:15:08 -0700 Subject: [PATCH] bad_page: clear reclaim and slab Since free_pages_check complains if PG_reclaim or PG_slab is set, bad_page ought to clear them to avoid repetitive reports (Nikita noticed this too). Let prep_new_page check page_count and PG_slab as free_pages_check does. Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_alloc.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 418102a02921..62b950901d6f 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -105,11 +105,13 @@ static void bad_page(const char *function, struct page *page) printk(KERN_EMERG "Backtrace:\n"); dump_stack(); printk(KERN_EMERG "Trying to fix it up, but a reboot is needed\n"); - page->flags &= ~(1 << PG_private | + page->flags &= ~(1 << PG_lru | + 1 << PG_private | 1 << PG_locked | - 1 << PG_lru | 1 << PG_active | 1 << PG_dirty | + 1 << PG_reclaim | + 1 << PG_slab | 1 << PG_swapcache | 1 << PG_writeback); set_page_count(page, 0); @@ -440,14 +442,17 @@ void set_page_refs(struct page *page, int order) */ static void prep_new_page(struct page *page, int order) { - if (page->mapping || page_mapcount(page) || - (page->flags & ( + if ( page_mapcount(page) || + page->mapping != NULL || + page_count(page) != 0 || + (page->flags & ( + 1 << PG_lru | 1 << PG_private | 1 << PG_locked | - 1 << PG_lru | 1 << PG_active | 1 << PG_dirty | 1 << PG_reclaim | + 1 << PG_slab | 1 << PG_swapcache | 1 << PG_writeback ))) bad_page(__FUNCTION__, page); -- cgit v1.2.3-59-g8ed1b From 7c2f3fda5666c280bcd00ac3b86963270b23e796 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Tue, 21 Jun 2005 17:15:09 -0700 Subject: [PATCH] rme96xx: fix PageReserved range rme96xx busmaster_malloc miscalculates and fails to set PageReserved on any page of char *buf; but busmaster_free does it right, so do the same (I don't have the card, just noticed this while sifting for rmap BUGs). Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- sound/oss/rme96xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c index 76774bbc1436..b4278eecc917 100644 --- a/sound/oss/rme96xx.c +++ b/sound/oss/rme96xx.c @@ -807,7 +807,7 @@ static void* busmaster_malloc(int size) { struct page* page, *last_page; page = virt_to_page(buf); - last_page = virt_to_page(buf + (1 << pg)); + last_page = page + (1 << pg); DBG(printk("setting reserved bit\n")); while (page < last_page) { SetPageReserved(page); -- cgit v1.2.3-59-g8ed1b From 08ef472937e918875a82fd350d3de138aac50414 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Tue, 21 Jun 2005 17:15:10 -0700 Subject: [PATCH] get_user_pages: kill get_page_map Since its birth, get_user_pages has been calling a misguided get_page_map function. follow_page has already returned NULL if the pfn is invalid, we cannot reach an invalid pfn from a validated struct page. Remove get_page_map, and the messy rewind in get_user_pages to cope with its failure. Oh, and could we please call that "struct page *page" like everywhere else, instead of "struct page *map"? Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memory.c | 45 ++++++++++----------------------------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/mm/memory.c b/mm/memory.c index d209f745db7f..b8846cf2358a 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -840,23 +840,8 @@ check_user_page_readable(struct mm_struct *mm, unsigned long address) { return __follow_page(mm, address, /*read*/1, /*write*/0) != NULL; } - EXPORT_SYMBOL(check_user_page_readable); -/* - * Given a physical address, is there a useful struct page pointing to - * it? This may become more complex in the future if we start dealing - * with IO-aperture pages for direct-IO. - */ - -static inline struct page *get_page_map(struct page *page) -{ - if (!pfn_valid(page_to_pfn(page))) - return NULL; - return page; -} - - static inline int untouched_anonymous_page(struct mm_struct* mm, struct vm_area_struct *vma, unsigned long address) @@ -887,7 +872,6 @@ untouched_anonymous_page(struct mm_struct* mm, struct vm_area_struct *vma, return 0; } - int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, int len, int write, int force, struct page **pages, struct vm_area_struct **vmas) @@ -951,21 +935,21 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, } spin_lock(&mm->page_table_lock); do { - struct page *map; + struct page *page; int lookup_write = write; cond_resched_lock(&mm->page_table_lock); - while (!(map = follow_page(mm, start, lookup_write))) { + while (!(page = follow_page(mm, start, lookup_write))) { /* * Shortcut for anonymous pages. We don't want * to force the creation of pages tables for - * insanly big anonymously mapped areas that + * insanely big anonymously mapped areas that * nobody touched so far. This is important * for doing a core dump for these mappings. */ if (!lookup_write && untouched_anonymous_page(mm,vma,start)) { - map = ZERO_PAGE(start); + page = ZERO_PAGE(start); break; } spin_unlock(&mm->page_table_lock); @@ -994,30 +978,21 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, spin_lock(&mm->page_table_lock); } if (pages) { - pages[i] = get_page_map(map); - if (!pages[i]) { - spin_unlock(&mm->page_table_lock); - while (i--) - page_cache_release(pages[i]); - i = -EFAULT; - goto out; - } - flush_dcache_page(pages[i]); - if (!PageReserved(pages[i])) - page_cache_get(pages[i]); + pages[i] = page; + flush_dcache_page(page); + if (!PageReserved(page)) + page_cache_get(page); } if (vmas) vmas[i] = vma; i++; start += PAGE_SIZE; len--; - } while(len && start < vma->vm_end); + } while (len && start < vma->vm_end); spin_unlock(&mm->page_table_lock); - } while(len); -out: + } while (len); return i; } - EXPORT_SYMBOL(get_user_pages); static int zeromap_pte_range(struct mm_struct *mm, pmd_t *pmd, -- cgit v1.2.3-59-g8ed1b From d296e9cd02c92e576ecce5344026a4df4353cdb2 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Tue, 21 Jun 2005 17:15:11 -0700 Subject: [PATCH] do_wp_page: cannot share file page A small optimization to do_wp_page's check for whether to avoid copy by reusing the page already mapped. It can never share a cached file page, nor can it share a reserved page (often the empty zero page), so it's a waste of time to lock and unlock in those cases. Which nowadays can both be neatly excluded by a preliminary PageAnon test. Christoph has reported that a preliminary page_count test proved valuable for scalability here, but PageAnon covers more common cases all at once. Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/memory.c b/mm/memory.c index b8846cf2358a..1c0a3db78a05 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1239,7 +1239,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma, } old_page = pfn_to_page(pfn); - if (!TestSetPageLocked(old_page)) { + if (PageAnon(old_page) && !TestSetPageLocked(old_page)) { int reuse = can_share_swap_page(old_page); unlock_page(old_page); if (reuse) { -- cgit v1.2.3-59-g8ed1b From c475a8ab625d567eacf5e30ec35d6d8704558062 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Tue, 21 Jun 2005 17:15:12 -0700 Subject: [PATCH] can_share_swap_page: use page_mapcount Remember that ironic get_user_pages race? when the raised page_count on a page swapped out led do_wp_page to decide that it had to copy on write, so substituted a different page into userspace. 2.6.7 onwards have Andrea's solution, where try_to_unmap_one backs out if it finds page_count raised. Which works, but is unsatisfying (rmap.c has no other page_count heuristics), and was found a few months ago to hang an intensive page migration test. A year ago I was hesitant to engage page_mapcount, now it seems the right fix. So remove the page_count hack from try_to_unmap_one; and use activate_page in unuse_mm when dropping lock, to replace its secondary effect of helping swapoff to make progress in that case. Simplify can_share_swap_page (now called only on anonymous pages) to check page_mapcount + page_swapcount == 1: still needs the page lock to stabilize their (pessimistic) sum, but does not need swapper_space.tree_lock for that. In do_swap_page, move swap_free and unlock_page below page_add_anon_rmap, to keep sum on the high side, and correct when can_share_swap_page called. Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memory.c | 10 +++++----- mm/rmap.c | 21 --------------------- mm/swapfile.c | 55 ++++++++++++++++--------------------------------------- 3 files changed, 21 insertions(+), 65 deletions(-) diff --git a/mm/memory.c b/mm/memory.c index 1c0a3db78a05..da91b7bf9986 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1686,10 +1686,6 @@ static int do_swap_page(struct mm_struct * mm, } /* The page isn't present yet, go ahead with the fault. */ - - swap_free(entry); - if (vm_swap_full()) - remove_exclusive_swap_page(page); inc_mm_counter(mm, rss); pte = mk_pte(page, vma->vm_page_prot); @@ -1697,12 +1693,16 @@ static int do_swap_page(struct mm_struct * mm, pte = maybe_mkwrite(pte_mkdirty(pte), vma); write_access = 0; } - unlock_page(page); flush_icache_page(vma, page); set_pte_at(mm, address, page_table, pte); page_add_anon_rmap(page, vma, address); + swap_free(entry); + if (vm_swap_full()) + remove_exclusive_swap_page(page); + unlock_page(page); + if (write_access) { if (do_wp_page(mm, vma, address, page_table, pmd, pte) == VM_FAULT_OOM) diff --git a/mm/rmap.c b/mm/rmap.c index 9827409eb7c7..89770bd25f31 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -539,27 +539,6 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma) goto out_unmap; } - /* - * Don't pull an anonymous page out from under get_user_pages. - * GUP carefully breaks COW and raises page count (while holding - * page_table_lock, as we have here) to make sure that the page - * cannot be freed. If we unmap that page here, a user write - * access to the virtual address will bring back the page, but - * its raised count will (ironically) be taken to mean it's not - * an exclusive swap page, do_wp_page will replace it by a copy - * page, and the user never get to see the data GUP was holding - * the original page for. - * - * This test is also useful for when swapoff (unuse_process) has - * to drop page lock: its reference to the page stops existing - * ptes from being unmapped, so swapoff can make progress. - */ - if (PageSwapCache(page) && - page_count(page) != page_mapcount(page) + 2) { - ret = SWAP_FAIL; - goto out_unmap; - } - /* Nuke the page table entry. */ flush_cache_page(vma, address, page_to_pfn(page)); pteval = ptep_clear_flush(vma, address, pte); diff --git a/mm/swapfile.c b/mm/swapfile.c index da48405cd9a3..60cd24a55204 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -276,61 +276,37 @@ void swap_free(swp_entry_t entry) } /* - * Check if we're the only user of a swap page, - * when the page is locked. + * How many references to page are currently swapped out? */ -static int exclusive_swap_page(struct page *page) +static inline int page_swapcount(struct page *page) { - int retval = 0; - struct swap_info_struct * p; + int count = 0; + struct swap_info_struct *p; swp_entry_t entry; entry.val = page->private; p = swap_info_get(entry); if (p) { - /* Is the only swap cache user the cache itself? */ - if (p->swap_map[swp_offset(entry)] == 1) { - /* Recheck the page count with the swapcache lock held.. */ - write_lock_irq(&swapper_space.tree_lock); - if (page_count(page) == 2) - retval = 1; - write_unlock_irq(&swapper_space.tree_lock); - } + /* Subtract the 1 for the swap cache itself */ + count = p->swap_map[swp_offset(entry)] - 1; swap_info_put(p); } - return retval; + return count; } /* * We can use this swap cache entry directly * if there are no other references to it. - * - * Here "exclusive_swap_page()" does the real - * work, but we opportunistically check whether - * we need to get all the locks first.. */ int can_share_swap_page(struct page *page) { - int retval = 0; + int count; - if (!PageLocked(page)) - BUG(); - switch (page_count(page)) { - case 3: - if (!PagePrivate(page)) - break; - /* Fallthrough */ - case 2: - if (!PageSwapCache(page)) - break; - retval = exclusive_swap_page(page); - break; - case 1: - if (PageReserved(page)) - break; - retval = 1; - } - return retval; + BUG_ON(!PageLocked(page)); + count = page_mapcount(page); + if (count <= 1 && PageSwapCache(page)) + count += page_swapcount(page); + return count == 1; } /* @@ -529,9 +505,10 @@ static int unuse_mm(struct mm_struct *mm, if (!down_read_trylock(&mm->mmap_sem)) { /* - * Our reference to the page stops try_to_unmap_one from - * unmapping its ptes, so swapoff can make progress. + * Activate page so shrink_cache is unlikely to unmap its + * ptes while lock is dropped, so swapoff can make progress. */ + activate_page(page); unlock_page(page); down_read(&mm->mmap_sem); lock_page(page); -- cgit v1.2.3-59-g8ed1b From b4955ce3dd0818b56da532a16c9a4a3804a558ee Mon Sep 17 00:00:00 2001 From: Abhijit Karmarkar Date: Tue, 21 Jun 2005 17:15:13 -0700 Subject: [PATCH] msync: check pte dirty earlier It's common practice to msync a large address range regularly, in which often only a few ptes have actually been dirtied since the previous pass. sync_pte_range then goes much faster if it tests whether pte is dirty before locating and accessing each struct page cacheline; and it is hardly slowed by ptep_clear_flush_dirty repeating that test in the opposite case, when every pte actually is dirty. But beware, s390's pte_dirty always says false, since its dirty bit is kept in the storage key, located via the struct page address. So skip this optimization in its case: use a pte_maybe_dirty macro which just says true if page_test_and_clear_dirty is implemented. Signed-off-by: Abhijit Karmarkar Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-generic/pgtable.h | 3 +++ mm/msync.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 1f4ec7b70270..f40593565173 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h @@ -125,6 +125,9 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres #ifndef __HAVE_ARCH_PAGE_TEST_AND_CLEAR_DIRTY #define page_test_and_clear_dirty(page) (0) +#define pte_maybe_dirty(pte) pte_dirty(pte) +#else +#define pte_maybe_dirty(pte) (1) #endif #ifndef __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG diff --git a/mm/msync.c b/mm/msync.c index 090f426bca7d..d0f5a1bce7cb 100644 --- a/mm/msync.c +++ b/mm/msync.c @@ -34,6 +34,8 @@ static void sync_pte_range(struct vm_area_struct *vma, pmd_t *pmd, if (!pte_present(*pte)) continue; + if (!pte_maybe_dirty(*pte)) + continue; pfn = pte_pfn(*pte); if (!pfn_valid(pfn)) continue; -- cgit v1.2.3-59-g8ed1b From c0d62219a48bd91ec40fb254c930914dccc77ff1 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Tue, 21 Jun 2005 17:15:14 -0700 Subject: [PATCH] Kill stray newline OOM killer prints a stray newline. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 62b950901d6f..206920796f5f 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1314,7 +1314,7 @@ void show_free_areas(void) get_page_state(&ps); get_zone_counts(&active, &inactive, &free); - printk("\nFree pages: %11ukB (%ukB HighMem)\n", + printk("Free pages: %11ukB (%ukB HighMem)\n", K(nr_free_pages()), K(nr_free_highpages())); -- cgit v1.2.3-59-g8ed1b From 0f667ff5c0282f686b4f739e46353779b3cfa2f6 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 21 Jun 2005 17:15:14 -0700 Subject: [PATCH] 3c59x: remove superfluous vortex_debug test from boomerang_start_xmit() Remove the superfluous test of "if (vortex_debug > 3)" inside the "if (vortex_debug > 6)" clause early in boomerang_start_xmit. Signed-off-by: John W. Linville Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/net/3c59x.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index b5e076043431..80ec9aa575bb 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -2202,9 +2202,8 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev) if (vortex_debug > 6) { printk(KERN_DEBUG "boomerang_start_xmit()\n"); - if (vortex_debug > 3) - printk(KERN_DEBUG "%s: Trying to send a packet, Tx index %d.\n", - dev->name, vp->cur_tx); + printk(KERN_DEBUG "%s: Trying to send a packet, Tx index %d.\n", + dev->name, vp->cur_tx); } if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) { -- cgit v1.2.3-59-g8ed1b From 2894801db1cea527885f7a8679e5a88fb7377d9c Mon Sep 17 00:00:00 2001 From: Coywolf Qi Hunt Date: Tue, 21 Jun 2005 17:15:15 -0700 Subject: [PATCH] kbuild: display compile version I am always trying to make sure I've booted the right kernel after a new install. Too paranoid maybe. But I guess there're other people like me. So let's make kbuild display the compile version number at the end to give us a hint. I know we may be booting vmlinux someday, but don't care about it for now. Signed-off-by: Coywolf Qi Hunt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/boot/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile index aa7064a75ee6..43cd6220ee49 100644 --- a/arch/i386/boot/Makefile +++ b/arch/i386/boot/Makefile @@ -48,7 +48,7 @@ cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \ $(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \ $(obj)/vmlinux.bin $(obj)/tools/build FORCE $(call if_changed,image) - @echo 'Kernel: $@ is ready' + @echo 'Kernel: $@ is ready' ' (#'`cat .version`')' $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE $(call if_changed,objcopy) -- cgit v1.2.3-59-g8ed1b From 8680e22f296e75e5497edb660c59c6b4dcfbbd32 Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Tue, 21 Jun 2005 17:15:16 -0700 Subject: [PATCH] VFS: memory leak in do_kern_mount() There is a memory leak during mount when CONFIG_SECURITY is enabled and mount options are specified. Signed-off-by: Gerald Schaefer Acked-by: James Morris Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/super.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/super.c b/fs/super.c index 3a1b8ca04ba6..573bcc81bb82 100644 --- a/fs/super.c +++ b/fs/super.c @@ -835,6 +835,7 @@ do_kern_mount(const char *fstype, int flags, const char *name, void *data) mnt->mnt_parent = mnt; mnt->mnt_namespace = current->namespace; up_write(&sb->s_umount); + free_secdata(secdata); put_filesystem(type); return mnt; out_sb: -- cgit v1.2.3-59-g8ed1b From da3caa204ca40c32dcb751ebead2a6835b83e8d1 Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Tue, 21 Jun 2005 17:15:18 -0700 Subject: [PATCH] SELinux: memory leak in selinux_sb_copy_data() There is a memory leak during mount when SELinux is active and mount options are specified. Signed-off-by: Gerald Schaefer Acked-by: Stephen Smalley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/selinux/hooks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index db845cbd5841..87302a49067b 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1945,6 +1945,7 @@ static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void } while (*in_end++); copy_page(in_save, nosec_save); + free_page((unsigned long)nosec_save); out: return rc; } -- cgit v1.2.3-59-g8ed1b From 5b37b700f7c491a9320f4e29472bbaf23dded8fd Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 21 Jun 2005 17:15:18 -0700 Subject: [PATCH] ppc32: Added support for new MPC8548 family of PowerQUICC III processors Added descriptions of the new MPC8548 family processors, e500 core and peripherals. Signed-off-by: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/kernel/cputable.c | 14 +++ arch/ppc/syslib/mpc85xx_devices.c | 185 ++++++++++++++++++++++++++++++++++++++ arch/ppc/syslib/mpc85xx_sys.c | 105 ++++++++++++++++++++++ include/asm-ppc/irq.h | 6 ++ include/asm-ppc/mpc85xx.h | 7 +- include/linux/fsl_devices.h | 8 +- 6 files changed, 323 insertions(+), 2 deletions(-) diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c index d44b7dc5390a..01c226008dbf 100644 --- a/arch/ppc/kernel/cputable.c +++ b/arch/ppc/kernel/cputable.c @@ -918,6 +918,20 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 32, .num_pmcs = 4, }, + { /* e500v2 */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x80210000, + .cpu_name = "e500v2", + /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_BIG_PHYS, + .cpu_user_features = PPC_FEATURE_32 | + PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP | + PPC_FEATURE_HAS_EFP_SINGLE | PPC_FEATURE_HAS_EFP_DOUBLE, + .icache_bsize = 32, + .dcache_bsize = 32, + .num_pmcs = 4, + }, #endif #if !CLASSIC_PPC { /* default match */ diff --git a/arch/ppc/syslib/mpc85xx_devices.c b/arch/ppc/syslib/mpc85xx_devices.c index 1e658ef57e75..b30c57d4518f 100644 --- a/arch/ppc/syslib/mpc85xx_devices.c +++ b/arch/ppc/syslib/mpc85xx_devices.c @@ -40,6 +40,42 @@ static struct gianfar_platform_data mpc85xx_tsec2_pdata = { .phy_reg_addr = MPC85xx_ENET1_OFFSET, }; +static struct gianfar_platform_data mpc85xx_etsec1_pdata = { + .device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT | + FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON | + FSL_GIANFAR_DEV_HAS_MULTI_INTR | + FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN | + FSL_GIANFAR_DEV_HAS_EXTENDED_HASH, + .phy_reg_addr = MPC85xx_ENET1_OFFSET, +}; + +static struct gianfar_platform_data mpc85xx_etsec2_pdata = { + .device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT | + FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON | + FSL_GIANFAR_DEV_HAS_MULTI_INTR | + FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN | + FSL_GIANFAR_DEV_HAS_EXTENDED_HASH, + .phy_reg_addr = MPC85xx_ENET1_OFFSET, +}; + +static struct gianfar_platform_data mpc85xx_etsec3_pdata = { + .device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT | + FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON | + FSL_GIANFAR_DEV_HAS_MULTI_INTR | + FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN | + FSL_GIANFAR_DEV_HAS_EXTENDED_HASH, + .phy_reg_addr = MPC85xx_ENET1_OFFSET, +}; + +static struct gianfar_platform_data mpc85xx_etsec4_pdata = { + .device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT | + FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON | + FSL_GIANFAR_DEV_HAS_MULTI_INTR | + FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN | + FSL_GIANFAR_DEV_HAS_EXTENDED_HASH, + .phy_reg_addr = MPC85xx_ENET1_OFFSET, +}; + static struct gianfar_platform_data mpc85xx_fec_pdata = { .phy_reg_addr = MPC85xx_ENET1_OFFSET, }; @@ -48,6 +84,10 @@ static struct fsl_i2c_platform_data mpc85xx_fsl_i2c_pdata = { .device_flags = FSL_I2C_DEV_SEPARATE_DFSRR, }; +static struct fsl_i2c_platform_data mpc85xx_fsl_i2c2_pdata = { + .device_flags = FSL_I2C_DEV_SEPARATE_DFSRR, +}; + static struct plat_serial8250_port serial_platform_data[] = { [0] = { .mapbase = 0x4500, @@ -536,6 +576,151 @@ struct platform_device ppc_sys_platform_devices[] = { }, }, #endif /* CONFIG_CPM2 */ + [MPC85xx_eTSEC1] = { + .name = "fsl-gianfar", + .id = 1, + .dev.platform_data = &mpc85xx_etsec1_pdata, + .num_resources = 4, + .resource = (struct resource[]) { + { + .start = MPC85xx_ENET1_OFFSET, + .end = MPC85xx_ENET1_OFFSET + + MPC85xx_ENET1_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "tx", + .start = MPC85xx_IRQ_TSEC1_TX, + .end = MPC85xx_IRQ_TSEC1_TX, + .flags = IORESOURCE_IRQ, + }, + { + .name = "rx", + .start = MPC85xx_IRQ_TSEC1_RX, + .end = MPC85xx_IRQ_TSEC1_RX, + .flags = IORESOURCE_IRQ, + }, + { + .name = "error", + .start = MPC85xx_IRQ_TSEC1_ERROR, + .end = MPC85xx_IRQ_TSEC1_ERROR, + .flags = IORESOURCE_IRQ, + }, + }, + }, + [MPC85xx_eTSEC2] = { + .name = "fsl-gianfar", + .id = 2, + .dev.platform_data = &mpc85xx_etsec2_pdata, + .num_resources = 4, + .resource = (struct resource[]) { + { + .start = MPC85xx_ENET2_OFFSET, + .end = MPC85xx_ENET2_OFFSET + + MPC85xx_ENET2_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "tx", + .start = MPC85xx_IRQ_TSEC2_TX, + .end = MPC85xx_IRQ_TSEC2_TX, + .flags = IORESOURCE_IRQ, + }, + { + .name = "rx", + .start = MPC85xx_IRQ_TSEC2_RX, + .end = MPC85xx_IRQ_TSEC2_RX, + .flags = IORESOURCE_IRQ, + }, + { + .name = "error", + .start = MPC85xx_IRQ_TSEC2_ERROR, + .end = MPC85xx_IRQ_TSEC2_ERROR, + .flags = IORESOURCE_IRQ, + }, + }, + }, + [MPC85xx_eTSEC3] = { + .name = "fsl-gianfar", + .id = 3, + .dev.platform_data = &mpc85xx_etsec3_pdata, + .num_resources = 4, + .resource = (struct resource[]) { + { + .start = MPC85xx_ENET3_OFFSET, + .end = MPC85xx_ENET3_OFFSET + + MPC85xx_ENET3_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "tx", + .start = MPC85xx_IRQ_TSEC3_TX, + .end = MPC85xx_IRQ_TSEC3_TX, + .flags = IORESOURCE_IRQ, + }, + { + .name = "rx", + .start = MPC85xx_IRQ_TSEC3_RX, + .end = MPC85xx_IRQ_TSEC3_RX, + .flags = IORESOURCE_IRQ, + }, + { + .name = "error", + .start = MPC85xx_IRQ_TSEC3_ERROR, + .end = MPC85xx_IRQ_TSEC3_ERROR, + .flags = IORESOURCE_IRQ, + }, + }, + }, + [MPC85xx_eTSEC4] = { + .name = "fsl-gianfar", + .id = 4, + .dev.platform_data = &mpc85xx_etsec4_pdata, + .num_resources = 4, + .resource = (struct resource[]) { + { + .start = 0x27000, + .end = 0x27fff, + .flags = IORESOURCE_MEM, + }, + { + .name = "tx", + .start = MPC85xx_IRQ_TSEC4_TX, + .end = MPC85xx_IRQ_TSEC4_TX, + .flags = IORESOURCE_IRQ, + }, + { + .name = "rx", + .start = MPC85xx_IRQ_TSEC4_RX, + .end = MPC85xx_IRQ_TSEC4_RX, + .flags = IORESOURCE_IRQ, + }, + { + .name = "error", + .start = MPC85xx_IRQ_TSEC4_ERROR, + .end = MPC85xx_IRQ_TSEC4_ERROR, + .flags = IORESOURCE_IRQ, + }, + }, + }, + [MPC85xx_IIC2] = { + .name = "fsl-i2c", + .id = 2, + .dev.platform_data = &mpc85xx_fsl_i2c2_pdata, + .num_resources = 2, + .resource = (struct resource[]) { + { + .start = 0x03100, + .end = 0x031ff, + .flags = IORESOURCE_MEM, + }, + { + .start = MPC85xx_IRQ_IIC1, + .end = MPC85xx_IRQ_IIC1, + .flags = IORESOURCE_IRQ, + }, + }, + }, }; static int __init mach_mpc85xx_fixup(struct platform_device *pdev) diff --git a/arch/ppc/syslib/mpc85xx_sys.c b/arch/ppc/syslib/mpc85xx_sys.c index d806a92a9401..6e3184ab354f 100644 --- a/arch/ppc/syslib/mpc85xx_sys.c +++ b/arch/ppc/syslib/mpc85xx_sys.c @@ -110,6 +110,111 @@ struct ppc_sys_spec ppc_sys_specs[] = { MPC85xx_CPM_USB, }, }, + /* SVRs on 8548 rev1.0 matches for 8548/8547/8545 */ + { + .ppc_sys_name = "8548E", + .mask = 0xFFFF00F0, + .value = 0x80390010, + .num_devices = 13, + .device_list = (enum ppc_sys_devices[]) + { + MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3, + MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2, + MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3, + MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2, + }, + }, + { + .ppc_sys_name = "8548", + .mask = 0xFFFF00F0, + .value = 0x80310010, + .num_devices = 12, + .device_list = (enum ppc_sys_devices[]) + { + MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3, + MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2, + MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3, + MPC85xx_PERFMON, MPC85xx_DUART, + }, + }, + { + .ppc_sys_name = "8547E", + .mask = 0xFFFF00F0, + .value = 0x80390010, + .num_devices = 13, + .device_list = (enum ppc_sys_devices[]) + { + MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3, + MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2, + MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3, + MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2, + }, + }, + { + .ppc_sys_name = "8547", + .mask = 0xFFFF00F0, + .value = 0x80310010, + .num_devices = 12, + .device_list = (enum ppc_sys_devices[]) + { + MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3, + MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2, + MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3, + MPC85xx_PERFMON, MPC85xx_DUART, + }, + }, + { + .ppc_sys_name = "8545E", + .mask = 0xFFFF00F0, + .value = 0x80390010, + .num_devices = 11, + .device_list = (enum ppc_sys_devices[]) + { + MPC85xx_eTSEC1, MPC85xx_eTSEC2, + MPC85xx_IIC1, MPC85xx_IIC2, + MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3, + MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2, + }, + }, + { + .ppc_sys_name = "8545", + .mask = 0xFFFF00F0, + .value = 0x80310010, + .num_devices = 10, + .device_list = (enum ppc_sys_devices[]) + { + MPC85xx_eTSEC1, MPC85xx_eTSEC2, + MPC85xx_IIC1, MPC85xx_IIC2, + MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3, + MPC85xx_PERFMON, MPC85xx_DUART, + }, + }, + { + .ppc_sys_name = "8543E", + .mask = 0xFFFF00F0, + .value = 0x803A0010, + .num_devices = 11, + .device_list = (enum ppc_sys_devices[]) + { + MPC85xx_eTSEC1, MPC85xx_eTSEC2, + MPC85xx_IIC1, MPC85xx_IIC2, + MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3, + MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2, + }, + }, + { + .ppc_sys_name = "8543", + .mask = 0xFFFF00F0, + .value = 0x80320010, + .num_devices = 10, + .device_list = (enum ppc_sys_devices[]) + { + MPC85xx_eTSEC1, MPC85xx_eTSEC2, + MPC85xx_IIC1, MPC85xx_IIC2, + MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3, + MPC85xx_PERFMON, MPC85xx_DUART, + }, + }, { /* default match */ .ppc_sys_name = "", .mask = 0x00000000, diff --git a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h index 06b86be61ed1..434fc515ba64 100644 --- a/include/asm-ppc/irq.h +++ b/include/asm-ppc/irq.h @@ -223,9 +223,15 @@ static __inline__ int irq_canonicalize(int irq) #define MPC85xx_IRQ_RIO_RX (12 + MPC85xx_OPENPIC_IRQ_OFFSET) #define MPC85xx_IRQ_TSEC1_TX (13 + MPC85xx_OPENPIC_IRQ_OFFSET) #define MPC85xx_IRQ_TSEC1_RX (14 + MPC85xx_OPENPIC_IRQ_OFFSET) +#define MPC85xx_IRQ_TSEC3_TX (15 + MPC85xx_OPENPIC_IRQ_OFFSET) +#define MPC85xx_IRQ_TSEC3_RX (16 + MPC85xx_OPENPIC_IRQ_OFFSET) +#define MPC85xx_IRQ_TSEC3_ERROR (17 + MPC85xx_OPENPIC_IRQ_OFFSET) #define MPC85xx_IRQ_TSEC1_ERROR (18 + MPC85xx_OPENPIC_IRQ_OFFSET) #define MPC85xx_IRQ_TSEC2_TX (19 + MPC85xx_OPENPIC_IRQ_OFFSET) #define MPC85xx_IRQ_TSEC2_RX (20 + MPC85xx_OPENPIC_IRQ_OFFSET) +#define MPC85xx_IRQ_TSEC4_TX (21 + MPC85xx_OPENPIC_IRQ_OFFSET) +#define MPC85xx_IRQ_TSEC4_RX (22 + MPC85xx_OPENPIC_IRQ_OFFSET) +#define MPC85xx_IRQ_TSEC4_ERROR (23 + MPC85xx_OPENPIC_IRQ_OFFSET) #define MPC85xx_IRQ_TSEC2_ERROR (24 + MPC85xx_OPENPIC_IRQ_OFFSET) #define MPC85xx_IRQ_FEC (25 + MPC85xx_OPENPIC_IRQ_OFFSET) #define MPC85xx_IRQ_DUART (26 + MPC85xx_OPENPIC_IRQ_OFFSET) diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h index 22713e331585..51b61d3305f7 100644 --- a/include/asm-ppc/mpc85xx.h +++ b/include/asm-ppc/mpc85xx.h @@ -74,7 +74,7 @@ extern unsigned char __res[]; #define MPC85xx_GUTS_OFFSET (0xe0000) #define MPC85xx_GUTS_SIZE (0x01000) #define MPC85xx_IIC1_OFFSET (0x03000) -#define MPC85xx_IIC1_SIZE (0x01000) +#define MPC85xx_IIC1_SIZE (0x00100) #define MPC85xx_OPENPIC_OFFSET (0x40000) #define MPC85xx_OPENPIC_SIZE (0x40000) #define MPC85xx_PCI1_OFFSET (0x08000) @@ -127,6 +127,11 @@ enum ppc_sys_devices { MPC85xx_CPM_MCC2, MPC85xx_CPM_SMC1, MPC85xx_CPM_SMC2, + MPC85xx_eTSEC1, + MPC85xx_eTSEC2, + MPC85xx_eTSEC3, + MPC85xx_eTSEC4, + MPC85xx_IIC2, }; #endif /* CONFIG_85xx */ diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index faaff4c64559..70f54af87b9f 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h @@ -51,6 +51,7 @@ struct gianfar_platform_data { /* board specific information */ u32 board_flags; + u32 phy_flags; u32 phyid; u32 interruptPHY; u8 mac_addr[6]; @@ -61,9 +62,14 @@ struct gianfar_platform_data { #define FSL_GIANFAR_DEV_HAS_COALESCE 0x00000002 #define FSL_GIANFAR_DEV_HAS_RMON 0x00000004 #define FSL_GIANFAR_DEV_HAS_MULTI_INTR 0x00000008 +#define FSL_GIANFAR_DEV_HAS_CSUM 0x00000010 +#define FSL_GIANFAR_DEV_HAS_VLAN 0x00000020 +#define FSL_GIANFAR_DEV_HAS_EXTENDED_HASH 0x00000040 +#define FSL_GIANFAR_DEV_HAS_PADDING 0x00000080 /* Flags in gianfar_platform_data */ -#define FSL_GIANFAR_BRD_HAS_PHY_INTR 0x00000001 /* if not set use a timer */ +#define FSL_GIANFAR_BRD_HAS_PHY_INTR 0x00000001 /* set or use a timer */ +#define FSL_GIANFAR_BRD_IS_REDUCED 0x00000002 /* Set if RGMII, RMII */ struct fsl_i2c_platform_data { /* device specific information */ -- cgit v1.2.3-59-g8ed1b From c91999bba3ae8b21d4a965f19bf127bac3e5f7f2 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 21 Jun 2005 17:15:19 -0700 Subject: [PATCH] ppc32: Added preliminary support for the MPC8548 CDS board Adds support for using the MPC8548 processor on the CDS reference board. Currently all the major busses (PCI, PCI-X, PCI-Express, sRIO) and eTSEC3 and eTSEC4 are not supported. Signed-off-by: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/configs/mpc8548_cds_defconfig | 659 +++++++++++++++++++++++++++ arch/ppc/platforms/85xx/Kconfig | 10 + arch/ppc/platforms/85xx/Makefile | 1 + arch/ppc/platforms/85xx/mpc85xx_cds_common.c | 50 +- arch/ppc/syslib/Makefile | 1 + arch/ppc/syslib/ppc85xx_setup.c | 6 +- include/asm-ppc/mpc85xx.h | 2 +- 7 files changed, 713 insertions(+), 16 deletions(-) create mode 100644 arch/ppc/configs/mpc8548_cds_defconfig diff --git a/arch/ppc/configs/mpc8548_cds_defconfig b/arch/ppc/configs/mpc8548_cds_defconfig new file mode 100644 index 000000000000..abe034f24b83 --- /dev/null +++ b/arch/ppc/configs/mpc8548_cds_defconfig @@ -0,0 +1,659 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc4 +# Tue May 24 22:36:27 2005 +# +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +# CONFIG_EPOLL is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Processor +# +# CONFIG_6xx is not set +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +CONFIG_E500=y +CONFIG_BOOKE=y +CONFIG_FSL_BOOKE=y +# CONFIG_PHYS_64BIT is not set +CONFIG_SPE=y +CONFIG_MATH_EMULATION=y +# CONFIG_CPU_FREQ is not set +# CONFIG_PM is not set +CONFIG_85xx=y +CONFIG_PPC_INDIRECT_PCI_BE=y + +# +# Freescale 85xx options +# +# CONFIG_MPC8540_ADS is not set +CONFIG_MPC8548_CDS=y +# CONFIG_MPC8555_CDS is not set +# CONFIG_MPC8560_ADS is not set +# CONFIG_SBC8560 is not set +# CONFIG_STX_GP3 is not set +CONFIG_MPC8548=y + +# +# Platform options +# +# CONFIG_SMP is not set +# CONFIG_PREEMPT is not set +# CONFIG_HIGHMEM is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +CONFIG_BOOT_LOAD=0x00800000 + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=32768 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_LBD is not set +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Macintosh device drivers +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_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 +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y + +# +# Ethernet (1000 Mbit) +# +CONFIG_GIANFAR=y +CONFIG_GFAR_NAPI=y + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE 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 is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=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 is not set +# CONFIG_NVRAM is not set +CONFIG_GEN_RTC=y +# CONFIG_GEN_RTC_X is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ISA is not set +CONFIG_I2C_MPC=y +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR 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_ASB100 is not set +# CONFIG_SENSORS_DS1621 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_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_M41T00 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 + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=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 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_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# diff --git a/arch/ppc/platforms/85xx/Kconfig b/arch/ppc/platforms/85xx/Kconfig index ff92e38e7da1..c5bc2821d991 100644 --- a/arch/ppc/platforms/85xx/Kconfig +++ b/arch/ppc/platforms/85xx/Kconfig @@ -21,6 +21,11 @@ config MPC8540_ADS help This option enables support for the MPC 8540 ADS evaluation board. +config MPC8548_CDS + bool "Freescale MPC8548 CDS" + help + This option enablese support for the MPC8548 CDS evaluation board. + config MPC8555_CDS bool "Freescale MPC8555 CDS" help @@ -53,6 +58,11 @@ config MPC8540 depends on MPC8540_ADS default y +config MPC8548 + bool + depends on MPC8548_CDS + default y + config MPC8555 bool depends on MPC8555_CDS diff --git a/arch/ppc/platforms/85xx/Makefile b/arch/ppc/platforms/85xx/Makefile index 854fbd298ba2..efdf813108f2 100644 --- a/arch/ppc/platforms/85xx/Makefile +++ b/arch/ppc/platforms/85xx/Makefile @@ -2,6 +2,7 @@ # Makefile for the PowerPC 85xx linux kernel. # obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads_common.o mpc8540_ads.o +obj-$(CONFIG_MPC8548_CDS) += mpc85xx_cds_common.o obj-$(CONFIG_MPC8555_CDS) += mpc85xx_cds_common.o obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads_common.o mpc8560_ads.o obj-$(CONFIG_SBC8560) += sbc85xx.o sbc8560.o diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c index e7cfa498568c..2d04bf599d2f 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c +++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c @@ -480,21 +480,47 @@ mpc85xx_cds_setup_arch(void) /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); - pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->interruptPHY = MPC85xx_IRQ_EXT5; - pdata->phyid = 0; - /* fixup phy address */ - pdata->phy_reg_addr += binfo->bi_immr_base; - memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); + if (pdata) { + pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; + pdata->interruptPHY = MPC85xx_IRQ_EXT5; + pdata->phyid = 0; + /* fixup phy address */ + pdata->phy_reg_addr += binfo->bi_immr_base; + memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); + } pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); - pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->interruptPHY = MPC85xx_IRQ_EXT5; - pdata->phyid = 1; - /* fixup phy address */ - pdata->phy_reg_addr += binfo->bi_immr_base; - memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); + if (pdata) { + pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; + pdata->interruptPHY = MPC85xx_IRQ_EXT5; + pdata->phyid = 1; + /* fixup phy address */ + pdata->phy_reg_addr += binfo->bi_immr_base; + memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); + } + + pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC1); + if (pdata) { + pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; + pdata->interruptPHY = MPC85xx_IRQ_EXT5; + pdata->phyid = 0; + /* fixup phy address */ + pdata->phy_reg_addr += binfo->bi_immr_base; + memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); + } + + pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC2); + if (pdata) { + pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; + pdata->interruptPHY = MPC85xx_IRQ_EXT5; + pdata->phyid = 1; + /* fixup phy address */ + pdata->phy_reg_addr += binfo->bi_immr_base; + memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); + } + ppc_sys_device_remove(MPC85xx_eTSEC3); + ppc_sys_device_remove(MPC85xx_eTSEC4); #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile index 96acf85800d4..6e7ecbc59aac 100644 --- a/arch/ppc/syslib/Makefile +++ b/arch/ppc/syslib/Makefile @@ -107,6 +107,7 @@ obj-$(CONFIG_83xx) += ipic.o ppc83xx_setup.o ppc_sys.o \ ifeq ($(CONFIG_83xx),y) obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o endif +obj-$(CONFIG_MPC8548_CDS) += todc_time.o obj-$(CONFIG_MPC8555_CDS) += todc_time.o obj-$(CONFIG_PPC_MPC52xx) += mpc52xx_setup.o mpc52xx_pic.o \ mpc52xx_sys.o mpc52xx_devices.o ppc_sys.o diff --git a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c index f3277f469e78..455473f589d1 100644 --- a/arch/ppc/syslib/ppc85xx_setup.c +++ b/arch/ppc/syslib/ppc85xx_setup.c @@ -133,7 +133,7 @@ mpc85xx_halt(void) #ifdef CONFIG_PCI -#if defined(CONFIG_MPC8555_CDS) +#if defined(CONFIG_MPC8555_CDS) || defined(CONFIG_MPC8548_CDS) extern void mpc85xx_cds_enable_via(struct pci_controller *hose); extern void mpc85xx_cds_fixup_via(struct pci_controller *hose); #endif @@ -308,14 +308,14 @@ mpc85xx_setup_hose(void) ppc_md.pci_exclude_device = mpc85xx_exclude_device; -#if defined(CONFIG_MPC8555_CDS) +#if defined(CONFIG_MPC8555_CDS) || defined(CONFIG_MPC8548_CDS) /* Pre pciauto_bus_scan VIA init */ mpc85xx_cds_enable_via(hose_a); #endif hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno); -#if defined(CONFIG_MPC8555_CDS) +#if defined(CONFIG_MPC8555_CDS) || defined(CONFIG_MPC8548_CDS) /* Post pciauto_bus_scan VIA fixup */ mpc85xx_cds_fixup_via(hose_a); #endif diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h index 51b61d3305f7..95cc22da8075 100644 --- a/include/asm-ppc/mpc85xx.h +++ b/include/asm-ppc/mpc85xx.h @@ -25,7 +25,7 @@ #ifdef CONFIG_MPC8540_ADS #include #endif -#ifdef CONFIG_MPC8555_CDS +#if defined(CONFIG_MPC8555_CDS) || defined(CONFIG_MPC8548_CDS) #include #endif #ifdef CONFIG_MPC8560_ADS -- cgit v1.2.3-59-g8ed1b From c93fcff6952068d484f2f7dae187037f46235647 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 21 Jun 2005 17:15:20 -0700 Subject: [PATCH] ppc32: Removed dependency on CONFIG_CPM2 for building mpc85xx_device.c Previously we needed CONFIG_CPM2 enabled to get the proper IRQ ifdef's for CPM interrupts. Recent changes have caused that to be no longer necessary. Signed-off-by: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/syslib/mpc85xx_devices.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/ppc/syslib/mpc85xx_devices.c b/arch/ppc/syslib/mpc85xx_devices.c index b30c57d4518f..8af322dd476a 100644 --- a/arch/ppc/syslib/mpc85xx_devices.c +++ b/arch/ppc/syslib/mpc85xx_devices.c @@ -321,7 +321,6 @@ struct platform_device ppc_sys_platform_devices[] = { }, }, }, -#ifdef CONFIG_CPM2 [MPC85xx_CPM_FCC1] = { .name = "fsl-cpm-fcc", .id = 1, @@ -575,7 +574,6 @@ struct platform_device ppc_sys_platform_devices[] = { }, }, }, -#endif /* CONFIG_CPM2 */ [MPC85xx_eTSEC1] = { .name = "fsl-gianfar", .id = 1, -- cgit v1.2.3-59-g8ed1b From b264c3527930ca4812fefc505fde9ad99d8a0117 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 21 Jun 2005 17:15:21 -0700 Subject: [PATCH] ppc32: Converted MPC10X bridge to use platform devices instead of OCP Converted the MPC10x bridge support (used by MPC10x and 8240/1/5) to used the standard platform device model. Signed-off-by: Matt McClintock Signed-off-by: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/Kconfig | 5 -- arch/ppc/kernel/setup.c | 4 +- arch/ppc/syslib/Makefile | 2 +- arch/ppc/syslib/mpc10x_common.c | 183 ++++++++++++++++++++++++++++++---------- include/asm-ppc/mpc10x.h | 6 ++ include/asm-ppc/ppc_sys.h | 2 + 6 files changed, 149 insertions(+), 53 deletions(-) diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index 54ce6da22644..10162b187bcf 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -826,11 +826,6 @@ config MPC10X_BRIDGE depends on PCORE || POWERPMC250 || LOPEC || SANDPOINT default y -config FSL_OCP - bool - depends on MPC10X_BRIDGE - default y - config MPC10X_OPENPIC bool depends on POWERPMC250 || LOPEC || SANDPOINT diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 5c20266e3b1f..c344c66e68f7 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -41,7 +41,7 @@ #include #include -#if defined(CONFIG_85xx) || defined(CONFIG_83xx) +#if defined(CONFIG_85xx) || defined(CONFIG_83xx) || defined(CONFIG_MPC10X_BRIDGE) #include #endif @@ -249,7 +249,7 @@ int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "bogomips\t: %lu.%02lu\n", lpj / (500000/HZ), (lpj / (5000/HZ)) % 100); -#if defined(CONFIG_85xx) || defined(CONFIG_83xx) +#if defined(CONFIG_85xx) || defined(CONFIG_83xx) || defined(CONFIG_MPC10X_BRIDGE) if (cur_ppc_sys_spec->ppc_sys_name) seq_printf(m, "chipset\t\t: %s\n", cur_ppc_sys_spec->ppc_sys_name); diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile index 6e7ecbc59aac..dec5bf4f6879 100644 --- a/arch/ppc/syslib/Makefile +++ b/arch/ppc/syslib/Makefile @@ -92,7 +92,7 @@ ifeq ($(CONFIG_SERIAL_MPSC_CONSOLE),y) obj-$(CONFIG_SERIAL_TEXT_DEBUG) += mv64x60_dbg.o endif obj-$(CONFIG_BOOTX_TEXT) += btext.o -obj-$(CONFIG_MPC10X_BRIDGE) += mpc10x_common.o indirect_pci.o +obj-$(CONFIG_MPC10X_BRIDGE) += mpc10x_common.o indirect_pci.o ppc_sys.o obj-$(CONFIG_MPC10X_OPENPIC) += open_pic.o obj-$(CONFIG_40x) += dcr.o obj-$(CONFIG_BOOKE) += dcr.o diff --git a/arch/ppc/syslib/mpc10x_common.c b/arch/ppc/syslib/mpc10x_common.c index fd93adfd464c..0130aeb4a2d3 100644 --- a/arch/ppc/syslib/mpc10x_common.c +++ b/arch/ppc/syslib/mpc10x_common.c @@ -21,6 +21,9 @@ #include #include #include +#include +#include +#include #include #include @@ -30,16 +33,7 @@ #include #include #include -#include - -/* The OCP structure is fixed by code below, before OCP initialises. - paddr depends on where the board places the EUMB. - - fixed in mpc10x_bridge_init(). - irq depends on two things: - > does the board use the EPIC at all? (PCORE does not). - > is the EPIC in serial or parallel mode? - - fixed in mpc10x_set_openpic(). -*/ +#include #ifdef CONFIG_MPC10X_OPENPIC #ifdef CONFIG_EPIC_SERIAL_MODE @@ -51,34 +45,127 @@ #define MPC10X_DMA0_IRQ (EPIC_IRQ_BASE + 1 + NUM_8259_INTERRUPTS) #define MPC10X_DMA1_IRQ (EPIC_IRQ_BASE + 2 + NUM_8259_INTERRUPTS) #else -#define MPC10X_I2C_IRQ OCP_IRQ_NA -#define MPC10X_DMA0_IRQ OCP_IRQ_NA -#define MPC10X_DMA1_IRQ OCP_IRQ_NA +#define MPC10X_I2C_IRQ -1 +#define MPC10X_DMA0_IRQ -1 +#define MPC10X_DMA1_IRQ -1 #endif - -struct ocp_def core_ocp[] = { - { .vendor = OCP_VENDOR_INVALID - } +static struct fsl_i2c_platform_data mpc10x_i2c_pdata = { + .device_flags = 0, }; -static struct ocp_fs_i2c_data mpc10x_i2c_data = { - .flags = 0 +static struct plat_serial8250_port serial_platform_data[] = { + { }, }; -static struct ocp_def mpc10x_i2c_ocp = { - .vendor = OCP_VENDOR_MOTOROLA, - .function = OCP_FUNC_IIC, - .index = 0, - .additions = &mpc10x_i2c_data + +struct platform_device ppc_sys_platform_devices[] = { + [MPC10X_IIC1] = { + .name = "fsl-i2c", + .id = 1, + .dev.platform_data = &mpc10x_i2c_pdata, + .num_resources = 2, + .resource = (struct resource[]) { + { + .start = MPC10X_EUMB_I2C_OFFSET, + .end = MPC10X_EUMB_I2C_OFFSET + + MPC10X_EUMB_I2C_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .flags = IORESOURCE_IRQ + }, + }, + }, + [MPC10X_DMA0] = { + .name = "fsl-dma", + .id = 0, + .num_resources = 2, + .resource = (struct resource[]) { + { + .start = MPC10X_EUMB_DMA_OFFSET + 0x10, + .end = MPC10X_EUMB_DMA_OFFSET + 0x1f, + .flags = IORESOURCE_MEM, + }, + { + .flags = IORESOURCE_IRQ, + }, + }, + }, + [MPC10X_DMA1] = { + .name = "fsl-dma", + .id = 1, + .num_resources = 2, + .resource = (struct resource[]) { + { + .start = MPC10X_EUMB_DMA_OFFSET + 0x20, + .end = MPC10X_EUMB_DMA_OFFSET + 0x2f, + .flags = IORESOURCE_MEM, + }, + { + .flags = IORESOURCE_IRQ, + }, + }, + }, + [MPC10X_DMA1] = { + .name = "fsl-dma", + .id = 1, + .num_resources = 2, + .resource = (struct resource[]) { + { + .start = MPC10X_EUMB_DMA_OFFSET + 0x20, + .end = MPC10X_EUMB_DMA_OFFSET + 0x2f, + .flags = IORESOURCE_MEM, + }, + { + .flags = IORESOURCE_IRQ, + }, + }, + }, + [MPC10X_DUART] = { + .name = "serial8250", + .id = 0, + .dev.platform_data = serial_platform_data, + }, }; -static struct ocp_def mpc10x_dma_ocp[2] = { -{ .vendor = OCP_VENDOR_MOTOROLA, - .function = OCP_FUNC_DMA, - .index = 0 }, -{ .vendor = OCP_VENDOR_MOTOROLA, - .function = OCP_FUNC_DMA, - .index = 1 } +/* We use the PCI ID to match on */ +struct ppc_sys_spec *cur_ppc_sys_spec; +struct ppc_sys_spec ppc_sys_specs[] = { + { + .ppc_sys_name = "8245", + .mask = 0xFFFFFFFF, + .value = MPC10X_BRIDGE_8245, + .num_devices = 4, + .device_list = (enum ppc_sys_devices[]) + { + MPC10X_IIC1, MPC10X_DMA0, MPC10X_DMA1, MPC10X_DUART, + }, + }, + { + .ppc_sys_name = "8240", + .mask = 0xFFFFFFFF, + .value = MPC10X_BRIDGE_8240, + .num_devices = 3, + .device_list = (enum ppc_sys_devices[]) + { + MPC10X_IIC1, MPC10X_DMA0, MPC10X_DMA1, + }, + }, + { + .ppc_sys_name = "107", + .mask = 0xFFFFFFFF, + .value = MPC10X_BRIDGE_107, + .num_devices = 3, + .device_list = (enum ppc_sys_devices[]) + { + MPC10X_IIC1, MPC10X_DMA0, MPC10X_DMA1, + }, + }, + { /* default match */ + .ppc_sys_name = "", + .mask = 0x00000000, + .value = 0x00000000, + }, }; /* Set resources to match bridge memory map */ @@ -132,7 +219,7 @@ mpc10x_bridge_init(struct pci_controller *hose, uint new_map, uint phys_eumb_base) { - int host_bridge, picr1, picr1_bit; + int host_bridge, picr1, picr1_bit, i; ulong pci_config_addr, pci_config_data; u_char pir, byte; @@ -273,7 +360,7 @@ mpc10x_bridge_init(struct pci_controller *hose, printk("Host bridge in Agent mode\n"); /* Read or Set LMBAR & PCSRBAR? */ } - + /* Set base addr of the 8240/107 EUMB. */ early_write_config_dword(hose, 0, @@ -287,17 +374,6 @@ mpc10x_bridge_init(struct pci_controller *hose, ioremap(phys_eumb_base + MPC10X_EUMB_EPIC_OFFSET, MPC10X_EUMB_EPIC_SIZE); #endif - mpc10x_i2c_ocp.paddr = phys_eumb_base + MPC10X_EUMB_I2C_OFFSET; - mpc10x_i2c_ocp.irq = MPC10X_I2C_IRQ; - ocp_add_one_device(&mpc10x_i2c_ocp); - mpc10x_dma_ocp[0].paddr = phys_eumb_base + - MPC10X_EUMB_DMA_OFFSET + 0x100; - mpc10x_dma_ocp[0].irq = MPC10X_DMA0_IRQ; - ocp_add_one_device(&mpc10x_dma_ocp[0]); - mpc10x_dma_ocp[1].paddr = phys_eumb_base + - MPC10X_EUMB_DMA_OFFSET + 0x200; - mpc10x_dma_ocp[1].irq = MPC10X_DMA1_IRQ; - ocp_add_one_device(&mpc10x_dma_ocp[1]); } #ifdef CONFIG_MPC10X_STORE_GATHERING @@ -306,6 +382,23 @@ mpc10x_bridge_init(struct pci_controller *hose, mpc10x_disable_store_gathering(hose); #endif + /* setup platform devices for MPC10x bridges */ + identify_ppc_sys_by_id (host_bridge); + + for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) { + unsigned int dev_id = cur_ppc_sys_spec->device_list[i]; + ppc_sys_fixup_mem_resource(&ppc_sys_platform_devices[dev_id], + phys_eumb_base); + } + + /* IRQ's are determined at runtime */ + ppc_sys_platform_devices[MPC10X_IIC1].resource[1].start = MPC10X_I2C_IRQ; + ppc_sys_platform_devices[MPC10X_IIC1].resource[1].end = MPC10X_I2C_IRQ; + ppc_sys_platform_devices[MPC10X_DMA0].resource[1].start = MPC10X_DMA0_IRQ; + ppc_sys_platform_devices[MPC10X_DMA0].resource[1].end = MPC10X_DMA0_IRQ; + ppc_sys_platform_devices[MPC10X_DMA1].resource[1].start = MPC10X_DMA1_IRQ; + ppc_sys_platform_devices[MPC10X_DMA1].resource[1].end = MPC10X_DMA1_IRQ; + /* * 8240 erratum 26, 8241/8245 erratum 29, 107 erratum 23: speculative * PCI reads may return stale data so turn off. @@ -330,7 +423,7 @@ mpc10x_bridge_init(struct pci_controller *hose, * 8245 (Rev 2., dated 10/2003) says PICR2[0] is reserverd. */ if (host_bridge == MPC10X_BRIDGE_8245) { - ulong picr2; + u32 picr2; early_read_config_dword(hose, 0, PCI_DEVFN(0,0), MPC10X_CFG_PICR2_REG, &picr2); diff --git a/include/asm-ppc/mpc10x.h b/include/asm-ppc/mpc10x.h index d8e7e2d6128e..f5196a4efbe0 100644 --- a/include/asm-ppc/mpc10x.h +++ b/include/asm-ppc/mpc10x.h @@ -159,6 +159,12 @@ extern unsigned long ioremap_base; #define MPC10X_MAPA_EUMB_BASE (ioremap_base - MPC10X_EUMB_SIZE) #define MPC10X_MAPB_EUMB_BASE MPC10X_MAPA_EUMB_BASE +enum ppc_sys_devices { + MPC10X_IIC1, + MPC10X_DMA0, + MPC10X_DMA1, + MPC10X_DUART, +}; int mpc10x_bridge_init(struct pci_controller *hose, uint current_map, diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h index 24b991c42769..8ea624566231 100644 --- a/include/asm-ppc/ppc_sys.h +++ b/include/asm-ppc/ppc_sys.h @@ -27,6 +27,8 @@ #include #elif defined(CONFIG_PPC_MPC52xx) #include +#elif defined(CONFIG_MPC10X_BRIDGE) +#include #else #error "need definition of ppc_sys_devices" #endif -- cgit v1.2.3-59-g8ed1b From a1604f9121ee97b27d5ce308ddd4b70c3a220279 Mon Sep 17 00:00:00 2001 From: Matt Porter Date: Tue, 21 Jun 2005 17:15:22 -0700 Subject: [PATCH] cpm_uart: Route SCC2 pins for the STx GP3 board Adds SCC2 pin routing specific to the GP3 board. Signed-off-by: Matt Porter Signed-off-by: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/cpm_uart/cpm_uart_cpm2.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index b422c3abfba6..c4c8f4b44f53 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c @@ -134,12 +134,21 @@ void scc1_lineif(struct uart_cpm_port *pinfo) void scc2_lineif(struct uart_cpm_port *pinfo) { + /* + * STx GP3 uses the SCC2 secondary option pin assignment + * which this driver doesn't account for in the static + * pin assignments. This kind of board specific info + * really has to get out of the driver so boards can + * be supported in a sane fashion. + */ +#ifndef CONFIG_STX_GP3 volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; io->iop_pparb |= 0x008b0000; io->iop_pdirb |= 0x00880000; io->iop_psorb |= 0x00880000; io->iop_pdirb &= ~0x00030000; io->iop_psorb &= ~0x00030000; +#endif cpm2_immr->im_cpmux.cmx_scr &= 0xff00ffff; cpm2_immr->im_cpmux.cmx_scr |= 0x00090000; pinfo->brg = 2; -- cgit v1.2.3-59-g8ed1b From 1e5aa8c86571deea5d8e8462fedcf610e21af717 Mon Sep 17 00:00:00 2001 From: Matt Porter Date: Tue, 21 Jun 2005 17:15:22 -0700 Subject: [PATCH] ppc32: fix CONFIG_TASK_SIZE handling on 40x This patch is virtually identical to my previous 44x one. It removes 0x8000'0000 TASK_SIZE hardcoded assumption from head_4xx.S. Signed-off-by: Eugene Surovegin Signed-off-by: Matt Porter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/kernel/head_4xx.S | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/ppc/kernel/head_4xx.S b/arch/ppc/kernel/head_4xx.S index 6f5d380e2345..23fb51819ba5 100644 --- a/arch/ppc/kernel/head_4xx.S +++ b/arch/ppc/kernel/head_4xx.S @@ -291,8 +291,9 @@ label: /* If we are faulting a kernel address, we have to use the * kernel page tables. */ - andis. r11, r10, 0x8000 - beq 3f + lis r11, TASK_SIZE@h + cmplw r10, r11 + blt+ 3f lis r11, swapper_pg_dir@h ori r11, r11, swapper_pg_dir@l li r9, 0 @@ -479,8 +480,9 @@ label: /* If we are faulting a kernel address, we have to use the * kernel page tables. */ - andis. r11, r10, 0x8000 - beq 3f + lis r11, TASK_SIZE@h + cmplw r10, r11 + blt+ 3f lis r11, swapper_pg_dir@h ori r11, r11, swapper_pg_dir@l li r9, 0 @@ -578,8 +580,9 @@ label: /* If we are faulting a kernel address, we have to use the * kernel page tables. */ - andis. r11, r10, 0x8000 - beq 3f + lis r11, TASK_SIZE@h + cmplw r10, r11 + blt+ 3f lis r11, swapper_pg_dir@h ori r11, r11, swapper_pg_dir@l li r9, 0 -- cgit v1.2.3-59-g8ed1b From 682afbbd1456e9e7b64f482eb05676b933173cdf Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 21 Jun 2005 17:15:23 -0700 Subject: [PATCH] ppc32: Add support for MPC8245 8250 serial ports on Sandpoint Added platform device initialization for the two 8250 style UARTs that exist on the MPC8245. Additionally, updated the Sandpoint code to enable one of these UARTs if an MPC8245 is connected to it. Signed-off-by: Matt McClintock Signed-off-by: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/platforms/sandpoint.c | 20 ++++++++++++++++++++ arch/ppc/syslib/mpc10x_common.c | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/arch/ppc/platforms/sandpoint.c b/arch/ppc/platforms/sandpoint.c index 531bfa0e4512..70e58f43f2b8 100644 --- a/arch/ppc/platforms/sandpoint.c +++ b/arch/ppc/platforms/sandpoint.c @@ -81,6 +81,7 @@ #include #include /* for linux/serial_core.h */ #include +#include #include #include @@ -99,6 +100,7 @@ #include #include #include +#include #include "sandpoint.h" @@ -305,6 +307,24 @@ sandpoint_setup_arch(void) /* Lookup PCI host bridges */ sandpoint_find_bridges(); + if (strncmp (cur_ppc_sys_spec->ppc_sys_name, "8245", 4) == 0) + { + bd_t *bp = (bd_t *)__res; + struct plat_serial8250_port *pdata; + pdata = (struct plat_serial8250_port *) ppc_sys_get_pdata(MPC10X_DUART); + + if (pdata) + { + pdata[0].uartclk = bp->bi_busfreq; + pdata[0].membase = ioremap(pdata[0].mapbase, 0x100); + + /* this disables the 2nd serial port on the DUART + * since the sandpoint does not have it connected */ + pdata[1].uartclk = 0; + pdata[1].irq = 0; + pdata[1].mapbase = 0; + } + printk(KERN_INFO "Motorola SPS Sandpoint Test Platform\n"); printk(KERN_INFO "Port by MontaVista Software, Inc. (source@mvista.com)\n"); diff --git a/arch/ppc/syslib/mpc10x_common.c b/arch/ppc/syslib/mpc10x_common.c index 0130aeb4a2d3..8fc5f4154521 100644 --- a/arch/ppc/syslib/mpc10x_common.c +++ b/arch/ppc/syslib/mpc10x_common.c @@ -44,10 +44,12 @@ #define MPC10X_I2C_IRQ (EPIC_IRQ_BASE + NUM_8259_INTERRUPTS) #define MPC10X_DMA0_IRQ (EPIC_IRQ_BASE + 1 + NUM_8259_INTERRUPTS) #define MPC10X_DMA1_IRQ (EPIC_IRQ_BASE + 2 + NUM_8259_INTERRUPTS) +#define MPC10X_UART0_IRQ (EPIC_IRQ_BASE + 4 + NUM_8259_INTERRUPTS) #else #define MPC10X_I2C_IRQ -1 #define MPC10X_DMA0_IRQ -1 #define MPC10X_DMA1_IRQ -1 +#define MPC10X_UART0_IRQ -1 #endif static struct fsl_i2c_platform_data mpc10x_i2c_pdata = { @@ -55,6 +57,16 @@ static struct fsl_i2c_platform_data mpc10x_i2c_pdata = { }; static struct plat_serial8250_port serial_platform_data[] = { + [0] = { + .mapbase = 0x4500, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + [1] = { + .mapbase = 0x4600, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, { }, }; @@ -399,6 +411,12 @@ mpc10x_bridge_init(struct pci_controller *hose, ppc_sys_platform_devices[MPC10X_DMA1].resource[1].start = MPC10X_DMA1_IRQ; ppc_sys_platform_devices[MPC10X_DMA1].resource[1].end = MPC10X_DMA1_IRQ; + serial_platform_data[0].mapbase += phys_eumb_base; + serial_platform_data[0].irq = MPC10X_UART0_IRQ; + + serial_platform_data[1].mapbase += phys_eumb_base; + serial_platform_data[1].irq = MPC10X_UART0_IRQ + 1; + /* * 8240 erratum 26, 8241/8245 erratum 29, 107 erratum 23: speculative * PCI reads may return stale data so turn off. @@ -597,6 +615,8 @@ void __init mpc10x_set_openpic(void) openpic_set_sources(EPIC_IRQ_BASE, 3, OpenPIC_Addr + 0x11020); /* Skip reserved space and map Message Unit Interrupt (I2O) */ openpic_set_sources(EPIC_IRQ_BASE + 3, 1, OpenPIC_Addr + 0x110C0); + /* Skip reserved space and map Serial Interupts */ + openpic_set_sources(EPIC_IRQ_BASE + 4, 2, OpenPIC_Addr + 0x11120); openpic_init(NUM_8259_INTERRUPTS); } -- cgit v1.2.3-59-g8ed1b From eee4146ab908188e556641f1cd7a10e894d10edb Mon Sep 17 00:00:00 2001 From: Matt Porter Date: Tue, 21 Jun 2005 17:15:24 -0700 Subject: [PATCH] ppc32: remove orphaned ppc4xx_kgdb.c Removes ppc4xx_kgdb.c which is no longer being used. Pointed out by Andrei Konovalov. Signed-off-by: Matt Porter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/syslib/ppc4xx_kgdb.c | 124 ------------------------------------------ 1 file changed, 124 deletions(-) delete mode 100644 arch/ppc/syslib/ppc4xx_kgdb.c diff --git a/arch/ppc/syslib/ppc4xx_kgdb.c b/arch/ppc/syslib/ppc4xx_kgdb.c deleted file mode 100644 index fe8668bf8137..000000000000 --- a/arch/ppc/syslib/ppc4xx_kgdb.c +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include -#include -#include - - - -#define LSR_DR 0x01 /* Data ready */ -#define LSR_OE 0x02 /* Overrun */ -#define LSR_PE 0x04 /* Parity error */ -#define LSR_FE 0x08 /* Framing error */ -#define LSR_BI 0x10 /* Break */ -#define LSR_THRE 0x20 /* Xmit holding register empty */ -#define LSR_TEMT 0x40 /* Xmitter empty */ -#define LSR_ERR 0x80 /* Error */ - -#include - -extern struct NS16550* COM_PORTS[]; -#ifndef NULL -#define NULL 0x00 -#endif - -static volatile struct NS16550 *kgdb_debugport = NULL; - -volatile struct NS16550 * -NS16550_init(int chan) -{ - volatile struct NS16550 *com_port; - int quot; -#ifdef BASE_BAUD - quot = BASE_BAUD / 9600; -#else - quot = 0x000c; /* 0xc = 9600 baud (on a pc) */ -#endif - - com_port = (struct NS16550 *) COM_PORTS[chan]; - - com_port->lcr = 0x00; - com_port->ier = 0xFF; - com_port->ier = 0x00; - com_port->lcr = com_port->lcr | 0x80; /* Access baud rate */ - com_port->dll = ( quot & 0x00ff ); /* 0xc = 9600 baud */ - com_port->dlm = ( quot & 0xff00 ) >> 8; - com_port->lcr = 0x03; /* 8 data, 1 stop, no parity */ - com_port->mcr = 0x00; /* RTS/DTR */ - com_port->fcr = 0x07; /* Clear & enable FIFOs */ - - return( com_port ); -} - - -void -NS16550_putc(volatile struct NS16550 *com_port, unsigned char c) -{ - while ((com_port->lsr & LSR_THRE) == 0) - ; - com_port->thr = c; - return; -} - -unsigned char -NS16550_getc(volatile struct NS16550 *com_port) -{ - while ((com_port->lsr & LSR_DR) == 0) - ; - return (com_port->rbr); -} - -unsigned char -NS16550_tstc(volatile struct NS16550 *com_port) -{ - return ((com_port->lsr & LSR_DR) != 0); -} - - -#if defined(CONFIG_KGDB_TTYS0) -#define KGDB_PORT 0 -#elif defined(CONFIG_KGDB_TTYS1) -#define KGDB_PORT 1 -#elif defined(CONFIG_KGDB_TTYS2) -#define KGDB_PORT 2 -#elif defined(CONFIG_KGDB_TTYS3) -#define KGDB_PORT 3 -#else -#error "invalid kgdb_tty port" -#endif - -void putDebugChar( unsigned char c ) -{ - if ( kgdb_debugport == NULL ) - kgdb_debugport = NS16550_init(KGDB_PORT); - NS16550_putc( kgdb_debugport, c ); -} - -int getDebugChar( void ) -{ - if (kgdb_debugport == NULL) - kgdb_debugport = NS16550_init(KGDB_PORT); - - return(NS16550_getc(kgdb_debugport)); -} - -void kgdb_interruptible(int enable) -{ - return; -} - -void putDebugString(char* str) -{ - while (*str != '\0') { - putDebugChar(*str); - str++; - } - putDebugChar('\r'); - return; -} - -void -kgdb_map_scc(void) -{ - printk("kgdb init \n"); - kgdb_debugport = NS16550_init(KGDB_PORT); -} -- cgit v1.2.3-59-g8ed1b From 65145e060b1c933ebc4215c3b493f586e08a1d5c Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 21 Jun 2005 17:15:25 -0700 Subject: [PATCH] ppc32: Added support for all MPC8548 internal interrupts The MPC8548 has 48 internal interrupts and 12 external interrupts. The previous generation PowerQUICC III devices only had 32 internal and 12 external interrupts on the primary interrupt controller. Expanded the number of internal interrupts to 48 for all PowerQUICC III processors and moved the interrupt numbers for the external after the 48 internal interrupt lines, rather than putting the 12 new internal interrupts at the end and ifdef'ng the whole mess. As parted of this created a macro which represents the internal interrupt senses since they are the same on all PQ3 processors. Signed-off-by: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/platforms/85xx/mpc85xx_ads_common.c | 36 ++------------------ arch/ppc/platforms/85xx/mpc85xx_cds_common.c | 41 ++++------------------ arch/ppc/platforms/85xx/sbc85xx.c | 36 ++------------------ arch/ppc/platforms/85xx/stx_gp3.c | 36 ++------------------ include/asm-ppc/irq.h | 28 +++++++-------- include/asm-ppc/mpc85xx.h | 51 ++++++++++++++++++++++++++++ 6 files changed, 77 insertions(+), 151 deletions(-) diff --git a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c index ba9f9f562c45..30397623fa6f 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c +++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c @@ -59,40 +59,8 @@ extern unsigned long total_memory; /* in mm/init */ unsigned char __res[sizeof (bd_t)]; /* Internal interrupts are all Level Sensitive, and Positive Polarity */ - static u_char mpc85xx_ads_openpic_initsenses[] __initdata = { - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 0: L2 Cache */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 1: ECM */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 2: DDR DRAM */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 3: LBIU */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 4: DMA 0 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 5: DMA 1 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 6: DMA 2 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 7: DMA 3 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 8: PCI/PCI-X */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 9: RIO Inbound Port Write Error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 10: RIO Doorbell Inbound */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 11: RIO Outbound Message */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 12: RIO Inbound Message */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 13: TSEC 0 Transmit */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 14: TSEC 0 Receive */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 15: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 16: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 17: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 18: TSEC 0 Receive/Transmit Error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 19: TSEC 1 Transmit */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 20: TSEC 1 Receive */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 21: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 22: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 23: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 24: TSEC 1 Receive/Transmit Error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 25: Fast Ethernet */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 26: DUART */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 27: I2C */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 28: Performance Monitor */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 29: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 30: CPM */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 31: Unused */ + MPC85XX_INTERNAL_IRQ_SENSES, 0x0, /* External 0: */ #if defined(CONFIG_PCI) (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 1: PCI slot 0 */ @@ -159,7 +127,7 @@ mpc85xx_ads_init_IRQ(void) /* Skip reserved space and internal sources */ openpic_set_sources(0, 32, OpenPIC_Addr + 0x10200); /* Map PIC IRQs 0-11 */ - openpic_set_sources(32, 12, OpenPIC_Addr + 0x10000); + openpic_set_sources(48, 12, OpenPIC_Addr + 0x10000); /* we let openpic interrupts starting from an offset, to * leave space for cascading interrupts underneath. diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c index 2d04bf599d2f..bee6633f4601 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c +++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c @@ -73,40 +73,8 @@ static int cds_pci_slot = 2; static volatile u8 * cadmus; /* Internal interrupts are all Level Sensitive, and Positive Polarity */ - static u_char mpc85xx_cds_openpic_initsenses[] __initdata = { - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 0: L2 Cache */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 1: ECM */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 2: DDR DRAM */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 3: LBIU */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 4: DMA 0 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 5: DMA 1 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 6: DMA 2 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 7: DMA 3 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 8: PCI/PCI-X */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 9: RIO Inbound Port Write Error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 10: RIO Doorbell Inbound */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 11: RIO Outbound Message */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 12: RIO Inbound Message */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 13: TSEC 0 Transmit */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 14: TSEC 0 Receive */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 15: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 16: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 17: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 18: TSEC 0 Receive/Transmit Error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 19: TSEC 1 Transmit */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 20: TSEC 1 Receive */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 21: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 22: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 23: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 24: TSEC 1 Receive/Transmit Error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 25: Fast Ethernet */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 26: DUART */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 27: I2C */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 28: Performance Monitor */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 29: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 30: CPM */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 31: Unused */ + MPC85XX_INTERNAL_IRQ_SENSES, #if defined(CONFIG_PCI) (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 0: PCI1 slot */ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 1: PCI1 slot */ @@ -182,7 +150,6 @@ void __init mpc85xx_cds_init_IRQ(void) { bd_t *binfo = (bd_t *) __res; - int i; /* Determine the Physical Address of the OpenPIC regs */ phys_addr_t OpenPIC_PAddr = binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET; @@ -191,9 +158,13 @@ mpc85xx_cds_init_IRQ(void) OpenPIC_NumInitSenses = sizeof (mpc85xx_cds_openpic_initsenses); /* Skip reserved space and internal sources */ +#ifdef CONFIG_MPC8548 + openpic_set_sources(0, 48, OpenPIC_Addr + 0x10200); +#else openpic_set_sources(0, 32, OpenPIC_Addr + 0x10200); +#endif /* Map PIC IRQs 0-11 */ - openpic_set_sources(32, 12, OpenPIC_Addr + 0x10000); + openpic_set_sources(48, 12, OpenPIC_Addr + 0x10000); /* we let openpic interrupts starting from an offset, to * leave space for cascading interrupts underneath. diff --git a/arch/ppc/platforms/85xx/sbc85xx.c b/arch/ppc/platforms/85xx/sbc85xx.c index 2d638c1c1bd6..a7cb625b2d0c 100644 --- a/arch/ppc/platforms/85xx/sbc85xx.c +++ b/arch/ppc/platforms/85xx/sbc85xx.c @@ -59,40 +59,8 @@ unsigned long pci_dram_offset = 0; extern unsigned long total_memory; /* in mm/init */ /* Internal interrupts are all Level Sensitive, and Positive Polarity */ - static u_char sbc8560_openpic_initsenses[] __initdata = { - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 0: L2 Cache */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 1: ECM */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 2: DDR DRAM */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 3: LBIU */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 4: DMA 0 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 5: DMA 1 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 6: DMA 2 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 7: DMA 3 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 8: PCI/PCI-X */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 9: RIO Inbound Port Write Error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 10: RIO Doorbell Inbound */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 11: RIO Outbound Message */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 12: RIO Inbound Message */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 13: TSEC 0 Transmit */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 14: TSEC 0 Receive */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 15: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 16: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 17: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 18: TSEC 0 Receive/Transmit Error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 19: TSEC 1 Transmit */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 20: TSEC 1 Receive */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 21: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 22: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 23: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 24: TSEC 1 Receive/Transmit Error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 25: Fast Ethernet */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 26: DUART */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 27: I2C */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 28: Performance Monitor */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 29: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 30: CPM */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 31: Unused */ + MPC85XX_INTERNAL_IRQ_SENSES, 0x0, /* External 0: */ 0x0, /* External 1: */ #if defined(CONFIG_PCI) @@ -159,7 +127,7 @@ sbc8560_init_IRQ(void) /* Skip reserved space and internal sources */ openpic_set_sources(0, 32, OpenPIC_Addr + 0x10200); /* Map PIC IRQs 0-11 */ - openpic_set_sources(32, 12, OpenPIC_Addr + 0x10000); + openpic_set_sources(48, 12, OpenPIC_Addr + 0x10000); /* we let openpic interrupts starting from an offset, to * leave space for cascading interrupts underneath. diff --git a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c index bc95836e417c..bc0a99638ff6 100644 --- a/arch/ppc/platforms/85xx/stx_gp3.c +++ b/arch/ppc/platforms/85xx/stx_gp3.c @@ -72,38 +72,7 @@ unsigned long pci_dram_offset = 0; /* Internal interrupts are all Level Sensitive, and Positive Polarity */ static u8 gp3_openpic_initsenses[] __initdata = { - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 0: L2 Cache */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 1: ECM */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 2: DDR DRAM */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 3: LBIU */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 4: DMA 0 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 5: DMA 1 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 6: DMA 2 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 7: DMA 3 */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 8: PCI/PCI-X */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 9: RIO Inbound Port Write Error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 10: RIO Doorbell Inbound */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 11: RIO Outbound Message */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 12: RIO Inbound Message */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 13: TSEC 0 Transmit */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 14: TSEC 0 Receive */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 15: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 16: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 17: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 18: TSEC 0 Receive/Transmit Error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 19: TSEC 1 Transmit */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 20: TSEC 1 Receive */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 21: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 22: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 23: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 24: TSEC 1 Receive/Transmit Error */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 25: Fast Ethernet */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 26: DUART */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 27: I2C */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 28: Performance Monitor */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 29: Unused */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 30: CPM */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 31: Unused */ + MPC85XX_INTERNAL_IRQ_SENSES, 0x0, /* External 0: */ #if defined(CONFIG_PCI) (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 1: PCI slot 0 */ @@ -200,7 +169,6 @@ static struct irqaction cpm2_irqaction = { static void __init gp3_init_IRQ(void) { - int i; bd_t *binfo = (bd_t *) __res; /* @@ -218,7 +186,7 @@ gp3_init_IRQ(void) openpic_set_sources(0, 32, OpenPIC_Addr + 0x10200); /* Map PIC IRQs 0-11 */ - openpic_set_sources(32, 12, OpenPIC_Addr + 0x10000); + openpic_set_sources(48, 12, OpenPIC_Addr + 0x10000); /* * Let openpic interrupts starting from an offset, to diff --git a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h index 434fc515ba64..a9b33324f562 100644 --- a/include/asm-ppc/irq.h +++ b/include/asm-ppc/irq.h @@ -176,7 +176,7 @@ static __inline__ int irq_canonicalize(int irq) */ #include -/* The MPC8560 openpic has 32 internal interrupts and 12 external +/* The MPC8548 openpic has 48 internal interrupts and 12 external * interrupts. * * We are "flattening" the interrupt vectors of the cascaded CPM @@ -184,7 +184,7 @@ static __inline__ int irq_canonicalize(int irq) * single integer. */ #define NR_CPM_INTS 64 -#define NR_EPIC_INTS 44 +#define NR_EPIC_INTS 60 #ifndef NR_8259_INTS #define NR_8259_INTS 0 #endif @@ -241,18 +241,18 @@ static __inline__ int irq_canonicalize(int irq) #define MPC85xx_IRQ_CPM (30 + MPC85xx_OPENPIC_IRQ_OFFSET) /* The 12 external interrupt lines */ -#define MPC85xx_IRQ_EXT0 (32 + MPC85xx_OPENPIC_IRQ_OFFSET) -#define MPC85xx_IRQ_EXT1 (33 + MPC85xx_OPENPIC_IRQ_OFFSET) -#define MPC85xx_IRQ_EXT2 (34 + MPC85xx_OPENPIC_IRQ_OFFSET) -#define MPC85xx_IRQ_EXT3 (35 + MPC85xx_OPENPIC_IRQ_OFFSET) -#define MPC85xx_IRQ_EXT4 (36 + MPC85xx_OPENPIC_IRQ_OFFSET) -#define MPC85xx_IRQ_EXT5 (37 + MPC85xx_OPENPIC_IRQ_OFFSET) -#define MPC85xx_IRQ_EXT6 (38 + MPC85xx_OPENPIC_IRQ_OFFSET) -#define MPC85xx_IRQ_EXT7 (39 + MPC85xx_OPENPIC_IRQ_OFFSET) -#define MPC85xx_IRQ_EXT8 (40 + MPC85xx_OPENPIC_IRQ_OFFSET) -#define MPC85xx_IRQ_EXT9 (41 + MPC85xx_OPENPIC_IRQ_OFFSET) -#define MPC85xx_IRQ_EXT10 (42 + MPC85xx_OPENPIC_IRQ_OFFSET) -#define MPC85xx_IRQ_EXT11 (43 + MPC85xx_OPENPIC_IRQ_OFFSET) +#define MPC85xx_IRQ_EXT0 (48 + MPC85xx_OPENPIC_IRQ_OFFSET) +#define MPC85xx_IRQ_EXT1 (49 + MPC85xx_OPENPIC_IRQ_OFFSET) +#define MPC85xx_IRQ_EXT2 (50 + MPC85xx_OPENPIC_IRQ_OFFSET) +#define MPC85xx_IRQ_EXT3 (51 + MPC85xx_OPENPIC_IRQ_OFFSET) +#define MPC85xx_IRQ_EXT4 (52 + MPC85xx_OPENPIC_IRQ_OFFSET) +#define MPC85xx_IRQ_EXT5 (53 + MPC85xx_OPENPIC_IRQ_OFFSET) +#define MPC85xx_IRQ_EXT6 (54 + MPC85xx_OPENPIC_IRQ_OFFSET) +#define MPC85xx_IRQ_EXT7 (55 + MPC85xx_OPENPIC_IRQ_OFFSET) +#define MPC85xx_IRQ_EXT8 (56 + MPC85xx_OPENPIC_IRQ_OFFSET) +#define MPC85xx_IRQ_EXT9 (57 + MPC85xx_OPENPIC_IRQ_OFFSET) +#define MPC85xx_IRQ_EXT10 (58 + MPC85xx_OPENPIC_IRQ_OFFSET) +#define MPC85xx_IRQ_EXT11 (59 + MPC85xx_OPENPIC_IRQ_OFFSET) /* CPM related interrupts */ #define SIU_INT_ERROR ((uint)0x00+CPM_IRQ_OFFSET) diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h index 95cc22da8075..516984ee14b5 100644 --- a/include/asm-ppc/mpc85xx.h +++ b/include/asm-ppc/mpc85xx.h @@ -134,6 +134,57 @@ enum ppc_sys_devices { MPC85xx_IIC2, }; +/* Internal interrupts are all Level Sensitive, and Positive Polarity */ +#define MPC85XX_INTERNAL_IRQ_SENSES \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 0 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 1 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 2 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 3 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 4 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 5 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 6 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 7 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 8 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 9 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 10 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 11 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 12 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 13 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 14 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 15 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 16 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 17 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 18 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 19 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 20 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 21 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 22 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 23 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 24 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 25 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 26 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 27 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 28 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 29 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 30 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 31 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 32 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 33 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 34 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 35 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 36 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 37 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 38 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 39 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 40 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 41 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 42 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 43 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 44 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 45 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 46 */ \ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE) /* Internal 47 */ + #endif /* CONFIG_85xx */ #endif /* __ASM_MPC85xx_H__ */ #endif /* __KERNEL__ */ -- cgit v1.2.3-59-g8ed1b From 5be061eee931db2718feecaf10df17610386202b Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 21 Jun 2005 17:15:26 -0700 Subject: [PATCH] ppc32: Clean up NUM_TLBCAMS usage for Freescale Book-E PPC's Made the number of TLB CAM entries private and converted the board consumers to use num_tlbcam_entries which is setup at boot time from configuration registers. This way the only consumers of the #define NUM_TLBCAMS are the arrays used to manage the TLB. Signed-off-by: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/mm/fsl_booke_mmu.c | 2 ++ arch/ppc/mm/mmu_decl.h | 2 ++ arch/ppc/mm/pgtable.c | 1 - arch/ppc/platforms/85xx/mpc8540_ads.c | 4 ++-- arch/ppc/platforms/85xx/mpc85xx_cds_common.c | 4 ++-- arch/ppc/platforms/85xx/sbc8560.c | 4 ++-- include/asm-ppc/pgtable.h | 2 -- 7 files changed, 10 insertions(+), 9 deletions(-) diff --git a/arch/ppc/mm/fsl_booke_mmu.c b/arch/ppc/mm/fsl_booke_mmu.c index 36233bdcdf8f..e07990efa046 100644 --- a/arch/ppc/mm/fsl_booke_mmu.c +++ b/arch/ppc/mm/fsl_booke_mmu.c @@ -64,6 +64,8 @@ extern unsigned long total_lowmem; extern unsigned long __max_low_memory; #define MAX_LOW_MEM CONFIG_LOWMEM_SIZE +#define NUM_TLBCAMS (16) + struct tlbcam { u32 MAS0; u32 MAS1; diff --git a/arch/ppc/mm/mmu_decl.h b/arch/ppc/mm/mmu_decl.h index ffcdb46997dc..540f3292b229 100644 --- a/arch/ppc/mm/mmu_decl.h +++ b/arch/ppc/mm/mmu_decl.h @@ -43,6 +43,8 @@ extern int mem_init_done; extern PTE *Hash, *Hash_end; extern unsigned long Hash_size, Hash_mask; +extern unsigned int num_tlbcam_entries; + /* ...and now those things that may be slightly different between processor * architectures. -- Dan */ diff --git a/arch/ppc/mm/pgtable.c b/arch/ppc/mm/pgtable.c index 5d2f3f66aefa..81a3d7446d37 100644 --- a/arch/ppc/mm/pgtable.c +++ b/arch/ppc/mm/pgtable.c @@ -66,7 +66,6 @@ void setbat(int index, unsigned long virt, unsigned long phys, #ifdef HAVE_TLBCAM extern unsigned int tlbcam_index; -extern unsigned int num_tlbcam_entries; extern unsigned long v_mapped_by_tlbcam(unsigned long va); extern unsigned long p_mapped_by_tlbcam(unsigned long pa); #else /* !HAVE_TLBCAM */ diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c index 583838ab02d8..d1c2c6cb3000 100644 --- a/arch/ppc/platforms/85xx/mpc8540_ads.c +++ b/arch/ppc/platforms/85xx/mpc8540_ads.c @@ -88,7 +88,7 @@ mpc8540ads_setup_arch(void) #ifdef CONFIG_SERIAL_TEXT_DEBUG /* Invalidate the entry we stole earlier the serial ports * should be properly mapped */ - invalidate_tlbcam_entry(NUM_TLBCAMS - 1); + invalidate_tlbcam_entry(num_tlbcam_entries - 1); #endif /* setup the board related information for the enet controllers */ @@ -150,7 +150,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, struct uart_port p; /* Use the last TLB entry to map CCSRBAR to allow access to DUART regs */ - settlbcam(NUM_TLBCAMS - 1, binfo->bi_immr_base, + settlbcam(num_tlbcam_entries - 1, binfo->bi_immr_base, binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0); memset(&p, 0, sizeof (p)); diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c index bee6633f4601..51964b3081eb 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c +++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c @@ -446,7 +446,7 @@ mpc85xx_cds_setup_arch(void) #ifdef CONFIG_SERIAL_TEXT_DEBUG /* Invalidate the entry we stole earlier the serial ports * should be properly mapped */ - invalidate_tlbcam_entry(NUM_TLBCAMS - 1); + invalidate_tlbcam_entry(num_tlbcam_entries - 1); #endif /* setup the board related information for the enet controllers */ @@ -528,7 +528,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, struct uart_port p; /* Use the last TLB entry to map CCSRBAR to allow access to DUART regs */ - settlbcam(NUM_TLBCAMS - 1, binfo->bi_immr_base, + settlbcam(num_tlbcam_entries - 1, binfo->bi_immr_base, binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0); memset(&p, 0, sizeof (p)); diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c index 7b9e1543e175..42e960a0bf33 100644 --- a/arch/ppc/platforms/85xx/sbc8560.c +++ b/arch/ppc/platforms/85xx/sbc8560.c @@ -125,7 +125,7 @@ sbc8560_setup_arch(void) #ifdef CONFIG_SERIAL_TEXT_DEBUG /* Invalidate the entry we stole earlier the serial ports * should be properly mapped */ - invalidate_tlbcam_entry(NUM_TLBCAMS - 1); + invalidate_tlbcam_entry(num_tlbcam_entries - 1); #endif /* setup the board related information for the enet controllers */ @@ -176,7 +176,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, #ifdef CONFIG_SERIAL_TEXT_DEBUG /* Use the last TLB entry to map CCSRBAR to allow access to DUART regs */ - settlbcam(NUM_TLBCAMS - 1, UARTA_ADDR, + settlbcam(num_tlbcam_entries - 1, UARTA_ADDR, UARTA_ADDR, 0x1000, _PAGE_IO, 0); #endif diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h index a38606d15549..4d4b20c9de78 100644 --- a/include/asm-ppc/pgtable.h +++ b/include/asm-ppc/pgtable.h @@ -267,8 +267,6 @@ extern unsigned long ioremap_bot, ioremap_base; #define _PMD_PRESENT_MASK (PAGE_MASK) #define _PMD_BAD (~PAGE_MASK) -#define NUM_TLBCAMS (16) - #elif defined(CONFIG_8xx) /* Definitions for 8xx embedded chips. */ #define _PAGE_PRESENT 0x0001 /* Page is valid */ -- cgit v1.2.3-59-g8ed1b From 1492ec8069ea6f82bc32df27cabbec72e554e2b8 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 21 Jun 2005 17:15:27 -0700 Subject: [PATCH] ppc32: Factor out common exception code into macro's for 4xx/Book-E 4xx and Book-E PPC's have several exception levels. The code to handle each level is fairly regular. Turning the code into macro's will ease the handling of future exception levels (debug) in forth coming chips. Signed-off-by: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/kernel/entry.S | 164 +++++++++++++++++-------------------------- arch/ppc/kernel/head_booke.h | 94 +++++++------------------ 2 files changed, 87 insertions(+), 171 deletions(-) diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index 661523707e8c..8377b6ca26da 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S @@ -46,26 +46,23 @@ #ifdef CONFIG_BOOKE #include "head_booke.h" +#define TRANSFER_TO_HANDLER_EXC_LEVEL(exc_level) \ + mtspr exc_level##_SPRG,r8; \ + BOOKE_LOAD_EXC_LEVEL_STACK(exc_level); \ + lwz r0,GPR10-INT_FRAME_SIZE(r8); \ + stw r0,GPR10(r11); \ + lwz r0,GPR11-INT_FRAME_SIZE(r8); \ + stw r0,GPR11(r11); \ + mfspr r8,exc_level##_SPRG + .globl mcheck_transfer_to_handler mcheck_transfer_to_handler: - mtspr MCHECK_SPRG,r8 - BOOKE_LOAD_MCHECK_STACK - lwz r0,GPR10-INT_FRAME_SIZE(r8) - stw r0,GPR10(r11) - lwz r0,GPR11-INT_FRAME_SIZE(r8) - stw r0,GPR11(r11) - mfspr r8,MCHECK_SPRG + TRANSFER_TO_HANDLER_EXC_LEVEL(MCHECK) b transfer_to_handler_full .globl crit_transfer_to_handler crit_transfer_to_handler: - mtspr CRIT_SPRG,r8 - BOOKE_LOAD_CRIT_STACK - lwz r0,GPR10-INT_FRAME_SIZE(r8) - stw r0,GPR10(r11) - lwz r0,GPR11-INT_FRAME_SIZE(r8) - stw r0,GPR11(r11) - mfspr r8,CRIT_SPRG + TRANSFER_TO_HANDLER_EXC_LEVEL(CRIT) /* fall through */ #endif @@ -783,99 +780,64 @@ exc_exit_restart_end: * time of the critical interrupt. * */ - .globl ret_from_crit_exc -ret_from_crit_exc: - REST_NVGPRS(r1) - lwz r3,_MSR(r1) - andi. r3,r3,MSR_PR - LOAD_MSR_KERNEL(r10,MSR_KERNEL) - bne user_exc_return - - lwz r0,GPR0(r1) - lwz r2,GPR2(r1) - REST_4GPRS(3, r1) - REST_2GPRS(7, r1) - - lwz r10,_XER(r1) - lwz r11,_CTR(r1) - mtspr SPRN_XER,r10 - mtctr r11 - - PPC405_ERR77(0,r1) - stwcx. r0,0,r1 /* to clear the reservation */ - - lwz r11,_LINK(r1) - mtlr r11 - lwz r10,_CCR(r1) - mtcrf 0xff,r10 #ifdef CONFIG_40x - /* avoid any possible TLB misses here by turning off MSR.DR, we - * assume the instructions here are mapped by a pinned TLB entry */ - li r10,MSR_IR - mtmsr r10 - isync - tophys(r1, r1) +#define PPC_40x_TURN_OFF_MSR_DR \ + /* avoid any possible TLB misses here by turning off MSR.DR, we \ + * assume the instructions here are mapped by a pinned TLB entry */ \ + li r10,MSR_IR; \ + mtmsr r10; \ + isync; \ + tophys(r1, r1); +#else +#define PPC_40x_TURN_OFF_MSR_DR #endif - lwz r9,_DEAR(r1) - lwz r10,_ESR(r1) - mtspr SPRN_DEAR,r9 - mtspr SPRN_ESR,r10 - lwz r11,_NIP(r1) - lwz r12,_MSR(r1) - mtspr SPRN_CSRR0,r11 - mtspr SPRN_CSRR1,r12 - lwz r9,GPR9(r1) - lwz r12,GPR12(r1) - lwz r10,GPR10(r1) - lwz r11,GPR11(r1) - lwz r1,GPR1(r1) - PPC405_ERR77_SYNC - rfci - b . /* prevent prefetch past rfci */ + +#define RET_FROM_EXC_LEVEL(exc_lvl_srr0, exc_lvl_srr1, exc_lvl_rfi) \ + REST_NVGPRS(r1); \ + lwz r3,_MSR(r1); \ + andi. r3,r3,MSR_PR; \ + LOAD_MSR_KERNEL(r10,MSR_KERNEL); \ + bne user_exc_return; \ + lwz r0,GPR0(r1); \ + lwz r2,GPR2(r1); \ + REST_4GPRS(3, r1); \ + REST_2GPRS(7, r1); \ + lwz r10,_XER(r1); \ + lwz r11,_CTR(r1); \ + mtspr SPRN_XER,r10; \ + mtctr r11; \ + PPC405_ERR77(0,r1); \ + stwcx. r0,0,r1; /* to clear the reservation */ \ + lwz r11,_LINK(r1); \ + mtlr r11; \ + lwz r10,_CCR(r1); \ + mtcrf 0xff,r10; \ + PPC_40x_TURN_OFF_MSR_DR; \ + lwz r9,_DEAR(r1); \ + lwz r10,_ESR(r1); \ + mtspr SPRN_DEAR,r9; \ + mtspr SPRN_ESR,r10; \ + lwz r11,_NIP(r1); \ + lwz r12,_MSR(r1); \ + mtspr exc_lvl_srr0,r11; \ + mtspr exc_lvl_srr1,r12; \ + lwz r9,GPR9(r1); \ + lwz r12,GPR12(r1); \ + lwz r10,GPR10(r1); \ + lwz r11,GPR11(r1); \ + lwz r1,GPR1(r1); \ + PPC405_ERR77_SYNC; \ + exc_lvl_rfi; \ + b .; /* prevent prefetch past exc_lvl_rfi */ + + .globl ret_from_crit_exc +ret_from_crit_exc: + RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI) #ifdef CONFIG_BOOKE -/* - * Return from a machine check interrupt, similar to a critical - * interrupt. - */ .globl ret_from_mcheck_exc ret_from_mcheck_exc: - REST_NVGPRS(r1) - lwz r3,_MSR(r1) - andi. r3,r3,MSR_PR - LOAD_MSR_KERNEL(r10,MSR_KERNEL) - bne user_exc_return - - lwz r0,GPR0(r1) - lwz r2,GPR2(r1) - REST_4GPRS(3, r1) - REST_2GPRS(7, r1) - - lwz r10,_XER(r1) - lwz r11,_CTR(r1) - mtspr SPRN_XER,r10 - mtctr r11 - - stwcx. r0,0,r1 /* to clear the reservation */ - - lwz r11,_LINK(r1) - mtlr r11 - lwz r10,_CCR(r1) - mtcrf 0xff,r10 - lwz r9,_DEAR(r1) - lwz r10,_ESR(r1) - mtspr SPRN_DEAR,r9 - mtspr SPRN_ESR,r10 - lwz r11,_NIP(r1) - lwz r12,_MSR(r1) - mtspr SPRN_MCSRR0,r11 - mtspr SPRN_MCSRR1,r12 - lwz r9,GPR9(r1) - lwz r12,GPR12(r1) - lwz r10,GPR10(r1) - lwz r11,GPR11(r1) - lwz r1,GPR1(r1) - RFMCI + RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI) #endif /* CONFIG_BOOKE */ /* diff --git a/arch/ppc/kernel/head_booke.h b/arch/ppc/kernel/head_booke.h index f213d12eec08..9c50f9d2657c 100644 --- a/arch/ppc/kernel/head_booke.h +++ b/arch/ppc/kernel/head_booke.h @@ -67,46 +67,36 @@ #define CRIT_STACK_TOP (exception_stack_top) #ifdef CONFIG_SMP -#define BOOKE_LOAD_CRIT_STACK \ +#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \ mfspr r8,SPRN_PIR; \ mulli r8,r8,BOOKE_EXCEPTION_STACK_SIZE; \ neg r8,r8; \ - addis r8,r8,CRIT_STACK_TOP@ha; \ - addi r8,r8,CRIT_STACK_TOP@l -#define BOOKE_LOAD_MCHECK_STACK \ - mfspr r8,SPRN_PIR; \ - mulli r8,r8,BOOKE_EXCEPTION_STACK_SIZE; \ - neg r8,r8; \ - addis r8,r8,MCHECK_STACK_TOP@ha; \ - addi r8,r8,MCHECK_STACK_TOP@l + addis r8,r8,level##_STACK_TOP@ha; \ + addi r8,r8,level##_STACK_TOP@l #else -#define BOOKE_LOAD_CRIT_STACK \ - lis r8,CRIT_STACK_TOP@h; \ - ori r8,r8,CRIT_STACK_TOP@l -#define BOOKE_LOAD_MCHECK_STACK \ - lis r8,MCHECK_STACK_TOP@h; \ - ori r8,r8,MCHECK_STACK_TOP@l +#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \ + lis r8,level##_STACK_TOP@h; \ + ori r8,r8,level##_STACK_TOP@l #endif /* - * Exception prolog for critical exceptions. This is a little different - * from the normal exception prolog above since a critical exception - * can potentially occur at any point during normal exception processing. - * Thus we cannot use the same SPRG registers as the normal prolog above. - * Instead we use a portion of the critical exception stack at low physical - * addresses. + * Exception prolog for critical/machine check exceptions. This is a + * little different from the normal exception prolog above since a + * critical/machine check exception can potentially occur at any point + * during normal exception processing. Thus we cannot use the same SPRG + * registers as the normal prolog above. Instead we use a portion of the + * critical/machine check exception stack at low physical addresses. */ - -#define CRITICAL_EXCEPTION_PROLOG \ - mtspr CRIT_SPRG,r8; \ - BOOKE_LOAD_CRIT_STACK; /* r8 points to the crit stack */ \ +#define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, exc_level_srr0, exc_level_srr1) \ + mtspr exc_level##_SPRG,r8; \ + BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);/* r8 points to the exc_level stack*/ \ stw r10,GPR10-INT_FRAME_SIZE(r8); \ stw r11,GPR11-INT_FRAME_SIZE(r8); \ mfcr r10; /* save CR in r10 for now */\ - mfspr r11,SPRN_CSRR1; /* check whether user or kernel */\ + mfspr r11,exc_level_srr1; /* check whether user or kernel */\ andi. r11,r11,MSR_PR; \ mr r11,r8; \ - mfspr r8,CRIT_SPRG; \ + mfspr r8,exc_level##_SPRG; \ beq 1f; \ /* COMING FROM USER MODE */ \ mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\ @@ -122,9 +112,9 @@ stw r12,_DEAR(r11); /* since they may have had stuff */\ mfspr r9,SPRN_ESR; /* in them at the point where the */\ stw r9,_ESR(r11); /* exception was taken */\ - mfspr r12,SPRN_CSRR0; \ + mfspr r12,exc_level_srr0; \ stw r1,GPR1(r11); \ - mfspr r9,SPRN_CSRR1; \ + mfspr r9,exc_level_srr1; \ stw r1,0(r11); \ mr r1,r11; \ rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\ @@ -132,45 +122,10 @@ SAVE_4GPRS(3, r11); \ SAVE_2GPRS(7, r11) -/* - * Exception prolog for machine check exceptions. This is similar to - * the critical exception prolog, except that machine check exceptions - * have their stack. - */ -#define MCHECK_EXCEPTION_PROLOG \ - mtspr MCHECK_SPRG,r8; \ - BOOKE_LOAD_MCHECK_STACK; /* r8 points to the mcheck stack */\ - stw r10,GPR10-INT_FRAME_SIZE(r8); \ - stw r11,GPR11-INT_FRAME_SIZE(r8); \ - mfcr r10; /* save CR in r10 for now */\ - mfspr r11,SPRN_MCSRR1; /* check whether user or kernel */\ - andi. r11,r11,MSR_PR; \ - mr r11,r8; \ - mfspr r8,MCHECK_SPRG; \ - beq 1f; \ - /* COMING FROM USER MODE */ \ - mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\ - lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\ - addi r11,r11,THREAD_SIZE; \ -1: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\ - stw r10,_CCR(r11); /* save various registers */\ - stw r12,GPR12(r11); \ - stw r9,GPR9(r11); \ - mflr r10; \ - stw r10,_LINK(r11); \ - mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\ - stw r12,_DEAR(r11); /* since they may have had stuff */\ - mfspr r9,SPRN_ESR; /* in them at the point where the */\ - stw r9,_ESR(r11); /* exception was taken */\ - mfspr r12,SPRN_MCSRR0; \ - stw r1,GPR1(r11); \ - mfspr r9,SPRN_MCSRR1; \ - stw r1,0(r11); \ - mr r1,r11; \ - rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\ - stw r0,GPR0(r11); \ - SAVE_4GPRS(3, r11); \ - SAVE_2GPRS(7, r11) +#define CRITICAL_EXCEPTION_PROLOG \ + EXC_LEVEL_EXCEPTION_PROLOG(CRIT, SPRN_CSRR0, SPRN_CSRR1) +#define MCHECK_EXCEPTION_PROLOG \ + EXC_LEVEL_EXCEPTION_PROLOG(MCHECK, SPRN_MCSRR0, SPRN_MCSRR1) /* * Exception vectors. @@ -237,7 +192,6 @@ label: EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \ ret_from_except) - /* Check for a single step debug exception while in an exception * handler before state has been saved. This is to catch the case * where an instruction that we are trying to single step causes @@ -291,7 +245,7 @@ label: lwz r9,GPR9(r11); \ lwz r12,GPR12(r11); \ mtspr CRIT_SPRG,r8; \ - BOOKE_LOAD_CRIT_STACK; /* r8 points to the crit stack */ \ + BOOKE_LOAD_EXC_LEVEL_STACK(CRIT); /* r8 points to the debug stack */ \ lwz r10,GPR10-INT_FRAME_SIZE(r8); \ lwz r11,GPR11-INT_FRAME_SIZE(r8); \ mfspr r8,CRIT_SPRG; \ -- cgit v1.2.3-59-g8ed1b From ba8c6d534a0144375f910e764ec965d5e8059f7a Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 21 Jun 2005 17:15:28 -0700 Subject: [PATCH] ppc32: remove some unnecessary includes of prom.h Fight the Good Fight: Limit prom.h header creep. Signed-off-by: Jon Loeliger Signed-off-by: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/platforms/83xx/mpc834x_sys.c | 1 - arch/ppc/platforms/85xx/mpc8540_ads.c | 1 - arch/ppc/platforms/85xx/mpc8560_ads.c | 1 - arch/ppc/platforms/85xx/mpc85xx_ads_common.c | 1 - arch/ppc/platforms/85xx/mpc85xx_cds_common.c | 1 - arch/ppc/platforms/85xx/sbc8560.c | 1 - arch/ppc/platforms/85xx/sbc85xx.c | 1 - arch/ppc/platforms/85xx/stx_gp3.c | 1 - arch/ppc/syslib/open_pic.c | 1 - arch/ppc/syslib/open_pic2.c | 1 - arch/ppc/syslib/ppc83xx_setup.c | 1 - arch/ppc/syslib/ppc85xx_setup.c | 3 ++- 12 files changed, 2 insertions(+), 12 deletions(-) diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c index e6348b5a1ddc..86ca5cf81263 100644 --- a/arch/ppc/platforms/83xx/mpc834x_sys.c +++ b/arch/ppc/platforms/83xx/mpc834x_sys.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c index d1c2c6cb3000..a2ed611cd936 100644 --- a/arch/ppc/platforms/85xx/mpc8540_ads.c +++ b/arch/ppc/platforms/85xx/mpc8540_ads.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.c b/arch/ppc/platforms/85xx/mpc8560_ads.c index 761b8c7b25d2..d87dfd5ce0a2 100644 --- a/arch/ppc/platforms/85xx/mpc8560_ads.c +++ b/arch/ppc/platforms/85xx/mpc8560_ads.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c index 30397623fa6f..18e952d1767c 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c +++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c index 51964b3081eb..203b2ca61df8 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c +++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c index 42e960a0bf33..3dbdd73618eb 100644 --- a/arch/ppc/platforms/85xx/sbc8560.c +++ b/arch/ppc/platforms/85xx/sbc8560.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc/platforms/85xx/sbc85xx.c b/arch/ppc/platforms/85xx/sbc85xx.c index a7cb625b2d0c..4f6d1ddd6fb8 100644 --- a/arch/ppc/platforms/85xx/sbc85xx.c +++ b/arch/ppc/platforms/85xx/sbc85xx.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c index bc0a99638ff6..9455bb6b45e9 100644 --- a/arch/ppc/platforms/85xx/stx_gp3.c +++ b/arch/ppc/platforms/85xx/stx_gp3.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c index 000ba47c67cb..b45d8268bf93 100644 --- a/arch/ppc/syslib/open_pic.c +++ b/arch/ppc/syslib/open_pic.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc/syslib/open_pic2.c b/arch/ppc/syslib/open_pic2.c index ea26da0d8b6b..7e272c51a497 100644 --- a/arch/ppc/syslib/open_pic2.c +++ b/arch/ppc/syslib/open_pic2.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c index 843cf8873e60..602a86891f7f 100644 --- a/arch/ppc/syslib/ppc83xx_setup.c +++ b/arch/ppc/syslib/ppc83xx_setup.c @@ -23,7 +23,6 @@ #include #include -#include #include #include #include diff --git a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c index 455473f589d1..ca95d79a704e 100644 --- a/arch/ppc/syslib/ppc85xx_setup.c +++ b/arch/ppc/syslib/ppc85xx_setup.c @@ -23,7 +23,6 @@ #include #include -#include #include #include #include @@ -33,6 +32,8 @@ #include +extern void abort(void); + /* Return the amount of memory */ unsigned long __init mpc85xx_find_end_of_memory(void) -- cgit v1.2.3-59-g8ed1b From a70d439345875d476ede258094356e2acd09b1a1 Mon Sep 17 00:00:00 2001 From: Jakub Bogusz Date: Tue, 21 Jun 2005 17:15:29 -0700 Subject: [PATCH] ppc32: don't recursively crash in die() on CHRP/PReP machines This patch avoids recursive crash (leading to kernel stack overflow) in die() on CHRP/PReP machines when CONFIG_PMAC_BACKLIGHT=y. set_backlight_* functions are placed in pmac section, which is discarded when _machine != _MACH_Pmac. Signed-off-by: Jakub Bogusz Acked-by: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/kernel/traps.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index c65731e8bc65..2ca8ecfeefd9 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -81,8 +81,10 @@ void die(const char * str, struct pt_regs * fp, long err) console_verbose(); spin_lock_irq(&die_lock); #ifdef CONFIG_PMAC_BACKLIGHT - set_backlight_enable(1); - set_backlight_level(BACKLIGHT_MAX); + if (_machine == _MACH_Pmac) { + set_backlight_enable(1); + set_backlight_level(BACKLIGHT_MAX); + } #endif printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); #ifdef CONFIG_PREEMPT -- cgit v1.2.3-59-g8ed1b From 6879dc137ea4efad65cab8bf8a7c0b742bcf92cc Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 21 Jun 2005 17:15:30 -0700 Subject: [PATCH] ppc32: Kill embedded system.map, use kallsyms This patch kills the whole embedded System.map mecanism and the bootloader-passed System.map that was used to provide symbol resolution in xmon. Instead, xmon now uses kallsyms like ppc64 does. No hurry getting that in Linus tree, let it be tested in -mm for a while first and make sure it doesn't break various embedded configs. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/boot/ld.script | 3 - arch/ppc/boot/openfirmware/Makefile | 5 +- arch/ppc/boot/openfirmware/common.c | 16 --- arch/ppc/boot/simple/Makefile | 4 +- arch/ppc/boot/utils/addSystemMap.c | 186 ------------------------- arch/ppc/kernel/setup.c | 7 - arch/ppc/mm/init.c | 16 +-- arch/ppc/xmon/xmon.c | 270 ++++++++++-------------------------- arch/ppc64/xmon/xmon.c | 9 +- 9 files changed, 84 insertions(+), 432 deletions(-) delete mode 100644 arch/ppc/boot/utils/addSystemMap.c diff --git a/arch/ppc/boot/ld.script b/arch/ppc/boot/ld.script index 6ee602d8b6a0..9362193742ac 100644 --- a/arch/ppc/boot/ld.script +++ b/arch/ppc/boot/ld.script @@ -58,9 +58,6 @@ SECTIONS *(.ramdisk) __ramdisk_end = .; . = ALIGN(4096); - __sysmap_begin = .; - *(.sysmap) - __sysmap_end = .; CONSTRUCTORS } _edata = .; diff --git a/arch/ppc/boot/openfirmware/Makefile b/arch/ppc/boot/openfirmware/Makefile index 4eacbd8c772a..03415238fabf 100644 --- a/arch/ppc/boot/openfirmware/Makefile +++ b/arch/ppc/boot/openfirmware/Makefile @@ -54,13 +54,10 @@ $(images)/ramdisk.image.gz: @echo ' RAM disk image must be provided separately' @/bin/false -objcpxmon-$(CONFIG_XMON) := --add-section=.sysmap=System.map \ - --set-section-flags=.sysmap=contents,alloc,load,readonly,data quiet_cmd_genimage = GEN $@ cmd_genimage = $(OBJCOPY) -R .comment \ --add-section=.image=$(images)/vmlinux.gz \ - --set-section-flags=.image=contents,alloc,load,readonly,data \ - $(objcpxmon-y) $< $@ + --set-section-flags=.image=contents,alloc,load,readonly,data $< $@ targets += image.o $(obj)/image.o: $(obj)/dummy.o $(images)/vmlinux.gz FORCE diff --git a/arch/ppc/boot/openfirmware/common.c b/arch/ppc/boot/openfirmware/common.c index 9e6952781f1f..0f46756a903e 100644 --- a/arch/ppc/boot/openfirmware/common.c +++ b/arch/ppc/boot/openfirmware/common.c @@ -15,7 +15,6 @@ #include /* Information from the linker */ -extern char __sysmap_begin, __sysmap_end; extern int strcmp(const char *s1, const char *s2); extern char *avail_ram, *avail_high; @@ -116,14 +115,8 @@ void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) void make_bi_recs(unsigned long addr, char *name, unsigned int mach, unsigned long progend) { - unsigned long sysmap_size; struct bi_record *rec; - /* Figure out the size of a possible System.map we're going to - * pass along. - * */ - sysmap_size = (unsigned long)(&__sysmap_end) - - (unsigned long)(&__sysmap_begin); /* leave a 1MB gap then align to the next 1MB boundary */ addr = _ALIGN(addr+ (1<<20) - 1, (1<<20)); @@ -147,15 +140,6 @@ void make_bi_recs(unsigned long addr, char *name, unsigned int mach, rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long); rec = (struct bi_record *)((unsigned long)rec + rec->size); - if (sysmap_size) { - rec->tag = BI_SYSMAP; - rec->data[0] = (unsigned long)(&__sysmap_begin); - rec->data[1] = sysmap_size; - rec->size = sizeof(struct bi_record) + 2 * - sizeof(unsigned long); - rec = (struct bi_record *)((unsigned long)rec + rec->size); - } - rec->tag = BI_LAST; rec->size = sizeof(struct bi_record); rec = (struct bi_record *)((unsigned long)rec + rec->size); diff --git a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile index c28061ad5982..991b4cbb83c8 100644 --- a/arch/ppc/boot/simple/Makefile +++ b/arch/ppc/boot/simple/Makefile @@ -203,7 +203,7 @@ $(obj)/zvmlinux: $(OBJS) $(LIBS) $(srctree)/$(boot)/ld.script \ $(obj)/dummy.o $(obj)/image.o $(LD) $(LD_ARGS) -o $@ $(OBJS) $(obj)/image.o $(LIBS) $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab \ - -R .stabstr -R .ramdisk -R .sysmap + -R .stabstr -R .ramdisk $(obj)/zvmlinux.initrd: $(OBJS) $(LIBS) $(srctree)/$(boot)/ld.script \ $(images)/vmlinux.gz $(obj)/dummy.o @@ -215,7 +215,7 @@ $(obj)/zvmlinux.initrd: $(OBJS) $(LIBS) $(srctree)/$(boot)/ld.script \ $(obj)/dummy.o $(obj)/image.o $(LD) $(LD_ARGS) -o $@ $(OBJS) $(obj)/image.o $(LIBS) $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab \ - -R .stabstr -R .sysmap + -R .stabstr # Sort-of dummy rules, that let us format the image we want. zImage: $(images)/$(zimage-y) $(obj)/zvmlinux diff --git a/arch/ppc/boot/utils/addSystemMap.c b/arch/ppc/boot/utils/addSystemMap.c deleted file mode 100644 index 4654f891b274..000000000000 --- a/arch/ppc/boot/utils/addSystemMap.c +++ /dev/null @@ -1,186 +0,0 @@ -#include -#include -#include -#include -#include - -void xlate( char * inb, char * trb, unsigned len ) -{ - unsigned i; - for ( i=0; i> 4; - char c2 = c & 0xf; - if ( c1 > 9 ) - c1 = c1 + 'A' - 10; - else - c1 = c1 + '0'; - if ( c2 > 9 ) - c2 = c2 + 'A' - 10; - else - c2 = c2 + '0'; - *trb++ = c1; - *trb++ = c2; - } - *trb = 0; -} - -#define ElfHeaderSize (64 * 1024) -#define ElfPages (ElfHeaderSize / 4096) -#define KERNELBASE (0xc0000000) - -void get4k( /*istream *inf*/FILE *file, char *buf ) -{ - unsigned j; - unsigned num = fread(buf, 1, 4096, file); - for ( j=num; j<4096; ++j ) - buf[j] = 0; -} - -void put4k( /*ostream *outf*/FILE *file, char *buf ) -{ - fwrite(buf, 1, 4096, file); -} - -int main(int argc, char **argv) -{ - char inbuf[4096]; - FILE *ramDisk = NULL; - FILE *inputVmlinux = NULL; - FILE *outputVmlinux = NULL; - unsigned i = 0; - unsigned long ramFileLen = 0; - unsigned long ramLen = 0; - unsigned long roundR = 0; - unsigned long kernelLen = 0; - unsigned long actualKernelLen = 0; - unsigned long round = 0; - unsigned long roundedKernelLen = 0; - unsigned long ramStartOffs = 0; - unsigned long ramPages = 0; - unsigned long roundedKernelPages = 0; - if ( argc < 2 ) { - printf("Name of System Map file missing.\n"); - exit(1); - } - - if ( argc < 3 ) { - printf("Name of vmlinux file missing.\n"); - exit(1); - } - - if ( argc < 4 ) { - printf("Name of vmlinux output file missing.\n"); - exit(1); - } - - ramDisk = fopen(argv[1], "r"); - if ( ! ramDisk ) { - printf("System Map file \"%s\" failed to open.\n", argv[1]); - exit(1); - } - inputVmlinux = fopen(argv[2], "r"); - if ( ! inputVmlinux ) { - printf("vmlinux file \"%s\" failed to open.\n", argv[2]); - exit(1); - } - outputVmlinux = fopen(argv[3], "w"); - if ( ! outputVmlinux ) { - printf("output vmlinux file \"%s\" failed to open.\n", argv[3]); - exit(1); - } - fseek(ramDisk, 0, SEEK_END); - ramFileLen = ftell(ramDisk); - fseek(ramDisk, 0, SEEK_SET); - printf("%s file size = %ld\n", argv[1], ramFileLen); - - ramLen = ramFileLen; - - roundR = 4096 - (ramLen % 4096); - if ( roundR ) { - printf("Rounding System Map file up to a multiple of 4096, adding %ld\n", roundR); - ramLen += roundR; - } - - printf("Rounded System Map size is %ld\n", ramLen); - fseek(inputVmlinux, 0, SEEK_END); - kernelLen = ftell(inputVmlinux); - fseek(inputVmlinux, 0, SEEK_SET); - printf("kernel file size = %ld\n", kernelLen); - if ( kernelLen == 0 ) { - printf("You must have a linux kernel specified as argv[2]\n"); - exit(1); - } - - actualKernelLen = kernelLen - ElfHeaderSize; - - printf("actual kernel length (minus ELF header) = %ld\n", actualKernelLen); - - round = actualKernelLen % 4096; - roundedKernelLen = actualKernelLen; - if ( round ) - roundedKernelLen += (4096 - round); - - printf("actual kernel length rounded up to a 4k multiple = %ld\n", roundedKernelLen); - - ramStartOffs = roundedKernelLen; - ramPages = ramLen / 4096; - - printf("System map pages to copy = %ld\n", ramPages); - - // Copy 64K ELF header - for (i=0; i<(ElfPages); ++i) { - get4k( inputVmlinux, inbuf ); - put4k( outputVmlinux, inbuf ); - } - - - - roundedKernelPages = roundedKernelLen / 4096; - - fseek(inputVmlinux, ElfHeaderSize, SEEK_SET); - - { - for ( i=0; i= (KERNELBASE)) ? data[0] : - (data[0]+KERNELBASE)); - sysmap_size = data[1]; - break; #ifdef CONFIG_BLK_DEV_INITRD case BI_INITRD: initrd_start = data[0] + KERNELBASE; diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index c8529d004cfa..334ef4150d92 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -96,9 +96,6 @@ extern struct task_struct *current_set[NR_CPUS]; char *klimit = _end; struct mem_pieces phys_avail; -extern char *sysmap; -extern unsigned long sysmap_size; - /* * this tells the system to map all of ram with the segregs * (i.e. page tables) instead of the bats. @@ -442,12 +439,6 @@ void __init mem_init(void) if (agp_special_page) SetPageReserved(virt_to_page(agp_special_page)); #endif - if ( sysmap ) - for (addr = (unsigned long)sysmap; - addr < PAGE_ALIGN((unsigned long)sysmap+sysmap_size) ; - addr += PAGE_SIZE) - SetPageReserved(virt_to_page(addr)); - for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory; addr += PAGE_SIZE) { if (!PageReserved(virt_to_page(addr))) @@ -482,9 +473,7 @@ void __init mem_init(void) codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10), initpages<< (PAGE_SHIFT-10), (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); - if (sysmap) - printk("System.map loaded at 0x%08x for debugger, size: %ld bytes\n", - (unsigned int)sysmap, sysmap_size); + #ifdef CONFIG_PPC_PMAC if (agp_special_page) printk(KERN_INFO "AGP special page: 0x%08lx\n", agp_special_page); @@ -534,9 +523,6 @@ set_phys_avail(unsigned long total_memory) if (rtas_data) mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1); #endif - /* remove the sysmap pages from the available memory */ - if (sysmap) - mem_pieces_remove(&phys_avail, __pa(sysmap), sysmap_size, 1); #ifdef CONFIG_PPC_PMAC /* Because of some uninorth weirdness, we need a page of * memory as high as possible (it must be outside of the diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c index 8565f49b8b0b..be7869e39465 100644 --- a/arch/ppc/xmon/xmon.c +++ b/arch/ppc/xmon/xmon.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -93,8 +94,7 @@ static void take_input(char *); static unsigned read_spr(int); static void write_spr(int, unsigned); static void super_regs(void); -static void print_sysmap(void); -static void sysmap_lookup(void); +static void symbol_lookup(void); static void remove_bpts(void); static void insert_bpts(void); static struct bpt *at_breakpoint(unsigned pc); @@ -103,7 +103,6 @@ static void cacheflush(void); #ifdef CONFIG_SMP static void cpu_cmd(void); #endif /* CONFIG_SMP */ -static int pretty_print_addr(unsigned long addr); static void csum(void); #ifdef CONFIG_BOOTX_TEXT static void vidcmds(void); @@ -120,8 +119,6 @@ extern void longjmp(u_int *, int); extern void xmon_enter(void); extern void xmon_leave(void); -extern char* xmon_find_symbol(unsigned long addr, unsigned long* saddr); -extern unsigned long xmon_symbol_to_addr(char* symbol); static unsigned start_tb[NR_CPUS][2]; static unsigned stop_tb[NR_CPUS][2]; @@ -148,7 +145,6 @@ Commands:\n\ mm move a block of memory\n\ ms set a block of memory\n\ md compare two blocks of memory\n\ - M print System.map\n\ r print registers\n\ S print special registers\n\ t print backtrace\n\ @@ -175,6 +171,35 @@ extern inline void __delay(unsigned int loops) "r" (loops) : "ctr"); } +/* Print an address in numeric and symbolic form (if possible) */ +static void xmon_print_symbol(unsigned long address, const char *mid, + const char *after) +{ + char *modname; + const char *name = NULL; + unsigned long offset, size; + static char tmpstr[128]; + + printf("%.8lx", address); + if (setjmp(bus_error_jmp) == 0) { + debugger_fault_handler = handle_fault; + sync(); + name = kallsyms_lookup(address, &size, &offset, &modname, + tmpstr); + sync(); + /* wait a little while to see if we get a machine check */ + __delay(200); + } + debugger_fault_handler = NULL; + + if (name) { + printf("%s%s+%#lx/%#lx", mid, name, offset, size); + if (modname) + printf(" [%s]", modname); + } + printf("%s", after); +} + static void get_tb(unsigned *p) { unsigned hi, lo, hiagain; @@ -454,7 +479,7 @@ cmds(struct pt_regs *excp) dump(); break; case 'l': - sysmap_lookup(); + symbol_lookup(); break; case 'r': if (excp != NULL) @@ -466,9 +491,6 @@ cmds(struct pt_regs *excp) else excprint(excp); break; - case 'M': - print_sysmap(); - break; case 'S': super_regs(); break; @@ -825,20 +847,19 @@ backtrace(struct pt_regs *excp) for (; sp != 0; sp = stack[0]) { if (mread(sp, stack, sizeof(stack)) != sizeof(stack)) break; - pretty_print_addr(stack[1]); - printf(" "); + printf("[%.8lx] ", stack); + xmon_print_symbol(stack[1], " ", "\n"); if (stack[1] == (unsigned) &ret_from_except || stack[1] == (unsigned) &ret_from_except_full || stack[1] == (unsigned) &ret_from_syscall) { if (mread(sp+16, ®s, sizeof(regs)) != sizeof(regs)) break; - printf("\nexception:%x [%x] %x ", regs.trap, sp+16, + printf("exception:%x [%x] %x\n", regs.trap, sp+16, regs.nip); sp = regs.gpr[1]; if (mread(sp, stack, sizeof(stack)) != sizeof(stack)) break; } - printf("\n"); } } @@ -859,11 +880,10 @@ excprint(struct pt_regs *fp) #ifdef CONFIG_SMP printf("cpu %d: ", smp_processor_id()); #endif /* CONFIG_SMP */ - printf("vector: %x at pc = ", fp->trap); - pretty_print_addr(fp->nip); - printf(", lr = "); - pretty_print_addr(fp->link); - printf("\nmsr = %x, sp = %x [%x]\n", fp->msr, fp->gpr[1], fp); + printf("vector: %x at pc=", fp->trap); + xmon_print_symbol(fp->nip, ": ", ", lr="); + xmon_print_symbol(fp->link, ": ", "\n"); + printf("msr = %x, sp = %x [%x]\n", fp->msr, fp->gpr[1], fp); trap = TRAP(fp); if (trap == 0x300 || trap == 0x600) printf("dar = %x, dsisr = %x\n", fp->dar, fp->dsisr); @@ -950,24 +970,6 @@ static unsigned int regno; extern char exc_prolog; extern char dec_exc; -void -print_sysmap(void) -{ - extern char *sysmap; - if ( sysmap ) { - printf("System.map: \n"); - if( setjmp(bus_error_jmp) == 0 ) { - debugger_fault_handler = handle_fault; - sync(); - xmon_puts(sysmap); - sync(); - } - debugger_fault_handler = NULL; - } - else - printf("No System.map\n"); -} - void super_regs(void) { @@ -1738,7 +1740,7 @@ scanhex(unsigned *vp) printf("invalid register name '%%%s'\n", regname); return 0; } else if (c == '$') { - static char symname[64]; + static char symname[128]; int i; for (i=0; i<63; i++) { c = inchar(); @@ -1749,7 +1751,14 @@ scanhex(unsigned *vp) symname[i] = c; } symname[i++] = 0; - *vp = xmon_symbol_to_addr(symname); + *vp = 0; + if (setjmp(bus_error_jmp) == 0) { + debugger_fault_handler = handle_fault; + sync(); + *vp = kallsyms_lookup_name(symname); + sync(); + } + debugger_fault_handler = NULL; if (!(*vp)) { printf("unknown symbol\n"); return 0; @@ -1840,169 +1849,34 @@ take_input(char *str) lineptr = str; } -void -sysmap_lookup(void) +static void +symbol_lookup(void) { int type = inchar(); unsigned addr; - static char tmp[64]; - char* cur; - - extern char *sysmap; - extern unsigned long sysmap_size; - if ( !sysmap || !sysmap_size ) - return; - - switch(type) { - case 'a': - if (scanhex(&addr)) { - pretty_print_addr(addr); - printf("\n"); - } - termch = 0; - break; - case 's': - getstring(tmp, 64); - if( setjmp(bus_error_jmp) == 0 ) { - debugger_fault_handler = handle_fault; - sync(); - cur = sysmap; - do { - cur = strstr(cur, tmp); - if (cur) { - static char res[64]; - char *p, *d; - p = cur; - while(p > sysmap && *p != 10) - p--; - if (*p == 10) p++; - d = res; - while(*p && p < (sysmap + sysmap_size) && *p != 10) - *(d++) = *(p++); - *(d++) = 0; - printf("%s\n", res); - cur++; - } - } while (cur); - sync(); - } - debugger_fault_handler = NULL; - termch = 0; - break; - } -} + static char tmp[128]; -static int -pretty_print_addr(unsigned long addr) -{ - char *sym; - unsigned long saddr; - - printf("%08x", addr); - sym = xmon_find_symbol(addr, &saddr); - if (sym) - printf(" (%s+0x%x)", sym, addr-saddr); - return (sym != 0); -} - -char* -xmon_find_symbol(unsigned long addr, unsigned long* saddr) -{ - static char rbuffer[64]; - char *p, *ep, *limit; - unsigned long prev, next; - char* psym; - - extern char *sysmap; - extern unsigned long sysmap_size; - if ( !sysmap || !sysmap_size ) - return NULL; - - prev = 0; - psym = NULL; - p = sysmap; - limit = p + sysmap_size; - if( setjmp(bus_error_jmp) == 0 ) { - debugger_fault_handler = handle_fault; - sync(); - do { - next = simple_strtoul(p, &p, 16); - if (next > addr && prev <= addr) { - if (!psym) - goto bail; - ep = rbuffer; - p = psym; - while(*p && p < limit && *p == 32) - p++; - while(*p && p < limit && *p != 10 && (ep - rbuffer) < 63) - *(ep++) = *(p++); - *(ep++) = 0; - if (saddr) - *saddr = prev; - debugger_fault_handler = NULL; - return rbuffer; - } - prev = next; - psym = p; - while(*p && p < limit && *p != 10) - p++; - if (*p) p++; - } while(*p && p < limit && next); -bail: - sync(); + switch (type) { + case 'a': + if (scanhex(&addr)) + xmon_print_symbol(addr, ": ", "\n"); + termch = 0; + break; + case 's': + getstring(tmp, 64); + if (setjmp(bus_error_jmp) == 0) { + debugger_fault_handler = handle_fault; + sync(); + addr = kallsyms_lookup_name(tmp); + if (addr) + printf("%s: %lx\n", tmp, addr); + else + printf("Symbol '%s' not found.\n", tmp); + sync(); + } + debugger_fault_handler = NULL; + termch = 0; + break; } - debugger_fault_handler = NULL; - return NULL; } -unsigned long -xmon_symbol_to_addr(char* symbol) -{ - char *p, *cur; - char *match = NULL; - int goodness = 0; - int result = 0; - - extern char *sysmap; - extern unsigned long sysmap_size; - if ( !sysmap || !sysmap_size ) - return 0; - - if( setjmp(bus_error_jmp) == 0 ) { - debugger_fault_handler = handle_fault; - sync(); - cur = sysmap; - while(cur) { - cur = strstr(cur, symbol); - if (cur) { - int gd = 1; - - /* best match if equal, better match if - * begins with - */ - if (cur == sysmap || *(cur-1) == ' ') { - gd++; - if (cur[strlen(symbol)] == 10) - gd++; - } - if (gd > goodness) { - match = cur; - goodness = gd; - if (gd == 3) - break; - } - cur++; - } - } - if (goodness) { - p = match; - while(p > sysmap && *p != 10) - p--; - if (*p == 10) p++; - result = simple_strtoul(p, &p, 16); - } - sync(); - } - debugger_fault_handler = NULL; - return result; -} diff --git a/arch/ppc64/xmon/xmon.c b/arch/ppc64/xmon/xmon.c index 3c0ccb2623ae..7f6e13a4b71e 100644 --- a/arch/ppc64/xmon/xmon.c +++ b/arch/ppc64/xmon/xmon.c @@ -2247,7 +2247,14 @@ scanhex(unsigned long *vp) tmpstr[i] = c; } tmpstr[i++] = 0; - *vp = kallsyms_lookup_name(tmpstr); + *vp = 0; + if (setjmp(bus_error_jmp) == 0) { + catch_memory_errors = 1; + sync(); + *vp = kallsyms_lookup_name(tmpstr); + sync(); + } + catch_memory_errors = 0; if (!(*vp)) { printf("unknown symbol '%s'\n", tmpstr); return 0; -- cgit v1.2.3-59-g8ed1b From 20cee16ced631f70a62c97bdebae08a1c9470448 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 21 Jun 2005 17:15:31 -0700 Subject: [PATCH] ppc64: Abolish ioremap_mm Currently ppc64 has two mm_structs for the kernel, init_mm and also ioremap_mm. The latter really isn't necessary: this patch abolishes it, instead restricting vmallocs to the lower 1TB of the init_mm's range and placing io mappings in the upper 1TB. This simplifies the code in a number of places and eliminates an unecessary set of pagetables. It also tweaks the unmap/free path a little, allowing us to remove the unmap_im_area() set of page table walkers, replacing them with unmap_vm_area(). Signed-off-by: David Gibson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/eeh.c | 2 +- arch/ppc64/kernel/head.S | 4 -- arch/ppc64/kernel/process.c | 8 ---- arch/ppc64/mm/hash_utils.c | 4 -- arch/ppc64/mm/imalloc.c | 20 ++++++---- arch/ppc64/mm/init.c | 93 +++++-------------------------------------- include/asm-ppc64/imalloc.h | 12 +++--- include/asm-ppc64/page.h | 2 - include/asm-ppc64/pgtable.h | 9 +---- include/asm-ppc64/processor.h | 10 ----- 10 files changed, 31 insertions(+), 133 deletions(-) diff --git a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c index d63d41f3eecf..af5272fedadf 100644 --- a/arch/ppc64/kernel/eeh.c +++ b/arch/ppc64/kernel/eeh.c @@ -505,7 +505,7 @@ static inline unsigned long eeh_token_to_phys(unsigned long token) pte_t *ptep; unsigned long pa; - ptep = find_linux_pte(ioremap_mm.pgd, token); + ptep = find_linux_pte(init_mm.pgd, token); if (!ptep) return token; pa = pte_pfn(*ptep) << PAGE_SHIFT; diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 346dbf606b5d..02c8f4e3e4bc 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S @@ -2121,10 +2121,6 @@ empty_zero_page: swapper_pg_dir: .space 4096 - .globl ioremap_dir -ioremap_dir: - .space 4096 - #ifdef CONFIG_SMP /* 1 page segment table per cpu (max 48, cpu0 allocated at STAB0_PHYS_ADDR) */ .globl stab_array diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c index cdfecbeb331f..aba89554d89d 100644 --- a/arch/ppc64/kernel/process.c +++ b/arch/ppc64/kernel/process.c @@ -58,14 +58,6 @@ struct task_struct *last_task_used_math = NULL; struct task_struct *last_task_used_altivec = NULL; #endif -struct mm_struct ioremap_mm = { - .pgd = ioremap_dir, - .mm_users = ATOMIC_INIT(2), - .mm_count = ATOMIC_INIT(1), - .cpu_vm_mask = CPU_MASK_ALL, - .page_table_lock = SPIN_LOCK_UNLOCKED, -}; - /* * Make sure the floating-point register state in the * the thread_struct is up to date for task tsk. diff --git a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c index 0a0f97008d02..87d0525f56fa 100644 --- a/arch/ppc64/mm/hash_utils.c +++ b/arch/ppc64/mm/hash_utils.c @@ -310,10 +310,6 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) vsid = get_vsid(mm->context.id, ea); break; - case IO_REGION_ID: - mm = &ioremap_mm; - vsid = get_kernel_vsid(ea); - break; case VMALLOC_REGION_ID: mm = &init_mm; vsid = get_kernel_vsid(ea); diff --git a/arch/ppc64/mm/imalloc.c b/arch/ppc64/mm/imalloc.c index cb8727f3267a..b6e75b891ac0 100644 --- a/arch/ppc64/mm/imalloc.c +++ b/arch/ppc64/mm/imalloc.c @@ -15,6 +15,7 @@ #include #include #include +#include static DECLARE_MUTEX(imlist_sem); struct vm_struct * imlist = NULL; @@ -285,29 +286,32 @@ struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size, return area; } -unsigned long im_free(void * addr) +void im_free(void * addr) { struct vm_struct **p, *tmp; - unsigned long ret_size = 0; if (!addr) - return ret_size; - if ((PAGE_SIZE-1) & (unsigned long) addr) { + return; + if ((unsigned long) addr & ~PAGE_MASK) { printk(KERN_ERR "Trying to %s bad address (%p)\n", __FUNCTION__, addr); - return ret_size; + return; } down(&imlist_sem); for (p = &imlist ; (tmp = *p) ; p = &tmp->next) { if (tmp->addr == addr) { - ret_size = tmp->size; *p = tmp->next; + + /* XXX: do we need the lock? */ + spin_lock(&init_mm.page_table_lock); + unmap_vm_area(tmp); + spin_unlock(&init_mm.page_table_lock); + kfree(tmp); up(&imlist_sem); - return ret_size; + return; } } up(&imlist_sem); printk(KERN_ERR "Trying to %s nonexistent area (%p)\n", __FUNCTION__, addr); - return ret_size; } diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c index 4b42aff74d73..6fa1e6490b57 100644 --- a/arch/ppc64/mm/init.c +++ b/arch/ppc64/mm/init.c @@ -73,9 +73,6 @@ static unsigned long phbs_io_bot = PHBS_IO_BASE; extern pgd_t swapper_pg_dir[]; extern struct task_struct *current_set[NR_CPUS]; -extern pgd_t ioremap_dir[]; -pgd_t * ioremap_pgd = (pgd_t *)&ioremap_dir; - unsigned long klimit = (unsigned long)_end; unsigned long _SDR1=0; @@ -137,69 +134,6 @@ void iounmap(volatile void __iomem *addr) #else -static void unmap_im_area_pte(pmd_t *pmd, unsigned long addr, - unsigned long end) -{ - pte_t *pte; - - pte = pte_offset_kernel(pmd, addr); - do { - pte_t ptent = ptep_get_and_clear(&ioremap_mm, addr, pte); - WARN_ON(!pte_none(ptent) && !pte_present(ptent)); - } while (pte++, addr += PAGE_SIZE, addr != end); -} - -static inline void unmap_im_area_pmd(pud_t *pud, unsigned long addr, - unsigned long end) -{ - pmd_t *pmd; - unsigned long next; - - pmd = pmd_offset(pud, addr); - do { - next = pmd_addr_end(addr, end); - if (pmd_none_or_clear_bad(pmd)) - continue; - unmap_im_area_pte(pmd, addr, next); - } while (pmd++, addr = next, addr != end); -} - -static inline void unmap_im_area_pud(pgd_t *pgd, unsigned long addr, - unsigned long end) -{ - pud_t *pud; - unsigned long next; - - pud = pud_offset(pgd, addr); - do { - next = pud_addr_end(addr, end); - if (pud_none_or_clear_bad(pud)) - continue; - unmap_im_area_pmd(pud, addr, next); - } while (pud++, addr = next, addr != end); -} - -static void unmap_im_area(unsigned long addr, unsigned long end) -{ - struct mm_struct *mm = &ioremap_mm; - unsigned long next; - pgd_t *pgd; - - spin_lock(&mm->page_table_lock); - - pgd = pgd_offset_i(addr); - flush_cache_vunmap(addr, end); - do { - next = pgd_addr_end(addr, end); - if (pgd_none_or_clear_bad(pgd)) - continue; - unmap_im_area_pud(pgd, addr, next); - } while (pgd++, addr = next, addr != end); - flush_tlb_kernel_range(start, end); - - spin_unlock(&mm->page_table_lock); -} - /* * map_io_page currently only called by __ioremap * map_io_page adds an entry to the ioremap page table @@ -214,21 +148,21 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags) unsigned long vsid; if (mem_init_done) { - spin_lock(&ioremap_mm.page_table_lock); - pgdp = pgd_offset_i(ea); - pudp = pud_alloc(&ioremap_mm, pgdp, ea); + spin_lock(&init_mm.page_table_lock); + pgdp = pgd_offset_k(ea); + pudp = pud_alloc(&init_mm, pgdp, ea); if (!pudp) return -ENOMEM; - pmdp = pmd_alloc(&ioremap_mm, pudp, ea); + pmdp = pmd_alloc(&init_mm, pudp, ea); if (!pmdp) return -ENOMEM; - ptep = pte_alloc_kernel(&ioremap_mm, pmdp, ea); + ptep = pte_alloc_kernel(&init_mm, pmdp, ea); if (!ptep) return -ENOMEM; pa = abs_to_phys(pa); - set_pte_at(&ioremap_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT, + set_pte_at(&init_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT, __pgprot(flags))); - spin_unlock(&ioremap_mm.page_table_lock); + spin_unlock(&init_mm.page_table_lock); } else { unsigned long va, vpn, hash, hpteg; @@ -267,13 +201,9 @@ static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa, for (i = 0; i < size; i += PAGE_SIZE) if (map_io_page(ea+i, pa+i, flags)) - goto failure; + return NULL; return (void __iomem *) (ea + (addr & ~PAGE_MASK)); - failure: - if (mem_init_done) - unmap_im_area(ea, ea + size); - return NULL; } @@ -381,19 +311,14 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea, */ void iounmap(volatile void __iomem *token) { - unsigned long address, size; void *addr; if (!mem_init_done) return; addr = (void *) ((unsigned long __force) token & PAGE_MASK); - - if ((size = im_free(addr)) == 0) - return; - address = (unsigned long)addr; - unmap_im_area(address, address + size); + im_free(addr); } static int iounmap_subset_regions(unsigned long addr, unsigned long size) diff --git a/include/asm-ppc64/imalloc.h b/include/asm-ppc64/imalloc.h index 3a45e918bf16..e46ff68a6e41 100644 --- a/include/asm-ppc64/imalloc.h +++ b/include/asm-ppc64/imalloc.h @@ -4,9 +4,9 @@ /* * Define the address range of the imalloc VM area. */ -#define PHBS_IO_BASE IOREGIONBASE -#define IMALLOC_BASE (IOREGIONBASE + 0x80000000ul) /* Reserve 2 gigs for PHBs */ -#define IMALLOC_END (IOREGIONBASE + EADDR_MASK) +#define PHBS_IO_BASE VMALLOC_END +#define IMALLOC_BASE (PHBS_IO_BASE + 0x80000000ul) /* Reserve 2 gigs for PHBs */ +#define IMALLOC_END (VMALLOC_START + EADDR_MASK) /* imalloc region types */ @@ -18,7 +18,9 @@ extern struct vm_struct * im_get_free_area(unsigned long size); extern struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size, - int region_type); -unsigned long im_free(void *addr); + int region_type); +extern void im_free(void *addr); + +extern unsigned long ioremap_bot; #endif /* _PPC64_IMALLOC_H */ diff --git a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h index bcd21789d3b7..257d87eb7c34 100644 --- a/include/asm-ppc64/page.h +++ b/include/asm-ppc64/page.h @@ -202,9 +202,7 @@ extern u64 ppc64_pft_size; /* Log 2 of page table size */ #define PAGE_OFFSET ASM_CONST(0xC000000000000000) #define KERNELBASE PAGE_OFFSET #define VMALLOCBASE ASM_CONST(0xD000000000000000) -#define IOREGIONBASE ASM_CONST(0xE000000000000000) -#define IO_REGION_ID (IOREGIONBASE >> REGION_SHIFT) #define VMALLOC_REGION_ID (VMALLOCBASE >> REGION_SHIFT) #define KERNEL_REGION_ID (KERNELBASE >> REGION_SHIFT) #define USER_REGION_ID (0UL) diff --git a/include/asm-ppc64/pgtable.h b/include/asm-ppc64/pgtable.h index 264c4f7993be..46cf61c2ff69 100644 --- a/include/asm-ppc64/pgtable.h +++ b/include/asm-ppc64/pgtable.h @@ -53,7 +53,8 @@ * Define the address range of the vmalloc VM area. */ #define VMALLOC_START (0xD000000000000000ul) -#define VMALLOC_END (VMALLOC_START + EADDR_MASK) +#define VMALLOC_SIZE (0x10000000000UL) +#define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE) /* * Bits in a linux-style PTE. These match the bits in the @@ -239,9 +240,6 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) /* This now only contains the vmalloc pages */ #define pgd_offset_k(address) pgd_offset(&init_mm, address) -/* to find an entry in the ioremap page-table-directory */ -#define pgd_offset_i(address) (ioremap_pgd + pgd_index(address)) - /* * The following only work if pte_present() is true. * Undefined behaviour if not.. @@ -459,15 +457,12 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr, #define __HAVE_ARCH_PTE_SAME #define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0) -extern unsigned long ioremap_bot, ioremap_base; - #define pmd_ERROR(e) \ printk("%s:%d: bad pmd %08x.\n", __FILE__, __LINE__, pmd_val(e)) #define pgd_ERROR(e) \ printk("%s:%d: bad pgd %08x.\n", __FILE__, __LINE__, pgd_val(e)) extern pgd_t swapper_pg_dir[]; -extern pgd_t ioremap_dir[]; extern void paging_init(void); diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h index 809c634ba1df..3084099086a8 100644 --- a/include/asm-ppc64/processor.h +++ b/include/asm-ppc64/processor.h @@ -429,16 +429,6 @@ struct thread_struct { .fpexc_mode = MSR_FE0|MSR_FE1, \ } -/* - * Note: the vm_start and vm_end fields here should *not* - * be in kernel space. (Could vm_end == vm_start perhaps?) - */ -#define IOREMAP_MMAP { &ioremap_mm, 0, 0x1000, NULL, \ - PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, \ - 1, NULL, NULL } - -extern struct mm_struct ioremap_mm; - /* * Return saved PC of a blocked thread. For now, this is the "user" PC */ -- cgit v1.2.3-59-g8ed1b From 723e2b35e43dcbcfd737c40453caa7d198092d23 Mon Sep 17 00:00:00 2001 From: Sven Luther Date: Tue, 21 Jun 2005 17:15:32 -0700 Subject: [PATCH] ppc64: override command line AS/LD/CC variables when adding -m64 and co for biarch compilers The following kind of calls currently fails : make ARCH=ppc64 CC="gcc-3.4" Since the code for detecting a biarch compiler and adding the needed 64bit magic argument fails if the AS/LD/CC commands are overriden in the command line. The attached patch fixes this by using the make override and += directive, but i am not 100% sure this will work without gmake, as i am no Makefile expert. Cc: Paul Mackerras Cc: Anton Blanchard Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index 691f3008e698..33c752ceca4b 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile @@ -35,9 +35,9 @@ CROSS32AS := $(AS) -a32 CROSS32LD := $(LD) -m elf32ppc CROSS32OBJCOPY := $(OBJCOPY) endif -AS := $(AS) -a64 -LD := $(LD) -m elf64ppc -CC := $(CC) -m64 +override AS += -a64 +override LD += -m elf64ppc +override CC += -m64 endif export CROSS32CC CROSS32AS CROSS32LD CROSS32OBJCOPY -- cgit v1.2.3-59-g8ed1b From 0e3e4a1c4dade7872fdb04a5e735ae26d8e2fbfb Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:33 -0700 Subject: [PATCH] ppc64 iSeries: remove iSeries_proc.h include/asm-ppc64/iSeries/iSeries_proc.h just contains a declaration of a function that no longer exists. Remove it. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/iSeries_proc.c | 1 - arch/ppc64/kernel/iSeries_setup.c | 1 - arch/ppc64/kernel/viopath.c | 1 - include/asm-ppc64/iSeries/iSeries_proc.h | 24 ------------------------ 4 files changed, 27 deletions(-) delete mode 100644 include/asm-ppc64/iSeries/iSeries_proc.h diff --git a/arch/ppc64/kernel/iSeries_proc.c b/arch/ppc64/kernel/iSeries_proc.c index 0cc58ddf48de..bf85a1f7e870 100644 --- a/arch/ppc64/kernel/iSeries_proc.c +++ b/arch/ppc64/kernel/iSeries_proc.c @@ -29,7 +29,6 @@ #include #include #include -#include static int __init iseries_proc_create(void) { diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 6d06eb550a3f..e80cfc570929 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -55,7 +55,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc64/kernel/viopath.c b/arch/ppc64/kernel/viopath.c index 2ed8ee075680..8caa078a658a 100644 --- a/arch/ppc64/kernel/viopath.c +++ b/arch/ppc64/kernel/viopath.c @@ -48,7 +48,6 @@ #include #include #include -#include #include /* Status of the path to each other partition in the system. diff --git a/include/asm-ppc64/iSeries/iSeries_proc.h b/include/asm-ppc64/iSeries/iSeries_proc.h deleted file mode 100644 index adb6dc14dd4d..000000000000 --- a/include/asm-ppc64/iSeries/iSeries_proc.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * iSeries_proc.h - * Copyright (C) 2001 Kyle A. Lucke IBM Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef _ISERIES_PROC_H -#define _ISERIES_PROC_H - -extern void iSeries_proc_early_init(void); - -#endif /* _iSeries_PROC_H */ -- cgit v1.2.3-59-g8ed1b From 45dc76aaf63fc336527da80337d3e3684f50f387 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:33 -0700 Subject: [PATCH] ppc64 iSeries: header file white space cleanups This patch just contains white space and comment cleanups in the iSeries headers files. There are no semantic changes. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-ppc64/iSeries/HvCall.h | 100 ++++----- include/asm-ppc64/iSeries/HvCallCfg.h | 116 +++++----- include/asm-ppc64/iSeries/HvCallEvent.h | 29 ++- include/asm-ppc64/iSeries/HvCallHpt.h | 89 ++++---- include/asm-ppc64/iSeries/HvCallPci.h | 340 +++++++++++++----------------- include/asm-ppc64/iSeries/HvCallSc.h | 38 ++-- include/asm-ppc64/iSeries/HvCallSm.h | 31 +-- include/asm-ppc64/iSeries/HvCallXm.h | 63 ++---- include/asm-ppc64/iSeries/HvLpConfig.h | 291 +++++++++++++------------ include/asm-ppc64/iSeries/HvLpEvent.h | 116 +++++----- include/asm-ppc64/iSeries/HvReleaseData.h | 76 ++++--- include/asm-ppc64/iSeries/HvTypes.h | 108 +++++----- 12 files changed, 644 insertions(+), 753 deletions(-) diff --git a/include/asm-ppc64/iSeries/HvCall.h b/include/asm-ppc64/iSeries/HvCall.h index d9a2e74e2399..c903387e9128 100644 --- a/include/asm-ppc64/iSeries/HvCall.h +++ b/include/asm-ppc64/iSeries/HvCall.h @@ -1,34 +1,28 @@ /* * HvCall.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 */ - -//=========================================================================== -// -// This file contains the "hypervisor call" interface which is used to -// drive the hypervisor from the OS. -// -//=========================================================================== +/* + * This file contains the "hypervisor call" interface which is used to + * drive the hypervisor from the OS. + */ #ifndef _HVCALL_H #define _HVCALL_H -//------------------------------------------------------------------- -// Standard Includes -//------------------------------------------------------------------- #include #include #include @@ -76,9 +70,9 @@ enum HvCall_VaryOffChunkRc */ /* Type of yield for HvCallBaseYieldProcessor */ -#define HvCall_YieldTimed 0 // Yield until specified time (tb) -#define HvCall_YieldToActive 1 // Yield until all active procs have run -#define HvCall_YieldToProc 2 // Yield until the specified processor has run +#define HvCall_YieldTimed 0 /* Yield until specified time (tb) */ +#define HvCall_YieldToActive 1 /* Yield until all active procs have run */ +#define HvCall_YieldToProc 2 /* Yield until the specified processor has run */ /* interrupt masks for setEnabledInterrupts */ #define HvCall_MaskIPI 0x00000001 @@ -86,7 +80,7 @@ enum HvCall_VaryOffChunkRc #define HvCall_MaskLpProd 0x00000004 #define HvCall_MaskTimeout 0x00000008 -/* Log buffer formats */ +/* Log buffer formats */ #define HvCall_LogBuffer_ASCII 0 #define HvCall_LogBuffer_EBCDIC 1 @@ -95,7 +89,7 @@ enum HvCall_VaryOffChunkRc #define HvCallBaseGetHwPatch HvCallBase + 2 #define HvCallBaseReIplSpAttn HvCallBase + 3 #define HvCallBaseSetASR HvCallBase + 4 -#define HvCallBaseSetASRAndRfi HvCallBase + 5 +#define HvCallBaseSetASRAndRfi HvCallBase + 5 #define HvCallBaseSetIMR HvCallBase + 6 #define HvCallBaseSendIPI HvCallBase + 7 #define HvCallBaseTerminateMachine HvCallBase + 8 @@ -115,81 +109,75 @@ enum HvCall_VaryOffChunkRc #define HvCallBaseGetLogBufferCodePage HvCallBase + 22 #define HvCallBaseGetLogBufferFormat HvCallBase + 23 #define HvCallBaseGetLogBufferLength HvCallBase + 24 -#define HvCallBaseReadLogBuffer HvCallBase + 25 +#define HvCallBaseReadLogBuffer HvCallBase + 25 #define HvCallBaseSetLogBufferFormatAndCodePage HvCallBase + 26 -#define HvCallBaseWriteLogBuffer HvCallBase + 27 +#define HvCallBaseWriteLogBuffer HvCallBase + 27 #define HvCallBaseRouter28 HvCallBase + 28 #define HvCallBaseRouter29 HvCallBase + 29 #define HvCallBaseRouter30 HvCallBase + 30 -#define HvCallBaseSetDebugBus HvCallBase + 31 +#define HvCallBaseSetDebugBus HvCallBase + 31 -#define HvCallCcSetDABR HvCallCc + 7 +#define HvCallCcSetDABR HvCallCc + 7 -//===================================================================================== -static inline void HvCall_setVirtualDecr(void) +static inline void HvCall_setVirtualDecr(void) { - /* Ignore any error return codes - most likely means that the target value for the - * LP has been increased and this vary off would bring us below the new target. */ + /* + * Ignore any error return codes - most likely means that the + * target value for the LP has been increased and this vary off + * would bring us below the new target. + */ HvCall0(HvCallBaseSetVirtualDecr); } -//===================================================================== -static inline void HvCall_yieldProcessor(unsigned typeOfYield, u64 yieldParm) + +static inline void HvCall_yieldProcessor(unsigned typeOfYield, u64 yieldParm) { - HvCall2( HvCallBaseYieldProcessor, typeOfYield, yieldParm ); + HvCall2(HvCallBaseYieldProcessor, typeOfYield, yieldParm); } -//===================================================================== -static inline void HvCall_setEnabledInterrupts(u64 enabledInterrupts) + +static inline void HvCall_setEnabledInterrupts(u64 enabledInterrupts) { - HvCall1(HvCallBaseSetEnabledInterrupts,enabledInterrupts); + HvCall1(HvCallBaseSetEnabledInterrupts, enabledInterrupts); } -//===================================================================== -static inline void HvCall_clearLogBuffer(HvLpIndex lpindex) +static inline void HvCall_clearLogBuffer(HvLpIndex lpindex) { - HvCall1(HvCallBaseClearLogBuffer,lpindex); + HvCall1(HvCallBaseClearLogBuffer, lpindex); } -//===================================================================== -static inline u32 HvCall_getLogBufferCodePage(HvLpIndex lpindex) +static inline u32 HvCall_getLogBufferCodePage(HvLpIndex lpindex) { - u32 retVal = HvCall1(HvCallBaseGetLogBufferCodePage,lpindex); + u32 retVal = HvCall1(HvCallBaseGetLogBufferCodePage, lpindex); return retVal; } -//===================================================================== -static inline int HvCall_getLogBufferFormat(HvLpIndex lpindex) +static inline int HvCall_getLogBufferFormat(HvLpIndex lpindex) { - int retVal = HvCall1(HvCallBaseGetLogBufferFormat,lpindex); + int retVal = HvCall1(HvCallBaseGetLogBufferFormat, lpindex); return retVal; } -//===================================================================== -static inline u32 HvCall_getLogBufferLength(HvLpIndex lpindex) +static inline u32 HvCall_getLogBufferLength(HvLpIndex lpindex) { - u32 retVal = HvCall1(HvCallBaseGetLogBufferLength,lpindex); + u32 retVal = HvCall1(HvCallBaseGetLogBufferLength, lpindex); return retVal; } -//===================================================================== -static inline void HvCall_setLogBufferFormatAndCodepage(int format, u32 codePage) +static inline void HvCall_setLogBufferFormatAndCodepage(int format, u32 codePage) { - HvCall2(HvCallBaseSetLogBufferFormatAndCodePage,format, codePage); + HvCall2(HvCallBaseSetLogBufferFormatAndCodePage, format, codePage); } -//===================================================================== -int HvCall_readLogBuffer(HvLpIndex lpindex, void *buffer, u64 bufLen); -void HvCall_writeLogBuffer(const void *buffer, u64 bufLen); +extern int HvCall_readLogBuffer(HvLpIndex lpindex, void *buffer, u64 bufLen); +extern void HvCall_writeLogBuffer(const void *buffer, u64 bufLen); -//===================================================================== -static inline void HvCall_sendIPI(struct paca_struct * targetPaca) +static inline void HvCall_sendIPI(struct paca_struct *targetPaca) { - HvCall1( HvCallBaseSendIPI, targetPaca->paca_index ); + HvCall1(HvCallBaseSendIPI, targetPaca->paca_index); } -//===================================================================== -static inline void HvCall_terminateMachineSrc(void) +static inline void HvCall_terminateMachineSrc(void) { - HvCall0( HvCallBaseTerminateMachineSrc ); + HvCall0(HvCallBaseTerminateMachineSrc); } static inline void HvCall_setDABR(unsigned long val) diff --git a/include/asm-ppc64/iSeries/HvCallCfg.h b/include/asm-ppc64/iSeries/HvCallCfg.h index 9f40f16de533..2223a9647d0e 100644 --- a/include/asm-ppc64/iSeries/HvCallCfg.h +++ b/include/asm-ppc64/iSeries/HvCallCfg.h @@ -1,43 +1,32 @@ /* * HvCallCfg.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 */ - -//===================================================================================== -// -// This file contains the "hypervisor call" interface which is used to -// drive the hypervisor from the OS. -// -//===================================================================================== +/* + * This file contains the "hypervisor call" interface which is used to + * drive the hypervisor from the OS. + */ #ifndef _HVCALLCFG_H #define _HVCALLCFG_H -//------------------------------------------------------------------- -// Standard Includes -//------------------------------------------------------------------- #include #include -//------------------------------------------------------------------------------------- -// Constants -//------------------------------------------------------------------------------------- - -enum HvCallCfg_ReqQual -{ +enum HvCallCfg_ReqQual { HvCallCfg_Cur = 0, HvCallCfg_Init = 1, HvCallCfg_Max = 2, @@ -49,7 +38,7 @@ enum HvCallCfg_ReqQual #define HvCallCfgGetLpVrmIndex HvCallCfg + 2 #define HvCallCfgGetLpMinSupportedPlicVrmIndex HvCallCfg + 3 #define HvCallCfgGetLpMinCompatablePlicVrmIndex HvCallCfg + 4 -#define HvCallCfgGetLpVrmName HvCallCfg + 5 +#define HvCallCfgGetLpVrmName HvCallCfg + 5 #define HvCallCfgGetSystemPhysicalProcessors HvCallCfg + 6 #define HvCallCfgGetPhysicalProcessors HvCallCfg + 7 #define HvCallCfgGetSystemMsChunks HvCallCfg + 8 @@ -76,108 +65,113 @@ enum HvCallCfg_ReqQual #define HvCallCfgSetMinRuntimeMsChunks HvCallCfg + 29 #define HvCallCfgGetVirtualLanIndexMap HvCallCfg + 30 #define HvCallCfgGetLpExecutionMode HvCallCfg + 31 -#define HvCallCfgGetHostingLpIndex HvCallCfg + 32 +#define HvCallCfgGetHostingLpIndex HvCallCfg + 32 -//==================================================================== static inline HvLpIndex HvCallCfg_getLps(void) { HvLpIndex retVal = HvCall0(HvCallCfgGetLps); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; } -//==================================================================== -static inline int HvCallCfg_isBusDedicated(u64 busIndex) + +static inline int HvCallCfg_isBusDedicated(u64 busIndex) { int retVal = HvCall1(HvCallCfgIsBusDedicated,busIndex); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; } -//==================================================================== + static inline HvLpIndex HvCallCfg_getBusOwner(u64 busIndex) { HvLpIndex retVal = HvCall1(HvCallCfgGetBusOwner,busIndex); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; } -//==================================================================== -static inline HvLpIndexMap HvCallCfg_getBusAllocation(u64 busIndex) + +static inline HvLpIndexMap HvCallCfg_getBusAllocation(u64 busIndex) { HvLpIndexMap retVal = HvCall1(HvCallCfgGetBusAllocation,busIndex); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; } -//==================================================================== -static inline HvLpIndexMap HvCallCfg_getActiveLpMap(void) + +static inline HvLpIndexMap HvCallCfg_getActiveLpMap(void) { HvLpIndexMap retVal = HvCall0(HvCallCfgGetActiveLpMap); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; } -//==================================================================== -static inline HvLpVirtualLanIndexMap HvCallCfg_getVirtualLanIndexMap(HvLpIndex lp) + +static inline HvLpVirtualLanIndexMap HvCallCfg_getVirtualLanIndexMap( + HvLpIndex lp) { - // This is a new function in V5R1 so calls to this on older - // hypervisors will return -1 + /* + * This is a new function in V5R1 so calls to this on older + * hypervisors will return -1 + */ u64 retVal = HvCall1(HvCallCfgGetVirtualLanIndexMap, lp); - if(retVal == -1) + if (retVal == -1) retVal = 0; // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; } -//=================================================================== -static inline u64 HvCallCfg_getSystemMsChunks(void) + +static inline u64 HvCallCfg_getSystemMsChunks(void) { u64 retVal = HvCall0(HvCallCfgGetSystemMsChunks); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; } -//=================================================================== -static inline u64 HvCallCfg_getMsChunks(HvLpIndex lp,enum HvCallCfg_ReqQual qual) + +static inline u64 HvCallCfg_getMsChunks(HvLpIndex lp, + enum HvCallCfg_ReqQual qual) { u64 retVal = HvCall2(HvCallCfgGetMsChunks,lp,qual); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; } -//=================================================================== -static inline u64 HvCallCfg_getMinRuntimeMsChunks(HvLpIndex lp) + +static inline u64 HvCallCfg_getMinRuntimeMsChunks(HvLpIndex lp) { - // NOTE: This function was added in v5r1 so older hypervisors will return a -1 value - u64 retVal = HvCall1(HvCallCfgGetMinRuntimeMsChunks,lp); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + /* + * NOTE: This function was added in v5r1 so older hypervisors + * will return a -1 value + */ + return HvCall1(HvCallCfgGetMinRuntimeMsChunks, lp); } -//=================================================================== -static inline u64 HvCallCfg_setMinRuntimeMsChunks(u64 chunks) + +static inline u64 HvCallCfg_setMinRuntimeMsChunks(u64 chunks) { u64 retVal = HvCall1(HvCallCfgSetMinRuntimeMsChunks,chunks); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; } -//=================================================================== -static inline u64 HvCallCfg_getSystemPhysicalProcessors(void) + +static inline u64 HvCallCfg_getSystemPhysicalProcessors(void) { u64 retVal = HvCall0(HvCallCfgGetSystemPhysicalProcessors); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; } -//=================================================================== -static inline u64 HvCallCfg_getPhysicalProcessors(HvLpIndex lp,enum HvCallCfg_ReqQual qual) + +static inline u64 HvCallCfg_getPhysicalProcessors(HvLpIndex lp, + enum HvCallCfg_ReqQual qual) { u64 retVal = HvCall2(HvCallCfgGetPhysicalProcessors,lp,qual); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; } -//=================================================================== -static inline u64 HvCallCfg_getConfiguredBusUnitsForInterruptProc(HvLpIndex lp, - u16 hvLogicalProcIndex) + +static inline u64 HvCallCfg_getConfiguredBusUnitsForInterruptProc(HvLpIndex lp, + u16 hvLogicalProcIndex) { u64 retVal = HvCall2(HvCallCfgGetConfiguredBusUnitsForIntProc,lp,hvLogicalProcIndex); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; } -//================================================================== -static inline HvLpSharedPoolIndex HvCallCfg_getSharedPoolIndex(HvLpIndex lp) + +static inline HvLpSharedPoolIndex HvCallCfg_getSharedPoolIndex(HvLpIndex lp) { HvLpSharedPoolIndex retVal = HvCall1(HvCallCfgGetSharedPoolIndex,lp); @@ -185,29 +179,29 @@ static inline HvLpSharedPoolIndex HvCallCfg_getSharedPoolIndex(HvLpIndex lp) return retVal; } -//================================================================== -static inline u64 HvCallCfg_getSharedProcUnits(HvLpIndex lp,enum HvCallCfg_ReqQual qual) + +static inline u64 HvCallCfg_getSharedProcUnits(HvLpIndex lp, + enum HvCallCfg_ReqQual qual) { u64 retVal = HvCall2(HvCallCfgGetSharedProcUnits,lp,qual); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; } -//================================================================== -static inline u64 HvCallCfg_getNumProcsInSharedPool(HvLpSharedPoolIndex sPI) + +static inline u64 HvCallCfg_getNumProcsInSharedPool(HvLpSharedPoolIndex sPI) { u16 retVal = HvCall1(HvCallCfgGetNumProcsInSharedPool,sPI); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; } -//================================================================== + static inline HvLpIndex HvCallCfg_getHostingLpIndex(HvLpIndex lp) { u64 retVal = HvCall1(HvCallCfgGetHostingLpIndex,lp); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; - } #endif /* _HVCALLCFG_H */ diff --git a/include/asm-ppc64/iSeries/HvCallEvent.h b/include/asm-ppc64/iSeries/HvCallEvent.h index 191ddce0c2c6..a5954785512d 100644 --- a/include/asm-ppc64/iSeries/HvCallEvent.h +++ b/include/asm-ppc64/iSeries/HvCallEvent.h @@ -1,32 +1,28 @@ /* * HvCallEvent.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 */ - /* - * This file contains the "hypervisor call" interface which is used to - * drive the hypervisor from the OS. + * This file contains the "hypervisor call" interface which is used to + * drive the hypervisor from the OS. */ #ifndef _HVCALLEVENT_H #define _HVCALLEVENT_H -/* - * Standard Includes - */ #include #include #include @@ -71,7 +67,7 @@ typedef u64 HvLpDma_Rc; #define HvCallEventCloseLpEventPath HvCallEvent + 2 #define HvCallEventDmaBufList HvCallEvent + 3 #define HvCallEventDmaSingle HvCallEvent + 4 -#define HvCallEventDmaToSp HvCallEvent + 5 +#define HvCallEventDmaToSp HvCallEvent + 5 #define HvCallEventGetOverflowLpEvents HvCallEvent + 6 #define HvCallEventGetSourceLpInstanceId HvCallEvent + 7 #define HvCallEventGetTargetLpInstanceId HvCallEvent + 8 @@ -85,13 +81,13 @@ typedef u64 HvLpDma_Rc; static inline void HvCallEvent_getOverflowLpEvents(u8 queueIndex) { - HvCall1(HvCallEventGetOverflowLpEvents,queueIndex); + HvCall1(HvCallEventGetOverflowLpEvents, queueIndex); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } static inline void HvCallEvent_setInterLpQueueIndex(u8 queueIndex) { - HvCall1(HvCallEventSetInterLpQueueIndex,queueIndex); + HvCall1(HvCallEventSetInterLpQueueIndex, queueIndex); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } @@ -138,7 +134,7 @@ static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp, { HvLpEvent_Rc retVal; - // Pack the misc bits into a single Dword to pass to PLIC + /* Pack the misc bits into a single Dword to pass to PLIC */ union { struct HvCallEvent_PackedParms parms; u64 dword; @@ -225,7 +221,7 @@ static inline HvLpDma_Rc HvCallEvent_dmaBufList(HvLpEvent_Type type, u64 localBufList, u64 remoteBufList, u32 transferLength) { HvLpDma_Rc retVal; - // Pack the misc bits into a single Dword to pass to PLIC + /* Pack the misc bits into a single Dword to pass to PLIC */ union { struct HvCallEvent_PackedDmaParms parms; u64 dword; @@ -257,7 +253,7 @@ static inline HvLpDma_Rc HvCallEvent_dmaSingle(HvLpEvent_Type type, u64 localAddrOrTce, u64 remoteAddrOrTce, u32 transferLength) { HvLpDma_Rc retVal; - // Pack the misc bits into a single Dword to pass to PLIC + /* Pack the misc bits into a single Dword to pass to PLIC */ union { struct HvCallEvent_PackedDmaParms parms; u64 dword; @@ -280,7 +276,7 @@ static inline HvLpDma_Rc HvCallEvent_dmaSingle(HvLpEvent_Type type, return retVal; } -static inline HvLpDma_Rc HvCallEvent_dmaToSp(void* local, u32 remote, +static inline HvLpDma_Rc HvCallEvent_dmaToSp(void *local, u32 remote, u32 length, HvLpDma_Direction dir) { u64 abs_addr; @@ -293,5 +289,4 @@ static inline HvLpDma_Rc HvCallEvent_dmaToSp(void* local, u32 remote, return retVal; } - #endif /* _HVCALLEVENT_H */ diff --git a/include/asm-ppc64/iSeries/HvCallHpt.h b/include/asm-ppc64/iSeries/HvCallHpt.h index da769873d18b..827d26c60fc1 100644 --- a/include/asm-ppc64/iSeries/HvCallHpt.h +++ b/include/asm-ppc64/iSeries/HvCallHpt.h @@ -1,17 +1,17 @@ /* * HvCallHpt.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 @@ -19,21 +19,15 @@ #ifndef _HVCALLHPT_H #define _HVCALLHPT_H -//============================================================================ -// -// This file contains the "hypervisor call" interface which is used to -// drive the hypervisor from the OS. -// -//============================================================================ +/* + * This file contains the "hypervisor call" interface which is used to + * drive the hypervisor from the OS. + */ #include #include #include -//----------------------------------------------------------------------------- -// Constants -//----------------------------------------------------------------------------- - #define HvCallHptGetHptAddress HvCallHpt + 0 #define HvCallHptGetHptPages HvCallHpt + 1 #define HvCallHptSetPp HvCallHpt + 5 @@ -47,81 +41,76 @@ #define HvCallHptInvalidateSetSwBitsGet HvCallHpt + 18 -//============================================================================ -static inline u64 HvCallHpt_getHptAddress(void) +static inline u64 HvCallHpt_getHptAddress(void) { u64 retval = HvCall0(HvCallHptGetHptAddress); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retval; } -//============================================================================ -static inline u64 HvCallHpt_getHptPages(void) -{ + +static inline u64 HvCallHpt_getHptPages(void) +{ u64 retval = HvCall0(HvCallHptGetHptPages); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retval; } -//============================================================================= -static inline void HvCallHpt_setPp(u32 hpteIndex, u8 value) + +static inline void HvCallHpt_setPp(u32 hpteIndex, u8 value) { - HvCall2( HvCallHptSetPp, hpteIndex, value ); + HvCall2(HvCallHptSetPp, hpteIndex, value); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } -//============================================================================= -static inline void HvCallHpt_setSwBits(u32 hpteIndex, u8 bitson, u8 bitsoff ) + +static inline void HvCallHpt_setSwBits(u32 hpteIndex, u8 bitson, u8 bitsoff) { - HvCall3( HvCallHptSetSwBits, hpteIndex, bitson, bitsoff ); + HvCall3(HvCallHptSetSwBits, hpteIndex, bitson, bitsoff); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } -//============================================================================= -static inline void HvCallHpt_invalidateNoSyncICache(u32 hpteIndex) - + +static inline void HvCallHpt_invalidateNoSyncICache(u32 hpteIndex) { - HvCall1( HvCallHptInvalidateNoSyncICache, hpteIndex ); + HvCall1(HvCallHptInvalidateNoSyncICache, hpteIndex); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } -//============================================================================= -static inline u64 HvCallHpt_invalidateSetSwBitsGet(u32 hpteIndex, u8 bitson, u8 bitsoff ) - + +static inline u64 HvCallHpt_invalidateSetSwBitsGet(u32 hpteIndex, u8 bitson, + u8 bitsoff) { u64 compressedStatus; - compressedStatus = HvCall4( HvCallHptInvalidateSetSwBitsGet, hpteIndex, bitson, bitsoff, 1 ); - HvCall1( HvCallHptInvalidateNoSyncICache, hpteIndex ); + + compressedStatus = HvCall4(HvCallHptInvalidateSetSwBitsGet, + hpteIndex, bitson, bitsoff, 1); + HvCall1(HvCallHptInvalidateNoSyncICache, hpteIndex); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return compressedStatus; } -//============================================================================= -static inline u64 HvCallHpt_findValid( HPTE *hpte, u64 vpn ) + +static inline u64 HvCallHpt_findValid(HPTE *hpte, u64 vpn) { u64 retIndex = HvCall3Ret16( HvCallHptFindValid, hpte, vpn, 0, 0 ); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retIndex; } -//============================================================================= -static inline u64 HvCallHpt_findNextValid( HPTE *hpte, u32 hpteIndex, u8 bitson, u8 bitsoff ) + +static inline u64 HvCallHpt_findNextValid(HPTE *hpte, u32 hpteIndex, + u8 bitson, u8 bitsoff) { u64 retIndex = HvCall3Ret16( HvCallHptFindNextValid, hpte, hpteIndex, bitson, bitsoff ); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retIndex; } -//============================================================================= -static inline void HvCallHpt_get( HPTE *hpte, u32 hpteIndex ) + +static inline void HvCallHpt_get(HPTE *hpte, u32 hpteIndex) { - HvCall2Ret16( HvCallHptGet, hpte, hpteIndex, 0 ); + HvCall2Ret16(HvCallHptGet, hpte, hpteIndex, 0); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } -//============================================================================ -static inline void HvCallHpt_addValidate( u32 hpteIndex, - u32 hBit, - HPTE *hpte ) - + +static inline void HvCallHpt_addValidate(u32 hpteIndex, u32 hBit, HPTE *hpte) { - HvCall4( HvCallHptAddValidate, hpteIndex, - hBit, (*((u64 *)hpte)), (*(((u64 *)hpte)+1)) ); + HvCall4(HvCallHptAddValidate, hpteIndex, hBit, (*((u64 *)hpte)), + (*(((u64 *)hpte)+1))); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } - -//============================================================================= - #endif /* _HVCALLHPT_H */ diff --git a/include/asm-ppc64/iSeries/HvCallPci.h b/include/asm-ppc64/iSeries/HvCallPci.h index 6887b619288e..346ab5d39dcd 100644 --- a/include/asm-ppc64/iSeries/HvCallPci.h +++ b/include/asm-ppc64/iSeries/HvCallPci.h @@ -1,26 +1,26 @@ -/************************************************************************/ -/* Provides the Hypervisor PCI calls for iSeries Linux Parition. */ -/* Copyright (C) 2001 */ -/* */ -/* 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 */ -/************************************************************************/ -/* Change Activity: */ -/* Created, Jan 9, 2001 */ -/************************************************************************/ +/* + * Provides the Hypervisor PCI calls for iSeries Linux Parition. + * Copyright (C) 2001 + * + * 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 + * + * Change Activity: + * Created, Jan 9, 2001 + */ #ifndef _HVCALLPCI_H #define _HVCALLPCI_H @@ -34,8 +34,8 @@ */ struct HvCallPci_DsaAddr { u16 busNumber; /* PHB index? */ - u8 subBusNumber; /* PCI bus number? */ - u8 deviceId; /* device and function? */ + u8 subBusNumber; /* PCI bus number? */ + u8 deviceId; /* device and function? */ u8 barNumber; u8 reserved[3]; }; @@ -52,34 +52,37 @@ struct HvCallPci_LoadReturn { enum HvCallPci_DeviceType { HvCallPci_NodeDevice = 1, - HvCallPci_SpDevice = 2, - HvCallPci_IopDevice = 3, - HvCallPci_BridgeDevice = 4, - HvCallPci_MultiFunctionDevice = 5, - HvCallPci_IoaDevice = 6 + HvCallPci_SpDevice = 2, + HvCallPci_IopDevice = 3, + HvCallPci_BridgeDevice = 4, + HvCallPci_MultiFunctionDevice = 5, + HvCallPci_IoaDevice = 6 }; struct HvCallPci_DeviceInfo { - u32 deviceType; // See DeviceType enum for values + u32 deviceType; /* See DeviceType enum for values */ }; - + struct HvCallPci_BusUnitInfo { - u32 sizeReturned; // length of data returned - u32 deviceType; // see DeviceType enum for values + u32 sizeReturned; /* length of data returned */ + u32 deviceType; /* see DeviceType enum for values */ }; struct HvCallPci_BridgeInfo { - struct HvCallPci_BusUnitInfo busUnitInfo; // Generic bus unit info - u8 subBusNumber; // Bus number of secondary bus - u8 maxAgents; // Max idsels on secondary bus - u8 maxSubBusNumber; // Max Sub Bus - u8 logicalSlotNumber; // Logical Slot Number for IOA + struct HvCallPci_BusUnitInfo busUnitInfo; /* Generic bus unit info */ + u8 subBusNumber; /* Bus number of secondary bus */ + u8 maxAgents; /* Max idsels on secondary bus */ + u8 maxSubBusNumber; /* Max Sub Bus */ + u8 logicalSlotNumber; /* Logical Slot Number for IOA */ }; - -// Maximum BusUnitInfo buffer size. Provided for clients so they can allocate -// a buffer big enough for any type of bus unit. Increase as needed. + +/* + * Maximum BusUnitInfo buffer size. Provided for clients so + * they can allocate a buffer big enough for any type of bus + * unit. Increase as needed. + */ enum {HvCallPci_MaxBusUnitInfoSize = 128}; struct HvCallPci_BarParms { @@ -89,12 +92,12 @@ struct HvCallPci_BarParms { u64 protectStart; u64 protectEnd; u64 relocationOffset; - u64 pciAddress; + u64 pciAddress; u64 reserved[3]; -}; +}; enum HvCallPci_VpdType { - HvCallPci_BusVpd = 1, + HvCallPci_BusVpd = 1, HvCallPci_BusAdapterVpd = 2 }; @@ -123,15 +126,13 @@ enum HvCallPci_VpdType { #define HvCallPciUnmaskInterrupts HvCallPci + 49 #define HvCallPciGetBusUnitInfo HvCallPci + 50 -//============================================================================ static inline u64 HvCallPci_configLoad8(u16 busNumber, u8 subBusNumber, - u8 deviceId, u32 offset, - u8 *value) + u8 deviceId, u32 offset, u8 *value) { struct HvCallPci_DsaAddr dsa; struct HvCallPci_LoadReturn retVal; - *((u64*)&dsa) = 0; + *((u64*)&dsa) = 0; dsa.busNumber = busNumber; dsa.subBusNumber = subBusNumber; @@ -145,15 +146,14 @@ static inline u64 HvCallPci_configLoad8(u16 busNumber, u8 subBusNumber, return retVal.rc; } -//============================================================================ + static inline u64 HvCallPci_configLoad16(u16 busNumber, u8 subBusNumber, - u8 deviceId, u32 offset, - u16 *value) + u8 deviceId, u32 offset, u16 *value) { struct HvCallPci_DsaAddr dsa; struct HvCallPci_LoadReturn retVal; - *((u64*)&dsa) = 0; + *((u64*)&dsa) = 0; dsa.busNumber = busNumber; dsa.subBusNumber = subBusNumber; @@ -167,15 +167,14 @@ static inline u64 HvCallPci_configLoad16(u16 busNumber, u8 subBusNumber, return retVal.rc; } -//============================================================================ -static inline u64 HvCallPci_configLoad32(u16 busNumber, u8 subBusNumber, - u8 deviceId, u32 offset, - u32 *value) + +static inline u64 HvCallPci_configLoad32(u16 busNumber, u8 subBusNumber, + u8 deviceId, u32 offset, u32 *value) { struct HvCallPci_DsaAddr dsa; struct HvCallPci_LoadReturn retVal; - *((u64*)&dsa) = 0; + *((u64*)&dsa) = 0; dsa.busNumber = busNumber; dsa.subBusNumber = subBusNumber; @@ -189,15 +188,14 @@ static inline u64 HvCallPci_configLoad32(u16 busNumber, u8 subBusNumber, return retVal.rc; } -//============================================================================ -static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber, - u8 deviceId, u32 offset, - u8 value) + +static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber, + u8 deviceId, u32 offset, u8 value) { struct HvCallPci_DsaAddr dsa; u64 retVal; - *((u64*)&dsa) = 0; + *((u64*)&dsa) = 0; dsa.busNumber = busNumber; dsa.subBusNumber = subBusNumber; @@ -209,15 +207,14 @@ static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber, return retVal; } -//============================================================================ -static inline u64 HvCallPci_configStore16(u16 busNumber, u8 subBusNumber, - u8 deviceId, u32 offset, - u16 value) + +static inline u64 HvCallPci_configStore16(u16 busNumber, u8 subBusNumber, + u8 deviceId, u32 offset, u16 value) { struct HvCallPci_DsaAddr dsa; u64 retVal; - *((u64*)&dsa) = 0; + *((u64*)&dsa) = 0; dsa.busNumber = busNumber; dsa.subBusNumber = subBusNumber; @@ -229,15 +226,14 @@ static inline u64 HvCallPci_configStore16(u16 busNumber, u8 subBusNumber, return retVal; } -//============================================================================ -static inline u64 HvCallPci_configStore32(u16 busNumber, u8 subBusNumber, - u8 deviceId, u32 offset, - u32 value) + +static inline u64 HvCallPci_configStore32(u16 busNumber, u8 subBusNumber, + u8 deviceId, u32 offset, u32 value) { struct HvCallPci_DsaAddr dsa; u64 retVal; - *((u64*)&dsa) = 0; + *((u64*)&dsa) = 0; dsa.busNumber = busNumber; dsa.subBusNumber = subBusNumber; @@ -249,18 +245,15 @@ static inline u64 HvCallPci_configStore32(u16 busNumber, u8 subBusNumber, return retVal; } -//============================================================================ -static inline u64 HvCallPci_barLoad8(u16 busNumberParm, - u8 subBusParm, - u8 deviceIdParm, - u8 barNumberParm, - u64 offsetParm, - u8* valueParm) + +static inline u64 HvCallPci_barLoad8(u16 busNumberParm, u8 subBusParm, + u8 deviceIdParm, u8 barNumberParm, u64 offsetParm, + u8 *valueParm) { struct HvCallPci_DsaAddr dsa; struct HvCallPci_LoadReturn retVal; - *((u64*)&dsa) = 0; + *((u64*)&dsa) = 0; dsa.busNumber = busNumberParm; dsa.subBusNumber = subBusParm; @@ -275,18 +268,15 @@ static inline u64 HvCallPci_barLoad8(u16 busNumberParm, return retVal.rc; } -//============================================================================ -static inline u64 HvCallPci_barLoad16(u16 busNumberParm, - u8 subBusParm, - u8 deviceIdParm, - u8 barNumberParm, - u64 offsetParm, - u16* valueParm) + +static inline u64 HvCallPci_barLoad16(u16 busNumberParm, u8 subBusParm, + u8 deviceIdParm, u8 barNumberParm, u64 offsetParm, + u16 *valueParm) { struct HvCallPci_DsaAddr dsa; struct HvCallPci_LoadReturn retVal; - *((u64*)&dsa) = 0; + *((u64*)&dsa) = 0; dsa.busNumber = busNumberParm; dsa.subBusNumber = subBusParm; @@ -301,18 +291,15 @@ static inline u64 HvCallPci_barLoad16(u16 busNumberParm, return retVal.rc; } -//============================================================================ -static inline u64 HvCallPci_barLoad32(u16 busNumberParm, - u8 subBusParm, - u8 deviceIdParm, - u8 barNumberParm, - u64 offsetParm, - u32* valueParm) + +static inline u64 HvCallPci_barLoad32(u16 busNumberParm, u8 subBusParm, + u8 deviceIdParm, u8 barNumberParm, u64 offsetParm, + u32 *valueParm) { struct HvCallPci_DsaAddr dsa; struct HvCallPci_LoadReturn retVal; - *((u64*)&dsa) = 0; + *((u64*)&dsa) = 0; dsa.busNumber = busNumberParm; dsa.subBusNumber = subBusParm; @@ -327,18 +314,15 @@ static inline u64 HvCallPci_barLoad32(u16 busNumberParm, return retVal.rc; } -//============================================================================ -static inline u64 HvCallPci_barLoad64(u16 busNumberParm, - u8 subBusParm, - u8 deviceIdParm, - u8 barNumberParm, - u64 offsetParm, - u64* valueParm) + +static inline u64 HvCallPci_barLoad64(u16 busNumberParm, u8 subBusParm, + u8 deviceIdParm, u8 barNumberParm, u64 offsetParm, + u64 *valueParm) { struct HvCallPci_DsaAddr dsa; struct HvCallPci_LoadReturn retVal; - *((u64*)&dsa) = 0; + *((u64*)&dsa) = 0; dsa.busNumber = busNumberParm; dsa.subBusNumber = subBusParm; @@ -353,19 +337,16 @@ static inline u64 HvCallPci_barLoad64(u16 busNumberParm, return retVal.rc; } -//============================================================================ -static inline u64 HvCallPci_barStore8(u16 busNumberParm, - u8 subBusParm, - u8 deviceIdParm, - u8 barNumberParm, - u64 offsetParm, - u8 valueParm) + +static inline u64 HvCallPci_barStore8(u16 busNumberParm, u8 subBusParm, + u8 deviceIdParm, u8 barNumberParm, u64 offsetParm, + u8 valueParm) { struct HvCallPci_DsaAddr dsa; u64 retVal; *((u64*)&dsa) = 0; - + dsa.busNumber = busNumberParm; dsa.subBusNumber = subBusParm; dsa.deviceId = deviceIdParm; @@ -377,19 +358,16 @@ static inline u64 HvCallPci_barStore8(u16 busNumberParm, return retVal; } -//============================================================================ -static inline u64 HvCallPci_barStore16(u16 busNumberParm, - u8 subBusParm, - u8 deviceIdParm, - u8 barNumberParm, - u64 offsetParm, - u16 valueParm) + +static inline u64 HvCallPci_barStore16(u16 busNumberParm, u8 subBusParm, + u8 deviceIdParm, u8 barNumberParm, u64 offsetParm, + u16 valueParm) { struct HvCallPci_DsaAddr dsa; u64 retVal; *((u64*)&dsa) = 0; - + dsa.busNumber = busNumberParm; dsa.subBusNumber = subBusParm; dsa.deviceId = deviceIdParm; @@ -401,19 +379,16 @@ static inline u64 HvCallPci_barStore16(u16 busNumberParm, return retVal; } -//============================================================================ -static inline u64 HvCallPci_barStore32(u16 busNumberParm, - u8 subBusParm, - u8 deviceIdParm, - u8 barNumberParm, - u64 offsetParm, - u32 valueParm) + +static inline u64 HvCallPci_barStore32(u16 busNumberParm, u8 subBusParm, + u8 deviceIdParm, u8 barNumberParm, u64 offsetParm, + u32 valueParm) { struct HvCallPci_DsaAddr dsa; u64 retVal; *((u64*)&dsa) = 0; - + dsa.busNumber = busNumberParm; dsa.subBusNumber = subBusParm; dsa.deviceId = deviceIdParm; @@ -425,19 +400,16 @@ static inline u64 HvCallPci_barStore32(u16 busNumberParm, return retVal; } -//============================================================================ -static inline u64 HvCallPci_barStore64(u16 busNumberParm, - u8 subBusParm, - u8 deviceIdParm, - u8 barNumberParm, - u64 offsetParm, - u64 valueParm) + +static inline u64 HvCallPci_barStore64(u16 busNumberParm, u8 subBusParm, + u8 deviceIdParm, u8 barNumberParm, u64 offsetParm, + u64 valueParm) { struct HvCallPci_DsaAddr dsa; u64 retVal; *((u64*)&dsa) = 0; - + dsa.busNumber = busNumberParm; dsa.subBusNumber = subBusParm; dsa.deviceId = deviceIdParm; @@ -449,10 +421,9 @@ static inline u64 HvCallPci_barStore64(u16 busNumberParm, return retVal; } -//============================================================================ -static inline u64 HvCallPci_eoi(u16 busNumberParm, - u8 subBusParm, - u8 deviceIdParm) + +static inline u64 HvCallPci_eoi(u16 busNumberParm, u8 subBusParm, + u8 deviceIdParm) { struct HvCallPci_DsaAddr dsa; struct HvCallPci_LoadReturn retVal; @@ -469,13 +440,9 @@ static inline u64 HvCallPci_eoi(u16 busNumberParm, return retVal.rc; } -//============================================================================ -static inline u64 HvCallPci_getBarParms(u16 busNumberParm, - u8 subBusParm, - u8 deviceIdParm, - u8 barNumberParm, - u64 parms, - u32 sizeofParms) + +static inline u64 HvCallPci_getBarParms(u16 busNumberParm, u8 subBusParm, + u8 deviceIdParm, u8 barNumberParm, u64 parms, u32 sizeofParms) { struct HvCallPci_DsaAddr dsa; u64 retVal; @@ -493,16 +460,14 @@ static inline u64 HvCallPci_getBarParms(u16 busNumberParm, return retVal; } -//============================================================================ -static inline u64 HvCallPci_maskFisr(u16 busNumberParm, - u8 subBusParm, - u8 deviceIdParm, - u64 fisrMask) + +static inline u64 HvCallPci_maskFisr(u16 busNumberParm, u8 subBusParm, + u8 deviceIdParm, u64 fisrMask) { struct HvCallPci_DsaAddr dsa; u64 retVal; - *((u64*)&dsa) = 0; + *((u64*)&dsa) = 0; dsa.busNumber = busNumberParm; dsa.subBusNumber = subBusParm; @@ -514,16 +479,14 @@ static inline u64 HvCallPci_maskFisr(u16 busNumberParm, return retVal; } -//============================================================================ -static inline u64 HvCallPci_unmaskFisr(u16 busNumberParm, - u8 subBusParm, - u8 deviceIdParm, - u64 fisrMask) + +static inline u64 HvCallPci_unmaskFisr(u16 busNumberParm, u8 subBusParm, + u8 deviceIdParm, u64 fisrMask) { struct HvCallPci_DsaAddr dsa; u64 retVal; - *((u64*)&dsa) = 0; + *((u64*)&dsa) = 0; dsa.busNumber = busNumberParm; dsa.subBusNumber = subBusParm; @@ -535,11 +498,9 @@ static inline u64 HvCallPci_unmaskFisr(u16 busNumberParm, return retVal; } -//============================================================================ -static inline u64 HvCallPci_setSlotReset(u16 busNumberParm, - u8 subBusParm, - u8 deviceIdParm, - u64 onNotOff) + +static inline u64 HvCallPci_setSlotReset(u16 busNumberParm, u8 subBusParm, + u8 deviceIdParm, u64 onNotOff) { struct HvCallPci_DsaAddr dsa; u64 retVal; @@ -556,12 +517,9 @@ static inline u64 HvCallPci_setSlotReset(u16 busNumberParm, return retVal; } -//============================================================================ -static inline u64 HvCallPci_getDeviceInfo(u16 busNumberParm, - u8 subBusParm, - u8 deviceNumberParm, - u64 parms, - u32 sizeofParms) + +static inline u64 HvCallPci_getDeviceInfo(u16 busNumberParm, u8 subBusParm, + u8 deviceNumberParm, u64 parms, u32 sizeofParms) { struct HvCallPci_DsaAddr dsa; u64 retVal; @@ -578,16 +536,14 @@ static inline u64 HvCallPci_getDeviceInfo(u16 busNumberParm, return retVal; } -//============================================================================ -static inline u64 HvCallPci_maskInterrupts(u16 busNumberParm, - u8 subBusParm, - u8 deviceIdParm, - u64 interruptMask) + +static inline u64 HvCallPci_maskInterrupts(u16 busNumberParm, u8 subBusParm, + u8 deviceIdParm, u64 interruptMask) { struct HvCallPci_DsaAddr dsa; u64 retVal; - *((u64*)&dsa) = 0; + *((u64*)&dsa) = 0; dsa.busNumber = busNumberParm; dsa.subBusNumber = subBusParm; @@ -599,16 +555,14 @@ static inline u64 HvCallPci_maskInterrupts(u16 busNumberParm, return retVal; } -//============================================================================ -static inline u64 HvCallPci_unmaskInterrupts(u16 busNumberParm, - u8 subBusParm, - u8 deviceIdParm, - u64 interruptMask) + +static inline u64 HvCallPci_unmaskInterrupts(u16 busNumberParm, u8 subBusParm, + u8 deviceIdParm, u64 interruptMask) { struct HvCallPci_DsaAddr dsa; u64 retVal; - *((u64*)&dsa) = 0; + *((u64*)&dsa) = 0; dsa.busNumber = busNumberParm; dsa.subBusNumber = subBusParm; @@ -620,18 +574,14 @@ static inline u64 HvCallPci_unmaskInterrupts(u16 busNumberParm, return retVal; } -//============================================================================ -static inline u64 HvCallPci_getBusUnitInfo(u16 busNumberParm, - u8 subBusParm, - u8 deviceIdParm, - u64 parms, - u32 sizeofParms) +static inline u64 HvCallPci_getBusUnitInfo(u16 busNumberParm, u8 subBusParm, + u8 deviceIdParm, u64 parms, u32 sizeofParms) { struct HvCallPci_DsaAddr dsa; u64 retVal; - *((u64*)&dsa) = 0; + *((u64*)&dsa) = 0; dsa.busNumber = busNumberParm; dsa.subBusNumber = subBusParm; @@ -643,9 +593,9 @@ static inline u64 HvCallPci_getBusUnitInfo(u16 busNumberParm, return retVal; } -//============================================================================ -static inline int HvCallPci_getBusVpd(u16 busNumParm, u64 destParm, u16 sizeParm) +static inline int HvCallPci_getBusVpd(u16 busNumParm, u64 destParm, + u16 sizeParm) { int xRetSize; u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm, sizeParm, HvCallPci_BusVpd); @@ -656,9 +606,9 @@ static inline int HvCallPci_getBusVpd(u16 busNumParm, u64 destParm, u16 sizeParm xRetSize = xRc & 0xFFFF; return xRetSize; } -//============================================================================ -static inline int HvCallPci_getBusAdapterVpd(u16 busNumParm, u64 destParm, u16 sizeParm) +static inline int HvCallPci_getBusAdapterVpd(u16 busNumParm, u64 destParm, + u16 sizeParm) { int xRetSize; u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm, sizeParm, HvCallPci_BusAdapterVpd); @@ -669,5 +619,5 @@ static inline int HvCallPci_getBusAdapterVpd(u16 busNumParm, u64 destParm, u16 s xRetSize = xRc & 0xFFFF; return xRetSize; } -//============================================================================ + #endif /* _HVCALLPCI_H */ diff --git a/include/asm-ppc64/iSeries/HvCallSc.h b/include/asm-ppc64/iSeries/HvCallSc.h index eea258447642..c32145f9ec75 100644 --- a/include/asm-ppc64/iSeries/HvCallSc.h +++ b/include/asm-ppc64/iSeries/HvCallSc.h @@ -1,17 +1,17 @@ /* * HvCallSc.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 @@ -30,22 +30,22 @@ #define HvCallSm 0x8007000000000000ul #define HvCallXm 0x8009000000000000ul -u64 HvCall0( u64 ); -u64 HvCall1( u64, u64 ); -u64 HvCall2( u64, u64, u64 ); -u64 HvCall3( u64, u64, u64, u64 ); -u64 HvCall4( u64, u64, u64, u64, u64 ); -u64 HvCall5( u64, u64, u64, u64, u64, u64 ); -u64 HvCall6( u64, u64, u64, u64, u64, u64, u64 ); -u64 HvCall7( u64, u64, u64, u64, u64, u64, u64, u64 ); +u64 HvCall0(u64); +u64 HvCall1(u64, u64); +u64 HvCall2(u64, u64, u64); +u64 HvCall3(u64, u64, u64, u64); +u64 HvCall4(u64, u64, u64, u64, u64); +u64 HvCall5(u64, u64, u64, u64, u64, u64); +u64 HvCall6(u64, u64, u64, u64, u64, u64, u64); +u64 HvCall7(u64, u64, u64, u64, u64, u64, u64, u64); -u64 HvCall0Ret16( u64, void * ); -u64 HvCall1Ret16( u64, void *, u64 ); -u64 HvCall2Ret16( u64, void *, u64, u64 ); -u64 HvCall3Ret16( u64, void *, u64, u64, u64 ); -u64 HvCall4Ret16( u64, void *, u64, u64, u64, u64 ); -u64 HvCall5Ret16( u64, void *, u64, u64, u64, u64, u64 ); -u64 HvCall6Ret16( u64, void *, u64, u64, u64, u64, u64, u64 ); -u64 HvCall7Ret16( u64, void *, u64, u64 ,u64 ,u64 ,u64 ,u64 ,u64 ); +u64 HvCall0Ret16(u64, void *); +u64 HvCall1Ret16(u64, void *, u64); +u64 HvCall2Ret16(u64, void *, u64, u64); +u64 HvCall3Ret16(u64, void *, u64, u64, u64); +u64 HvCall4Ret16(u64, void *, u64, u64, u64, u64); +u64 HvCall5Ret16(u64, void *, u64, u64, u64, u64, u64); +u64 HvCall6Ret16(u64, void *, u64, u64, u64, u64, u64, u64); +u64 HvCall7Ret16(u64, void *, u64, u64 ,u64 ,u64 ,u64 ,u64 ,u64); #endif /* _HVCALLSC_H */ diff --git a/include/asm-ppc64/iSeries/HvCallSm.h b/include/asm-ppc64/iSeries/HvCallSm.h index 9050c94a529d..ef6b303e4d28 100644 --- a/include/asm-ppc64/iSeries/HvCallSm.h +++ b/include/asm-ppc64/iSeries/HvCallSm.h @@ -1,17 +1,17 @@ /* * HvCallSm.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 @@ -19,34 +19,23 @@ #ifndef _HVCALLSM_H #define _HVCALLSM_H -//============================================================================ -// -// This file contains the "hypervisor call" interface which is used to -// drive the hypervisor from the OS. -// -//============================================================================ +/* + * This file contains the "hypervisor call" interface which is used to + * drive the hypervisor from the OS. + */ -//------------------------------------------------------------------- -// Standard Includes -//------------------------------------------------------------------- #include #include -//----------------------------------------------------------------------------- -// Constants -//----------------------------------------------------------------------------- - #define HvCallSmGet64BitsOfAccessMap HvCallSm + 11 - -//============================================================================ -static inline u64 HvCallSm_get64BitsOfAccessMap( - HvLpIndex lpIndex, u64 indexIntoBitMap ) +static inline u64 HvCallSm_get64BitsOfAccessMap(HvLpIndex lpIndex, + u64 indexIntoBitMap) { u64 retval = HvCall2(HvCallSmGet64BitsOfAccessMap, lpIndex, indexIntoBitMap ); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retval; } -//============================================================================ + #endif /* _HVCALLSM_H */ diff --git a/include/asm-ppc64/iSeries/HvCallXm.h b/include/asm-ppc64/iSeries/HvCallXm.h index bfb898f4db8d..a99f29b93611 100644 --- a/include/asm-ppc64/iSeries/HvCallXm.h +++ b/include/asm-ppc64/iSeries/HvCallXm.h @@ -1,30 +1,13 @@ -//============================================================================ -// Header File Id -// Name______________: HvCallXm.H -// -// Description_______: -// -// This file contains the "hypervisor call" interface which is used to -// drive the hypervisor from SLIC. -// -//============================================================================ +/* + * This file contains the "hypervisor call" interface which is used to + * drive the hypervisor from SLIC. + */ #ifndef _HVCALLXM_H #define _HVCALLXM_H -//------------------------------------------------------------------- -// Forward declarations -//------------------------------------------------------------------- - -//------------------------------------------------------------------- -// Standard Includes -//------------------------------------------------------------------- #include #include -//----------------------------------------------------------------------------- -// Constants -//----------------------------------------------------------------------------- - #define HvCallXmGetTceTableParms HvCallXm + 0 #define HvCallXmTestBus HvCallXm + 1 #define HvCallXmConnectBusUnit HvCallXm + 2 @@ -33,47 +16,46 @@ #define HvCallXmSetTce HvCallXm + 11 #define HvCallXmSetTces HvCallXm + 13 - - -//============================================================================ -static inline void HvCallXm_getTceTableParms(u64 cb) +static inline void HvCallXm_getTceTableParms(u64 cb) { HvCall1(HvCallXmGetTceTableParms, cb); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } -//============================================================================ -static inline u64 HvCallXm_setTce(u64 tceTableToken, u64 tceOffset, u64 tce) -{ + +static inline u64 HvCallXm_setTce(u64 tceTableToken, u64 tceOffset, u64 tce) +{ u64 retval = HvCall3(HvCallXmSetTce, tceTableToken, tceOffset, tce ); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retval; } -//============================================================================ -static inline u64 HvCallXm_setTces(u64 tceTableToken, u64 tceOffset, u64 numTces, u64 tce1, u64 tce2, u64 tce3, u64 tce4) -{ + +static inline u64 HvCallXm_setTces(u64 tceTableToken, u64 tceOffset, + u64 numTces, u64 tce1, u64 tce2, u64 tce3, u64 tce4) +{ u64 retval = HvCall7(HvCallXmSetTces, tceTableToken, tceOffset, numTces, tce1, tce2, tce3, tce4 ); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retval; } -//============================================================================= -static inline u64 HvCallXm_testBus(u16 busNumber) + +static inline u64 HvCallXm_testBus(u16 busNumber) { u64 retVal = HvCall1(HvCallXmTestBus, busNumber); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; } -//===================================================================================== -static inline u64 HvCallXm_testBusUnit(u16 busNumber, u8 subBusNumber, u8 deviceId) + +static inline u64 HvCallXm_testBusUnit(u16 busNumber, u8 subBusNumber, + u8 deviceId) { u64 busUnitNumber = (subBusNumber << 8) | deviceId; u64 retVal = HvCall2(HvCallXmTestBusUnit, busNumber, busUnitNumber); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; } -//===================================================================================== -static inline u64 HvCallXm_connectBusUnit(u16 busNumber, u8 subBusNumber, u8 deviceId, - u64 interruptToken) + +static inline u64 HvCallXm_connectBusUnit(u16 busNumber, u8 subBusNumber, + u8 deviceId, u64 interruptToken) { u64 busUnitNumber = (subBusNumber << 8) | deviceId; u64 queueIndex = 0; // HvLpConfig::mapDsaToQueueIndex(HvLpDSA(busNumber, xBoard, xCard)); @@ -83,13 +65,12 @@ static inline u64 HvCallXm_connectBusUnit(u16 busNumber, u8 subBusNumber, u8 dev // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; } -//===================================================================================== -static inline u64 HvCallXm_loadTod(void) + +static inline u64 HvCallXm_loadTod(void) { u64 retVal = HvCall0(HvCallXmLoadTod); // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; } -//===================================================================================== #endif /* _HVCALLXM_H */ diff --git a/include/asm-ppc64/iSeries/HvLpConfig.h b/include/asm-ppc64/iSeries/HvLpConfig.h index bdbd70f42c9d..47311cc952d9 100644 --- a/include/asm-ppc64/iSeries/HvLpConfig.h +++ b/include/asm-ppc64/iSeries/HvLpConfig.h @@ -1,17 +1,17 @@ /* * HvLpConfig.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 @@ -19,262 +19,285 @@ #ifndef _HVLPCONFIG_H #define _HVLPCONFIG_H -//=========================================================================== -// -// This file contains the interface to the LPAR configuration data -// to determine which resources should be allocated to each partition. -// -//=========================================================================== +/* + * This file contains the interface to the LPAR configuration data + * to determine which resources should be allocated to each partition. + */ #include #include #include #include -//------------------------------------------------------------------- -// Constants -//------------------------------------------------------------------- - extern HvLpIndex HvLpConfig_getLpIndex_outline(void); -//=================================================================== static inline HvLpIndex HvLpConfig_getLpIndex(void) { return itLpNaca.xLpIndex; } -//=================================================================== + static inline HvLpIndex HvLpConfig_getPrimaryLpIndex(void) { return itLpNaca.xPrimaryLpIndex; } -//================================================================= + static inline HvLpIndex HvLpConfig_getLps(void) { return HvCallCfg_getLps(); } -//================================================================= -static inline HvLpIndexMap HvLpConfig_getActiveLpMap(void) + +static inline HvLpIndexMap HvLpConfig_getActiveLpMap(void) { return HvCallCfg_getActiveLpMap(); } -//================================================================= -static inline u64 HvLpConfig_getSystemMsMegs(void) + +static inline u64 HvLpConfig_getSystemMsMegs(void) { return HvCallCfg_getSystemMsChunks() / HVCHUNKSPERMEG; } -//================================================================= -static inline u64 HvLpConfig_getSystemMsChunks(void) + +static inline u64 HvLpConfig_getSystemMsChunks(void) { return HvCallCfg_getSystemMsChunks(); } -//================================================================= -static inline u64 HvLpConfig_getSystemMsPages(void) + +static inline u64 HvLpConfig_getSystemMsPages(void) { return HvCallCfg_getSystemMsChunks() * HVPAGESPERCHUNK; } -//================================================================ -static inline u64 HvLpConfig_getMsMegs(void) + +static inline u64 HvLpConfig_getMsMegs(void) { - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Cur) / HVCHUNKSPERMEG; + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Cur) + / HVCHUNKSPERMEG; } -//================================================================ -static inline u64 HvLpConfig_getMsChunks(void) + +static inline u64 HvLpConfig_getMsChunks(void) { - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Cur); + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Cur); } -//================================================================ -static inline u64 HvLpConfig_getMsPages(void) + +static inline u64 HvLpConfig_getMsPages(void) { - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Cur) * HVPAGESPERCHUNK; + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Cur) + * HVPAGESPERCHUNK; } -//================================================================ -static inline u64 HvLpConfig_getMinMsMegs(void) + +static inline u64 HvLpConfig_getMinMsMegs(void) { - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Min) / HVCHUNKSPERMEG; + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Min) + / HVCHUNKSPERMEG; } -//================================================================ -static inline u64 HvLpConfig_getMinMsChunks(void) + +static inline u64 HvLpConfig_getMinMsChunks(void) { - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Min); + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Min); } -//================================================================ -static inline u64 HvLpConfig_getMinMsPages(void) + +static inline u64 HvLpConfig_getMinMsPages(void) { - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Min) * HVPAGESPERCHUNK; + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Min) + * HVPAGESPERCHUNK; } -//================================================================ -static inline u64 HvLpConfig_getMinRuntimeMsMegs(void) + +static inline u64 HvLpConfig_getMinRuntimeMsMegs(void) { - return HvCallCfg_getMinRuntimeMsChunks(HvLpConfig_getLpIndex()) / HVCHUNKSPERMEG; + return HvCallCfg_getMinRuntimeMsChunks(HvLpConfig_getLpIndex()) + / HVCHUNKSPERMEG; } -//=============================================================== -static inline u64 HvLpConfig_getMinRuntimeMsChunks(void) + +static inline u64 HvLpConfig_getMinRuntimeMsChunks(void) { return HvCallCfg_getMinRuntimeMsChunks(HvLpConfig_getLpIndex()); } -//=============================================================== -static inline u64 HvLpConfig_getMinRuntimeMsPages(void) + +static inline u64 HvLpConfig_getMinRuntimeMsPages(void) { - return HvCallCfg_getMinRuntimeMsChunks(HvLpConfig_getLpIndex()) * HVPAGESPERCHUNK; + return HvCallCfg_getMinRuntimeMsChunks(HvLpConfig_getLpIndex()) + * HVPAGESPERCHUNK; } -//=============================================================== -static inline u64 HvLpConfig_getMaxMsMegs(void) + +static inline u64 HvLpConfig_getMaxMsMegs(void) { - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Max) / HVCHUNKSPERMEG; + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Max) + / HVCHUNKSPERMEG; } -//=============================================================== -static inline u64 HvLpConfig_getMaxMsChunks(void) + +static inline u64 HvLpConfig_getMaxMsChunks(void) { - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Max); + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Max); } -//=============================================================== -static inline u64 HvLpConfig_getMaxMsPages(void) + +static inline u64 HvLpConfig_getMaxMsPages(void) { - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Max) * HVPAGESPERCHUNK; + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Max) + * HVPAGESPERCHUNK; } -//=============================================================== -static inline u64 HvLpConfig_getInitMsMegs(void) + +static inline u64 HvLpConfig_getInitMsMegs(void) { - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Init) / HVCHUNKSPERMEG; + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Init) + / HVCHUNKSPERMEG; } -//=============================================================== -static inline u64 HvLpConfig_getInitMsChunks(void) + +static inline u64 HvLpConfig_getInitMsChunks(void) { - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Init); + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Init); } -//=============================================================== -static inline u64 HvLpConfig_getInitMsPages(void) -{ return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Init) * HVPAGESPERCHUNK; + +static inline u64 HvLpConfig_getInitMsPages(void) +{ + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Init) + * HVPAGESPERCHUNK; } -//=============================================================== -static inline u64 HvLpConfig_getSystemPhysicalProcessors(void) + +static inline u64 HvLpConfig_getSystemPhysicalProcessors(void) { return HvCallCfg_getSystemPhysicalProcessors(); } -//=============================================================== -static inline u64 HvLpConfig_getSystemLogicalProcessors(void) + +static inline u64 HvLpConfig_getSystemLogicalProcessors(void) { - return HvCallCfg_getSystemPhysicalProcessors() * (/*getPaca()->getSecondaryThreadCount() +*/ 1); + return HvCallCfg_getSystemPhysicalProcessors() + * (/*getPaca()->getSecondaryThreadCount() +*/ 1); } -//=============================================================== -static inline u64 HvLpConfig_getNumProcsInSharedPool(HvLpSharedPoolIndex sPI) + +static inline u64 HvLpConfig_getNumProcsInSharedPool(HvLpSharedPoolIndex sPI) { return HvCallCfg_getNumProcsInSharedPool(sPI); } -//=============================================================== -static inline u64 HvLpConfig_getPhysicalProcessors(void) + +static inline u64 HvLpConfig_getPhysicalProcessors(void) { - return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Cur); + return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(), + HvCallCfg_Cur); } -//=============================================================== -static inline u64 HvLpConfig_getLogicalProcessors(void) + +static inline u64 HvLpConfig_getLogicalProcessors(void) { - return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Cur) * (/*getPaca()->getSecondaryThreadCount() +*/ 1); + return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(), + HvCallCfg_Cur) + * (/*getPaca()->getSecondaryThreadCount() +*/ 1); } -//=============================================================== -static inline HvLpSharedPoolIndex HvLpConfig_getSharedPoolIndex(void) + +static inline HvLpSharedPoolIndex HvLpConfig_getSharedPoolIndex(void) { return HvCallCfg_getSharedPoolIndex(HvLpConfig_getLpIndex()); } -//=============================================================== -static inline u64 HvLpConfig_getSharedProcUnits(void) + +static inline u64 HvLpConfig_getSharedProcUnits(void) { - return HvCallCfg_getSharedProcUnits(HvLpConfig_getLpIndex(),HvCallCfg_Cur); + return HvCallCfg_getSharedProcUnits(HvLpConfig_getLpIndex(), + HvCallCfg_Cur); } -//=============================================================== -static inline u64 HvLpConfig_getMinSharedProcUnits(void) + +static inline u64 HvLpConfig_getMinSharedProcUnits(void) { - return HvCallCfg_getSharedProcUnits(HvLpConfig_getLpIndex(),HvCallCfg_Min); + return HvCallCfg_getSharedProcUnits(HvLpConfig_getLpIndex(), + HvCallCfg_Min); } -//=============================================================== -static inline u64 HvLpConfig_getMaxSharedProcUnits(void) + +static inline u64 HvLpConfig_getMaxSharedProcUnits(void) { - return HvCallCfg_getSharedProcUnits(HvLpConfig_getLpIndex(),HvCallCfg_Max); + return HvCallCfg_getSharedProcUnits(HvLpConfig_getLpIndex(), + HvCallCfg_Max); } -//=============================================================== -static inline u64 HvLpConfig_getMinPhysicalProcessors(void) + +static inline u64 HvLpConfig_getMinPhysicalProcessors(void) { - return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Min); + return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(), + HvCallCfg_Min); } -//=============================================================== -static inline u64 HvLpConfig_getMinLogicalProcessors(void) + +static inline u64 HvLpConfig_getMinLogicalProcessors(void) { - return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Min) * (/*getPaca()->getSecondaryThreadCount() +*/ 1); + return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(), + HvCallCfg_Min) + * (/*getPaca()->getSecondaryThreadCount() +*/ 1); } -//=============================================================== -static inline u64 HvLpConfig_getMaxPhysicalProcessors(void) + +static inline u64 HvLpConfig_getMaxPhysicalProcessors(void) { - return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Max); + return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(), + HvCallCfg_Max); } -//=============================================================== -static inline u64 HvLpConfig_getMaxLogicalProcessors(void) + +static inline u64 HvLpConfig_getMaxLogicalProcessors(void) { - return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Max) * (/*getPaca()->getSecondaryThreadCount() +*/ 1); + return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(), + HvCallCfg_Max) + * (/*getPaca()->getSecondaryThreadCount() +*/ 1); } -//=============================================================== -static inline u64 HvLpConfig_getInitPhysicalProcessors(void) + +static inline u64 HvLpConfig_getInitPhysicalProcessors(void) { - return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Init); + return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(), + HvCallCfg_Init); } -//=============================================================== -static inline u64 HvLpConfig_getInitLogicalProcessors(void) + +static inline u64 HvLpConfig_getInitLogicalProcessors(void) { - return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Init) * (/*getPaca()->getSecondaryThreadCount() +*/ 1); + return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(), + HvCallCfg_Init) + * (/*getPaca()->getSecondaryThreadCount() +*/ 1); } -//================================================================ -static inline HvLpVirtualLanIndexMap HvLpConfig_getVirtualLanIndexMap(void) + +static inline HvLpVirtualLanIndexMap HvLpConfig_getVirtualLanIndexMap(void) { return HvCallCfg_getVirtualLanIndexMap(HvLpConfig_getLpIndex_outline()); } -//=============================================================== -static inline HvLpVirtualLanIndexMap HvLpConfig_getVirtualLanIndexMapForLp(HvLpIndex lp) + +static inline HvLpVirtualLanIndexMap HvLpConfig_getVirtualLanIndexMapForLp( + HvLpIndex lp) { return HvCallCfg_getVirtualLanIndexMap(lp); } -//================================================================ -static inline HvLpIndex HvLpConfig_getBusOwner(HvBusNumber busNumber) + +static inline HvLpIndex HvLpConfig_getBusOwner(HvBusNumber busNumber) { return HvCallCfg_getBusOwner(busNumber); } -//=============================================================== -static inline int HvLpConfig_isBusDedicated(HvBusNumber busNumber) + +static inline int HvLpConfig_isBusDedicated(HvBusNumber busNumber) { return HvCallCfg_isBusDedicated(busNumber); } -//================================================================ -static inline HvLpIndexMap HvLpConfig_getBusAllocation(HvBusNumber busNumber) + +static inline HvLpIndexMap HvLpConfig_getBusAllocation(HvBusNumber busNumber) { return HvCallCfg_getBusAllocation(busNumber); } -//================================================================ -// returns the absolute real address of the load area -static inline u64 HvLpConfig_getLoadAddress(void) + +/* returns the absolute real address of the load area */ +static inline u64 HvLpConfig_getLoadAddress(void) { return itLpNaca.xLoadAreaAddr & 0x7fffffffffffffff; } -//================================================================ -static inline u64 HvLpConfig_getLoadPages(void) + +static inline u64 HvLpConfig_getLoadPages(void) { return itLpNaca.xLoadAreaChunks * HVPAGESPERCHUNK; } -//================================================================ -static inline int HvLpConfig_isBusOwnedByThisLp(HvBusNumber busNumber) + +static inline int HvLpConfig_isBusOwnedByThisLp(HvBusNumber busNumber) { HvLpIndex busOwner = HvLpConfig_getBusOwner(busNumber); return (busOwner == HvLpConfig_getLpIndex()); } -//================================================================ -static inline int HvLpConfig_doLpsCommunicateOnVirtualLan(HvLpIndex lp1, HvLpIndex lp2) + +static inline int HvLpConfig_doLpsCommunicateOnVirtualLan(HvLpIndex lp1, + HvLpIndex lp2) { - HvLpVirtualLanIndexMap virtualLanIndexMap1 = HvCallCfg_getVirtualLanIndexMap( lp1 ); - HvLpVirtualLanIndexMap virtualLanIndexMap2 = HvCallCfg_getVirtualLanIndexMap( lp2 ); + HvLpVirtualLanIndexMap virtualLanIndexMap1 = + HvCallCfg_getVirtualLanIndexMap(lp1); + HvLpVirtualLanIndexMap virtualLanIndexMap2 = + HvCallCfg_getVirtualLanIndexMap(lp2); return ((virtualLanIndexMap1 & virtualLanIndexMap2) != 0); } -//================================================================ -static inline HvLpIndex HvLpConfig_getHostingLpIndex(HvLpIndex lp) + +static inline HvLpIndex HvLpConfig_getHostingLpIndex(HvLpIndex lp) { return HvCallCfg_getHostingLpIndex(lp); } -//================================================================ #endif /* _HVLPCONFIG_H */ diff --git a/include/asm-ppc64/iSeries/HvLpEvent.h b/include/asm-ppc64/iSeries/HvLpEvent.h index 30936e433064..865000de79b6 100644 --- a/include/asm-ppc64/iSeries/HvLpEvent.h +++ b/include/asm-ppc64/iSeries/HvLpEvent.h @@ -1,27 +1,24 @@ /* * HvLpEvent.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 */ -//====================================================================== -// -// This file contains the class for HV events in the system. -// -//===================================================================== +/* This file contains the class for HV events in the system. */ + #ifndef _HVLPEVENT_H #define _HVLPEVENT_H @@ -30,69 +27,70 @@ #include #include -//===================================================================== -// -// HvLpEvent is the structure for Lp Event messages passed between -// partitions through PLIC. -// -//===================================================================== - -struct HvEventFlags -{ - u8 xValid:1; // Indicates a valid request x00-x00 - u8 xRsvd1:4; // Reserved ... - u8 xAckType:1; // Immediate or deferred ... - u8 xAckInd:1; // Indicates if ACK required ... - u8 xFunction:1; // Interrupt or Acknowledge ... +/* + * HvLpEvent is the structure for Lp Event messages passed between + * partitions through PLIC. + */ + +struct HvEventFlags { + u8 xValid:1; /* Indicates a valid request x00-x00 */ + u8 xRsvd1:4; /* Reserved ... */ + u8 xAckType:1; /* Immediate or deferred ... */ + u8 xAckInd:1; /* Indicates if ACK required ... */ + u8 xFunction:1; /* Interrupt or Acknowledge ... */ }; -struct HvLpEvent -{ - struct HvEventFlags xFlags; // Event flags x00-x00 - u8 xType; // Type of message x01-x01 - u16 xSubtype; // Subtype for event x02-x03 - u8 xSourceLp; // Source LP x04-x04 - u8 xTargetLp; // Target LP x05-x05 - u8 xSizeMinus1; // Size of Derived class - 1 x06-x06 - u8 xRc; // RC for Ack flows x07-x07 - u16 xSourceInstanceId; // Source sides instance id x08-x09 - u16 xTargetInstanceId; // Target sides instance id x0A-x0B +struct HvLpEvent { + struct HvEventFlags xFlags; /* Event flags x00-x00 */ + u8 xType; /* Type of message x01-x01 */ + u16 xSubtype; /* Subtype for event x02-x03 */ + u8 xSourceLp; /* Source LP x04-x04 */ + u8 xTargetLp; /* Target LP x05-x05 */ + u8 xSizeMinus1; /* Size of Derived class - 1 x06-x06 */ + u8 xRc; /* RC for Ack flows x07-x07 */ + u16 xSourceInstanceId; /* Source sides instance id x08-x09 */ + u16 xTargetInstanceId; /* Target sides instance id x0A-x0B */ union { - u32 xSubtypeData; // Data usable by the subtype x0C-x0F - u16 xSubtypeDataShort[2]; // Data as 2 shorts - u8 xSubtypeDataChar[4]; // Data as 4 chars + u32 xSubtypeData; /* Data usable by the subtype x0C-x0F */ + u16 xSubtypeDataShort[2]; /* Data as 2 shorts */ + u8 xSubtypeDataChar[4]; /* Data as 4 chars */ } x; - u64 xCorrelationToken; // Unique value for source/type x10-x17 + u64 xCorrelationToken; /* Unique value for source/type x10-x17 */ }; -// Lp Event handler function typedef void (*LpEventHandler)(struct HvLpEvent *, struct pt_regs *); -// Register a handler for an event type -// returns 0 on success -extern int HvLpEvent_registerHandler( HvLpEvent_Type eventType, LpEventHandler hdlr); - -// Unregister a handler for an event type -// This call will sleep until the handler being removed is guaranteed to -// be no longer executing on any CPU. Do not call with locks held. -// -// returns 0 on success -// Unregister will fail if there are any paths open for the type -extern int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType ); +/* Register a handler for an event type - returns 0 on success */ +extern int HvLpEvent_registerHandler(HvLpEvent_Type eventType, + LpEventHandler hdlr); -// Open an Lp Event Path for an event type -// returns 0 on success -// openPath will fail if there is no handler registered for the event type. -// The lpIndex specified is the partition index for the target partition -// (for VirtualIo, VirtualLan and SessionMgr) other types specify zero) -extern int HvLpEvent_openPath( HvLpEvent_Type eventType, HvLpIndex lpIndex ); +/* + * Unregister a handler for an event type + * + * This call will sleep until the handler being removed is guaranteed to + * be no longer executing on any CPU. Do not call with locks held. + * + * returns 0 on success + * Unregister will fail if there are any paths open for the type + */ +extern int HvLpEvent_unregisterHandler(HvLpEvent_Type eventType); +/* + * Open an Lp Event Path for an event type + * returns 0 on success + * openPath will fail if there is no handler registered for the event type. + * The lpIndex specified is the partition index for the target partition + * (for VirtualIo, VirtualLan and SessionMgr) other types specify zero) + */ +extern int HvLpEvent_openPath(HvLpEvent_Type eventType, HvLpIndex lpIndex); -// Close an Lp Event Path for a type and partition -// returns 0 on sucess -extern int HvLpEvent_closePath( HvLpEvent_Type eventType, HvLpIndex lpIndex ); +/* + * Close an Lp Event Path for a type and partition + * returns 0 on sucess + */ +extern int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex); #define HvLpEvent_Type_Hypervisor 0 #define HvLpEvent_Type_MachineFac 1 @@ -141,4 +139,4 @@ extern int HvLpEvent_closePath( HvLpEvent_Type eventType, HvLpIndex lpIndex ); #define HvLpDma_Rc_InvalidAddress 4 #define HvLpDma_Rc_InvalidLength 5 -#endif // _HVLPEVENT_H +#endif /* _HVLPEVENT_H */ diff --git a/include/asm-ppc64/iSeries/HvReleaseData.h b/include/asm-ppc64/iSeries/HvReleaseData.h index 183e5e738c26..c0cd21caf8fd 100644 --- a/include/asm-ppc64/iSeries/HvReleaseData.h +++ b/include/asm-ppc64/iSeries/HvReleaseData.h @@ -1,17 +1,17 @@ /* * HvReleaseData.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 @@ -19,47 +19,43 @@ #ifndef _HVRELEASEDATA_H #define _HVRELEASEDATA_H -//============================================================================= -// -// This control block contains the critical information about the -// release so that it can be changed in the future (ie, the virtual -// address of the OS's NACA). -// +/* + * This control block contains the critical information about the + * release so that it can be changed in the future (ie, the virtual + * address of the OS's NACA). + */ #include #include -//============================================================================= -// -// When we IPL a secondary partition, we will check if if the -// secondary xMinPlicVrmIndex > the primary xVrmIndex. -// If it is then this tells PLIC that this secondary is not -// supported running on this "old" of a level of PLIC. -// -// Likewise, we will compare the primary xMinSlicVrmIndex to -// the secondary xVrmIndex. -// If the primary xMinSlicVrmDelta > secondary xVrmDelta then we -// know that this PLIC does not support running an OS "that old". -// -//============================================================================= +/* + * When we IPL a secondary partition, we will check if if the + * secondary xMinPlicVrmIndex > the primary xVrmIndex. + * If it is then this tells PLIC that this secondary is not + * supported running on this "old" of a level of PLIC. + * + * Likewise, we will compare the primary xMinSlicVrmIndex to + * the secondary xVrmIndex. + * If the primary xMinSlicVrmDelta > secondary xVrmDelta then we + * know that this PLIC does not support running an OS "that old". + */ -struct HvReleaseData -{ - u32 xDesc; // Descriptor "HvRD" ebcdic x00-x03 - u16 xSize; // Size of this control block x04-x05 - u16 xVpdAreasPtrOffset; // Offset in NACA of ItVpdAreas x06-x07 - struct naca_struct * xSlicNacaAddr; // Virt addr of SLIC NACA x08-x0F - u32 xMsNucDataOffset; // Offset of Linux Mapping Data x10-x13 - u32 xRsvd1; // Reserved x14-x17 - u16 xTagsMode:1; // 0 == tags active, 1 == tags inactive - u16 xAddressSize:1; // 0 == 64-bit, 1 == 32-bit - u16 xNoSharedProcs:1; // 0 == shared procs, 1 == no shared - u16 xNoHMT:1; // 0 == allow HMT, 1 == no HMT - u16 xRsvd2:12; // Reserved x18-x19 - u16 xVrmIndex; // VRM Index of OS image x1A-x1B - u16 xMinSupportedPlicVrmIndex;// Min PLIC level (soft) x1C-x1D - u16 xMinCompatablePlicVrmIndex;// Min PLIC levelP (hard) x1E-x1F - char xVrmName[12]; // Displayable name x20-x2B - char xRsvd3[20]; // Reserved x2C-x3F +struct HvReleaseData { + u32 xDesc; /* Descriptor "HvRD" ebcdic x00-x03 */ + u16 xSize; /* Size of this control block x04-x05 */ + u16 xVpdAreasPtrOffset; /* Offset in NACA of ItVpdAreas x06-x07 */ + struct naca_struct *xSlicNacaAddr; /* Virt addr of SLIC NACA x08-x0F */ + u32 xMsNucDataOffset; /* Offset of Linux Mapping Data x10-x13 */ + u32 xRsvd1; /* Reserved x14-x17 */ + u16 xTagsMode:1; /* 0 == tags active, 1 == tags inactive */ + u16 xAddressSize:1; /* 0 == 64-bit, 1 == 32-bit */ + u16 xNoSharedProcs:1; /* 0 == shared procs, 1 == no shared */ + u16 xNoHMT:1; /* 0 == allow HMT, 1 == no HMT */ + u16 xRsvd2:12; /* Reserved x18-x19 */ + u16 xVrmIndex; /* VRM Index of OS image x1A-x1B */ + u16 xMinSupportedPlicVrmIndex; /* Min PLIC level (soft) x1C-x1D */ + u16 xMinCompatablePlicVrmIndex; /* Min PLIC levelP (hard) x1E-x1F */ + char xVrmName[12]; /* Displayable name x20-x2B */ + char xRsvd3[20]; /* Reserved x2C-x3F */ }; #endif /* _HVRELEASEDATA_H */ diff --git a/include/asm-ppc64/iSeries/HvTypes.h b/include/asm-ppc64/iSeries/HvTypes.h index 3ec49c1aec32..111191ddb181 100644 --- a/include/asm-ppc64/iSeries/HvTypes.h +++ b/include/asm-ppc64/iSeries/HvTypes.h @@ -1,17 +1,17 @@ /* * HvTypes.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 @@ -19,74 +19,62 @@ #ifndef _HVTYPES_H #define _HVTYPES_H -//=========================================================================== -// Header File Id -// Name______________: HvTypes.H -// -// Description_______: -// -// General typedefs for the hypervisor. -// -// Declared Class(es): -// -//=========================================================================== +/* + * General typedefs for the hypervisor. + */ #include -//------------------------------------------------------------------- -// Typedefs -//------------------------------------------------------------------- typedef u8 HvLpIndex; typedef u16 HvLpInstanceId; -typedef u64 HvLpTOD; -typedef u64 HvLpSystemSerialNum; -typedef u8 HvLpDeviceSerialNum[12]; -typedef u16 HvLpSanHwSet; -typedef u16 HvLpBus; -typedef u16 HvLpBoard; -typedef u16 HvLpCard; -typedef u8 HvLpDeviceType[4]; -typedef u8 HvLpDeviceModel[3]; -typedef u64 HvIoToken; -typedef u8 HvLpName[8]; +typedef u64 HvLpTOD; +typedef u64 HvLpSystemSerialNum; +typedef u8 HvLpDeviceSerialNum[12]; +typedef u16 HvLpSanHwSet; +typedef u16 HvLpBus; +typedef u16 HvLpBoard; +typedef u16 HvLpCard; +typedef u8 HvLpDeviceType[4]; +typedef u8 HvLpDeviceModel[3]; +typedef u64 HvIoToken; +typedef u8 HvLpName[8]; typedef u32 HvIoId; typedef u64 HvRealMemoryIndex; -typedef u32 HvLpIndexMap; // Must hold HvMaxArchitectedLps bits!!! +typedef u32 HvLpIndexMap; /* Must hold HvMaxArchitectedLps bits!!! */ typedef u16 HvLpVrmIndex; typedef u32 HvXmGenerationId; -typedef u8 HvLpBusPool; -typedef u8 HvLpSharedPoolIndex; +typedef u8 HvLpBusPool; +typedef u8 HvLpSharedPoolIndex; typedef u16 HvLpSharedProcUnitsX100; typedef u8 HvLpVirtualLanIndex; -typedef u16 HvLpVirtualLanIndexMap; // Must hold HvMaxArchitectedVirtualLans bits!!! -typedef u16 HvBusNumber; // Hypervisor Bus Number -typedef u8 HvSubBusNumber; // Hypervisor SubBus Number -typedef u8 HvAgentId; // Hypervisor DevFn +typedef u16 HvLpVirtualLanIndexMap; /* Must hold HvMaxArchitectedVirtualLans bits!!! */ +typedef u16 HvBusNumber; /* Hypervisor Bus Number */ +typedef u8 HvSubBusNumber; /* Hypervisor SubBus Number */ +typedef u8 HvAgentId; /* Hypervisor DevFn */ + +#define HVMAXARCHITECTEDLPS 32 +#define HVMAXARCHITECTEDVIRTUALLANS 16 +#define HVMAXARCHITECTEDVIRTUALDISKS 32 +#define HVMAXARCHITECTEDVIRTUALCDROMS 8 +#define HVMAXARCHITECTEDVIRTUALTAPES 8 +#define HVCHUNKSIZE (256 * 1024) +#define HVPAGESIZE (4 * 1024) +#define HVLPMINMEGSPRIMARY 256 +#define HVLPMINMEGSSECONDARY 64 +#define HVCHUNKSPERMEG 4 +#define HVPAGESPERMEG 256 +#define HVPAGESPERCHUNK 64 -#define HVMAXARCHITECTEDLPS 32 -#define HVMAXARCHITECTEDVIRTUALLANS 16 -#define HVMAXARCHITECTEDVIRTUALDISKS 32 -#define HVMAXARCHITECTEDVIRTUALCDROMS 8 -#define HVMAXARCHITECTEDVIRTUALTAPES 8 -#define HVCHUNKSIZE 256 * 1024 -#define HVPAGESIZE 4 * 1024 -#define HVLPMINMEGSPRIMARY 256 -#define HVLPMINMEGSSECONDARY 64 -#define HVCHUNKSPERMEG 4 -#define HVPAGESPERMEG 256 -#define HVPAGESPERCHUNK 64 - -#define HvMaxArchitectedLps ((HvLpIndex)HVMAXARCHITECTEDLPS) +#define HvMaxArchitectedLps ((HvLpIndex)HVMAXARCHITECTEDLPS) #define HvMaxArchitectedVirtualLans ((HvLpVirtualLanIndex)16) #define HvLpIndexInvalid ((HvLpIndex)0xff) -//-------------------------------------------------------------------- -// Enums for the sub-components under PLIC -// Used in HvCall and HvPrimaryCall -//-------------------------------------------------------------------- -enum HvCallCompIds -{ +/* + * Enums for the sub-components under PLIC + * Used in HvCall and HvPrimaryCall + */ +enum HvCallCompIds { HvCallCompId = 0, HvCallCpuCtlsCompId = 1, HvCallCfgCompId = 2, @@ -97,18 +85,18 @@ enum HvCallCompIds HvCallSmCompId = 7, HvCallSpdCompId = 8, HvCallXmCompId = 9, - HvCallRioCompId = 10, + HvCallRioCompId = 10, HvCallRsvd3CompId = 11, HvCallRsvd2CompId = 12, HvCallRsvd1CompId = 13, HvCallMaxCompId = 14, - HvPrimaryCallCompId = 0, + HvPrimaryCallCompId = 0, HvPrimaryCallCfgCompId = 1, - HvPrimaryCallPciCompId = 2, + HvPrimaryCallPciCompId = 2, HvPrimaryCallSmCompId = 3, HvPrimaryCallSpdCompId = 4, HvPrimaryCallXmCompId = 5, - HvPrimaryCallRioCompId = 6, + HvPrimaryCallRioCompId = 6, HvPrimaryCallRsvd7CompId = 7, HvPrimaryCallRsvd6CompId = 8, HvPrimaryCallRsvd5CompId = 9, @@ -116,7 +104,7 @@ enum HvCallCompIds HvPrimaryCallRsvd3CompId = 11, HvPrimaryCallRsvd2CompId = 12, HvPrimaryCallRsvd1CompId = 13, - HvPrimaryCallMaxCompId = HvCallMaxCompId + HvPrimaryCallMaxCompId = HvCallMaxCompId }; struct HvLpBufferList { -- cgit v1.2.3-59-g8ed1b From fcee38952609fccb2bdfe166b3b96bd75a292aa6 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:34 -0700 Subject: [PATCH] ppc64 iSeries: more header file white space cleanups This patch just contains white space and comment cleanups in the iSeries headers files. There are no semantic changes. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-ppc64/iSeries/IoHriMainStore.h | 33 +++--- include/asm-ppc64/iSeries/IoHriProcessorVpd.h | 30 +++-- include/asm-ppc64/iSeries/ItExtVpdPanel.h | 52 ++++----- include/asm-ppc64/iSeries/ItIplParmsReal.h | 97 ++++++++-------- include/asm-ppc64/iSeries/ItLpNaca.h | 42 +++---- include/asm-ppc64/iSeries/ItLpQueue.h | 74 ++++++------ include/asm-ppc64/iSeries/ItLpRegSave.h | 41 +++---- include/asm-ppc64/iSeries/ItSpCommArea.h | 10 +- include/asm-ppc64/iSeries/ItVpdAreas.h | 121 ++++++++++---------- include/asm-ppc64/iSeries/LparData.h | 27 +++-- include/asm-ppc64/iSeries/LparMap.h | 42 +++---- include/asm-ppc64/iSeries/XmPciLpEvent.h | 3 - include/asm-ppc64/iSeries/iSeries_io.h | 59 +++++----- include/asm-ppc64/iSeries/iSeries_pci.h | 159 +++++++++++++------------- include/asm-ppc64/iSeries/mf.h | 5 +- include/asm-ppc64/iSeries/vio.h | 37 +++--- 16 files changed, 395 insertions(+), 437 deletions(-) diff --git a/include/asm-ppc64/iSeries/IoHriMainStore.h b/include/asm-ppc64/iSeries/IoHriMainStore.h index ff00e865f620..fbb3ee4d174b 100644 --- a/include/asm-ppc64/iSeries/IoHriMainStore.h +++ b/include/asm-ppc64/iSeries/IoHriMainStore.h @@ -1,17 +1,17 @@ /* * IoHriMainStore.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 @@ -21,7 +21,7 @@ #define _IOHRIMAINSTORE_H /* Main Store Vpd for Condor,iStar,sStar */ -struct IoHriMainStoreSegment4 { +struct IoHriMainStoreSegment4 { u8 msArea0Exists:1; u8 msArea1Exists:1; u8 msArea2Exists:1; @@ -51,7 +51,7 @@ struct IoHriMainStoreSegment4 { u8 msArea1HasRiserVpd:1; u8 msArea2HasRiserVpd:1; u8 msArea3HasRiserVpd:1; - u8 reserved5:4; + u8 reserved5:4; u8 reserved6; u16 reserved7; @@ -82,8 +82,8 @@ struct IoHriMainStoreVpdFruData { }; struct IoHriMainStoreAdrRangeBlock { - void * blockStart __attribute((packed)); - void * blockEnd __attribute((packed)); + void *blockStart __attribute((packed)); + void *blockEnd __attribute((packed)); u32 blockProcChipId __attribute((packed)); }; @@ -102,7 +102,7 @@ struct IoHriMainStoreArea4 { u32 procNodeId __attribute((packed)); u32 numAdrRangeBlocks __attribute((packed)); - struct IoHriMainStoreAdrRangeBlock xAdrRangeBlock[MaxAreaAdrRangeBlocks] __attribute((packed)); + struct IoHriMainStoreAdrRangeBlock xAdrRangeBlock[MaxAreaAdrRangeBlocks] __attribute((packed)); struct IoHriMainStoreChipInfo1 chipInfo0 __attribute((packed)); struct IoHriMainStoreChipInfo1 chipInfo1 __attribute((packed)); @@ -113,17 +113,17 @@ struct IoHriMainStoreArea4 { struct IoHriMainStoreChipInfo1 chipInfo6 __attribute((packed)); struct IoHriMainStoreChipInfo1 chipInfo7 __attribute((packed)); - void * msRamAreaArray __attribute((packed)); + void *msRamAreaArray __attribute((packed)); u32 msRamAreaArrayNumEntries __attribute((packed)); u32 msRamAreaArrayEntrySize __attribute((packed)); u32 numaDimmExists __attribute((packed)); u32 numaDimmFunctional __attribute((packed)); - void * numaDimmArray __attribute((packed)); + void *numaDimmArray __attribute((packed)); u32 numaDimmArrayNumEntries __attribute((packed)); u32 numaDimmArrayEntrySize __attribute((packed)); - struct IoHriMainStoreVpdIdData idData __attribute((packed)); + struct IoHriMainStoreVpdIdData idData __attribute((packed)); u64 powerData __attribute((packed)); u64 cardAssemblyPartNum __attribute((packed)); @@ -143,7 +143,7 @@ struct IoHriMainStoreArea4 { }; -struct IoHriMainStoreSegment5 { +struct IoHriMainStoreSegment5 { u16 reserved1; u8 reserved2; u8 msVpdFormat; @@ -151,17 +151,14 @@ struct IoHriMainStoreSegment5 { u32 totalMainStore; u64 maxConfiguredMsAdr; - struct IoHriMainStoreArea4* msAreaArray; + struct IoHriMainStoreArea4 *msAreaArray; u32 msAreaArrayNumEntries; u32 msAreaArrayEntrySize; - u32 msAreaExists; + u32 msAreaExists; u32 msAreaFunctional; u64 reserved3; }; - - -#endif // _IOHRIMAINSTORE_H - +#endif /* _IOHRIMAINSTORE_H */ diff --git a/include/asm-ppc64/iSeries/IoHriProcessorVpd.h b/include/asm-ppc64/iSeries/IoHriProcessorVpd.h index 965433888653..ccb7b7c55a40 100644 --- a/include/asm-ppc64/iSeries/IoHriProcessorVpd.h +++ b/include/asm-ppc64/iSeries/IoHriProcessorVpd.h @@ -1,17 +1,17 @@ /* * IoHriProcessorVpd.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 @@ -19,16 +19,12 @@ #ifndef _IOHRIPROCESSORVPD_H #define _IOHRIPROCESSORVPD_H -//=================================================================== -// -// This struct maps Processor Vpd that is DMAd to SLIC by CSP -// - #include -struct IoHriProcessorVpd -{ - +/* + * This struct maps Processor Vpd that is DMAd to SLIC by CSP + */ +struct IoHriProcessorVpd { u8 xFormat; // VPD format indicator x00-x00 u8 xProcStatus:8; // Processor State x01-x01 u8 xSecondaryThreadCount; // Secondary thread cnt x02-x02 @@ -40,12 +36,12 @@ struct IoHriProcessorVpd u16 xRsvd2; // Reserved x06-x07 u32 xHwNodeId; // Hardware node id x08-x0B u32 xHwProcId; // Hardware processor id x0C-x0F - + u32 xTypeNum; // Card Type/CCIN number x10-x13 u32 xModelNum; // Model/Feature number x14-x17 u64 xSerialNum; // Serial number x18-x1F - char xPartNum[12]; // Book Part or FPU number x20-x2B - char xMfgID[4]; // Manufacturing ID x2C-x2F + char xPartNum[12]; // Book Part or FPU number x20-x2B + char xMfgID[4]; // Manufacturing ID x2C-x2F u32 xProcFreq; // Processor Frequency x30-x33 u32 xTimeBaseFreq; // Time Base Frequency x34-x37 @@ -71,7 +67,7 @@ struct IoHriProcessorVpd u32 xDataL3CacheSizeKB; // L3 data cache size in KB x80-x83 u32 xDataL3CacheLineSize; // L3 data cache block size x84-x87 u64 xRsvd6; // Reserved x88-x8F - + u64 xFruLabel; // Card Location Label x90-x97 u8 xSlotsOnCard; // Slots on card (0=no slots) x98-x98 u8 xPartLocFlag; // Location flag (0-pluggable 1-imbedded) x99-x99 @@ -79,10 +75,10 @@ struct IoHriProcessorVpd u8 xSmartCardPortNo; // Smart card port number x9C-x9C u8 xRsvd7; // Reserved x9D-x9D u16 xFrameIdAndRackUnit; // Frame ID and rack unit adr x9E-x9F - + u8 xRsvd8[24]; // Reserved xA0-xB7 - char xProcSrc[72]; // CSP format SRC xB8-xFF + char xProcSrc[72]; // CSP format SRC xB8-xFF }; #endif /* _IOHRIPROCESSORVPD_H */ diff --git a/include/asm-ppc64/iSeries/ItExtVpdPanel.h b/include/asm-ppc64/iSeries/ItExtVpdPanel.h index dee6b1273031..b7149079d3ca 100644 --- a/include/asm-ppc64/iSeries/ItExtVpdPanel.h +++ b/include/asm-ppc64/iSeries/ItExtVpdPanel.h @@ -1,17 +1,17 @@ /* * ItExtVpdPanel.h * Copyright (C) 2002 Dave Boutcher IBM Corporation - * + * * 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 @@ -20,39 +20,31 @@ #define _ITEXTVPDPANEL_H /* - * - * This struct maps the panel information + * This struct maps the panel information * * Warning: * This data must match the architecture for the panel information - * */ - -/*------------------------------------------------------------------- - * Standard Includes - *------------------------------------------------------------------- -*/ #include -struct ItExtVpdPanel -{ - // Definition of the Extended Vpd On Panel Data Area - char systemSerial[8]; - char mfgID[4]; - char reserved1[24]; - char machineType[4]; - char systemID[6]; - char somUniqueCnt[4]; - char serialNumberCount; - char reserved2[7]; - u16 bbu3; - u16 bbu2; - u16 bbu1; - char xLocationLabel[8]; - u8 xRsvd1[6]; - u16 xFrameId; - u8 xRsvd2[48]; +struct ItExtVpdPanel { + /* Definition of the Extended Vpd On Panel Data Area */ + char systemSerial[8]; + char mfgID[4]; + char reserved1[24]; + char machineType[4]; + char systemID[6]; + char somUniqueCnt[4]; + char serialNumberCount; + char reserved2[7]; + u16 bbu3; + u16 bbu2; + u16 bbu1; + char xLocationLabel[8]; + u8 xRsvd1[6]; + u16 xFrameId; + u8 xRsvd2[48]; }; -#endif /* _ITEXTVPDPANEL_H */ +#endif /* _ITEXTVPDPANEL_H */ diff --git a/include/asm-ppc64/iSeries/ItIplParmsReal.h b/include/asm-ppc64/iSeries/ItIplParmsReal.h index 4d8b430ab12d..14f0b0a2a823 100644 --- a/include/asm-ppc64/iSeries/ItIplParmsReal.h +++ b/include/asm-ppc64/iSeries/ItIplParmsReal.h @@ -1,17 +1,17 @@ /* * ItIplParmsReal.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 @@ -19,58 +19,51 @@ #ifndef _ITIPLPARMSREAL_H #define _ITIPLPARMSREAL_H -//============================================================================== -// -// This struct maps the IPL Parameters DMA'd from the SP. -// -// Warning: -// This data must map in exactly 64 bytes and match the architecture for -// the IPL parms -// -//============================================================================= - +/* + * This struct maps the IPL Parameters DMA'd from the SP. + * + * Warning: + * This data must map in exactly 64 bytes and match the architecture for + * the IPL parms + */ -//------------------------------------------------------------------- -// Standard Includes -//------------------------------------------------------------------- #include -struct ItIplParmsReal -{ - u8 xFormat; // Defines format of IplParms x00-x00 - u8 xRsvd01:6; // Reserved x01-x01 - u8 xAlternateSearch:1; // Alternate search indicator ... - u8 xUaSupplied:1; // UA Supplied on programmed IPL ... - u8 xLsUaFormat; // Format byte for UA x02-x02 - u8 xRsvd02; // Reserved x03-x03 - u32 xLsUa; // LS UA x04-x07 - u32 xUnusedLsLid; // First OS LID to load x08-x0B - u16 xLsBusNumber; // LS Bus Number x0C-x0D - u8 xLsCardAdr; // LS Card Address x0E-x0E - u8 xLsBoardAdr; // LS Board Address x0F-x0F - u32 xRsvd03; // Reserved x10-x13 - u8 xSpcnPresent:1; // SPCN present x14-x14 - u8 xCpmPresent:1; // CPM present ... - u8 xRsvd04:6; // Reserved ... - u8 xRsvd05:4; // Reserved x15-x15 - u8 xKeyLock:4; // Keylock setting ... - u8 xRsvd06:6; // Reserved x16-x16 - u8 xIplMode:2; // Ipl mode (A|B|C|D) ... - u8 xHwIplType; // Fast v slow v slow EC HW IPL x17-x17 - u16 xCpmEnabledIpl:1; // CPM in effect when IPL initiated x18-x19 - u16 xPowerOnResetIpl:1; // Indicate POR condition ... - u16 xMainStorePreserved:1; // Main Storage is preserved ... - u16 xRsvd07:13; // Reserved ... - u16 xIplSource:16; // Ipl source x1A-x1B - u8 xIplReason:8; // Reason for this IPL x1C-x1C - u8 xRsvd08; // Reserved x1D-x1D - u16 xRsvd09; // Reserved x1E-x1F - u16 xSysBoxType; // System Box Type x20-x21 - u16 xSysProcType; // System Processor Type x22-x23 - u32 xRsvd10; // Reserved x24-x27 - u64 xRsvd11; // Reserved x28-x2F - u64 xRsvd12; // Reserved x30-x37 - u64 xRsvd13; // Reserved x38-x3F +struct ItIplParmsReal { + u8 xFormat; // Defines format of IplParms x00-x00 + u8 xRsvd01:6; // Reserved x01-x01 + u8 xAlternateSearch:1; // Alternate search indicator ... + u8 xUaSupplied:1; // UA Supplied on programmed IPL... + u8 xLsUaFormat; // Format byte for UA x02-x02 + u8 xRsvd02; // Reserved x03-x03 + u32 xLsUa; // LS UA x04-x07 + u32 xUnusedLsLid; // First OS LID to load x08-x0B + u16 xLsBusNumber; // LS Bus Number x0C-x0D + u8 xLsCardAdr; // LS Card Address x0E-x0E + u8 xLsBoardAdr; // LS Board Address x0F-x0F + u32 xRsvd03; // Reserved x10-x13 + u8 xSpcnPresent:1; // SPCN present x14-x14 + u8 xCpmPresent:1; // CPM present ... + u8 xRsvd04:6; // Reserved ... + u8 xRsvd05:4; // Reserved x15-x15 + u8 xKeyLock:4; // Keylock setting ... + u8 xRsvd06:6; // Reserved x16-x16 + u8 xIplMode:2; // Ipl mode (A|B|C|D) ... + u8 xHwIplType; // Fast v slow v slow EC HW IPL x17-x17 + u16 xCpmEnabledIpl:1; // CPM in effect when IPL initiatedx18-x19 + u16 xPowerOnResetIpl:1; // Indicate POR condition ... + u16 xMainStorePreserved:1; // Main Storage is preserved ... + u16 xRsvd07:13; // Reserved ... + u16 xIplSource:16; // Ipl source x1A-x1B + u8 xIplReason:8; // Reason for this IPL x1C-x1C + u8 xRsvd08; // Reserved x1D-x1D + u16 xRsvd09; // Reserved x1E-x1F + u16 xSysBoxType; // System Box Type x20-x21 + u16 xSysProcType; // System Processor Type x22-x23 + u32 xRsvd10; // Reserved x24-x27 + u64 xRsvd11; // Reserved x28-x2F + u64 xRsvd12; // Reserved x30-x37 + u64 xRsvd13; // Reserved x38-x3F }; #endif /* _ITIPLPARMSREAL_H */ diff --git a/include/asm-ppc64/iSeries/ItLpNaca.h b/include/asm-ppc64/iSeries/ItLpNaca.h index 5baffddfae1b..942b07d91408 100644 --- a/include/asm-ppc64/iSeries/ItLpNaca.h +++ b/include/asm-ppc64/iSeries/ItLpNaca.h @@ -1,17 +1,17 @@ /* * ItLpNaca.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 @@ -19,18 +19,13 @@ #ifndef _ITLPNACA_H #define _ITLPNACA_H -//============================================================================= -// -// This control block contains the data that is shared between the -// hypervisor (PLIC) and the OS. -// -//============================================================================= +/* + * This control block contains the data that is shared between the + * hypervisor (PLIC) and the OS. + */ -struct ItLpNaca -{ -//============================================================================= +struct ItLpNaca { // CACHE_LINE_1 0x0000 - 0x007F Contains read-only data -//============================================================================= u32 xDesc; // Eye catcher x00-x03 u16 xSize; // Size of this class x04-x05 u16 xIntHdlrOffset; // Offset to IntHdlr array x06-x07 @@ -59,30 +54,23 @@ struct ItLpNaca u64 xLoadAreaAddr; // ER address of load area x28-x2F u32 xLoadAreaChunks; // Chunks for the load area x30-x33 u32 xPaseSysCallCRMask; // Mask used to test CR before x34-x37 - // doing an ASR switch on PASE - // system call. - u64 xSlicSegmentTablePtr; // Pointer to Slic seg table. x38-x3f - u8 xRsvd1_4[64]; // x40-x7F - -//============================================================================= + // doing an ASR switch on PASE + // system call. + u64 xSlicSegmentTablePtr; // Pointer to Slic seg table. x38-x3f + u8 xRsvd1_4[64]; // x40-x7F + // CACHE_LINE_2 0x0080 - 0x00FF Contains local read-write data -//============================================================================= u8 xRsvd2_0[128]; // Reserved x00-x7F -//============================================================================= // CACHE_LINE_3-6 0x0100 - 0x02FF Contains LP Queue indicators -// NB: Padding required to keep xInterrruptHdlr at x300 which is required +// NB: Padding required to keep xInterrruptHdlr at x300 which is required // for v4r4 PLIC. -//============================================================================= u8 xOldLpQueue[128]; // LP Queue needed for v4r4 100-17F u8 xRsvd3_0[384]; // Reserved 180-2FF -//============================================================================= + // CACHE_LINE_7-8 0x0300 - 0x03FF Contains the address of the OS interrupt // handlers -//============================================================================= u64 xInterruptHdlr[32]; // Interrupt handlers 300-x3FF }; -//============================================================================= - #endif /* _ITLPNACA_H */ diff --git a/include/asm-ppc64/iSeries/ItLpQueue.h b/include/asm-ppc64/iSeries/ItLpQueue.h index 4f4dde2a638d..b2bdef429591 100644 --- a/include/asm-ppc64/iSeries/ItLpQueue.h +++ b/include/asm-ppc64/iSeries/ItLpQueue.h @@ -1,17 +1,17 @@ /* * ItLpQueue.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 @@ -19,47 +19,47 @@ #ifndef _ITLPQUEUE_H #define _ITLPQUEUE_H -//============================================================================= -// -// This control block defines the simple LP queue structure that is -// shared between the hypervisor (PLIC) and the OS in order to send -// events to an LP. -// +/* + * This control block defines the simple LP queue structure that is + * shared between the hypervisor (PLIC) and the OS in order to send + * events to an LP. + */ #include #include struct HvLpEvent; -#define ITMaxLpQueues 8 +#define ITMaxLpQueues 8 #define NotUsed 0 // Queue will not be used by PLIC #define DedicatedIo 1 // Queue dedicated to IO processor specified #define DedicatedLp 2 // Queue dedicated to LP specified #define Shared 3 // Queue shared for both IO and LP -#define LpEventStackSize 4096 -#define LpEventMaxSize 256 -#define LpEventAlign 64 +#define LpEventStackSize 4096 +#define LpEventMaxSize 256 +#define LpEventAlign 64 -struct ItLpQueue -{ -// -// The xSlicCurEventPtr is the pointer to the next event stack entry that will -// become valid. The OS must peek at this entry to determine if it is valid. -// PLIC will set the valid indicator as the very last store into that entry. -// -// When the OS has completed processing of the event then it will mark the event -// as invalid so that PLIC knows it can store into that event location again. -// -// If the event stack fills and there are overflow events, then PLIC will set -// the xPlicOverflowIntPending flag in which case the OS will have to fetch the -// additional LP events once they have drained the event stack. -// -// The first 16-bytes are known by both the OS and PLIC. The remainder of the -// cache line is for use by the OS. -// -//============================================================================= +struct ItLpQueue { +/* + * The xSlicCurEventPtr is the pointer to the next event stack entry + * that will become valid. The OS must peek at this entry to determine + * if it is valid. PLIC will set the valid indicator as the very last + * store into that entry. + * + * When the OS has completed processing of the event then it will mark + * the event as invalid so that PLIC knows it can store into that event + * location again. + * + * If the event stack fills and there are overflow events, then PLIC + * will set the xPlicOverflowIntPending flag in which case the OS will + * have to fetch the additional LP events once they have drained the + * event stack. + * + * The first 16-bytes are known by both the OS and PLIC. The remainder + * of the cache line is for use by the OS. + */ u8 xPlicOverflowIntPending;// 0x00 Overflow events are pending u8 xPlicStatus; // 0x01 DedicatedIo or DedicatedLp or NotUsed u16 xSlicLogicalProcIndex; // 0x02 Logical Proc Index for correlation @@ -76,17 +76,17 @@ struct ItLpQueue extern struct ItLpQueue xItLpQueue; -extern struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * ); -extern int ItLpQueue_isLpIntPending( struct ItLpQueue * ); -extern unsigned ItLpQueue_process( struct ItLpQueue *, struct pt_regs * ); -extern void ItLpQueue_clearValid( struct HvLpEvent * ); +extern struct HvLpEvent * ItLpQueue_getNextLpEvent(struct ItLpQueue *); +extern int ItLpQueue_isLpIntPending(struct ItLpQueue *); +extern unsigned ItLpQueue_process(struct ItLpQueue *, struct pt_regs *); +extern void ItLpQueue_clearValid(struct HvLpEvent *); -static __inline__ void process_iSeries_events( void ) +static __inline__ void process_iSeries_events(void) { __asm__ __volatile__ ( " li 0,0x5555 \n\ sc" - : : : "r0", "r3" ); + : : : "r0", "r3"); } #endif /* _ITLPQUEUE_H */ diff --git a/include/asm-ppc64/iSeries/ItLpRegSave.h b/include/asm-ppc64/iSeries/ItLpRegSave.h index dafc4c813788..1b3087e76205 100644 --- a/include/asm-ppc64/iSeries/ItLpRegSave.h +++ b/include/asm-ppc64/iSeries/ItLpRegSave.h @@ -1,17 +1,17 @@ /* * ItLpRegSave.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 @@ -19,33 +19,30 @@ #ifndef _ITLPREGSAVE_H #define _ITLPREGSAVE_H -//===================================================================================== -// -// This control block contains the data that is shared between PLIC -// and the OS -// -// +/* + * This control block contains the data that is shared between PLIC + * and the OS + */ -struct ItLpRegSave -{ +struct ItLpRegSave { u32 xDesc; // Eye catcher "LpRS" ebcdic 000-003 u16 xSize; // Size of this class 004-005 u8 xInUse; // Area is live 006-007 - u8 xRsvd1[9]; // Reserved 007-00F + u8 xRsvd1[9]; // Reserved 007-00F - u8 xFixedRegSave[352]; // Fixed Register Save Area 010-16F + u8 xFixedRegSave[352]; // Fixed Register Save Area 010-16F u32 xCTRL; // Control Register 170-173 - u32 xDEC; // Decrementer 174-177 + u32 xDEC; // Decrementer 174-177 u32 xFPSCR; // FP Status and Control Reg 178-17B u32 xPVR; // Processor Version Number 17C-17F - + u64 xMMCR0; // Monitor Mode Control Reg 0 180-187 u32 xPMC1; // Perf Monitor Counter 1 188-18B u32 xPMC2; // Perf Monitor Counter 2 18C-18F u32 xPMC3; // Perf Monitor Counter 3 190-193 u32 xPMC4; // Perf Monitor Counter 4 194-197 u32 xPIR; // Processor ID Reg 198-19B - + u32 xMMCR1; // Monitor Mode Control Reg 1 19C-19F u32 xMMCRA; // Monitor Mode Control Reg A 1A0-1A3 u32 xPMC5; // Perf Monitor Counter 5 1A4-1A7 @@ -57,17 +54,17 @@ struct ItLpRegSave u32 xRsvd; // Reserved 1BC-1BF u64 xACCR; // Address Compare Control Reg 1C0-1C7 - u64 xIMR; // Instruction Match Register 1C8-1CF - u64 xSDR1; // Storage Description Reg 1 1D0-1D7 + u64 xIMR; // Instruction Match Register 1C8-1CF + u64 xSDR1; // Storage Description Reg 1 1D0-1D7 u64 xSPRG0; // Special Purpose Reg General0 1D8-1DF u64 xSPRG1; // Special Purpose Reg General1 1E0-1E7 u64 xSPRG2; // Special Purpose Reg General2 1E8-1EF u64 xSPRG3; // Special Purpose Reg General3 1F0-1F7 u64 xTB; // Time Base Register 1F8-1FF - + u64 xFPR[32]; // Floating Point Registers 200-2FF - u64 xMSR; // Machine State Register 300-307 + u64 xMSR; // Machine State Register 300-307 u64 xNIA; // Next Instruction Address 308-30F u64 xDABR; // Data Address Breakpoint Reg 310-317 @@ -76,8 +73,8 @@ struct ItLpRegSave u64 xHID0; // HW Implementation Dependent0 320-327 u64 xHID4; // HW Implementation Dependent4 328-32F - u64 xSCOMd; // SCON Data Reg (SPRG4) 330-337 - u64 xSCOMc; // SCON Command Reg (SPRG5) 338-33F + u64 xSCOMd; // SCON Data Reg (SPRG4) 330-337 + u64 xSCOMc; // SCON Command Reg (SPRG5) 338-33F u64 xSDAR; // Sample Data Address Register 340-347 u64 xSIAR; // Sample Inst Address Register 348-34F diff --git a/include/asm-ppc64/iSeries/ItSpCommArea.h b/include/asm-ppc64/iSeries/ItSpCommArea.h index f1b56f9e11e2..5535f8271c9f 100644 --- a/include/asm-ppc64/iSeries/ItSpCommArea.h +++ b/include/asm-ppc64/iSeries/ItSpCommArea.h @@ -1,29 +1,27 @@ /* * ItSpCommArea.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef _ITSPCOMMAREA_H #define _ITSPCOMMAREA_H -struct SpCommArea -{ +struct SpCommArea { u32 xDesc; // Descriptor (only in new formats) 000-003 u8 xFormat; // Format (only in new formats) 004-004 u8 xRsvd1[11]; // Reserved 005-00F diff --git a/include/asm-ppc64/iSeries/ItVpdAreas.h b/include/asm-ppc64/iSeries/ItVpdAreas.h index d120439f30a5..cfb9925e40aa 100644 --- a/include/asm-ppc64/iSeries/ItVpdAreas.h +++ b/include/asm-ppc64/iSeries/ItVpdAreas.h @@ -1,17 +1,17 @@ /* * ItVpdAreas.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 @@ -19,78 +19,75 @@ #ifndef _ITVPDAREAS_H #define _ITVPDAREAS_H -//===================================================================================== -// -// This file defines the address and length of all of the VPD area passed to -// the OS from PLIC (most of which start from the SP). -// +/* + * This file defines the address and length of all of the VPD area passed to + * the OS from PLIC (most of which start from the SP). + */ #include -// VPD Entry index is carved in stone - cannot be changed (easily). -#define ItVpdCecVpd 0 -#define ItVpdDynamicSpace 1 -#define ItVpdExtVpd 2 -#define ItVpdExtVpdOnPanel 3 -#define ItVpdFirstPaca 4 -#define ItVpdIoVpd 5 -#define ItVpdIplParms 6 -#define ItVpdMsVpd 7 -#define ItVpdPanelVpd 8 -#define ItVpdLpNaca 9 -#define ItVpdBackplaneAndMaybeClockCardVpd 10 -#define ItVpdRecoveryLogBuffer 11 -#define ItVpdSpCommArea 12 -#define ItVpdSpLogBuffer 13 -#define ItVpdSpLogBufferSave 14 -#define ItVpdSpCardVpd 15 -#define ItVpdFirstProcVpd 16 -#define ItVpdApModelVpd 17 -#define ItVpdClockCardVpd 18 -#define ItVpdBusExtCardVpd 19 -#define ItVpdProcCapacityVpd 20 -#define ItVpdInteractiveCapacityVpd 21 -#define ItVpdFirstSlotLabel 22 -#define ItVpdFirstLpQueue 23 -#define ItVpdFirstL3CacheVpd 24 -#define ItVpdFirstProcFruVpd 25 - -#define ItVpdMaxEntries 26 +/* VPD Entry index is carved in stone - cannot be changed (easily). */ +#define ItVpdCecVpd 0 +#define ItVpdDynamicSpace 1 +#define ItVpdExtVpd 2 +#define ItVpdExtVpdOnPanel 3 +#define ItVpdFirstPaca 4 +#define ItVpdIoVpd 5 +#define ItVpdIplParms 6 +#define ItVpdMsVpd 7 +#define ItVpdPanelVpd 8 +#define ItVpdLpNaca 9 +#define ItVpdBackplaneAndMaybeClockCardVpd 10 +#define ItVpdRecoveryLogBuffer 11 +#define ItVpdSpCommArea 12 +#define ItVpdSpLogBuffer 13 +#define ItVpdSpLogBufferSave 14 +#define ItVpdSpCardVpd 15 +#define ItVpdFirstProcVpd 16 +#define ItVpdApModelVpd 17 +#define ItVpdClockCardVpd 18 +#define ItVpdBusExtCardVpd 19 +#define ItVpdProcCapacityVpd 20 +#define ItVpdInteractiveCapacityVpd 21 +#define ItVpdFirstSlotLabel 22 +#define ItVpdFirstLpQueue 23 +#define ItVpdFirstL3CacheVpd 24 +#define ItVpdFirstProcFruVpd 25 +#define ItVpdMaxEntries 26 -#define ItDmaMaxEntries 10 +#define ItDmaMaxEntries 10 -#define ItVpdAreasMaxSlotLabels 192 +#define ItVpdAreasMaxSlotLabels 192 struct SlicVpdAdrs { u32 pad1; - void * vpdAddr; + void *vpdAddr; }; -struct ItVpdAreas -{ - u32 xSlicDesc; // Descriptor 000-003 - u16 xSlicSize; // Size of this control block 004-005 - u16 xPlicAdjustVpdLens:1; // Flag to indicate new interface 006-007 - u16 xRsvd1:15; // Reserved bits ... - u16 xSlicVpdEntries; // Number of VPD entries 008-009 - u16 xSlicDmaEntries; // Number of DMA entries 00A-00B - u16 xSlicMaxLogicalProcs; // Maximum logical processors 00C-00D - u16 xSlicMaxPhysicalProcs; // Maximum physical processors 00E-00F - u16 xSlicDmaToksOffset; // Offset into this of array 010-011 - u16 xSlicVpdAdrsOffset; // Offset into this of array 012-013 - u16 xSlicDmaLensOffset; // Offset into this of array 014-015 - u16 xSlicVpdLensOffset; // Offset into this of array 016-017 - u16 xSlicMaxSlotLabels; // Maximum number of slot labels 018-019 - u16 xSlicMaxLpQueues; // Maximum number of LP Queues 01A-01B - u8 xRsvd2[4]; // Reserved 01C-01F - u64 xRsvd3[12]; // Reserved 020-07F - u32 xPlicDmaLens[ItDmaMaxEntries];// Array of DMA lengths 080-0A7 - u32 xPlicDmaToks[ItDmaMaxEntries];// Array of DMA tokens 0A8-0CF - u32 xSlicVpdLens[ItVpdMaxEntries];// Array of VPD lengths 0D0-12F - void * xSlicVpdAdrs[ItVpdMaxEntries];// Array of VPD buffers 130-1EF +struct ItVpdAreas { + u32 xSlicDesc; // Descriptor 000-003 + u16 xSlicSize; // Size of this control block 004-005 + u16 xPlicAdjustVpdLens:1; // Flag to indicate new interface006-007 + u16 xRsvd1:15; // Reserved bits ... + u16 xSlicVpdEntries; // Number of VPD entries 008-009 + u16 xSlicDmaEntries; // Number of DMA entries 00A-00B + u16 xSlicMaxLogicalProcs; // Maximum logical processors 00C-00D + u16 xSlicMaxPhysicalProcs; // Maximum physical processors 00E-00F + u16 xSlicDmaToksOffset; // Offset into this of array 010-011 + u16 xSlicVpdAdrsOffset; // Offset into this of array 012-013 + u16 xSlicDmaLensOffset; // Offset into this of array 014-015 + u16 xSlicVpdLensOffset; // Offset into this of array 016-017 + u16 xSlicMaxSlotLabels; // Maximum number of slot labels018-019 + u16 xSlicMaxLpQueues; // Maximum number of LP Queues 01A-01B + u8 xRsvd2[4]; // Reserved 01C-01F + u64 xRsvd3[12]; // Reserved 020-07F + u32 xPlicDmaLens[ItDmaMaxEntries];// Array of DMA lengths 080-0A7 + u32 xPlicDmaToks[ItDmaMaxEntries];// Array of DMA tokens 0A8-0CF + u32 xSlicVpdLens[ItVpdMaxEntries];// Array of VPD lengths 0D0-12F + void *xSlicVpdAdrs[ItVpdMaxEntries];// Array of VPD buffers 130-1EF }; #endif /* _ITVPDAREAS_H */ diff --git a/include/asm-ppc64/iSeries/LparData.h b/include/asm-ppc64/iSeries/LparData.h index e54f3b686e58..a9fd6e287e6d 100644 --- a/include/asm-ppc64/iSeries/LparData.h +++ b/include/asm-ppc64/iSeries/LparData.h @@ -1,17 +1,17 @@ /* * LparData.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 @@ -34,16 +34,15 @@ #include #include -extern struct LparMap xLparMap; -extern struct HvReleaseData hvReleaseData; -extern struct ItLpNaca itLpNaca; -extern struct ItIplParmsReal xItIplParmsReal; -extern struct ItExtVpdPanel xItExtVpdPanel; -extern struct IoHriProcessorVpd xIoHriProcessorVpd[]; -extern struct ItLpQueue xItLpQueue; -extern struct ItVpdAreas itVpdAreas; -extern u64 xMsVpd[]; -extern struct msChunks msChunks; - +extern struct LparMap xLparMap; +extern struct HvReleaseData hvReleaseData; +extern struct ItLpNaca itLpNaca; +extern struct ItIplParmsReal xItIplParmsReal; +extern struct ItExtVpdPanel xItExtVpdPanel; +extern struct IoHriProcessorVpd xIoHriProcessorVpd[]; +extern struct ItLpQueue xItLpQueue; +extern struct ItVpdAreas itVpdAreas; +extern u64 xMsVpd[]; +extern struct msChunks msChunks; #endif /* _LPARDATA_H */ diff --git a/include/asm-ppc64/iSeries/LparMap.h b/include/asm-ppc64/iSeries/LparMap.h index 075205bb0f4a..1505c4f0f1b4 100644 --- a/include/asm-ppc64/iSeries/LparMap.h +++ b/include/asm-ppc64/iSeries/LparMap.h @@ -1,17 +1,17 @@ /* * LparMap.h * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 @@ -21,13 +21,14 @@ #include -/* The iSeries hypervisor will set up mapping for one or more +/* + * The iSeries hypervisor will set up mapping for one or more * ESID/VSID pairs (in SLB/segment registers) and will set up * mappings of one or more ranges of pages to VAs. * We will have the hypervisor set up the ESID->VSID mapping * for the four kernel segments (C-F). With shared processors, * the hypervisor will clear all segment registers and reload - * these four whenever the processor is switched from one + * these four whenever the processor is switched from one * partition to another. */ @@ -38,30 +39,29 @@ * need to be located within the load area (if the total partition size * is 64 MB), but cannot be mapped. Typically, this should specify * to map half (32 MB) of the load area. - * - * The hypervisor will set up page table entries for the number of + * + * The hypervisor will set up page table entries for the number of * pages specified. * * In 32-bit mode, the hypervisor will load all four of the - * segment registers (identified by the low-order four bits of the + * segment registers (identified by the low-order four bits of the * Esid field. In 64-bit mode, the hypervisor will load one SLB * entry to map the Esid to the Vsid. */ -// Hypervisor initially maps 32MB of the load area -#define HvPagesToMap 8192 +/* Hypervisor initially maps 32MB of the load area */ +#define HvPagesToMap 8192 -struct LparMap -{ - u64 xNumberEsids; // Number of ESID/VSID pairs (1) - u64 xNumberRanges; // Number of VA ranges to map (1) - u64 xSegmentTableOffs; // Page number within load area of seg table (0) - u64 xRsvd[5]; // Reserved (0) - u64 xKernelEsid; // Esid used to map kernel load (0x0C00000000) - u64 xKernelVsid; // Vsid used to map kernel load (0x0C00000000) - u64 xPages; // Number of pages to be mapped (8192) - u64 xOffset; // Offset from start of load area (0) - u64 xVPN; // Virtual Page Number (0x000C000000000000) +struct LparMap { + u64 xNumberEsids; // Number of ESID/VSID pairs (1) + u64 xNumberRanges; // Number of VA ranges to map (1) + u64 xSegmentTableOffs; // Page number within load area of seg table (0) + u64 xRsvd[5]; + u64 xKernelEsid; // Esid used to map kernel load (0x0C00000000) + u64 xKernelVsid; // Vsid used to map kernel load (0x0C00000000) + u64 xPages; // Number of pages to be mapped (8192) + u64 xOffset; // Offset from start of load area (0) + u64 xVPN; // Virtual Page Number (0x000C000000000000) }; #endif /* _LPARMAP_H */ diff --git a/include/asm-ppc64/iSeries/XmPciLpEvent.h b/include/asm-ppc64/iSeries/XmPciLpEvent.h index a3d27f116e49..9c800792bc5c 100644 --- a/include/asm-ppc64/iSeries/XmPciLpEvent.h +++ b/include/asm-ppc64/iSeries/XmPciLpEvent.h @@ -1,8 +1,6 @@ - #ifndef __XMPCILPEVENT_H__ #define __XMPCILPEVENT_H__ - #ifdef __cplusplus extern "C" { #endif @@ -10,7 +8,6 @@ extern "C" { int XmPciLpEvent_init(void); void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq); - #ifdef __cplusplus } #endif diff --git a/include/asm-ppc64/iSeries/iSeries_io.h b/include/asm-ppc64/iSeries/iSeries_io.h index f52b7599b372..9f79413342b3 100644 --- a/include/asm-ppc64/iSeries/iSeries_io.h +++ b/include/asm-ppc64/iSeries/iSeries_io.h @@ -5,32 +5,33 @@ #ifdef CONFIG_PPC_ISERIES #include -/************************************************************************/ -/* File iSeries_io.h created by Allan Trautman on Thu Dec 28 2000. */ -/************************************************************************/ -/* Remaps the io.h for the iSeries Io */ -/* Copyright (C) 20yy Allan H Trautman, IBM Corporation */ -/* */ -/* 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 */ -/************************************************************************/ -/* Change Activity: */ -/* Created December 28, 2000 */ -/* End Change Activity */ -/************************************************************************/ +/* + * File iSeries_io.h created by Allan Trautman on Thu Dec 28 2000. + * + * Remaps the io.h for the iSeries Io + * Copyright (C) 2000 Allan H Trautman, IBM Corporation + * + * 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 + * + * Change Activity: + * Created December 28, 2000 + * End Change Activity + */ + extern u8 iSeries_Read_Byte(const volatile void __iomem * IoAddress); extern u16 iSeries_Read_Word(const volatile void __iomem * IoAddress); extern u32 iSeries_Read_Long(const volatile void __iomem * IoAddress); @@ -39,8 +40,10 @@ extern void iSeries_Write_Word(u16 IoData, volatile void __iomem * IoAddress); extern void iSeries_Write_Long(u32 IoData, volatile void __iomem * IoAddress); extern void iSeries_memset_io(volatile void __iomem *dest, char x, size_t n); -extern void iSeries_memcpy_toio(volatile void __iomem *dest, void *source, size_t n); -extern void iSeries_memcpy_fromio(void *dest, const volatile void __iomem *source, size_t n); +extern void iSeries_memcpy_toio(volatile void __iomem *dest, void *source, + size_t n); +extern void iSeries_memcpy_fromio(void *dest, + const volatile void __iomem *source, size_t n); #endif /* CONFIG_PPC_ISERIES */ #endif /* _ISERIES_IO_H */ diff --git a/include/asm-ppc64/iSeries/iSeries_pci.h b/include/asm-ppc64/iSeries/iSeries_pci.h index 5769cff4c00c..9c6d64526d59 100644 --- a/include/asm-ppc64/iSeries/iSeries_pci.h +++ b/include/asm-ppc64/iSeries/iSeries_pci.h @@ -1,112 +1,113 @@ #ifndef _ISERIES_64_PCI_H #define _ISERIES_64_PCI_H -/************************************************************************/ -/* File iSeries_pci.h created by Allan Trautman on Tue Feb 20, 2001. */ -/************************************************************************/ -/* Define some useful macros for the iSeries pci routines. */ -/* Copyright (C) 2001 Allan H Trautman, IBM Corporation */ -/* */ -/* 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 */ -/************************************************************************/ -/* Change Activity: */ -/* Created Feb 20, 2001 */ -/* Added device reset, March 22, 2001 */ -/* Ported to ppc64, May 25, 2001 */ -/* End Change Activity */ -/************************************************************************/ +/* + * File iSeries_pci.h created by Allan Trautman on Tue Feb 20, 2001. + * + * Define some useful macros for the iSeries pci routines. + * Copyright (C) 2001 Allan H Trautman, IBM Corporation + * + * 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 + * + * Change Activity: + * Created Feb 20, 2001 + * Added device reset, March 22, 2001 + * Ported to ppc64, May 25, 2001 + * End Change Activity + */ #include #include -struct pci_dev; /* For Forward Reference */ +struct pci_dev; /* For Forward Reference */ struct iSeries_Device_Node; -/************************************************************************/ -/* Gets iSeries Bus, SubBus, DevFn using iSeries_Device_Node structure */ -/************************************************************************/ +/* + * Gets iSeries Bus, SubBus, DevFn using iSeries_Device_Node structure + */ #define ISERIES_BUS(DevPtr) DevPtr->DsaAddr.Dsa.busNumber #define ISERIES_SUBBUS(DevPtr) DevPtr->DsaAddr.Dsa.subBusNumber #define ISERIES_DEVICE(DevPtr) DevPtr->DsaAddr.Dsa.deviceId #define ISERIES_DSA(DevPtr) DevPtr->DsaAddr.DsaAddr #define ISERIES_DEVFUN(DevPtr) DevPtr->DevFn -#define ISERIES_DEVNODE(PciDev) ((struct iSeries_Device_Node*)PciDev->sysdata) +#define ISERIES_DEVNODE(PciDev) ((struct iSeries_Device_Node*)PciDev->sysdata) #define EADsMaxAgents 7 -/************************************************************************/ -/* Decodes Linux DevFn to iSeries DevFn, bridge device, or function. */ -/* For Linux, see PCI_SLOT and PCI_FUNC in include/linux/pci.h */ -/************************************************************************/ +/* + * Decodes Linux DevFn to iSeries DevFn, bridge device, or function. + * For Linux, see PCI_SLOT and PCI_FUNC in include/linux/pci.h + */ -#define ISERIES_PCI_AGENTID(idsel,func) ((idsel & 0x0F) << 4) | (func & 0x07) -#define ISERIES_ENCODE_DEVICE(agentid) ((0x10) | ((agentid&0x20)>>2) | (agentid&07)) +#define ISERIES_PCI_AGENTID(idsel, func) \ + ((idsel & 0x0F) << 4) | (func & 0x07) +#define ISERIES_ENCODE_DEVICE(agentid) \ + ((0x10) | ((agentid & 0x20) >> 2) | (agentid & 0x07)) -#define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus) ((subbus >> 5) & 0x7) -#define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus) ((subbus >> 2) & 0x7) +#define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus) ((subbus >> 5) & 0x7) +#define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus) ((subbus >> 2) & 0x7) /* * N.B. the ISERIES_DECODE_* macros are not used anywhere, and I think * the 0x71 (at least) must be wrong - 0x78 maybe? -- paulus. */ -#define ISERIES_DECODE_DEVFN(linuxdevfn) (((linuxdevfn & 0x71) << 1) | (linuxdevfn & 0x07)) -#define ISERIES_DECODE_DEVICE(linuxdevfn) (((linuxdevfn & 0x38) >> 3) |(((linuxdevfn & 0x40) >> 2) + 0x10)) -#define ISERIES_DECODE_FUNCTION(linuxdevfn) (linuxdevfn & 0x07) - -/************************************************************************/ -/* Converts Virtual Address to Real Address for Hypervisor calls */ -/************************************************************************/ +#define ISERIES_DECODE_DEVFN(linuxdevfn) \ + (((linuxdevfn & 0x71) << 1) | (linuxdevfn & 0x07)) +#define ISERIES_DECODE_DEVICE(linuxdevfn) \ + (((linuxdevfn & 0x38) >> 3) | (((linuxdevfn & 0x40) >> 2) + 0x10)) +#define ISERIES_DECODE_FUNCTION(linuxdevfn) \ + (linuxdevfn & 0x07) -#define ISERIES_HV_ADDR(virtaddr) (0x8000000000000000 | virt_to_abs(virtaddr)) - -/************************************************************************/ -/* iSeries Device Information */ -/************************************************************************/ +/* + * Converts Virtual Address to Real Address for Hypervisor calls + */ +#define ISERIES_HV_ADDR(virtaddr) \ + (0x8000000000000000 | virt_to_abs(virtaddr)) +/* + * iSeries Device Information + */ struct iSeries_Device_Node { struct list_head Device_List; - struct pci_dev* PciDev; /* Pointer to pci_dev structure*/ - union HvDsaMap DsaAddr; /* Direct Select Address */ - /* busNumber,subBusNumber, */ - /* deviceId, barNumber */ - HvAgentId AgentId; /* Hypervisor DevFn */ - int DevFn; /* Linux devfn */ - int BarOffset; - int Irq; /* Assigned IRQ */ - int ReturnCode; /* Return Code Holder */ - int IoRetry; /* Current Retry Count */ - int Flags; /* Possible flags(disable/bist)*/ - u16 Vendor; /* Vendor ID */ - u8 LogicalSlot; /* Hv Slot Index for Tces */ - struct iommu_table* iommu_table;/* Device TCE Table */ - u8 PhbId; /* Phb Card is on. */ - u16 Board; /* Board Number */ - u8 FrameId; /* iSeries spcn Frame Id */ - char CardLocation[4];/* Char format of planar vpd */ - char Location[20]; /* Frame 1, Card C10 */ + struct pci_dev *PciDev; + union HvDsaMap DsaAddr; /* Direct Select Address */ + /* busNumber, subBusNumber, */ + /* deviceId, barNumber */ + HvAgentId AgentId; /* Hypervisor DevFn */ + int DevFn; /* Linux devfn */ + int BarOffset; + int Irq; /* Assigned IRQ */ + int ReturnCode; /* Return Code Holder */ + int IoRetry; /* Current Retry Count */ + int Flags; /* Possible flags(disable/bist)*/ + u16 Vendor; /* Vendor ID */ + u8 LogicalSlot; /* Hv Slot Index for Tces */ + struct iommu_table *iommu_table;/* Device TCE Table */ + u8 PhbId; /* Phb Card is on. */ + u16 Board; /* Board Number */ + u8 FrameId; /* iSeries spcn Frame Id */ + char CardLocation[4];/* Char format of planar vpd */ + char Location[20]; /* Frame 1, Card C10 */ }; -/************************************************************************/ -/* Functions */ -/************************************************************************/ - -extern int iSeries_Device_Information(struct pci_dev*,char*, int); -extern void iSeries_Get_Location_Code(struct iSeries_Device_Node*); -extern int iSeries_Device_ToggleReset(struct pci_dev* PciDev, int AssertTime, int DelayTime); +extern int iSeries_Device_Information(struct pci_dev*, char*, int); +extern void iSeries_Get_Location_Code(struct iSeries_Device_Node*); +extern int iSeries_Device_ToggleReset(struct pci_dev* PciDev, + int AssertTime, int DelayTime); #endif /* _ISERIES_64_PCI_H */ diff --git a/include/asm-ppc64/iSeries/mf.h b/include/asm-ppc64/iSeries/mf.h index db333e1ee216..7e6a0d936999 100644 --- a/include/asm-ppc64/iSeries/mf.h +++ b/include/asm-ppc64/iSeries/mf.h @@ -9,17 +9,16 @@ * all partitions in the iSeries. It also provides miscellaneous low-level * machine facility type operations. * - * * 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 diff --git a/include/asm-ppc64/iSeries/vio.h b/include/asm-ppc64/iSeries/vio.h index 3e5766a849d6..614088f61b8f 100644 --- a/include/asm-ppc64/iSeries/vio.h +++ b/include/asm-ppc64/iSeries/vio.h @@ -8,32 +8,32 @@ * Colin Devilbiss * * (C) Copyright 2000 IBM Corporation - * + * * This header file is used by the iSeries virtual I/O device * drivers. It defines the interfaces to the common functions * (implemented in drivers/char/viopath.h) as well as defining - * common functions and structures. Currently (at the time I + * common functions and structures. Currently (at the time I * wrote this comment) the iSeries virtual I/O device drivers - * that use this are - * drivers/block/viodasd.c + * that use this are + * drivers/block/viodasd.c * drivers/char/viocons.c * drivers/char/viotape.c * drivers/cdrom/viocd.c * * The iSeries virtual ethernet support (veth.c) uses a whole * different set of functions. - * + * * 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) anyu later version. * * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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. + * General Public License for more details. * - * You should have received a copy of the GNU General Public License + * 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 * @@ -44,14 +44,16 @@ #include #include -/* iSeries virtual I/O events use the subtype field in +/* + * iSeries virtual I/O events use the subtype field in * HvLpEvent to figure out what kind of vio event is coming * in. We use a table to route these, and this defines * the maximum number of distinct subtypes */ #define VIO_MAX_SUBTYPES 8 -/* Each subtype can register a handler to process their events. +/* + * Each subtype can register a handler to process their events. * The handler must have this interface. */ typedef void (vio_event_handler_t) (struct HvLpEvent * event); @@ -70,13 +72,13 @@ void vio_free_event_buffer(int subtype, void *buffer); extern HvLpIndex viopath_hostLp; extern HvLpIndex viopath_ourLp; -#define VIOCHAR_MAX_DATA 200 +#define VIOCHAR_MAX_DATA 200 -#define VIOMAJOR_SUBTYPE_MASK 0xff00 -#define VIOMINOR_SUBTYPE_MASK 0x00ff -#define VIOMAJOR_SUBTYPE_SHIFT 8 +#define VIOMAJOR_SUBTYPE_MASK 0xff00 +#define VIOMINOR_SUBTYPE_MASK 0x00ff +#define VIOMAJOR_SUBTYPE_SHIFT 8 -#define VIOVERSION 0x0101 +#define VIOVERSION 0x0101 /* * This is the general structure for VIO errors; each module should have @@ -89,8 +91,8 @@ struct vio_error_entry { int errno; const char *msg; }; -const struct vio_error_entry *vio_lookup_rc(const struct vio_error_entry - *local_table, u16 rc); +extern const struct vio_error_entry *vio_lookup_rc( + const struct vio_error_entry *local_table, u16 rc); enum viosubtypes { viomajorsubtype_monitor = 0x0100, @@ -102,7 +104,6 @@ enum viosubtypes { viomajorsubtype_scsi = 0x0700 }; - enum vioconfigsubtype { vioconfigget = 0x0001, }; -- cgit v1.2.3-59-g8ed1b From 6b7feecb2f8fcab184a38916d10349bd6648e0bc Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:35 -0700 Subject: [PATCH] ppc64 iSeries: obvious code simplifications This patch does some obvious code cleanups in the iSeries headers files. - simplifies the bodies of lots of inline functions - parenthesises a macros result - removes C++ wrapping - adds "extern" to some function declarations There are no semantic changes. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-ppc64/iSeries/HvCallCfg.h | 61 ++++--------- include/asm-ppc64/iSeries/HvCallEvent.h | 65 +++----------- include/asm-ppc64/iSeries/HvCallHpt.h | 23 ++--- include/asm-ppc64/iSeries/HvCallPci.h | 146 ++++++------------------------- include/asm-ppc64/iSeries/HvCallSm.h | 5 +- include/asm-ppc64/iSeries/HvCallXm.h | 35 +++----- include/asm-ppc64/iSeries/HvLpConfig.h | 3 +- include/asm-ppc64/iSeries/XmPciLpEvent.h | 12 +-- include/asm-ppc64/iSeries/iSeries_irq.h | 18 ++-- include/asm-ppc64/iSeries/iSeries_pci.h | 2 +- include/asm-ppc64/iSeries/vio.h | 20 ++--- 11 files changed, 92 insertions(+), 298 deletions(-) diff --git a/include/asm-ppc64/iSeries/HvCallCfg.h b/include/asm-ppc64/iSeries/HvCallCfg.h index 2223a9647d0e..aa491c3ad0a2 100644 --- a/include/asm-ppc64/iSeries/HvCallCfg.h +++ b/include/asm-ppc64/iSeries/HvCallCfg.h @@ -69,37 +69,27 @@ enum HvCallCfg_ReqQual { static inline HvLpIndex HvCallCfg_getLps(void) { - HvLpIndex retVal = HvCall0(HvCallCfgGetLps); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall0(HvCallCfgGetLps); } static inline int HvCallCfg_isBusDedicated(u64 busIndex) { - int retVal = HvCall1(HvCallCfgIsBusDedicated,busIndex); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall1(HvCallCfgIsBusDedicated, busIndex); } static inline HvLpIndex HvCallCfg_getBusOwner(u64 busIndex) { - HvLpIndex retVal = HvCall1(HvCallCfgGetBusOwner,busIndex); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall1(HvCallCfgGetBusOwner, busIndex); } static inline HvLpIndexMap HvCallCfg_getBusAllocation(u64 busIndex) { - HvLpIndexMap retVal = HvCall1(HvCallCfgGetBusAllocation,busIndex); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall1(HvCallCfgGetBusAllocation, busIndex); } static inline HvLpIndexMap HvCallCfg_getActiveLpMap(void) { - HvLpIndexMap retVal = HvCall0(HvCallCfgGetActiveLpMap); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall0(HvCallCfgGetActiveLpMap); } static inline HvLpVirtualLanIndexMap HvCallCfg_getVirtualLanIndexMap( @@ -112,23 +102,18 @@ static inline HvLpVirtualLanIndexMap HvCallCfg_getVirtualLanIndexMap( u64 retVal = HvCall1(HvCallCfgGetVirtualLanIndexMap, lp); if (retVal == -1) retVal = 0; - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return retVal; } static inline u64 HvCallCfg_getSystemMsChunks(void) { - u64 retVal = HvCall0(HvCallCfgGetSystemMsChunks); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall0(HvCallCfgGetSystemMsChunks); } static inline u64 HvCallCfg_getMsChunks(HvLpIndex lp, enum HvCallCfg_ReqQual qual) { - u64 retVal = HvCall2(HvCallCfgGetMsChunks,lp,qual); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall2(HvCallCfgGetMsChunks, lp, qual); } static inline u64 HvCallCfg_getMinRuntimeMsChunks(HvLpIndex lp) @@ -142,65 +127,51 @@ static inline u64 HvCallCfg_getMinRuntimeMsChunks(HvLpIndex lp) static inline u64 HvCallCfg_setMinRuntimeMsChunks(u64 chunks) { - u64 retVal = HvCall1(HvCallCfgSetMinRuntimeMsChunks,chunks); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall1(HvCallCfgSetMinRuntimeMsChunks, chunks); } static inline u64 HvCallCfg_getSystemPhysicalProcessors(void) { - u64 retVal = HvCall0(HvCallCfgGetSystemPhysicalProcessors); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall0(HvCallCfgGetSystemPhysicalProcessors); } static inline u64 HvCallCfg_getPhysicalProcessors(HvLpIndex lp, enum HvCallCfg_ReqQual qual) { - u64 retVal = HvCall2(HvCallCfgGetPhysicalProcessors,lp,qual); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall2(HvCallCfgGetPhysicalProcessors, lp, qual); } static inline u64 HvCallCfg_getConfiguredBusUnitsForInterruptProc(HvLpIndex lp, u16 hvLogicalProcIndex) { - u64 retVal = HvCall2(HvCallCfgGetConfiguredBusUnitsForIntProc,lp,hvLogicalProcIndex); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall2(HvCallCfgGetConfiguredBusUnitsForIntProc, lp, + hvLogicalProcIndex); } static inline HvLpSharedPoolIndex HvCallCfg_getSharedPoolIndex(HvLpIndex lp) { - HvLpSharedPoolIndex retVal = - HvCall1(HvCallCfgGetSharedPoolIndex,lp); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall1(HvCallCfgGetSharedPoolIndex, lp); } static inline u64 HvCallCfg_getSharedProcUnits(HvLpIndex lp, enum HvCallCfg_ReqQual qual) { - u64 retVal = HvCall2(HvCallCfgGetSharedProcUnits,lp,qual); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall2(HvCallCfgGetSharedProcUnits, lp, qual); } static inline u64 HvCallCfg_getNumProcsInSharedPool(HvLpSharedPoolIndex sPI) { - u16 retVal = HvCall1(HvCallCfgGetNumProcsInSharedPool,sPI); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + u16 retVal = HvCall1(HvCallCfgGetNumProcsInSharedPool, sPI); return retVal; } static inline HvLpIndex HvCallCfg_getHostingLpIndex(HvLpIndex lp) { - u64 retVal = HvCall1(HvCallCfgGetHostingLpIndex,lp); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + u64 retVal = HvCall1(HvCallCfgGetHostingLpIndex, lp); return retVal; } diff --git a/include/asm-ppc64/iSeries/HvCallEvent.h b/include/asm-ppc64/iSeries/HvCallEvent.h index a5954785512d..5d9a327d0122 100644 --- a/include/asm-ppc64/iSeries/HvCallEvent.h +++ b/include/asm-ppc64/iSeries/HvCallEvent.h @@ -82,13 +82,11 @@ typedef u64 HvLpDma_Rc; static inline void HvCallEvent_getOverflowLpEvents(u8 queueIndex) { HvCall1(HvCallEventGetOverflowLpEvents, queueIndex); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } static inline void HvCallEvent_setInterLpQueueIndex(u8 queueIndex) { HvCall1(HvCallEventSetInterLpQueueIndex, queueIndex); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } static inline void HvCallEvent_setLpEventStack(u8 queueIndex, @@ -99,7 +97,6 @@ static inline void HvCallEvent_setLpEventStack(u8 queueIndex, abs_addr = virt_to_abs(eventStackAddr); HvCall3(HvCallEventSetLpEventStack, queueIndex, abs_addr, eventStackSize); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } static inline void HvCallEvent_setLpEventQueueInterruptProc(u8 queueIndex, @@ -107,22 +104,18 @@ static inline void HvCallEvent_setLpEventQueueInterruptProc(u8 queueIndex, { HvCall2(HvCallEventSetLpEventQueueInterruptProc, queueIndex, lpLogicalProcIndex); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } static inline HvLpEvent_Rc HvCallEvent_signalLpEvent(struct HvLpEvent *event) { u64 abs_addr; - HvLpEvent_Rc retVal; #ifdef DEBUG_SENDEVENT printk("HvCallEvent_signalLpEvent: *event = %016lx\n ", (unsigned long)event); #endif abs_addr = virt_to_abs(event); - retVal = (HvLpEvent_Rc)HvCall1(HvCallEventSignalLpEvent, abs_addr); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall1(HvCallEventSignalLpEvent, abs_addr); } static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp, @@ -132,8 +125,6 @@ static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp, u64 eventData1, u64 eventData2, u64 eventData3, u64 eventData4, u64 eventData5) { - HvLpEvent_Rc retVal; - /* Pack the misc bits into a single Dword to pass to PLIC */ union { struct HvCallEvent_PackedParms parms; @@ -148,67 +139,49 @@ static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp, packed.parms.xSourceInstId = sourceInstanceId; packed.parms.xTargetInstId = targetInstanceId; - retVal = (HvLpEvent_Rc)HvCall7(HvCallEventSignalLpEventParms, - packed.dword, correlationToken, eventData1,eventData2, - eventData3,eventData4, eventData5); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall7(HvCallEventSignalLpEventParms, packed.dword, + correlationToken, eventData1, eventData2, + eventData3, eventData4, eventData5); } static inline HvLpEvent_Rc HvCallEvent_ackLpEvent(struct HvLpEvent *event) { u64 abs_addr; - HvLpEvent_Rc retVal; abs_addr = virt_to_abs(event); - retVal = (HvLpEvent_Rc)HvCall1(HvCallEventAckLpEvent, abs_addr); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall1(HvCallEventAckLpEvent, abs_addr); } static inline HvLpEvent_Rc HvCallEvent_cancelLpEvent(struct HvLpEvent *event) { u64 abs_addr; - HvLpEvent_Rc retVal; abs_addr = virt_to_abs(event); - retVal = (HvLpEvent_Rc)HvCall1(HvCallEventCancelLpEvent, abs_addr); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall1(HvCallEventCancelLpEvent, abs_addr); } static inline HvLpInstanceId HvCallEvent_getSourceLpInstanceId( HvLpIndex targetLp, HvLpEvent_Type type) { - HvLpInstanceId retVal; - - retVal = HvCall2(HvCallEventGetSourceLpInstanceId, targetLp, type); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall2(HvCallEventGetSourceLpInstanceId, targetLp, type); } static inline HvLpInstanceId HvCallEvent_getTargetLpInstanceId( HvLpIndex targetLp, HvLpEvent_Type type) { - HvLpInstanceId retVal; - - retVal = HvCall2(HvCallEventGetTargetLpInstanceId, targetLp, type); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall2(HvCallEventGetTargetLpInstanceId, targetLp, type); } static inline void HvCallEvent_openLpEventPath(HvLpIndex targetLp, HvLpEvent_Type type) { HvCall2(HvCallEventOpenLpEventPath, targetLp, type); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } static inline void HvCallEvent_closeLpEventPath(HvLpIndex targetLp, HvLpEvent_Type type) { HvCall2(HvCallEventCloseLpEventPath, targetLp, type); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } static inline HvLpDma_Rc HvCallEvent_dmaBufList(HvLpEvent_Type type, @@ -220,7 +193,6 @@ static inline HvLpDma_Rc HvCallEvent_dmaBufList(HvLpEvent_Type type, /* Do these need to be converted to absolute addresses? */ u64 localBufList, u64 remoteBufList, u32 transferLength) { - HvLpDma_Rc retVal; /* Pack the misc bits into a single Dword to pass to PLIC */ union { struct HvCallEvent_PackedDmaParms parms; @@ -237,11 +209,8 @@ static inline HvLpDma_Rc HvCallEvent_dmaBufList(HvLpEvent_Type type, packed.parms.xLocalInstId = localInstanceId; packed.parms.xRemoteInstId = remoteInstanceId; - retVal = (HvLpDma_Rc)HvCall4(HvCallEventDmaBufList, - packed.dword, localBufList, remoteBufList, - transferLength); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall4(HvCallEventDmaBufList, packed.dword, localBufList, + remoteBufList, transferLength); } static inline HvLpDma_Rc HvCallEvent_dmaSingle(HvLpEvent_Type type, @@ -252,7 +221,6 @@ static inline HvLpDma_Rc HvCallEvent_dmaSingle(HvLpEvent_Type type, HvLpDma_AddressType remoteAddressType, u64 localAddrOrTce, u64 remoteAddrOrTce, u32 transferLength) { - HvLpDma_Rc retVal; /* Pack the misc bits into a single Dword to pass to PLIC */ union { struct HvCallEvent_PackedDmaParms parms; @@ -269,24 +237,17 @@ static inline HvLpDma_Rc HvCallEvent_dmaSingle(HvLpEvent_Type type, packed.parms.xLocalInstId = localInstanceId; packed.parms.xRemoteInstId = remoteInstanceId; - retVal = (HvLpDma_Rc)HvCall4(HvCallEventDmaSingle, - packed.dword, localAddrOrTce, remoteAddrOrTce, - transferLength); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return (HvLpDma_Rc)HvCall4(HvCallEventDmaSingle, packed.dword, + localAddrOrTce, remoteAddrOrTce, transferLength); } static inline HvLpDma_Rc HvCallEvent_dmaToSp(void *local, u32 remote, u32 length, HvLpDma_Direction dir) { u64 abs_addr; - HvLpDma_Rc retVal; abs_addr = virt_to_abs(local); - retVal = (HvLpDma_Rc)HvCall4(HvCallEventDmaToSp, abs_addr, remote, - length, dir); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall4(HvCallEventDmaToSp, abs_addr, remote, length, dir); } #endif /* _HVCALLEVENT_H */ diff --git a/include/asm-ppc64/iSeries/HvCallHpt.h b/include/asm-ppc64/iSeries/HvCallHpt.h index 827d26c60fc1..66f38222ff75 100644 --- a/include/asm-ppc64/iSeries/HvCallHpt.h +++ b/include/asm-ppc64/iSeries/HvCallHpt.h @@ -43,34 +43,27 @@ static inline u64 HvCallHpt_getHptAddress(void) { - u64 retval = HvCall0(HvCallHptGetHptAddress); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retval; + return HvCall0(HvCallHptGetHptAddress); } static inline u64 HvCallHpt_getHptPages(void) { - u64 retval = HvCall0(HvCallHptGetHptPages); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retval; + return HvCall0(HvCallHptGetHptPages); } static inline void HvCallHpt_setPp(u32 hpteIndex, u8 value) { HvCall2(HvCallHptSetPp, hpteIndex, value); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } static inline void HvCallHpt_setSwBits(u32 hpteIndex, u8 bitson, u8 bitsoff) { HvCall3(HvCallHptSetSwBits, hpteIndex, bitson, bitsoff); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } static inline void HvCallHpt_invalidateNoSyncICache(u32 hpteIndex) { HvCall1(HvCallHptInvalidateNoSyncICache, hpteIndex); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } static inline u64 HvCallHpt_invalidateSetSwBitsGet(u32 hpteIndex, u8 bitson, @@ -81,36 +74,30 @@ static inline u64 HvCallHpt_invalidateSetSwBitsGet(u32 hpteIndex, u8 bitson, compressedStatus = HvCall4(HvCallHptInvalidateSetSwBitsGet, hpteIndex, bitson, bitsoff, 1); HvCall1(HvCallHptInvalidateNoSyncICache, hpteIndex); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); return compressedStatus; } static inline u64 HvCallHpt_findValid(HPTE *hpte, u64 vpn) { - u64 retIndex = HvCall3Ret16( HvCallHptFindValid, hpte, vpn, 0, 0 ); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retIndex; + return HvCall3Ret16(HvCallHptFindValid, hpte, vpn, 0, 0); } static inline u64 HvCallHpt_findNextValid(HPTE *hpte, u32 hpteIndex, u8 bitson, u8 bitsoff) { - u64 retIndex = HvCall3Ret16( HvCallHptFindNextValid, hpte, hpteIndex, bitson, bitsoff ); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retIndex; + return HvCall3Ret16(HvCallHptFindNextValid, hpte, hpteIndex, + bitson, bitsoff); } static inline void HvCallHpt_get(HPTE *hpte, u32 hpteIndex) { HvCall2Ret16(HvCallHptGet, hpte, hpteIndex, 0); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } static inline void HvCallHpt_addValidate(u32 hpteIndex, u32 hBit, HPTE *hpte) { HvCall4(HvCallHptAddValidate, hpteIndex, hBit, (*((u64 *)hpte)), (*(((u64 *)hpte)+1))); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } #endif /* _HVCALLHPT_H */ diff --git a/include/asm-ppc64/iSeries/HvCallPci.h b/include/asm-ppc64/iSeries/HvCallPci.h index 346ab5d39dcd..c8d675c40f5e 100644 --- a/include/asm-ppc64/iSeries/HvCallPci.h +++ b/include/asm-ppc64/iSeries/HvCallPci.h @@ -140,8 +140,6 @@ static inline u64 HvCallPci_configLoad8(u16 busNumber, u8 subBusNumber, HvCall3Ret16(HvCallPciConfigLoad8, &retVal, *(u64 *)&dsa, offset, 0); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - *value = retVal.value; return retVal.rc; @@ -161,8 +159,6 @@ static inline u64 HvCallPci_configLoad16(u16 busNumber, u8 subBusNumber, HvCall3Ret16(HvCallPciConfigLoad16, &retVal, *(u64 *)&dsa, offset, 0); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - *value = retVal.value; return retVal.rc; @@ -182,8 +178,6 @@ static inline u64 HvCallPci_configLoad32(u16 busNumber, u8 subBusNumber, HvCall3Ret16(HvCallPciConfigLoad32, &retVal, *(u64 *)&dsa, offset, 0); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - *value = retVal.value; return retVal.rc; @@ -193,7 +187,6 @@ static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber, u8 deviceId, u32 offset, u8 value) { struct HvCallPci_DsaAddr dsa; - u64 retVal; *((u64*)&dsa) = 0; @@ -201,18 +194,13 @@ static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber, dsa.subBusNumber = subBusNumber; dsa.deviceId = deviceId; - retVal = HvCall4(HvCallPciConfigStore8, *(u64 *)&dsa, offset, value, 0); - - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - - return retVal; + return HvCall4(HvCallPciConfigStore8, *(u64 *)&dsa, offset, value, 0); } static inline u64 HvCallPci_configStore16(u16 busNumber, u8 subBusNumber, u8 deviceId, u32 offset, u16 value) { struct HvCallPci_DsaAddr dsa; - u64 retVal; *((u64*)&dsa) = 0; @@ -220,18 +208,13 @@ static inline u64 HvCallPci_configStore16(u16 busNumber, u8 subBusNumber, dsa.subBusNumber = subBusNumber; dsa.deviceId = deviceId; - retVal = HvCall4(HvCallPciConfigStore16, *(u64 *)&dsa, offset, value, 0); - - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - - return retVal; + return HvCall4(HvCallPciConfigStore16, *(u64 *)&dsa, offset, value, 0); } static inline u64 HvCallPci_configStore32(u16 busNumber, u8 subBusNumber, u8 deviceId, u32 offset, u32 value) { struct HvCallPci_DsaAddr dsa; - u64 retVal; *((u64*)&dsa) = 0; @@ -239,11 +222,7 @@ static inline u64 HvCallPci_configStore32(u16 busNumber, u8 subBusNumber, dsa.subBusNumber = subBusNumber; dsa.deviceId = deviceId; - retVal = HvCall4(HvCallPciConfigStore32, *(u64 *)&dsa, offset, value, 0); - - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - - return retVal; + return HvCall4(HvCallPciConfigStore32, *(u64 *)&dsa, offset, value, 0); } static inline u64 HvCallPci_barLoad8(u16 busNumberParm, u8 subBusParm, @@ -262,8 +241,6 @@ static inline u64 HvCallPci_barLoad8(u16 busNumberParm, u8 subBusParm, HvCall3Ret16(HvCallPciBarLoad8, &retVal, *(u64 *)&dsa, offsetParm, 0); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - *valueParm = retVal.value; return retVal.rc; @@ -285,8 +262,6 @@ static inline u64 HvCallPci_barLoad16(u16 busNumberParm, u8 subBusParm, HvCall3Ret16(HvCallPciBarLoad16, &retVal, *(u64 *)&dsa, offsetParm, 0); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - *valueParm = retVal.value; return retVal.rc; @@ -308,8 +283,6 @@ static inline u64 HvCallPci_barLoad32(u16 busNumberParm, u8 subBusParm, HvCall3Ret16(HvCallPciBarLoad32, &retVal, *(u64 *)&dsa, offsetParm, 0); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - *valueParm = retVal.value; return retVal.rc; @@ -331,8 +304,6 @@ static inline u64 HvCallPci_barLoad64(u16 busNumberParm, u8 subBusParm, HvCall3Ret16(HvCallPciBarLoad64, &retVal, *(u64 *)&dsa, offsetParm, 0); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - *valueParm = retVal.value; return retVal.rc; @@ -343,7 +314,6 @@ static inline u64 HvCallPci_barStore8(u16 busNumberParm, u8 subBusParm, u8 valueParm) { struct HvCallPci_DsaAddr dsa; - u64 retVal; *((u64*)&dsa) = 0; @@ -352,11 +322,8 @@ static inline u64 HvCallPci_barStore8(u16 busNumberParm, u8 subBusParm, dsa.deviceId = deviceIdParm; dsa.barNumber = barNumberParm; - retVal = HvCall4(HvCallPciBarStore8, *(u64 *)&dsa, offsetParm, valueParm, 0); - - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - - return retVal; + return HvCall4(HvCallPciBarStore8, *(u64 *)&dsa, offsetParm, + valueParm, 0); } static inline u64 HvCallPci_barStore16(u16 busNumberParm, u8 subBusParm, @@ -364,7 +331,6 @@ static inline u64 HvCallPci_barStore16(u16 busNumberParm, u8 subBusParm, u16 valueParm) { struct HvCallPci_DsaAddr dsa; - u64 retVal; *((u64*)&dsa) = 0; @@ -373,11 +339,8 @@ static inline u64 HvCallPci_barStore16(u16 busNumberParm, u8 subBusParm, dsa.deviceId = deviceIdParm; dsa.barNumber = barNumberParm; - retVal = HvCall4(HvCallPciBarStore16, *(u64 *)&dsa, offsetParm, valueParm, 0); - - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - - return retVal; + return HvCall4(HvCallPciBarStore16, *(u64 *)&dsa, offsetParm, + valueParm, 0); } static inline u64 HvCallPci_barStore32(u16 busNumberParm, u8 subBusParm, @@ -385,7 +348,6 @@ static inline u64 HvCallPci_barStore32(u16 busNumberParm, u8 subBusParm, u32 valueParm) { struct HvCallPci_DsaAddr dsa; - u64 retVal; *((u64*)&dsa) = 0; @@ -394,11 +356,8 @@ static inline u64 HvCallPci_barStore32(u16 busNumberParm, u8 subBusParm, dsa.deviceId = deviceIdParm; dsa.barNumber = barNumberParm; - retVal = HvCall4(HvCallPciBarStore32, *(u64 *)&dsa, offsetParm, valueParm, 0); - - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - - return retVal; + return HvCall4(HvCallPciBarStore32, *(u64 *)&dsa, offsetParm, + valueParm, 0); } static inline u64 HvCallPci_barStore64(u16 busNumberParm, u8 subBusParm, @@ -406,7 +365,6 @@ static inline u64 HvCallPci_barStore64(u16 busNumberParm, u8 subBusParm, u64 valueParm) { struct HvCallPci_DsaAddr dsa; - u64 retVal; *((u64*)&dsa) = 0; @@ -415,11 +373,8 @@ static inline u64 HvCallPci_barStore64(u16 busNumberParm, u8 subBusParm, dsa.deviceId = deviceIdParm; dsa.barNumber = barNumberParm; - retVal = HvCall4(HvCallPciBarStore64, *(u64 *)&dsa, offsetParm, valueParm, 0); - - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - - return retVal; + return HvCall4(HvCallPciBarStore64, *(u64 *)&dsa, offsetParm, + valueParm, 0); } static inline u64 HvCallPci_eoi(u16 busNumberParm, u8 subBusParm, @@ -436,8 +391,6 @@ static inline u64 HvCallPci_eoi(u16 busNumberParm, u8 subBusParm, HvCall1Ret16(HvCallPciEoi, &retVal, *(u64*)&dsa); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal.rc; } @@ -445,7 +398,6 @@ static inline u64 HvCallPci_getBarParms(u16 busNumberParm, u8 subBusParm, u8 deviceIdParm, u8 barNumberParm, u64 parms, u32 sizeofParms) { struct HvCallPci_DsaAddr dsa; - u64 retVal; *((u64*)&dsa) = 0; @@ -454,18 +406,13 @@ static inline u64 HvCallPci_getBarParms(u16 busNumberParm, u8 subBusParm, dsa.deviceId = deviceIdParm; dsa.barNumber = barNumberParm; - retVal = HvCall3(HvCallPciGetBarParms, *(u64*)&dsa, parms, sizeofParms); - - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - - return retVal; + return HvCall3(HvCallPciGetBarParms, *(u64*)&dsa, parms, sizeofParms); } static inline u64 HvCallPci_maskFisr(u16 busNumberParm, u8 subBusParm, u8 deviceIdParm, u64 fisrMask) { struct HvCallPci_DsaAddr dsa; - u64 retVal; *((u64*)&dsa) = 0; @@ -473,18 +420,13 @@ static inline u64 HvCallPci_maskFisr(u16 busNumberParm, u8 subBusParm, dsa.subBusNumber = subBusParm; dsa.deviceId = deviceIdParm; - retVal = HvCall2(HvCallPciMaskFisr, *(u64*)&dsa, fisrMask); - - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - - return retVal; + return HvCall2(HvCallPciMaskFisr, *(u64*)&dsa, fisrMask); } static inline u64 HvCallPci_unmaskFisr(u16 busNumberParm, u8 subBusParm, u8 deviceIdParm, u64 fisrMask) { struct HvCallPci_DsaAddr dsa; - u64 retVal; *((u64*)&dsa) = 0; @@ -492,18 +434,13 @@ static inline u64 HvCallPci_unmaskFisr(u16 busNumberParm, u8 subBusParm, dsa.subBusNumber = subBusParm; dsa.deviceId = deviceIdParm; - retVal = HvCall2(HvCallPciUnmaskFisr, *(u64*)&dsa, fisrMask); - - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - - return retVal; + return HvCall2(HvCallPciUnmaskFisr, *(u64*)&dsa, fisrMask); } static inline u64 HvCallPci_setSlotReset(u16 busNumberParm, u8 subBusParm, u8 deviceIdParm, u64 onNotOff) { struct HvCallPci_DsaAddr dsa; - u64 retVal; *((u64*)&dsa) = 0; @@ -511,18 +448,13 @@ static inline u64 HvCallPci_setSlotReset(u16 busNumberParm, u8 subBusParm, dsa.subBusNumber = subBusParm; dsa.deviceId = deviceIdParm; - retVal = HvCall2(HvCallPciSetSlotReset, *(u64*)&dsa, onNotOff); - - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - - return retVal; + return HvCall2(HvCallPciSetSlotReset, *(u64*)&dsa, onNotOff); } static inline u64 HvCallPci_getDeviceInfo(u16 busNumberParm, u8 subBusParm, u8 deviceNumberParm, u64 parms, u32 sizeofParms) { struct HvCallPci_DsaAddr dsa; - u64 retVal; *((u64*)&dsa) = 0; @@ -530,18 +462,13 @@ static inline u64 HvCallPci_getDeviceInfo(u16 busNumberParm, u8 subBusParm, dsa.subBusNumber = subBusParm; dsa.deviceId = deviceNumberParm << 4; - retVal = HvCall3(HvCallPciGetDeviceInfo, *(u64*)&dsa, parms, sizeofParms); - - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - - return retVal; + return HvCall3(HvCallPciGetDeviceInfo, *(u64*)&dsa, parms, sizeofParms); } static inline u64 HvCallPci_maskInterrupts(u16 busNumberParm, u8 subBusParm, u8 deviceIdParm, u64 interruptMask) { struct HvCallPci_DsaAddr dsa; - u64 retVal; *((u64*)&dsa) = 0; @@ -549,18 +476,13 @@ static inline u64 HvCallPci_maskInterrupts(u16 busNumberParm, u8 subBusParm, dsa.subBusNumber = subBusParm; dsa.deviceId = deviceIdParm; - retVal = HvCall2(HvCallPciMaskInterrupts, *(u64*)&dsa, interruptMask); - - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - - return retVal; + return HvCall2(HvCallPciMaskInterrupts, *(u64*)&dsa, interruptMask); } static inline u64 HvCallPci_unmaskInterrupts(u16 busNumberParm, u8 subBusParm, u8 deviceIdParm, u64 interruptMask) { struct HvCallPci_DsaAddr dsa; - u64 retVal; *((u64*)&dsa) = 0; @@ -568,18 +490,13 @@ static inline u64 HvCallPci_unmaskInterrupts(u16 busNumberParm, u8 subBusParm, dsa.subBusNumber = subBusParm; dsa.deviceId = deviceIdParm; - retVal = HvCall2(HvCallPciUnmaskInterrupts, *(u64*)&dsa, interruptMask); - - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - - return retVal; + return HvCall2(HvCallPciUnmaskInterrupts, *(u64*)&dsa, interruptMask); } static inline u64 HvCallPci_getBusUnitInfo(u16 busNumberParm, u8 subBusParm, u8 deviceIdParm, u64 parms, u32 sizeofParms) { struct HvCallPci_DsaAddr dsa; - u64 retVal; *((u64*)&dsa) = 0; @@ -587,37 +504,30 @@ static inline u64 HvCallPci_getBusUnitInfo(u16 busNumberParm, u8 subBusParm, dsa.subBusNumber = subBusParm; dsa.deviceId = deviceIdParm; - retVal = HvCall3(HvCallPciGetBusUnitInfo, *(u64*)&dsa, parms, sizeofParms); - - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - - return retVal; + return HvCall3(HvCallPciGetBusUnitInfo, *(u64*)&dsa, parms, + sizeofParms); } static inline int HvCallPci_getBusVpd(u16 busNumParm, u64 destParm, u16 sizeParm) { - int xRetSize; - u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm, sizeParm, HvCallPci_BusVpd); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm, + sizeParm, HvCallPci_BusVpd); if (xRc == -1) - xRetSize = -1; + return -1; else - xRetSize = xRc & 0xFFFF; - return xRetSize; + return xRc & 0xFFFF; } static inline int HvCallPci_getBusAdapterVpd(u16 busNumParm, u64 destParm, u16 sizeParm) { - int xRetSize; - u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm, sizeParm, HvCallPci_BusAdapterVpd); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm, + sizeParm, HvCallPci_BusAdapterVpd); if (xRc == -1) - xRetSize = -1; + return -1; else - xRetSize = xRc & 0xFFFF; - return xRetSize; + return xRc & 0xFFFF; } #endif /* _HVCALLPCI_H */ diff --git a/include/asm-ppc64/iSeries/HvCallSm.h b/include/asm-ppc64/iSeries/HvCallSm.h index ef6b303e4d28..8a3dbb071a43 100644 --- a/include/asm-ppc64/iSeries/HvCallSm.h +++ b/include/asm-ppc64/iSeries/HvCallSm.h @@ -32,10 +32,7 @@ static inline u64 HvCallSm_get64BitsOfAccessMap(HvLpIndex lpIndex, u64 indexIntoBitMap) { - u64 retval = HvCall2(HvCallSmGet64BitsOfAccessMap, lpIndex, - indexIntoBitMap ); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retval; + return HvCall2(HvCallSmGet64BitsOfAccessMap, lpIndex, indexIntoBitMap); } #endif /* _HVCALLSM_H */ diff --git a/include/asm-ppc64/iSeries/HvCallXm.h b/include/asm-ppc64/iSeries/HvCallXm.h index a99f29b93611..1362a425913f 100644 --- a/include/asm-ppc64/iSeries/HvCallXm.h +++ b/include/asm-ppc64/iSeries/HvCallXm.h @@ -19,58 +19,43 @@ static inline void HvCallXm_getTceTableParms(u64 cb) { HvCall1(HvCallXmGetTceTableParms, cb); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); } static inline u64 HvCallXm_setTce(u64 tceTableToken, u64 tceOffset, u64 tce) { - u64 retval = HvCall3(HvCallXmSetTce, tceTableToken, tceOffset, tce ); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retval; + return HvCall3(HvCallXmSetTce, tceTableToken, tceOffset, tce); } static inline u64 HvCallXm_setTces(u64 tceTableToken, u64 tceOffset, u64 numTces, u64 tce1, u64 tce2, u64 tce3, u64 tce4) { - u64 retval = HvCall7(HvCallXmSetTces, tceTableToken, tceOffset, numTces, - tce1, tce2, tce3, tce4 ); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retval; + return HvCall7(HvCallXmSetTces, tceTableToken, tceOffset, numTces, + tce1, tce2, tce3, tce4); } static inline u64 HvCallXm_testBus(u16 busNumber) { - u64 retVal = HvCall1(HvCallXmTestBus, busNumber); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall1(HvCallXmTestBus, busNumber); } static inline u64 HvCallXm_testBusUnit(u16 busNumber, u8 subBusNumber, u8 deviceId) { - u64 busUnitNumber = (subBusNumber << 8) | deviceId; - u64 retVal = HvCall2(HvCallXmTestBusUnit, busNumber, busUnitNumber); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall2(HvCallXmTestBusUnit, busNumber, + (subBusNumber << 8) | deviceId); } static inline u64 HvCallXm_connectBusUnit(u16 busNumber, u8 subBusNumber, u8 deviceId, u64 interruptToken) { - u64 busUnitNumber = (subBusNumber << 8) | deviceId; - u64 queueIndex = 0; // HvLpConfig::mapDsaToQueueIndex(HvLpDSA(busNumber, xBoard, xCard)); - - u64 retVal = HvCall5(HvCallXmConnectBusUnit, busNumber, busUnitNumber, - interruptToken, 0, queueIndex); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall5(HvCallXmConnectBusUnit, busNumber, + (subBusNumber << 8) | deviceId, interruptToken, 0, + 0 /* HvLpConfig::mapDsaToQueueIndex(HvLpDSA(busNumber, xBoard, xCard)) */); } static inline u64 HvCallXm_loadTod(void) { - u64 retVal = HvCall0(HvCallXmLoadTod); - // getPaca()->adjustHmtForNoOfSpinLocksHeld(); - return retVal; + return HvCall0(HvCallXmLoadTod); } #endif /* _HVCALLXM_H */ diff --git a/include/asm-ppc64/iSeries/HvLpConfig.h b/include/asm-ppc64/iSeries/HvLpConfig.h index 47311cc952d9..817698052ea8 100644 --- a/include/asm-ppc64/iSeries/HvLpConfig.h +++ b/include/asm-ppc64/iSeries/HvLpConfig.h @@ -281,8 +281,7 @@ static inline u64 HvLpConfig_getLoadPages(void) static inline int HvLpConfig_isBusOwnedByThisLp(HvBusNumber busNumber) { - HvLpIndex busOwner = HvLpConfig_getBusOwner(busNumber); - return (busOwner == HvLpConfig_getLpIndex()); + return (HvLpConfig_getBusOwner(busNumber) == HvLpConfig_getLpIndex()); } static inline int HvLpConfig_doLpsCommunicateOnVirtualLan(HvLpIndex lp1, diff --git a/include/asm-ppc64/iSeries/XmPciLpEvent.h b/include/asm-ppc64/iSeries/XmPciLpEvent.h index 9c800792bc5c..4936627b26d0 100644 --- a/include/asm-ppc64/iSeries/XmPciLpEvent.h +++ b/include/asm-ppc64/iSeries/XmPciLpEvent.h @@ -1,15 +1,7 @@ #ifndef __XMPCILPEVENT_H__ #define __XMPCILPEVENT_H__ -#ifdef __cplusplus -extern "C" { -#endif - -int XmPciLpEvent_init(void); -void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq); - -#ifdef __cplusplus -} -#endif +extern int XmPciLpEvent_init(void); +extern void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq); #endif /* __XMPCILPEVENT_H__ */ diff --git a/include/asm-ppc64/iSeries/iSeries_irq.h b/include/asm-ppc64/iSeries/iSeries_irq.h index ff8ddede038c..fbd5f523ba1d 100644 --- a/include/asm-ppc64/iSeries/iSeries_irq.h +++ b/include/asm-ppc64/iSeries/iSeries_irq.h @@ -1,19 +1,11 @@ #ifndef __ISERIES_IRQ_H__ #define __ISERIES_IRQ_H__ -#ifdef __cplusplus -extern "C" { -#endif +extern void iSeries_init_IRQ(void); +extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId); +extern int iSeries_assign_IRQ(int, HvBusNumber, HvSubBusNumber, HvAgentId); +extern void iSeries_activate_IRQs(void); -void iSeries_init_IRQ(void); -int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId); -int iSeries_assign_IRQ(int, HvBusNumber, HvSubBusNumber, HvAgentId); -void iSeries_activate_IRQs(void); - -int XmPciLpEvent_init(void); - -#ifdef __cplusplus -} -#endif +extern int XmPciLpEvent_init(void); #endif /* __ISERIES_IRQ_H__ */ diff --git a/include/asm-ppc64/iSeries/iSeries_pci.h b/include/asm-ppc64/iSeries/iSeries_pci.h index 9c6d64526d59..f45cd8a2e7be 100644 --- a/include/asm-ppc64/iSeries/iSeries_pci.h +++ b/include/asm-ppc64/iSeries/iSeries_pci.h @@ -55,7 +55,7 @@ struct iSeries_Device_Node; */ #define ISERIES_PCI_AGENTID(idsel, func) \ - ((idsel & 0x0F) << 4) | (func & 0x07) + (((idsel & 0x0F) << 4) | (func & 0x07)) #define ISERIES_ENCODE_DEVICE(agentid) \ ((0x10) | ((agentid & 0x20) >> 2) | (agentid & 0x07)) diff --git a/include/asm-ppc64/iSeries/vio.h b/include/asm-ppc64/iSeries/vio.h index 614088f61b8f..6c05e6257f53 100644 --- a/include/asm-ppc64/iSeries/vio.h +++ b/include/asm-ppc64/iSeries/vio.h @@ -58,16 +58,16 @@ */ typedef void (vio_event_handler_t) (struct HvLpEvent * event); -int viopath_open(HvLpIndex remoteLp, int subtype, int numReq); -int viopath_close(HvLpIndex remoteLp, int subtype, int numReq); -int vio_setHandler(int subtype, vio_event_handler_t * beh); -int vio_clearHandler(int subtype); -int viopath_isactive(HvLpIndex lp); -HvLpInstanceId viopath_sourceinst(HvLpIndex lp); -HvLpInstanceId viopath_targetinst(HvLpIndex lp); -void vio_set_hostlp(void); -void *vio_get_event_buffer(int subtype); -void vio_free_event_buffer(int subtype, void *buffer); +extern int viopath_open(HvLpIndex remoteLp, int subtype, int numReq); +extern int viopath_close(HvLpIndex remoteLp, int subtype, int numReq); +extern int vio_setHandler(int subtype, vio_event_handler_t * beh); +extern int vio_clearHandler(int subtype); +extern int viopath_isactive(HvLpIndex lp); +extern HvLpInstanceId viopath_sourceinst(HvLpIndex lp); +extern HvLpInstanceId viopath_targetinst(HvLpIndex lp); +extern void vio_set_hostlp(void); +extern void *vio_get_event_buffer(int subtype); +extern void vio_free_event_buffer(int subtype, void *buffer); extern HvLpIndex viopath_hostLp; extern HvLpIndex viopath_ourLp; -- cgit v1.2.3-59-g8ed1b From 0bc0ffd5f0854b9143606684fb925f4290ae13e7 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:36 -0700 Subject: [PATCH] ppc64 iSeries: remove LparData.h include/asm-ppc64/iSeries/LparData.h just included a whole lot of other files to declare variables that would be better declared in those other files. So, remove it. This will reduce that number of things needed to be included in most cases to access the relevant variables. Signed-off-by: Stephen Rothwell Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/HvLpEvent.c | 2 +- arch/ppc64/kernel/ItLpQueue.c | 1 - arch/ppc64/kernel/iSeries_VpdInfo.c | 1 - arch/ppc64/kernel/iSeries_pci.c | 1 - arch/ppc64/kernel/iSeries_proc.c | 2 +- arch/ppc64/kernel/iSeries_setup.c | 5 ++- arch/ppc64/kernel/iSeries_smp.c | 1 - arch/ppc64/kernel/irq.c | 2 +- arch/ppc64/kernel/lparcfg.c | 2 +- arch/ppc64/kernel/ras.c | 1 - arch/ppc64/kernel/rtc.c | 1 - arch/ppc64/kernel/setup.c | 3 +- arch/ppc64/kernel/viopath.c | 2 +- include/asm-ppc64/iSeries/HvLpConfig.h | 1 - include/asm-ppc64/iSeries/HvReleaseData.h | 2 ++ include/asm-ppc64/iSeries/IoHriMainStore.h | 2 ++ include/asm-ppc64/iSeries/IoHriProcessorVpd.h | 2 ++ include/asm-ppc64/iSeries/ItExtVpdPanel.h | 2 ++ include/asm-ppc64/iSeries/ItIplParmsReal.h | 2 ++ include/asm-ppc64/iSeries/ItLpNaca.h | 4 +++ include/asm-ppc64/iSeries/ItVpdAreas.h | 2 ++ include/asm-ppc64/iSeries/LparData.h | 48 --------------------------- include/asm-ppc64/iSeries/LparMap.h | 2 ++ 23 files changed, 29 insertions(+), 62 deletions(-) delete mode 100644 include/asm-ppc64/iSeries/LparData.h diff --git a/arch/ppc64/kernel/HvLpEvent.c b/arch/ppc64/kernel/HvLpEvent.c index f8f19637f73f..90032b138902 100644 --- a/arch/ppc64/kernel/HvLpEvent.c +++ b/arch/ppc64/kernel/HvLpEvent.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include /* Array of LpEvent handler functions */ LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index c923a815760e..cdea00d7707f 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -16,7 +16,6 @@ #include #include #include -#include static __inline__ int set_inUse( struct ItLpQueue * lpQueue ) { diff --git a/arch/ppc64/kernel/iSeries_VpdInfo.c b/arch/ppc64/kernel/iSeries_VpdInfo.c index a6f0ff2d0239..a82caf98d2e3 100644 --- a/arch/ppc64/kernel/iSeries_VpdInfo.c +++ b/arch/ppc64/kernel/iSeries_VpdInfo.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include "pci.h" diff --git a/arch/ppc64/kernel/iSeries_pci.c b/arch/ppc64/kernel/iSeries_pci.c index bd4c2554f1a0..9829cd4666d8 100644 --- a/arch/ppc64/kernel/iSeries_pci.c +++ b/arch/ppc64/kernel/iSeries_pci.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc64/kernel/iSeries_proc.c b/arch/ppc64/kernel/iSeries_proc.c index bf85a1f7e870..356bd9931fcc 100644 --- a/arch/ppc64/kernel/iSeries_proc.c +++ b/arch/ppc64/kernel/iSeries_proc.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include static int __init iseries_proc_create(void) { diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index e80cfc570929..3d3ed631499a 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -47,7 +47,7 @@ #include #include #include -#include +#include #include #include #include @@ -58,6 +58,9 @@ #include #include #include +#include +#include +#include extern void hvlog(char *fmt, ...); diff --git a/arch/ppc64/kernel/iSeries_smp.c b/arch/ppc64/kernel/iSeries_smp.c index ba1f084d5462..ff2281b457ed 100644 --- a/arch/ppc64/kernel/iSeries_smp.c +++ b/arch/ppc64/kernel/iSeries_smp.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index 4fd7f203c1e3..d860467b8f09 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c @@ -52,7 +52,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/ppc64/kernel/lparcfg.c b/arch/ppc64/kernel/lparcfg.c index a8fd32df848b..387923fcf9b0 100644 --- a/arch/ppc64/kernel/lparcfg.c +++ b/arch/ppc64/kernel/lparcfg.c @@ -28,12 +28,12 @@ #include #include #include -#include #include #include #include #include #include +#include #define MODULE_VERS "1.6" #define MODULE_NAME "lparcfg" diff --git a/arch/ppc64/kernel/ras.c b/arch/ppc64/kernel/ras.c index 1c4c796b212b..3c00f7bfc1b5 100644 --- a/arch/ppc64/kernel/ras.c +++ b/arch/ppc64/kernel/ras.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c index 67989055a9fe..4cdafb4007b1 100644 --- a/arch/ppc64/kernel/rtc.c +++ b/arch/ppc64/kernel/rtc.c @@ -42,7 +42,6 @@ #include #include -#include #include #include #include diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index dce198d39328..8e439a817642 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -57,6 +56,8 @@ #include #include #include +#include +#include #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) diff --git a/arch/ppc64/kernel/viopath.c b/arch/ppc64/kernel/viopath.c index 8caa078a658a..4e5c36e81f48 100644 --- a/arch/ppc64/kernel/viopath.c +++ b/arch/ppc64/kernel/viopath.c @@ -43,7 +43,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/asm-ppc64/iSeries/HvLpConfig.h b/include/asm-ppc64/iSeries/HvLpConfig.h index 817698052ea8..9411b5a04d00 100644 --- a/include/asm-ppc64/iSeries/HvLpConfig.h +++ b/include/asm-ppc64/iSeries/HvLpConfig.h @@ -27,7 +27,6 @@ #include #include #include -#include extern HvLpIndex HvLpConfig_getLpIndex_outline(void); diff --git a/include/asm-ppc64/iSeries/HvReleaseData.h b/include/asm-ppc64/iSeries/HvReleaseData.h index c0cd21caf8fd..01a1f13ea4a0 100644 --- a/include/asm-ppc64/iSeries/HvReleaseData.h +++ b/include/asm-ppc64/iSeries/HvReleaseData.h @@ -58,4 +58,6 @@ struct HvReleaseData { char xRsvd3[20]; /* Reserved x2C-x3F */ }; +extern struct HvReleaseData hvReleaseData; + #endif /* _HVRELEASEDATA_H */ diff --git a/include/asm-ppc64/iSeries/IoHriMainStore.h b/include/asm-ppc64/iSeries/IoHriMainStore.h index fbb3ee4d174b..45ed3ea67d06 100644 --- a/include/asm-ppc64/iSeries/IoHriMainStore.h +++ b/include/asm-ppc64/iSeries/IoHriMainStore.h @@ -161,4 +161,6 @@ struct IoHriMainStoreSegment5 { u64 reserved3; }; +extern u64 xMsVpd[]; + #endif /* _IOHRIMAINSTORE_H */ diff --git a/include/asm-ppc64/iSeries/IoHriProcessorVpd.h b/include/asm-ppc64/iSeries/IoHriProcessorVpd.h index ccb7b7c55a40..73b73d80b8b1 100644 --- a/include/asm-ppc64/iSeries/IoHriProcessorVpd.h +++ b/include/asm-ppc64/iSeries/IoHriProcessorVpd.h @@ -81,4 +81,6 @@ struct IoHriProcessorVpd { char xProcSrc[72]; // CSP format SRC xB8-xFF }; +extern struct IoHriProcessorVpd xIoHriProcessorVpd[]; + #endif /* _IOHRIPROCESSORVPD_H */ diff --git a/include/asm-ppc64/iSeries/ItExtVpdPanel.h b/include/asm-ppc64/iSeries/ItExtVpdPanel.h index b7149079d3ca..4c546a8802b4 100644 --- a/include/asm-ppc64/iSeries/ItExtVpdPanel.h +++ b/include/asm-ppc64/iSeries/ItExtVpdPanel.h @@ -47,4 +47,6 @@ struct ItExtVpdPanel { u8 xRsvd2[48]; }; +extern struct ItExtVpdPanel xItExtVpdPanel; + #endif /* _ITEXTVPDPANEL_H */ diff --git a/include/asm-ppc64/iSeries/ItIplParmsReal.h b/include/asm-ppc64/iSeries/ItIplParmsReal.h index 14f0b0a2a823..ae3417dc599e 100644 --- a/include/asm-ppc64/iSeries/ItIplParmsReal.h +++ b/include/asm-ppc64/iSeries/ItIplParmsReal.h @@ -66,4 +66,6 @@ struct ItIplParmsReal { u64 xRsvd13; // Reserved x38-x3F }; +extern struct ItIplParmsReal xItIplParmsReal; + #endif /* _ITIPLPARMSREAL_H */ diff --git a/include/asm-ppc64/iSeries/ItLpNaca.h b/include/asm-ppc64/iSeries/ItLpNaca.h index 942b07d91408..225d0176779d 100644 --- a/include/asm-ppc64/iSeries/ItLpNaca.h +++ b/include/asm-ppc64/iSeries/ItLpNaca.h @@ -19,6 +19,8 @@ #ifndef _ITLPNACA_H #define _ITLPNACA_H +#include + /* * This control block contains the data that is shared between the * hypervisor (PLIC) and the OS. @@ -73,4 +75,6 @@ struct ItLpNaca { u64 xInterruptHdlr[32]; // Interrupt handlers 300-x3FF }; +extern struct ItLpNaca itLpNaca; + #endif /* _ITLPNACA_H */ diff --git a/include/asm-ppc64/iSeries/ItVpdAreas.h b/include/asm-ppc64/iSeries/ItVpdAreas.h index cfb9925e40aa..97cfa6c427ec 100644 --- a/include/asm-ppc64/iSeries/ItVpdAreas.h +++ b/include/asm-ppc64/iSeries/ItVpdAreas.h @@ -90,4 +90,6 @@ struct ItVpdAreas { void *xSlicVpdAdrs[ItVpdMaxEntries];// Array of VPD buffers 130-1EF }; +extern struct ItVpdAreas itVpdAreas; + #endif /* _ITVPDAREAS_H */ diff --git a/include/asm-ppc64/iSeries/LparData.h b/include/asm-ppc64/iSeries/LparData.h deleted file mode 100644 index a9fd6e287e6d..000000000000 --- a/include/asm-ppc64/iSeries/LparData.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * LparData.h - * Copyright (C) 2001 Mike Corrigan IBM Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _LPARDATA_H -#define _LPARDATA_H - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern struct LparMap xLparMap; -extern struct HvReleaseData hvReleaseData; -extern struct ItLpNaca itLpNaca; -extern struct ItIplParmsReal xItIplParmsReal; -extern struct ItExtVpdPanel xItExtVpdPanel; -extern struct IoHriProcessorVpd xIoHriProcessorVpd[]; -extern struct ItLpQueue xItLpQueue; -extern struct ItVpdAreas itVpdAreas; -extern u64 xMsVpd[]; -extern struct msChunks msChunks; - -#endif /* _LPARDATA_H */ diff --git a/include/asm-ppc64/iSeries/LparMap.h b/include/asm-ppc64/iSeries/LparMap.h index 1505c4f0f1b4..038e5df7e9f8 100644 --- a/include/asm-ppc64/iSeries/LparMap.h +++ b/include/asm-ppc64/iSeries/LparMap.h @@ -64,4 +64,6 @@ struct LparMap { u64 xVPN; // Virtual Page Number (0x000C000000000000) }; +extern struct LparMap xLparMap; + #endif /* _LPARMAP_H */ -- cgit v1.2.3-59-g8ed1b From dd61ce922770b299081c3e729ea65758ed676034 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:37 -0700 Subject: [PATCH] ppc64 iSeries: eliminate some unused inline functions This patch removes from the iSeries header files a large number of inline functions that are not used. It also changes the only caller of a HvCallCfg function that is outside HvLpConfig.h to its equivalent HvLpConfig function and no longer includes HvCallCfg.h where it is not needed. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/iSeries_smp.c | 1 - arch/ppc64/kernel/viopath.c | 3 +- include/asm-ppc64/iSeries/HvCallCfg.h | 53 +--------- include/asm-ppc64/iSeries/HvLpConfig.h | 188 --------------------------------- 4 files changed, 3 insertions(+), 242 deletions(-) diff --git a/arch/ppc64/kernel/iSeries_smp.c b/arch/ppc64/kernel/iSeries_smp.c index ff2281b457ed..f74386e31638 100644 --- a/arch/ppc64/kernel/iSeries_smp.c +++ b/arch/ppc64/kernel/iSeries_smp.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc64/kernel/viopath.c b/arch/ppc64/kernel/viopath.c index 4e5c36e81f48..ef524042e496 100644 --- a/arch/ppc64/kernel/viopath.c +++ b/arch/ppc64/kernel/viopath.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include @@ -364,7 +363,7 @@ void vio_set_hostlp(void) * while we're active */ viopath_ourLp = HvLpConfig_getLpIndex(); - viopath_hostLp = HvCallCfg_getHostingLpIndex(viopath_ourLp); + viopath_hostLp = HvLpConfig_getHostingLpIndex(viopath_ourLp); if (viopath_hostLp != HvLpIndexInvalid) vio_setHandler(viomajorsubtype_config, handleConfig); diff --git a/include/asm-ppc64/iSeries/HvCallCfg.h b/include/asm-ppc64/iSeries/HvCallCfg.h index aa491c3ad0a2..ddf2bb59d73c 100644 --- a/include/asm-ppc64/iSeries/HvCallCfg.h +++ b/include/asm-ppc64/iSeries/HvCallCfg.h @@ -67,31 +67,11 @@ enum HvCallCfg_ReqQual { #define HvCallCfgGetLpExecutionMode HvCallCfg + 31 #define HvCallCfgGetHostingLpIndex HvCallCfg + 32 -static inline HvLpIndex HvCallCfg_getLps(void) -{ - return HvCall0(HvCallCfgGetLps); -} - -static inline int HvCallCfg_isBusDedicated(u64 busIndex) -{ - return HvCall1(HvCallCfgIsBusDedicated, busIndex); -} - static inline HvLpIndex HvCallCfg_getBusOwner(u64 busIndex) { return HvCall1(HvCallCfgGetBusOwner, busIndex); } -static inline HvLpIndexMap HvCallCfg_getBusAllocation(u64 busIndex) -{ - return HvCall1(HvCallCfgGetBusAllocation, busIndex); -} - -static inline HvLpIndexMap HvCallCfg_getActiveLpMap(void) -{ - return HvCall0(HvCallCfgGetActiveLpMap); -} - static inline HvLpVirtualLanIndexMap HvCallCfg_getVirtualLanIndexMap( HvLpIndex lp) { @@ -105,31 +85,12 @@ static inline HvLpVirtualLanIndexMap HvCallCfg_getVirtualLanIndexMap( return retVal; } -static inline u64 HvCallCfg_getSystemMsChunks(void) -{ - return HvCall0(HvCallCfgGetSystemMsChunks); -} - static inline u64 HvCallCfg_getMsChunks(HvLpIndex lp, enum HvCallCfg_ReqQual qual) { return HvCall2(HvCallCfgGetMsChunks, lp, qual); } -static inline u64 HvCallCfg_getMinRuntimeMsChunks(HvLpIndex lp) -{ - /* - * NOTE: This function was added in v5r1 so older hypervisors - * will return a -1 value - */ - return HvCall1(HvCallCfgGetMinRuntimeMsChunks, lp); -} - -static inline u64 HvCallCfg_setMinRuntimeMsChunks(u64 chunks) -{ - return HvCall1(HvCallCfgSetMinRuntimeMsChunks, chunks); -} - static inline u64 HvCallCfg_getSystemPhysicalProcessors(void) { return HvCall0(HvCallCfgGetSystemPhysicalProcessors); @@ -141,14 +102,6 @@ static inline u64 HvCallCfg_getPhysicalProcessors(HvLpIndex lp, return HvCall2(HvCallCfgGetPhysicalProcessors, lp, qual); } -static inline u64 HvCallCfg_getConfiguredBusUnitsForInterruptProc(HvLpIndex lp, - u16 hvLogicalProcIndex) -{ - return HvCall2(HvCallCfgGetConfiguredBusUnitsForIntProc, lp, - hvLogicalProcIndex); - -} - static inline HvLpSharedPoolIndex HvCallCfg_getSharedPoolIndex(HvLpIndex lp) { return HvCall1(HvCallCfgGetSharedPoolIndex, lp); @@ -164,15 +117,13 @@ static inline u64 HvCallCfg_getSharedProcUnits(HvLpIndex lp, static inline u64 HvCallCfg_getNumProcsInSharedPool(HvLpSharedPoolIndex sPI) { - u16 retVal = HvCall1(HvCallCfgGetNumProcsInSharedPool, sPI); - return retVal; + return (u16)HvCall1(HvCallCfgGetNumProcsInSharedPool, sPI); } static inline HvLpIndex HvCallCfg_getHostingLpIndex(HvLpIndex lp) { - u64 retVal = HvCall1(HvCallCfgGetHostingLpIndex, lp); - return retVal; + return HvCall1(HvCallCfgGetHostingLpIndex, lp); } #endif /* _HVCALLCFG_H */ diff --git a/include/asm-ppc64/iSeries/HvLpConfig.h b/include/asm-ppc64/iSeries/HvLpConfig.h index 9411b5a04d00..78d68281cc8b 100644 --- a/include/asm-ppc64/iSeries/HvLpConfig.h +++ b/include/asm-ppc64/iSeries/HvLpConfig.h @@ -40,127 +40,16 @@ static inline HvLpIndex HvLpConfig_getPrimaryLpIndex(void) return itLpNaca.xPrimaryLpIndex; } -static inline HvLpIndex HvLpConfig_getLps(void) -{ - return HvCallCfg_getLps(); -} - -static inline HvLpIndexMap HvLpConfig_getActiveLpMap(void) -{ - return HvCallCfg_getActiveLpMap(); -} - -static inline u64 HvLpConfig_getSystemMsMegs(void) -{ - return HvCallCfg_getSystemMsChunks() / HVCHUNKSPERMEG; -} - -static inline u64 HvLpConfig_getSystemMsChunks(void) -{ - return HvCallCfg_getSystemMsChunks(); -} - -static inline u64 HvLpConfig_getSystemMsPages(void) -{ - return HvCallCfg_getSystemMsChunks() * HVPAGESPERCHUNK; -} - -static inline u64 HvLpConfig_getMsMegs(void) -{ - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Cur) - / HVCHUNKSPERMEG; -} - static inline u64 HvLpConfig_getMsChunks(void) { return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Cur); } -static inline u64 HvLpConfig_getMsPages(void) -{ - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Cur) - * HVPAGESPERCHUNK; -} - -static inline u64 HvLpConfig_getMinMsMegs(void) -{ - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Min) - / HVCHUNKSPERMEG; -} - -static inline u64 HvLpConfig_getMinMsChunks(void) -{ - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Min); -} - -static inline u64 HvLpConfig_getMinMsPages(void) -{ - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Min) - * HVPAGESPERCHUNK; -} - -static inline u64 HvLpConfig_getMinRuntimeMsMegs(void) -{ - return HvCallCfg_getMinRuntimeMsChunks(HvLpConfig_getLpIndex()) - / HVCHUNKSPERMEG; -} - -static inline u64 HvLpConfig_getMinRuntimeMsChunks(void) -{ - return HvCallCfg_getMinRuntimeMsChunks(HvLpConfig_getLpIndex()); -} - -static inline u64 HvLpConfig_getMinRuntimeMsPages(void) -{ - return HvCallCfg_getMinRuntimeMsChunks(HvLpConfig_getLpIndex()) - * HVPAGESPERCHUNK; -} - -static inline u64 HvLpConfig_getMaxMsMegs(void) -{ - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Max) - / HVCHUNKSPERMEG; -} - -static inline u64 HvLpConfig_getMaxMsChunks(void) -{ - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Max); -} - -static inline u64 HvLpConfig_getMaxMsPages(void) -{ - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Max) - * HVPAGESPERCHUNK; -} - -static inline u64 HvLpConfig_getInitMsMegs(void) -{ - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Init) - / HVCHUNKSPERMEG; -} - -static inline u64 HvLpConfig_getInitMsChunks(void) -{ - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Init); -} - -static inline u64 HvLpConfig_getInitMsPages(void) -{ - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Init) - * HVPAGESPERCHUNK; -} - static inline u64 HvLpConfig_getSystemPhysicalProcessors(void) { return HvCallCfg_getSystemPhysicalProcessors(); } -static inline u64 HvLpConfig_getSystemLogicalProcessors(void) -{ - return HvCallCfg_getSystemPhysicalProcessors() - * (/*getPaca()->getSecondaryThreadCount() +*/ 1); -} - static inline u64 HvLpConfig_getNumProcsInSharedPool(HvLpSharedPoolIndex sPI) { return HvCallCfg_getNumProcsInSharedPool(sPI); @@ -172,13 +61,6 @@ static inline u64 HvLpConfig_getPhysicalProcessors(void) HvCallCfg_Cur); } -static inline u64 HvLpConfig_getLogicalProcessors(void) -{ - return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(), - HvCallCfg_Cur) - * (/*getPaca()->getSecondaryThreadCount() +*/ 1); -} - static inline HvLpSharedPoolIndex HvLpConfig_getSharedPoolIndex(void) { return HvCallCfg_getSharedPoolIndex(HvLpConfig_getLpIndex()); @@ -190,57 +72,18 @@ static inline u64 HvLpConfig_getSharedProcUnits(void) HvCallCfg_Cur); } -static inline u64 HvLpConfig_getMinSharedProcUnits(void) -{ - return HvCallCfg_getSharedProcUnits(HvLpConfig_getLpIndex(), - HvCallCfg_Min); -} - static inline u64 HvLpConfig_getMaxSharedProcUnits(void) { return HvCallCfg_getSharedProcUnits(HvLpConfig_getLpIndex(), HvCallCfg_Max); } -static inline u64 HvLpConfig_getMinPhysicalProcessors(void) -{ - return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(), - HvCallCfg_Min); -} - -static inline u64 HvLpConfig_getMinLogicalProcessors(void) -{ - return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(), - HvCallCfg_Min) - * (/*getPaca()->getSecondaryThreadCount() +*/ 1); -} - static inline u64 HvLpConfig_getMaxPhysicalProcessors(void) { return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(), HvCallCfg_Max); } -static inline u64 HvLpConfig_getMaxLogicalProcessors(void) -{ - return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(), - HvCallCfg_Max) - * (/*getPaca()->getSecondaryThreadCount() +*/ 1); -} - -static inline u64 HvLpConfig_getInitPhysicalProcessors(void) -{ - return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(), - HvCallCfg_Init); -} - -static inline u64 HvLpConfig_getInitLogicalProcessors(void) -{ - return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(), - HvCallCfg_Init) - * (/*getPaca()->getSecondaryThreadCount() +*/ 1); -} - static inline HvLpVirtualLanIndexMap HvLpConfig_getVirtualLanIndexMap(void) { return HvCallCfg_getVirtualLanIndexMap(HvLpConfig_getLpIndex_outline()); @@ -252,37 +95,6 @@ static inline HvLpVirtualLanIndexMap HvLpConfig_getVirtualLanIndexMapForLp( return HvCallCfg_getVirtualLanIndexMap(lp); } -static inline HvLpIndex HvLpConfig_getBusOwner(HvBusNumber busNumber) -{ - return HvCallCfg_getBusOwner(busNumber); -} - -static inline int HvLpConfig_isBusDedicated(HvBusNumber busNumber) -{ - return HvCallCfg_isBusDedicated(busNumber); -} - -static inline HvLpIndexMap HvLpConfig_getBusAllocation(HvBusNumber busNumber) -{ - return HvCallCfg_getBusAllocation(busNumber); -} - -/* returns the absolute real address of the load area */ -static inline u64 HvLpConfig_getLoadAddress(void) -{ - return itLpNaca.xLoadAreaAddr & 0x7fffffffffffffff; -} - -static inline u64 HvLpConfig_getLoadPages(void) -{ - return itLpNaca.xLoadAreaChunks * HVPAGESPERCHUNK; -} - -static inline int HvLpConfig_isBusOwnedByThisLp(HvBusNumber busNumber) -{ - return (HvLpConfig_getBusOwner(busNumber) == HvLpConfig_getLpIndex()); -} - static inline int HvLpConfig_doLpsCommunicateOnVirtualLan(HvLpIndex lp1, HvLpIndex lp2) { -- cgit v1.2.3-59-g8ed1b From 2310c977a9b7a4d08fbaa74e694b49b38d49f5ae Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:38 -0700 Subject: [PATCH] ppc64 iSeries: remove HvCallCfg.h Now that the only users of things in HvCallCfg.h are in HvLpConfig.h, merge in the bit we need and remove HvCallCfg.h. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-ppc64/iSeries/HvCallCfg.h | 129 --------------------------------- include/asm-ppc64/iSeries/HvLpConfig.h | 59 ++++++++++----- 2 files changed, 42 insertions(+), 146 deletions(-) delete mode 100644 include/asm-ppc64/iSeries/HvCallCfg.h diff --git a/include/asm-ppc64/iSeries/HvCallCfg.h b/include/asm-ppc64/iSeries/HvCallCfg.h deleted file mode 100644 index ddf2bb59d73c..000000000000 --- a/include/asm-ppc64/iSeries/HvCallCfg.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * HvCallCfg.h - * Copyright (C) 2001 Mike Corrigan IBM Corporation - * - * 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 - */ -/* - * This file contains the "hypervisor call" interface which is used to - * drive the hypervisor from the OS. - */ -#ifndef _HVCALLCFG_H -#define _HVCALLCFG_H - -#include -#include - -enum HvCallCfg_ReqQual { - HvCallCfg_Cur = 0, - HvCallCfg_Init = 1, - HvCallCfg_Max = 2, - HvCallCfg_Min = 3 -}; - -#define HvCallCfgGetLps HvCallCfg + 0 -#define HvCallCfgGetActiveLpMap HvCallCfg + 1 -#define HvCallCfgGetLpVrmIndex HvCallCfg + 2 -#define HvCallCfgGetLpMinSupportedPlicVrmIndex HvCallCfg + 3 -#define HvCallCfgGetLpMinCompatablePlicVrmIndex HvCallCfg + 4 -#define HvCallCfgGetLpVrmName HvCallCfg + 5 -#define HvCallCfgGetSystemPhysicalProcessors HvCallCfg + 6 -#define HvCallCfgGetPhysicalProcessors HvCallCfg + 7 -#define HvCallCfgGetSystemMsChunks HvCallCfg + 8 -#define HvCallCfgGetMsChunks HvCallCfg + 9 -#define HvCallCfgGetInteractivePercentage HvCallCfg + 10 -#define HvCallCfgIsBusDedicated HvCallCfg + 11 -#define HvCallCfgGetBusOwner HvCallCfg + 12 -#define HvCallCfgGetBusAllocation HvCallCfg + 13 -#define HvCallCfgGetBusUnitOwner HvCallCfg + 14 -#define HvCallCfgGetBusUnitAllocation HvCallCfg + 15 -#define HvCallCfgGetVirtualBusPool HvCallCfg + 16 -#define HvCallCfgGetBusUnitInterruptProc HvCallCfg + 17 -#define HvCallCfgGetConfiguredBusUnitsForIntProc HvCallCfg + 18 -#define HvCallCfgGetRioSanBusPool HvCallCfg + 19 -#define HvCallCfgGetSharedPoolIndex HvCallCfg + 20 -#define HvCallCfgGetSharedProcUnits HvCallCfg + 21 -#define HvCallCfgGetNumProcsInSharedPool HvCallCfg + 22 -#define HvCallCfgRouter23 HvCallCfg + 23 -#define HvCallCfgRouter24 HvCallCfg + 24 -#define HvCallCfgRouter25 HvCallCfg + 25 -#define HvCallCfgRouter26 HvCallCfg + 26 -#define HvCallCfgRouter27 HvCallCfg + 27 -#define HvCallCfgGetMinRuntimeMsChunks HvCallCfg + 28 -#define HvCallCfgSetMinRuntimeMsChunks HvCallCfg + 29 -#define HvCallCfgGetVirtualLanIndexMap HvCallCfg + 30 -#define HvCallCfgGetLpExecutionMode HvCallCfg + 31 -#define HvCallCfgGetHostingLpIndex HvCallCfg + 32 - -static inline HvLpIndex HvCallCfg_getBusOwner(u64 busIndex) -{ - return HvCall1(HvCallCfgGetBusOwner, busIndex); -} - -static inline HvLpVirtualLanIndexMap HvCallCfg_getVirtualLanIndexMap( - HvLpIndex lp) -{ - /* - * This is a new function in V5R1 so calls to this on older - * hypervisors will return -1 - */ - u64 retVal = HvCall1(HvCallCfgGetVirtualLanIndexMap, lp); - if (retVal == -1) - retVal = 0; - return retVal; -} - -static inline u64 HvCallCfg_getMsChunks(HvLpIndex lp, - enum HvCallCfg_ReqQual qual) -{ - return HvCall2(HvCallCfgGetMsChunks, lp, qual); -} - -static inline u64 HvCallCfg_getSystemPhysicalProcessors(void) -{ - return HvCall0(HvCallCfgGetSystemPhysicalProcessors); -} - -static inline u64 HvCallCfg_getPhysicalProcessors(HvLpIndex lp, - enum HvCallCfg_ReqQual qual) -{ - return HvCall2(HvCallCfgGetPhysicalProcessors, lp, qual); -} - -static inline HvLpSharedPoolIndex HvCallCfg_getSharedPoolIndex(HvLpIndex lp) -{ - return HvCall1(HvCallCfgGetSharedPoolIndex, lp); - -} - -static inline u64 HvCallCfg_getSharedProcUnits(HvLpIndex lp, - enum HvCallCfg_ReqQual qual) -{ - return HvCall2(HvCallCfgGetSharedProcUnits, lp, qual); - -} - -static inline u64 HvCallCfg_getNumProcsInSharedPool(HvLpSharedPoolIndex sPI) -{ - return (u16)HvCall1(HvCallCfgGetNumProcsInSharedPool, sPI); - -} - -static inline HvLpIndex HvCallCfg_getHostingLpIndex(HvLpIndex lp) -{ - return HvCall1(HvCallCfgGetHostingLpIndex, lp); -} - -#endif /* _HVCALLCFG_H */ diff --git a/include/asm-ppc64/iSeries/HvLpConfig.h b/include/asm-ppc64/iSeries/HvLpConfig.h index 78d68281cc8b..f1cf1e70ca3c 100644 --- a/include/asm-ppc64/iSeries/HvLpConfig.h +++ b/include/asm-ppc64/iSeries/HvLpConfig.h @@ -24,10 +24,26 @@ * to determine which resources should be allocated to each partition. */ -#include +#include #include #include +enum { + HvCallCfg_Cur = 0, + HvCallCfg_Init = 1, + HvCallCfg_Max = 2, + HvCallCfg_Min = 3 +}; + +#define HvCallCfgGetSystemPhysicalProcessors HvCallCfg + 6 +#define HvCallCfgGetPhysicalProcessors HvCallCfg + 7 +#define HvCallCfgGetMsChunks HvCallCfg + 9 +#define HvCallCfgGetSharedPoolIndex HvCallCfg + 20 +#define HvCallCfgGetSharedProcUnits HvCallCfg + 21 +#define HvCallCfgGetNumProcsInSharedPool HvCallCfg + 22 +#define HvCallCfgGetVirtualLanIndexMap HvCallCfg + 30 +#define HvCallCfgGetHostingLpIndex HvCallCfg + 32 + extern HvLpIndex HvLpConfig_getLpIndex_outline(void); static inline HvLpIndex HvLpConfig_getLpIndex(void) @@ -42,72 +58,81 @@ static inline HvLpIndex HvLpConfig_getPrimaryLpIndex(void) static inline u64 HvLpConfig_getMsChunks(void) { - return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(), HvCallCfg_Cur); + return HvCall2(HvCallCfgGetMsChunks, HvLpConfig_getLpIndex(), + HvCallCfg_Cur); } static inline u64 HvLpConfig_getSystemPhysicalProcessors(void) { - return HvCallCfg_getSystemPhysicalProcessors(); + return HvCall0(HvCallCfgGetSystemPhysicalProcessors); } static inline u64 HvLpConfig_getNumProcsInSharedPool(HvLpSharedPoolIndex sPI) { - return HvCallCfg_getNumProcsInSharedPool(sPI); + return (u16)HvCall1(HvCallCfgGetNumProcsInSharedPool, sPI); } static inline u64 HvLpConfig_getPhysicalProcessors(void) { - return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(), + return HvCall2(HvCallCfgGetPhysicalProcessors, HvLpConfig_getLpIndex(), HvCallCfg_Cur); } static inline HvLpSharedPoolIndex HvLpConfig_getSharedPoolIndex(void) { - return HvCallCfg_getSharedPoolIndex(HvLpConfig_getLpIndex()); + return HvCall1(HvCallCfgGetSharedPoolIndex, HvLpConfig_getLpIndex()); } static inline u64 HvLpConfig_getSharedProcUnits(void) { - return HvCallCfg_getSharedProcUnits(HvLpConfig_getLpIndex(), + return HvCall2(HvCallCfgGetSharedProcUnits, HvLpConfig_getLpIndex(), HvCallCfg_Cur); } static inline u64 HvLpConfig_getMaxSharedProcUnits(void) { - return HvCallCfg_getSharedProcUnits(HvLpConfig_getLpIndex(), + return HvCall2(HvCallCfgGetSharedProcUnits, HvLpConfig_getLpIndex(), HvCallCfg_Max); } static inline u64 HvLpConfig_getMaxPhysicalProcessors(void) { - return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(), + return HvCall2(HvCallCfgGetPhysicalProcessors, HvLpConfig_getLpIndex(), HvCallCfg_Max); } -static inline HvLpVirtualLanIndexMap HvLpConfig_getVirtualLanIndexMap(void) +static inline HvLpVirtualLanIndexMap HvLpConfig_getVirtualLanIndexMapForLp( + HvLpIndex lp) { - return HvCallCfg_getVirtualLanIndexMap(HvLpConfig_getLpIndex_outline()); + /* + * This is a new function in V5R1 so calls to this on older + * hypervisors will return -1 + */ + u64 retVal = HvCall1(HvCallCfgGetVirtualLanIndexMap, lp); + if (retVal == -1) + retVal = 0; + return retVal; } -static inline HvLpVirtualLanIndexMap HvLpConfig_getVirtualLanIndexMapForLp( - HvLpIndex lp) +static inline HvLpVirtualLanIndexMap HvLpConfig_getVirtualLanIndexMap(void) { - return HvCallCfg_getVirtualLanIndexMap(lp); + return HvLpConfig_getVirtualLanIndexMapForLp( + HvLpConfig_getLpIndex_outline()); } static inline int HvLpConfig_doLpsCommunicateOnVirtualLan(HvLpIndex lp1, HvLpIndex lp2) { HvLpVirtualLanIndexMap virtualLanIndexMap1 = - HvCallCfg_getVirtualLanIndexMap(lp1); + HvLpConfig_getVirtualLanIndexMapForLp(lp1); HvLpVirtualLanIndexMap virtualLanIndexMap2 = - HvCallCfg_getVirtualLanIndexMap(lp2); + HvLpConfig_getVirtualLanIndexMapForLp(lp2); return ((virtualLanIndexMap1 & virtualLanIndexMap2) != 0); } static inline HvLpIndex HvLpConfig_getHostingLpIndex(HvLpIndex lp) { - return HvCallCfg_getHostingLpIndex(lp); + return HvCall1(HvCallCfgGetHostingLpIndex, lp); } #endif /* _HVLPCONFIG_H */ -- cgit v1.2.3-59-g8ed1b From c92877e0a079fe5a488cb244c7afb05137702b49 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:39 -0700 Subject: [PATCH] ppc64 iSeries: cleanup ItLpQueue.h Just white space cleaups and move process_iSeries_events into its only caller. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/idle.c | 5 +++++ include/asm-ppc64/iSeries/ItLpQueue.h | 16 ++++------------ 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index ff8a7db142d3..bdf13b4dc1c8 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c @@ -42,6 +42,11 @@ static int (*idle_loop)(void); static unsigned long maxYieldTime = 0; static unsigned long minYieldTime = 0xffffffffffffffffUL; +static inline void process_iSeries_events(void) +{ + asm volatile ("li 0,0x5555; sc" : : : "r0", "r3"); +} + static void yield_shared_processor(void) { unsigned long tb; diff --git a/include/asm-ppc64/iSeries/ItLpQueue.h b/include/asm-ppc64/iSeries/ItLpQueue.h index b2bdef429591..393299e04d7f 100644 --- a/include/asm-ppc64/iSeries/ItLpQueue.h +++ b/include/asm-ppc64/iSeries/ItLpQueue.h @@ -64,9 +64,9 @@ struct ItLpQueue { u8 xPlicStatus; // 0x01 DedicatedIo or DedicatedLp or NotUsed u16 xSlicLogicalProcIndex; // 0x02 Logical Proc Index for correlation u8 xPlicRsvd[12]; // 0x04 - char* xSlicCurEventPtr; // 0x10 - char* xSlicLastValidEventPtr; // 0x18 - char* xSlicEventStackPtr; // 0x20 + char *xSlicCurEventPtr; // 0x10 + char *xSlicLastValidEventPtr; // 0x18 + char *xSlicEventStackPtr; // 0x20 u8 xIndex; // 0x28 unique sequential index. u8 xSlicRsvd[3]; // 0x29-2b u32 xInUseWord; // 0x2C @@ -76,17 +76,9 @@ struct ItLpQueue { extern struct ItLpQueue xItLpQueue; -extern struct HvLpEvent * ItLpQueue_getNextLpEvent(struct ItLpQueue *); +extern struct HvLpEvent *ItLpQueue_getNextLpEvent(struct ItLpQueue *); extern int ItLpQueue_isLpIntPending(struct ItLpQueue *); extern unsigned ItLpQueue_process(struct ItLpQueue *, struct pt_regs *); extern void ItLpQueue_clearValid(struct HvLpEvent *); -static __inline__ void process_iSeries_events(void) -{ - __asm__ __volatile__ ( - " li 0,0x5555 \n\ - sc" - : : : "r0", "r3"); -} - #endif /* _ITLPQUEUE_H */ -- cgit v1.2.3-59-g8ed1b From 4a5304f5ba04eff979cd108309eae7a00f3fff77 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:40 -0700 Subject: [PATCH] ppc64 iSeries: tidy up some includes and HvCall.h This patch removes some unused bits from HvCall.h and some unneeded #includes from other files. Also includes ItLpQueue.h in paca.h in preference to a stub declaration of struct ItLpQueue. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/asm-offsets.c | 1 - arch/ppc64/kernel/iSeries_pci.c | 1 - arch/ppc64/kernel/mf.c | 1 - arch/ppc64/kernel/rtc.c | 1 - include/asm-ppc64/iSeries/HvCall.h | 84 +------------------------------------- include/asm-ppc64/paca.h | 2 +- 6 files changed, 3 insertions(+), 87 deletions(-) diff --git a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c index 0094ac79a18c..abb9e5b5da03 100644 --- a/arch/ppc64/kernel/asm-offsets.c +++ b/arch/ppc64/kernel/asm-offsets.c @@ -31,7 +31,6 @@ #include #include -#include #include #include #include diff --git a/arch/ppc64/kernel/iSeries_pci.c b/arch/ppc64/kernel/iSeries_pci.c index 9829cd4666d8..1bff515bd298 100644 --- a/arch/ppc64/kernel/iSeries_pci.c +++ b/arch/ppc64/kernel/iSeries_pci.c @@ -38,7 +38,6 @@ #include #include -#include #include #include #include diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c index 5aca7e8005a8..d98bebf7042f 100644 --- a/arch/ppc64/kernel/mf.c +++ b/arch/ppc64/kernel/mf.c @@ -40,7 +40,6 @@ #include #include #include -#include #include /* diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c index 4cdafb4007b1..de02aedbe080 100644 --- a/arch/ppc64/kernel/rtc.c +++ b/arch/ppc64/kernel/rtc.c @@ -44,7 +44,6 @@ #include #include -#include extern int piranha_simulator; diff --git a/include/asm-ppc64/iSeries/HvCall.h b/include/asm-ppc64/iSeries/HvCall.h index c903387e9128..c3f19475c0d9 100644 --- a/include/asm-ppc64/iSeries/HvCall.h +++ b/include/asm-ppc64/iSeries/HvCall.h @@ -27,48 +27,6 @@ #include #include -/* -enum HvCall_ReturnCode -{ - HvCall_Good = 0, - HvCall_Partial = 1, - HvCall_NotOwned = 2, - HvCall_NotFreed = 3, - HvCall_UnspecifiedError = 4 -}; - -enum HvCall_TypeOfSIT -{ - HvCall_ReduceOnly = 0, - HvCall_Unconditional = 1 -}; - -enum HvCall_TypeOfYield -{ - HvCall_YieldTimed = 0, // Yield until specified time - HvCall_YieldToActive = 1, // Yield until all active procs have run - HvCall_YieldToProc = 2 // Yield until the specified processor has run -}; - -enum HvCall_InterruptMasks -{ - HvCall_MaskIPI = 0x00000001, - HvCall_MaskLpEvent = 0x00000002, - HvCall_MaskLpProd = 0x00000004, - HvCall_MaskTimeout = 0x00000008 -}; - -enum HvCall_VaryOffChunkRc -{ - HvCall_VaryOffSucceeded = 0, - HvCall_VaryOffWithdrawn = 1, - HvCall_ChunkInLoadArea = 2, - HvCall_ChunkInHPT = 3, - HvCall_ChunkNotAccessible = 4, - HvCall_ChunkInUse = 5 -}; -*/ - /* Type of yield for HvCallBaseYieldProcessor */ #define HvCall_YieldTimed 0 /* Yield until specified time (tb) */ #define HvCall_YieldToActive 1 /* Yield until all active procs have run */ @@ -139,35 +97,12 @@ static inline void HvCall_setEnabledInterrupts(u64 enabledInterrupts) HvCall1(HvCallBaseSetEnabledInterrupts, enabledInterrupts); } -static inline void HvCall_clearLogBuffer(HvLpIndex lpindex) -{ - HvCall1(HvCallBaseClearLogBuffer, lpindex); -} - -static inline u32 HvCall_getLogBufferCodePage(HvLpIndex lpindex) -{ - u32 retVal = HvCall1(HvCallBaseGetLogBufferCodePage, lpindex); - return retVal; -} - -static inline int HvCall_getLogBufferFormat(HvLpIndex lpindex) -{ - int retVal = HvCall1(HvCallBaseGetLogBufferFormat, lpindex); - return retVal; -} - -static inline u32 HvCall_getLogBufferLength(HvLpIndex lpindex) -{ - u32 retVal = HvCall1(HvCallBaseGetLogBufferLength, lpindex); - return retVal; -} - -static inline void HvCall_setLogBufferFormatAndCodepage(int format, u32 codePage) +static inline void HvCall_setLogBufferFormatAndCodepage(int format, + u32 codePage) { HvCall2(HvCallBaseSetLogBufferFormatAndCodePage, format, codePage); } -extern int HvCall_readLogBuffer(HvLpIndex lpindex, void *buffer, u64 bufLen); extern void HvCall_writeLogBuffer(const void *buffer, u64 bufLen); static inline void HvCall_sendIPI(struct paca_struct *targetPaca) @@ -175,19 +110,4 @@ static inline void HvCall_sendIPI(struct paca_struct *targetPaca) HvCall1(HvCallBaseSendIPI, targetPaca->paca_index); } -static inline void HvCall_terminateMachineSrc(void) -{ - HvCall0(HvCallBaseTerminateMachineSrc); -} - -static inline void HvCall_setDABR(unsigned long val) -{ - HvCall1(HvCallCcSetDABR, val); -} - -static inline void HvCall_setDebugBus(unsigned long val) -{ - HvCall1(HvCallBaseSetDebugBus, val); -} - #endif /* _HVCALL_H */ diff --git a/include/asm-ppc64/paca.h b/include/asm-ppc64/paca.h index 1a0223b5f3b8..ae76cae1483f 100644 --- a/include/asm-ppc64/paca.h +++ b/include/asm-ppc64/paca.h @@ -20,13 +20,13 @@ #include #include #include +#include #include register struct paca_struct *local_paca asm("r13"); #define get_paca() local_paca struct task_struct; -struct ItLpQueue; /* * Defines the layout of the paca. -- cgit v1.2.3-59-g8ed1b From c670b1acd0ed0d9f7a27154759a9825cb5012ae4 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:41 -0700 Subject: [PATCH] ppc64 iSeries: misc header cleanups Last of this round of the iSeries header cleanups - don't have two defines for the same thing (HvMaxArchitectedLps and HvMaxArchitectedVirtualLans) - HvCallSc.h only needs linux/types.h - remove unused struct definition - add "extern" to some more function declarations Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/viopath.c | 4 ++-- include/asm-ppc64/iSeries/HvCallSc.h | 34 +++++++++++++++++----------------- include/asm-ppc64/iSeries/HvTypes.h | 8 +++----- include/asm-ppc64/iSeries/ItVpdAreas.h | 6 ------ 4 files changed, 22 insertions(+), 30 deletions(-) diff --git a/arch/ppc64/kernel/viopath.c b/arch/ppc64/kernel/viopath.c index ef524042e496..2a6c4f01c45e 100644 --- a/arch/ppc64/kernel/viopath.c +++ b/arch/ppc64/kernel/viopath.c @@ -485,7 +485,7 @@ int viopath_open(HvLpIndex remoteLp, int subtype, int numReq) unsigned long flags; int tempNumAllocated; - if ((remoteLp >= HvMaxArchitectedLps) || (remoteLp == HvLpIndexInvalid)) + if ((remoteLp >= HVMAXARCHITECTEDLPS) || (remoteLp == HvLpIndexInvalid)) return -EINVAL; subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT; @@ -556,7 +556,7 @@ int viopath_close(HvLpIndex remoteLp, int subtype, int numReq) int numOpen; struct alloc_parms parms; - if ((remoteLp >= HvMaxArchitectedLps) || (remoteLp == HvLpIndexInvalid)) + if ((remoteLp >= HVMAXARCHITECTEDLPS) || (remoteLp == HvLpIndexInvalid)) return -EINVAL; subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT; diff --git a/include/asm-ppc64/iSeries/HvCallSc.h b/include/asm-ppc64/iSeries/HvCallSc.h index c32145f9ec75..a62cef3822f9 100644 --- a/include/asm-ppc64/iSeries/HvCallSc.h +++ b/include/asm-ppc64/iSeries/HvCallSc.h @@ -19,7 +19,7 @@ #ifndef _HVCALLSC_H #define _HVCALLSC_H -#include +#include #define HvCallBase 0x8000000000000000ul #define HvCallCc 0x8001000000000000ul @@ -30,22 +30,22 @@ #define HvCallSm 0x8007000000000000ul #define HvCallXm 0x8009000000000000ul -u64 HvCall0(u64); -u64 HvCall1(u64, u64); -u64 HvCall2(u64, u64, u64); -u64 HvCall3(u64, u64, u64, u64); -u64 HvCall4(u64, u64, u64, u64, u64); -u64 HvCall5(u64, u64, u64, u64, u64, u64); -u64 HvCall6(u64, u64, u64, u64, u64, u64, u64); -u64 HvCall7(u64, u64, u64, u64, u64, u64, u64, u64); +extern u64 HvCall0(u64); +extern u64 HvCall1(u64, u64); +extern u64 HvCall2(u64, u64, u64); +extern u64 HvCall3(u64, u64, u64, u64); +extern u64 HvCall4(u64, u64, u64, u64, u64); +extern u64 HvCall5(u64, u64, u64, u64, u64, u64); +extern u64 HvCall6(u64, u64, u64, u64, u64, u64, u64); +extern u64 HvCall7(u64, u64, u64, u64, u64, u64, u64, u64); -u64 HvCall0Ret16(u64, void *); -u64 HvCall1Ret16(u64, void *, u64); -u64 HvCall2Ret16(u64, void *, u64, u64); -u64 HvCall3Ret16(u64, void *, u64, u64, u64); -u64 HvCall4Ret16(u64, void *, u64, u64, u64, u64); -u64 HvCall5Ret16(u64, void *, u64, u64, u64, u64, u64); -u64 HvCall6Ret16(u64, void *, u64, u64, u64, u64, u64, u64); -u64 HvCall7Ret16(u64, void *, u64, u64 ,u64 ,u64 ,u64 ,u64 ,u64); +extern u64 HvCall0Ret16(u64, void *); +extern u64 HvCall1Ret16(u64, void *, u64); +extern u64 HvCall2Ret16(u64, void *, u64, u64); +extern u64 HvCall3Ret16(u64, void *, u64, u64, u64); +extern u64 HvCall4Ret16(u64, void *, u64, u64, u64, u64); +extern u64 HvCall5Ret16(u64, void *, u64, u64, u64, u64, u64); +extern u64 HvCall6Ret16(u64, void *, u64, u64, u64, u64, u64, u64); +extern u64 HvCall7Ret16(u64, void *, u64, u64 ,u64 ,u64 ,u64 ,u64 ,u64); #endif /* _HVCALLSC_H */ diff --git a/include/asm-ppc64/iSeries/HvTypes.h b/include/asm-ppc64/iSeries/HvTypes.h index 111191ddb181..b1ef2b4cb3e3 100644 --- a/include/asm-ppc64/iSeries/HvTypes.h +++ b/include/asm-ppc64/iSeries/HvTypes.h @@ -40,14 +40,14 @@ typedef u64 HvIoToken; typedef u8 HvLpName[8]; typedef u32 HvIoId; typedef u64 HvRealMemoryIndex; -typedef u32 HvLpIndexMap; /* Must hold HvMaxArchitectedLps bits!!! */ +typedef u32 HvLpIndexMap; /* Must hold HVMAXARCHITECTEDLPS bits!!! */ typedef u16 HvLpVrmIndex; typedef u32 HvXmGenerationId; typedef u8 HvLpBusPool; typedef u8 HvLpSharedPoolIndex; typedef u16 HvLpSharedProcUnitsX100; typedef u8 HvLpVirtualLanIndex; -typedef u16 HvLpVirtualLanIndexMap; /* Must hold HvMaxArchitectedVirtualLans bits!!! */ +typedef u16 HvLpVirtualLanIndexMap; /* Must hold HVMAXARCHITECTEDVIRTUALLANS bits!!! */ typedef u16 HvBusNumber; /* Hypervisor Bus Number */ typedef u8 HvSubBusNumber; /* Hypervisor SubBus Number */ typedef u8 HvAgentId; /* Hypervisor DevFn */ @@ -66,15 +66,13 @@ typedef u8 HvAgentId; /* Hypervisor DevFn */ #define HVPAGESPERMEG 256 #define HVPAGESPERCHUNK 64 -#define HvMaxArchitectedLps ((HvLpIndex)HVMAXARCHITECTEDLPS) -#define HvMaxArchitectedVirtualLans ((HvLpVirtualLanIndex)16) #define HvLpIndexInvalid ((HvLpIndex)0xff) /* * Enums for the sub-components under PLIC * Used in HvCall and HvPrimaryCall */ -enum HvCallCompIds { +enum { HvCallCompId = 0, HvCallCpuCtlsCompId = 1, HvCallCfgCompId = 2, diff --git a/include/asm-ppc64/iSeries/ItVpdAreas.h b/include/asm-ppc64/iSeries/ItVpdAreas.h index 97cfa6c427ec..71b3ad24f95a 100644 --- a/include/asm-ppc64/iSeries/ItVpdAreas.h +++ b/include/asm-ppc64/iSeries/ItVpdAreas.h @@ -61,12 +61,6 @@ #define ItVpdAreasMaxSlotLabels 192 -struct SlicVpdAdrs { - u32 pad1; - void *vpdAddr; -}; - - struct ItVpdAreas { u32 xSlicDesc; // Descriptor 000-003 u16 xSlicSize; // Size of this control block 004-005 -- cgit v1.2.3-59-g8ed1b From ea7190d0afebbd922eeb13ee6a8148b17964b1b2 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:42 -0700 Subject: [PATCH] ppc64 iSeries: remove iSeries_pci_reset.c The file arch/ppc64/kernel/iSeries_pci_reset contains only one function that is not use anywhere (any more). Remove it. This function is the only user of the ReturnCode member of iSeries_Device_Node, so remove that as well. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/Makefile | 2 +- arch/ppc64/kernel/iSeries_pci_reset.c | 104 -------------------------------- include/asm-ppc64/iSeries/iSeries_pci.h | 3 - 3 files changed, 1 insertion(+), 108 deletions(-) delete mode 100644 arch/ppc64/kernel/iSeries_pci_reset.c diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 96d90b0c5119..9132d927171f 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -16,7 +16,7 @@ obj-y += vdso32/ vdso64/ obj-$(CONFIG_PPC_OF) += of_device.o -pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o iSeries_pci_reset.o +pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) diff --git a/arch/ppc64/kernel/iSeries_pci_reset.c b/arch/ppc64/kernel/iSeries_pci_reset.c deleted file mode 100644 index 0f785e4584f7..000000000000 --- a/arch/ppc64/kernel/iSeries_pci_reset.c +++ /dev/null @@ -1,104 +0,0 @@ -#define PCIFR(...) -/************************************************************************/ -/* File iSeries_pci_reset.c created by Allan Trautman on Mar 21 2001. */ -/************************************************************************/ -/* This code supports the pci interface on the IBM iSeries systems. */ -/* Copyright (C) 20yy */ -/* */ -/* 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 */ -/************************************************************************/ -/* Change Activity: */ -/* Created, March 20, 2001 */ -/* April 30, 2001, Added return codes on functions. */ -/* September 10, 2001, Ported to ppc64. */ -/* End Change Activity */ -/************************************************************************/ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include "pci.h" - -/* - * Interface to toggle the reset line - * Time is in .1 seconds, need for seconds. - */ -int iSeries_Device_ToggleReset(struct pci_dev *PciDev, int AssertTime, - int DelayTime) -{ - unsigned int AssertDelay, WaitDelay; - struct iSeries_Device_Node *DeviceNode = - (struct iSeries_Device_Node *)PciDev->sysdata; - - if (DeviceNode == NULL) { - printk("PCI: Pci Reset Failed, Device Node not found for pci_dev %p\n", - PciDev); - return -1; - } - /* - * Set defaults, Assert is .5 second, Wait is 3 seconds. - */ - if (AssertTime == 0) - AssertDelay = 500; - else - AssertDelay = AssertTime * 100; - - if (DelayTime == 0) - WaitDelay = 3000; - else - WaitDelay = DelayTime * 100; - - /* - * Assert reset - */ - DeviceNode->ReturnCode = HvCallPci_setSlotReset(ISERIES_BUS(DeviceNode), - 0x00, DeviceNode->AgentId, 1); - if (DeviceNode->ReturnCode == 0) { - msleep(AssertDelay); /* Sleep for the time */ - DeviceNode->ReturnCode = - HvCallPci_setSlotReset(ISERIES_BUS(DeviceNode), - 0x00, DeviceNode->AgentId, 0); - - /* - * Wait for device to reset - */ - msleep(WaitDelay); - } - if (DeviceNode->ReturnCode == 0) - PCIFR("Slot 0x%04X.%02 Reset\n", ISERIES_BUS(DeviceNode), - DeviceNode->AgentId); - else { - printk("PCI: Slot 0x%04X.%02X Reset Failed, RCode: %04X\n", - ISERIES_BUS(DeviceNode), DeviceNode->AgentId, - DeviceNode->ReturnCode); - PCIFR("Slot 0x%04X.%02X Reset Failed, RCode: %04X\n", - ISERIES_BUS(DeviceNode), DeviceNode->AgentId, - DeviceNode->ReturnCode); - } - return DeviceNode->ReturnCode; -} -EXPORT_SYMBOL(iSeries_Device_ToggleReset); diff --git a/include/asm-ppc64/iSeries/iSeries_pci.h b/include/asm-ppc64/iSeries/iSeries_pci.h index f45cd8a2e7be..4313a6684023 100644 --- a/include/asm-ppc64/iSeries/iSeries_pci.h +++ b/include/asm-ppc64/iSeries/iSeries_pci.h @@ -92,7 +92,6 @@ struct iSeries_Device_Node { int DevFn; /* Linux devfn */ int BarOffset; int Irq; /* Assigned IRQ */ - int ReturnCode; /* Return Code Holder */ int IoRetry; /* Current Retry Count */ int Flags; /* Possible flags(disable/bist)*/ u16 Vendor; /* Vendor ID */ @@ -107,7 +106,5 @@ struct iSeries_Device_Node { extern int iSeries_Device_Information(struct pci_dev*, char*, int); extern void iSeries_Get_Location_Code(struct iSeries_Device_Node*); -extern int iSeries_Device_ToggleReset(struct pci_dev* PciDev, - int AssertTime, int DelayTime); #endif /* _ISERIES_64_PCI_H */ -- cgit v1.2.3-59-g8ed1b From e7eb22d201936fb3450fa5d1d30cbf2de2fb918b Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:44 -0700 Subject: [PATCH] ppc64 iSeries: iommu.h cleanups The iommu_table_cb structure is iSeries specific, so move it to the header file that declares the function we pass it to. vio_tce_table and iommu_setup_iSeries no longer exist, so remove their declarations. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-ppc64/iSeries/HvCallXm.h | 17 +++++++++++++++++ include/asm-ppc64/iommu.h | 21 --------------------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/include/asm-ppc64/iSeries/HvCallXm.h b/include/asm-ppc64/iSeries/HvCallXm.h index 1362a425913f..8b9ba608daaf 100644 --- a/include/asm-ppc64/iSeries/HvCallXm.h +++ b/include/asm-ppc64/iSeries/HvCallXm.h @@ -16,6 +16,23 @@ #define HvCallXmSetTce HvCallXm + 11 #define HvCallXmSetTces HvCallXm + 13 +/* + * Structure passed to HvCallXm_getTceTableParms + */ +struct iommu_table_cb { + unsigned long itc_busno; /* Bus number for this tce table */ + unsigned long itc_start; /* Will be NULL for secondary */ + unsigned long itc_totalsize; /* Size (in pages) of whole table */ + unsigned long itc_offset; /* Index into real tce table of the + start of our section */ + unsigned long itc_size; /* Size (in pages) of our section */ + unsigned long itc_index; /* Index of this tce table */ + unsigned short itc_maxtables; /* Max num of tables for partition */ + unsigned char itc_virtbus; /* Flag to indicate virtual bus */ + unsigned char itc_slotno; /* IOA Tce Slot Index */ + unsigned char itc_rsvd[4]; +}; + static inline void HvCallXm_getTceTableParms(u64 cb) { HvCall1(HvCallXmGetTceTableParms, cb); diff --git a/include/asm-ppc64/iommu.h b/include/asm-ppc64/iommu.h index bd53ca4dcfa2..d9b53374d23a 100644 --- a/include/asm-ppc64/iommu.h +++ b/include/asm-ppc64/iommu.h @@ -82,24 +82,6 @@ struct iommu_table { unsigned long *it_map; /* A simple allocation bitmap for now */ }; -#ifdef CONFIG_PPC_ISERIES -struct iommu_table_cb { - unsigned long itc_busno; /* Bus number for this tce table */ - unsigned long itc_start; /* Will be NULL for secondary */ - unsigned long itc_totalsize; /* Size (in pages) of whole table */ - unsigned long itc_offset; /* Index into real tce table of the - start of our section */ - unsigned long itc_size; /* Size (in pages) of our section */ - unsigned long itc_index; /* Index of this tce table */ - unsigned short itc_maxtables; /* Max num of tables for partition */ - unsigned char itc_virtbus; /* Flag to indicate virtual bus */ - unsigned char itc_slotno; /* IOA Tce Slot Index */ - unsigned char itc_rsvd[4]; -}; - -extern struct iommu_table vio_tce_table; /* Tce table for virtual bus */ -#endif /* CONFIG_PPC_ISERIES */ - struct scatterlist; #ifdef CONFIG_PPC_MULTIPLATFORM @@ -122,9 +104,6 @@ extern void iommu_devnode_init_pSeries(struct device_node *dn); #ifdef CONFIG_PPC_ISERIES -/* Walks all buses and creates iommu tables */ -extern void iommu_setup_iSeries(void); - /* Initializes tables for bio buses */ extern void __init iommu_vio_init(void); -- cgit v1.2.3-59-g8ed1b From 57ca86d4f0e44f81be10bc77a5d0e26760e4844f Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:45 -0700 Subject: [PATCH] ppc64 iSeries: iSeries_VpdInfo.c cleanups Clean up iSeries_VpdInfo.c: - white space and comment fixes - make a function static - the functions here are only called from iSeries_pci.c, so CONFIG_PCI will be set (so remove check) - only build when CONFIG_PCI is set - remove unneeded includes and cast Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/Makefile | 5 +-- arch/ppc64/kernel/iSeries_VpdInfo.c | 84 ++++++++++++++++++------------------- 2 files changed, 43 insertions(+), 46 deletions(-) diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 9132d927171f..ada9be84ddee 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -16,13 +16,12 @@ obj-y += vdso32/ vdso64/ obj-$(CONFIG_PPC_OF) += of_device.o -pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o +pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o iSeries_VpdInfo.o pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) -obj-$(CONFIG_PPC_ISERIES) += iSeries_irq.o \ - iSeries_VpdInfo.o XmPciLpEvent.o \ +obj-$(CONFIG_PPC_ISERIES) += iSeries_irq.o XmPciLpEvent.o \ HvCall.o HvLpConfig.o LparData.o \ iSeries_setup.o ItLpQueue.o hvCall.o \ mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \ diff --git a/arch/ppc64/kernel/iSeries_VpdInfo.c b/arch/ppc64/kernel/iSeries_VpdInfo.c index a82caf98d2e3..9c89ce9a3d0b 100644 --- a/arch/ppc64/kernel/iSeries_VpdInfo.c +++ b/arch/ppc64/kernel/iSeries_VpdInfo.c @@ -1,31 +1,31 @@ -/************************************************************************/ -/* File iSeries_vpdInfo.c created by Allan Trautman on Fri Feb 2 2001. */ -/************************************************************************/ -/* This code gets the card location of the hardware */ -/* Copyright (C) 20yy */ -/* */ -/* 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 */ -/************************************************************************/ -/* Change Activity: */ -/* Created, Feb 2, 2001 */ -/* Ported to ppc64, August 20, 2001 */ -/* End Change Activity */ -/************************************************************************/ -#include +/* + * File iSeries_vpdInfo.c created by Allan Trautman on Fri Feb 2 2001. + * + * This code gets the card location of the hardware + * Copyright (C) 2001 + * Copyright (C) 2005 Stephen Rothwel, IBM Corp + * + * 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 + * + * Change Activity: + * Created, Feb 2, 2001 + * Ported to ppc64, August 20, 2001 + * End Change Activity + */ #include #include #include @@ -34,14 +34,13 @@ #include #include -#include #include -#include "pci.h" /* * Size of Bus VPD data */ #define BUS_VPDSIZE 1024 + /* * Bus Vpd Tags */ @@ -49,6 +48,7 @@ #define VpdEndOfAreaTag 0x79 #define VpdIdStringTag 0x82 #define VpdVendorAreaTag 0x84 + /* * Mfg Area Tags */ @@ -78,7 +78,7 @@ struct SlotMapStruct { char CardLocation[3]; char Parms[8]; char Reserved[2]; -}; +}; typedef struct SlotMapStruct SlotMap; #define SLOT_ENTRY_SIZE 16 @@ -111,28 +111,26 @@ int iSeries_Device_Information(struct pci_dev *PciDev, char *buffer, PciDev->vendor); len += sprintf(buffer + len, "Frame%3d, Card %4s ", DevNode->FrameId, DevNode->CardLocation); -#ifdef CONFIG_PCI if (pci_class_name(PciDev->class >> 8) == 0) len += sprintf(buffer + len, "0x%04X ", (int)(PciDev->class >> 8)); else len += sprintf(buffer + len, "%s", pci_class_name(PciDev->class >> 8)); -#endif return len; } /* * Parse the Slot Area */ -void iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen, +static void iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen, struct iSeries_Device_Node *DevNode) { int SlotMapLen = MapLen; SlotMap *SlotMapPtr = MapPtr; /* - * Parse Slot label until we find the one requrested + * Parse Slot label until we find the one requested */ while (SlotMapLen > 0) { if (SlotMapPtr->AgentId == DevNode->AgentId ) { @@ -182,7 +180,7 @@ static void iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, if (SlotMapFmt == 0x1004) SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr + MFG_ENTRY_SIZE + 1); - else + else SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr + MFG_ENTRY_SIZE); iSeries_Parse_SlotArea(SlotMapPtr, MfgTagLen, DevNode); @@ -193,8 +191,8 @@ static void iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, */ MfgAreaPtr = (MfgArea *)((char *)MfgAreaPtr + MfgTagLen + MFG_ENTRY_SIZE); - MfgAreaLen -= (MfgTagLen + MFG_ENTRY_SIZE); - } + MfgAreaLen -= (MfgTagLen + MFG_ENTRY_SIZE); + } } /* @@ -205,7 +203,7 @@ static int iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength) { u8 *PhbPtr = AreaPtr; int DataLen = AreaLength; - char PhbId = 0xFF; + char PhbId = 0xFF; while (DataLen > 0) { if ((*PhbPtr == 'B') && (*(PhbPtr + 1) == 'U') @@ -215,7 +213,7 @@ static int iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength) ++PhbPtr; PhbId = (*PhbPtr & 0x0F); break; - } + } ++PhbPtr; --DataLen; } @@ -232,7 +230,7 @@ static void iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen, int DataLen = VpdDataLen - 3; while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) { - int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256); + int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256); u8 *AreaData = TagPtr + 3; if (*TagPtr == VpdIdStringTag) @@ -243,12 +241,12 @@ static void iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen, TagPtr = AreaData + AreaLen; DataLen -= AreaLen; } -} +} void iSeries_Get_Location_Code(struct iSeries_Device_Node *DevNode) { int BusVpdLen = 0; - u8 *BusVpdPtr = (u8 *)kmalloc(BUS_VPDSIZE, GFP_KERNEL); + u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL); if (BusVpdPtr == NULL) { printk("PCI: Bus VPD Buffer allocation failure.\n"); -- cgit v1.2.3-59-g8ed1b From aab41dea80b1b00e66533af096f797320be05f13 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:46 -0700 Subject: [PATCH] ppc64 iSeries: iSeries_pci.h cleanups Remove no longer used things from iSeries_pci.h. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/iSeries_pci.c | 1 - include/asm-ppc64/iSeries/iSeries_pci.h | 17 +---------------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/arch/ppc64/kernel/iSeries_pci.c b/arch/ppc64/kernel/iSeries_pci.c index 1bff515bd298..1313a7a2f005 100644 --- a/arch/ppc64/kernel/iSeries_pci.c +++ b/arch/ppc64/kernel/iSeries_pci.c @@ -497,7 +497,6 @@ static int scan_bridge_slot(HvBusNumber Bus, ++DeviceCount; node = build_device_node(Bus, SubBus, EADsIdSel, Function); - node->Vendor = VendorId; node->Irq = Irq; node->LogicalSlot = BridgeInfo->logicalSlotNumber; diff --git a/include/asm-ppc64/iSeries/iSeries_pci.h b/include/asm-ppc64/iSeries/iSeries_pci.h index 4313a6684023..5d127cf29bf5 100644 --- a/include/asm-ppc64/iSeries/iSeries_pci.h +++ b/include/asm-ppc64/iSeries/iSeries_pci.h @@ -44,8 +44,7 @@ struct iSeries_Device_Node; #define ISERIES_SUBBUS(DevPtr) DevPtr->DsaAddr.Dsa.subBusNumber #define ISERIES_DEVICE(DevPtr) DevPtr->DsaAddr.Dsa.deviceId #define ISERIES_DSA(DevPtr) DevPtr->DsaAddr.DsaAddr -#define ISERIES_DEVFUN(DevPtr) DevPtr->DevFn -#define ISERIES_DEVNODE(PciDev) ((struct iSeries_Device_Node*)PciDev->sysdata) +#define ISERIES_DEVNODE(PciDev) ((struct iSeries_Device_Node *)PciDev->sysdata) #define EADsMaxAgents 7 @@ -62,17 +61,6 @@ struct iSeries_Device_Node; #define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus) ((subbus >> 5) & 0x7) #define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus) ((subbus >> 2) & 0x7) -/* - * N.B. the ISERIES_DECODE_* macros are not used anywhere, and I think - * the 0x71 (at least) must be wrong - 0x78 maybe? -- paulus. - */ -#define ISERIES_DECODE_DEVFN(linuxdevfn) \ - (((linuxdevfn & 0x71) << 1) | (linuxdevfn & 0x07)) -#define ISERIES_DECODE_DEVICE(linuxdevfn) \ - (((linuxdevfn & 0x38) >> 3) | (((linuxdevfn & 0x40) >> 2) + 0x10)) -#define ISERIES_DECODE_FUNCTION(linuxdevfn) \ - (linuxdevfn & 0x07) - /* * Converts Virtual Address to Real Address for Hypervisor calls */ @@ -90,15 +78,12 @@ struct iSeries_Device_Node { /* deviceId, barNumber */ HvAgentId AgentId; /* Hypervisor DevFn */ int DevFn; /* Linux devfn */ - int BarOffset; int Irq; /* Assigned IRQ */ int IoRetry; /* Current Retry Count */ int Flags; /* Possible flags(disable/bist)*/ - u16 Vendor; /* Vendor ID */ u8 LogicalSlot; /* Hv Slot Index for Tces */ struct iommu_table *iommu_table;/* Device TCE Table */ u8 PhbId; /* Phb Card is on. */ - u16 Board; /* Board Number */ u8 FrameId; /* iSeries spcn Frame Id */ char CardLocation[4];/* Char format of planar vpd */ char Location[20]; /* Frame 1, Card C10 */ -- cgit v1.2.3-59-g8ed1b From a2ebaf250fabc5c5644b707dbee44c9e0ec442e9 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:47 -0700 Subject: [PATCH] ppc64 iSeries: remove IoRetry from iSeries_Device_Node The IoRetry member of iSeries_Devide_Node is really only used locally, so remove it and replace it with a local variable. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/iSeries_pci.c | 35 +++++++++++++++++---------------- include/asm-ppc64/iSeries/iSeries_pci.h | 1 - 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/arch/ppc64/kernel/iSeries_pci.c b/arch/ppc64/kernel/iSeries_pci.c index 1313a7a2f005..0a28b6ca65d0 100644 --- a/arch/ppc64/kernel/iSeries_pci.c +++ b/arch/ppc64/kernel/iSeries_pci.c @@ -225,7 +225,6 @@ static struct iSeries_Device_Node *build_device_node(HvBusNumber Bus, node->DsaAddr.Dsa.deviceId = 0x10; node->AgentId = AgentId; node->DevFn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function); - node->IoRetry = 0; iSeries_Get_Location_Code(node); return node; } @@ -658,38 +657,34 @@ static struct pci_ops iSeries_pci_ops = { * Check Return Code * -> On Failure, print and log information. * Increment Retry Count, if exceeds max, panic partition. - * -> If in retry, print and log success * * PCI: Device 23.90 ReadL I/O Error( 0): 0x1234 * PCI: Device 23.90 ReadL Retry( 1) * PCI: Device 23.90 ReadL Retry Successful(1) */ static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode, - u64 ret) + int *retry, u64 ret) { if (ret != 0) { ++Pci_Error_Count; - ++DevNode->IoRetry; + (*retry)++; printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n", TextHdr, DevNode->DsaAddr.Dsa.busNumber, DevNode->DevFn, - DevNode->IoRetry, (int)ret); + *retry, (int)ret); /* * Bump the retry and check for retry count exceeded. * If, Exceeded, panic the system. */ - if ((DevNode->IoRetry > Pci_Retry_Max) && + if (((*retry) > Pci_Retry_Max) && (Pci_Error_Flag > 0)) { mf_display_src(0xB6000103); - panic_timeout = 0; + panic_timeout = 0; panic("PCI: Hardware I/O Error, SRC B6000103, " "Automatic Reboot Disabled.\n"); } return -1; /* Retry Try */ } - /* If retry was in progress, log success and rest retry count */ - if (DevNode->IoRetry > 0) - DevNode->IoRetry = 0; - return 0; + return 0; } /* @@ -735,6 +730,7 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) { u64 BarOffset; u64 dsa; + int retry = 0; struct HvCallPci_LoadReturn ret; struct iSeries_Device_Node *DevNode = xlate_iomm_address(IoAddress, &dsa, &BarOffset); @@ -754,7 +750,7 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) do { ++Pci_Io_Read_Count; HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0); - } while (CheckReturnCode("RDB", DevNode, ret.rc) != 0); + } while (CheckReturnCode("RDB", DevNode, &retry, ret.rc) != 0); return (u8)ret.value; } @@ -764,6 +760,7 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) { u64 BarOffset; u64 dsa; + int retry = 0; struct HvCallPci_LoadReturn ret; struct iSeries_Device_Node *DevNode = xlate_iomm_address(IoAddress, &dsa, &BarOffset); @@ -784,7 +781,7 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) ++Pci_Io_Read_Count; HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa, BarOffset, 0); - } while (CheckReturnCode("RDW", DevNode, ret.rc) != 0); + } while (CheckReturnCode("RDW", DevNode, &retry, ret.rc) != 0); return swab16((u16)ret.value); } @@ -794,6 +791,7 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) { u64 BarOffset; u64 dsa; + int retry = 0; struct HvCallPci_LoadReturn ret; struct iSeries_Device_Node *DevNode = xlate_iomm_address(IoAddress, &dsa, &BarOffset); @@ -814,7 +812,7 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) ++Pci_Io_Read_Count; HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa, BarOffset, 0); - } while (CheckReturnCode("RDL", DevNode, ret.rc) != 0); + } while (CheckReturnCode("RDL", DevNode, &retry, ret.rc) != 0); return swab32((u32)ret.value); } @@ -831,6 +829,7 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) { u64 BarOffset; u64 dsa; + int retry = 0; u64 rc; struct iSeries_Device_Node *DevNode = xlate_iomm_address(IoAddress, &dsa, &BarOffset); @@ -850,7 +849,7 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) do { ++Pci_Io_Write_Count; rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0); - } while (CheckReturnCode("WWB", DevNode, rc) != 0); + } while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0); } EXPORT_SYMBOL(iSeries_Write_Byte); @@ -858,6 +857,7 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) { u64 BarOffset; u64 dsa; + int retry = 0; u64 rc; struct iSeries_Device_Node *DevNode = xlate_iomm_address(IoAddress, &dsa, &BarOffset); @@ -877,7 +877,7 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) do { ++Pci_Io_Write_Count; rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0); - } while (CheckReturnCode("WWW", DevNode, rc) != 0); + } while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0); } EXPORT_SYMBOL(iSeries_Write_Word); @@ -885,6 +885,7 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) { u64 BarOffset; u64 dsa; + int retry = 0; u64 rc; struct iSeries_Device_Node *DevNode = xlate_iomm_address(IoAddress, &dsa, &BarOffset); @@ -904,6 +905,6 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) do { ++Pci_Io_Write_Count; rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0); - } while (CheckReturnCode("WWL", DevNode, rc) != 0); + } while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0); } EXPORT_SYMBOL(iSeries_Write_Long); diff --git a/include/asm-ppc64/iSeries/iSeries_pci.h b/include/asm-ppc64/iSeries/iSeries_pci.h index 5d127cf29bf5..ee0212f18b99 100644 --- a/include/asm-ppc64/iSeries/iSeries_pci.h +++ b/include/asm-ppc64/iSeries/iSeries_pci.h @@ -79,7 +79,6 @@ struct iSeries_Device_Node { HvAgentId AgentId; /* Hypervisor DevFn */ int DevFn; /* Linux devfn */ int Irq; /* Assigned IRQ */ - int IoRetry; /* Current Retry Count */ int Flags; /* Possible flags(disable/bist)*/ u8 LogicalSlot; /* Hv Slot Index for Tces */ struct iommu_table *iommu_table;/* Device TCE Table */ -- cgit v1.2.3-59-g8ed1b From 061c063efce96b33f9e26d5f83a8eb0643fa493c Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:48 -0700 Subject: [PATCH] ppc64 iSeries: remove some more members of iSeries_Device_Node The AgentId, PhbId, FrameId, CardLocation and Location members of iSeries_Device_Node are stored early in the boot process just so that a message about the device can be printed later in the boot process. Remove them and construct the message by doing the VPD parsing at the time the message is printed. Also remove a few unused defines in iSeries_VpdInfo.c. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/iSeries_VpdInfo.c | 137 ++++++++++++++++---------------- arch/ppc64/kernel/iSeries_pci.c | 7 +- include/asm-ppc64/iSeries/iSeries_pci.h | 8 +- 3 files changed, 69 insertions(+), 83 deletions(-) diff --git a/arch/ppc64/kernel/iSeries_VpdInfo.c b/arch/ppc64/kernel/iSeries_VpdInfo.c index 9c89ce9a3d0b..d11c732daf81 100644 --- a/arch/ppc64/kernel/iSeries_VpdInfo.c +++ b/arch/ppc64/kernel/iSeries_VpdInfo.c @@ -44,7 +44,6 @@ /* * Bus Vpd Tags */ -#define VpdEndOfDataTag 0x78 #define VpdEndOfAreaTag 0x79 #define VpdIdStringTag 0x82 #define VpdVendorAreaTag 0x84 @@ -52,11 +51,8 @@ /* * Mfg Area Tags */ -#define VpdFruFlag 0x4647 // "FG" #define VpdFruFrameId 0x4649 // "FI" #define VpdSlotMapFormat 0x4D46 // "MF" -#define VpdAsmPartNumber 0x504E // "PN" -#define VpdFruSerial 0x534E // "SN" #define VpdSlotMap 0x534D // "SM" /* @@ -82,49 +78,11 @@ struct SlotMapStruct { typedef struct SlotMapStruct SlotMap; #define SLOT_ENTRY_SIZE 16 -/* - * Formats the device information. - * - Pass in pci_dev* pointer to the device. - * - Pass in buffer to place the data. Danger here is the buffer must - * be as big as the client says it is. Should be at least 128 bytes. - * Return will the length of the string data put in the buffer. - * Format: - * PCI: Bus 0, Device 26, Vendor 0x12AE Frame 1, Card C10 Ethernet - * controller - */ -int iSeries_Device_Information(struct pci_dev *PciDev, char *buffer, - int BufferSize) -{ - struct iSeries_Device_Node *DevNode = - (struct iSeries_Device_Node *)PciDev->sysdata; - int len; - - if (DevNode == NULL) - return sprintf(buffer, - "PCI: iSeries_Device_Information DevNode is NULL"); - - if (BufferSize < 128) - return 0; - - len = sprintf(buffer, "PCI: Bus%3d, Device%3d, Vendor %04X ", - ISERIES_BUS(DevNode), PCI_SLOT(PciDev->devfn), - PciDev->vendor); - len += sprintf(buffer + len, "Frame%3d, Card %4s ", - DevNode->FrameId, DevNode->CardLocation); - if (pci_class_name(PciDev->class >> 8) == 0) - len += sprintf(buffer + len, "0x%04X ", - (int)(PciDev->class >> 8)); - else - len += sprintf(buffer + len, "%s", - pci_class_name(PciDev->class >> 8)); - return len; -} - /* * Parse the Slot Area */ -static void iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen, - struct iSeries_Device_Node *DevNode) +static void __init iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen, + HvAgentId agent, u8 *PhbId, char card[4]) { int SlotMapLen = MapLen; SlotMap *SlotMapPtr = MapPtr; @@ -133,17 +91,16 @@ static void iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen, * Parse Slot label until we find the one requested */ while (SlotMapLen > 0) { - if (SlotMapPtr->AgentId == DevNode->AgentId ) { + if (SlotMapPtr->AgentId == agent) { /* * If Phb wasn't found, grab the entry first one found. */ - if (DevNode->PhbId == 0xff) - DevNode->PhbId = SlotMapPtr->PhbId; + if (*PhbId == 0xff) + *PhbId = SlotMapPtr->PhbId; /* Found it, extract the data. */ - if (SlotMapPtr->PhbId == DevNode->PhbId ) { - memcpy(&DevNode->CardLocation, - &SlotMapPtr->CardLocation, 3); - DevNode->CardLocation[3] = 0; + if (SlotMapPtr->PhbId == *PhbId) { + memcpy(card, &SlotMapPtr->CardLocation, 3); + card[3] = 0; break; } } @@ -156,8 +113,9 @@ static void iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen, /* * Parse the Mfg Area */ -static void iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, - struct iSeries_Device_Node *DevNode) +static void __init iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, + HvAgentId agent, u8 *PhbId, + u8 *frame, char card[4]) { MfgArea *MfgAreaPtr = (MfgArea *)AreaData; int MfgAreaLen = AreaLen; @@ -168,7 +126,7 @@ static void iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, int MfgTagLen = MfgAreaPtr->TagLength; /* Frame ID (FI 4649020310 ) */ if (MfgAreaPtr->Tag == VpdFruFrameId) /* FI */ - DevNode->FrameId = MfgAreaPtr->AreaData1; + *frame = MfgAreaPtr->AreaData1; /* Slot Map Format (MF 4D46020004 ) */ else if (MfgAreaPtr->Tag == VpdSlotMapFormat) /* MF */ SlotMapFmt = (MfgAreaPtr->AreaData1 * 256) @@ -183,7 +141,8 @@ static void iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, else SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr + MFG_ENTRY_SIZE); - iSeries_Parse_SlotArea(SlotMapPtr, MfgTagLen, DevNode); + iSeries_Parse_SlotArea(SlotMapPtr, MfgTagLen, + agent, PhbId, card); } /* * Point to the next Mfg Area @@ -199,7 +158,7 @@ static void iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, * Look for "BUS".. Data is not Null terminated. * PHBID of 0xFF indicates PHB was not found in VPD Data. */ -static int iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength) +static int __init iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength) { u8 *PhbPtr = AreaPtr; int DataLen = AreaLength; @@ -223,27 +182,30 @@ static int iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength) /* * Parse out the VPD Areas */ -static void iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen, - struct iSeries_Device_Node *DevNode) +static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen, + HvAgentId agent, u8 *frame, char card[4]) { u8 *TagPtr = VpdData; int DataLen = VpdDataLen - 3; + u8 PhbId; while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) { int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256); u8 *AreaData = TagPtr + 3; if (*TagPtr == VpdIdStringTag) - DevNode->PhbId = iSeries_Parse_PhbId(AreaData, AreaLen); + PhbId = iSeries_Parse_PhbId(AreaData, AreaLen); else if (*TagPtr == VpdVendorAreaTag) - iSeries_Parse_MfgArea(AreaData, AreaLen, DevNode); + iSeries_Parse_MfgArea(AreaData, AreaLen, + agent, &PhbId, frame, card); /* Point to next Area. */ TagPtr = AreaData + AreaLen; DataLen -= AreaLen; } } -void iSeries_Get_Location_Code(struct iSeries_Device_Node *DevNode) +static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent, + u8 *frame, char card[4]) { int BusVpdLen = 0; u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL); @@ -252,23 +214,58 @@ void iSeries_Get_Location_Code(struct iSeries_Device_Node *DevNode) printk("PCI: Bus VPD Buffer allocation failure.\n"); return; } - BusVpdLen = HvCallPci_getBusVpd(ISERIES_BUS(DevNode), - ISERIES_HV_ADDR(BusVpdPtr), + BusVpdLen = HvCallPci_getBusVpd(bus, ISERIES_HV_ADDR(BusVpdPtr), BUS_VPDSIZE); if (BusVpdLen == 0) { - kfree(BusVpdPtr); printk("PCI: Bus VPD Buffer zero length.\n"); - return; + goto out_free; } /* printk("PCI: BusVpdPtr: %p, %d\n",BusVpdPtr, BusVpdLen); */ /* Make sure this is what I think it is */ if (*BusVpdPtr != VpdIdStringTag) { /* 0x82 */ printk("PCI: Bus VPD Buffer missing starting tag.\n"); - kfree(BusVpdPtr); - return; + goto out_free; } - iSeries_Parse_Vpd(BusVpdPtr,BusVpdLen, DevNode); - sprintf(DevNode->Location, "Frame%3d, Card %-4s", DevNode->FrameId, - DevNode->CardLocation); + iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card); +out_free: kfree(BusVpdPtr); } + +/* + * Prints the device information. + * - Pass in pci_dev* pointer to the device. + * - Pass in the device count + * + * Format: + * PCI: Bus 0, Device 26, Vendor 0x12AE Frame 1, Card C10 Ethernet + * controller + */ +void __init iSeries_Device_Information(struct pci_dev *PciDev, int count) +{ + struct iSeries_Device_Node *DevNode = PciDev->sysdata; + u16 bus; + u8 frame; + char card[4]; + HvSubBusNumber subbus; + HvAgentId agent; + + if (DevNode == NULL) { + printk("%d. PCI: iSeries_Device_Information DevNode is NULL\n", + count); + return; + } + + bus = ISERIES_BUS(DevNode); + subbus = ISERIES_SUBBUS(DevNode); + agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus), + ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus)); + iSeries_Get_Location_Code(bus, agent, &frame, card); + + printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, Card %4s ", + count, bus, PCI_SLOT(PciDev->devfn), PciDev->vendor, + frame, card); + if (pci_class_name(PciDev->class >> 8) == 0) + printk("0x%04X\n", (int)(PciDev->class >> 8)); + else + printk("%s\n", pci_class_name(PciDev->class >> 8)); +} diff --git a/arch/ppc64/kernel/iSeries_pci.c b/arch/ppc64/kernel/iSeries_pci.c index 0a28b6ca65d0..356e4fd9a94f 100644 --- a/arch/ppc64/kernel/iSeries_pci.c +++ b/arch/ppc64/kernel/iSeries_pci.c @@ -223,9 +223,7 @@ static struct iSeries_Device_Node *build_device_node(HvBusNumber Bus, node->DsaAddr.Dsa.busNumber = Bus; node->DsaAddr.Dsa.subBusNumber = SubBus; node->DsaAddr.Dsa.deviceId = 0x10; - node->AgentId = AgentId; node->DevFn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function); - iSeries_Get_Location_Code(node); return node; } @@ -299,7 +297,6 @@ void __init iSeries_pci_final_fixup(void) { struct pci_dev *pdev = NULL; struct iSeries_Device_Node *node; - char Buffer[256]; int DeviceCount = 0; PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n"); @@ -321,9 +318,7 @@ void __init iSeries_pci_final_fixup(void) "pdev 0x%p <==> DevNode 0x%p\n", pdev, node); allocate_device_bars(pdev); - iSeries_Device_Information(pdev, Buffer, - sizeof(Buffer)); - printk("%d. %s\n", DeviceCount, Buffer); + iSeries_Device_Information(pdev, DeviceCount); iommu_devnode_init_iSeries(node); } else printk("PCI: Device Tree not found for 0x%016lX\n", diff --git a/include/asm-ppc64/iSeries/iSeries_pci.h b/include/asm-ppc64/iSeries/iSeries_pci.h index ee0212f18b99..575f611f8b33 100644 --- a/include/asm-ppc64/iSeries/iSeries_pci.h +++ b/include/asm-ppc64/iSeries/iSeries_pci.h @@ -76,19 +76,13 @@ struct iSeries_Device_Node { union HvDsaMap DsaAddr; /* Direct Select Address */ /* busNumber, subBusNumber, */ /* deviceId, barNumber */ - HvAgentId AgentId; /* Hypervisor DevFn */ int DevFn; /* Linux devfn */ int Irq; /* Assigned IRQ */ int Flags; /* Possible flags(disable/bist)*/ u8 LogicalSlot; /* Hv Slot Index for Tces */ struct iommu_table *iommu_table;/* Device TCE Table */ - u8 PhbId; /* Phb Card is on. */ - u8 FrameId; /* iSeries spcn Frame Id */ - char CardLocation[4];/* Char format of planar vpd */ - char Location[20]; /* Frame 1, Card C10 */ }; -extern int iSeries_Device_Information(struct pci_dev*, char*, int); -extern void iSeries_Get_Location_Code(struct iSeries_Device_Node*); +extern void iSeries_Device_Information(struct pci_dev*, int); #endif /* _ISERIES_64_PCI_H */ -- cgit v1.2.3-59-g8ed1b From 0c3b4f1a8e06584d8a1051a74ed79cf8b41f703e Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:49 -0700 Subject: [PATCH] ppc64 iSeries: irq simple cleanups This patch is just simple cleanups to the iSeries irq code. - whitespace and comments - rearrange some functions to avoid forward declarations - remove XmPciLpEvent.h as its functions were declared elsewhere - remove decaration of function that no longer exists No semantic changes. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/XmPciLpEvent.c | 105 ++++++++++----------- arch/ppc64/kernel/iSeries_irq.c | 155 +++++++++++++++---------------- include/asm-ppc64/iSeries/XmPciLpEvent.h | 7 -- include/asm-ppc64/iSeries/iSeries_irq.h | 1 - 4 files changed, 123 insertions(+), 145 deletions(-) delete mode 100644 include/asm-ppc64/iSeries/XmPciLpEvent.h diff --git a/arch/ppc64/kernel/XmPciLpEvent.c b/arch/ppc64/kernel/XmPciLpEvent.c index 809c9bc6678b..3db530744831 100644 --- a/arch/ppc64/kernel/XmPciLpEvent.c +++ b/arch/ppc64/kernel/XmPciLpEvent.c @@ -1,9 +1,8 @@ /* - * File XmPciLpEvent.h created by Wayne Holm on Mon Jan 15 2001. + * File XmPciLpEvent.c created by Wayne Holm on Mon Jan 15 2001. * * This module handles PCI interrupt events sent by the iSeries Hypervisor. -*/ - + */ #include #include #include @@ -17,22 +16,22 @@ #include #include #include -#include +#include #include static long Pci_Interrupt_Count; static long Pci_Event_Count; enum XmPciLpEvent_Subtype { - XmPciLpEvent_BusCreated = 0, // PHB has been created - XmPciLpEvent_BusError = 1, // PHB has failed - XmPciLpEvent_BusFailed = 2, // Msg to Secondary, Primary failed bus - XmPciLpEvent_NodeFailed = 4, // Multi-adapter bridge has failed - XmPciLpEvent_NodeRecovered = 5, // Multi-adapter bridge has recovered - XmPciLpEvent_BusRecovered = 12, // PHB has been recovered - XmPciLpEvent_UnQuiesceBus = 18, // Secondary bus unqiescing - XmPciLpEvent_BridgeError = 21, // Bridge Error - XmPciLpEvent_SlotInterrupt = 22 // Slot interrupt + XmPciLpEvent_BusCreated = 0, // PHB has been created + XmPciLpEvent_BusError = 1, // PHB has failed + XmPciLpEvent_BusFailed = 2, // Msg to Secondary, Primary failed bus + XmPciLpEvent_NodeFailed = 4, // Multi-adapter bridge has failed + XmPciLpEvent_NodeRecovered = 5, // Multi-adapter bridge has recovered + XmPciLpEvent_BusRecovered = 12, // PHB has been recovered + XmPciLpEvent_UnQuiesceBus = 18, // Secondary bus unqiescing + XmPciLpEvent_BridgeError = 21, // Bridge Error + XmPciLpEvent_SlotInterrupt = 22 // Slot interrupt }; struct XmPciLpEvent_BusInterrupt { @@ -70,43 +69,6 @@ struct XmPciLpEvent { }; -static void intReceived(struct XmPciLpEvent *eventParm, - struct pt_regs *regsParm); - -static void XmPciLpEvent_handler(struct HvLpEvent *eventParm, - struct pt_regs *regsParm) -{ -#ifdef CONFIG_PCI -#if 0 - PPCDBG(PPCDBG_BUSWALK, "XmPciLpEvent_handler, type 0x%x\n", - eventParm->xType); -#endif - ++Pci_Event_Count; - - if (eventParm && (eventParm->xType == HvLpEvent_Type_PciIo)) { - switch (eventParm->xFlags.xFunction) { - case HvLpEvent_Function_Int: - intReceived((struct XmPciLpEvent *)eventParm, regsParm); - break; - case HvLpEvent_Function_Ack: - printk(KERN_ERR - "XmPciLpEvent.c: unexpected ack received\n"); - break; - default: - printk(KERN_ERR - "XmPciLpEvent.c: unexpected event function %d\n", - (int)eventParm->xFlags.xFunction); - break; - } - } else if (eventParm) - printk(KERN_ERR - "XmPciLpEvent.c: Unrecognized PCI event type 0x%x\n", - (int)eventParm->xType); - else - printk(KERN_ERR "XmPciLpEvent.c: NULL event received\n"); -#endif -} - static void intReceived(struct XmPciLpEvent *eventParm, struct pt_regs *regsParm) { @@ -164,6 +126,39 @@ static void intReceived(struct XmPciLpEvent *eventParm, } } +static void XmPciLpEvent_handler(struct HvLpEvent *eventParm, + struct pt_regs *regsParm) +{ +#ifdef CONFIG_PCI +#if 0 + PPCDBG(PPCDBG_BUSWALK, "XmPciLpEvent_handler, type 0x%x\n", + eventParm->xType); +#endif + ++Pci_Event_Count; + + if (eventParm && (eventParm->xType == HvLpEvent_Type_PciIo)) { + switch (eventParm->xFlags.xFunction) { + case HvLpEvent_Function_Int: + intReceived((struct XmPciLpEvent *)eventParm, regsParm); + break; + case HvLpEvent_Function_Ack: + printk(KERN_ERR + "XmPciLpEvent.c: unexpected ack received\n"); + break; + default: + printk(KERN_ERR + "XmPciLpEvent.c: unexpected event function %d\n", + (int)eventParm->xFlags.xFunction); + break; + } + } else if (eventParm) + printk(KERN_ERR + "XmPciLpEvent.c: Unrecognized PCI event type 0x%x\n", + (int)eventParm->xType); + else + printk(KERN_ERR "XmPciLpEvent.c: NULL event received\n"); +#endif +} /* This should be called sometime prior to buswalk (init_IRQ would be good) */ int XmPciLpEvent_init() @@ -179,12 +174,10 @@ int XmPciLpEvent_init() if (xRc == 0) { xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0); if (xRc != 0) - printk(KERN_ERR - "XmPciLpEvent.c: open event path failed with rc 0x%x\n", - xRc); + printk(KERN_ERR "XmPciLpEvent.c: open event path " + "failed with rc 0x%x\n", xRc); } else - printk(KERN_ERR - "XmPciLpEvent.c: register handler failed with rc 0x%x\n", - xRc); + printk(KERN_ERR "XmPciLpEvent.c: register handler " + "failed with rc 0x%x\n", xRc); return xRc; } diff --git a/arch/ppc64/kernel/iSeries_irq.c b/arch/ppc64/kernel/iSeries_irq.c index f831d259dbb7..41902e358e76 100644 --- a/arch/ppc64/kernel/iSeries_irq.c +++ b/arch/ppc64/kernel/iSeries_irq.c @@ -1,27 +1,27 @@ -/************************************************************************/ -/* This module supports the iSeries PCI bus interrupt handling */ -/* Copyright (C) 20yy */ -/* */ -/* 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 */ -/************************************************************************/ -/* Change Activity: */ -/* Created, December 13, 2000 by Wayne Holm */ -/* End Change Activity */ -/************************************************************************/ +/* + * This module supports the iSeries PCI bus interrupt handling + * Copyright (C) 20yy + * + * 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 + * + * Change Activity: + * Created, December 13, 2000 by Wayne Holm + * End Change Activity + */ #include #include #include @@ -38,22 +38,6 @@ #include #include #include -#include - -static unsigned int iSeries_startup_IRQ(unsigned int irq); -static void iSeries_shutdown_IRQ(unsigned int irq); -static void iSeries_enable_IRQ(unsigned int irq); -static void iSeries_disable_IRQ(unsigned int irq); -static void iSeries_end_IRQ(unsigned int irq); - -static hw_irq_controller iSeries_IRQ_handler = { - .typename = "iSeries irq controller", - .startup = iSeries_startup_IRQ, - .shutdown = iSeries_shutdown_IRQ, - .enable = iSeries_enable_IRQ, - .disable = iSeries_disable_IRQ, - .end = iSeries_end_IRQ -}; /* This maps virtual irq numbers to real irqs */ unsigned int virt_irq_to_real_map[NR_IRQS]; @@ -69,30 +53,32 @@ void __init iSeries_init_IRQ(void) XmPciLpEvent_init(); } +#define REAL_IRQ_TO_BUS(irq) ((((irq) >> 6) & 0xff) + 1) +#define REAL_IRQ_TO_IDSEL(irq) ((((irq) >> 3) & 7) + 1) +#define REAL_IRQ_TO_FUNC(irq) ((irq) & 7) + /* - * This is called out of iSeries_scan_slot to allocate an IRQ for an EADS slot - * It calculates the irq value for the slot. - * Note that subBusNumber is always 0 (at the moment at least). + * This will be called by device drivers (via enable_IRQ) + * to enable INTA in the bridge interrupt status register. */ -int __init iSeries_allocate_IRQ(HvBusNumber busNumber, - HvSubBusNumber subBusNumber, HvAgentId deviceId) +static void iSeries_enable_IRQ(unsigned int irq) { - unsigned int realirq, virtirq; - u8 idsel = (deviceId >> 4); - u8 function = deviceId & 7; + u32 bus, deviceId, function, mask; + const u32 subBus = 0; + unsigned int rirq = virt_irq_to_real_map[irq]; - virtirq = next_virtual_irq++; - realirq = ((busNumber - 1) << 6) + ((idsel - 1) << 3) + function; - virt_irq_to_real_map[virtirq] = realirq; + /* The IRQ has already been locked by the caller */ + bus = REAL_IRQ_TO_BUS(rirq); + function = REAL_IRQ_TO_FUNC(rirq); + deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function; - irq_desc[virtirq].handler = &iSeries_IRQ_handler; - return virtirq; + /* Unmask secondary INTA */ + mask = 0x80000000; + HvCallPci_unmaskInterrupts(bus, subBus, deviceId, mask); + PPCDBG(PPCDBG_BUSWALK, "iSeries_enable_IRQ 0x%02X.%02X.%02X 0x%04X\n", + bus, subBus, deviceId, irq); } -#define REAL_IRQ_TO_BUS(irq) ((((irq) >> 6) & 0xff) + 1) -#define REAL_IRQ_TO_IDSEL(irq) ((((irq) >> 3) & 7) + 1) -#define REAL_IRQ_TO_FUNC(irq) ((irq) & 7) - /* This is called by iSeries_activate_IRQs */ static unsigned int iSeries_startup_IRQ(unsigned int irq) { @@ -131,7 +117,7 @@ void __init iSeries_activate_IRQs() desc->handler->startup(irq); spin_unlock_irqrestore(&desc->lock, flags); } - } + } } /* this is not called anywhere currently */ @@ -173,29 +159,7 @@ static void iSeries_disable_IRQ(unsigned int irq) mask = 0x80000000; HvCallPci_maskInterrupts(bus, subBus, deviceId, mask); PPCDBG(PPCDBG_BUSWALK, "iSeries_disable_IRQ 0x%02X.%02X.%02X 0x%04X\n", - bus, subBus, deviceId, irq); -} - -/* - * This will be called by device drivers (via enable_IRQ) - * to enable INTA in the bridge interrupt status register. - */ -static void iSeries_enable_IRQ(unsigned int irq) -{ - u32 bus, deviceId, function, mask; - const u32 subBus = 0; - unsigned int rirq = virt_irq_to_real_map[irq]; - - /* The IRQ has already been locked by the caller */ - bus = REAL_IRQ_TO_BUS(rirq); - function = REAL_IRQ_TO_FUNC(rirq); - deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function; - - /* Unmask secondary INTA */ - mask = 0x80000000; - HvCallPci_unmaskInterrupts(bus, subBus, deviceId, mask); - PPCDBG(PPCDBG_BUSWALK, "iSeries_enable_IRQ 0x%02X.%02X.%02X 0x%04X\n", - bus, subBus, deviceId, irq); + bus, subBus, deviceId, irq); } /* @@ -207,3 +171,32 @@ static void iSeries_enable_IRQ(unsigned int irq) static void iSeries_end_IRQ(unsigned int irq) { } + +static hw_irq_controller iSeries_IRQ_handler = { + .typename = "iSeries irq controller", + .startup = iSeries_startup_IRQ, + .shutdown = iSeries_shutdown_IRQ, + .enable = iSeries_enable_IRQ, + .disable = iSeries_disable_IRQ, + .end = iSeries_end_IRQ +}; + +/* + * This is called out of iSeries_scan_slot to allocate an IRQ for an EADS slot + * It calculates the irq value for the slot. + * Note that subBusNumber is always 0 (at the moment at least). + */ +int __init iSeries_allocate_IRQ(HvBusNumber busNumber, + HvSubBusNumber subBusNumber, HvAgentId deviceId) +{ + unsigned int realirq, virtirq; + u8 idsel = (deviceId >> 4); + u8 function = deviceId & 7; + + virtirq = next_virtual_irq++; + realirq = ((busNumber - 1) << 6) + ((idsel - 1) << 3) + function; + virt_irq_to_real_map[virtirq] = realirq; + + irq_desc[virtirq].handler = &iSeries_IRQ_handler; + return virtirq; +} diff --git a/include/asm-ppc64/iSeries/XmPciLpEvent.h b/include/asm-ppc64/iSeries/XmPciLpEvent.h deleted file mode 100644 index 4936627b26d0..000000000000 --- a/include/asm-ppc64/iSeries/XmPciLpEvent.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __XMPCILPEVENT_H__ -#define __XMPCILPEVENT_H__ - -extern int XmPciLpEvent_init(void); -extern void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq); - -#endif /* __XMPCILPEVENT_H__ */ diff --git a/include/asm-ppc64/iSeries/iSeries_irq.h b/include/asm-ppc64/iSeries/iSeries_irq.h index fbd5f523ba1d..a7c5bceae8fa 100644 --- a/include/asm-ppc64/iSeries/iSeries_irq.h +++ b/include/asm-ppc64/iSeries/iSeries_irq.h @@ -3,7 +3,6 @@ extern void iSeries_init_IRQ(void); extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId); -extern int iSeries_assign_IRQ(int, HvBusNumber, HvSubBusNumber, HvAgentId); extern void iSeries_activate_IRQs(void); extern int XmPciLpEvent_init(void); -- cgit v1.2.3-59-g8ed1b From 89ef68f0be53df6c4f1552fc329fe5abb1d5ed33 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:50 -0700 Subject: [PATCH] ppc64 iSeries: remove XmPciLpEvent.c This patch just merges XmPciLpEvent.c into iSeries_irq.c (the only caller of its only external function). XmPciLpEvent.c just contained the lowlevel iSeries irq code. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/Makefile | 2 +- arch/ppc64/kernel/XmPciLpEvent.c | 183 --------------------------------------- arch/ppc64/kernel/iSeries_irq.c | 170 +++++++++++++++++++++++++++++++++++- 3 files changed, 169 insertions(+), 186 deletions(-) delete mode 100644 arch/ppc64/kernel/XmPciLpEvent.c diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index ada9be84ddee..ebf9b3cbf33d 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -21,7 +21,7 @@ pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) -obj-$(CONFIG_PPC_ISERIES) += iSeries_irq.o XmPciLpEvent.o \ +obj-$(CONFIG_PPC_ISERIES) += iSeries_irq.o \ HvCall.o HvLpConfig.o LparData.o \ iSeries_setup.o ItLpQueue.o hvCall.o \ mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \ diff --git a/arch/ppc64/kernel/XmPciLpEvent.c b/arch/ppc64/kernel/XmPciLpEvent.c deleted file mode 100644 index 3db530744831..000000000000 --- a/arch/ppc64/kernel/XmPciLpEvent.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * File XmPciLpEvent.c created by Wayne Holm on Mon Jan 15 2001. - * - * This module handles PCI interrupt events sent by the iSeries Hypervisor. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -static long Pci_Interrupt_Count; -static long Pci_Event_Count; - -enum XmPciLpEvent_Subtype { - XmPciLpEvent_BusCreated = 0, // PHB has been created - XmPciLpEvent_BusError = 1, // PHB has failed - XmPciLpEvent_BusFailed = 2, // Msg to Secondary, Primary failed bus - XmPciLpEvent_NodeFailed = 4, // Multi-adapter bridge has failed - XmPciLpEvent_NodeRecovered = 5, // Multi-adapter bridge has recovered - XmPciLpEvent_BusRecovered = 12, // PHB has been recovered - XmPciLpEvent_UnQuiesceBus = 18, // Secondary bus unqiescing - XmPciLpEvent_BridgeError = 21, // Bridge Error - XmPciLpEvent_SlotInterrupt = 22 // Slot interrupt -}; - -struct XmPciLpEvent_BusInterrupt { - HvBusNumber busNumber; - HvSubBusNumber subBusNumber; -}; - -struct XmPciLpEvent_NodeInterrupt { - HvBusNumber busNumber; - HvSubBusNumber subBusNumber; - HvAgentId deviceId; -}; - -struct XmPciLpEvent { - struct HvLpEvent hvLpEvent; - - union { - u64 alignData; // Align on an 8-byte boundary - - struct { - u32 fisr; - HvBusNumber busNumber; - HvSubBusNumber subBusNumber; - HvAgentId deviceId; - } slotInterrupt; - - struct XmPciLpEvent_BusInterrupt busFailed; - struct XmPciLpEvent_BusInterrupt busRecovered; - struct XmPciLpEvent_BusInterrupt busCreated; - - struct XmPciLpEvent_NodeInterrupt nodeFailed; - struct XmPciLpEvent_NodeInterrupt nodeRecovered; - - } eventData; - -}; - -static void intReceived(struct XmPciLpEvent *eventParm, - struct pt_regs *regsParm) -{ - int irq; - - ++Pci_Interrupt_Count; -#if 0 - PPCDBG(PPCDBG_BUSWALK, "PCI: XmPciLpEvent.c: intReceived\n"); -#endif - - switch (eventParm->hvLpEvent.xSubtype) { - case XmPciLpEvent_SlotInterrupt: - irq = eventParm->hvLpEvent.xCorrelationToken; - /* Dispatch the interrupt handlers for this irq */ - ppc_irq_dispatch_handler(regsParm, irq); - HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber, - eventParm->eventData.slotInterrupt.subBusNumber, - eventParm->eventData.slotInterrupt.deviceId); - break; - /* Ignore error recovery events for now */ - case XmPciLpEvent_BusCreated: - printk(KERN_INFO "XmPciLpEvent.c: system bus %d created\n", - eventParm->eventData.busCreated.busNumber); - break; - case XmPciLpEvent_BusError: - case XmPciLpEvent_BusFailed: - printk(KERN_INFO "XmPciLpEvent.c: system bus %d failed\n", - eventParm->eventData.busFailed.busNumber); - break; - case XmPciLpEvent_BusRecovered: - case XmPciLpEvent_UnQuiesceBus: - printk(KERN_INFO "XmPciLpEvent.c: system bus %d recovered\n", - eventParm->eventData.busRecovered.busNumber); - break; - case XmPciLpEvent_NodeFailed: - case XmPciLpEvent_BridgeError: - printk(KERN_INFO - "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d failed\n", - eventParm->eventData.nodeFailed.busNumber, - eventParm->eventData.nodeFailed.subBusNumber, - eventParm->eventData.nodeFailed.deviceId); - break; - case XmPciLpEvent_NodeRecovered: - printk(KERN_INFO - "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d recovered\n", - eventParm->eventData.nodeRecovered.busNumber, - eventParm->eventData.nodeRecovered.subBusNumber, - eventParm->eventData.nodeRecovered.deviceId); - break; - default: - printk(KERN_ERR - "XmPciLpEvent.c: unrecognized event subtype 0x%x\n", - eventParm->hvLpEvent.xSubtype); - break; - } -} - -static void XmPciLpEvent_handler(struct HvLpEvent *eventParm, - struct pt_regs *regsParm) -{ -#ifdef CONFIG_PCI -#if 0 - PPCDBG(PPCDBG_BUSWALK, "XmPciLpEvent_handler, type 0x%x\n", - eventParm->xType); -#endif - ++Pci_Event_Count; - - if (eventParm && (eventParm->xType == HvLpEvent_Type_PciIo)) { - switch (eventParm->xFlags.xFunction) { - case HvLpEvent_Function_Int: - intReceived((struct XmPciLpEvent *)eventParm, regsParm); - break; - case HvLpEvent_Function_Ack: - printk(KERN_ERR - "XmPciLpEvent.c: unexpected ack received\n"); - break; - default: - printk(KERN_ERR - "XmPciLpEvent.c: unexpected event function %d\n", - (int)eventParm->xFlags.xFunction); - break; - } - } else if (eventParm) - printk(KERN_ERR - "XmPciLpEvent.c: Unrecognized PCI event type 0x%x\n", - (int)eventParm->xType); - else - printk(KERN_ERR "XmPciLpEvent.c: NULL event received\n"); -#endif -} - -/* This should be called sometime prior to buswalk (init_IRQ would be good) */ -int XmPciLpEvent_init() -{ - int xRc; - - PPCDBG(PPCDBG_BUSWALK, - "XmPciLpEvent_init, Register Event type 0x%04X\n", - HvLpEvent_Type_PciIo); - - xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo, - &XmPciLpEvent_handler); - if (xRc == 0) { - xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0); - if (xRc != 0) - printk(KERN_ERR "XmPciLpEvent.c: open event path " - "failed with rc 0x%x\n", xRc); - } else - printk(KERN_ERR "XmPciLpEvent.c: register handler " - "failed with rc 0x%x\n", xRc); - return xRc; -} diff --git a/arch/ppc64/kernel/iSeries_irq.c b/arch/ppc64/kernel/iSeries_irq.c index 41902e358e76..96a1f8cd67e7 100644 --- a/arch/ppc64/kernel/iSeries_irq.c +++ b/arch/ppc64/kernel/iSeries_irq.c @@ -1,6 +1,7 @@ /* * This module supports the iSeries PCI bus interrupt handling * Copyright (C) 20yy + * Copyright (C) 2004-2005 IBM Corporation * * 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 @@ -22,6 +23,7 @@ * Created, December 13, 2000 by Wayne Holm * End Change Activity */ +#include #include #include #include @@ -30,11 +32,12 @@ #include #include #include - #include #include -#include +#include +#include +#include #include #include #include @@ -46,6 +49,169 @@ unsigned int virt_irq_to_real_map[NR_IRQS]; /* Note: the pcnet32 driver assumes irq numbers < 2 aren't valid. :( */ static int next_virtual_irq = 2; +static long Pci_Interrupt_Count; +static long Pci_Event_Count; + +enum XmPciLpEvent_Subtype { + XmPciLpEvent_BusCreated = 0, // PHB has been created + XmPciLpEvent_BusError = 1, // PHB has failed + XmPciLpEvent_BusFailed = 2, // Msg to Secondary, Primary failed bus + XmPciLpEvent_NodeFailed = 4, // Multi-adapter bridge has failed + XmPciLpEvent_NodeRecovered = 5, // Multi-adapter bridge has recovered + XmPciLpEvent_BusRecovered = 12, // PHB has been recovered + XmPciLpEvent_UnQuiesceBus = 18, // Secondary bus unqiescing + XmPciLpEvent_BridgeError = 21, // Bridge Error + XmPciLpEvent_SlotInterrupt = 22 // Slot interrupt +}; + +struct XmPciLpEvent_BusInterrupt { + HvBusNumber busNumber; + HvSubBusNumber subBusNumber; +}; + +struct XmPciLpEvent_NodeInterrupt { + HvBusNumber busNumber; + HvSubBusNumber subBusNumber; + HvAgentId deviceId; +}; + +struct XmPciLpEvent { + struct HvLpEvent hvLpEvent; + + union { + u64 alignData; // Align on an 8-byte boundary + + struct { + u32 fisr; + HvBusNumber busNumber; + HvSubBusNumber subBusNumber; + HvAgentId deviceId; + } slotInterrupt; + + struct XmPciLpEvent_BusInterrupt busFailed; + struct XmPciLpEvent_BusInterrupt busRecovered; + struct XmPciLpEvent_BusInterrupt busCreated; + + struct XmPciLpEvent_NodeInterrupt nodeFailed; + struct XmPciLpEvent_NodeInterrupt nodeRecovered; + + } eventData; + +}; + +static void intReceived(struct XmPciLpEvent *eventParm, + struct pt_regs *regsParm) +{ + int irq; + + ++Pci_Interrupt_Count; +#if 0 + PPCDBG(PPCDBG_BUSWALK, "PCI: XmPciLpEvent.c: intReceived\n"); +#endif + + switch (eventParm->hvLpEvent.xSubtype) { + case XmPciLpEvent_SlotInterrupt: + irq = eventParm->hvLpEvent.xCorrelationToken; + /* Dispatch the interrupt handlers for this irq */ + ppc_irq_dispatch_handler(regsParm, irq); + HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber, + eventParm->eventData.slotInterrupt.subBusNumber, + eventParm->eventData.slotInterrupt.deviceId); + break; + /* Ignore error recovery events for now */ + case XmPciLpEvent_BusCreated: + printk(KERN_INFO "XmPciLpEvent.c: system bus %d created\n", + eventParm->eventData.busCreated.busNumber); + break; + case XmPciLpEvent_BusError: + case XmPciLpEvent_BusFailed: + printk(KERN_INFO "XmPciLpEvent.c: system bus %d failed\n", + eventParm->eventData.busFailed.busNumber); + break; + case XmPciLpEvent_BusRecovered: + case XmPciLpEvent_UnQuiesceBus: + printk(KERN_INFO "XmPciLpEvent.c: system bus %d recovered\n", + eventParm->eventData.busRecovered.busNumber); + break; + case XmPciLpEvent_NodeFailed: + case XmPciLpEvent_BridgeError: + printk(KERN_INFO + "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d failed\n", + eventParm->eventData.nodeFailed.busNumber, + eventParm->eventData.nodeFailed.subBusNumber, + eventParm->eventData.nodeFailed.deviceId); + break; + case XmPciLpEvent_NodeRecovered: + printk(KERN_INFO + "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d recovered\n", + eventParm->eventData.nodeRecovered.busNumber, + eventParm->eventData.nodeRecovered.subBusNumber, + eventParm->eventData.nodeRecovered.deviceId); + break; + default: + printk(KERN_ERR + "XmPciLpEvent.c: unrecognized event subtype 0x%x\n", + eventParm->hvLpEvent.xSubtype); + break; + } +} + +static void XmPciLpEvent_handler(struct HvLpEvent *eventParm, + struct pt_regs *regsParm) +{ +#ifdef CONFIG_PCI +#if 0 + PPCDBG(PPCDBG_BUSWALK, "XmPciLpEvent_handler, type 0x%x\n", + eventParm->xType); +#endif + ++Pci_Event_Count; + + if (eventParm && (eventParm->xType == HvLpEvent_Type_PciIo)) { + switch (eventParm->xFlags.xFunction) { + case HvLpEvent_Function_Int: + intReceived((struct XmPciLpEvent *)eventParm, regsParm); + break; + case HvLpEvent_Function_Ack: + printk(KERN_ERR + "XmPciLpEvent.c: unexpected ack received\n"); + break; + default: + printk(KERN_ERR + "XmPciLpEvent.c: unexpected event function %d\n", + (int)eventParm->xFlags.xFunction); + break; + } + } else if (eventParm) + printk(KERN_ERR + "XmPciLpEvent.c: Unrecognized PCI event type 0x%x\n", + (int)eventParm->xType); + else + printk(KERN_ERR "XmPciLpEvent.c: NULL event received\n"); +#endif +} + +/* This should be called sometime prior to buswalk (init_IRQ would be good) */ +int XmPciLpEvent_init() +{ + int xRc; + + PPCDBG(PPCDBG_BUSWALK, + "XmPciLpEvent_init, Register Event type 0x%04X\n", + HvLpEvent_Type_PciIo); + + xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo, + &XmPciLpEvent_handler); + if (xRc == 0) { + xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0); + if (xRc != 0) + printk(KERN_ERR "XmPciLpEvent.c: open event path " + "failed with rc 0x%x\n", xRc); + } else + printk(KERN_ERR "XmPciLpEvent.c: register handler " + "failed with rc 0x%x\n", xRc); + return xRc; +} + /* This is called by init_IRQ. set in ppc_md.init_IRQ by iSeries_setup.c */ void __init iSeries_init_IRQ(void) { -- cgit v1.2.3-59-g8ed1b From 7f74e79fe749da035cc150446f02aec29938a5c8 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:51 -0700 Subject: [PATCH] ppc64 iSeries: tidy up irq code after merge This patch just removes some dead code, fixes messages that referred to the file this code used to be in and inserts XmPciLpEvent_init into its caller. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/iSeries_irq.c | 51 ++++++++++++--------------------- include/asm-ppc64/iSeries/iSeries_irq.h | 2 -- 2 files changed, 18 insertions(+), 35 deletions(-) diff --git a/arch/ppc64/kernel/iSeries_irq.c b/arch/ppc64/kernel/iSeries_irq.c index 96a1f8cd67e7..77376c1bd611 100644 --- a/arch/ppc64/kernel/iSeries_irq.c +++ b/arch/ppc64/kernel/iSeries_irq.c @@ -105,9 +105,6 @@ static void intReceived(struct XmPciLpEvent *eventParm, int irq; ++Pci_Interrupt_Count; -#if 0 - PPCDBG(PPCDBG_BUSWALK, "PCI: XmPciLpEvent.c: intReceived\n"); -#endif switch (eventParm->hvLpEvent.xSubtype) { case XmPciLpEvent_SlotInterrupt: @@ -120,37 +117,37 @@ static void intReceived(struct XmPciLpEvent *eventParm, break; /* Ignore error recovery events for now */ case XmPciLpEvent_BusCreated: - printk(KERN_INFO "XmPciLpEvent.c: system bus %d created\n", + printk(KERN_INFO "intReceived: system bus %d created\n", eventParm->eventData.busCreated.busNumber); break; case XmPciLpEvent_BusError: case XmPciLpEvent_BusFailed: - printk(KERN_INFO "XmPciLpEvent.c: system bus %d failed\n", + printk(KERN_INFO "intReceived: system bus %d failed\n", eventParm->eventData.busFailed.busNumber); break; case XmPciLpEvent_BusRecovered: case XmPciLpEvent_UnQuiesceBus: - printk(KERN_INFO "XmPciLpEvent.c: system bus %d recovered\n", + printk(KERN_INFO "intReceived: system bus %d recovered\n", eventParm->eventData.busRecovered.busNumber); break; case XmPciLpEvent_NodeFailed: case XmPciLpEvent_BridgeError: printk(KERN_INFO - "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d failed\n", + "intReceived: multi-adapter bridge %d/%d/%d failed\n", eventParm->eventData.nodeFailed.busNumber, eventParm->eventData.nodeFailed.subBusNumber, eventParm->eventData.nodeFailed.deviceId); break; case XmPciLpEvent_NodeRecovered: printk(KERN_INFO - "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d recovered\n", + "intReceived: multi-adapter bridge %d/%d/%d recovered\n", eventParm->eventData.nodeRecovered.busNumber, eventParm->eventData.nodeRecovered.subBusNumber, eventParm->eventData.nodeRecovered.deviceId); break; default: printk(KERN_ERR - "XmPciLpEvent.c: unrecognized event subtype 0x%x\n", + "intReceived: unrecognized event subtype 0x%x\n", eventParm->hvLpEvent.xSubtype); break; } @@ -160,10 +157,6 @@ static void XmPciLpEvent_handler(struct HvLpEvent *eventParm, struct pt_regs *regsParm) { #ifdef CONFIG_PCI -#if 0 - PPCDBG(PPCDBG_BUSWALK, "XmPciLpEvent_handler, type 0x%x\n", - eventParm->xType); -#endif ++Pci_Event_Count; if (eventParm && (eventParm->xType == HvLpEvent_Type_PciIo)) { @@ -173,50 +166,42 @@ static void XmPciLpEvent_handler(struct HvLpEvent *eventParm, break; case HvLpEvent_Function_Ack: printk(KERN_ERR - "XmPciLpEvent.c: unexpected ack received\n"); + "XmPciLpEvent_handler: unexpected ack received\n"); break; default: printk(KERN_ERR - "XmPciLpEvent.c: unexpected event function %d\n", + "XmPciLpEvent_handler: unexpected event function %d\n", (int)eventParm->xFlags.xFunction); break; } } else if (eventParm) printk(KERN_ERR - "XmPciLpEvent.c: Unrecognized PCI event type 0x%x\n", + "XmPciLpEvent_handler: Unrecognized PCI event type 0x%x\n", (int)eventParm->xType); else - printk(KERN_ERR "XmPciLpEvent.c: NULL event received\n"); + printk(KERN_ERR "XmPciLpEvent_handler: NULL event received\n"); #endif } -/* This should be called sometime prior to buswalk (init_IRQ would be good) */ -int XmPciLpEvent_init() +/* + * This is called by init_IRQ. set in ppc_md.init_IRQ by iSeries_setup.c + * It must be called before the bus walk. + */ +void __init iSeries_init_IRQ(void) { + /* Register PCI event handler and open an event path */ int xRc; - PPCDBG(PPCDBG_BUSWALK, - "XmPciLpEvent_init, Register Event type 0x%04X\n", - HvLpEvent_Type_PciIo); - xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo, &XmPciLpEvent_handler); if (xRc == 0) { xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0); if (xRc != 0) - printk(KERN_ERR "XmPciLpEvent.c: open event path " + printk(KERN_ERR "iSeries_init_IRQ: open event path " "failed with rc 0x%x\n", xRc); } else - printk(KERN_ERR "XmPciLpEvent.c: register handler " + printk(KERN_ERR "iSeries_init_IRQ: register handler " "failed with rc 0x%x\n", xRc); - return xRc; -} - -/* This is called by init_IRQ. set in ppc_md.init_IRQ by iSeries_setup.c */ -void __init iSeries_init_IRQ(void) -{ - /* Register PCI event handler and open an event path */ - XmPciLpEvent_init(); } #define REAL_IRQ_TO_BUS(irq) ((((irq) >> 6) & 0xff) + 1) diff --git a/include/asm-ppc64/iSeries/iSeries_irq.h b/include/asm-ppc64/iSeries/iSeries_irq.h index a7c5bceae8fa..6c9767ac1302 100644 --- a/include/asm-ppc64/iSeries/iSeries_irq.h +++ b/include/asm-ppc64/iSeries/iSeries_irq.h @@ -5,6 +5,4 @@ extern void iSeries_init_IRQ(void); extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId); extern void iSeries_activate_IRQs(void); -extern int XmPciLpEvent_init(void); - #endif /* __ISERIES_IRQ_H__ */ -- cgit v1.2.3-59-g8ed1b From 145d01e4287b8cbf50f87c3283e33bf5c84e8468 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:52 -0700 Subject: [PATCH] ppc64 iSeries: allow build with no PCI This patch allows iSeries to build with CONFIG_PCI=n. This is useful for partitions that have only virtual I/O. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/Kconfig | 2 +- arch/ppc64/kernel/Makefile | 6 +++--- arch/ppc64/kernel/dma.c | 4 ++++ arch/ppc64/kernel/iSeries_iommu.c | 3 ++- arch/ppc64/kernel/iSeries_setup.c | 8 ++++++++ arch/ppc64/kernel/sys_ppc32.c | 3 ++- arch/ppc64/lib/Makefile | 2 +- drivers/char/mem.c | 8 ++++---- drivers/serial/Kconfig | 2 +- include/asm-ppc64/dma.h | 3 +++ include/asm-ppc64/iommu.h | 4 ++++ 11 files changed, 33 insertions(+), 12 deletions(-) diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index 5cb343883e4d..0f1fa289744e 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig @@ -323,7 +323,7 @@ config EISA bool config PCI - bool + bool "support for PCI devices" if (EMBEDDED && PPC_ISERIES) default y help Find out whether your system includes a PCI bus. PCI is the name of diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index ebf9b3cbf33d..b5e167cf1a05 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile @@ -16,13 +16,13 @@ obj-y += vdso32/ vdso64/ obj-$(CONFIG_PPC_OF) += of_device.o -pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o iSeries_VpdInfo.o +pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o iSeries_irq.o \ + iSeries_VpdInfo.o pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) -obj-$(CONFIG_PPC_ISERIES) += iSeries_irq.o \ - HvCall.o HvLpConfig.o LparData.o \ +obj-$(CONFIG_PPC_ISERIES) += HvCall.o HvLpConfig.o LparData.o \ iSeries_setup.o ItLpQueue.o hvCall.o \ mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \ iSeries_iommu.o diff --git a/arch/ppc64/kernel/dma.c b/arch/ppc64/kernel/dma.c index ce714c927134..4da8e31b2b61 100644 --- a/arch/ppc64/kernel/dma.c +++ b/arch/ppc64/kernel/dma.c @@ -15,8 +15,10 @@ static struct dma_mapping_ops *get_dma_ops(struct device *dev) { +#ifdef CONFIG_PCI if (dev->bus == &pci_bus_type) return &pci_dma_ops; +#endif #ifdef CONFIG_IBMVIO if (dev->bus == &vio_bus_type) return &vio_dma_ops; @@ -37,8 +39,10 @@ EXPORT_SYMBOL(dma_supported); int dma_set_mask(struct device *dev, u64 dma_mask) { +#ifdef CONFIG_PCI if (dev->bus == &pci_bus_type) return pci_set_dma_mask(to_pci_dev(dev), dma_mask); +#endif #ifdef CONFIG_IBMVIO if (dev->bus == &vio_bus_type) return -EIO; diff --git a/arch/ppc64/kernel/iSeries_iommu.c b/arch/ppc64/kernel/iSeries_iommu.c index 4e1a47c8a802..f8ff1bb054dc 100644 --- a/arch/ppc64/kernel/iSeries_iommu.c +++ b/arch/ppc64/kernel/iSeries_iommu.c @@ -83,7 +83,7 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages) } } - +#ifdef CONFIG_PCI /* * This function compares the known tables to find an iommu_table * that has already been built for hardware TCEs. @@ -159,6 +159,7 @@ void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn) else kfree(tbl); } +#endif static void iommu_dev_setup_iSeries(struct pci_dev *dev) { } static void iommu_bus_setup_iSeries(struct pci_bus *bus) { } diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 3d3ed631499a..b31962436fe3 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -76,7 +76,11 @@ extern void ppcdbg_initialize(void); static void build_iSeries_Memory_Map(void); static void setup_iSeries_cache_sizes(void); static void iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr); +#ifdef CONFIG_PCI extern void iSeries_pci_final_fixup(void); +#else +static void iSeries_pci_final_fixup(void) { } +#endif /* Global Variables */ static unsigned long procFreqHz; @@ -876,6 +880,10 @@ static int set_spread_lpevents(char *str) } __setup("spread_lpevents=", set_spread_lpevents); +#ifndef CONFIG_PCI +void __init iSeries_init_IRQ(void) { } +#endif + void __init iSeries_early_setup(void) { iSeries_fixup_klimit(); diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c index 9c8e317c598d..118436e8085a 100644 --- a/arch/ppc64/kernel/sys_ppc32.c +++ b/arch/ppc64/kernel/sys_ppc32.c @@ -741,6 +741,7 @@ asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubu asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn) { +#ifdef CONFIG_PCI struct pci_controller* hose; struct list_head *ln; struct pci_bus *bus = NULL; @@ -786,7 +787,7 @@ asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn) case IOBASE_ISA_MEM: return -EINVAL; } - +#endif /* CONFIG_PCI */ return -EOPNOTSUPP; } diff --git a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile index bf7b5bbfc04e..76fbfa9f706f 100644 --- a/arch/ppc64/lib/Makefile +++ b/arch/ppc64/lib/Makefile @@ -12,7 +12,7 @@ lib-$(CONFIG_SMP) += locks.o # e2a provides EBCDIC to ASCII conversions. ifdef CONFIG_PPC_ISERIES -obj-$(CONFIG_PCI) += e2a.o +obj-y += e2a.o endif lib-$(CONFIG_DEBUG_KERNEL) += sstep.o diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 257b8ee605e5..e3085b22a365 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -484,7 +484,7 @@ static ssize_t write_kmem(struct file * file, const char __user * buf, return virtr + wrote; } -#if defined(CONFIG_ISA) || !defined(__mc68000__) +#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)) static ssize_t read_port(struct file * file, char __user * buf, size_t count, loff_t *ppos) { @@ -744,7 +744,7 @@ static struct file_operations null_fops = { .write = write_null, }; -#if defined(CONFIG_ISA) || !defined(__mc68000__) +#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)) static struct file_operations port_fops = { .llseek = memory_lseek, .read = read_port, @@ -804,7 +804,7 @@ static int memory_open(struct inode * inode, struct file * filp) case 3: filp->f_op = &null_fops; break; -#if defined(CONFIG_ISA) || !defined(__mc68000__) +#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)) case 4: filp->f_op = &port_fops; break; @@ -846,7 +846,7 @@ static const struct { {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops}, {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops}, {3, "null", S_IRUGO | S_IWUGO, &null_fops}, -#if defined(CONFIG_ISA) || !defined(__mc68000__) +#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)) {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops}, #endif {5, "zero", S_IRUGO | S_IWUGO, &zero_fops}, diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 6e44b46c9e9d..6a15703f1cb9 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -753,7 +753,7 @@ config SERIAL_MPC52xx_CONSOLE_BAUD config SERIAL_ICOM tristate "IBM Multiport Serial Adapter" - depends on PPC_ISERIES || PPC_PSERIES + depends on PCI && (PPC_ISERIES || PPC_PSERIES) select SERIAL_CORE help This driver is for a family of multiport serial adapters diff --git a/include/asm-ppc64/dma.h b/include/asm-ppc64/dma.h index d693b8026bc3..dfd1f69059ba 100644 --- a/include/asm-ppc64/dma.h +++ b/include/asm-ppc64/dma.h @@ -27,6 +27,8 @@ /* Doesn't really apply... */ #define MAX_DMA_ADDRESS (~0UL) +#if !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI) + #define dma_outb outb #define dma_inb inb @@ -323,4 +325,5 @@ extern int isa_dma_bridge_buggy; #else #define isa_dma_bridge_buggy (0) #endif +#endif /* !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI) */ #endif /* _ASM_DMA_H */ diff --git a/include/asm-ppc64/iommu.h b/include/asm-ppc64/iommu.h index d9b53374d23a..729de5cc21d9 100644 --- a/include/asm-ppc64/iommu.h +++ b/include/asm-ppc64/iommu.h @@ -137,8 +137,12 @@ extern void iommu_init_early_pSeries(void); extern void iommu_init_early_iSeries(void); extern void iommu_init_early_u3(void); +#ifdef CONFIG_PCI extern void pci_iommu_init(void); extern void pci_direct_iommu_init(void); +#else +static inline void pci_iommu_init(void) { } +#endif extern void alloc_u3_dart_table(void); -- cgit v1.2.3-59-g8ed1b From ac5b33c9bcf1c05ae949b026a51d7f8f9573591c Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Jun 2005 17:15:54 -0700 Subject: [PATCH] ppc64: tidy up vio devices fake parent Currently we dynamically allocate the fake parent device for all devices on the vio bus. This patch statically allocates it. This also allows us to reuse it for the iSeries "generic" vio device (that is used for passing to dma routines when communicating with the hypervisor without a device involved). Also unexport vio_bus_type as it is never used in modules. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/vio.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/arch/ppc64/kernel/vio.c b/arch/ppc64/kernel/vio.c index 79f2dc7a9833..0c0ba71ac0e8 100644 --- a/arch/ppc64/kernel/vio.c +++ b/arch/ppc64/kernel/vio.c @@ -41,20 +41,25 @@ static const struct vio_device_id *vio_match_device( static struct iommu_table *vio_build_iommu_table(struct vio_dev *); static int vio_num_address_cells; #endif -static struct vio_dev *vio_bus_device; /* fake "parent" device */ - #ifdef CONFIG_PPC_ISERIES -static struct vio_dev *__init vio_register_device_iseries(char *type, - uint32_t unit_num); - static struct iommu_table veth_iommu_table; static struct iommu_table vio_iommu_table; - -static struct vio_dev _vio_dev = { +#endif +static struct vio_dev vio_bus_device = { /* fake "parent" device */ + .name = vio_bus_device.dev.bus_id, + .type = "", +#ifdef CONFIG_PPC_ISERIES .iommu_table = &vio_iommu_table, - .dev.bus = &vio_bus_type +#endif + .dev.bus_id = "vio", + .dev.bus = &vio_bus_type, }; -struct device *iSeries_vio_dev = &_vio_dev.dev; + +#ifdef CONFIG_PPC_ISERIES +static struct vio_dev *__init vio_register_device_iseries(char *type, + uint32_t unit_num); + +struct device *iSeries_vio_dev = &vio_bus_device.dev; EXPORT_SYMBOL(iSeries_vio_dev); #define device_is_compatible(a, b) 1 @@ -260,18 +265,10 @@ static int __init vio_bus_init(void) } /* the fake parent of all vio devices, just to give us a nice directory */ - vio_bus_device = kmalloc(sizeof(struct vio_dev), GFP_KERNEL); - if (!vio_bus_device) { - return 1; - } - memset(vio_bus_device, 0, sizeof(struct vio_dev)); - strcpy(vio_bus_device->dev.bus_id, "vio"); - - err = device_register(&vio_bus_device->dev); + err = device_register(&vio_bus_device.dev); if (err) { printk(KERN_WARNING "%s: device_register returned %i\n", __FUNCTION__, err); - kfree(vio_bus_device); return err; } @@ -326,7 +323,7 @@ static struct vio_dev * __devinit vio_register_device_common( viodev->unit_address = unit_address; viodev->iommu_table = iommu_table; /* init generic 'struct device' fields: */ - viodev->dev.parent = &vio_bus_device->dev; + viodev->dev.parent = &vio_bus_device.dev; viodev->dev.bus = &vio_bus_type; viodev->dev.release = vio_dev_release; @@ -636,5 +633,3 @@ struct bus_type vio_bus_type = { .name = "vio", .match = vio_bus_match, }; - -EXPORT_SYMBOL(vio_bus_type); -- cgit v1.2.3-59-g8ed1b From 515bae9cdc6a78eda0879e1f158056d73ec808b7 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 21 Jun 2005 17:15:55 -0700 Subject: [PATCH] ppc64: Mark kernel hptes dirty We dont use the hardware referenced and changed bits and setting them early avoids a store to memory. We already do this for userspace hptes but not kernel ones. Do it. Signed-off-by: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/mm/hash_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c index 87d0525f56fa..1647b1c6f28e 100644 --- a/arch/ppc64/mm/hash_utils.c +++ b/arch/ppc64/mm/hash_utils.c @@ -195,7 +195,7 @@ void __init htab_initialize(void) memset((void *)table, 0, htab_size_bytes); } - mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX; + mode_rw = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX; /* On U3 based machines, we need to reserve the DART area and * _NOT_ map it to avoid cache paradoxes as it's remapped non -- cgit v1.2.3-59-g8ed1b From 9b843cda193c56f5e12fedeaf95e0126b706d57b Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 21 Jun 2005 17:15:55 -0700 Subject: [PATCH] ppc64: set/clear SMT capable bit at boot Allow the SMT bit to be set/reset at boot, like the ALTIVEC bit. This means we will enable SMT on unknown cpus that support it. Signed-off-by: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/prom.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index eb6538b58008..47727a6f7346 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c @@ -884,6 +884,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node, { char *type = get_flat_dt_prop(node, "device_type", NULL); u32 *prop; + unsigned long size; /* We are scanning "cpu" nodes only */ if (type == NULL || strcmp(type, "cpu") != 0) @@ -929,6 +930,17 @@ static int __init early_init_dt_scan_cpus(unsigned long node, cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; } + /* + * Check for an SMT capable CPU and set the CPU feature. We do + * this by looking at the size of the ibm,ppc-interrupt-server#s + * property + */ + prop = (u32 *)get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", + &size); + cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT; + if (prop && ((size / sizeof(u32)) > 1)) + cur_cpu_spec->cpu_features |= CPU_FTR_SMT; + return 0; } -- cgit v1.2.3-59-g8ed1b From e400bae98499583767da58fb0a1b9ad3e24fcb86 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Tue, 21 Jun 2005 17:15:56 -0700 Subject: [PATCH] mips: add vr41xx gpio support Add vr41xx gpio support. Signed-off-by: Yoichi Yuasa Cc: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/Kconfig | 4 + drivers/char/Makefile | 1 + drivers/char/vr41xx_giu.c | 743 +++++++++++++++++++++++++++++++++++++++ include/asm-mips/vr41xx/giu.h | 69 ++++ include/asm-mips/vr41xx/vr41xx.h | 35 -- 5 files changed, 817 insertions(+), 35 deletions(-) create mode 100644 drivers/char/vr41xx_giu.c create mode 100644 include/asm-mips/vr41xx/giu.h diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 5ed6515ae01f..7ccf871d3c9d 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -929,6 +929,10 @@ config SCx200_GPIO If compiled as a module, it will be called scx200_gpio. +config GPIO_VR41XX + tristate "NEC VR4100 series General-purpose I/O Unit support" + depends on CPU_VR41XX + config RAW_DRIVER tristate "RAW driver (/dev/raw/rawN) (OBSOLETE)" help diff --git a/drivers/char/Makefile b/drivers/char/Makefile index e3f5c32aac55..1aff819f3832 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -80,6 +80,7 @@ obj-$(CONFIG_PPDEV) += ppdev.o obj-$(CONFIG_NWBUTTON) += nwbutton.o obj-$(CONFIG_NWFLASH) += nwflash.o obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o +obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o obj-$(CONFIG_TANBAC_TB0219) += tb0219.o obj-$(CONFIG_WATCHDOG) += watchdog/ diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c new file mode 100644 index 000000000000..683278bc5241 --- /dev/null +++ b/drivers/char/vr41xx_giu.c @@ -0,0 +1,743 @@ +/* + * Driver for NEC VR4100 series General-purpose I/O Unit. + * + * Copyright (C) 2002 MontaVista Software Inc. + * Author: Yoichi Yuasa + * Copyright (C) 2003-2005 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +MODULE_AUTHOR("Yoichi Yuasa "); +MODULE_DESCRIPTION("NEC VR4100 series General-purpose I/O Unit driver"); +MODULE_LICENSE("GPL"); + +static int major; /* default is dynamic major device number */ +module_param(major, int, 0); +MODULE_PARM_DESC(major, "Major device number"); + +#define GIU_TYPE1_START 0x0b000100UL +#define GIU_TYPE1_SIZE 0x20UL + +#define GIU_TYPE2_START 0x0f000140UL +#define GIU_TYPE2_SIZE 0x20UL + +#define GIU_TYPE3_START 0x0f000140UL +#define GIU_TYPE3_SIZE 0x28UL + +#define GIU_PULLUPDOWN_START 0x0b0002e0UL +#define GIU_PULLUPDOWN_SIZE 0x04UL + +#define GIUIOSELL 0x00 +#define GIUIOSELH 0x02 +#define GIUPIODL 0x04 +#define GIUPIODH 0x06 +#define GIUINTSTATL 0x08 +#define GIUINTSTATH 0x0a +#define GIUINTENL 0x0c +#define GIUINTENH 0x0e +#define GIUINTTYPL 0x10 +#define GIUINTTYPH 0x12 +#define GIUINTALSELL 0x14 +#define GIUINTALSELH 0x16 +#define GIUINTHTSELL 0x18 +#define GIUINTHTSELH 0x1a +#define GIUPODATL 0x1c +#define GIUPODATEN 0x1c +#define GIUPODATH 0x1e + #define PIOEN0 0x0100 + #define PIOEN1 0x0200 +#define GIUPODAT 0x1e +#define GIUFEDGEINHL 0x20 +#define GIUFEDGEINHH 0x22 +#define GIUREDGEINHL 0x24 +#define GIUREDGEINHH 0x26 + +#define GIUUSEUPDN 0x1e0 +#define GIUTERMUPDN 0x1e2 + +#define GPIO_HAS_PULLUPDOWN_IO 0x0001 +#define GPIO_HAS_OUTPUT_ENABLE 0x0002 +#define GPIO_HAS_INTERRUPT_EDGE_SELECT 0x0100 + +static spinlock_t giu_lock; +static struct resource *giu_resource1; +static struct resource *giu_resource2; +static unsigned long giu_flags; +static unsigned int giu_nr_pins; + +static void __iomem *giu_base; + +#define giu_read(offset) readw(giu_base + (offset)) +#define giu_write(offset, value) writew((value), giu_base + (offset)) + +#define GPIO_PIN_OF_IRQ(irq) ((irq) - GIU_IRQ_BASE) +#define GIUINT_HIGH_OFFSET 16 +#define GIUINT_HIGH_MAX 32 + +static inline uint16_t giu_set(uint16_t offset, uint16_t set) +{ + uint16_t data; + + data = giu_read(offset); + data |= set; + giu_write(offset, data); + + return data; +} + +static inline uint16_t giu_clear(uint16_t offset, uint16_t clear) +{ + uint16_t data; + + data = giu_read(offset); + data &= ~clear; + giu_write(offset, data); + + return data; +} + +static unsigned int startup_giuint_low_irq(unsigned int irq) +{ + unsigned int pin; + + pin = GPIO_PIN_OF_IRQ(irq); + giu_write(GIUINTSTATL, 1 << pin); + giu_set(GIUINTENL, 1 << pin); + + return 0; +} + +static void shutdown_giuint_low_irq(unsigned int irq) +{ + giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); +} + +static void enable_giuint_low_irq(unsigned int irq) +{ + giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); +} + +#define disable_giuint_low_irq shutdown_giuint_low_irq + +static void ack_giuint_low_irq(unsigned int irq) +{ + unsigned int pin; + + pin = GPIO_PIN_OF_IRQ(irq); + giu_clear(GIUINTENL, 1 << pin); + giu_write(GIUINTSTATL, 1 << pin); +} + +static void end_giuint_low_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); +} + +static struct hw_interrupt_type giuint_low_irq_type = { + .typename = "GIUINTL", + .startup = startup_giuint_low_irq, + .shutdown = shutdown_giuint_low_irq, + .enable = enable_giuint_low_irq, + .disable = disable_giuint_low_irq, + .ack = ack_giuint_low_irq, + .end = end_giuint_low_irq, +}; + +static unsigned int startup_giuint_high_irq(unsigned int irq) +{ + unsigned int pin; + + pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET; + giu_write(GIUINTSTATH, 1 << pin); + giu_set(GIUINTENH, 1 << pin); + + return 0; +} + +static void shutdown_giuint_high_irq(unsigned int irq) +{ + giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); +} + +static void enable_giuint_high_irq(unsigned int irq) +{ + giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); +} + +#define disable_giuint_high_irq shutdown_giuint_high_irq + +static void ack_giuint_high_irq(unsigned int irq) +{ + unsigned int pin; + + pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET; + giu_clear(GIUINTENH, 1 << pin); + giu_write(GIUINTSTATH, 1 << pin); +} + +static void end_giuint_high_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); +} + +static struct hw_interrupt_type giuint_high_irq_type = { + .typename = "GIUINTH", + .startup = startup_giuint_high_irq, + .shutdown = shutdown_giuint_high_irq, + .enable = enable_giuint_high_irq, + .disable = disable_giuint_high_irq, + .ack = ack_giuint_high_irq, + .end = end_giuint_high_irq, +}; + +static int giu_get_irq(unsigned int irq, struct pt_regs *regs) +{ + uint16_t pendl, pendh, maskl, maskh; + int i; + + pendl = giu_read(GIUINTSTATL); + pendh = giu_read(GIUINTSTATH); + maskl = giu_read(GIUINTENL); + maskh = giu_read(GIUINTENH); + + maskl &= pendl; + maskh &= pendh; + + if (maskl) { + for (i = 0; i < 16; i++) { + if (maskl & (1 << i)) + return GIU_IRQ(i); + } + } else if (maskh) { + for (i = 0; i < 16; i++) { + if (maskh & (1 << i)) + return GIU_IRQ(i + GIUINT_HIGH_OFFSET); + } + } + + printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n", + maskl, pendl, maskh, pendh); + + atomic_inc(&irq_err_count); + + return -EINVAL; +} + +void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_t signal) +{ + uint16_t mask; + + if (pin < GIUINT_HIGH_OFFSET) { + mask = 1 << pin; + if (trigger != IRQ_TRIGGER_LEVEL) { + giu_set(GIUINTTYPL, mask); + if (signal == IRQ_SIGNAL_HOLD) + giu_set(GIUINTHTSELL, mask); + else + giu_clear(GIUINTHTSELL, mask); + if (current_cpu_data.cputype == CPU_VR4133) { + switch (trigger) { + case IRQ_TRIGGER_EDGE_FALLING: + giu_set(GIUFEDGEINHL, mask); + giu_clear(GIUREDGEINHL, mask); + break; + case IRQ_TRIGGER_EDGE_RISING: + giu_clear(GIUFEDGEINHL, mask); + giu_set(GIUREDGEINHL, mask); + break; + default: + giu_set(GIUFEDGEINHL, mask); + giu_set(GIUREDGEINHL, mask); + break; + } + } + } else { + giu_clear(GIUINTTYPL, mask); + giu_clear(GIUINTHTSELL, mask); + } + giu_write(GIUINTSTATL, mask); + } else if (pin < GIUINT_HIGH_MAX) { + mask = 1 << (pin - GIUINT_HIGH_OFFSET); + if (trigger != IRQ_TRIGGER_LEVEL) { + giu_set(GIUINTTYPH, mask); + if (signal == IRQ_SIGNAL_HOLD) + giu_set(GIUINTHTSELH, mask); + else + giu_clear(GIUINTHTSELH, mask); + if (current_cpu_data.cputype == CPU_VR4133) { + switch (trigger) { + case IRQ_TRIGGER_EDGE_FALLING: + giu_set(GIUFEDGEINHH, mask); + giu_clear(GIUREDGEINHH, mask); + break; + case IRQ_TRIGGER_EDGE_RISING: + giu_clear(GIUFEDGEINHH, mask); + giu_set(GIUREDGEINHH, mask); + break; + default: + giu_set(GIUFEDGEINHH, mask); + giu_set(GIUREDGEINHH, mask); + break; + } + } + } else { + giu_clear(GIUINTTYPH, mask); + giu_clear(GIUINTHTSELH, mask); + } + giu_write(GIUINTSTATH, mask); + } +} + +EXPORT_SYMBOL_GPL(vr41xx_set_irq_trigger); + +void vr41xx_set_irq_level(unsigned int pin, irq_level_t level) +{ + uint16_t mask; + + if (pin < GIUINT_HIGH_OFFSET) { + mask = 1 << pin; + if (level == IRQ_LEVEL_HIGH) + giu_set(GIUINTALSELL, mask); + else + giu_clear(GIUINTALSELL, mask); + giu_write(GIUINTSTATL, mask); + } else if (pin < GIUINT_HIGH_MAX) { + mask = 1 << (pin - GIUINT_HIGH_OFFSET); + if (level == IRQ_LEVEL_HIGH) + giu_set(GIUINTALSELH, mask); + else + giu_clear(GIUINTALSELH, mask); + giu_write(GIUINTSTATH, mask); + } +} + +EXPORT_SYMBOL_GPL(vr41xx_set_irq_level); + +gpio_data_t vr41xx_gpio_get_pin(unsigned int pin) +{ + uint16_t reg, mask; + + if (pin >= giu_nr_pins) + return GPIO_DATA_INVAL; + + if (pin < 16) { + reg = giu_read(GIUPIODL); + mask = (uint16_t)1 << pin; + } else if (pin < 32) { + reg = giu_read(GIUPIODH); + mask = (uint16_t)1 << (pin - 16); + } else if (pin < 48) { + reg = giu_read(GIUPODATL); + mask = (uint16_t)1 << (pin - 32); + } else { + reg = giu_read(GIUPODATH); + mask = (uint16_t)1 << (pin - 48); + } + + if (reg & mask) + return GPIO_DATA_HIGH; + + return GPIO_DATA_LOW; +} + +EXPORT_SYMBOL_GPL(vr41xx_gpio_get_pin); + +int vr41xx_gpio_set_pin(unsigned int pin, gpio_data_t data) +{ + uint16_t offset, mask, reg; + unsigned long flags; + + if (pin >= giu_nr_pins) + return -EINVAL; + + if (pin < 16) { + offset = GIUPIODL; + mask = (uint16_t)1 << pin; + } else if (pin < 32) { + offset = GIUPIODH; + mask = (uint16_t)1 << (pin - 16); + } else if (pin < 48) { + offset = GIUPODATL; + mask = (uint16_t)1 << (pin - 32); + } else { + offset = GIUPODATH; + mask = (uint16_t)1 << (pin - 48); + } + + spin_lock_irqsave(&giu_lock, flags); + + reg = giu_read(offset); + if (data == GPIO_DATA_HIGH) + reg |= mask; + else + reg &= ~mask; + giu_write(offset, reg); + + spin_unlock_irqrestore(&giu_lock, flags); + + return 0; +} + +EXPORT_SYMBOL_GPL(vr41xx_gpio_set_pin); + +int vr41xx_gpio_set_direction(unsigned int pin, gpio_direction_t dir) +{ + uint16_t offset, mask, reg; + unsigned long flags; + + if (pin >= giu_nr_pins) + return -EINVAL; + + if (pin < 16) { + offset = GIUIOSELL; + mask = (uint16_t)1 << pin; + } else if (pin < 32) { + offset = GIUIOSELH; + mask = (uint16_t)1 << (pin - 16); + } else { + if (giu_flags & GPIO_HAS_OUTPUT_ENABLE) { + offset = GIUPODATEN; + mask = (uint16_t)1 << (pin - 32); + } else { + switch (pin) { + case 48: + offset = GIUPODATH; + mask = PIOEN0; + break; + case 49: + offset = GIUPODATH; + mask = PIOEN1; + break; + default: + return -EINVAL; + } + } + } + + spin_lock_irqsave(&giu_lock, flags); + + reg = giu_read(offset); + if (dir == GPIO_OUTPUT) + reg |= mask; + else + reg &= ~mask; + giu_write(offset, reg); + + spin_unlock_irqrestore(&giu_lock, flags); + + return 0; +} + +EXPORT_SYMBOL_GPL(vr41xx_gpio_set_direction); + +int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull) +{ + uint16_t reg, mask; + unsigned long flags; + + if ((giu_flags & GPIO_HAS_PULLUPDOWN_IO) != GPIO_HAS_PULLUPDOWN_IO) + return -EPERM; + + if (pin >= 15) + return -EINVAL; + + mask = (uint16_t)1 << pin; + + spin_lock_irqsave(&giu_lock, flags); + + if (pull == GPIO_PULL_UP || pull == GPIO_PULL_DOWN) { + reg = giu_read(GIUTERMUPDN); + if (pull == GPIO_PULL_UP) + reg |= mask; + else + reg &= ~mask; + giu_write(GIUTERMUPDN, reg); + + reg = giu_read(GIUUSEUPDN); + reg |= mask; + giu_write(GIUUSEUPDN, reg); + } else { + reg = giu_read(GIUUSEUPDN); + reg &= ~mask; + giu_write(GIUUSEUPDN, reg); + } + + spin_unlock_irqrestore(&giu_lock, flags); + + return 0; +} + +EXPORT_SYMBOL_GPL(vr41xx_gpio_pullupdown); + +static ssize_t gpio_read(struct file *file, char __user *buf, size_t len, + loff_t *ppos) +{ + unsigned int pin; + char value = '0'; + + pin = iminor(file->f_dentry->d_inode); + if (pin >= giu_nr_pins) + return -EBADF; + + if (vr41xx_gpio_get_pin(pin) == GPIO_DATA_HIGH) + value = '1'; + + if (len <= 0) + return -EFAULT; + + if (put_user(value, buf)) + return -EFAULT; + + return 1; +} + +static ssize_t gpio_write(struct file *file, const char __user *data, + size_t len, loff_t *ppos) +{ + unsigned int pin; + size_t i; + char c; + int retval = 0; + + pin = iminor(file->f_dentry->d_inode); + if (pin >= giu_nr_pins) + return -EBADF; + + for (i = 0; i < len; i++) { + if (get_user(c, data + i)) + return -EFAULT; + + switch (c) { + case '0': + retval = vr41xx_gpio_set_pin(pin, GPIO_DATA_LOW); + break; + case '1': + retval = vr41xx_gpio_set_pin(pin, GPIO_DATA_HIGH); + break; + case 'D': + printk(KERN_INFO "GPIO%d: pull down\n", pin); + retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DOWN); + break; + case 'd': + printk(KERN_INFO "GPIO%d: pull up/down disable\n", pin); + retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DISABLE); + break; + case 'I': + printk(KERN_INFO "GPIO%d: input\n", pin); + retval = vr41xx_gpio_set_direction(pin, GPIO_INPUT); + break; + case 'O': + printk(KERN_INFO "GPIO%d: output\n", pin); + retval = vr41xx_gpio_set_direction(pin, GPIO_OUTPUT); + break; + case 'o': + printk(KERN_INFO "GPIO%d: output disable\n", pin); + retval = vr41xx_gpio_set_direction(pin, GPIO_OUTPUT_DISABLE); + break; + case 'P': + printk(KERN_INFO "GPIO%d: pull up\n", pin); + retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_UP); + break; + case 'p': + printk(KERN_INFO "GPIO%d: pull up/down disable\n", pin); + retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DISABLE); + break; + default: + break; + } + + if (retval < 0) + break; + } + + return i; +} + +static int gpio_open(struct inode *inode, struct file *file) +{ + unsigned int pin; + + pin = iminor(inode); + if (pin >= giu_nr_pins) + return -EBADF; + + return nonseekable_open(inode, file); +} + +static int gpio_release(struct inode *inode, struct file *file) +{ + unsigned int pin; + + pin = iminor(inode); + if (pin >= giu_nr_pins) + return -EBADF; + + return 0; +} + +static struct file_operations gpio_fops = { + .owner = THIS_MODULE, + .read = gpio_read, + .write = gpio_write, + .open = gpio_open, + .release = gpio_release, +}; + +static int giu_probe(struct device *dev) +{ + unsigned long start, size, flags = 0; + unsigned int nr_pins = 0; + struct resource *res1, *res2 = NULL; + void *base; + int retval, i; + + switch (current_cpu_data.cputype) { + case CPU_VR4111: + case CPU_VR4121: + start = GIU_TYPE1_START; + size = GIU_TYPE1_SIZE; + flags = GPIO_HAS_PULLUPDOWN_IO; + nr_pins = 50; + break; + case CPU_VR4122: + case CPU_VR4131: + start = GIU_TYPE2_START; + size = GIU_TYPE2_SIZE; + nr_pins = 36; + break; + case CPU_VR4133: + start = GIU_TYPE3_START; + size = GIU_TYPE3_SIZE; + flags = GPIO_HAS_INTERRUPT_EDGE_SELECT; + nr_pins = 48; + break; + default: + return -ENODEV; + } + + res1 = request_mem_region(start, size, "GIU"); + if (res1 == NULL) + return -EBUSY; + + base = ioremap(start, size); + if (base == NULL) { + release_resource(res1); + return -ENOMEM; + } + + if (flags & GPIO_HAS_PULLUPDOWN_IO) { + res2 = request_mem_region(GIU_PULLUPDOWN_START, GIU_PULLUPDOWN_SIZE, "GIU"); + if (res2 == NULL) { + iounmap(base); + release_resource(res1); + return -EBUSY; + } + } + + retval = register_chrdev(major, "GIU", &gpio_fops); + if (retval < 0) { + iounmap(base); + release_resource(res1); + release_resource(res2); + return retval; + } + + if (major == 0) { + major = retval; + printk(KERN_INFO "GIU: major number %d\n", major); + } + + spin_lock_init(&giu_lock); + giu_base = base; + giu_resource1 = res1; + giu_resource2 = res2; + giu_flags = flags; + giu_nr_pins = nr_pins; + + giu_write(GIUINTENL, 0); + giu_write(GIUINTENH, 0); + + for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { + if (i < GIU_IRQ(GIUINT_HIGH_OFFSET)) + irq_desc[i].handler = &giuint_low_irq_type; + else + irq_desc[i].handler = &giuint_high_irq_type; + } + + return cascade_irq(GIUINT_IRQ, giu_get_irq); +} + +static int giu_remove(struct device *dev) +{ + iounmap(giu_base); + + release_resource(giu_resource1); + if (giu_flags & GPIO_HAS_PULLUPDOWN_IO) + release_resource(giu_resource2); + + return 0; +} + +static struct platform_device *giu_platform_device; + +static struct device_driver giu_device_driver = { + .name = "GIU", + .bus = &platform_bus_type, + .probe = giu_probe, + .remove = giu_remove, +}; + +static int __devinit vr41xx_giu_init(void) +{ + int retval; + + giu_platform_device = platform_device_register_simple("GIU", -1, NULL, 0); + if (IS_ERR(giu_platform_device)) + return PTR_ERR(giu_platform_device); + + retval = driver_register(&giu_device_driver); + if (retval < 0) + platform_device_unregister(giu_platform_device); + + return retval; +} + +static void __devexit vr41xx_giu_exit(void) +{ + driver_unregister(&giu_device_driver); + + platform_device_unregister(giu_platform_device); +} + +module_init(vr41xx_giu_init); +module_exit(vr41xx_giu_exit); diff --git a/include/asm-mips/vr41xx/giu.h b/include/asm-mips/vr41xx/giu.h new file mode 100644 index 000000000000..8590885a7638 --- /dev/null +++ b/include/asm-mips/vr41xx/giu.h @@ -0,0 +1,69 @@ +/* + * Include file for NEC VR4100 series General-purpose I/O Unit. + * + * Copyright (C) 2005 Yoichi Yuasa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __NEC_VR41XX_GIU_H +#define __NEC_VR41XX_GIU_H + +typedef enum { + IRQ_TRIGGER_LEVEL, + IRQ_TRIGGER_EDGE, + IRQ_TRIGGER_EDGE_FALLING, + IRQ_TRIGGER_EDGE_RISING, +} irq_trigger_t; + +typedef enum { + IRQ_SIGNAL_THROUGH, + IRQ_SIGNAL_HOLD, +} irq_signal_t; + +extern void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_t signal); + +typedef enum { + IRQ_LEVEL_LOW, + IRQ_LEVEL_HIGH, +} irq_level_t; + +extern void vr41xx_set_irq_level(unsigned int pin, irq_level_t level); + +typedef enum { + GPIO_DATA_LOW, + GPIO_DATA_HIGH, + GPIO_DATA_INVAL, +} gpio_data_t; + +extern gpio_data_t vr41xx_gpio_get_pin(unsigned int pin); +extern int vr41xx_gpio_set_pin(unsigned int pin, gpio_data_t data); + +typedef enum { + GPIO_INPUT, + GPIO_OUTPUT, + GPIO_OUTPUT_DISABLE, +} gpio_direction_t; + +extern int vr41xx_gpio_set_direction(unsigned int pin, gpio_direction_t dir); + +typedef enum { + GPIO_PULL_DOWN, + GPIO_PULL_UP, + GPIO_PULL_DISABLE, +} gpio_pull_t; + +extern int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull); + +#endif /* __NEC_VR41XX_GIU_H */ diff --git a/include/asm-mips/vr41xx/vr41xx.h b/include/asm-mips/vr41xx/vr41xx.h index ad0d1ea144f0..7d41e44463f9 100644 --- a/include/asm-mips/vr41xx/vr41xx.h +++ b/include/asm-mips/vr41xx/vr41xx.h @@ -126,7 +126,6 @@ extern void vr41xx_mask_clock(vr41xx_clock_t clock); #define GIU_IRQ_BASE 40 #define GIU_IRQ(x) (GIU_IRQ_BASE + (x)) /* IRQ 40-71 */ #define GIU_IRQ_LAST GIU_IRQ(31) -#define GIU_IRQ_TO_PIN(x) ((x) - GIU_IRQ_BASE) /* Pin 0-31 */ extern int vr41xx_set_intassign(unsigned int irq, unsigned char intassign); extern int vr41xx_cascade_irq(unsigned int irq, int (*get_irq_number)(int irq)); @@ -197,38 +196,4 @@ extern void vr41xx_disable_csiint(uint16_t mask); extern void vr41xx_enable_bcuint(void); extern void vr41xx_disable_bcuint(void); -/* - * General-Purpose I/O Unit - */ -enum { - TRIGGER_LEVEL, - TRIGGER_EDGE, - TRIGGER_EDGE_FALLING, - TRIGGER_EDGE_RISING -}; - -enum { - SIGNAL_THROUGH, - SIGNAL_HOLD -}; - -extern void vr41xx_set_irq_trigger(int pin, int trigger, int hold); - -enum { - LEVEL_LOW, - LEVEL_HIGH -}; - -extern void vr41xx_set_irq_level(int pin, int level); - -enum { - PIO_INPUT, - PIO_OUTPUT -}; - -enum { - DATA_LOW, - DATA_HIGH -}; - #endif /* __NEC_VR41XX_H */ -- cgit v1.2.3-59-g8ed1b From 22329b511a97557b293583194037d1f4c71e1504 Mon Sep 17 00:00:00 2001 From: Brent Casavant Date: Tue, 21 Jun 2005 17:15:59 -0700 Subject: [PATCH] ioc4: Core driver rewrite This series of patches reworks the configuration and internal structure of the SGI IOC4 I/O controller device drivers. These changes are motivated by several factors: - The IOC4 chip PCI resources are of mixed use between functions (i.e. multiple functions are handled in the same address range, sometimes within the same register), muddling resource ownership and initialization issues. Centralizing this ownership in a core driver is desirable. - The IOC4 chip implements multiple functions (serial, IDE, others not yet implemented in the mainline kernel) but is not a multifunction PCI device. In order to properly handle device addition and removal as well as module insertion and deletion, an intermediary IOC4-specific driver layer is needed to handle these operations cleanly. - All IOC4 drivers are currently enabled by a single CONFIG value. As not all systems need all IOC4 functions, it is desireable to enable these drivers independently. - The current IOC4 core driver will trigger loading of all function-level drivers, as it makes direct calls to them. This situation should be reversed (i.e. function-level drivers cause loading of core driver) in order to maintain a clear and least-surprise driver loading model. - IOC4 hardware design necessitates some driver-level dependency on the PCI bus clock speed. Current code assumes a 66MHz bus, but the speed should be autodetected and appropriate compensation taken. This patch series effects the above changes by a newly and better designed IOC4 core driver with which the function-level drivers can register and deregister themselves upon module insertion/removal. By tracking these modules, device addition/removal is also handled properly. PCI resource management and ownership issues are centralized in this core driver, and IOC4-wide configuration actions such as bus speed detection are also handled in this core driver. This patch: The SGI IOC4 I/O controller chip implements multiple functions, though it is not a multi-function PCI device. Additionally, various PCI resources of the IOC4 are shared by multiple hardware functions, and thus resource ownership by driver is not clearly delineated. Due to the current driver design, all core and subordinate drivers must be loaded, or none, which is undesirable if not all IOC4 hardware features are being used. This patch reorganizes the IOC4 drivers so that the core driver provides a subdriver registration service. Through appropriate callbacks the subdrivers can now handle device addition and removal, as well as module insertion and deletion (though the IOC4 IDE driver requires further work before module deletion will work). The core driver now takes care of allocating PCI resources and data which must be shared between subdrivers, to clearly delineate module ownership of these items. Signed-off-by: Brent Casavant Acked-by: Pat Gefre Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/sgi-ioc4.txt | 45 +++++++ drivers/ide/pci/sgiioc4.c | 30 ++++- drivers/serial/ioc4_serial.c | 311 ++++++++++++++++++------------------------- drivers/sn/ioc4.c | 290 ++++++++++++++++++++++++++++++++++++---- include/linux/ioc4.h | 156 ++++++++++++++++++++++ include/linux/ioc4_common.h | 21 --- 6 files changed, 617 insertions(+), 236 deletions(-) create mode 100644 Documentation/sgi-ioc4.txt create mode 100644 include/linux/ioc4.h delete mode 100644 include/linux/ioc4_common.h diff --git a/Documentation/sgi-ioc4.txt b/Documentation/sgi-ioc4.txt new file mode 100644 index 000000000000..876c96ae38db --- /dev/null +++ b/Documentation/sgi-ioc4.txt @@ -0,0 +1,45 @@ +The SGI IOC4 PCI device is a bit of a strange beast, so some notes on +it are in order. + +First, even though the IOC4 performs multiple functions, such as an +IDE controller, a serial controller, a PS/2 keyboard/mouse controller, +and an external interrupt mechanism, it's not implemented as a +multifunction device. The consequence of this from a software +standpoint is that all these functions share a single IRQ, and +they can't all register to own the same PCI device ID. To make +matters a bit worse, some of the register blocks (and even registers +themselves) present in IOC4 are mixed-purpose between these several +functions, meaning that there's no clear "owning" device driver. + +The solution is to organize the IOC4 driver into several independent +drivers, "ioc4", "sgiioc4", and "ioc4_serial". Note that there is no +PS/2 controller driver as this functionality has never been wired up +on a shipping IO card. + +ioc4 +==== +This is the core (or shim) driver for IOC4. It is responsible for +initializing the basic functionality of the chip, and allocating +the PCI resources that are shared between the IOC4 functions. + +This driver also provides registration functions that the other +IOC4 drivers can call to make their presence known. Each driver +needs to provide a probe and remove function, which are invoked +by the core driver at appropriate times. The interface of these +IOC4 function probe and remove operations isn't precisely the same +as PCI device probe and remove operations, but is logically the +same operation. + +sgiioc4 +======= +This is the IDE driver for IOC4. Its name isn't very descriptive +simply for historical reasons (it used to be the only IOC4 driver +component). There's not much to say about it other than it hooks +up to the ioc4 driver via the appropriate registration, probe, and +remove functions. + +ioc4_serial +=========== +This is the serial driver for IOC4. There's not much to say about it +other than it hooks up to the ioc4 driver via the appropriate registration, +probe, and remove functions. diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index 4651a22bf12e..af526b671c4e 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include @@ -715,14 +715,34 @@ static ide_pci_device_t sgiioc4_chipsets[] __devinitdata = { }; int -ioc4_ide_attach_one(struct pci_dev *dev, const struct pci_device_id *id) +ioc4_ide_attach_one(struct ioc4_driver_data *idd) { - return pci_init_sgiioc4(dev, &sgiioc4_chipsets[id->driver_data]); + return pci_init_sgiioc4(idd->idd_pdev, + &sgiioc4_chipsets[idd->idd_pci_id->driver_data]); } +static struct ioc4_submodule ioc4_ide_submodule = { + .is_name = "IOC4_ide", + .is_owner = THIS_MODULE, + .is_probe = ioc4_ide_attach_one, +/* .is_remove = ioc4_ide_remove_one, */ +}; + +static int __devinit +ioc4_ide_init(void) +{ + return ioc4_register_submodule(&ioc4_ide_submodule); +} + +static void __devexit +ioc4_ide_exit(void) +{ + ioc4_unregister_submodule(&ioc4_ide_submodule); +} + +module_init(ioc4_ide_init); +module_exit(ioc4_ide_exit); MODULE_AUTHOR("Aniket Malatpure - Silicon Graphics Inc. (SGI)"); MODULE_DESCRIPTION("IDE PCI driver module for SGI IOC4 Base-IO Card"); MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(ioc4_ide_attach_one); diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c index ba4e13a22a50..da5f10eb4845 100644 --- a/drivers/serial/ioc4_serial.c +++ b/drivers/serial/ioc4_serial.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include /* @@ -130,12 +130,19 @@ IOC4_SIO_IR_S3_TX_EXPLICIT) /* Bitmasks for IOC4_OTHER_IR, IOC4_OTHER_IEC, and IOC4_OTHER_IES */ -#define IOC4_OTHER_IR_ATA_INT 0x00000001 /* ATAPI intr pass-thru */ -#define IOC4_OTHER_IR_ATA_MEMERR 0x00000002 /* ATAPI DMA PCI error */ -#define IOC4_OTHER_IR_S0_MEMERR 0x00000004 /* Port 0 PCI error */ -#define IOC4_OTHER_IR_S1_MEMERR 0x00000008 /* Port 1 PCI error */ -#define IOC4_OTHER_IR_S2_MEMERR 0x00000010 /* Port 2 PCI error */ -#define IOC4_OTHER_IR_S3_MEMERR 0x00000020 /* Port 3 PCI error */ +#define IOC4_OTHER_IR_ATA_INT 0x00000001 /* ATAPI intr pass-thru */ +#define IOC4_OTHER_IR_ATA_MEMERR 0x00000002 /* ATAPI DMA PCI error */ +#define IOC4_OTHER_IR_S0_MEMERR 0x00000004 /* Port 0 PCI error */ +#define IOC4_OTHER_IR_S1_MEMERR 0x00000008 /* Port 1 PCI error */ +#define IOC4_OTHER_IR_S2_MEMERR 0x00000010 /* Port 2 PCI error */ +#define IOC4_OTHER_IR_S3_MEMERR 0x00000020 /* Port 3 PCI error */ +#define IOC4_OTHER_IR_KBD_INT 0x00000040 /* Keyboard/mouse */ +#define IOC4_OTHER_IR_RESERVED 0x007fff80 /* Reserved */ +#define IOC4_OTHER_IR_RT_INT 0x00800000 /* INT_OUT section output */ +#define IOC4_OTHER_IR_GEN_INT 0xff000000 /* Generic pins */ + +#define IOC4_OTHER_IR_SER_MEMERR (IOC4_OTHER_IR_S0_MEMERR | IOC4_OTHER_IR_S1_MEMERR | \ + IOC4_OTHER_IR_S2_MEMERR | IOC4_OTHER_IR_S3_MEMERR) /* Bitmasks for IOC4_SIO_CR */ #define IOC4_SIO_CR_CMD_PULSE_SHIFT 0 /* byte bus strobe shift */ @@ -274,67 +281,22 @@ struct ioc4_uartregs { #define i4u_dlm u2.dlm #define i4u_fcr u3.fcr -/* PCI memory space register map addressed using pci_bar0 */ -struct ioc4_memregs { - struct ioc4_mem { - /* Miscellaneous IOC4 registers */ - uint32_t pci_err_addr_l; - uint32_t pci_err_addr_h; - uint32_t sio_ir; - uint32_t other_ir; - - /* These registers are read-only for general kernel code. */ - uint32_t sio_ies_ro; - uint32_t other_ies_ro; - uint32_t sio_iec_ro; - uint32_t other_iec_ro; - uint32_t sio_cr; - uint32_t misc_fill1; - uint32_t int_out; - uint32_t misc_fill2; - uint32_t gpcr_s; - uint32_t gpcr_c; - uint32_t gpdr; - uint32_t misc_fill3; - uint32_t gppr_0; - uint32_t gppr_1; - uint32_t gppr_2; - uint32_t gppr_3; - uint32_t gppr_4; - uint32_t gppr_5; - uint32_t gppr_6; - uint32_t gppr_7; - } ioc4_mem; - - char misc_fill4[0x100 - 0x5C - 4]; - - /* ATA/ATAP registers */ - uint32_t ata_notused[9]; - char ata_fill1[0x140 - 0x120 - 4]; - uint32_t ata_notused1[8]; - char ata_fill2[0x200 - 0x15C - 4]; - - /* Keyboard and mouse registers */ - uint32_t km_notused[5];; - char km_fill1[0x300 - 0x210 - 4]; - - /* Serial port registers used for DMA serial I/O */ - struct ioc4_serial { - uint32_t sbbr01_l; - uint32_t sbbr01_h; - uint32_t sbbr23_l; - uint32_t sbbr23_h; - - struct ioc4_serialregs port_0; - struct ioc4_serialregs port_1; - struct ioc4_serialregs port_2; - struct ioc4_serialregs port_3; - struct ioc4_uartregs uart_0; - struct ioc4_uartregs uart_1; - struct ioc4_uartregs uart_2; - struct ioc4_uartregs uart_3; - } ioc4_serial; -}; +/* Serial port registers used for DMA serial I/O */ +struct ioc4_serial { + uint32_t sbbr01_l; + uint32_t sbbr01_h; + uint32_t sbbr23_l; + uint32_t sbbr23_h; + + struct ioc4_serialregs port_0; + struct ioc4_serialregs port_1; + struct ioc4_serialregs port_2; + struct ioc4_serialregs port_3; + struct ioc4_uartregs uart_0; + struct ioc4_uartregs uart_1; + struct ioc4_uartregs uart_2; + struct ioc4_uartregs uart_3; +} ioc4_serial; /* UART clock speed */ #define IOC4_SER_XIN_CLK IOC4_SER_XIN_CLK_66 @@ -412,8 +374,8 @@ enum sio_proto { | UART_LCR_WLEN7 | UART_LCR_WLEN8) #define LCR_MASK_STOP_BITS (UART_LCR_STOP) -#define PENDING(_p) (readl(&(_p)->ip_mem->sio_ir) & _p->ip_ienb) -#define READ_SIO_IR(_p) readl(&(_p)->ip_mem->sio_ir) +#define PENDING(_p) (readl(&(_p)->ip_mem->sio_ir.raw) & _p->ip_ienb) +#define READ_SIO_IR(_p) readl(&(_p)->ip_mem->sio_ir.raw) /* Default to 4k buffers */ #ifdef IOC4_1K_BUFFERS @@ -447,7 +409,7 @@ struct ioc4_control { */ #define MAX_IOC4_INTR_ENTS (8 * sizeof(uint32_t)) struct ioc4_soft { - struct ioc4_mem __iomem *is_ioc4_mem_addr; + struct ioc4_misc_regs __iomem *is_ioc4_misc_addr; struct ioc4_serial __iomem *is_ioc4_serial_addr; /* Each interrupt type has an entry in the array */ @@ -486,7 +448,7 @@ struct ioc4_port { struct ioc4_soft *ip_ioc4_soft; /* pci mem addresses */ - struct ioc4_mem __iomem *ip_mem; + struct ioc4_misc_regs __iomem *ip_mem; struct ioc4_serial __iomem *ip_serial; struct ioc4_serialregs __iomem *ip_serial_regs; struct ioc4_uartregs __iomem *ip_uart_regs; @@ -553,7 +515,7 @@ struct hooks { uint32_t intr_dma_error; uint32_t intr_clear; uint32_t intr_all; - char rs422_select_pin; + int rs422_select_pin; }; static struct hooks hooks_array[IOC4_NUM_SERIAL_PORTS] = { @@ -669,7 +631,7 @@ static void handle_intr(void *arg, uint32_t sio_ir); static inline void write_ireg(struct ioc4_soft *ioc4_soft, uint32_t val, int which, int type) { - struct ioc4_mem __iomem *mem = ioc4_soft->is_ioc4_mem_addr; + struct ioc4_misc_regs __iomem *mem = ioc4_soft->is_ioc4_misc_addr; unsigned long flags; spin_lock_irqsave(&ioc4_soft->is_ir_lock, flags); @@ -678,11 +640,11 @@ write_ireg(struct ioc4_soft *ioc4_soft, uint32_t val, int which, int type) case IOC4_SIO_INTR_TYPE: switch (which) { case IOC4_W_IES: - writel(val, &mem->sio_ies_ro); + writel(val, &mem->sio_ies.raw); break; case IOC4_W_IEC: - writel(val, &mem->sio_iec_ro); + writel(val, &mem->sio_iec.raw); break; } break; @@ -690,11 +652,11 @@ write_ireg(struct ioc4_soft *ioc4_soft, uint32_t val, int which, int type) case IOC4_OTHER_INTR_TYPE: switch (which) { case IOC4_W_IES: - writel(val, &mem->other_ies_ro); + writel(val, &mem->other_ies.raw); break; case IOC4_W_IEC: - writel(val, &mem->other_iec_ro); + writel(val, &mem->other_iec.raw); break; } break; @@ -747,7 +709,8 @@ static int set_baud(struct ioc4_port *port, int baud) */ static struct ioc4_port *get_ioc4_port(struct uart_port *the_port) { - struct ioc4_control *control = dev_get_drvdata(the_port->dev); + struct ioc4_driver_data *idd = dev_get_drvdata(the_port->dev); + struct ioc4_control *control = idd->idd_serial_data; int ii; if (control) { @@ -782,7 +745,7 @@ static struct ioc4_port *get_ioc4_port(struct uart_port *the_port) static inline uint32_t pending_intrs(struct ioc4_soft *soft, int type) { - struct ioc4_mem __iomem *mem = soft->is_ioc4_mem_addr; + struct ioc4_misc_regs __iomem *mem = soft->is_ioc4_misc_addr; unsigned long flag; uint32_t intrs = 0; @@ -793,11 +756,11 @@ pending_intrs(struct ioc4_soft *soft, int type) switch (type) { case IOC4_SIO_INTR_TYPE: - intrs = readl(&mem->sio_ir) & readl(&mem->sio_ies_ro); + intrs = readl(&mem->sio_ir.raw) & readl(&mem->sio_ies.raw); break; case IOC4_OTHER_INTR_TYPE: - intrs = readl(&mem->other_ir) & readl(&mem->other_ies_ro); + intrs = readl(&mem->other_ir.raw) & readl(&mem->other_ies.raw); /* Don't process any ATA interrupte */ intrs &= ~(IOC4_OTHER_IR_ATA_INT | IOC4_OTHER_IR_ATA_MEMERR); @@ -826,7 +789,7 @@ static int inline port_init(struct ioc4_port *port) /* Wait until any pending bus activity for this port has ceased */ do - sio_cr = readl(&port->ip_mem->sio_cr); + sio_cr = readl(&port->ip_mem->sio_cr.raw); while (!(sio_cr & IOC4_SIO_CR_SIO_DIAG_IDLE)); /* Finish reset sequence */ @@ -899,7 +862,7 @@ static int inline port_init(struct ioc4_port *port) write_ireg(port->ip_ioc4_soft, hooks->intr_clear, IOC4_W_IEC, IOC4_SIO_INTR_TYPE); port->ip_ienb &= ~hooks->intr_clear; - writel(hooks->intr_clear, &port->ip_mem->sio_ir); + writel(hooks->intr_clear, &port->ip_mem->sio_ir.raw); return 0; } @@ -918,23 +881,23 @@ static void handle_dma_error_intr(void *arg, uint32_t other_ir) spin_lock_irqsave(&port->ip_lock, flags); /* ACK the interrupt */ - writel(hooks->intr_dma_error, &port->ip_mem->other_ir); + writel(hooks->intr_dma_error, &port->ip_mem->other_ir.raw); - if (readl(&port->ip_mem->pci_err_addr_l) & IOC4_PCI_ERR_ADDR_VLD) { + if (readl(&port->ip_mem->pci_err_addr_l.raw) & IOC4_PCI_ERR_ADDR_VLD) { printk(KERN_ERR "PCI error address is 0x%lx, " "master is serial port %c %s\n", (((uint64_t)readl(&port->ip_mem->pci_err_addr_h) << 32) - | readl(&port->ip_mem->pci_err_addr_l)) + | readl(&port->ip_mem->pci_err_addr_l.raw)) & IOC4_PCI_ERR_ADDR_ADDR_MSK, '1' + - ((char)(readl(&port->ip_mem-> pci_err_addr_l) & + ((char)(readl(&port->ip_mem->pci_err_addr_l.raw) & IOC4_PCI_ERR_ADDR_MST_NUM_MSK) >> 1), - (readl(&port->ip_mem->pci_err_addr_l) + (readl(&port->ip_mem->pci_err_addr_l.raw) & IOC4_PCI_ERR_ADDR_MST_TYP_MSK) ? "RX" : "TX"); - if (readl(&port->ip_mem->pci_err_addr_l) + if (readl(&port->ip_mem->pci_err_addr_l.raw) & IOC4_PCI_ERR_ADDR_MUL_ERR) { printk(KERN_ERR "Multiple errors occurred\n"); @@ -1018,26 +981,26 @@ static irqreturn_t ioc4_intr(int irq, void *arg, struct pt_regs *regs) "other_ies = 0x%x\n", (intr_type == IOC4_SIO_INTR_TYPE) ? "sio" : "other", this_ir, - readl(&soft->is_ioc4_mem_addr->sio_ir), - readl(&soft->is_ioc4_mem_addr->sio_ies_ro), - readl(&soft->is_ioc4_mem_addr->other_ir), - readl(&soft->is_ioc4_mem_addr->other_ies_ro)); + readl(&soft->is_ioc4_misc_addr->sio_ir.raw), + readl(&soft->is_ioc4_misc_addr->sio_ies.raw), + readl(&soft->is_ioc4_misc_addr->other_ir.raw), + readl(&soft->is_ioc4_misc_addr->other_ies.raw)); } } #ifdef DEBUG_INTERRUPTS { - struct ioc4_mem __iomem *mem = soft->is_ioc4_mem_addr; + struct ioc4_misc_regs __iomem *mem = soft->is_ioc4_misc_addr; spinlock_t *lp = &soft->is_ir_lock; unsigned long flag; spin_lock_irqsave(&soft->is_ir_lock, flag); - printk ("%s : %d : mem 0x%p sio_ir 0x%x sio_ies_ro 0x%x " - "other_ir 0x%x other_ies_ro 0x%x mask 0x%x\n", + printk ("%s : %d : mem 0x%p sio_ir 0x%x sio_ies 0x%x " + "other_ir 0x%x other_ies 0x%x mask 0x%x\n", __FUNCTION__, __LINE__, - (void *)mem, readl(&mem->sio_ir), - readl(&mem->sio_ies_ro), - readl(&mem->other_ir), - readl(&mem->other_ies_ro), + (void *)mem, readl(&mem->sio_ir.raw), + readl(&mem->sio_ies.raw), + readl(&mem->other_ir.raw), + readl(&mem->other_ies.raw), IOC4_OTHER_IR_ATA_INT | IOC4_OTHER_IR_ATA_MEMERR); spin_unlock_irqrestore(&soft->is_ir_lock, flag); } @@ -1056,7 +1019,7 @@ static irqreturn_t ioc4_intr(int irq, void *arg, struct pt_regs *regs) */ static int inline ioc4_attach_local(struct pci_dev *pdev, struct ioc4_control *control, - struct ioc4_soft *soft, void __iomem *ioc4_mem, + struct ioc4_soft *soft, void __iomem *ioc4_misc, void __iomem *ioc4_serial) { struct ioc4_port *port; @@ -1076,7 +1039,7 @@ static int inline ioc4_attach_local(struct pci_dev *pdev, ioc4_revid, ioc4_revid_min); return -EPERM; } - BUG_ON(ioc4_mem == NULL); + BUG_ON(ioc4_misc == NULL); BUG_ON(ioc4_serial == NULL); /* Create port structures for each port */ @@ -1103,7 +1066,7 @@ static int inline ioc4_attach_local(struct pci_dev *pdev, port->ip_pci_bus_speed = IOC4_SER_XIN_CLK; port->ip_baud = 9600; port->ip_control = control; - port->ip_mem = ioc4_mem; + port->ip_mem = ioc4_misc; port->ip_serial = ioc4_serial; /* point to the right hook */ @@ -1604,14 +1567,12 @@ static int ioc4_set_proto(struct ioc4_port *port, enum sio_proto proto) switch (proto) { case PROTO_RS232: /* Clear the appropriate GIO pin */ - writel(0, (&port->ip_mem->gppr_0 + - hooks->rs422_select_pin)); + writel(0, (&port->ip_mem->gppr[hooks->rs422_select_pin].raw)); break; case PROTO_RS422: /* Set the appropriate GIO pin */ - writel(1, (&port->ip_mem->gppr_0 + - hooks->rs422_select_pin)); + writel(1, (&port->ip_mem->gppr[hooks->rs422_select_pin].raw)); break; default: @@ -1885,7 +1846,7 @@ static void handle_intr(void *arg, uint32_t sio_ir) if (sio_ir & hooks->intr_delta_dcd) { /* ACK the interrupt */ writel(hooks->intr_delta_dcd, - &port->ip_mem->sio_ir); + &port->ip_mem->sio_ir.raw); shadow = readl(&port->ip_serial_regs->shadow); @@ -1907,7 +1868,7 @@ static void handle_intr(void *arg, uint32_t sio_ir) if (sio_ir & hooks->intr_delta_cts) { /* ACK the interrupt */ writel(hooks->intr_delta_cts, - &port->ip_mem->sio_ir); + &port->ip_mem->sio_ir.raw); shadow = readl(&port->ip_serial_regs->shadow); @@ -1928,7 +1889,7 @@ static void handle_intr(void *arg, uint32_t sio_ir) if (sio_ir & hooks->intr_rx_timer) { /* ACK the interrupt */ writel(hooks->intr_rx_timer, - &port->ip_mem->sio_ir); + &port->ip_mem->sio_ir.raw); if ((port->ip_notify & N_DATA_READY) && (port->ip_port)) { @@ -1974,7 +1935,7 @@ static void handle_intr(void *arg, uint32_t sio_ir) /* ACK the interrupt */ writel(hooks->intr_tx_explicit, - &port->ip_mem->sio_ir); + &port->ip_mem->sio_ir.raw); if (port->ip_notify & N_OUTPUT_LOWAT) ioc4_cb_output_lowat(port); @@ -2634,7 +2595,8 @@ ioc4_serial_core_attach(struct pci_dev *pdev) { struct ioc4_port *port; struct uart_port *the_port; - struct ioc4_control *control = pci_get_drvdata(pdev); + struct ioc4_driver_data *idd = pci_get_drvdata(pdev); + struct ioc4_control *control = idd->idd_serial_data; int ii; DPRINT_CONFIG(("%s: attach pdev 0x%p - control 0x%p\n", @@ -2680,55 +2642,29 @@ ioc4_serial_core_attach(struct pci_dev *pdev) /** * ioc4_serial_attach_one - register attach function - * called per card found from ioc4_serial_detect as part - * of module_init(). - * @pdev: handle for this card - * @pci_id: pci id for this card + * called per card found from IOC4 master module. + * @idd: Master module data for this IOC4 */ int -ioc4_serial_attach_one(struct pci_dev *pdev, const struct pci_device_id *pci_id) +ioc4_serial_attach_one(struct ioc4_driver_data *idd) { - struct ioc4_mem __iomem *mem; - unsigned long tmp_addr, tmp_addr1; + unsigned long tmp_addr1; struct ioc4_serial __iomem *serial; struct ioc4_soft *soft; struct ioc4_control *control; - int tmp, ret = 0; + int ret = 0; - DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __FUNCTION__, pdev, pci_id)); - - /* Map in the ioc4 memory */ - tmp_addr = pci_resource_start(pdev, 0); - if (!tmp_addr) { - printk(KERN_WARNING - "ioc4 (%p) : unable to get PIO mapping for " - "MEM space\n", (void *)pdev); - return -ENODEV; - } - if (!request_region(tmp_addr, sizeof(struct ioc4_mem), "sioc4_mem")) { - printk(KERN_ALERT - "ioc4 (%p): unable to get request region for " - "MEM space\n", (void *)pdev); - return -ENODEV; - } - mem = ioremap(tmp_addr, sizeof(struct ioc4_mem)); - if (!mem) { - printk(KERN_WARNING - "ioc4 (%p) : unable to remap ioc4 memory\n", - (void *)pdev); - ret = -ENODEV; - goto out1; - } + DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __FUNCTION__, idd->idd_pdev, idd->idd_pci_id)); /* request serial registers */ - tmp_addr1 = pci_resource_start(pdev, 0) + IOC4_SERIAL_OFFSET; + tmp_addr1 = idd->idd_bar0 + IOC4_SERIAL_OFFSET; if (!request_region(tmp_addr1, sizeof(struct ioc4_serial), "sioc4_uart")) { printk(KERN_WARNING "ioc4 (%p): unable to get request region for " - "uart space\n", (void *)pdev); + "uart space\n", (void *)idd->idd_pdev); ret = -ENODEV; goto out1; } @@ -2736,12 +2672,12 @@ ioc4_serial_attach_one(struct pci_dev *pdev, const struct pci_device_id *pci_id) if (!serial) { printk(KERN_WARNING "ioc4 (%p) : unable to remap ioc4 serial register\n", - (void *)pdev); + (void *)idd->idd_pdev); ret = -ENODEV; goto out2; } DPRINT_CONFIG(("%s : mem 0x%p, serial 0x%p\n", - __FUNCTION__, (void *)mem, (void *)serial)); + __FUNCTION__, (void *)idd->idd_misc_regs, (void *)serial)); /* Get memory for the new card */ control = kmalloc(sizeof(struct ioc4_control) * IOC4_NUM_SERIAL_PORTS, @@ -2754,59 +2690,57 @@ ioc4_serial_attach_one(struct pci_dev *pdev, const struct pci_device_id *pci_id) goto out2; } memset(control, 0, sizeof(struct ioc4_control)); - pci_set_drvdata(pdev, control); + idd->idd_serial_data = control; /* Allocate the soft structure */ soft = kmalloc(sizeof(struct ioc4_soft), GFP_KERNEL); if (!soft) { printk(KERN_WARNING "ioc4 (%p): unable to get memory for the soft struct\n", - (void *)pdev); + (void *)idd->idd_pdev); ret = -ENOMEM; goto out3; } memset(soft, 0, sizeof(struct ioc4_soft)); spin_lock_init(&soft->is_ir_lock); - soft->is_ioc4_mem_addr = mem; + soft->is_ioc4_misc_addr = idd->idd_misc_regs; soft->is_ioc4_serial_addr = serial; /* Init the IOC4 */ - pci_read_config_dword(pdev, PCI_COMMAND, &tmp); - pci_write_config_dword(pdev, PCI_COMMAND, - tmp | PCI_COMMAND_PARITY | PCI_COMMAND_SERR); - - writel(0xf << IOC4_SIO_CR_CMD_PULSE_SHIFT, &mem->sio_cr); + writel(0xf << IOC4_SIO_CR_CMD_PULSE_SHIFT, + &idd->idd_misc_regs->sio_cr.raw); /* Enable serial port mode select generic PIO pins as outputs */ writel(IOC4_GPCR_UART0_MODESEL | IOC4_GPCR_UART1_MODESEL | IOC4_GPCR_UART2_MODESEL | IOC4_GPCR_UART3_MODESEL, - &mem->gpcr_s); + &idd->idd_misc_regs->gpcr_s.raw); - /* Clear and disable all interrupts */ + /* Clear and disable all serial interrupts */ write_ireg(soft, ~0, IOC4_W_IEC, IOC4_SIO_INTR_TYPE); - writel(~0, &mem->sio_ir); - write_ireg(soft, ~(IOC4_OTHER_IR_ATA_INT | IOC4_OTHER_IR_ATA_MEMERR), - IOC4_W_IEC, IOC4_OTHER_INTR_TYPE); - writel(~(IOC4_OTHER_IR_ATA_MEMERR | IOC4_OTHER_IR_ATA_MEMERR), - &mem->other_ir); + writel(~0, &idd->idd_misc_regs->sio_ir.raw); + write_ireg(soft, IOC4_OTHER_IR_SER_MEMERR, IOC4_W_IEC, + IOC4_OTHER_INTR_TYPE); + writel(IOC4_OTHER_IR_SER_MEMERR, &idd->idd_misc_regs->other_ir.raw); control->ic_soft = soft; - if (!request_irq(pdev->irq, ioc4_intr, SA_SHIRQ, + + /* Hook up interrupt handler */ + if (!request_irq(idd->idd_pdev->irq, ioc4_intr, SA_SHIRQ, "sgi-ioc4serial", (void *)soft)) { - control->ic_irq = pdev->irq; + control->ic_irq = idd->idd_pdev->irq; } else { printk(KERN_WARNING "%s : request_irq fails for IRQ 0x%x\n ", - __FUNCTION__, pdev->irq); + __FUNCTION__, idd->idd_pdev->irq); } - if ((ret = ioc4_attach_local(pdev, control, soft, - soft->is_ioc4_mem_addr, + if ((ret = ioc4_attach_local(idd->idd_pdev, control, soft, + soft->is_ioc4_misc_addr, soft->is_ioc4_serial_addr))) goto out4; /* register port with the serial core */ - if ((ret = ioc4_serial_core_attach(pdev))) + if ((ret = ioc4_serial_core_attach(idd->idd_pdev))) goto out4; return ret; @@ -2819,7 +2753,6 @@ out3: out2: release_region(tmp_addr1, sizeof(struct ioc4_serial)); out1: - release_region(tmp_addr, sizeof(struct ioc4_mem)); return ret; } @@ -2828,11 +2761,10 @@ out1: /** * ioc4_serial_remove_one - detach function * - * @pdev: handle for this card + * @idd: IOC4 master module data for this IOC4 */ -#if 0 -void ioc4_serial_remove_one(struct pci_dev *pdev) +int ioc4_serial_remove_one(struct ioc4_driver_data *idd) { int ii; struct ioc4_control *control; @@ -2840,7 +2772,7 @@ void ioc4_serial_remove_one(struct pci_dev *pdev) struct ioc4_port *port; struct ioc4_soft *soft; - control = pci_get_drvdata(pdev); + control = idd->idd_serial_data; for (ii = 0; ii < IOC4_NUM_SERIAL_PORTS; ii++) { the_port = &control->ic_port[ii].icp_uart_port; @@ -2867,10 +2799,17 @@ void ioc4_serial_remove_one(struct pci_dev *pdev) kfree(soft); } kfree(control); - pci_set_drvdata(pdev, NULL); - uart_unregister_driver(&ioc4_uart); + idd->idd_serial_data = NULL; + + return 0; } -#endif + +static struct ioc4_submodule ioc4_serial_submodule = { + .is_name = "IOC4_serial", + .is_owner = THIS_MODULE, + .is_probe = ioc4_serial_attach_one, + .is_remove = ioc4_serial_remove_one, +}; /** * ioc4_serial_init - module init @@ -2886,12 +2825,20 @@ int ioc4_serial_init(void) __FUNCTION__); return ret; } - return 0; + + /* register with IOC4 main module */ + return ioc4_register_submodule(&ioc4_serial_submodule); } +static void __devexit ioc4_serial_exit(void) +{ + ioc4_unregister_submodule(&ioc4_serial_submodule); + uart_unregister_driver(&ioc4_uart); +} + +module_init(ioc4_serial_init); +module_exit(ioc4_serial_exit); + MODULE_AUTHOR("Pat Gefre - Silicon Graphics Inc. (SGI) "); MODULE_DESCRIPTION("Serial PCI driver module for SGI IOC4 Base-IO Card"); MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(ioc4_serial_init); -EXPORT_SYMBOL(ioc4_serial_attach_one); diff --git a/drivers/sn/ioc4.c b/drivers/sn/ioc4.c index d9e4ee280e5f..70862d72ea9d 100644 --- a/drivers/sn/ioc4.c +++ b/drivers/sn/ioc4.c @@ -6,60 +6,294 @@ * Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. */ -/* - * This file contains a shim driver for the IOC4 IDE and serial drivers. +/* This file contains the master driver module for use by SGI IOC4 subdrivers. + * + * It allocates any resources shared between multiple subdevices, and + * provides accessor functions (where needed) and the like for those + * resources. It also provides a mechanism for the subdevice modules + * to support loading and unloading. + * + * Non-shared resources (e.g. external interrupt A_INT_OUT register page + * alias, serial port and UART registers) are handled by the subdevice + * modules themselves. + * + * This is all necessary because IOC4 is not implemented as a multi-function + * PCI device, but an amalgamation of disparate registers for several + * types of device (ATA, serial, external interrupts). The normal + * resource management in the kernel doesn't have quite the right interfaces + * to handle this situation (e.g. multiple modules can't claim the same + * PCI ID), thus this IOC4 master module. */ #include #include #include -#include -#include +#include +#include +/************************ + * Submodule management * + ************************/ -static int __devinit -ioc4_probe_one(struct pci_dev *pdev, const struct pci_device_id *pci_id) +static LIST_HEAD(ioc4_devices); +static DECLARE_RWSEM(ioc4_devices_rwsem); + +static LIST_HEAD(ioc4_submodules); +static DECLARE_RWSEM(ioc4_submodules_rwsem); + +/* Register an IOC4 submodule */ +int +ioc4_register_submodule(struct ioc4_submodule *is) +{ + struct ioc4_driver_data *idd; + + down_write(&ioc4_submodules_rwsem); + list_add(&is->is_list, &ioc4_submodules); + up_write(&ioc4_submodules_rwsem); + + /* Initialize submodule for each IOC4 */ + if (!is->is_probe) + return 0; + + down_read(&ioc4_devices_rwsem); + list_for_each_entry(idd, &ioc4_devices, idd_list) { + if (is->is_probe(idd)) { + printk(KERN_WARNING + "%s: IOC4 submodule %s probe failed " + "for pci_dev %s", + __FUNCTION__, module_name(is->is_owner), + pci_name(idd->idd_pdev)); + } + } + up_read(&ioc4_devices_rwsem); + + return 0; +} + +/* Unregister an IOC4 submodule */ +void +ioc4_unregister_submodule(struct ioc4_submodule *is) { + struct ioc4_driver_data *idd; + + down_write(&ioc4_submodules_rwsem); + list_del(&is->is_list); + up_write(&ioc4_submodules_rwsem); + + /* Remove submodule for each IOC4 */ + if (!is->is_remove) + return; + + down_read(&ioc4_devices_rwsem); + list_for_each_entry(idd, &ioc4_devices, idd_list) { + if (is->is_remove(idd)) { + printk(KERN_WARNING + "%s: IOC4 submodule %s remove failed " + "for pci_dev %s.\n", + __FUNCTION__, module_name(is->is_owner), + pci_name(idd->idd_pdev)); + } + } + up_read(&ioc4_devices_rwsem); +} + +/********************* + * Device management * + *********************/ + +/* Adds a new instance of an IOC4 card */ +static int +ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) +{ + struct ioc4_driver_data *idd; + struct ioc4_submodule *is; + uint32_t pcmd; int ret; + /* Enable IOC4 and take ownership of it */ if ((ret = pci_enable_device(pdev))) { printk(KERN_WARNING - "%s: Failed to enable device with " - "pci_dev 0x%p... returning\n", - __FUNCTION__, (void *)pdev); - return ret; + "%s: Failed to enable IOC4 device for pci_dev %s.\n", + __FUNCTION__, pci_name(pdev)); + goto out; } pci_set_master(pdev); - /* attach each sub-device */ - ret = ioc4_ide_attach_one(pdev, pci_id); - if (ret) - return ret; - return ioc4_serial_attach_one(pdev, pci_id); + /* Set up per-IOC4 data */ + idd = kmalloc(sizeof(struct ioc4_driver_data), GFP_KERNEL); + if (!idd) { + printk(KERN_WARNING + "%s: Failed to allocate IOC4 data for pci_dev %s.\n", + __FUNCTION__, pci_name(pdev)); + ret = -ENODEV; + goto out_idd; + } + idd->idd_pdev = pdev; + idd->idd_pci_id = pci_id; + + /* Map IOC4 misc registers. These are shared between subdevices + * so the main IOC4 module manages them. + */ + idd->idd_bar0 = pci_resource_start(idd->idd_pdev, 0); + if (!idd->idd_bar0) { + printk(KERN_WARNING + "%s: Unable to find IOC4 misc resource " + "for pci_dev %s.\n", + __FUNCTION__, pci_name(idd->idd_pdev)); + ret = -ENODEV; + goto out_pci; + } + if (!request_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs), + "ioc4_misc")) { + printk(KERN_WARNING + "%s: Unable to request IOC4 misc region " + "for pci_dev %s.\n", + __FUNCTION__, pci_name(idd->idd_pdev)); + ret = -ENODEV; + goto out_pci; + } + idd->idd_misc_regs = ioremap(idd->idd_bar0, + sizeof(struct ioc4_misc_regs)); + if (!idd->idd_misc_regs) { + printk(KERN_WARNING + "%s: Unable to remap IOC4 misc region " + "for pci_dev %s.\n", + __FUNCTION__, pci_name(idd->idd_pdev)); + ret = -ENODEV; + goto out_misc_region; + } + + /* Failsafe portion of per-IOC4 initialization */ + + /* Initialize IOC4 */ + pci_read_config_dword(idd->idd_pdev, PCI_COMMAND, &pcmd); + pci_write_config_dword(idd->idd_pdev, PCI_COMMAND, + pcmd | PCI_COMMAND_PARITY | PCI_COMMAND_SERR); + + /* Disable/clear all interrupts. Need to do this here lest + * one submodule request the shared IOC4 IRQ, but interrupt + * is generated by a different subdevice. + */ + /* Disable */ + writel(~0, &idd->idd_misc_regs->other_iec.raw); + writel(~0, &idd->idd_misc_regs->sio_iec); + /* Clear (i.e. acknowledge) */ + writel(~0, &idd->idd_misc_regs->other_ir.raw); + writel(~0, &idd->idd_misc_regs->sio_ir); + + /* Track PCI-device specific data */ + idd->idd_serial_data = NULL; + pci_set_drvdata(idd->idd_pdev, idd); + down_write(&ioc4_devices_rwsem); + list_add(&idd->idd_list, &ioc4_devices); + up_write(&ioc4_devices_rwsem); + + /* Add this IOC4 to all submodules */ + down_read(&ioc4_submodules_rwsem); + list_for_each_entry(is, &ioc4_submodules, is_list) { + if (is->is_probe && is->is_probe(idd)) { + printk(KERN_WARNING + "%s: IOC4 submodule 0x%s probe failed " + "for pci_dev %s.\n", + __FUNCTION__, module_name(is->is_owner), + pci_name(idd->idd_pdev)); + } + } + up_read(&ioc4_submodules_rwsem); + + return 0; + +out_misc_region: + release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs)); +out_pci: + kfree(idd); +out_idd: + pci_disable_device(pdev); +out: + return ret; } -/* pci device struct */ -static struct pci_device_id ioc4_s_id_table[] = { +/* Removes a particular instance of an IOC4 card. */ +static void +ioc4_remove(struct pci_dev *pdev) +{ + struct ioc4_submodule *is; + struct ioc4_driver_data *idd; + + idd = pci_get_drvdata(pdev); + + /* Remove this IOC4 from all submodules */ + down_read(&ioc4_submodules_rwsem); + list_for_each_entry(is, &ioc4_submodules, is_list) { + if (is->is_remove && is->is_remove(idd)) { + printk(KERN_WARNING + "%s: IOC4 submodule 0x%s remove failed " + "for pci_dev %s.\n", + __FUNCTION__, module_name(is->is_owner), + pci_name(idd->idd_pdev)); + } + } + up_read(&ioc4_submodules_rwsem); + + /* Release resources */ + iounmap(idd->idd_misc_regs); + if (!idd->idd_bar0) { + printk(KERN_WARNING + "%s: Unable to get IOC4 misc mapping for pci_dev %s. " + "Device removal may be incomplete.\n", + __FUNCTION__, pci_name(idd->idd_pdev)); + } + release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs)); + + /* Disable IOC4 and relinquish */ + pci_disable_device(pdev); + + /* Remove and free driver data */ + down_write(&ioc4_devices_rwsem); + list_del(&idd->idd_list); + up_write(&ioc4_devices_rwsem); + kfree(idd); +} + +static struct pci_device_id ioc4_id_table[] = { {PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC4, PCI_ANY_ID, PCI_ANY_ID, 0x0b4000, 0xFFFFFF}, {0} }; -MODULE_DEVICE_TABLE(pci, ioc4_s_id_table); -static struct pci_driver __devinitdata ioc4_s_driver = { - .name = "IOC4", - .id_table = ioc4_s_id_table, - .probe = ioc4_probe_one, +static struct pci_driver __devinitdata ioc4_driver = { + .name = "IOC4", + .id_table = ioc4_id_table, + .probe = ioc4_probe, + .remove = ioc4_remove, }; -static int __devinit ioc4_detect(void) +MODULE_DEVICE_TABLE(pci, ioc4_id_table); + +/********************* + * Module management * + *********************/ + +/* Module load */ +static int __devinit +ioc4_init(void) { - ioc4_serial_init(); + return pci_register_driver(&ioc4_driver); +} - return pci_register_driver(&ioc4_s_driver); +/* Module unload */ +static void __devexit +ioc4_exit(void) +{ + pci_unregister_driver(&ioc4_driver); } -module_init(ioc4_detect); -MODULE_AUTHOR("Pat Gefre - Silicon Graphics Inc. (SGI) "); -MODULE_DESCRIPTION("PCI driver module for SGI IOC4 Base-IO Card"); +module_init(ioc4_init); +module_exit(ioc4_exit); + +MODULE_AUTHOR("Brent Casavant - Silicon Graphics, Inc. "); +MODULE_DESCRIPTION("PCI driver master module for SGI IOC4 Base-IO Card"); MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL(ioc4_register_submodule); +EXPORT_SYMBOL(ioc4_unregister_submodule); diff --git a/include/linux/ioc4.h b/include/linux/ioc4.h new file mode 100644 index 000000000000..729bfa4c4ac5 --- /dev/null +++ b/include/linux/ioc4.h @@ -0,0 +1,156 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved. + */ + +#ifndef _LINUX_IOC4_H +#define _LINUX_IOC4_H + +#include + +/*********************************** + * Structures needed by subdrivers * + ***********************************/ + +/* This structure fully describes the IOC4 miscellaneous registers which + * appear at bar[0]+0x00000 through bar[0]+0x0005c. The corresponding + * PCI resource is managed by the main IOC4 driver because it contains + * registers of interest to many different IOC4 subdrivers. + */ +struct ioc4_misc_regs { + /* Miscellaneous IOC4 registers */ + union ioc4_pci_err_addr_l { + uint32_t raw; + struct { + uint32_t valid:1; /* Address captured */ + uint32_t master_id:4; /* Unit causing error + * 0/1: Serial port 0 TX/RX + * 2/3: Serial port 1 TX/RX + * 4/5: Serial port 2 TX/RX + * 6/7: Serial port 3 TX/RX + * 8: ATA/ATAPI + * 9-15: Undefined + */ + uint32_t mul_err:1; /* Multiple errors occurred */ + uint32_t addr:26; /* Bits 31-6 of error addr */ + } fields; + } pci_err_addr_l; + uint32_t pci_err_addr_h; /* Bits 63-32 of error addr */ + union ioc4_sio_int { + uint32_t raw; + struct { + uint8_t tx_mt:1; /* TX ring buffer empty */ + uint8_t rx_full:1; /* RX ring buffer full */ + uint8_t rx_high:1; /* RX high-water exceeded */ + uint8_t rx_timer:1; /* RX timer has triggered */ + uint8_t delta_dcd:1; /* DELTA_DCD seen */ + uint8_t delta_cts:1; /* DELTA_CTS seen */ + uint8_t intr_pass:1; /* Interrupt pass-through */ + uint8_t tx_explicit:1; /* TX, MCW, or delay complete */ + } fields[4]; + } sio_ir; /* Serial interrupt state */ + union ioc4_other_int { + uint32_t raw; + struct { + uint32_t ata_int:1; /* ATA port passthru */ + uint32_t ata_memerr:1; /* ATA halted by mem error */ + uint32_t memerr:4; /* Serial halted by mem err */ + uint32_t kbd_int:1; /* kbd/mouse intr asserted */ + uint32_t reserved:16; /* zero */ + uint32_t rt_int:1; /* INT_OUT section latch */ + uint32_t gen_int:8; /* Intr. from generic pins */ + } fields; + } other_ir; /* Other interrupt state */ + union ioc4_sio_int sio_ies; /* Serial interrupt enable set */ + union ioc4_other_int other_ies; /* Other interrupt enable set */ + union ioc4_sio_int sio_iec; /* Serial interrupt enable clear */ + union ioc4_other_int other_iec; /* Other interrupt enable clear */ + union ioc4_sio_cr { + uint32_t raw; + struct { + uint32_t cmd_pulse:4; /* Bytebus strobe width */ + uint32_t arb_diag:3; /* PCI bus requester */ + uint32_t sio_diag_idle:1; /* Active ser req? */ + uint32_t ata_diag_idle:1; /* Active ATA req? */ + uint32_t ata_diag_active:1; /* ATA req is winner */ + uint32_t reserved:22; /* zero */ + } fields; + } sio_cr; + uint32_t unused1; + union ioc4_int_out { + uint32_t raw; + struct { + uint32_t count:16; /* Period control */ + uint32_t mode:3; /* Output signal shape */ + uint32_t reserved:11; /* zero */ + uint32_t diag:1; /* Timebase control */ + uint32_t int_out:1; /* Current value */ + } fields; + } int_out; /* External interrupt output control */ + uint32_t unused2; + union ioc4_gpcr { + uint32_t raw; + struct { + uint32_t dir:8; /* Pin direction */ + uint32_t edge:8; /* Edge/level mode */ + uint32_t reserved1:4; /* zero */ + uint32_t int_out_en:1; /* INT_OUT enable */ + uint32_t reserved2:11; /* zero */ + } fields; + } gpcr_s; /* Generic PIO control set */ + union ioc4_gpcr gpcr_c; /* Generic PIO control clear */ + union ioc4_gpdr { + uint32_t raw; + struct { + uint32_t gen_pin:8; /* State of pins */ + uint32_t reserved:24; + } fields; + } gpdr; /* Generic PIO data */ + uint32_t unused3; + union ioc4_gppr { + uint32_t raw; + struct { + uint32_t gen_pin:1; /* Single pin state */ + uint32_t reserved:31; + } fields; + } gppr[8]; /* Generic PIO pins */ +}; + +/* One of these per IOC4 + * + * The idd_serial_data field is present here, even though it's used + * solely by the serial subdriver, because the main IOC4 module + * properly owns pci_{get,set}_drvdata functionality. This field + * allows that subdriver to stash its own drvdata somewhere. + */ +struct ioc4_driver_data { + struct list_head idd_list; + unsigned long idd_bar0; + struct pci_dev *idd_pdev; + const struct pci_device_id *idd_pci_id; + struct __iomem ioc4_misc_regs *idd_misc_regs; + void *idd_serial_data; +}; + +/* One per submodule */ +struct ioc4_submodule { + struct list_head is_list; + char *is_name; + struct module *is_owner; + int (*is_probe) (struct ioc4_driver_data *); + int (*is_remove) (struct ioc4_driver_data *); +}; + +#define IOC4_NUM_CARDS 8 /* max cards per partition */ + +/********************************** + * Functions needed by submodules * + **********************************/ + +extern int ioc4_register_submodule(struct ioc4_submodule *); +extern void ioc4_unregister_submodule(struct ioc4_submodule *); + +#endif /* _LINUX_IOC4_H */ diff --git a/include/linux/ioc4_common.h b/include/linux/ioc4_common.h deleted file mode 100644 index b03bcc46df55..000000000000 --- a/include/linux/ioc4_common.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved. - */ - -#ifndef _LINUX_IOC4_COMMON_H -#define _LINUX_IOC4_COMMON_H - -/* prototypes */ - -int ioc4_serial_init(void); - -int ioc4_serial_attach_one(struct pci_dev *pdev, const struct - pci_device_id *pci_id); -int ioc4_ide_attach_one(struct pci_dev *pdev, const struct - pci_device_id *pci_id); - -#endif /* _LINUX_IOC4_COMMON_H */ -- cgit v1.2.3-59-g8ed1b From e5d310b349b2cbcc0dab31139c92201f332695bb Mon Sep 17 00:00:00 2001 From: Brent Casavant Date: Tue, 21 Jun 2005 17:16:01 -0700 Subject: [PATCH] ioc4: CONFIG split The SGI IOC4 I/O controller chip drivers are currently all configured by CONFIG_BLK_DEV_SGIIOC4. This is undesirable as not all IOC4 hardware features are needed by all systems. This patch adds two configuration variables, CONFIG_SGI_IOC4 for core IOC4 driver support (see patch 1/3 in this series for further explanation) and CONFIG_SERIAL_SGI_IOC4 to independently enable serial port support. Signed-off-by: Brent Casavant Acked-by: Pat Gefre Acked-by: Jeremy Higdon Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/configs/sn2_defconfig | 6 ++++++ arch/ia64/defconfig | 6 ++++++ drivers/Kconfig | 2 ++ drivers/Makefile | 2 +- drivers/ide/Kconfig | 4 ++-- drivers/serial/Kconfig | 9 +++++++++ drivers/serial/Makefile | 2 +- drivers/sn/Kconfig | 20 ++++++++++++++++++++ drivers/sn/Makefile | 2 +- 9 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 drivers/sn/Kconfig diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig index 6ff7107fee4d..a01bb02d074d 100644 --- a/arch/ia64/configs/sn2_defconfig +++ b/arch/ia64/configs/sn2_defconfig @@ -588,6 +588,7 @@ CONFIG_SGI_MBCS=m CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_SGI_L1_CONSOLE=y +CONFIG_SERIAL_SGI_IOC4=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -787,6 +788,11 @@ CONFIG_INFINIBAND_MTHCA=m CONFIG_INFINIBAND_IPOIB=m # CONFIG_INFINIBAND_IPOIB_DEBUG is not set +# +# SN Devices +# +CONFIG_SGI_IOC4=y + # # File systems # diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig index 7539e83bf054..9997ef45ab23 100644 --- a/arch/ia64/defconfig +++ b/arch/ia64/defconfig @@ -638,6 +638,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_SGI_L1_CONSOLE=y +CONFIG_SERIAL_SGI_IOC4=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -942,6 +943,11 @@ CONFIG_INFINIBAND_MTHCA=m CONFIG_INFINIBAND_IPOIB=m # CONFIG_INFINIBAND_IPOIB_DEBUG is not set +# +# SN Devices +# +CONFIG_SGI_IOC4=y + # # File systems # diff --git a/drivers/Kconfig b/drivers/Kconfig index ed41d9036bfc..aed4a9b97c14 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -58,4 +58,6 @@ source "drivers/mmc/Kconfig" source "drivers/infiniband/Kconfig" +source "drivers/sn/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 15681de688f4..3167be54fedd 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -61,6 +61,6 @@ obj-$(CONFIG_EISA) += eisa/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_MMC) += mmc/ obj-$(CONFIG_INFINIBAND) += infiniband/ -obj-$(CONFIG_BLK_DEV_SGIIOC4) += sn/ +obj-$(CONFIG_SGI_IOC4) += sn/ obj-y += firmware/ obj-$(CONFIG_CRYPTO) += crypto/ diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 3ac0a535b4aa..0273f124a4f7 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -672,8 +672,8 @@ config BLK_DEV_SVWKS chipsets. config BLK_DEV_SGIIOC4 - tristate "Silicon Graphics IOC4 chipset support" - depends on IA64_SGI_SN2 || IA64_GENERIC + tristate "Silicon Graphics IOC4 chipset ATA/ATAPI support" + depends on (IA64_SGI_SN2 || IA64_GENERIC) && SGI_IOC4 help This driver adds PIO & MultiMode DMA-2 support for the SGI IOC4 chipset, which has one channel and can support two devices. diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 6a15703f1cb9..25fcef2c42de 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -843,4 +843,13 @@ config SERIAL_JSM To compile this driver as a module, choose M here: the module will be called jsm. +config SERIAL_SGI_IOC4 + tristate "SGI IOC4 controller serial support" + depends on (IA64_GENERIC || IA64_SGI_SN2) && SGI_IOC4 + select SERIAL_CORE + help + If you have an SGI Altix with an IOC4 based Base IO card + and wish to use the serial ports on this card, say Y. + Otherwise, say N. + endmenu diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 81b77d769b84..8f1cdde7dbed 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -51,4 +51,4 @@ obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o obj-$(CONFIG_SERIAL_JSM) += jsm/ obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o -obj-$(CONFIG_BLK_DEV_SGIIOC4) += ioc4_serial.o +obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o diff --git a/drivers/sn/Kconfig b/drivers/sn/Kconfig new file mode 100644 index 000000000000..20f7515ab830 --- /dev/null +++ b/drivers/sn/Kconfig @@ -0,0 +1,20 @@ +# +# Miscellaneous SN-specific devices +# + +menu "SN Devices" + +config SGI_IOC4 + tristate "SGI IOC4 Base IO support" + depends on IA64_GENERIC || IA64_SGI_SN2 + default m + ---help--- + This option enables basic support for the SGI IOC4-based Base IO + controller card. This option does not enable any specific + functions on such a card, but provides necessary infrastructure + for other drivers to utilize. + + If you have an SGI Altix with an IOC4-based + I/O controller say Y. Otherwise say N. + +endmenu diff --git a/drivers/sn/Makefile b/drivers/sn/Makefile index 631e54958448..c2a284185372 100644 --- a/drivers/sn/Makefile +++ b/drivers/sn/Makefile @@ -3,4 +3,4 @@ # # -obj-$(CONFIG_BLK_DEV_SGIIOC4) += ioc4.o +obj-$(CONFIG_SGI_IOC4) += ioc4.o -- cgit v1.2.3-59-g8ed1b From d4c477ca5448f19afaaf6c0cfd655009ea9e614d Mon Sep 17 00:00:00 2001 From: Brent Casavant Date: Tue, 21 Jun 2005 17:16:01 -0700 Subject: [PATCH] ioc4: PCI bus speed detection Several hardware features of SGI's IOC4 I/O controller chip require timing-related driver calculations dependent upon the PCI bus speed. This patch enables the core IOC4 driver code to detect the actual bus speed and store a value that can later be used by the IOC4 subdrivers as needed. Signed-off-by: Brent Casavant Acked-by: Pat Gefre Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/ioc4_serial.c | 31 ++++++----- drivers/sn/Kconfig | 2 +- drivers/sn/ioc4.c | 128 +++++++++++++++++++++++++++++++++++++++++++ include/linux/ioc4.h | 37 ++++++++++--- 4 files changed, 177 insertions(+), 21 deletions(-) diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c index da5f10eb4845..793c3a7cbe47 100644 --- a/drivers/serial/ioc4_serial.c +++ b/drivers/serial/ioc4_serial.c @@ -299,7 +299,6 @@ struct ioc4_serial { } ioc4_serial; /* UART clock speed */ -#define IOC4_SER_XIN_CLK IOC4_SER_XIN_CLK_66 #define IOC4_SER_XIN_CLK_66 66666667 #define IOC4_SER_XIN_CLK_33 33333333 @@ -1012,21 +1011,20 @@ static irqreturn_t ioc4_intr(int irq, void *arg, struct pt_regs *regs) * ioc4_attach_local - Device initialization. * Called at *_attach() time for each * IOC4 with serial ports in the system. - * @control: ioc4_control ptr - * @pdev: PCI handle for this device - * @soft: soft struct for this device - * @ioc4: ioc4 mem space + * @idd: Master module data for this IOC4 */ -static int inline ioc4_attach_local(struct pci_dev *pdev, - struct ioc4_control *control, - struct ioc4_soft *soft, void __iomem *ioc4_misc, - void __iomem *ioc4_serial) +static int inline ioc4_attach_local(struct ioc4_driver_data *idd) { struct ioc4_port *port; struct ioc4_port *ports[IOC4_NUM_SERIAL_PORTS]; int port_number; uint16_t ioc4_revid_min = 62; uint16_t ioc4_revid; + struct pci_dev *pdev = idd->idd_pdev; + struct ioc4_control* control = idd->idd_serial_data; + struct ioc4_soft *soft = control->ic_soft; + void __iomem *ioc4_misc = idd->idd_misc_regs; + void __iomem *ioc4_serial = soft->is_ioc4_serial_addr; /* IOC4 firmware must be at least rev 62 */ pci_read_config_word(pdev, PCI_COMMAND_SPECIAL, &ioc4_revid); @@ -1063,7 +1061,15 @@ static int inline ioc4_attach_local(struct pci_dev *pdev, port->ip_ioc4_soft = soft; port->ip_pdev = pdev; port->ip_ienb = 0; - port->ip_pci_bus_speed = IOC4_SER_XIN_CLK; + /* Use baud rate calculations based on detected PCI + * bus speed. Simply test whether the PCI clock is + * running closer to 66MHz or 33MHz. + */ + if (idd->count_period/IOC4_EXTINT_COUNT_DIVISOR < 20) { + port->ip_pci_bus_speed = IOC4_SER_XIN_CLK_66; + } else { + port->ip_pci_bus_speed = IOC4_SER_XIN_CLK_33; + } port->ip_baud = 9600; port->ip_control = control; port->ip_mem = ioc4_misc; @@ -2733,9 +2739,8 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd) "%s : request_irq fails for IRQ 0x%x\n ", __FUNCTION__, idd->idd_pdev->irq); } - if ((ret = ioc4_attach_local(idd->idd_pdev, control, soft, - soft->is_ioc4_misc_addr, - soft->is_ioc4_serial_addr))) + ret = ioc4_attach_local(idd); + if (ret) goto out4; /* register port with the serial core */ diff --git a/drivers/sn/Kconfig b/drivers/sn/Kconfig index 20f7515ab830..13b8d249da5c 100644 --- a/drivers/sn/Kconfig +++ b/drivers/sn/Kconfig @@ -6,7 +6,7 @@ menu "SN Devices" config SGI_IOC4 tristate "SGI IOC4 Base IO support" - depends on IA64_GENERIC || IA64_SGI_SN2 + depends on (IA64_GENERIC || IA64_SGI_SN2) && MMTIMER default m ---help--- This option enables basic support for the SGI IOC4-based Base IO diff --git a/drivers/sn/ioc4.c b/drivers/sn/ioc4.c index 70862d72ea9d..ea75b3d0612b 100644 --- a/drivers/sn/ioc4.c +++ b/drivers/sn/ioc4.c @@ -29,7 +29,26 @@ #include #include #include +#include +#include #include +#include +#include +#include + +/*************** + * Definitions * + ***************/ + +/* Tweakable values */ + +/* PCI bus speed detection/calibration */ +#define IOC4_CALIBRATE_COUNT 63 /* Calibration cycle period */ +#define IOC4_CALIBRATE_CYCLES 256 /* Average over this many cycles */ +#define IOC4_CALIBRATE_DISCARD 2 /* Discard first few cycles */ +#define IOC4_CALIBRATE_LOW_MHZ 25 /* Lower bound on bus speed sanity */ +#define IOC4_CALIBRATE_HIGH_MHZ 75 /* Upper bound on bus speed sanity */ +#define IOC4_CALIBRATE_DEFAULT_MHZ 66 /* Assumed if sanity check fails */ /************************ * Submodule management * @@ -101,6 +120,112 @@ ioc4_unregister_submodule(struct ioc4_submodule *is) * Device management * *********************/ +#define IOC4_CALIBRATE_LOW_LIMIT \ + (1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_LOW_MHZ) +#define IOC4_CALIBRATE_HIGH_LIMIT \ + (1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_HIGH_MHZ) +#define IOC4_CALIBRATE_DEFAULT \ + (1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_DEFAULT_MHZ) + +#define IOC4_CALIBRATE_END \ + (IOC4_CALIBRATE_CYCLES + IOC4_CALIBRATE_DISCARD) + +#define IOC4_INT_OUT_MODE_TOGGLE 0x7 /* Toggle INT_OUT every COUNT+1 ticks */ + +/* Determines external interrupt output clock period of the PCI bus an + * IOC4 is attached to. This value can be used to determine the PCI + * bus speed. + * + * IOC4 has a design feature that various internal timers are derived from + * the PCI bus clock. This causes IOC4 device drivers to need to take the + * bus speed into account when setting various register values (e.g. INT_OUT + * register COUNT field, UART divisors, etc). Since this information is + * needed by several subdrivers, it is determined by the main IOC4 driver, + * even though the following code utilizes external interrupt registers + * to perform the speed calculation. + */ +static void +ioc4_clock_calibrate(struct ioc4_driver_data *idd) +{ + extern unsigned long sn_rtc_cycles_per_second; + union ioc4_int_out int_out; + union ioc4_gpcr gpcr; + unsigned int state, last_state = 1; + uint64_t start = 0, end, period; + unsigned int count = 0; + + /* Enable output */ + gpcr.raw = 0; + gpcr.fields.dir = IOC4_GPCR_DIR_0; + gpcr.fields.int_out_en = 1; + writel(gpcr.raw, &idd->idd_misc_regs->gpcr_s.raw); + + /* Reset to power-on state */ + writel(0, &idd->idd_misc_regs->int_out.raw); + mmiowb(); + + printk(KERN_INFO + "%s: Calibrating PCI bus speed " + "for pci_dev %s ... ", __FUNCTION__, pci_name(idd->idd_pdev)); + /* Set up square wave */ + int_out.raw = 0; + int_out.fields.count = IOC4_CALIBRATE_COUNT; + int_out.fields.mode = IOC4_INT_OUT_MODE_TOGGLE; + int_out.fields.diag = 0; + writel(int_out.raw, &idd->idd_misc_regs->int_out.raw); + mmiowb(); + + /* Check square wave period averaged over some number of cycles */ + do { + int_out.raw = readl(&idd->idd_misc_regs->int_out.raw); + state = int_out.fields.int_out; + if (!last_state && state) { + count++; + if (count == IOC4_CALIBRATE_END) { + end = rtc_time(); + break; + } else if (count == IOC4_CALIBRATE_DISCARD) + start = rtc_time(); + } + last_state = state; + } while (1); + + /* Calculation rearranged to preserve intermediate precision. + * Logically: + * 1. "end - start" gives us number of RTC cycles over all the + * square wave cycles measured. + * 2. Divide by number of square wave cycles to get number of + * RTC cycles per square wave cycle. + * 3. Divide by 2*(int_out.fields.count+1), which is the formula + * by which the IOC4 generates the square wave, to get the + * number of RTC cycles per IOC4 INT_OUT count. + * 4. Divide by sn_rtc_cycles_per_second to get seconds per + * count. + * 5. Multiply by 1E9 to get nanoseconds per count. + */ + period = ((end - start) * 1000000000) / + (IOC4_CALIBRATE_CYCLES * 2 * (IOC4_CALIBRATE_COUNT + 1) + * sn_rtc_cycles_per_second); + + /* Bounds check the result. */ + if (period > IOC4_CALIBRATE_LOW_LIMIT || + period < IOC4_CALIBRATE_HIGH_LIMIT) { + printk("failed. Assuming PCI clock ticks are %d ns.\n", + IOC4_CALIBRATE_DEFAULT / IOC4_EXTINT_COUNT_DIVISOR); + period = IOC4_CALIBRATE_DEFAULT; + } else { + printk("succeeded. PCI clock ticks are %ld ns.\n", + period / IOC4_EXTINT_COUNT_DIVISOR); + } + + /* Remember results. We store the extint clock period rather + * than the PCI clock period so that greater precision is + * retained. Divide by IOC4_EXTINT_COUNT_DIVISOR to get + * PCI clock period. + */ + idd->count_period = period; +} + /* Adds a new instance of an IOC4 card */ static int ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) @@ -170,6 +295,9 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) pci_write_config_dword(idd->idd_pdev, PCI_COMMAND, pcmd | PCI_COMMAND_PARITY | PCI_COMMAND_SERR); + /* Determine PCI clock */ + ioc4_clock_calibrate(idd); + /* Disable/clear all interrupts. Need to do this here lest * one submodule request the shared IOC4 IRQ, but interrupt * is generated by a different subdevice. diff --git a/include/linux/ioc4.h b/include/linux/ioc4.h index 729bfa4c4ac5..3dd18b785ebd 100644 --- a/include/linux/ioc4.h +++ b/include/linux/ioc4.h @@ -11,6 +11,14 @@ #include +/*************** + * Definitions * + ***************/ + +/* Miscellaneous values inherent to hardware */ + +#define IOC4_EXTINT_COUNT_DIVISOR 520 /* PCI clocks per COUNT tick */ + /*********************************** * Structures needed by subdrivers * ***********************************/ @@ -119,19 +127,34 @@ struct ioc4_misc_regs { } gppr[8]; /* Generic PIO pins */ }; -/* One of these per IOC4 - * - * The idd_serial_data field is present here, even though it's used - * solely by the serial subdriver, because the main IOC4 module - * properly owns pci_{get,set}_drvdata functionality. This field - * allows that subdriver to stash its own drvdata somewhere. - */ +/* Masks for GPCR DIR pins */ +#define IOC4_GPCR_DIR_0 0x01 /* External interrupt output */ +#define IOC4_GPCR_DIR_1 0x02 /* External interrupt input */ +#define IOC4_GPCR_DIR_2 0x04 +#define IOC4_GPCR_DIR_3 0x08 /* Keyboard/mouse presence */ +#define IOC4_GPCR_DIR_4 0x10 /* Ser. port 0 xcvr select (0=232, 1=422) */ +#define IOC4_GPCR_DIR_5 0x20 /* Ser. port 1 xcvr select (0=232, 1=422) */ +#define IOC4_GPCR_DIR_6 0x40 /* Ser. port 2 xcvr select (0=232, 1=422) */ +#define IOC4_GPCR_DIR_7 0x80 /* Ser. port 3 xcvr select (0=232, 1=422) */ + +/* Masks for GPCR EDGE pins */ +#define IOC4_GPCR_EDGE_0 0x01 +#define IOC4_GPCR_EDGE_1 0x02 /* External interrupt input */ +#define IOC4_GPCR_EDGE_2 0x04 +#define IOC4_GPCR_EDGE_3 0x08 +#define IOC4_GPCR_EDGE_4 0x10 +#define IOC4_GPCR_EDGE_5 0x20 +#define IOC4_GPCR_EDGE_6 0x40 +#define IOC4_GPCR_EDGE_7 0x80 + +/* One of these per IOC4 */ struct ioc4_driver_data { struct list_head idd_list; unsigned long idd_bar0; struct pci_dev *idd_pdev; const struct pci_device_id *idd_pci_id; struct __iomem ioc4_misc_regs *idd_misc_regs; + unsigned long count_period; void *idd_serial_data; }; -- cgit v1.2.3-59-g8ed1b From 2368086344c3d67b0f4aecac39d620fb9b8795c3 Mon Sep 17 00:00:00 2001 From: Hirokazu Takata Date: Tue, 21 Jun 2005 17:16:10 -0700 Subject: [PATCH] m32r: Support M3A-2170(Mappi-III) platform This patchset is for supporting a new m32r platform, M3A-2170(Mappi-III) evaluation board. An M32R chip multiprocessor is equipped on the board. http://http://www.linux-m32r.org/eng/platform/platform.html * arch/m32r/Kconfig: Support Mappi-III platform. * arch/m32r/kernel/Makefile: ditto. * arch/m32r/kernel/io_mappi3.c: ditto. * arch/m32r/kernel/setup.c: ditto. * arch/m32r/kernel/setup_mappi3.c: ditto. * include/asm-m32r/m32102.h: ditto. * include/asm-m32r/m32r.h: ditto. * include/asm-m32r/mappi3/mappi3_pld.h: ditto. * include/asm-m32r/ide.h: CF support for Mappi-III. * arch/m32r/kernel/setup_mappi3.c: ditto. * arch/m32r/mappi3/defconfig.smp: A default config file for Mappi-III. * arch/m32r/mappi3/dot.gdbinit: A default .gdbinit file for Mappi-III. * arch/m32r/boot/compressed/m32r_sio.c: Modified for Mappi-III - At boot time, m32r-g00ff bootloader makes MMU off for Mappi-III, on the contrary it makes MMU on for Mappi-II. * arch/m32r/kernel/io_mappi2.c: Update comments. * arch/m32r/kernel/setup_mappi2.c: ditto. Signed-off-by: Mamoru Sakugawa Signed-off-by: Hirokazu Takata Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/m32r/Kconfig | 7 +- arch/m32r/boot/compressed/m32r_sio.c | 19 +- arch/m32r/kernel/Makefile | 2 +- arch/m32r/kernel/io_m32700ut.c | 92 +---- arch/m32r/kernel/io_mappi.c | 74 +--- arch/m32r/kernel/io_mappi2.c | 92 +---- arch/m32r/kernel/io_mappi3.c | 378 ++++++++++++++++++ arch/m32r/kernel/io_oaks32r.c | 36 +- arch/m32r/kernel/io_opsput.c | 79 +--- arch/m32r/kernel/io_usrv.c | 51 +-- arch/m32r/kernel/setup.c | 2 + arch/m32r/kernel/setup_mappi2.c | 6 +- arch/m32r/kernel/setup_mappi3.c | 208 ++++++++++ arch/m32r/mappi3/defconfig.smp | 751 +++++++++++++++++++++++++++++++++++ arch/m32r/mappi3/dot.gdbinit | 224 +++++++++++ include/asm-m32r/ide.h | 2 +- include/asm-m32r/m32102.h | 1 + include/asm-m32r/m32r.h | 4 + include/asm-m32r/mappi3/mappi3_pld.h | 143 +++++++ 19 files changed, 1785 insertions(+), 386 deletions(-) create mode 100644 arch/m32r/kernel/io_mappi3.c create mode 100644 arch/m32r/kernel/setup_mappi3.c create mode 100644 arch/m32r/mappi3/defconfig.smp create mode 100644 arch/m32r/mappi3/dot.gdbinit create mode 100644 include/asm-m32r/mappi3/mappi3_pld.h diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index 0d90ea58a0cb..64c133344afe 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig @@ -78,6 +78,9 @@ config PLAT_OAKS32R config PLAT_MAPPI2 bool "Mappi-II(M3A-ZA36/M3A-ZA52)" +config PLAT_MAPPI3 + bool "Mappi-III(M3A-2170)" + endchoice choice @@ -134,6 +137,7 @@ config BUS_CLOCK int "Bus Clock [Hz] (integer)" default "70000000" if PLAT_MAPPI default "25000000" if PLAT_USRV + default "50000000" if PLAT_MAPPI3 default "50000000" if PLAT_M32700UT default "50000000" if PLAT_OPSPUT default "33333333" if PLAT_OAKS32R @@ -149,7 +153,7 @@ config CPU_LITTLE_ENDIAN config MEMORY_START hex "Physical memory start address (hex)" - default "08000000" if PLAT_MAPPI || PLAT_MAPPI2 + default "08000000" if PLAT_MAPPI || PLAT_MAPPI2 || PLAT_MAPPI3 default "08000000" if PLAT_USRV default "08000000" if PLAT_M32700UT default "08000000" if PLAT_OPSPUT @@ -157,6 +161,7 @@ config MEMORY_START config MEMORY_SIZE hex "Physical memory size (hex)" + default "08000000" if PLAT_MAPPI3 default "04000000" if PLAT_MAPPI || PLAT_MAPPI2 default "02000000" if PLAT_USRV default "01000000" if PLAT_M32700UT diff --git a/arch/m32r/boot/compressed/m32r_sio.c b/arch/m32r/boot/compressed/m32r_sio.c index bad5475eff90..8f9a57271f83 100644 --- a/arch/m32r/boot/compressed/m32r_sio.c +++ b/arch/m32r/boot/compressed/m32r_sio.c @@ -6,6 +6,7 @@ */ #include +#include static void putc(char c); @@ -38,16 +39,17 @@ static int puts(const char *s) static void putc(char c) { - - while ((*BOOT_SIO0STS & 0x3) != 0x3) ; + while ((*BOOT_SIO0STS & 0x3) != 0x3) + cpu_relax(); if (c == '\n') { *BOOT_SIO0TXB = '\r'; - while ((*BOOT_SIO0STS & 0x3) != 0x3) ; + while ((*BOOT_SIO0STS & 0x3) != 0x3) + cpu_relax(); } *BOOT_SIO0TXB = c; } -#else /* defined(CONFIG_PLAT_M32700UT_Alpha) || defined(CONFIG_PLAT_M32700UT) */ -#ifdef CONFIG_MMU +#else /* !(CONFIG_PLAT_M32700UT_Alpha) && !(CONFIG_PLAT_M32700UT) */ +#if defined(CONFIG_PLAT_MAPPI2) #define SIO0STS (volatile unsigned short *)(0xa0efd000 + 14) #define SIO0TXB (volatile unsigned short *)(0xa0efd000 + 30) #else @@ -57,11 +59,12 @@ static void putc(char c) static void putc(char c) { - - while ((*SIO0STS & 0x1) == 0) ; + while ((*SIO0STS & 0x1) == 0) + cpu_relax(); if (c == '\n') { *SIO0TXB = '\r'; - while ((*SIO0STS & 0x1) == 0) ; + while ((*SIO0STS & 0x1) == 0) + cpu_relax(); } *SIO0TXB = c; } diff --git a/arch/m32r/kernel/Makefile b/arch/m32r/kernel/Makefile index cfd690bf6d8a..6c6b6c376638 100644 --- a/arch/m32r/kernel/Makefile +++ b/arch/m32r/kernel/Makefile @@ -10,6 +10,7 @@ obj-y := process.o entry.o traps.o align.o irq.o setup.o time.o \ obj-$(CONFIG_SMP) += smp.o smpboot.o obj-$(CONFIG_PLAT_MAPPI) += setup_mappi.o io_mappi.o obj-$(CONFIG_PLAT_MAPPI2) += setup_mappi2.o io_mappi2.o +obj-$(CONFIG_PLAT_MAPPI3) += setup_mappi3.o io_mappi3.o obj-$(CONFIG_PLAT_USRV) += setup_usrv.o io_usrv.o obj-$(CONFIG_PLAT_M32700UT) += setup_m32700ut.o io_m32700ut.o obj-$(CONFIG_PLAT_OPSPUT) += setup_opsput.o io_opsput.o @@ -17,4 +18,3 @@ obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_PLAT_OAKS32R) += setup_oaks32r.o io_oaks32r.o EXTRA_AFLAGS := -traditional - diff --git a/arch/m32r/kernel/io_m32700ut.c b/arch/m32r/kernel/io_m32700ut.c index 371ba904e968..e545b065f7e9 100644 --- a/arch/m32r/kernel/io_m32700ut.c +++ b/arch/m32r/kernel/io_m32700ut.c @@ -3,8 +3,8 @@ * * Typical I/O routines for M32700UT board. * - * Copyright (c) 2001, 2002 Hiroyuki Kondo, Hirokazu Takata, - * Hitoshi Yamamoto, Takeo Takahashi + * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata, + * Hitoshi Yamamoto, Takeo Takahashi * * This file is subject to the terms and conditions of the GNU General * Public License. See the file "COPYING" in the main directory of this @@ -172,64 +172,21 @@ unsigned long _inl(unsigned long port) unsigned char _inb_p(unsigned long port) { - unsigned char v; - - if (port >= LAN_IOSTART && port < LAN_IOEND) - v = _ne_inb(PORT2ADDR_NE(port)); - else -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { - return *(volatile unsigned char *)__port2addr_ata(port); - } else -#endif -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) - if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { - unsigned char b; - pcc_ioread_byte(0, port, &b, sizeof(b), 1, 0); - return b; - } else -#endif - v = *(volatile unsigned char *)PORT2ADDR(port); - + unsigned char v = _inb(port); delay(); return (v); } unsigned short _inw_p(unsigned long port) { - unsigned short v; - - if (port >= LAN_IOSTART && port < LAN_IOEND) - v = _ne_inw(PORT2ADDR_NE(port)); - else -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { - return *(volatile unsigned short *)__port2addr_ata(port); - } else -#endif -#if defined(CONFIG_USB) - if(port >= 0x340 && port < 0x3a0) - return *(volatile unsigned short *)PORT2ADDR_USB(port); - else -#endif -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) - if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { - unsigned short w; - pcc_ioread_word(0, port, &w, sizeof(w), 1, 0); - return w; - } else -#endif - v = *(volatile unsigned short *)PORT2ADDR(port); - + unsigned short v = _inw(port); delay(); return (v); } unsigned long _inl_p(unsigned long port) { - unsigned long v; - - v = *(volatile unsigned long *)PORT2ADDR(port); + unsigned long v = _inl(port); delay(); return (v); } @@ -287,52 +244,19 @@ void _outl(unsigned long l, unsigned long port) void _outb_p(unsigned char b, unsigned long port) { - if (port >= LAN_IOSTART && port < LAN_IOEND) - _ne_outb(b, PORT2ADDR_NE(port)); - else -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { - *(volatile unsigned char *)__port2addr_ata(port) = b; - } else -#endif -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) - if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { - pcc_iowrite_byte(0, port, &b, sizeof(b), 1, 0); - } else -#endif - *(volatile unsigned char *)PORT2ADDR(port) = b; - + _outb(b, port); delay(); } void _outw_p(unsigned short w, unsigned long port) { - if (port >= LAN_IOSTART && port < LAN_IOEND) - _ne_outw(w, PORT2ADDR_NE(port)); - else -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { - *(volatile unsigned short *)__port2addr_ata(port) = w; - } else -#endif -#if defined(CONFIG_USB) - if(port >= 0x340 && port < 0x3a0) - *(volatile unsigned short *)PORT2ADDR_USB(port) = w; - else -#endif -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) - if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { - pcc_iowrite_word(0, port, &w, sizeof(w), 1, 0); - } else -#endif - *(volatile unsigned short *)PORT2ADDR(port) = w; - + _outw(w, port); delay(); } void _outl_p(unsigned long l, unsigned long port) { - *(volatile unsigned long *)PORT2ADDR(port) = l; + _outl(l, port); delay(); } diff --git a/arch/m32r/kernel/io_mappi.c b/arch/m32r/kernel/io_mappi.c index 85688ffb52f9..78033165fb5c 100644 --- a/arch/m32r/kernel/io_mappi.c +++ b/arch/m32r/kernel/io_mappi.c @@ -3,8 +3,8 @@ * * Typical I/O routines for Mappi board. * - * Copyright (c) 2001, 2002 Hiroyuki Kondo, Hirokazu Takata, - * Hitoshi Yamamoto + * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata, + * Hitoshi Yamamoto */ #include @@ -130,57 +130,21 @@ unsigned long _inl(unsigned long port) unsigned char _inb_p(unsigned long port) { - unsigned char v; - - if (port >= 0x300 && port < 0x320) - v = _ne_inb(PORT2ADDR_NE(port)); - else -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) - if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { - unsigned char b; - pcc_ioread(0, port, &b, sizeof(b), 1, 0); - return b; - } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { - unsigned char b; - pcc_ioread(1, port, &b, sizeof(b), 1, 0); - return b; - } else -#endif - v = *(volatile unsigned char *)PORT2ADDR(port); - + unsigned char v = _inb(port); delay(); return (v); } unsigned short _inw_p(unsigned long port) { - unsigned short v; - - if (port >= 0x300 && port < 0x320) - v = _ne_inw(PORT2ADDR_NE(port)); - else -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) - if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { - unsigned short w; - pcc_ioread(0, port, &w, sizeof(w), 1, 0); - return w; - } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { - unsigned short w; - pcc_ioread(1, port, &w, sizeof(w), 1, 0); - return w; - } else -#endif - v = *(volatile unsigned short *)PORT2ADDR(port); - + unsigned short v = _inw(port); delay(); return (v); } unsigned long _inl_p(unsigned long port) { - unsigned long v; - - v = *(volatile unsigned long *)PORT2ADDR(port); + unsigned long v = _inl(port); delay(); return (v); } @@ -229,41 +193,19 @@ void _outl(unsigned long l, unsigned long port) void _outb_p(unsigned char b, unsigned long port) { - if (port >= 0x300 && port < 0x320) - _ne_outb(b, PORT2ADDR_NE(port)); - else -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) - if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { - pcc_iowrite(0, port, &b, sizeof(b), 1, 0); - } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { - pcc_iowrite(1, port, &b, sizeof(b), 1, 0); - } else -#endif - *(volatile unsigned char *)PORT2ADDR(port) = b; - + _outb(b, port); delay(); } void _outw_p(unsigned short w, unsigned long port) { - if (port >= 0x300 && port < 0x320) - _ne_outw(w, PORT2ADDR_NE(port)); - else -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) - if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { - pcc_iowrite(0, port, &w, sizeof(w), 1, 0); - } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { - pcc_iowrite(1, port, &w, sizeof(w), 1, 0); - } else -#endif - *(volatile unsigned short *)PORT2ADDR(port) = w; - + _outw(w, port); delay(); } void _outl_p(unsigned long l, unsigned long port) { - *(volatile unsigned long *)PORT2ADDR(port) = l; + _outl(l, port); delay(); } diff --git a/arch/m32r/kernel/io_mappi2.c b/arch/m32r/kernel/io_mappi2.c index 4182cd4f97c8..5c03504bf653 100644 --- a/arch/m32r/kernel/io_mappi2.c +++ b/arch/m32r/kernel/io_mappi2.c @@ -3,7 +3,7 @@ * * Typical I/O routines for Mappi2 board. * - * Copyright (c) 2001-2003 Hiroyuki Kondo, Hirokazu Takata, + * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata, * Hitoshi Yamamoto, Mamoru Sakugawa */ @@ -25,7 +25,7 @@ extern void pcc_ioread_byte(int, unsigned long, void *, size_t, size_t, int); extern void pcc_ioread_word(int, unsigned long, void *, size_t, size_t, int); extern void pcc_iowrite_byte(int, unsigned long, void *, size_t, size_t, int); extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int); -#endif /* CONFIG_PCMCIA && CONFIG_MAPPI2_CFC */ +#endif /* CONFIG_PCMCIA && CONFIG_M32R_CFC */ #define PORT2ADDR(port) _port2addr(port) #define PORT2ADDR_NE(port) _port2addr_ne(port) @@ -169,64 +169,21 @@ unsigned long _inl(unsigned long port) unsigned char _inb_p(unsigned long port) { - unsigned char v; - - if (port >= LAN_IOSTART && port < LAN_IOEND) - v = _ne_inb(PORT2ADDR_NE(port)); - else -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { - return *(volatile unsigned char *)__port2addr_ata(port); - } else -#endif -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) - if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { - unsigned char b; - pcc_ioread_byte(0, port, &b, sizeof(b), 1, 0); - return b; - } else -#endif - v = *(volatile unsigned char *)PORT2ADDR(port); - + unsigned char v = _inb(port); delay(); return (v); } unsigned short _inw_p(unsigned long port) { - unsigned short v; - - if (port >= LAN_IOSTART && port < LAN_IOEND) - v = _ne_inw(PORT2ADDR_NE(port)); - else -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { - return *(volatile unsigned short *)__port2addr_ata(port); - } else -#endif -#if defined(CONFIG_USB) - if (port >= 0x340 && port < 0x3a0) - v = *(volatile unsigned short *)PORT2ADDR_USB(port); - else -#endif -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) - if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { - unsigned short w; - pcc_ioread_word(0, port, &w, sizeof(w), 1, 0); - return w; - } else -#endif - v = *(volatile unsigned short *)PORT2ADDR(port); - + unsigned short v = _inw(port); delay(); return (v); } unsigned long _inl_p(unsigned long port) { - unsigned long v; - - v = *(volatile unsigned long *)PORT2ADDR(port); + unsigned long v = _inl(port); delay(); return (v); } @@ -284,52 +241,19 @@ void _outl(unsigned long l, unsigned long port) void _outb_p(unsigned char b, unsigned long port) { - if (port >= LAN_IOSTART && port < LAN_IOEND) - _ne_outb(b, PORT2ADDR_NE(port)); - else -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { - *(volatile unsigned char *)__port2addr_ata(port) = b; - } else -#endif -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) - if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { - pcc_iowrite_byte(0, port, &b, sizeof(b), 1, 0); - } else -#endif - *(volatile unsigned char *)PORT2ADDR(port) = b; - + _outb(b, port); delay(); } void _outw_p(unsigned short w, unsigned long port) { - if (port >= LAN_IOSTART && port < LAN_IOEND) - _ne_outw(w, PORT2ADDR_NE(port)); - else -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { - *(volatile unsigned short *)__port2addr_ata(port) = w; - } else -#endif -#if defined(CONFIG_USB) - if (port >= 0x340 && port < 0x3a0) - *(volatile unsigned short *)PORT2ADDR_USB(port) = w; - else -#endif -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) - if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { - pcc_iowrite_word(0, port, &w, sizeof(w), 1, 0); - } else -#endif - *(volatile unsigned short *)PORT2ADDR(port) = w; - + _outw(w, port); delay(); } void _outl_p(unsigned long l, unsigned long port) { - *(volatile unsigned long *)PORT2ADDR(port) = l; + _outl(l, port); delay(); } diff --git a/arch/m32r/kernel/io_mappi3.c b/arch/m32r/kernel/io_mappi3.c new file mode 100644 index 000000000000..c80bde657854 --- /dev/null +++ b/arch/m32r/kernel/io_mappi3.c @@ -0,0 +1,378 @@ +/* + * linux/arch/m32r/kernel/io_mappi3.c + * + * Typical I/O routines for Mappi3 board. + * + * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata, + * Hitoshi Yamamoto, Mamoru Sakugawa + */ + +#include +#include +#include +#include +#include + +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) +#include + +#define M32R_PCC_IOMAP_SIZE 0x1000 + +#define M32R_PCC_IOSTART0 0x1000 +#define M32R_PCC_IOEND0 (M32R_PCC_IOSTART0 + M32R_PCC_IOMAP_SIZE - 1) + +extern void pcc_ioread_byte(int, unsigned long, void *, size_t, size_t, int); +extern void pcc_ioread_word(int, unsigned long, void *, size_t, size_t, int); +extern void pcc_iowrite_byte(int, unsigned long, void *, size_t, size_t, int); +extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int); +#endif /* CONFIG_PCMCIA && CONFIG_M32R_CFC */ + +#define PORT2ADDR(port) _port2addr(port) +#define PORT2ADDR_NE(port) _port2addr_ne(port) +#define PORT2ADDR_USB(port) _port2addr_usb(port) + +static inline void *_port2addr(unsigned long port) +{ + return (void *)(port + NONCACHE_OFFSET); +} + +#define LAN_IOSTART 0x300 +#define LAN_IOEND 0x320 + +#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) +static inline void *__port2addr_ata(unsigned long port) +{ + static int dummy_reg; + + switch (port) { + case 0x1f0: return (void *)0xb4002000; + case 0x1f1: return (void *)0xb4012800; + case 0x1f2: return (void *)0xb4012002; + case 0x1f3: return (void *)0xb4012802; + case 0x1f4: return (void *)0xb4012004; + case 0x1f5: return (void *)0xb4012804; + case 0x1f6: return (void *)0xb4012006; + case 0x1f7: return (void *)0xb4012806; + case 0x3f6: return (void *)0xb401200e; + default: return (void *)&dummy_reg; + } +} +#endif + +static inline void *_port2addr_ne(unsigned long port) +{ + return (void *)(port + NONCACHE_OFFSET + 0x10000000); +} + +static inline void *_port2addr_usb(unsigned long port) +{ + return (void *)(port + NONCACHE_OFFSET + 0x12000000); +} +static inline void delay(void) +{ + __asm__ __volatile__ ("push r0; \n\t pop r0;" : : :"memory"); +} + +/* + * NIC I/O function + */ + +static inline unsigned char _ne_inb(void *portp) +{ + return (unsigned char) *(volatile unsigned char *)portp; +} + +static inline unsigned short _ne_inw(void *portp) +{ + return (unsigned short)le16_to_cpu(*(volatile unsigned short *)portp); +} + +static inline void _ne_insb(void *portp, void * addr, unsigned long count) +{ + unsigned char *buf = addr; + + while (count--) + *buf++ = *(volatile unsigned char *)portp; +} + +static inline void _ne_outb(unsigned char b, void *portp) +{ + *(volatile unsigned char *)portp = (unsigned char)b; +} + +static inline void _ne_outw(unsigned short w, void *portp) +{ + *(volatile unsigned short *)portp = cpu_to_le16(w); +} + +unsigned char _inb(unsigned long port) +{ + if (port >= LAN_IOSTART && port < LAN_IOEND) + return _ne_inb(PORT2ADDR_NE(port)); +#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) + else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { + return *(volatile unsigned char *)__port2addr_ata(port); + } +#endif +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) + else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { + unsigned char b; + pcc_ioread_byte(0, port, &b, sizeof(b), 1, 0); + return b; + } else +#endif + return *(volatile unsigned char *)PORT2ADDR(port); +} + +unsigned short _inw(unsigned long port) +{ + if (port >= LAN_IOSTART && port < LAN_IOEND) + return _ne_inw(PORT2ADDR_NE(port)); +#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) + else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { + return *(volatile unsigned short *)__port2addr_ata(port); + } +#endif +#if defined(CONFIG_USB) + else if (port >= 0x340 && port < 0x3a0) + return *(volatile unsigned short *)PORT2ADDR_USB(port); +#endif + +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) + else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { + unsigned short w; + pcc_ioread_word(0, port, &w, sizeof(w), 1, 0); + return w; + } else +#endif + return *(volatile unsigned short *)PORT2ADDR(port); +} + +unsigned long _inl(unsigned long port) +{ +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) + if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { + unsigned long l; + pcc_ioread_word(0, port, &l, sizeof(l), 1, 0); + return l; + } else +#endif + return *(volatile unsigned long *)PORT2ADDR(port); +} + +unsigned char _inb_p(unsigned long port) +{ + unsigned char v = _inb(port); + delay(); + return (v); +} + +unsigned short _inw_p(unsigned long port) +{ + unsigned short v = _inw(port); + delay(); + return (v); +} + +unsigned long _inl_p(unsigned long port) +{ + unsigned long v = _inl(port); + delay(); + return (v); +} + +void _outb(unsigned char b, unsigned long port) +{ + if (port >= LAN_IOSTART && port < LAN_IOEND) + _ne_outb(b, PORT2ADDR_NE(port)); + else +#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) + if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { + *(volatile unsigned char *)__port2addr_ata(port) = b; + } else +#endif +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) + if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { + pcc_iowrite_byte(0, port, &b, sizeof(b), 1, 0); + } else +#endif + *(volatile unsigned char *)PORT2ADDR(port) = b; +} + +void _outw(unsigned short w, unsigned long port) +{ + if (port >= LAN_IOSTART && port < LAN_IOEND) + _ne_outw(w, PORT2ADDR_NE(port)); + else +#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) + if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { + *(volatile unsigned short *)__port2addr_ata(port) = w; + } else +#endif +#if defined(CONFIG_USB) + if (port >= 0x340 && port < 0x3a0) + *(volatile unsigned short *)PORT2ADDR_USB(port) = w; + else +#endif +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) + if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { + pcc_iowrite_word(0, port, &w, sizeof(w), 1, 0); + } else +#endif + *(volatile unsigned short *)PORT2ADDR(port) = w; +} + +void _outl(unsigned long l, unsigned long port) +{ +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) + if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { + pcc_iowrite_word(0, port, &l, sizeof(l), 1, 0); + } else +#endif + *(volatile unsigned long *)PORT2ADDR(port) = l; +} + +void _outb_p(unsigned char b, unsigned long port) +{ + _outb(b, port); + delay(); +} + +void _outw_p(unsigned short w, unsigned long port) +{ + _outw(w, port); + delay(); +} + +void _outl_p(unsigned long l, unsigned long port) +{ + _outl(l, port); + delay(); +} + +void _insb(unsigned int port, void * addr, unsigned long count) +{ + if (port >= LAN_IOSTART && port < LAN_IOEND) + _ne_insb(PORT2ADDR_NE(port), addr, count); +#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) + else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { + unsigned char *buf = addr; + unsigned char *portp = __port2addr_ata(port); + while (count--) + *buf++ = *(volatile unsigned char *)portp; + } +#endif +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) + else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { + pcc_ioread_byte(0, port, (void *)addr, sizeof(unsigned char), + count, 1); + } +#endif + else { + unsigned char *buf = addr; + unsigned char *portp = PORT2ADDR(port); + while (count--) + *buf++ = *(volatile unsigned char *)portp; + } +} + +void _insw(unsigned int port, void * addr, unsigned long count) +{ + unsigned short *buf = addr; + unsigned short *portp; + + if (port >= LAN_IOSTART && port < LAN_IOEND) { + portp = PORT2ADDR_NE(port); + while (count--) + *buf++ = *(volatile unsigned short *)portp; +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) + } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { + pcc_ioread_word(9, port, (void *)addr, sizeof(unsigned short), + count, 1); +#endif +#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) + } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { + portp = __port2addr_ata(port); + while (count--) + *buf++ = *(volatile unsigned short *)portp; +#endif + } else { + portp = PORT2ADDR(port); + while (count--) + *buf++ = *(volatile unsigned short *)portp; + } +} + +void _insl(unsigned int port, void * addr, unsigned long count) +{ + unsigned long *buf = addr; + unsigned long *portp; + + portp = PORT2ADDR(port); + while (count--) + *buf++ = *(volatile unsigned long *)portp; +} + +void _outsb(unsigned int port, const void * addr, unsigned long count) +{ + const unsigned char *buf = addr; + unsigned char *portp; + + if (port >= LAN_IOSTART && port < LAN_IOEND) { + portp = PORT2ADDR_NE(port); + while (count--) + _ne_outb(*buf++, portp); +#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) + } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { + portp = __port2addr_ata(port); + while (count--) + *(volatile unsigned char *)portp = *buf++; +#endif +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) + } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { + pcc_iowrite_byte(0, port, (void *)addr, sizeof(unsigned char), + count, 1); +#endif + } else { + portp = PORT2ADDR(port); + while (count--) + *(volatile unsigned char *)portp = *buf++; + } +} + +void _outsw(unsigned int port, const void * addr, unsigned long count) +{ + const unsigned short *buf = addr; + unsigned short *portp; + + if (port >= LAN_IOSTART && port < LAN_IOEND) { + portp = PORT2ADDR_NE(port); + while (count--) + *(volatile unsigned short *)portp = *buf++; +#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) + } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { + portp = __port2addr_ata(port); + while (count--) + *(volatile unsigned short *)portp = *buf++; +#endif +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) + } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { + pcc_iowrite_word(9, port, (void *)addr, sizeof(unsigned short), + count, 1); +#endif + } else { + portp = PORT2ADDR(port); + while (count--) + *(volatile unsigned short *)portp = *buf++; + } +} + +void _outsl(unsigned int port, const void * addr, unsigned long count) +{ + const unsigned long *buf = addr; + unsigned char *portp; + + portp = PORT2ADDR(port); + while (count--) + *(volatile unsigned long *)portp = *buf++; +} diff --git a/arch/m32r/kernel/io_oaks32r.c b/arch/m32r/kernel/io_oaks32r.c index 286964794d51..9997dddd24d7 100644 --- a/arch/m32r/kernel/io_oaks32r.c +++ b/arch/m32r/kernel/io_oaks32r.c @@ -3,7 +3,7 @@ * * Typical I/O routines for OAKS32R board. * - * Copyright (c) 2001-2004 Hiroyuki Kondo, Hirokazu Takata, + * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata, * Hitoshi Yamamoto, Mamoru Sakugawa */ @@ -90,35 +90,21 @@ unsigned long _inl(unsigned long port) unsigned char _inb_p(unsigned long port) { - unsigned char v; - - if (port >= 0x300 && port < 0x320) - v = _ne_inb(PORT2ADDR_NE(port)); - else - v = *(volatile unsigned char *)PORT2ADDR(port); - + unsigned char v = _inb(port); delay(); return (v); } unsigned short _inw_p(unsigned long port) { - unsigned short v; - - if (port >= 0x300 && port < 0x320) - v = _ne_inw(PORT2ADDR_NE(port)); - else - v = *(volatile unsigned short *)PORT2ADDR(port); - + unsigned short v = _inw(port); delay(); return (v); } unsigned long _inl_p(unsigned long port) { - unsigned long v; - - v = *(volatile unsigned long *)PORT2ADDR(port); + unsigned long v = _inl(port); delay(); return (v); } @@ -146,27 +132,19 @@ void _outl(unsigned long l, unsigned long port) void _outb_p(unsigned char b, unsigned long port) { - if (port >= 0x300 && port < 0x320) - _ne_outb(b, PORT2ADDR_NE(port)); - else - *(volatile unsigned char *)PORT2ADDR(port) = b; - + _outb(b, port); delay(); } void _outw_p(unsigned short w, unsigned long port) { - if (port >= 0x300 && port < 0x320) - _ne_outw(w, PORT2ADDR_NE(port)); - else - *(volatile unsigned short *)PORT2ADDR(port) = w; - + _outw(w, port); delay(); } void _outl_p(unsigned long l, unsigned long port) { - *(volatile unsigned long *)PORT2ADDR(port) = l; + _outl(l, port); delay(); } diff --git a/arch/m32r/kernel/io_opsput.c b/arch/m32r/kernel/io_opsput.c index aaf42f9f76da..e34951e8156f 100644 --- a/arch/m32r/kernel/io_opsput.c +++ b/arch/m32r/kernel/io_opsput.c @@ -1,10 +1,10 @@ /* - * linux/arch/m32r/kernel/io_mappi.c + * linux/arch/m32r/kernel/io_opsput.c * * Typical I/O routines for OPSPUT board. * - * Copyright (c) 2001, 2002 Hiroyuki Kondo, Hirokazu Takata, - * Hitoshi Yamamoto, Takeo Takahashi + * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata, + * Hitoshi Yamamoto, Takeo Takahashi * * This file is subject to the terms and conditions of the GNU General * Public License. See the file "COPYING" in the main directory of this @@ -98,7 +98,6 @@ unsigned char _inb(unsigned long port) { if (port >= LAN_IOSTART && port < LAN_IOEND) return _ne_inb(PORT2ADDR_NE(port)); - #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { unsigned char b; @@ -118,7 +117,6 @@ unsigned short _inw(unsigned long port) else if(port >= 0x340 && port < 0x3a0) return *(volatile unsigned short *)PORT2ADDR_USB(port); #endif - #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { unsigned short w; @@ -143,55 +141,21 @@ unsigned long _inl(unsigned long port) unsigned char _inb_p(unsigned long port) { - unsigned char v; - - if (port >= LAN_IOSTART && port < LAN_IOEND) - v = _ne_inb(PORT2ADDR_NE(port)); - else -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) - if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { - unsigned char b; - pcc_ioread_byte(0, port, &b, sizeof(b), 1, 0); - return b; - } else -#endif - v = *(volatile unsigned char *)PORT2ADDR(port); - + unsigned char v = _inb(port); delay(); return (v); } unsigned short _inw_p(unsigned long port) { - unsigned short v; - - if (port >= LAN_IOSTART && port < LAN_IOEND) - v = _ne_inw(PORT2ADDR_NE(port)); - else -#if defined(CONFIG_USB) - if(port >= 0x340 && port < 0x3a0) - return *(volatile unsigned short *)PORT2ADDR_USB(port); - else -#endif - -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) - if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { - unsigned short w; - pcc_ioread_word(0, port, &w, sizeof(w), 1, 0); - return w; - } else -#endif - v = *(volatile unsigned short *)PORT2ADDR(port); - + unsigned short v = _inw(port); delay(); return (v); } unsigned long _inl_p(unsigned long port) { - unsigned long v; - - v = *(volatile unsigned long *)PORT2ADDR(port); + unsigned long v = _inl(port); delay(); return (v); } @@ -219,7 +183,6 @@ void _outw(unsigned short w, unsigned long port) *(volatile unsigned short *)PORT2ADDR_USB(port) = w; else #endif - #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_iowrite_word(0, port, &w, sizeof(w), 1, 0); @@ -240,43 +203,19 @@ void _outl(unsigned long l, unsigned long port) void _outb_p(unsigned char b, unsigned long port) { - if (port >= LAN_IOSTART && port < LAN_IOEND) - _ne_outb(b, PORT2ADDR_NE(port)); - else -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) - if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { - pcc_iowrite_byte(0, port, &b, sizeof(b), 1, 0); - } else -#endif - *(volatile unsigned char *)PORT2ADDR(port) = b; - + _outb(b, port); delay(); } void _outw_p(unsigned short w, unsigned long port) { - if (port >= LAN_IOSTART && port < LAN_IOEND) - _ne_outw(w, PORT2ADDR_NE(port)); - else -#if defined(CONFIG_USB) - if(port >= 0x340 && port < 0x3a0) - *(volatile unsigned short *)PORT2ADDR_USB(port) = w; - else -#endif - -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) - if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { - pcc_iowrite_word(0, port, &w, sizeof(w), 1, 0); - } else -#endif - *(volatile unsigned short *)PORT2ADDR(port) = w; - + _outw(w, port); delay(); } void _outl_p(unsigned long l, unsigned long port) { - *(volatile unsigned long *)PORT2ADDR(port) = l; + _outl(l, port); delay(); } diff --git a/arch/m32r/kernel/io_usrv.c b/arch/m32r/kernel/io_usrv.c index 27928a0b99ed..9eb161dcc104 100644 --- a/arch/m32r/kernel/io_usrv.c +++ b/arch/m32r/kernel/io_usrv.c @@ -3,8 +3,8 @@ * * Typical I/O routines for uServer board. * - * Copyright (c) 2001 - 2003 Hiroyuki Kondo, Hirokazu Takata, - * Hitoshi Yamamoto, Takeo Takahashi + * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata, + * Hitoshi Yamamoto, Takeo Takahashi * * This file is subject to the terms and conditions of the GNU General * Public License. See the file "COPYING" in the main directory of this @@ -39,7 +39,7 @@ extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int); #define PORT2ADDR(port) _port2addr(port) -static __inline__ void *_port2addr(unsigned long port) +static inline void *_port2addr(unsigned long port) { #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) if (port >= UART0_IOSTART && port <= UART0_IOEND) @@ -50,7 +50,7 @@ static __inline__ void *_port2addr(unsigned long port) return (void *)(port + NONCACHE_OFFSET); } -static __inline__ void delay(void) +static inline void delay(void) { __asm__ __volatile__ ("push r0; \n\t pop r0;" : : :"memory"); } @@ -87,39 +87,22 @@ unsigned long _inl(unsigned long port) unsigned char _inb_p(unsigned long port) { - unsigned char b; - - if (port >= CFC_IOSTART && port <= CFC_IOEND) { - pcc_ioread_byte(0, port, &b, sizeof(b), 1, 0); - return b; - } else { - b = *(volatile unsigned char *)PORT2ADDR(port); - delay(); - return b; - } + unsigned char v = _inb(port); + delay(); + return v; } unsigned short _inw_p(unsigned long port) { - unsigned short w; - - if (port >= CFC_IOSTART && port <= CFC_IOEND) { - pcc_ioread_word(0, port, &w, sizeof(w), 1, 0); - return w; - } else { - w = *(volatile unsigned short *)PORT2ADDR(port); - delay(); - return w; - } + unsigned short v = _inw(port); + delay(); + return v; } unsigned long _inl_p(unsigned long port) { - unsigned long v; - - v = *(volatile unsigned long *)PORT2ADDR(port); + unsigned long v = _inl(port); delay(); - return v; } @@ -149,25 +132,19 @@ void _outl(unsigned long l, unsigned long port) void _outb_p(unsigned char b, unsigned long port) { - if (port >= CFC_IOSTART && port <= CFC_IOEND) - pcc_iowrite_byte(0, port, &b, sizeof(b), 1, 0); - else - *(volatile unsigned char *)PORT2ADDR(port) = b; + _outb(b, port); delay(); } void _outw_p(unsigned short w, unsigned long port) { - if (port >= CFC_IOSTART && port <= CFC_IOEND) - pcc_iowrite_word(0, port, &w, sizeof(w), 1, 0); - else - *(volatile unsigned short *)PORT2ADDR(port) = w; + _outw(w, port); delay(); } void _outl_p(unsigned long l, unsigned long port) { - *(volatile unsigned long *)PORT2ADDR(port) = l; + _outl(l, port); delay(); } diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c index 4826cd6e40e8..ec5674727e7f 100644 --- a/arch/m32r/kernel/setup.c +++ b/arch/m32r/kernel/setup.c @@ -330,6 +330,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "Machine\t\t: Mappi Evaluation board\n"); #elif CONFIG_PLAT_MAPPI2 seq_printf(m, "Machine\t\t: Mappi-II Evaluation board\n"); +#elif CONFIG_PLAT_MAPPI3 + seq_printf(m, "Machine\t\t: Mappi-III Evaluation board\n"); #elif CONFIG_PLAT_M32700UT seq_printf(m, "Machine\t\t: M32700UT Evaluation board\n"); #elif CONFIG_PLAT_OPSPUT diff --git a/arch/m32r/kernel/setup_mappi2.c b/arch/m32r/kernel/setup_mappi2.c index 1904d465a507..248fc658dbd5 100644 --- a/arch/m32r/kernel/setup_mappi2.c +++ b/arch/m32r/kernel/setup_mappi2.c @@ -1,5 +1,5 @@ /* - * linux/arch/m32r/kernel/setup_mappi.c + * linux/arch/m32r/kernel/setup_mappi2.c * * Setup routines for Renesas MAPPI-II(M3A-ZA36) Board * @@ -156,7 +156,6 @@ void __init init_IRQ(void) irq_desc[PLD_IRQ_CFIREQ].handler = &mappi2_irq_type; irq_desc[PLD_IRQ_CFIREQ].action = 0; irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ -// icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00; icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; disable_mappi2_irq(PLD_IRQ_CFIREQ); @@ -167,7 +166,6 @@ void __init init_IRQ(void) irq_desc[PLD_IRQ_CFC_INSERT].action = 0; irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00; -// icu_data[PLD_IRQ_CFC_INSERT].icucr = 0; disable_mappi2_irq(PLD_IRQ_CFC_INSERT); /* ICUCR42: CFC Eject */ @@ -176,9 +174,7 @@ void __init init_IRQ(void) irq_desc[PLD_IRQ_CFC_EJECT].action = 0; irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_CFC_EJECT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; -// icu_data[PLD_IRQ_CFC_EJECT].icucr = 0; disable_mappi2_irq(PLD_IRQ_CFC_EJECT); - #endif /* CONFIG_MAPPI2_CFC */ } diff --git a/arch/m32r/kernel/setup_mappi3.c b/arch/m32r/kernel/setup_mappi3.c new file mode 100644 index 000000000000..72b5b7609cea --- /dev/null +++ b/arch/m32r/kernel/setup_mappi3.c @@ -0,0 +1,208 @@ +/* + * linux/arch/m32r/kernel/setup_mappi3.c + * + * Setup routines for Renesas MAPPI-III(M3A-2170) Board + * + * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata, + * Hitoshi Yamamoto, Mamoru Sakugawa + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long))) + +#ifndef CONFIG_SMP +typedef struct { + unsigned long icucr; /* ICU Control Register */ +} icu_data_t; +#endif /* CONFIG_SMP */ + +icu_data_t icu_data[NR_IRQS]; + +static void disable_mappi3_irq(unsigned int irq) +{ + unsigned long port, data; + + if ((irq == 0) ||(irq >= NR_IRQS)) { + printk("bad irq 0x%08x\n", irq); + return; + } + port = irq2port(irq); + data = icu_data[irq].icucr|M32R_ICUCR_ILEVEL7; + outl(data, port); +} + +static void enable_mappi3_irq(unsigned int irq) +{ + unsigned long port, data; + + if ((irq == 0) ||(irq >= NR_IRQS)) { + printk("bad irq 0x%08x\n", irq); + return; + } + port = irq2port(irq); + data = icu_data[irq].icucr|M32R_ICUCR_IEN|M32R_ICUCR_ILEVEL6; + outl(data, port); +} + +static void mask_and_ack_mappi3(unsigned int irq) +{ + disable_mappi3_irq(irq); +} + +static void end_mappi3_irq(unsigned int irq) +{ + enable_mappi3_irq(irq); +} + +static unsigned int startup_mappi3_irq(unsigned int irq) +{ + enable_mappi3_irq(irq); + return (0); +} + +static void shutdown_mappi3_irq(unsigned int irq) +{ + unsigned long port; + + port = irq2port(irq); + outl(M32R_ICUCR_ILEVEL7, port); +} + +static struct hw_interrupt_type mappi3_irq_type = +{ + "MAPPI3-IRQ", + startup_mappi3_irq, + shutdown_mappi3_irq, + enable_mappi3_irq, + disable_mappi3_irq, + mask_and_ack_mappi3, + end_mappi3_irq +}; + +void __init init_IRQ(void) +{ +#if defined(CONFIG_SMC91X) + /* INT0 : LAN controller (SMC91111) */ + irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; + irq_desc[M32R_IRQ_INT0].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_INT0].action = 0; + irq_desc[M32R_IRQ_INT0].depth = 1; + icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; + disable_mappi3_irq(M32R_IRQ_INT0); +#endif /* CONFIG_SMC91X */ + + /* MFT2 : system timer */ + irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; + irq_desc[M32R_IRQ_MFT2].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_MFT2].action = 0; + irq_desc[M32R_IRQ_MFT2].depth = 1; + icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; + disable_mappi3_irq(M32R_IRQ_MFT2); + +#ifdef CONFIG_SERIAL_M32R_SIO + /* SIO0_R : uart receive data */ + irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; + irq_desc[M32R_IRQ_SIO0_R].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_SIO0_R].action = 0; + irq_desc[M32R_IRQ_SIO0_R].depth = 1; + icu_data[M32R_IRQ_SIO0_R].icucr = 0; + disable_mappi3_irq(M32R_IRQ_SIO0_R); + + /* SIO0_S : uart send data */ + irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; + irq_desc[M32R_IRQ_SIO0_S].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_SIO0_S].action = 0; + irq_desc[M32R_IRQ_SIO0_S].depth = 1; + icu_data[M32R_IRQ_SIO0_S].icucr = 0; + disable_mappi3_irq(M32R_IRQ_SIO0_S); + /* SIO1_R : uart receive data */ + irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; + irq_desc[M32R_IRQ_SIO1_R].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_SIO1_R].action = 0; + irq_desc[M32R_IRQ_SIO1_R].depth = 1; + icu_data[M32R_IRQ_SIO1_R].icucr = 0; + disable_mappi3_irq(M32R_IRQ_SIO1_R); + + /* SIO1_S : uart send data */ + irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; + irq_desc[M32R_IRQ_SIO1_S].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_SIO1_S].action = 0; + irq_desc[M32R_IRQ_SIO1_S].depth = 1; + icu_data[M32R_IRQ_SIO1_S].icucr = 0; + disable_mappi3_irq(M32R_IRQ_SIO1_S); +#endif /* CONFIG_M32R_USE_DBG_CONSOLE */ + +#if defined(CONFIG_USB) + /* INT1 : USB Host controller interrupt */ + irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED; + irq_desc[M32R_IRQ_INT1].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_INT1].action = 0; + irq_desc[M32R_IRQ_INT1].depth = 1; + icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_ISMOD01; + disable_mappi3_irq(M32R_IRQ_INT1); +#endif /* CONFIG_USB */ + + /* ICUCR40: CFC IREQ */ + irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; + irq_desc[PLD_IRQ_CFIREQ].handler = &mappi3_irq_type; + irq_desc[PLD_IRQ_CFIREQ].action = 0; + irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ + icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; + disable_mappi3_irq(PLD_IRQ_CFIREQ); + +#if defined(CONFIG_M32R_CFC) + /* ICUCR41: CFC Insert */ + irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; + irq_desc[PLD_IRQ_CFC_INSERT].handler = &mappi3_irq_type; + irq_desc[PLD_IRQ_CFC_INSERT].action = 0; + irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ + icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00; + disable_mappi3_irq(PLD_IRQ_CFC_INSERT); + + /* ICUCR42: CFC Eject */ + irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED; + irq_desc[PLD_IRQ_CFC_EJECT].handler = &mappi3_irq_type; + irq_desc[PLD_IRQ_CFC_EJECT].action = 0; + irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ + icu_data[PLD_IRQ_CFC_EJECT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; + disable_mappi3_irq(PLD_IRQ_CFC_EJECT); +#endif /* CONFIG_M32R_CFC */ +} + +#define LAN_IOSTART 0x300 +#define LAN_IOEND 0x320 +static struct resource smc91x_resources[] = { + [0] = { + .start = (LAN_IOSTART), + .end = (LAN_IOEND), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = M32R_IRQ_INT0, + .end = M32R_IRQ_INT0, + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +static int __init platform_init(void) +{ + platform_device_register(&smc91x_device); + return 0; +} +arch_initcall(platform_init); diff --git a/arch/m32r/mappi3/defconfig.smp b/arch/m32r/mappi3/defconfig.smp new file mode 100644 index 000000000000..2eebe75fc071 --- /dev/null +++ b/arch/m32r/mappi3/defconfig.smp @@ -0,0 +1,751 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc5 +# Tue May 31 17:55:34 2005 +# +CONFIG_M32R=y +# CONFIG_UID16 is not set +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +CONFIG_BROKEN=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_CPUSETS is not set +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +# CONFIG_FUTEX is not set +# CONFIG_EPOLL is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_STOP_MACHINE=y + +# +# Processor type and features +# +# CONFIG_PLAT_MAPPI is not set +# CONFIG_PLAT_USRV is not set +# CONFIG_PLAT_M32700UT is not set +# CONFIG_PLAT_OPSPUT is not set +# CONFIG_PLAT_OAKS32R is not set +# CONFIG_PLAT_MAPPI2 is not set +CONFIG_PLAT_MAPPI3=y +CONFIG_CHIP_M32700=y +# CONFIG_CHIP_M32102 is not set +# CONFIG_CHIP_VDEC2 is not set +# CONFIG_CHIP_OPSP is not set +CONFIG_MMU=y +CONFIG_TLB_ENTRIES=32 +CONFIG_ISA_M32R2=y +CONFIG_ISA_DSP_LEVEL2=y +CONFIG_ISA_DUAL_ISSUE=y +CONFIG_BUS_CLOCK=10000000 +CONFIG_TIMER_DIVIDE=128 +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_MEMORY_START=0x08000000 +CONFIG_MEMORY_SIZE=0x08000000 +CONFIG_NOHIGHMEM=y +CONFIG_DISCONTIGMEM=y +CONFIG_IRAM_START=0x00f00000 +CONFIG_IRAM_SIZE=0x00080000 +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_PREEMPT=y +# CONFIG_HAVE_DEC_LOCK is not set +CONFIG_SMP=y +# CONFIG_CHIP_M32700_TS1 is not set +CONFIG_NR_CPUS=2 +# CONFIG_NUMA is not set + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +# CONFIG_PCI is not set +# CONFIG_ISA is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=y +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=y + +# +# PC-card bridges +# +# CONFIG_TCIC is not set +# CONFIG_M32R_PCC is not set +# CONFIG_M32R_CFC is not set + +# +# PCI Hotplug Support +# + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +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 + +# +# 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 + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECS=y +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_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 +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_SMC91X=y +# CONFIG_NE2000 is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_M32R_SIO=y +CONFIG_SERIAL_M32R_SIO_CONSOLE=y +# CONFIG_SERIAL_M32R_PLDSIO is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# 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=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# 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 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_FRAME_POINTER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/m32r/mappi3/dot.gdbinit b/arch/m32r/mappi3/dot.gdbinit new file mode 100644 index 000000000000..89c22184e139 --- /dev/null +++ b/arch/m32r/mappi3/dot.gdbinit @@ -0,0 +1,224 @@ +# .gdbinit file +# $Id: dot.gdbinit,v 1.1 2005/04/11 02:21:08 sakugawa Exp $ + +# setting +set width 0d70 +set radix 0d16 +use_debug_dma + +# Initialize SDRAM controller for Mappi +define sdram_init + # SDIR0 + set *(unsigned long *)0x00ef6008 = 0x00000182 + # SDIR1 + set *(unsigned long *)0x00ef600c = 0x00000001 + # Initialize wait + shell sleep 0.1 + # MOD + set *(unsigned long *)0x00ef602c = 0x00000020 + set *(unsigned long *)0x00ef604c = 0x00000020 + # TR + set *(unsigned long *)0x00ef6028 = 0x00051502 + set *(unsigned long *)0x00ef6048 = 0x00051502 + # ADR + set *(unsigned long *)0x00ef6020 = 0x08000004 + set *(unsigned long *)0x00ef6040 = 0x0c000004 + # AutoRef On + set *(unsigned long *)0x00ef6004 = 0x00010517 + # Access enable + set *(unsigned long *)0x00ef6024 = 0x00000001 + set *(unsigned long *)0x00ef6044 = 0x00000001 +end + +# Initialize LAN controller for Mappi +define lanc_init + # Set BSEL4 + #set *(unsigned long *)0x00ef5004 = 0x0fff330f + #set *(unsigned long *)0x00ef5004 = 0x01113301 + +# set *(unsigned long *)0x00ef5004 = 0x02011101 +# set *(unsigned long *)0x00ef5004 = 0x04441104 +end + +define clock_init + set *(unsigned long *)0x00ef4010 = 2 + set *(unsigned long *)0x00ef4014 = 2 + set *(unsigned long *)0x00ef4020 = 3 + set *(unsigned long *)0x00ef4024 = 3 + set *(unsigned long *)0x00ef4004 = 0x7 +# shell sleep 0.1 +# set *(unsigned long *)0x00ef4004 = 0x5 + shell sleep 0.1 + set *(unsigned long *)0x00ef4008 = 0x0200 +end + +define port_init + set $sfrbase = 0x00ef0000 + set *(unsigned short *)0x00ef1060 = 0x5555 + set *(unsigned short *)0x00ef1062 = 0x5555 + set *(unsigned short *)0x00ef1064 = 0x5555 + set *(unsigned short *)0x00ef1066 = 0x5555 + set *(unsigned short *)0x00ef1068 = 0x5555 + set *(unsigned short *)0x00ef106a = 0x0000 + set *(unsigned short *)0x00ef106e = 0x5555 + set *(unsigned short *)0x00ef1070 = 0x5555 +end + +# MMU enable +define mmu_enable + set $evb=0x88000000 + set *(unsigned long *)0xffff0024=1 +end + +# MMU disable +define mmu_disable + set $evb=0 + set *(unsigned long *)0xffff0024=0 +end + +# Show TLB entries +define show_tlb_entries + set $i = 0 + set $addr = $arg0 + while ($i < 0d16 ) + set $tlb_tag = *(unsigned long*)$addr + set $tlb_data = *(unsigned long*)($addr + 4) + printf " [%2d] 0x%08lx : 0x%08lx - 0x%08lx\n", $i, $addr, $tlb_tag, $tlb_data + set $i = $i + 1 + set $addr = $addr + 8 + end +end +define itlb + set $itlb=0xfe000000 + show_tlb_entries $itlb +end +define dtlb + set $dtlb=0xfe000800 + show_tlb_entries $dtlb +end + +# Cache ON +define set_cache_type + set $mctype = (void*)0xfffffff8 +# chaos +# set *(unsigned long *)($mctype) = 0x0000c000 +# m32102 i-cache only + set *(unsigned long *)($mctype) = 0x00008000 +# m32102 d-cache only +# set *(unsigned long *)($mctype) = 0x00004000 +end +define cache_on + set $param = (void*)0x08001000 + set *(unsigned long *)($param) = 0x60ff6102 +end + + +# Show current task structure +define show_current + set $current = $spi & 0xffffe000 + printf "$current=0x%08lX\n",$current + print *(struct task_struct *)$current +end + +# Show user assigned task structure +define show_task + set $task = $arg0 & 0xffffe000 + printf "$task=0x%08lX\n",$task + print *(struct task_struct *)$task +end +document show_task + Show user assigned task structure + arg0 : task structure address +end + +# Show M32R registers +define show_regs + printf " R0[0x%08lX] R1[0x%08lX] R2[0x%08lX] R3[0x%08lX]\n",$r0,$r1,$r2,$r3 + printf " R4[0x%08lX] R5[0x%08lX] R6[0x%08lX] R7[0x%08lX]\n",$r4,$r5,$r6,$r7 + printf " R8[0x%08lX] R9[0x%08lX] R10[0x%08lX] R11[0x%08lX]\n",$r8,$r9,$r10,$r11 + printf "R12[0x%08lX] FP[0x%08lX] LR[0x%08lX] SP[0x%08lX]\n",$r12,$fp,$lr,$sp + printf "PSW[0x%08lX] CBR[0x%08lX] SPI[0x%08lX] SPU[0x%08lX]\n",$psw,$cbr,$spi,$spu + printf "BPC[0x%08lX] PC[0x%08lX] ACCL[0x%08lX] ACCH[0x%08lX]\n",$bpc,$pc,$accl,$acch + printf "EVB[0x%08lX]\n",$evb + + set $mests = *(unsigned long *)0xffff000c + set $mdeva = *(unsigned long *)0xffff0010 + printf "MESTS[0x%08lX] MDEVA[0x%08lX]\n",$mests,$mdeva +end + + +# Setup all +define setup + clock_init + shell sleep 0.1 + port_init + sdram_init +# lanc_init +# dispc_init +# set $evb=0x08000000 +end + +# Load modules +define load_modules + use_debug_dma + load +# load busybox.mot +end + +# Set kernel parameters +define set_kernel_parameters + set $param = (void*)0x08001000 + + ## MOUNT_ROOT_RDONLY + set {long}($param+0x00)=0 + ## RAMDISK_FLAGS + #set {long}($param+0x04)=0 + ## ORIG_ROOT_DEV + #set {long}($param+0x08)=0x00000100 + ## LOADER_TYPE + #set {long}($param+0x0C)=0 + ## INITRD_START + set {long}($param+0x10)=0x082a0000 + ## INITRD_SIZE + set {long}($param+0x14)=0d6200000 + + # M32R_CPUCLK + set *(unsigned long *)($param + 0x0018) = 0d100000000 + # M32R_BUSCLK + set *(unsigned long *)($param + 0x001c) = 0d50000000 + # M32R_TIMER_DIVIDE + set *(unsigned long *)($param + 0x0020) = 0d128 + + + set {char[0x200]}($param + 0x100) = "console=ttyS0,115200n8x root=/dev/nfsroot nfsroot=192.168.0.1:/project/m32r-linux/export/root.2.6_04 nfsaddrs=192.168.0.102:192.168.0.1:192.168.0.1:255.255.255.0:mappi: \0" + + +end + +# Boot +define boot + set_kernel_parameters + debug_chaos + set *(unsigned long *)0x00f00000=0x08002000 + set $pc=0x08002000 + set $fp=0 + del b + si +end + +# Restart +define restart + sdireset + sdireset + setup + load_modules + boot +end + +sdireset +sdireset +file vmlinux +target m32rsdi + +restart +boot diff --git a/include/asm-m32r/ide.h b/include/asm-m32r/ide.h index be64f24e37ee..194393bd8beb 100644 --- a/include/asm-m32r/ide.h +++ b/include/asm-m32r/ide.h @@ -35,7 +35,7 @@ static __inline__ int ide_default_irq(unsigned long base) { switch (base) { -#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) +#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3) case 0x1f0: return PLD_IRQ_CFIREQ; default: return 0; diff --git a/include/asm-m32r/m32102.h b/include/asm-m32r/m32102.h index b56034026bf8..cb98101f4f6e 100644 --- a/include/asm-m32r/m32102.h +++ b/include/asm-m32r/m32102.h @@ -175,6 +175,7 @@ #define M32R_ICU_CR5_PORTL (0x210+M32R_ICU_OFFSET) /* INT4 */ #define M32R_ICU_CR6_PORTL (0x214+M32R_ICU_OFFSET) /* INT5 */ #define M32R_ICU_CR7_PORTL (0x218+M32R_ICU_OFFSET) /* INT6 */ +#define M32R_ICU_CR8_PORTL (0x219+M32R_ICU_OFFSET) /* INT7 */ #define M32R_ICU_CR16_PORTL (0x23C+M32R_ICU_OFFSET) /* MFT0 */ #define M32R_ICU_CR17_PORTL (0x240+M32R_ICU_OFFSET) /* MFT1 */ #define M32R_ICU_CR18_PORTL (0x244+M32R_ICU_OFFSET) /* MFT2 */ diff --git a/include/asm-m32r/m32r.h b/include/asm-m32r/m32r.h index f116649bbef3..fd2b2823762b 100644 --- a/include/asm-m32r/m32r.h +++ b/include/asm-m32r/m32r.h @@ -36,6 +36,10 @@ #include #endif /* CONFIG_PLAT_MAPPI2 */ +#if defined(CONFIG_PLAT_MAPPI3) +#include +#endif /* CONFIG_PLAT_MAPPI3 */ + #if defined(CONFIG_PLAT_USRV) #include #endif diff --git a/include/asm-m32r/mappi3/mappi3_pld.h b/include/asm-m32r/mappi3/mappi3_pld.h new file mode 100644 index 000000000000..3f1551f7f01f --- /dev/null +++ b/include/asm-m32r/mappi3/mappi3_pld.h @@ -0,0 +1,143 @@ +/* + * include/asm/mappi3/mappi3_pld.h + * + * Definitions for Extended IO Logic on MAPPI3 board. + * based on m32700ut_pld.h + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file "COPYING" in the main directory of + * this archive for more details. + * + */ + +#ifndef _MAPPI3_PLD_H +#define _MAPPI3_PLD_H + +#ifndef __ASSEMBLY__ +/* FIXME: + * Some C functions use non-cache address, so can't define non-cache address. + */ +#define PLD_BASE (0x1c000000 /* + NONCACHE_OFFSET */) +#define __reg8 (volatile unsigned char *) +#define __reg16 (volatile unsigned short *) +#define __reg32 (volatile unsigned int *) +#else +#define PLD_BASE (0x1c000000 + NONCACHE_OFFSET) +#define __reg8 +#define __reg16 +#define __reg32 +#endif /* __ASSEMBLY__ */ + +/* CFC */ +#define PLD_CFRSTCR __reg16(PLD_BASE + 0x0000) +#define PLD_CFSTS __reg16(PLD_BASE + 0x0002) +#define PLD_CFIMASK __reg16(PLD_BASE + 0x0004) +#define PLD_CFBUFCR __reg16(PLD_BASE + 0x0006) +#define PLD_CFCR0 __reg16(PLD_BASE + 0x000a) +#define PLD_CFCR1 __reg16(PLD_BASE + 0x000c) + +/* MMC */ +#define PLD_MMCCR __reg16(PLD_BASE + 0x4000) +#define PLD_MMCMOD __reg16(PLD_BASE + 0x4002) +#define PLD_MMCSTS __reg16(PLD_BASE + 0x4006) +#define PLD_MMCBAUR __reg16(PLD_BASE + 0x400a) +#define PLD_MMCCMDBCUT __reg16(PLD_BASE + 0x400c) +#define PLD_MMCCDTBCUT __reg16(PLD_BASE + 0x400e) +#define PLD_MMCDET __reg16(PLD_BASE + 0x4010) +#define PLD_MMCWP __reg16(PLD_BASE + 0x4012) +#define PLD_MMCWDATA __reg16(PLD_BASE + 0x5000) +#define PLD_MMCRDATA __reg16(PLD_BASE + 0x6000) +#define PLD_MMCCMDDATA __reg16(PLD_BASE + 0x7000) +#define PLD_MMCRSPDATA __reg16(PLD_BASE + 0x7006) + +/* Power Control of MMC and CF */ +#define PLD_CPCR __reg16(PLD_BASE + 0x14000) + + +/*==== ICU ====*/ +#define M32R_IRQ_PC104 (5) /* INT4(PC/104) */ +#define M32R_IRQ_I2C (28) /* I2C-BUS */ +#define PLD_IRQ_CFIREQ (6) /* INT5 CFC Card Interrupt */ +#define PLD_IRQ_CFC_INSERT (7) /* INT6 CFC Card Insert */ +#define PLD_IRQ_CFC_EJECT (8) /* INT7 CFC Card Eject */ +#define PLD_IRQ_MMCCARD (43) /* MMC Card Insert */ +#define PLD_IRQ_MMCIRQ (44) /* MMC Transfer Done */ + + +#if 0 +/* LED Control + * + * 1: DIP swich side + * 2: Reset switch side + */ +#define PLD_IOLEDCR __reg16(PLD_BASE + 0x14002) +#define PLD_IOLED_1_ON 0x001 +#define PLD_IOLED_1_OFF 0x000 +#define PLD_IOLED_2_ON 0x002 +#define PLD_IOLED_2_OFF 0x000 + +/* DIP Switch + * 0: Write-protect of Flash Memory (0:protected, 1:non-protected) + * 1: - + * 2: - + * 3: - + */ +#define PLD_IOSWSTS __reg16(PLD_BASE + 0x14004) +#define PLD_IOSWSTS_IOSW2 0x0200 +#define PLD_IOSWSTS_IOSW1 0x0100 +#define PLD_IOSWSTS_IOWP0 0x0001 + +#endif + +/* CRC */ +#define PLD_CRC7DATA __reg16(PLD_BASE + 0x18000) +#define PLD_CRC7INDATA __reg16(PLD_BASE + 0x18002) +#define PLD_CRC16DATA __reg16(PLD_BASE + 0x18004) +#define PLD_CRC16INDATA __reg16(PLD_BASE + 0x18006) +#define PLD_CRC16ADATA __reg16(PLD_BASE + 0x18008) +#define PLD_CRC16AINDATA __reg16(PLD_BASE + 0x1800a) + + +#if 0 +/* RTC */ +#define PLD_RTCCR __reg16(PLD_BASE + 0x1c000) +#define PLD_RTCBAUR __reg16(PLD_BASE + 0x1c002) +#define PLD_RTCWRDATA __reg16(PLD_BASE + 0x1c004) +#define PLD_RTCRDDATA __reg16(PLD_BASE + 0x1c006) +#define PLD_RTCRSTODT __reg16(PLD_BASE + 0x1c008) + +/* SIO0 */ +#define PLD_ESIO0CR __reg16(PLD_BASE + 0x20000) +#define PLD_ESIO0CR_TXEN 0x0001 +#define PLD_ESIO0CR_RXEN 0x0002 +#define PLD_ESIO0MOD0 __reg16(PLD_BASE + 0x20002) +#define PLD_ESIO0MOD0_CTSS 0x0040 +#define PLD_ESIO0MOD0_RTSS 0x0080 +#define PLD_ESIO0MOD1 __reg16(PLD_BASE + 0x20004) +#define PLD_ESIO0MOD1_LMFS 0x0010 +#define PLD_ESIO0STS __reg16(PLD_BASE + 0x20006) +#define PLD_ESIO0STS_TEMP 0x0001 +#define PLD_ESIO0STS_TXCP 0x0002 +#define PLD_ESIO0STS_RXCP 0x0004 +#define PLD_ESIO0STS_TXSC 0x0100 +#define PLD_ESIO0STS_RXSC 0x0200 +#define PLD_ESIO0STS_TXREADY (PLD_ESIO0STS_TXCP | PLD_ESIO0STS_TEMP) +#define PLD_ESIO0INTCR __reg16(PLD_BASE + 0x20008) +#define PLD_ESIO0INTCR_TXIEN 0x0002 +#define PLD_ESIO0INTCR_RXCEN 0x0004 +#define PLD_ESIO0BAUR __reg16(PLD_BASE + 0x2000a) +#define PLD_ESIO0TXB __reg16(PLD_BASE + 0x2000c) +#define PLD_ESIO0RXB __reg16(PLD_BASE + 0x2000e) + +/* SIM Card */ +#define PLD_SCCR __reg16(PLD_BASE + 0x38000) +#define PLD_SCMOD __reg16(PLD_BASE + 0x38004) +#define PLD_SCSTS __reg16(PLD_BASE + 0x38006) +#define PLD_SCINTCR __reg16(PLD_BASE + 0x38008) +#define PLD_SCBAUR __reg16(PLD_BASE + 0x3800a) +#define PLD_SCTXB __reg16(PLD_BASE + 0x3800c) +#define PLD_SCRXB __reg16(PLD_BASE + 0x3800e) + +#endif + +#endif /* _MAPPI3_PLD.H */ -- cgit v1.2.3-59-g8ed1b From 6f973b001a9b511900fb73d816adf77d8755838c Mon Sep 17 00:00:00 2001 From: Hirokazu Takata Date: Tue, 21 Jun 2005 17:16:13 -0700 Subject: [PATCH] m32r: Update setup_xxxxx.c Change coding styles of hw_interrupt_type struct's initialization portions. Signed-off-by: Hirokazu Takata Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/m32r/kernel/setup_m32700ut.c | 56 +++++++++++++++++++-------------------- arch/m32r/kernel/setup_mappi.c | 14 +++++----- arch/m32r/kernel/setup_mappi2.c | 14 +++++----- arch/m32r/kernel/setup_mappi3.c | 14 +++++----- arch/m32r/kernel/setup_oaks32r.c | 14 +++++----- arch/m32r/kernel/setup_opsput.c | 28 ++++++++++---------- arch/m32r/kernel/setup_usrv.c | 28 ++++++++++---------- 7 files changed, 84 insertions(+), 84 deletions(-) diff --git a/arch/m32r/kernel/setup_m32700ut.c b/arch/m32r/kernel/setup_m32700ut.c index 488aa87bab76..b014e2c1e524 100644 --- a/arch/m32r/kernel/setup_m32700ut.c +++ b/arch/m32r/kernel/setup_m32700ut.c @@ -78,13 +78,13 @@ static void shutdown_m32700ut_irq(unsigned int irq) static struct hw_interrupt_type m32700ut_irq_type = { - "M32700UT-IRQ", - startup_m32700ut_irq, - shutdown_m32700ut_irq, - enable_m32700ut_irq, - disable_m32700ut_irq, - mask_and_ack_m32700ut, - end_m32700ut_irq + .typename = "M32700UT-IRQ", + .startup = startup_m32700ut_irq, + .shutdown = shutdown_m32700ut_irq, + .enable = enable_m32700ut_irq, + .disable = disable_m32700ut_irq, + .ack = mask_and_ack_m32700ut, + .end = end_m32700ut_irq }; /* @@ -155,13 +155,13 @@ static void shutdown_m32700ut_pld_irq(unsigned int irq) static struct hw_interrupt_type m32700ut_pld_irq_type = { - "M32700UT-PLD-IRQ", - startup_m32700ut_pld_irq, - shutdown_m32700ut_pld_irq, - enable_m32700ut_pld_irq, - disable_m32700ut_pld_irq, - mask_and_ack_m32700ut_pld, - end_m32700ut_pld_irq + .typename = "M32700UT-PLD-IRQ", + .startup = startup_m32700ut_pld_irq, + .shutdown = shutdown_m32700ut_pld_irq, + .enable = enable_m32700ut_pld_irq, + .disable = disable_m32700ut_pld_irq, + .ack = mask_and_ack_m32700ut_pld, + .end = end_m32700ut_pld_irq }; /* @@ -224,13 +224,13 @@ static void shutdown_m32700ut_lanpld_irq(unsigned int irq) static struct hw_interrupt_type m32700ut_lanpld_irq_type = { - "M32700UT-PLD-LAN-IRQ", - startup_m32700ut_lanpld_irq, - shutdown_m32700ut_lanpld_irq, - enable_m32700ut_lanpld_irq, - disable_m32700ut_lanpld_irq, - mask_and_ack_m32700ut_lanpld, - end_m32700ut_lanpld_irq + .typename = "M32700UT-PLD-LAN-IRQ", + .startup = startup_m32700ut_lanpld_irq, + .shutdown = shutdown_m32700ut_lanpld_irq, + .enable = enable_m32700ut_lanpld_irq, + .disable = disable_m32700ut_lanpld_irq, + .ack = mask_and_ack_m32700ut_lanpld, + .end = end_m32700ut_lanpld_irq }; /* @@ -293,13 +293,13 @@ static void shutdown_m32700ut_lcdpld_irq(unsigned int irq) static struct hw_interrupt_type m32700ut_lcdpld_irq_type = { - "M32700UT-PLD-LCD-IRQ", - startup_m32700ut_lcdpld_irq, - shutdown_m32700ut_lcdpld_irq, - enable_m32700ut_lcdpld_irq, - disable_m32700ut_lcdpld_irq, - mask_and_ack_m32700ut_lcdpld, - end_m32700ut_lcdpld_irq + .typename = "M32700UT-PLD-LCD-IRQ", + .startup = startup_m32700ut_lcdpld_irq, + .shutdown = shutdown_m32700ut_lcdpld_irq, + .enable = enable_m32700ut_lcdpld_irq, + .disable = disable_m32700ut_lcdpld_irq, + .ack = mask_and_ack_m32700ut_lcdpld, + .end = end_m32700ut_lcdpld_irq }; void __init init_IRQ(void) diff --git a/arch/m32r/kernel/setup_mappi.c b/arch/m32r/kernel/setup_mappi.c index 1e74110f0670..aaf8e569b930 100644 --- a/arch/m32r/kernel/setup_mappi.c +++ b/arch/m32r/kernel/setup_mappi.c @@ -70,13 +70,13 @@ static void shutdown_mappi_irq(unsigned int irq) static struct hw_interrupt_type mappi_irq_type = { - "MAPPI-IRQ", - startup_mappi_irq, - shutdown_mappi_irq, - enable_mappi_irq, - disable_mappi_irq, - mask_and_ack_mappi, - end_mappi_irq + .typename = "MAPPI-IRQ", + .startup = startup_mappi_irq, + .shutdown = shutdown_mappi_irq, + .enable = enable_mappi_irq, + .disable = disable_mappi_irq, + .ack = mask_and_ack_mappi, + .end = end_mappi_irq }; void __init init_IRQ(void) diff --git a/arch/m32r/kernel/setup_mappi2.c b/arch/m32r/kernel/setup_mappi2.c index 248fc658dbd5..38d5e9a41427 100644 --- a/arch/m32r/kernel/setup_mappi2.c +++ b/arch/m32r/kernel/setup_mappi2.c @@ -79,13 +79,13 @@ static void shutdown_mappi2_irq(unsigned int irq) static struct hw_interrupt_type mappi2_irq_type = { - "MAPPI2-IRQ", - startup_mappi2_irq, - shutdown_mappi2_irq, - enable_mappi2_irq, - disable_mappi2_irq, - mask_and_ack_mappi2, - end_mappi2_irq + .typename = "MAPPI2-IRQ", + .startup = startup_mappi2_irq, + .shutdown = shutdown_mappi2_irq, + .enable = enable_mappi2_irq, + .disable = disable_mappi2_irq, + .ack = mask_and_ack_mappi2, + .end = end_mappi2_irq }; void __init init_IRQ(void) diff --git a/arch/m32r/kernel/setup_mappi3.c b/arch/m32r/kernel/setup_mappi3.c index 72b5b7609cea..3d60a85aaec5 100644 --- a/arch/m32r/kernel/setup_mappi3.c +++ b/arch/m32r/kernel/setup_mappi3.c @@ -79,13 +79,13 @@ static void shutdown_mappi3_irq(unsigned int irq) static struct hw_interrupt_type mappi3_irq_type = { - "MAPPI3-IRQ", - startup_mappi3_irq, - shutdown_mappi3_irq, - enable_mappi3_irq, - disable_mappi3_irq, - mask_and_ack_mappi3, - end_mappi3_irq + .typename = "MAPPI3-IRQ", + .startup = startup_mappi3_irq, + .shutdown = shutdown_mappi3_irq, + .enable = enable_mappi3_irq, + .disable = disable_mappi3_irq, + .ack = mask_and_ack_mappi3, + .end = end_mappi3_irq }; void __init init_IRQ(void) diff --git a/arch/m32r/kernel/setup_oaks32r.c b/arch/m32r/kernel/setup_oaks32r.c index b04834526c9a..d656640badc9 100644 --- a/arch/m32r/kernel/setup_oaks32r.c +++ b/arch/m32r/kernel/setup_oaks32r.c @@ -70,13 +70,13 @@ static void shutdown_oaks32r_irq(unsigned int irq) static struct hw_interrupt_type oaks32r_irq_type = { - "OAKS32R-IRQ", - startup_oaks32r_irq, - shutdown_oaks32r_irq, - enable_oaks32r_irq, - disable_oaks32r_irq, - mask_and_ack_mappi, - end_oaks32r_irq + .typename = "OAKS32R-IRQ", + .startup = startup_oaks32r_irq, + .shutdown = shutdown_oaks32r_irq, + .enable = enable_oaks32r_irq, + .disable = disable_oaks32r_irq, + .ack = mask_and_ack_mappi, + .end = end_oaks32r_irq }; void __init init_IRQ(void) diff --git a/arch/m32r/kernel/setup_opsput.c b/arch/m32r/kernel/setup_opsput.c index 84315e344c58..86f4cf2a86c3 100644 --- a/arch/m32r/kernel/setup_opsput.c +++ b/arch/m32r/kernel/setup_opsput.c @@ -79,13 +79,13 @@ static void shutdown_opsput_irq(unsigned int irq) static struct hw_interrupt_type opsput_irq_type = { - "OPSPUT-IRQ", - startup_opsput_irq, - shutdown_opsput_irq, - enable_opsput_irq, - disable_opsput_irq, - mask_and_ack_opsput, - end_opsput_irq + .typename = "OPSPUT-IRQ", + .startup = startup_opsput_irq, + .shutdown = shutdown_opsput_irq, + .enable = enable_opsput_irq, + .disable = disable_opsput_irq, + .ack = mask_and_ack_opsput, + .end = end_opsput_irq }; /* @@ -156,13 +156,13 @@ static void shutdown_opsput_pld_irq(unsigned int irq) static struct hw_interrupt_type opsput_pld_irq_type = { - "OPSPUT-PLD-IRQ", - startup_opsput_pld_irq, - shutdown_opsput_pld_irq, - enable_opsput_pld_irq, - disable_opsput_pld_irq, - mask_and_ack_opsput_pld, - end_opsput_pld_irq + .typename = "OPSPUT-PLD-IRQ", + .startup = startup_opsput_pld_irq, + .shutdown = shutdown_opsput_pld_irq, + .enable = enable_opsput_pld_irq, + .disable = disable_opsput_pld_irq, + .ack = mask_and_ack_opsput_pld, + .end = end_opsput_pld_irq }; /* diff --git a/arch/m32r/kernel/setup_usrv.c b/arch/m32r/kernel/setup_usrv.c index fe417be5e3e9..634741bf9d35 100644 --- a/arch/m32r/kernel/setup_usrv.c +++ b/arch/m32r/kernel/setup_usrv.c @@ -70,13 +70,13 @@ static void shutdown_mappi_irq(unsigned int irq) static struct hw_interrupt_type mappi_irq_type = { - "M32700-IRQ", - startup_mappi_irq, - shutdown_mappi_irq, - enable_mappi_irq, - disable_mappi_irq, - mask_and_ack_mappi, - end_mappi_irq + .typename = "M32700-IRQ", + .startup = startup_mappi_irq, + .shutdown = shutdown_mappi_irq, + .enable = enable_mappi_irq, + .disable = disable_mappi_irq, + .ack = mask_and_ack_mappi, + .end = end_mappi_irq }; /* @@ -143,13 +143,13 @@ static void shutdown_m32700ut_pld_irq(unsigned int irq) static struct hw_interrupt_type m32700ut_pld_irq_type = { - "USRV-PLD-IRQ", - startup_m32700ut_pld_irq, - shutdown_m32700ut_pld_irq, - enable_m32700ut_pld_irq, - disable_m32700ut_pld_irq, - mask_and_ack_m32700ut_pld, - end_m32700ut_pld_irq + .typename = "USRV-PLD-IRQ", + .startup = startup_m32700ut_pld_irq, + .shutdown = shutdown_m32700ut_pld_irq, + .enable = enable_m32700ut_pld_irq, + .disable = disable_m32700ut_pld_irq, + .ack = mask_and_ack_m32700ut_pld, + .end = end_m32700ut_pld_irq }; void __init init_IRQ(void) -- cgit v1.2.3-59-g8ed1b From 934bb7f88eb398f62314fa63ba72ac6dcd21192a Mon Sep 17 00:00:00 2001 From: Hirokazu Takata Date: Tue, 21 Jun 2005 17:16:14 -0700 Subject: [PATCH] m32r: Update m32r_cfc.[ch] to support Mappi-III platform This patch is for the M32R CF/PCMCIA drivers to support a new platform, Mappi-III evaluation board. Signed-off-by: Mamoru Sakugawa Signed-off-by: Hirokazu Takata Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pcmcia/Kconfig | 6 +++-- drivers/pcmcia/m32r_cfc.c | 57 +++++++++++++++++++---------------------------- drivers/pcmcia/m32r_cfc.h | 8 +++++-- 3 files changed, 33 insertions(+), 38 deletions(-) diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index 6375ebc85020..14e4124e1523 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -171,19 +171,21 @@ config PCMCIA_PROBE config M32R_PCC bool "M32R PCMCIA I/F" depends on M32R && CHIP_M32700 && PCMCIA + select PCCARD_NONSTATIC help Say Y here to use the M32R PCMCIA controller. config M32R_CFC bool "M32R CF I/F Controller" - depends on M32R && (PLAT_USRV || PLAT_M32700UT || PLAT_MAPPI2 || PLAT_OPSPUT) + depends on M32R && (PLAT_USRV || PLAT_M32700UT || PLAT_MAPPI2 || PLAT_MAPPI3 || PLAT_OPSPUT) + select PCCARD_NONSTATIC help Say Y here to use the M32R CompactFlash controller. config M32R_CFC_NUM int "M32R CF I/F number" depends on M32R_CFC - default "1" if PLAT_USRV || PLAT_M32700UT || PLAT_MAPPI2 || PLAT_OPSPUT + default "1" if PLAT_USRV || PLAT_M32700UT || PLAT_MAPPI2 || PLAT_MAPPI3 || PLAT_OPSPUT help Set the number of M32R CF slots. diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c index 581bfa95429e..b1111c6bf062 100644 --- a/drivers/pcmcia/m32r_cfc.c +++ b/drivers/pcmcia/m32r_cfc.c @@ -24,9 +24,9 @@ #include #include #include +#include #include #include -#include #include #include @@ -444,7 +444,7 @@ static int _pcc_get_status(u_short sock, u_int *value) debug(3, "m32r_cfc: _pcc_get_status: " "power off (CPCR=0x%08x)\n", status); } -#elif defined(CONFIG_PLAT_MAPPI2) +#elif defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3) if ( status ) { status = pcc_get(sock, (unsigned int)PLD_CPCR); if (status == 0) { /* power off */ @@ -452,18 +452,23 @@ static int _pcc_get_status(u_short sock, u_int *value) pcc_set(sock, (unsigned int)PLD_CFBUFCR,0); /* force buffer off for ZA-36 */ udelay(50); } - status = pcc_get(sock, (unsigned int)PLD_CFBUFCR); - if (status != 0) { /* buffer off */ - pcc_set(sock, (unsigned int)PLD_CFBUFCR,0); - udelay(50); - pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0101); - udelay(25); /* for IDE reset */ - pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0100); - mdelay(2); /* for IDE reset */ - } else { - *value |= SS_POWERON; - *value |= SS_READY; - } + *value |= SS_POWERON; + + pcc_set(sock, (unsigned int)PLD_CFBUFCR,0); + udelay(50); + pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0101); + udelay(25); /* for IDE reset */ + pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0100); + mdelay(2); /* for IDE reset */ + + *value |= SS_READY; + *value |= SS_3VCARD; + } else { + /* disable CF power */ + pcc_set(sock, (unsigned int)PLD_CPCR, 0); + udelay(100); + debug(3, "m32r_cfc: _pcc_get_status: " + "power off (CPCR=0x%08x)\n", status); } #else #error no platform configuration @@ -479,14 +484,13 @@ static int _pcc_get_socket(u_short sock, socket_state_t *state) { // pcc_socket_t *t = &socket[sock]; -#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT) state->flags = 0; state->csc_mask = SS_DETECT; state->csc_mask |= SS_READY; state->io_irq = 0; state->Vcc = 33; /* 3.3V fixed */ state->Vpp = 33; -#endif + debug(3, "m32r_cfc: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " "io_irq %d, csc_mask %#2.2x\n", sock, state->flags, state->Vcc, state->Vpp, state->io_irq, state->csc_mask); @@ -497,32 +501,17 @@ static int _pcc_get_socket(u_short sock, socket_state_t *state) static int _pcc_set_socket(u_short sock, socket_state_t *state) { -#if defined(CONFIG_PLAT_MAPPI2) - u_long reg = 0; -#endif debug(3, "m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags, state->Vcc, state->Vpp, state->io_irq, state->csc_mask); -#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT) +#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3) if (state->Vcc) { if ((state->Vcc != 50) && (state->Vcc != 33)) return -EINVAL; /* accept 5V and 3.3V */ } -#elif defined(CONFIG_PLAT_MAPPI2) - if (state->Vcc) { - /* - * 5V only - */ - if (state->Vcc == 50) { - reg |= PCCSIGCR_VEN; - } else { - return -EINVAL; - } - } #endif - if (state->flags & SS_RESET) { debug(3, ":RESET\n"); pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x101); @@ -788,7 +777,7 @@ static int __init init_m32r_pcc(void) return ret; } -#if defined(CONFIG_PLAT_MAPPI2) +#if defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3) pcc_set(0, (unsigned int)PLD_CFCR0, 0x0f0f); pcc_set(0, (unsigned int)PLD_CFCR1, 0x0200); #endif @@ -825,7 +814,7 @@ static int __init init_m32r_pcc(void) for (i = 0 ; i < pcc_sockets ; i++) { socket[i].socket.dev.dev = &pcc_device.dev; socket[i].socket.ops = &pcc_operations; - socket[i].socket.resource_ops = &pccard_static_ops; + socket[i].socket.resource_ops = &pccard_nonstatic_ops; socket[i].socket.owner = THIS_MODULE; socket[i].number = i; ret = pcmcia_register_socket(&socket[i].socket); diff --git a/drivers/pcmcia/m32r_cfc.h b/drivers/pcmcia/m32r_cfc.h index 17c1db7ae155..8146e3bee2e8 100644 --- a/drivers/pcmcia/m32r_cfc.h +++ b/drivers/pcmcia/m32r_cfc.h @@ -71,11 +71,15 @@ #define CFC_IOPORT_BASE 0x1000 -#if !defined(CONFIG_PLAT_USRV) +#if defined(CONFIG_PLAT_MAPPI3) +#define CFC_ATTR_MAPBASE 0x14014000 +#define CFC_IO_MAPBASE_BYTE 0xb4012000 +#define CFC_IO_MAPBASE_WORD 0xb4002000 +#elif !defined(CONFIG_PLAT_USRV) #define CFC_ATTR_MAPBASE 0x0c014000 #define CFC_IO_MAPBASE_BYTE 0xac012000 #define CFC_IO_MAPBASE_WORD 0xac002000 -#else /* CONFIG_PLAT_USRV */ +#else #define CFC_ATTR_MAPBASE 0x04014000 #define CFC_IO_MAPBASE_BYTE 0xa4012000 #define CFC_IO_MAPBASE_WORD 0xa4002000 -- cgit v1.2.3-59-g8ed1b From 1cc1265e9a8579be0029cd675ec22a6151893e04 Mon Sep 17 00:00:00 2001 From: Hirokazu Takata Date: Tue, 21 Jun 2005 17:16:15 -0700 Subject: [PATCH] m32r: Cleanup arch/m32r/mm/extable.c Signed-off-by: Hirokazu Takata Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/m32r/mm/extable.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/m32r/mm/extable.c b/arch/m32r/mm/extable.c index 9a97363b6524..1743f23d49a3 100644 --- a/arch/m32r/mm/extable.c +++ b/arch/m32r/mm/extable.c @@ -1,10 +1,8 @@ /* - * linux/arch/i386/mm/extable.c + * linux/arch/m32r/mm/extable.c */ -#include #include -#include #include int fixup_exception(struct pt_regs *regs) @@ -19,4 +17,3 @@ int fixup_exception(struct pt_regs *regs) return 0; } - -- cgit v1.2.3-59-g8ed1b From 0adbb44a146d6dff3f74ea7a9d3826f8942ed709 Mon Sep 17 00:00:00 2001 From: Hirokazu Takata Date: Tue, 21 Jun 2005 17:16:16 -0700 Subject: [PATCH] m32r: Remove include/asm-m32r/m32102peri.h This patch removes an obsolete header file include/asm-m32r/m32102peri.h. In this header, there are some undesirable single character types, like V. And the header is almost no longer used. Signed-off-by: Hayato Fujiwara Signed-off-by: Hirokazu Takata Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/net/8390.c | 4 +- include/asm-m32r/m32102peri.h | 468 ------------------------------------------ include/asm-m32r/m32r.h | 1 - 3 files changed, 2 insertions(+), 471 deletions(-) delete mode 100644 include/asm-m32r/m32102peri.h diff --git a/drivers/net/8390.c b/drivers/net/8390.c index bab16bcc9ae5..6d76f3a99b17 100644 --- a/drivers/net/8390.c +++ b/drivers/net/8390.c @@ -225,9 +225,9 @@ void ei_tx_timeout(struct net_device *dev) unsigned long icucr; local_irq_save(flags); - icucr = inl(ICUCR1); + icucr = inl(M32R_ICU_CR1_PORTL); icucr |= M32R_ICUCR_ISMOD11; - outl(icucr, ICUCR1); + outl(icucr, M32R_ICU_CR1_PORTL); local_irq_restore(flags); #endif ei_local->stat.tx_errors++; diff --git a/include/asm-m32r/m32102peri.h b/include/asm-m32r/m32102peri.h deleted file mode 100644 index 3c12955ad0f0..000000000000 --- a/include/asm-m32r/m32102peri.h +++ /dev/null @@ -1,468 +0,0 @@ -/* $Id$ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000,2001 by Hiroyuki Kondo - */ - -#ifndef __ASSEMBLY__ - -typedef void V; -typedef char B; -typedef short S; -typedef int W; -typedef long L; -typedef float F; -typedef double D; -typedef unsigned char UB; -typedef unsigned short US; -typedef unsigned int UW; -typedef unsigned long UL; -typedef const unsigned int CUW; - -/********************************* - -M32102 ICU - -*********************************/ -#define ICUISTS (UW *)0xa0EFF004 -#define ICUIREQ0 (UW *)0xa0EFF008 -#define ICUIREQ1 (UW *)0xa0EFF00C - -#define ICUSBICR (UW *)0xa0EFF018 -#define ICUIMASK (UW *)0xa0EFF01C - -#define ICUCR1 (UW *)0xa0EFF200 /* INT0 */ -#define ICUCR2 (UW *)0xa0EFF204 /* INT1 */ -#define ICUCR3 (UW *)0xa0EFF208 /* INT2 */ -#define ICUCR4 (UW *)0xa0EFF20C /* INT3 */ -#define ICUCR5 (UW *)0xa0EFF210 /* INT4 */ -#define ICUCR6 (UW *)0xa0EFF214 /* INT5 */ -#define ICUCR7 (UW *)0xa0EFF218 /* INT6 */ - -#define ICUCR16 (UW *)0xa0EFF23C /* MFT0 */ -#define ICUCR17 (UW *)0xa0EFF240 /* MFT1 */ -#define ICUCR18 (UW *)0xa0EFF244 /* MFT2 */ -#define ICUCR19 (UW *)0xa0EFF248 /* MFT3 */ -#define ICUCR20 (UW *)0xa0EFF24C /* MFT4 */ -#define ICUCR21 (UW *)0xa0EFF250 /* MFT5 */ - -#define ICUCR32 (UW *)0xa0EFF27C /* DMA0 */ -#define ICUCR33 (UW *)0xa0EFF280 /* DMA1 */ - -#define ICUCR48 (UW *)0xa0EFF2BC /* SIO0R */ -#define ICUCR49 (UW *)0xa0EFF2C0 /* SIO0S */ -#define ICUCR50 (UW *)0xa0EFF2C4 /* SIO1R */ -#define ICUCR51 (UW *)0xa0EFF2C8 /* SIO1S */ -#define ICUCR52 (UW *)0xa0EFF2CC /* SIO2R */ -#define ICUCR53 (UW *)0xa0EFF2D0 /* SIO2S */ -#define ICUCR54 (UW *)0xa0EFF2D4 /* SIO3R */ -#define ICUCR55 (UW *)0xa0EFF2D8 /* SIO3S */ -#define ICUCR56 (UW *)0xa0EFF2DC /* SIO4R */ -#define ICUCR57 (UW *)0xa0EFF2E0 /* SIO4S */ - -/********************************* - -M32102 MFT - -*********************************/ -#define MFTCR (US *)0xa0EFC002 -#define MFTRPR (UB *)0xa0EFC006 - -#define MFT0MOD (US *)0xa0EFC102 -#define MFT0BOS (US *)0xa0EFC106 -#define MFT0CUT (US *)0xa0EFC10A -#define MFT0RLD (US *)0xa0EFC10E -#define MFT0CRLD (US *)0xa0EFC112 - -#define MFT1MOD (US *)0xa0EFC202 -#define MFT1BOS (US *)0xa0EFC206 -#define MFT1CUT (US *)0xa0EFC20A -#define MFT1RLD (US *)0xa0EFC20E -#define MFT1CRLD (US *)0xa0EFC212 - -#define MFT2MOD (US *)0xa0EFC302 -#define MFT2BOS (US *)0xa0EFC306 -#define MFT2CUT (US *)0xa0EFC30A -#define MFT2RLD (US *)0xa0EFC30E -#define MFT2CRLD (US *)0xa0EFC312 - -#define MFT3MOD (US *)0xa0EFC402 -#define MFT3CUT (US *)0xa0EFC40A -#define MFT3RLD (US *)0xa0EFC40E -#define MFT3CRLD (US *)0xa0EFC412 - -#define MFT4MOD (US *)0xa0EFC502 -#define MFT4CUT (US *)0xa0EFC50A -#define MFT4RLD (US *)0xa0EFC50E -#define MFT4CRLD (US *)0xa0EFC512 - -#define MFT5MOD (US *)0xa0EFC602 -#define MFT5CUT (US *)0xa0EFC60A -#define MFT5RLD (US *)0xa0EFC60E -#define MFT5CRLD (US *)0xa0EFC612 - -/********************************* - -M32102 SIO - -*********************************/ - -#define SIO0CR (volatile int *)0xa0efd000 -#define SIO0MOD0 (volatile int *)0xa0efd004 -#define SIO0MOD1 (volatile int *)0xa0efd008 -#define SIO0STS (volatile int *)0xa0efd00c -#define SIO0IMASK (volatile int *)0xa0efd010 -#define SIO0BAUR (volatile int *)0xa0efd014 -#define SIO0RBAUR (volatile int *)0xa0efd018 -#define SIO0TXB (volatile int *)0xa0efd01c -#define SIO0RXB (volatile int *)0xa0efd020 - -#define SIO1CR (volatile int *)0xa0efd100 -#define SIO1MOD0 (volatile int *)0xa0efd104 -#define SIO1MOD1 (volatile int *)0xa0efd108 -#define SIO1STS (volatile int *)0xa0efd10c -#define SIO1IMASK (volatile int *)0xa0efd110 -#define SIO1BAUR (volatile int *)0xa0efd114 -#define SIO1RBAUR (volatile int *)0xa0efd118 -#define SIO1TXB (volatile int *)0xa0efd11c -#define SIO1RXB (volatile int *)0xa0efd120 -/********************************* - -M32102 PORT - -*********************************/ -#define PIEN (UB *)0xa0EF1003 /* input enable */ - -#define P0DATA (UB *)0xa0EF1020 /* data */ -#define P1DATA (UB *)0xa0EF1021 -#define P2DATA (UB *)0xa0EF1022 -#define P3DATA (UB *)0xa0EF1023 -#define P4DATA (UB *)0xa0EF1024 -#define P5DATA (UB *)0xa0EF1025 -#define P6DATA (UB *)0xa0EF1026 -#define P7DATA (UB *)0xa0EF1027 - -#define P0DIR (UB *)0xa0EF1040 /* direction */ -#define P1DIR (UB *)0xa0EF1041 -#define P2DIR (UB *)0xa0EF1042 -#define P3DIR (UB *)0xa0EF1043 -#define P4DIR (UB *)0xa0EF1044 -#define P5DIR (UB *)0xa0EF1045 -#define P6DIR (UB *)0xa0EF1046 -#define P7DIR (UB *)0xa0EF1047 - -#define P0MOD (US *)0xa0EF1060 /* mode control */ -#define P1MOD (US *)0xa0EF1062 -#define P2MOD (US *)0xa0EF1064 -#define P3MOD (US *)0xa0EF1066 -#define P4MOD (US *)0xa0EF1068 -#define P5MOD (US *)0xa0EF106A -#define P6MOD (US *)0xa0EF106C -#define P7MOD (US *)0xa0EF106E - -#define P0ODCR (UB *)0xa0EF1080 /* open-drain control */ -#define P1ODCR (UB *)0xa0EF1081 -#define P2ODCR (UB *)0xa0EF1082 -#define P3ODCR (UB *)0xa0EF1083 -#define P4ODCR (UB *)0xa0EF1084 -#define P5ODCR (UB *)0xa0EF1085 -#define P6ODCR (UB *)0xa0EF1086 -#define P7ODCR (UB *)0xa0EF1087 - -/********************************* - -M32102 Cache - -********************************/ - -#define MCCR (US *)0xFFFFFFFE - - -#else /* __ASSEMBLY__ */ - -;; -;; PIO 0x80ef1000 -;; - -#define PIEN 0xa0ef1000 - -#define P0DATA 0xa0ef1020 -#define P1DATA 0xa0ef1021 -#define P2DATA 0xa0ef1022 -#define P3DATA 0xa0ef1023 -#define P4DATA 0xa0ef1024 -#define P5DATA 0xa0ef1025 -#define P6DATA 0xa0ef1026 -#define P7DATA 0xa0ef1027 - -#define P0DIR 0xa0ef1040 -#define P1DIR 0xa0ef1041 -#define P2DIR 0xa0ef1042 -#define P3DIR 0xa0ef1043 -#define P4DIR 0xa0ef1044 -#define P5DIR 0xa0ef1045 -#define P6DIR 0xa0ef1046 -#define P7DIR 0xa0ef1047 - -#define P0MOD 0xa0ef1060 -#define P1MOD 0xa0ef1062 -#define P2MOD 0xa0ef1064 -#define P3MOD 0xa0ef1066 -#define P4MOD 0xa0ef1068 -#define P5MOD 0xa0ef106a -#define P6MOD 0xa0ef106c -#define P7MOD 0xa0ef106e -; -#define P0ODCR 0xa0ef1080 -#define P1ODCR 0xa0ef1081 -#define P2ODCR 0xa0ef1082 -#define P3ODCR 0xa0ef1083 -#define P4ODCR 0xa0ef1084 -#define P5ODCR 0xa0ef1085 -#define P6ODCR 0xa0ef1086 -#define P7ODCR 0xa0ef1087 - -;; -;; WDT 0xa0ef2000 -;; - -#define WDTCR 0xa0ef2000 - - -;; -;; CLK 0xa0ef4000 -;; - -#define CPUCLKCR 0xa0ef4000 -#define CLKMOD 0xa0ef4004 -#define PLLCR 0xa0ef4008 - - -;; -;; BSEL 0xa0ef5000 -;; - -#define BSEL0CR 0xa0ef5000 -#define BSEL1CR 0xa0ef5004 -#define BSEL2CR 0xa0ef5008 -#define BSEL3CR 0xa0ef500c -#define BSEL4CR 0xa0ef5010 -#define BSEL5CR 0xa0ef5014 - - -;; -;; SDRAMC 0xa0ef6000 -;; - -#define SDRF0 0xa0ef6000 -#define SDRF1 0xa0ef6004 -#define SDIR0 0xa0ef6008 -#define SDIR1 0xa0ef600c -#define SDBR 0xa0ef6010 - -;; CH0 -#define SD0ADR 0xa0ef6020 -#define SD0SZ 0xa0ef6022 -#define SD0ER 0xa0ef6024 -#define SD0TR 0xa0ef6028 -#define SD0MOD 0xa0ef602c - -;; CH1 -#define SD1ADR 0xa0ef6040 -#define SD1SZ 0xa0ef6042 -#define SD1ER 0xa0ef6044 -#define SD1TR 0xa0ef6048 -#define SD1MOD 0xa0ef604c - - -;; -;; DMAC 0xa0ef8000 -;; - -#define DMAEN 0xa0ef8000 -#define DMAISTS 0xa0ef8004 -#define DMAEDET 0xa0ef8008 -#define DMAASTS 0xa0ef800c - -;; CH0 -#define DMA0CR0 0xa0ef8100 -#define DMA0CR1 0xa0ef8104 -#define DMA0CSA 0xa0ef8108 -#define DMA0RSA 0xa0ef810c -#define DMA0CDA 0xa0ef8110 -#define DMA0RDA 0xa0ef8114 -#define DMA0CBCUT 0xa0ef8118 -#define DMA0RBCUT 0xa0ef811c - -;; CH1 -#define DMA1CR0 0xa0ef8200 -#define DMA1CR1 0xa0ef8204 -#define DMA1CSA 0xa0ef8208 -#define DMA1RSA 0xa0ef820c -#define DMA1CDA 0xa0ef8210 -#define DMA1RDA 0xa0ef8214 -#define DMA1CBCUT 0xa0ef8218 -#define DMA1RBCUT 0xa0ef821c - - -;; -;; MFT 0xa0efc000 -;; - -#define MFTCR 0xa0efc000 -#define MFTRPR 0xa0efc004 - -;; CH0 -#define MFT0MOD 0xa0efc100 -#define MFT0BOS 0xa0efc104 -#define MFT0CUT 0xa0efc108 -#define MFT0RLD 0xa0efc10c -#define MFT0CMPRLD 0xa0efc110 - -;; CH1 -#define MFT1MOD 0xa0efc200 -#define MFT1BOS 0xa0efc204 -#define MFT1CUT 0xa0efc208 -#define MFT1RLD 0xa0efc20c -#define MFT1CMPRLD 0xa0efc210 - -;; CH2 -#define MFT2MOD 0xa0efc300 -#define MFT2BOS 0xa0efc304 -#define MFT2CUT 0xa0efc308 -#define MFT2RLD 0xa0efc30c -#define MFT2CMPRLD 0xa0efc310 - -;; CH3 -#define MFT3MOD 0xa0efc400 -#define MFT3BOS 0xa0efc404 -#define MFT3CUT 0xa0efc408 -#define MFT3RLD 0xa0efc40c -#define MFT3CMPRLD 0xa0efc410 - -;; CH4 -#define MFT4MOD 0xa0efc500 -#define MFT4BOS 0xa0efc504 -#define MFT4CUT 0xa0efc508 -#define MFT4RLD 0xa0efc50c -#define MFT4CMPRLD 0xa0efc510 - -;; CH5 -#define MFT5MOD 0xa0efc600 -#define MFT5BOS 0xa0efc604 -#define MFT5CUT 0xa0efc608 -#define MFT5RLD 0xa0efc60c -#define MFT5CMPRLD 0xa0efc610 - - -;; -;; SIO 0xa0efd000 -;; - -;; CH0 -#define SIO0CR 0xa0efd000 -#define SIO0MOD0 0xa0efd004 -#define SIO0MOD1 0xa0efd008 -#define SIO0STS 0xa0efd00c -#define SIO0IMASK 0xa0efd010 -#define SIO0BAUR 0xa0efd014 -#define SIO0RBAUR 0xa0efd018 -#define SIO0TXB 0xa0efd01c -#define SIO0RXB 0xa0efd020 - -;; CH1 -#define SIO1CR 0xa0efd100 -#define SIO1MOD0 0xa0efd104 -#define SIO1MOD1 0xa0efd108 -#define SIO1STS 0xa0efd10c -#define SIO1IMASK 0xa0efd110 -#define SIO1BAUR 0xa0efd114 -#define SIO1RBAUR 0xa0efd118 -#define SIO1TXB 0xa0efd11c -#define SIO1RXB 0xa0efd120 - -;; CH2 -#define SIO2CR 0xa0efd200 -#define SIO2MOD0 0xa0efd204 -#define SIO2MOD1 0xa0efd208 -#define SIO2STS 0xa0efd20c -#define SIO2IMASK 0xa0efd210 -#define SIO2BAUR 0xa0efd214 -#define SIO2RBAUR 0xa0efd218 -#define SIO2TXB 0xa0efd21c -#define SIO2RXB 0xa0efd220 - -;; CH3 -#define SIO3CR 0xa0efd300 -#define SIO3MOD0 0xa0efd304 -#define SIO3MOD1 0xa0efd308 -#define SIO3STS 0xa0efd30c -#define SIO3IMASK 0xa0efd310 -#define SIO3BAUR 0xa0efd314 -#define SIO3RBAUR 0xa0efd318 -#define SIO3TXB 0xa0efd31c -#define SIO3RXB 0xa0efd320 - -;; CH4 -#define SIO4CR 0xa0efd400 -#define SIO4MOD0 0xa0efd404 -#define SIO4MOD1 0xa0efd408 -#define SIO4STS 0xa0efd40c -#define SIO4IMASK 0xa0efd410 -#define SIO4BAUR 0xa0efd414 -#define SIO4RBAUR 0xa0efd418 -#define SIO4TXB 0xa0efd41c -#define SIO4RXB 0xa0efd420 - - -;; -;; ICU 0xa0eff000 -;; - -#define ICUISTS 0xa0eff004 -#define ICUIREQ0 0xa0eff008 -#define ICUIREQ1 0xa0eff00c - -#define ICUSBICR 0xa0eff018 -#define ICUIMASK 0xa0eff01c - -#define ICUCR1 0xa0eff200 -#define ICUCR2 0xa0eff204 -#define ICUCR3 0xa0eff208 -#define ICUCR4 0xa0eff20c -#define ICUCR5 0xa0eff210 -#define ICUCR6 0xa0eff214 -#define ICUCR7 0xa0eff218 - -#define ICUCR16 0xa0eff23c -#define ICUCR17 0xa0eff240 -#define ICUCR18 0xa0eff244 -#define ICUCR19 0xa0eff248 -#define ICUCR20 0xa0eff24c -#define ICUCR21 0xa0eff250 - -#define ICUCR32 0xa0eff27c -#define ICUCR33 0xa0eff280 - -#define ICUCR48 0xa0eff2bc -#define ICUCR49 0xa0eff2c0 -#define ICUCR50 0xa0eff2c4 -#define ICUCR51 0xa0eff2c8 -#define ICUCR52 0xa0eff2cc -#define ICUCR53 0xa0eff2d0 -#define ICUCR54 0xa0eff2d4 -#define ICUCR55 0xa0eff2d8 -#define ICUCR56 0xa0eff2dc -#define ICUCR57 0xa0eff2e0 - -;; -;; CACHE -;; - -#define MCCR 0xfffffffc - - -#endif /* __ASSEMBLY__ */ diff --git a/include/asm-m32r/m32r.h b/include/asm-m32r/m32r.h index fd2b2823762b..ec142be00862 100644 --- a/include/asm-m32r/m32r.h +++ b/include/asm-m32r/m32r.h @@ -16,7 +16,6 @@ || defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_M32102) \ || defined(CONFIG_CHIP_OPSP) #include -#include #endif /* Platform type */ -- cgit v1.2.3-59-g8ed1b From 960c2a89a051333d2e6793a416d9a33c4b116b41 Mon Sep 17 00:00:00 2001 From: Hirokazu Takata Date: Tue, 21 Jun 2005 17:16:16 -0700 Subject: [PATCH] m32r: Update defconfig files Signed-off-by: Hirokazu Takata Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/m32r/defconfig | 52 ++++++++++++++++++------------ arch/m32r/m32700ut/defconfig.m32700ut.smp | 53 +++++++++++++++++++------------ arch/m32r/m32700ut/defconfig.m32700ut.up | 52 ++++++++++++++++++------------ arch/m32r/mappi/defconfig.nommu | 46 +++++++++++++++------------ arch/m32r/mappi/defconfig.smp | 49 +++++++++++++++------------- arch/m32r/mappi/defconfig.up | 48 +++++++++++++++------------- arch/m32r/mappi2/defconfig.vdec2 | 46 +++++++++++++++------------ arch/m32r/oaks32r/defconfig.nommu | 50 ++++++++++++++--------------- arch/m32r/opsput/defconfig.opsput | 45 ++++++++++++++------------ 9 files changed, 247 insertions(+), 194 deletions(-) diff --git a/arch/m32r/defconfig b/arch/m32r/defconfig index 417c95ba87e9..853093093168 100644 --- a/arch/m32r/defconfig +++ b/arch/m32r/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc4 -# Wed Feb 16 21:10:44 2005 +# Linux kernel version: 2.6.12-rc5 +# Fri Jun 3 16:20:11 2005 # CONFIG_M32R=y # CONFIG_UID16 is not set @@ -16,6 +16,7 @@ CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -28,13 +29,15 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=14 CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y # CONFIG_IKCONFIG_PROC is not set CONFIG_EMBEDDED=y # CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set # CONFIG_EPOLL is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -44,6 +47,7 @@ CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -65,6 +69,7 @@ CONFIG_PLAT_M32700UT=y # CONFIG_PLAT_OPSPUT is not set # CONFIG_PLAT_OAKS32R is not set # CONFIG_PLAT_MAPPI2 is not set +# CONFIG_PLAT_MAPPI3 is not set CONFIG_CHIP_M32700=y # CONFIG_CHIP_M32102 is not set # CONFIG_CHIP_VDEC2 is not set @@ -268,7 +273,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -392,18 +396,6 @@ CONFIG_INPUT=y # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_LIBPS2 is not set -# CONFIG_SERIO_RAW is not set - # # Input Device Drivers # @@ -413,6 +405,17 @@ CONFIG_SERIO_SERPORT=y # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + # # Character devices # @@ -464,6 +467,10 @@ CONFIG_DS1302=y # CONFIG_SYNCLINK_CS is not set # CONFIG_RAW_DRIVER is not set +# +# TPM devices +# + # # I2C support # @@ -508,8 +515,14 @@ CONFIG_VIDEO_M32R_AR_M64278=y # 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_SOFT_CURSOR is not set +# CONFIG_FB_MACMODES is not set # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -542,10 +555,6 @@ CONFIG_LOGO_LINUX_CLUT224=y # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information -# - # # USB Gadget Support # @@ -719,8 +728,9 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_DEBUG_PREEMPT=y +CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_FRAME_POINTER is not set diff --git a/arch/m32r/m32700ut/defconfig.m32700ut.smp b/arch/m32r/m32700ut/defconfig.m32700ut.smp index 1c002181df7f..3e607d90b5f4 100644 --- a/arch/m32r/m32700ut/defconfig.m32700ut.smp +++ b/arch/m32r/m32700ut/defconfig.m32700ut.smp @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc4 -# Wed Feb 16 21:10:50 2005 +# Linux kernel version: 2.6.12-rc5 +# Fri Jun 3 16:20:58 2005 # CONFIG_M32R=y # CONFIG_UID16 is not set @@ -15,6 +15,7 @@ CONFIG_GENERIC_IRQ_PROBE=y CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -27,13 +28,16 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=15 CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y # CONFIG_IKCONFIG_PROC is not set +# CONFIG_CPUSETS is not set CONFIG_EMBEDDED=y # CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set # CONFIG_EPOLL is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -43,6 +47,7 @@ CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -65,6 +70,7 @@ CONFIG_PLAT_M32700UT=y # CONFIG_PLAT_OPSPUT is not set # CONFIG_PLAT_OAKS32R is not set # CONFIG_PLAT_MAPPI2 is not set +# CONFIG_PLAT_MAPPI3 is not set CONFIG_CHIP_M32700=y # CONFIG_CHIP_M32102 is not set # CONFIG_CHIP_VDEC2 is not set @@ -271,7 +277,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -395,18 +400,6 @@ CONFIG_INPUT=y # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_LIBPS2 is not set -# CONFIG_SERIO_RAW is not set - # # Input Device Drivers # @@ -416,6 +409,17 @@ CONFIG_SERIO_SERPORT=y # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + # # Character devices # @@ -467,6 +471,10 @@ CONFIG_DS1302=y # CONFIG_SYNCLINK_CS is not set # CONFIG_RAW_DRIVER is not set +# +# TPM devices +# + # # I2C support # @@ -511,8 +519,14 @@ CONFIG_VIDEO_M32R_AR_M64278=y # 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_SOFT_CURSOR is not set +# CONFIG_FB_MACMODES is not set # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -545,10 +559,6 @@ CONFIG_LOGO_LINUX_CLUT224=y # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information -# - # # USB Gadget Support # @@ -722,8 +732,9 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_DEBUG_PREEMPT=y +CONFIG_LOG_BUF_SHIFT=15 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_FRAME_POINTER is not set diff --git a/arch/m32r/m32700ut/defconfig.m32700ut.up b/arch/m32r/m32700ut/defconfig.m32700ut.up index 805357f7bda1..2d3e7cda8f46 100644 --- a/arch/m32r/m32700ut/defconfig.m32700ut.up +++ b/arch/m32r/m32700ut/defconfig.m32700ut.up @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc4 -# Wed Feb 16 21:10:54 2005 +# Linux kernel version: 2.6.12-rc5 +# Fri Jun 3 16:21:34 2005 # CONFIG_M32R=y # CONFIG_UID16 is not set @@ -16,6 +16,7 @@ CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -28,13 +29,15 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=14 CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y # CONFIG_IKCONFIG_PROC is not set CONFIG_EMBEDDED=y # CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set # CONFIG_EPOLL is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -44,6 +47,7 @@ CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -65,6 +69,7 @@ CONFIG_PLAT_M32700UT=y # CONFIG_PLAT_OPSPUT is not set # CONFIG_PLAT_OAKS32R is not set # CONFIG_PLAT_MAPPI2 is not set +# CONFIG_PLAT_MAPPI3 is not set CONFIG_CHIP_M32700=y # CONFIG_CHIP_M32102 is not set # CONFIG_CHIP_VDEC2 is not set @@ -268,7 +273,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -392,18 +396,6 @@ CONFIG_INPUT=y # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_LIBPS2 is not set -# CONFIG_SERIO_RAW is not set - # # Input Device Drivers # @@ -413,6 +405,17 @@ CONFIG_SERIO_SERPORT=y # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + # # Character devices # @@ -464,6 +467,10 @@ CONFIG_DS1302=y # CONFIG_SYNCLINK_CS is not set # CONFIG_RAW_DRIVER is not set +# +# TPM devices +# + # # I2C support # @@ -508,8 +515,14 @@ CONFIG_VIDEO_M32R_AR_M64278=y # 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_SOFT_CURSOR is not set +# CONFIG_FB_MACMODES is not set # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -542,10 +555,6 @@ CONFIG_LOGO_LINUX_CLUT224=y # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information -# - # # USB Gadget Support # @@ -719,8 +728,9 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_DEBUG_PREEMPT=y +CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_FRAME_POINTER is not set diff --git a/arch/m32r/mappi/defconfig.nommu b/arch/m32r/mappi/defconfig.nommu index 714aa6e7034c..a8425fba340b 100644 --- a/arch/m32r/mappi/defconfig.nommu +++ b/arch/m32r/mappi/defconfig.nommu @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc4 -# Wed Feb 16 21:10:57 2005 +# Linux kernel version: 2.6.12-rc5 +# Fri Jun 3 16:21:46 2005 # CONFIG_M32R=y # CONFIG_UID16 is not set @@ -16,6 +16,7 @@ CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -26,13 +27,15 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=14 CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y # CONFIG_IKCONFIG_PROC is not set CONFIG_EMBEDDED=y # CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set # CONFIG_EPOLL is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -41,6 +44,7 @@ CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 CONFIG_TINY_SHMEM=y +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -62,6 +66,7 @@ CONFIG_PLAT_MAPPI=y # CONFIG_PLAT_OPSPUT is not set # CONFIG_PLAT_OAKS32R is not set # CONFIG_PLAT_MAPPI2 is not set +# CONFIG_PLAT_MAPPI3 is not set CONFIG_CHIP_M32700=y # CONFIG_CHIP_M32102 is not set # CONFIG_CHIP_VDEC2 is not set @@ -202,7 +207,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -324,18 +328,6 @@ CONFIG_INPUT=y # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_LIBPS2 is not set -# CONFIG_SERIO_RAW is not set - # # Input Device Drivers # @@ -345,6 +337,17 @@ CONFIG_SERIO_SERPORT=y # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + # # Character devices # @@ -393,6 +396,10 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_SYNCLINK_CS is not set # CONFIG_RAW_DRIVER is not set +# +# TPM devices +# + # # I2C support # @@ -433,10 +440,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information -# - # # USB Gadget Support # @@ -595,8 +598,9 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_DEBUG_PREEMPT=y +CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_FRAME_POINTER is not set diff --git a/arch/m32r/mappi/defconfig.smp b/arch/m32r/mappi/defconfig.smp index 956a8e2f98d6..1a7f3cd42246 100644 --- a/arch/m32r/mappi/defconfig.smp +++ b/arch/m32r/mappi/defconfig.smp @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc4 -# Wed Feb 16 21:11:02 2005 +# Linux kernel version: 2.6.12-rc5 +# Fri Jun 3 16:21:52 2005 # CONFIG_M32R=y # CONFIG_UID16 is not set @@ -17,6 +17,7 @@ CONFIG_EXPERIMENTAL=y CONFIG_BROKEN=y CONFIG_BROKEN_ON_SMP=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -28,13 +29,16 @@ CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=15 CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +# CONFIG_CPUSETS is not set CONFIG_EMBEDDED=y # CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set # CONFIG_EPOLL is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -44,6 +48,7 @@ CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -66,6 +71,7 @@ CONFIG_PLAT_MAPPI=y # CONFIG_PLAT_OPSPUT is not set # CONFIG_PLAT_OAKS32R is not set # CONFIG_PLAT_MAPPI2 is not set +# CONFIG_PLAT_MAPPI3 is not set CONFIG_CHIP_M32700=y # CONFIG_CHIP_M32102 is not set # CONFIG_CHIP_VDEC2 is not set @@ -139,8 +145,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set -CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 # CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set @@ -294,7 +300,6 @@ CONFIG_NET=y # Networking options # # CONFIG_PACKET is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -419,18 +424,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_LIBPS2 is not set -# CONFIG_SERIO_RAW is not set - # # Input Device Drivers # @@ -440,6 +433,17 @@ CONFIG_SERIO=y # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + # # Character devices # @@ -488,6 +492,10 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_SYNCLINK_CS is not set # CONFIG_RAW_DRIVER is not set +# +# TPM devices +# + # # I2C support # @@ -528,10 +536,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information -# - # # USB Gadget Support # @@ -708,8 +712,9 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_DEBUG_PREEMPT=y +CONFIG_LOG_BUF_SHIFT=15 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_FRAME_POINTER is not set diff --git a/arch/m32r/mappi/defconfig.up b/arch/m32r/mappi/defconfig.up index c9253e94efbd..38910fb76692 100644 --- a/arch/m32r/mappi/defconfig.up +++ b/arch/m32r/mappi/defconfig.up @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc4 -# Wed Feb 16 21:11:07 2005 +# Linux kernel version: 2.6.12-rc5 +# Fri Jun 3 16:21:59 2005 # CONFIG_M32R=y # CONFIG_UID16 is not set @@ -17,6 +17,7 @@ CONFIG_EXPERIMENTAL=y CONFIG_BROKEN=y CONFIG_BROKEN_ON_SMP=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -28,13 +29,15 @@ CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=14 CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_EMBEDDED=y # CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set # CONFIG_EPOLL is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -44,6 +47,7 @@ CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -65,6 +69,7 @@ CONFIG_PLAT_MAPPI=y # CONFIG_PLAT_OPSPUT is not set # CONFIG_PLAT_OAKS32R is not set # CONFIG_PLAT_MAPPI2 is not set +# CONFIG_PLAT_MAPPI3 is not set CONFIG_CHIP_M32700=y # CONFIG_CHIP_M32102 is not set # CONFIG_CHIP_VDEC2 is not set @@ -135,8 +140,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set -CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 # CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set @@ -290,7 +295,6 @@ CONFIG_NET=y # Networking options # # CONFIG_PACKET is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -415,18 +419,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_LIBPS2 is not set -# CONFIG_SERIO_RAW is not set - # # Input Device Drivers # @@ -436,6 +428,17 @@ CONFIG_SERIO=y # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + # # Character devices # @@ -484,6 +487,10 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_SYNCLINK_CS is not set # CONFIG_RAW_DRIVER is not set +# +# TPM devices +# + # # I2C support # @@ -524,10 +531,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information -# - # # USB Gadget Support # @@ -704,8 +707,9 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_DEBUG_PREEMPT=y +CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_FRAME_POINTER is not set diff --git a/arch/m32r/mappi2/defconfig.vdec2 b/arch/m32r/mappi2/defconfig.vdec2 index c14791d27300..56f287b65898 100644 --- a/arch/m32r/mappi2/defconfig.vdec2 +++ b/arch/m32r/mappi2/defconfig.vdec2 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc4 -# Wed Feb 16 21:11:10 2005 +# Linux kernel version: 2.6.12-rc5 +# Fri Jun 3 16:22:02 2005 # CONFIG_M32R=y # CONFIG_UID16 is not set @@ -16,6 +16,7 @@ CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -28,13 +29,15 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=14 CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y # CONFIG_IKCONFIG_PROC is not set CONFIG_EMBEDDED=y # CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set # CONFIG_EPOLL is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -44,6 +47,7 @@ CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -65,6 +69,7 @@ CONFIG_KMOD=y # CONFIG_PLAT_OPSPUT is not set # CONFIG_PLAT_OAKS32R is not set CONFIG_PLAT_MAPPI2=y +# CONFIG_PLAT_MAPPI3 is not set # CONFIG_CHIP_M32700 is not set # CONFIG_CHIP_M32102 is not set CONFIG_CHIP_VDEC2=y @@ -264,7 +269,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -388,18 +392,6 @@ CONFIG_INPUT=y # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_LIBPS2 is not set -# CONFIG_SERIO_RAW is not set - # # Input Device Drivers # @@ -409,6 +401,17 @@ CONFIG_SERIO_SERPORT=y # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + # # Character devices # @@ -459,6 +462,10 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_SYNCLINK_CS is not set # CONFIG_RAW_DRIVER is not set +# +# TPM devices +# + # # I2C support # @@ -520,10 +527,6 @@ CONFIG_DUMMY_CONSOLE=y # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information -# - # # USB Gadget Support # @@ -697,8 +700,9 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_DEBUG_PREEMPT=y +CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_FRAME_POINTER is not set diff --git a/arch/m32r/oaks32r/defconfig.nommu b/arch/m32r/oaks32r/defconfig.nommu index f2da9be726e5..3f9fe519acb2 100644 --- a/arch/m32r/oaks32r/defconfig.nommu +++ b/arch/m32r/oaks32r/defconfig.nommu @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc4 -# Wed Feb 16 21:11:13 2005 +# Linux kernel version: 2.6.12-rc5 +# Fri Jun 3 16:22:04 2005 # CONFIG_M32R=y # CONFIG_UID16 is not set @@ -16,6 +16,7 @@ CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -26,12 +27,14 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=14 CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set CONFIG_EMBEDDED=y # CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set # CONFIG_EPOLL is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -40,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 CONFIG_TINY_SHMEM=y +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -61,6 +65,7 @@ CONFIG_KMOD=y # CONFIG_PLAT_OPSPUT is not set CONFIG_PLAT_OAKS32R=y # CONFIG_PLAT_MAPPI2 is not set +# CONFIG_PLAT_MAPPI3 is not set # CONFIG_CHIP_M32700 is not set CONFIG_CHIP_M32102=y # CONFIG_CHIP_VDEC2 is not set @@ -91,10 +96,6 @@ CONFIG_PREEMPT=y # # CONFIG_PCCARD is not set -# -# PC-card bridges -# - # # PCI Hotplug Support # @@ -193,7 +194,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -310,18 +310,6 @@ CONFIG_INPUT=y # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_LIBPS2 is not set -# CONFIG_SERIO_RAW is not set - # # Input Device Drivers # @@ -331,6 +319,17 @@ CONFIG_SERIO_SERPORT=y # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + # # Character devices # @@ -374,6 +373,10 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set +# +# TPM devices +# + # # I2C support # @@ -414,10 +417,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information -# - # # USB Gadget Support # @@ -574,8 +573,9 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_DEBUG_PREEMPT=y +CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_FRAME_POINTER is not set diff --git a/arch/m32r/opsput/defconfig.opsput b/arch/m32r/opsput/defconfig.opsput index a87e1ea4c301..66adec6a701a 100644 --- a/arch/m32r/opsput/defconfig.opsput +++ b/arch/m32r/opsput/defconfig.opsput @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc4 -# Wed Feb 16 21:11:41 2005 +# Linux kernel version: 2.6.12-rc5 +# Fri Jun 3 16:22:06 2005 # CONFIG_M32R=y # CONFIG_UID16 is not set @@ -15,6 +15,7 @@ CONFIG_GENERIC_IRQ_PROBE=y CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -27,13 +28,15 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=14 CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y # CONFIG_IKCONFIG_PROC is not set CONFIG_EMBEDDED=y # CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set # CONFIG_EPOLL is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -43,6 +46,7 @@ CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -64,6 +68,7 @@ CONFIG_KMOD=y CONFIG_PLAT_OPSPUT=y # CONFIG_PLAT_OAKS32R is not set # CONFIG_PLAT_MAPPI2 is not set +# CONFIG_PLAT_MAPPI3 is not set # CONFIG_CHIP_M32700 is not set # CONFIG_CHIP_M32102 is not set # CONFIG_CHIP_VDEC2 is not set @@ -243,7 +248,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -367,18 +371,6 @@ CONFIG_INPUT=y # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_LIBPS2 is not set -# CONFIG_SERIO_RAW is not set - # # Input Device Drivers # @@ -388,6 +380,17 @@ CONFIG_SERIO_SERPORT=y # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + # # Character devices # @@ -437,6 +440,10 @@ CONFIG_DS1302=y # CONFIG_SYNCLINK_CS is not set # CONFIG_RAW_DRIVER is not set +# +# TPM devices +# + # # I2C support # @@ -477,10 +484,6 @@ CONFIG_DS1302=y # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information -# - # # USB Gadget Support # @@ -654,8 +657,10 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y # CONFIG_MAGIC_SYSRQ is not set +CONFIG_LOG_BUF_SHIFT=14 # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set -- cgit v1.2.3-59-g8ed1b From 5757b284a300e0e5d2173750906625b6470bd9f0 Mon Sep 17 00:00:00 2001 From: Hirokazu Takata Date: Tue, 21 Jun 2005 17:16:17 -0700 Subject: [PATCH] m32r: Use asm-generic/div64.h The current include/asm-m32r/div64.h of 2.6.12-rc5 looks buggy. Here is a patch for updating it to use asm-generic/div64.h for m32r like other architectures. Signed-off-by: Hitoshi Yamamoto Signed-off-by: Hirokazu Takata Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-m32r/div64.h | 39 +-------------------------------------- 1 file changed, 1 insertion(+), 38 deletions(-) diff --git a/include/asm-m32r/div64.h b/include/asm-m32r/div64.h index 417a51bd552d..6cd978cefb28 100644 --- a/include/asm-m32r/div64.h +++ b/include/asm-m32r/div64.h @@ -1,38 +1 @@ -#ifndef _ASM_M32R_DIV64 -#define _ASM_M32R_DIV64 - -/* $Id$ */ - -/* unsigned long long division. - * Input: - * unsigned long long n - * unsigned long base - * Output: - * n = n / base; - * return value = n % base; - */ -#define do_div(n, base) \ -({ \ - unsigned long _res, _high, _mid, _low; \ - \ - _low = (n) & 0xffffffffUL; \ - _high = (n) >> 32; \ - if (_high) { \ - _mid = (_high % (unsigned long)(base)) << 16; \ - _high = _high / (unsigned long)(base); \ - _mid += _low >> 16; \ - _low &= 0x0000ffffUL; \ - _low += (_mid % (unsigned long)(base)) << 16; \ - _mid = _mid / (unsigned long)(base); \ - _res = _low % (unsigned long)(base); \ - _low = _low / (unsigned long)(base); \ - n = _low + ((long long)_mid << 16) + \ - ((long long)_high << 32); \ - } else { \ - _res = _low % (unsigned long)(base); \ - n = (_low / (unsigned long)(base)); \ - } \ - _res; \ -}) - -#endif /* _ASM_M32R_DIV64 */ +#include -- cgit v1.2.3-59-g8ed1b From dbce706e2550253c5ab6043f4f5dfde0cd02470f Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Tue, 21 Jun 2005 17:16:19 -0700 Subject: [PATCH] uml: add and use generic hw_controller_type->release With Chris Wedgwood Currently UML must explicitly call the UML-specific free_irq_by_irq_and_dev() for each free_irq call it's done. This is needed because ->shutdown and/or ->disable are only called when the last "action" for that irq is removed. Instead, for UML shared IRQs (UML IRQs are very often, if not always, shared), for each dev_id some setup is done, which must be cleared on the release of that fd. For instance, for each open console a new instance (i.e. new dev_id) of the same IRQ is requested(). Exactly, a fd is stored in an array (pollfds), which is after read by a host thread and passed to poll(). Each event registered by poll() triggers an interrupt. So, for each free_irq() we must remove the corresponding host fd from the table, which we do via this -release() method. In this patch we add an appropriate hook for this, and remove all uses of it by pointing the hook to the said procedure; this is safe to do since the said procedure. Also some cosmetic improvements are included. This is heavily based on some work by Chris Wedgwood, which however didn't get the patch merged for something I'd call a "misunderstanding" (the need for this patch wasn't cleanly explained, thus adding the generic hook was felt as undesirable). Signed-off-by: Paolo 'Blaisorblade' Giarrusso CC: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/line.c | 2 -- arch/um/drivers/net_kern.c | 1 - arch/um/drivers/port_kern.c | 1 - arch/um/drivers/xterm_kern.c | 1 - arch/um/kernel/irq.c | 11 +++++++---- arch/um/kernel/irq_user.c | 2 -- include/linux/irq.h | 1 + kernel/irq/manage.c | 4 ++++ 8 files changed, 12 insertions(+), 11 deletions(-) diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 025d3be8aca4..562f864254ba 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -406,14 +406,12 @@ void line_disable(struct tty_struct *tty, int current_irq) if(line->driver->read_irq == current_irq) free_irq_later(line->driver->read_irq, tty); else { - free_irq_by_irq_and_dev(line->driver->read_irq, tty); free_irq(line->driver->read_irq, tty); } if(line->driver->write_irq == current_irq) free_irq_later(line->driver->write_irq, tty); else { - free_irq_by_irq_and_dev(line->driver->write_irq, tty); free_irq(line->driver->write_irq, tty); } diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 4eeaf88c1e97..5388a7428691 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -146,7 +146,6 @@ static int uml_net_close(struct net_device *dev) netif_stop_queue(dev); spin_lock(&lp->lock); - free_irq_by_irq_and_dev(dev->irq, dev); free_irq(dev->irq, dev); if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user); diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index b5ee07472f79..c41efd207fcc 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c @@ -257,7 +257,6 @@ int port_wait(void *data) * connection. Then we loop here throwing out failed * connections until a good one is found. */ - free_irq_by_irq_and_dev(TELNETD_IRQ, conn); free_irq(TELNETD_IRQ, conn); if(conn->fd >= 0) break; diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c index a4fdf3584ad2..d269a80f4b0c 100644 --- a/arch/um/drivers/xterm_kern.c +++ b/arch/um/drivers/xterm_kern.c @@ -69,7 +69,6 @@ int xterm_fd(int socket, int *pid_out) * isn't set) this will hang... */ wait_for_completion(&data->ready); - free_irq_by_irq_and_dev(XTERM_IRQ, data); free_irq(XTERM_IRQ, data); ret = data->new_fd; diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index d44fb5282547..9f18061ef4c9 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -124,14 +124,16 @@ void irq_unlock(unsigned long flags) spin_unlock_irqrestore(&irq_spinlock, flags); } -/* presently hw_interrupt_type must define (startup || enable) && - * disable && end */ +/* hw_interrupt_type must define (startup || enable) && + * (shutdown || disable) && end */ static void dummy(unsigned int irq) { } -static struct hw_interrupt_type SIGIO_irq_type = { +/* This is used for everything else than the timer. */ +static struct hw_interrupt_type normal_irq_type = { .typename = "SIGIO", + .release = free_irq_by_irq_and_dev, .disable = dummy, .enable = dummy, .ack = dummy, @@ -140,6 +142,7 @@ static struct hw_interrupt_type SIGIO_irq_type = { static struct hw_interrupt_type SIGVTALRM_irq_type = { .typename = "SIGVTALRM", + .release = free_irq_by_irq_and_dev, .shutdown = dummy, /* never called */ .disable = dummy, .enable = dummy, @@ -160,7 +163,7 @@ void __init init_IRQ(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].handler = &SIGIO_irq_type; + irq_desc[i].handler = &normal_irq_type; enable_irq(i); } } diff --git a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c index b3074cbaa479..c3ccaf24f3e0 100644 --- a/arch/um/kernel/irq_user.c +++ b/arch/um/kernel/irq_user.c @@ -85,8 +85,6 @@ void sigio_handler(int sig, union uml_pt_regs *regs) next = irq_fd->next; if(irq_fd->freed){ free_irq(irq_fd->irq, irq_fd->id); - free_irq_by_irq_and_dev(irq_fd->irq, - irq_fd->id); } } } diff --git a/include/linux/irq.h b/include/linux/irq.h index c3ff4d101667..b68ad80e2464 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -47,6 +47,7 @@ struct hw_interrupt_type { void (*ack)(unsigned int irq); void (*end)(unsigned int irq); void (*set_affinity)(unsigned int irq, cpumask_t dest); + void (*release)(unsigned int irq, void *dev_id); }; typedef struct hw_interrupt_type hw_irq_controller; diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 5202e4c4a5b6..5fde8177eedf 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -255,6 +255,10 @@ void free_irq(unsigned int irq, void *dev_id) /* Found it - now remove it from the list of entries */ *pp = action->next; + + if (desc->handler->release) + desc->handler->release(irq, dev_id); + if (!desc->action) { desc->status |= IRQ_DISABLED; if (desc->handler->shutdown) -- cgit v1.2.3-59-g8ed1b From faec1e99ba9ca7371d9aee1656938373133c4b21 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Tue, 21 Jun 2005 17:16:21 -0700 Subject: [PATCH] uml: complete hw_controller_type->release conversion This occurrence of free_irq_by_irq_and_dev() was missed when converting UML to the use of hw_controller_type->release. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/line.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 562f864254ba..0f59736db329 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -756,7 +756,6 @@ static void unregister_winch(struct tty_struct *tty) if(winch->pid != -1) os_kill_process(winch->pid, 1); - free_irq_by_irq_and_dev(WINCH_IRQ, winch); free_irq(WINCH_IRQ, winch); list_del(&winch->list); kfree(winch); -- cgit v1.2.3-59-g8ed1b From b77d6adc922b8bbf8b16b67f567958c42962cf88 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Tue, 21 Jun 2005 17:16:24 -0700 Subject: [PATCH] uml: make hw_controller_type->release exist only for archs needing it With Chris Wedgwood As suggested by Chris, we can make the "just added" method ->release conditional to UML only (better: to archs requesting it, i.e. only UML currently), so that other archs don't get this unneeded crud, and if UML won't need it any more we can kill this. Signed-off-by: Paolo 'Blaisorblade' Giarrusso CC: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/Kconfig | 5 +++++ include/linux/irq.h | 3 +++ kernel/irq/manage.c | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/arch/um/Kconfig b/arch/um/Kconfig index c5292181a664..b8e952c88fd1 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -35,6 +35,11 @@ config GENERIC_CALIBRATE_DELAY bool default y +# Used in kernel/irq/manage.c and include/linux/irq.h +config IRQ_RELEASE_METHOD + bool + default y + menu "UML-specific options" config MODE_TT diff --git a/include/linux/irq.h b/include/linux/irq.h index b68ad80e2464..7fc1022be9ee 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -47,7 +47,10 @@ struct hw_interrupt_type { void (*ack)(unsigned int irq); void (*end)(unsigned int irq); void (*set_affinity)(unsigned int irq, cpumask_t dest); + /* Currently used only by UML, might disappear one day.*/ +#ifdef CONFIG_IRQ_RELEASE_METHOD void (*release)(unsigned int irq, void *dev_id); +#endif }; typedef struct hw_interrupt_type hw_irq_controller; diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 5fde8177eedf..ac6700985705 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -6,6 +6,7 @@ * This file contains driver APIs to the irq subsystem. */ +#include #include #include #include @@ -256,8 +257,11 @@ void free_irq(unsigned int irq, void *dev_id) /* Found it - now remove it from the list of entries */ *pp = action->next; + /* Currently used only by UML, might disappear one day.*/ +#ifdef CONFIG_IRQ_RELEASE_METHOD if (desc->handler->release) desc->handler->release(irq, dev_id); +#endif if (!desc->action) { desc->status |= IRQ_DISABLED; -- cgit v1.2.3-59-g8ed1b From 60b2737de1b1ddfdb90f3ba622634eb49d6f3603 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Tue, 21 Jun 2005 17:16:25 -0700 Subject: [PATCH] uml: fix linkage of tt mode against NPTL With Al Viro To make sure switcheroo() can execute when we remap all the executable image, we used a trick to make it use a local copy of errno... this trick does not work with NPTL glibc, only with LinuxThreads, so use another (simpler) one to make it work anyway. Hopefully, a lot improved thanks to merging with the version of Al Viro (which had his part of problems, though, i.e. removing a fix to another bug and not fixing the problem on i386). Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/Makefile | 2 +- arch/um/kernel/tt/Makefile | 15 --------------- arch/um/kernel/tt/unmap.c | 31 ------------------------------- arch/um/kernel/uml.lds.S | 15 +++------------ arch/um/scripts/Makefile.rules | 6 ++++++ arch/um/scripts/Makefile.unmap | 22 ++++++++++++++++++++++ arch/um/sys-i386/Makefile | 2 ++ arch/um/sys-i386/unmap.c | 25 +++++++++++++++++++++++++ arch/um/sys-x86_64/Makefile | 2 ++ arch/um/sys-x86_64/unmap.c | 25 +++++++++++++++++++++++++ 10 files changed, 86 insertions(+), 59 deletions(-) delete mode 100644 arch/um/kernel/tt/unmap.c create mode 100644 arch/um/scripts/Makefile.unmap create mode 100644 arch/um/sys-i386/unmap.c create mode 100644 arch/um/sys-x86_64/unmap.c diff --git a/arch/um/Makefile b/arch/um/Makefile index f2a0c40a9204..3f073902351f 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -122,7 +122,7 @@ endif CPPFLAGS_vmlinux.lds = $(shell echo -U$(SUBARCH) \ -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \ -DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE-y) \ - -DKERNEL_STACK_SIZE=$(STACK_SIZE)) + -DKERNEL_STACK_SIZE=$(STACK_SIZE) -DSUBARCH=$(SUBARCH)) #The wrappers will select whether using "malloc" or the kernel allocator. LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc diff --git a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile index c3faea21a996..3fd2554e60b6 100644 --- a/arch/um/kernel/tt/Makefile +++ b/arch/um/kernel/tt/Makefile @@ -3,10 +3,6 @@ # Licensed under the GPL # -extra-y := unmap_fin.o -targets := unmap.o -clean-files := unmap_tmp.o - obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \ syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \ uaccess.o uaccess_user.o @@ -16,14 +12,3 @@ obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/ USER_OBJS := gdb.o time.o tracer.o include arch/um/scripts/Makefile.rules - -UNMAP_CFLAGS := $(patsubst -pg -DPROFILING,,$(USER_CFLAGS)) -UNMAP_CFLAGS := $(patsubst -fprofile-arcs -ftest-coverage,,$(UNMAP_CFLAGS)) - -#XXX: partially copied from arch/um/scripts/Makefile.rules -$(obj)/unmap.o: c_flags = -Wp,-MD,$(depfile) $(UNMAP_CFLAGS) - -$(obj)/unmap_fin.o : $(obj)/unmap.o - $(LD) -r -o $(obj)/unmap_tmp.o $< $(shell $(CC) -print-file-name=libc.a) - $(OBJCOPY) $(obj)/unmap_tmp.o $@ -G switcheroo - diff --git a/arch/um/kernel/tt/unmap.c b/arch/um/kernel/tt/unmap.c deleted file mode 100644 index 3f7aecdbe532..000000000000 --- a/arch/um/kernel/tt/unmap.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include - -int switcheroo(int fd, int prot, void *from, void *to, int size) -{ - if(munmap(to, size) < 0){ - return(-1); - } - if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){ - return(-1); - } - if(munmap(from, size) < 0){ - return(-1); - } - return(0); -} - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index dd5355500bdc..61dfd4fef752 100644 --- a/arch/um/kernel/uml.lds.S +++ b/arch/um/kernel/uml.lds.S @@ -14,19 +14,10 @@ SECTIONS /* Used in arch/um/kernel/mem.c. Any memory between START and __binary_start * is remapped.*/ __binary_start = .; -#ifdef MODE_TT - .thread_private : { - __start_thread_private = .; - errno = .; - . += 4; - arch/um/kernel/tt/unmap_fin.o (.data) - __end_thread_private = .; - } - . = ALIGN(4096); - .remap : { arch/um/kernel/tt/unmap_fin.o (.text) } - /* We want it only if we are in MODE_TT. In both cases, however, when MODE_TT - * is off the resulting binary segfaults.*/ +#ifdef MODE_TT + .remap_data : { arch/um/sys-SUBARCH/unmap_fin.o (.data .bss) } + .remap : { arch/um/sys-SUBARCH/unmap_fin.o (.text) } . = ALIGN(4096); /* Init code and data */ #endif diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index 98346c711493..7459d09c233e 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules @@ -10,6 +10,12 @@ USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) $(USER_OBJS) : c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) \ $(CFLAGS_$(notdir $@)) +# The stubs and unmap.o can't try to call mcount or update basic block data +define unprofile + $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1))) +endef + + quiet_cmd_make_link = SYMLINK $@ cmd_make_link = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@ diff --git a/arch/um/scripts/Makefile.unmap b/arch/um/scripts/Makefile.unmap new file mode 100644 index 000000000000..37a8f9765295 --- /dev/null +++ b/arch/um/scripts/Makefile.unmap @@ -0,0 +1,22 @@ +clean-files += unmap_tmp.o unmap_fin.o unmap.o + +ifdef CONFIG_MODE_TT + +#Always build unmap_fin.o +extra-y += unmap_fin.o +#Do dependency tracking for unmap.o (it will be always built, but won't get the tracking unless we use this). +targets += unmap.o + +#XXX: partially copied from arch/um/scripts/Makefile.rules +$(obj)/unmap.o: _c_flags = $(call unprofile,$(CFLAGS)) + +quiet_cmd_wrapld = LD $@ +define cmd_wrapld + $(LD) -r -o $(obj)/unmap_tmp.o $< $(shell $(CC) -print-file-name=libc.a); \ + $(OBJCOPY) $(obj)/unmap_tmp.o $@ -G switcheroo +endef + +$(obj)/unmap_fin.o : $(obj)/unmap.o FORCE + $(call if_changed,wrapld) + +endif diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index 4351e5605506..095bcdb0b9cc 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile @@ -17,3 +17,5 @@ highmem.c-dir = mm module.c-dir = kernel subdir- := util + +include arch/um/scripts/Makefile.unmap diff --git a/arch/um/sys-i386/unmap.c b/arch/um/sys-i386/unmap.c new file mode 100644 index 000000000000..136875263d27 --- /dev/null +++ b/arch/um/sys-i386/unmap.c @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#include +#include + +static int errno; + +static inline _syscall2(int,munmap,void *,start,size_t,len) +static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset) +int switcheroo(int fd, int prot, void *from, void *to, int size) +{ + if(munmap(to, size) < 0){ + return(-1); + } + if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){ + return(-1); + } + if(munmap(from, size) < 0){ + return(-1); + } + return(0); +} diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index 608466ad6b22..2bc6f6849010 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile @@ -29,3 +29,5 @@ thunk.S-dir = lib module.c-dir = kernel subdir- := util + +include arch/um/scripts/Makefile.unmap diff --git a/arch/um/sys-x86_64/unmap.c b/arch/um/sys-x86_64/unmap.c new file mode 100644 index 000000000000..bc7094cce47e --- /dev/null +++ b/arch/um/sys-x86_64/unmap.c @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#include +#include + +static int errno; + +static inline _syscall2(int,munmap,void *,start,size_t,len) +static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset) +int switcheroo(int fd, int prot, void *from, void *to, int size) +{ + if(munmap(to, size) < 0){ + return(-1); + } + if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){ + return(-1); + } + if(munmap(from, size) < 0){ + return(-1); + } + return(0); +} -- cgit v1.2.3-59-g8ed1b From 5bdfcfcc0780f58b927a164dfd54d1e1b6767347 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Tue, 21 Jun 2005 17:16:26 -0700 Subject: [PATCH] s390: cio max channels checks Fix max channel check in cio_ignore display function. Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/s390/cio/blacklist.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c index 4a06c7d0e5e4..aac83ce6469c 100644 --- a/drivers/s390/cio/blacklist.c +++ b/drivers/s390/cio/blacklist.c @@ -1,7 +1,7 @@ /* * drivers/s390/cio/blacklist.c * S/390 common I/O routines -- blacklisting of specific devices - * $Revision: 1.33 $ + * $Revision: 1.34 $ * * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, * IBM Corporation @@ -289,7 +289,7 @@ static int cio_ignore_read (char *page, char **start, off_t off, len = 0; for (devno = off; /* abuse the page variable * as counter, see fs/proc/generic.c */ - devno <= __MAX_SUBCHANNELS && len + entry_size < count; devno++) { + devno < __MAX_SUBCHANNELS && len + entry_size < count; devno++) { if (!test_bit(devno, bl_dev)) continue; len += sprintf(page + len, "0.0.%04lx", devno); @@ -302,7 +302,7 @@ static int cio_ignore_read (char *page, char **start, off_t off, len += sprintf(page + len, "\n"); } - if (devno <= __MAX_SUBCHANNELS) + if (devno < __MAX_SUBCHANNELS) *eof = 1; *start = (char *) (devno - off); /* number of checked entries */ return len; -- cgit v1.2.3-59-g8ed1b From 6fd6e4a44ff9ff406bcff69050b508f186507df1 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Tue, 21 Jun 2005 17:16:27 -0700 Subject: [PATCH] s390: cio documentation Some clarifications in the cio documentation. Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/s390/CommonIO | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Documentation/s390/CommonIO b/Documentation/s390/CommonIO index a831d9ae5a5e..59d1166d41ee 100644 --- a/Documentation/s390/CommonIO +++ b/Documentation/s390/CommonIO @@ -30,7 +30,7 @@ Command line parameters device numbers (0xabcd or abcd, for 2.4 backward compatibility). You can use the 'all' keyword to ignore all devices. The '!' operator will cause the I/O-layer to _not_ ignore a device. - The order on the command line is not important. + The command line is parsed from left to right. For example, cio_ignore=0.0.0023-0.0.0042,0.0.4711 @@ -72,13 +72,14 @@ Command line parameters /proc/cio_ignore; "add , , ..." will ignore the specified devices. - Note: Already known devices cannot be ignored. + Note: While already known devices can be added to the list of devices to be + ignored, there will be no effect on then. However, if such a device + disappears and then reappeares, it will then be ignored. - For example, if device 0.0.abcd is already known and all other devices - 0.0.a000-0.0.afff are not known, + For example, "echo add 0.0.a000-0.0.accc, 0.0.af00-0.0.afff > /proc/cio_ignore" - will add 0.0.a000-0.0.abcc, 0.0.abce-0.0.accc and 0.0.af00-0.0.afff to the - list of ignored devices and skip 0.0.abcd. + will add 0.0.a000-0.0.accc and 0.0.af00-0.0.afff to the list of ignored + devices. The devices can be specified either by bus id (0.0.abcd) or, for 2.4 backward compatibilty, by the device number in hexadecimal (0xabcd or abcd). @@ -98,7 +99,8 @@ Command line parameters - /proc/s390dbf/cio_trace/hex_ascii Logs the calling of functions in the common I/O-layer and, if applicable, - which subchannel they were called for. + which subchannel they were called for, as well as dumps of some data + structures (like irb in an error case). The level of logging can be changed to be more or less verbose by piping to /proc/s390dbf/cio_*/level a number between 0 and 6; see the documentation on -- cgit v1.2.3-59-g8ed1b From 14651c798a2a4d15ccc53d064df28bfd0283bad6 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Tue, 21 Jun 2005 17:16:28 -0700 Subject: [PATCH] s390: #ifdefs in compat_ioctls Remove superflous #if .. #endif pairs from compat_ioctl.c. Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/s390/kernel/compat_ioctl.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/arch/s390/kernel/compat_ioctl.c b/arch/s390/kernel/compat_ioctl.c index 03d03c6d3cbb..24a1e9f069a7 100644 --- a/arch/s390/kernel/compat_ioctl.c +++ b/arch/s390/kernel/compat_ioctl.c @@ -42,7 +42,6 @@ struct ioctl_trans ioctl_start[] = { #include "../../../fs/compat_ioctl.c" /* s390 only ioctls */ -#if defined(CONFIG_DASD) || defined(CONFIG_DASD_MODULE) COMPATIBLE_IOCTL(DASDAPIVER) COMPATIBLE_IOCTL(BIODASDDISABLE) COMPATIBLE_IOCTL(BIODASDENABLE) @@ -59,16 +58,11 @@ COMPATIBLE_IOCTL(BIODASDPRRD) COMPATIBLE_IOCTL(BIODASDPSRD) COMPATIBLE_IOCTL(BIODASDGATTR) COMPATIBLE_IOCTL(BIODASDSATTR) -#if defined(CONFIG_DASD_CMB) || defined(CONFIG_DASD_CMB_MODULE) COMPATIBLE_IOCTL(BIODASDCMFENABLE) COMPATIBLE_IOCTL(BIODASDCMFDISABLE) COMPATIBLE_IOCTL(BIODASDREADALLCMB) -#endif -#endif -#if defined(CONFIG_S390_TAPE) || defined(CONFIG_S390_TAPE_MODULE) COMPATIBLE_IOCTL(TAPE390_DISPLAY) -#endif /* s390 doesn't need handlers here */ COMPATIBLE_IOCTL(TIOCGSERIAL) -- cgit v1.2.3-59-g8ed1b From 77eb65cbc18d86a9c334964ed4c3d178f5560918 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 21 Jun 2005 17:16:28 -0700 Subject: [PATCH] s390: kernel stack overflow panic die() doesn't return, therefore print registers and then panic instead. Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/s390/kernel/traps.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 8b90e9528b91..ca34b6f34b38 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -668,7 +668,10 @@ asmlinkage void space_switch_exception(struct pt_regs * regs, long int_code) asmlinkage void kernel_stack_overflow(struct pt_regs * regs) { - die("Kernel stack overflow", regs, 0); + bust_spinlocks(1); + printk("Kernel stack overflow.\n"); + show_regs(regs); + bust_spinlocks(0); panic("Corrupt kernel stack, can't continue."); } -- cgit v1.2.3-59-g8ed1b From 447570cfde680d5bf09c47b9c8d1dcf5bcb18f10 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 21 Jun 2005 17:16:29 -0700 Subject: [PATCH] s390: cmm sender parameter visibility Make cmm module parameter "sender" visible in sysfs. Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/s390/mm/cmm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c index f5a5bc09b8fa..2d5cb1385753 100644 --- a/arch/s390/mm/cmm.c +++ b/arch/s390/mm/cmm.c @@ -21,7 +21,7 @@ #include static char *sender = "VMRMSVM"; -module_param(sender, charp, 0); +module_param(sender, charp, 0400); MODULE_PARM_DESC(sender, "Guest name that may send SMSG messages (default VMRMSVM)"); -- cgit v1.2.3-59-g8ed1b From e9b9a04796eade5241452a913ec6f3433437b4f5 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 21 Jun 2005 17:16:30 -0700 Subject: [PATCH] s390: memory detection > 32GB The kernel takes a very long time to boot if the memory size is bigger then 32767 MB. The memory size is contained in a structure created by an sclp call. The kernel accesses the field with a LH instrution which performs a sign extension of a 16 bit word. In the case of a memory size with bit 2^15 set this results in a very large value and the memory detection just loops for a long time. In addition if more then 64 GB are used on a 64 bit system the memory size is read from an incorrect storage location. Use zero-extention to read the 16 bit memory size and the correct offset to read the 4 byte memory size on 64 bit. Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/s390/kernel/head.S | 8 ++++---- arch/s390/kernel/head64.S | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index b804c55bd919..658e8de74f88 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S @@ -517,10 +517,10 @@ startup:basr %r13,0 # get base l %r2, .Lrcp2-.LPG1(%r13) # try with Read SCP b .Lservicecall-.LPG1(%r13) .Lprocsccb: - lh %r1,.Lscpincr1-PARMAREA(%r4) # use this one if != 0 - chi %r1,0x00 - jne .Lscnd - l %r1,.Lscpincr2-PARMAREA(%r4) # otherwise use this one + lhi %r1,0 + icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0 + jnz .Lscnd + l %r1,.Lscpincr2-PARMAREA+4(%r4) # otherwise use this one .Lscnd: xr %r3,%r3 # same logic ic %r3,.Lscpa1-PARMAREA(%r4) diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 8366793bc371..8e2caf9dc185 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S @@ -518,9 +518,9 @@ startup:basr %r13,0 # get base l %r2,.Lrcp2-.LPG1(%r13) # try with Read SCP b .Lservicecall-.LPG1(%r13) .Lprocsccb: - lh %r1,.Lscpincr1-PARMAREA(%r4) # use this one if != 0 - chi %r1,0x00 - jne .Lscnd + lghi %r1,0 + icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0 + jnz .Lscnd lg %r1,.Lscpincr2-PARMAREA(%r4) # otherwise use this one .Lscnd: xr %r3,%r3 # same logic -- cgit v1.2.3-59-g8ed1b From 2b071886170df456e230c38a3e504da4a11fff79 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 21 Jun 2005 17:16:31 -0700 Subject: [PATCH] s390: pending interrupt after ipl from reader Wait for interrupt and clear status pending after resetting the reader. Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/s390/kernel/head.S | 19 +++++++++++++++++-- arch/s390/kernel/head64.S | 19 +++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index 658e8de74f88..fc8bf5e285f6 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S @@ -345,10 +345,25 @@ iplstart: bno .Lnoreset la %r2,.Lreset lhi %r3,26 - .long 0x83230008 + diag %r2,%r3,8 + mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw +.Lwaitrdrirq: + lpsw .Lrdrwaitpsw +.Lrdrint: + c %r1,0xb8 # compare subchannel number + bne .Lwaitrdrirq + la %r5,.Lirb + tsch 0(%r5) .Lnoreset: + b .Lnoload + + .align 8 +.Lrdrnewpsw: + .long 0x00080000,0x80000000+.Lrdrint +.Lrdrwaitpsw: + .long 0x020a0000,0x80000000+.Lrdrint #endif - + # # everything loaded, go for it # diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 8e2caf9dc185..f525c0c21250 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S @@ -344,10 +344,25 @@ iplstart: bno .Lnoreset la %r2,.Lreset lhi %r3,26 - .long 0x83230008 + diag %r2,%r3,8 + mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw +.Lwaitrdrirq: + lpsw .Lrdrwaitpsw +.Lrdrint: + c %r1,0xb8 # compare subchannel number + bne .Lwaitrdrirq + la %r5,.Lirb + tsch 0(%r5) .Lnoreset: + b .Lnoload + + .align 8 +.Lrdrnewpsw: + .long 0x00080000,0x80000000+.Lrdrint +.Lrdrwaitpsw: + .long 0x020a0000,0x80000000+.Lrdrint #endif - + # # everything loaded, go for it # -- cgit v1.2.3-59-g8ed1b From f5ccc842318efcd7c05dee3203dfdbbafae47bd6 Mon Sep 17 00:00:00 2001 From: Max Asbock Date: Tue, 21 Jun 2005 17:16:32 -0700 Subject: [PATCH] ibmasm driver: fix command buffer size First of a series of patches for the ibmasm driver. (that is the driver for the IBM xSeries RSA service processor) To summarize what they do: [1] change a #define for the buffer size for commands [2] Fix a bug where threads in the event handling code calling wait_event_interruptible() weren't woken up as expected. [3] Redesigned how remote mouse and keyboard events received by the driver are handled. [4] Fixed a race in the command reference counting logic. This patch: - change a #define for the buffer size for commands Signed-off-by: Max Asbock Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/ibmasm/ibmasm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/ibmasm/ibmasm.h b/drivers/misc/ibmasm/ibmasm.h index 6fec7fd8cd1a..1e83406382e7 100644 --- a/drivers/misc/ibmasm/ibmasm.h +++ b/drivers/misc/ibmasm/ibmasm.h @@ -52,7 +52,7 @@ #define IBMASM_CMD_TIMEOUT_NORMAL 45 #define IBMASM_CMD_TIMEOUT_EXTRA 240 -#define IBMASM_CMD_MAX_BUFFER_SIZE 0x4000 +#define IBMASM_CMD_MAX_BUFFER_SIZE 0x8000 #define REVERSE_HEARTBEAT_TIMEOUT 120 -- cgit v1.2.3-59-g8ed1b From b8acb808468a88a188d7c5aba3681c583a5785f9 Mon Sep 17 00:00:00 2001 From: Max Asbock Date: Tue, 21 Jun 2005 17:16:33 -0700 Subject: [PATCH] ibmasm driver: correctly wake up sleeping threads Due to my incomplete understanding of the wait_event_interruptible() function threads waiting for service processor events were not woken up. This patch fixes that problem. Signed-off-by: Max Asbock Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/ibmasm/event.c | 18 ++++++++++++------ drivers/misc/ibmasm/ibmasm.h | 2 ++ drivers/misc/ibmasm/ibmasmfs.c | 34 ++++++++++++++++++++++++++-------- 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/drivers/misc/ibmasm/event.c b/drivers/misc/ibmasm/event.c index e100f34f1587..fe1e819235a4 100644 --- a/drivers/misc/ibmasm/event.c +++ b/drivers/misc/ibmasm/event.c @@ -23,6 +23,7 @@ */ #include "ibmasm.h" +#include "lowlevel.h" /* * ASM service processor event handling routines. @@ -34,7 +35,6 @@ * circular buffer. */ - static void wake_up_event_readers(struct service_processor *sp) { struct event_reader *reader; @@ -63,7 +63,7 @@ void ibmasm_receive_event(struct service_processor *sp, void *data, unsigned int spin_lock_irqsave(&sp->lock, flags); /* copy the event into the next slot in the circular buffer */ event = &buffer->events[buffer->next_index]; - memcpy(event->data, data, data_size); + memcpy_fromio(event->data, data, data_size); event->data_size = data_size; event->serial_number = buffer->next_serial_number; @@ -93,7 +93,10 @@ int ibmasm_get_next_event(struct service_processor *sp, struct event_reader *rea unsigned int index; unsigned long flags; - if (wait_event_interruptible(reader->wait, event_available(buffer, reader))) + reader->cancelled = 0; + + if (wait_event_interruptible(reader->wait, + event_available(buffer, reader) || reader->cancelled)) return -ERESTARTSYS; if (!event_available(buffer, reader)) @@ -116,6 +119,12 @@ int ibmasm_get_next_event(struct service_processor *sp, struct event_reader *rea return event->data_size; } +void ibmasm_cancel_next_event(struct event_reader *reader) +{ + reader->cancelled = 1; + wake_up_interruptible(&reader->wait); +} + void ibmasm_event_reader_register(struct service_processor *sp, struct event_reader *reader) { unsigned long flags; @@ -131,8 +140,6 @@ void ibmasm_event_reader_unregister(struct service_processor *sp, struct event_r { unsigned long flags; - wake_up_interruptible(&reader->wait); - spin_lock_irqsave(&sp->lock, flags); list_del(&reader->node); spin_unlock_irqrestore(&sp->lock, flags); @@ -164,6 +171,5 @@ int ibmasm_event_buffer_init(struct service_processor *sp) void ibmasm_event_buffer_exit(struct service_processor *sp) { - wake_up_event_readers(sp); kfree(sp->event_buffer); } diff --git a/drivers/misc/ibmasm/ibmasm.h b/drivers/misc/ibmasm/ibmasm.h index 1e83406382e7..35c4def5af18 100644 --- a/drivers/misc/ibmasm/ibmasm.h +++ b/drivers/misc/ibmasm/ibmasm.h @@ -108,6 +108,7 @@ struct event_buffer { }; struct event_reader { + int cancelled; unsigned int next_serial_number; wait_queue_head_t wait; struct list_head node; @@ -185,6 +186,7 @@ extern void ibmasm_receive_event(struct service_processor *sp, void *data, unsi extern void ibmasm_event_reader_register(struct service_processor *sp, struct event_reader *reader); extern void ibmasm_event_reader_unregister(struct service_processor *sp, struct event_reader *reader); extern int ibmasm_get_next_event(struct service_processor *sp, struct event_reader *reader); +extern void ibmasm_cancel_next_event(struct event_reader *reader); /* heartbeat - from SP to OS */ extern void ibmasm_register_panic_notifier(void); diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c index 866e867e68f2..c87ef7d82b70 100644 --- a/drivers/misc/ibmasm/ibmasmfs.c +++ b/drivers/misc/ibmasm/ibmasmfs.c @@ -374,6 +374,7 @@ static int event_file_open(struct inode *inode, struct file *file) ibmasm_event_reader_register(sp, &event_data->reader); event_data->sp = sp; + event_data->active = 0; file->private_data = event_data; return 0; } @@ -391,7 +392,9 @@ static ssize_t event_file_read(struct file *file, char __user *buf, size_t count { struct ibmasmfs_event_data *event_data = file->private_data; struct event_reader *reader = &event_data->reader; + struct service_processor *sp = event_data->sp; int ret; + unsigned long flags; if (*offset < 0) return -EINVAL; @@ -400,17 +403,32 @@ static ssize_t event_file_read(struct file *file, char __user *buf, size_t count if (*offset != 0) return 0; - ret = ibmasm_get_next_event(event_data->sp, reader); + spin_lock_irqsave(&sp->lock, flags); + if (event_data->active) { + spin_unlock_irqrestore(&sp->lock, flags); + return -EBUSY; + } + event_data->active = 1; + spin_unlock_irqrestore(&sp->lock, flags); + + ret = ibmasm_get_next_event(sp, reader); if (ret <= 0) - return ret; + goto out; - if (count < reader->data_size) - return -EINVAL; + if (count < reader->data_size) { + ret = -EINVAL; + goto out; + } - if (copy_to_user(buf, reader->data, reader->data_size)) - return -EFAULT; + if (copy_to_user(buf, reader->data, reader->data_size)) { + ret = -EFAULT; + goto out; + } + ret = reader->data_size; - return reader->data_size; +out: + event_data->active = 0; + return ret; } static ssize_t event_file_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) @@ -424,7 +442,7 @@ static ssize_t event_file_write(struct file *file, const char __user *buf, size_ if (*offset != 0) return 0; - wake_up_interruptible(&event_data->reader.wait); + ibmasm_cancel_next_event(&event_data->reader); return 0; } -- cgit v1.2.3-59-g8ed1b From 278d72ae8803ffcd16070c95fe1d53f4466dc741 Mon Sep 17 00:00:00 2001 From: Max Asbock Date: Tue, 21 Jun 2005 17:16:34 -0700 Subject: [PATCH] ibmasm driver: redesign handling of remote control events This patch rewrites the handling of remote control events. Rather than making them available from a special file in the ibmasmfs, now the events from the RSA card get translated into kernel input events and injected into the input subsystem. The driver now will generate two /dev/input/eventX nodes -- one for the keyboard and one for the mouse. The mouse node generates absolute events more like a touch pad than a mouse. Signed-off-by: Vernon Mauery Signed-off-by: Max Asbock Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/ibmasm/ibmasm.h | 65 ++++----- drivers/misc/ibmasm/ibmasmfs.c | 89 ------------ drivers/misc/ibmasm/lowlevel.c | 18 ++- drivers/misc/ibmasm/module.c | 69 ++++++---- drivers/misc/ibmasm/remote.c | 304 ++++++++++++++++++++++++++++------------- drivers/misc/ibmasm/remote.h | 173 +++++++++++++++++++++-- 6 files changed, 449 insertions(+), 269 deletions(-) diff --git a/drivers/misc/ibmasm/ibmasm.h b/drivers/misc/ibmasm/ibmasm.h index 35c4def5af18..653a7d096a8b 100644 --- a/drivers/misc/ibmasm/ibmasm.h +++ b/drivers/misc/ibmasm/ibmasm.h @@ -34,16 +34,31 @@ #include #include #include +#include /* Driver identification */ #define DRIVER_NAME "ibmasm" -#define DRIVER_VERSION "0.4" -#define DRIVER_AUTHOR "Max Asbock" +#define DRIVER_VERSION "1.0" +#define DRIVER_AUTHOR "Max Asbock , Vernon Mauery " #define DRIVER_DESC "IBM ASM Service Processor Driver" #define err(msg) printk(KERN_ERR "%s: " msg "\n", DRIVER_NAME) #define info(msg) printk(KERN_INFO "%s: " msg "\n", DRIVER_NAME) +extern int ibmasm_debug; +#define dbg(STR, ARGS...) \ + do { \ + if (ibmasm_debug) \ + printk(KERN_DEBUG STR , ##ARGS); \ + } while (0) + +static inline char *get_timestamp(char *buf) +{ + struct timeval now; + do_gettimeofday(&now); + sprintf(buf, "%lu.%lu", now.tv_sec, now.tv_usec); + return buf; +} #define IBMASM_CMD_PENDING 0 #define IBMASM_CMD_COMPLETE 1 @@ -121,41 +136,11 @@ struct reverse_heartbeat { unsigned int stopped; }; - -/* remote console events */ -struct mouse_event { - long x; - long y; - unsigned char buttons; - unsigned char transitions; +struct ibmasm_remote { + struct input_dev keybd_dev; + struct input_dev mouse_dev; }; -struct keyboard_event { - unsigned long key_code; - unsigned char key_down; -}; - -struct remote_event { - unsigned long type; - union { - struct mouse_event mouse; - struct keyboard_event keyboard; - } data; -}; - -#define DRIVER_REMOTE_QUEUE_SIZE 240 - -struct remote_queue { - struct remote_event *start; - struct remote_event *end; - struct remote_event *reader; - struct remote_event *writer; - unsigned int size; - int open; - wait_queue_head_t wait; -}; - - struct service_processor { struct list_head node; spinlock_t lock; @@ -168,7 +153,7 @@ struct service_processor { char dirname[IBMASM_NAME_SIZE]; char devname[IBMASM_NAME_SIZE]; unsigned int number; - struct remote_queue remote_queue; + struct ibmasm_remote *remote; int serial_line; struct device *dev; }; @@ -210,11 +195,9 @@ extern int ibmasm_send_i2o_message(struct service_processor *sp); extern irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id, struct pt_regs *regs); /* remote console */ -extern void ibmasm_handle_mouse_interrupt(struct service_processor *sp); -extern int ibmasm_init_remote_queue(struct service_processor *sp); -extern void ibmasm_free_remote_queue(struct service_processor *sp); -extern void ibmasm_advance_reader(struct remote_queue *q, unsigned int n); -extern size_t ibmasm_events_available(struct remote_queue *q); +extern void ibmasm_handle_mouse_interrupt(struct service_processor *sp, struct pt_regs *regs); +extern int ibmasm_init_remote_input_dev(struct service_processor *sp); +extern void ibmasm_free_remote_input_dev(struct service_processor *sp); /* file system */ extern int ibmasmfs_register(void); diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c index c87ef7d82b70..ca839162e4f7 100644 --- a/drivers/misc/ibmasm/ibmasmfs.c +++ b/drivers/misc/ibmasm/ibmasmfs.c @@ -37,9 +37,7 @@ * | |-- event * | |-- reverse_heartbeat * | `-- remote_video - * | |-- connected * | |-- depth - * | |-- events * | |-- height * | `-- width * . @@ -50,9 +48,7 @@ * |-- event * |-- reverse_heartbeat * `-- remote_video - * |-- connected * |-- depth - * |-- events * |-- height * `-- width * @@ -75,14 +71,6 @@ * remote_video/width: control remote display settings * write: set value * read: read value - * - * remote_video/connected - * read: return "1" if web browser VNC java applet is connected, - * "0" otherwise - * - * remote_video/events - * read: sleep until a remote mouse or keyboard event occurs, then return - * then event. */ #include @@ -593,75 +581,6 @@ static ssize_t remote_settings_file_write(struct file *file, const char __user * return count; } -static int remote_event_file_open(struct inode *inode, struct file *file) -{ - struct service_processor *sp; - unsigned long flags; - struct remote_queue *q; - - file->private_data = inode->u.generic_ip; - sp = file->private_data; - q = &sp->remote_queue; - - /* allow only one event reader */ - spin_lock_irqsave(&sp->lock, flags); - if (q->open) { - spin_unlock_irqrestore(&sp->lock, flags); - return -EBUSY; - } - q->open = 1; - spin_unlock_irqrestore(&sp->lock, flags); - - enable_mouse_interrupts(sp); - - return 0; -} - -static int remote_event_file_close(struct inode *inode, struct file *file) -{ - struct service_processor *sp = file->private_data; - - disable_mouse_interrupts(sp); - wake_up_interruptible(&sp->remote_queue.wait); - sp->remote_queue.open = 0; - - return 0; -} - -static ssize_t remote_event_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset) -{ - struct service_processor *sp = file->private_data; - struct remote_queue *q = &sp->remote_queue; - size_t data_size; - struct remote_event *reader = q->reader; - size_t num_events; - - if (*offset < 0) - return -EINVAL; - if (count == 0 || count > 1024) - return 0; - if (*offset != 0) - return 0; - - if (wait_event_interruptible(q->wait, q->reader != q->writer)) - return -ERESTARTSYS; - - /* only get multiples of struct remote_event */ - num_events = min((count/sizeof(struct remote_event)), ibmasm_events_available(q)); - if (!num_events) - return 0; - - data_size = num_events * sizeof(struct remote_event); - - if (copy_to_user(buf, reader, data_size)) - return -EFAULT; - - ibmasm_advance_reader(q, num_events); - - return data_size; -} - - static struct file_operations command_fops = { .open = command_file_open, .release = command_file_close, @@ -690,12 +609,6 @@ static struct file_operations remote_settings_fops = { .write = remote_settings_file_write, }; -static struct file_operations remote_event_fops = { - .open = remote_event_file_open, - .release = remote_event_file_close, - .read = remote_event_file_read, -}; - static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root) { @@ -721,7 +634,5 @@ static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root) ibmasmfs_create_file(sb, remote_dir, "width", &remote_settings_fops, (void *)display_width(sp), S_IRUSR|S_IWUSR); ibmasmfs_create_file(sb, remote_dir, "height", &remote_settings_fops, (void *)display_height(sp), S_IRUSR|S_IWUSR); ibmasmfs_create_file(sb, remote_dir, "depth", &remote_settings_fops, (void *)display_depth(sp), S_IRUSR|S_IWUSR); - ibmasmfs_create_file(sb, remote_dir, "connected", &remote_settings_fops, (void *)vnc_status(sp), S_IRUSR); - ibmasmfs_create_file(sb, remote_dir, "events", &remote_event_fops, (void *)sp, S_IRUSR); } } diff --git a/drivers/misc/ibmasm/lowlevel.c b/drivers/misc/ibmasm/lowlevel.c index 5156de2759d8..47949a2c7e94 100644 --- a/drivers/misc/ibmasm/lowlevel.c +++ b/drivers/misc/ibmasm/lowlevel.c @@ -46,8 +46,8 @@ int ibmasm_send_i2o_message(struct service_processor *sp) message = get_i2o_message(sp->base_address, mfa); - memcpy(&message->header, &header, sizeof(struct i2o_header)); - memcpy(&message->data, command->buffer, command_size); + memcpy_toio(&message->header, &header, sizeof(struct i2o_header)); + memcpy_toio(&message->data, command->buffer, command_size); set_mfa_inbound(sp->base_address, mfa); @@ -59,23 +59,27 @@ irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id, struct pt_regs *reg u32 mfa; struct service_processor *sp = (struct service_processor *)dev_id; void __iomem *base_address = sp->base_address; + char tsbuf[32]; if (!sp_interrupt_pending(base_address)) return IRQ_NONE; + dbg("respond to interrupt at %s\n", get_timestamp(tsbuf)); + if (mouse_interrupt_pending(sp)) { - ibmasm_handle_mouse_interrupt(sp); - mfa = get_mfa_outbound(base_address); + ibmasm_handle_mouse_interrupt(sp, regs); clear_mouse_interrupt(sp); - set_mfa_outbound(base_address, mfa); - return IRQ_HANDLED; } mfa = get_mfa_outbound(base_address); if (valid_mfa(mfa)) { struct i2o_message *msg = get_i2o_message(base_address, mfa); ibmasm_receive_message(sp, &msg->data, incoming_data_size(msg)); - } + } else + dbg("didn't get a valid MFA\n"); + set_mfa_outbound(base_address, mfa); + dbg("finished interrupt at %s\n", get_timestamp(tsbuf)); + return IRQ_HANDLED; } diff --git a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c index 777432ae764a..1fdf03fd2da7 100644 --- a/drivers/misc/ibmasm/module.c +++ b/drivers/misc/ibmasm/module.c @@ -56,17 +56,26 @@ #include "lowlevel.h" #include "remote.h" +int ibmasm_debug = 0; +module_param(ibmasm_debug, int , S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(ibmasm_debug, " Set debug mode on or off"); + static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { - int err, result = -ENOMEM; + int result; struct service_processor *sp; - if ((err = pci_enable_device(pdev))) { - printk(KERN_ERR "%s: can't enable PCI device at %s\n", - DRIVER_NAME, pci_name(pdev)); - return err; + if ((result = pci_enable_device(pdev))) { + dev_err(&pdev->dev, "Failed to enable PCI device\n"); + return result; } + if ((result = pci_request_regions(pdev, DRIVER_NAME))) { + dev_err(&pdev->dev, "Failed to allocate PCI resources\n"); + goto error_resources; + } + /* vnc client won't work without bus-mastering */ + pci_set_master(pdev); sp = kmalloc(sizeof(struct service_processor), GFP_KERNEL); if (sp == NULL) { @@ -76,6 +85,9 @@ static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_devi } memset(sp, 0, sizeof(struct service_processor)); + sp->lock = SPIN_LOCK_UNLOCKED; + INIT_LIST_HEAD(&sp->command_queue); + pci_set_drvdata(pdev, (void *)sp); sp->dev = &pdev->dev; sp->number = pdev->bus->number; @@ -101,15 +113,6 @@ static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_devi goto error_ioremap; } - result = ibmasm_init_remote_queue(sp); - if (result) { - dev_err(sp->dev, "Failed to initialize remote queue\n"); - goto error_remote_queue; - } - - spin_lock_init(&sp->lock); - INIT_LIST_HEAD(&sp->command_queue); - result = request_irq(sp->irq, ibmasm_interrupt_handler, SA_SHIRQ, sp->devname, (void*)sp); if (result) { dev_err(sp->dev, "Failed to register interrupt handler\n"); @@ -117,7 +120,12 @@ static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_devi } enable_sp_interrupts(sp->base_address); - disable_mouse_interrupts(sp); + + result = ibmasm_init_remote_input_dev(sp); + if (result) { + dev_err(sp->dev, "Failed to initialize remote queue\n"); + goto error_send_message; + } result = ibmasm_send_driver_vpd(sp); if (result) { @@ -133,30 +141,25 @@ static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_devi ibmasm_register_uart(sp); - dev_printk(KERN_DEBUG, &pdev->dev, "WARNING: This software may not be supported or function\n"); - dev_printk(KERN_DEBUG, &pdev->dev, "correctly on your IBM server. Please consult the IBM\n"); - dev_printk(KERN_DEBUG, &pdev->dev, "ServerProven website\n"); - dev_printk(KERN_DEBUG, &pdev->dev, "http://www.pc.ibm.com/ww/eserver/xseries/serverproven\n"); - dev_printk(KERN_DEBUG, &pdev->dev, "for information on the specific driver level and support\n"); - dev_printk(KERN_DEBUG, &pdev->dev, "statement for your IBM server.\n"); - return 0; error_send_message: disable_sp_interrupts(sp->base_address); + ibmasm_free_remote_input_dev(sp); free_irq(sp->irq, (void *)sp); error_request_irq: - ibmasm_free_remote_queue(sp); -error_remote_queue: iounmap(sp->base_address); error_ioremap: ibmasm_heartbeat_exit(sp); error_heartbeat: ibmasm_event_buffer_exit(sp); error_eventbuffer: + pci_set_drvdata(pdev, NULL); kfree(sp); error_kmalloc: - pci_disable_device(pdev); + pci_release_regions(pdev); +error_resources: + pci_disable_device(pdev); return result; } @@ -165,16 +168,24 @@ static void __devexit ibmasm_remove_one(struct pci_dev *pdev) { struct service_processor *sp = (struct service_processor *)pci_get_drvdata(pdev); + dbg("Unregistering UART\n"); ibmasm_unregister_uart(sp); - ibmasm_send_os_state(sp, SYSTEM_STATE_OS_DOWN); + dbg("Sending OS down message\n"); + if (ibmasm_send_os_state(sp, SYSTEM_STATE_OS_DOWN)) + err("failed to get repsonse to 'Send OS State' command\n"); + dbg("Disabling heartbeats\n"); + ibmasm_heartbeat_exit(sp); + dbg("Disabling interrupts\n"); disable_sp_interrupts(sp->base_address); - disable_mouse_interrupts(sp); + dbg("Freeing SP irq\n"); free_irq(sp->irq, (void *)sp); - ibmasm_heartbeat_exit(sp); - ibmasm_free_remote_queue(sp); + dbg("Cleaning up\n"); + ibmasm_free_remote_input_dev(sp); iounmap(sp->base_address); ibmasm_event_buffer_exit(sp); + pci_set_drvdata(pdev, NULL); kfree(sp); + pci_release_regions(pdev); pci_disable_device(pdev); } diff --git a/drivers/misc/ibmasm/remote.c b/drivers/misc/ibmasm/remote.c index 520c3f10c271..d3c48d23ee51 100644 --- a/drivers/misc/ibmasm/remote.c +++ b/drivers/misc/ibmasm/remote.c @@ -1,4 +1,3 @@ - /* * IBM ASM Service Processor Device Driver * @@ -18,135 +17,256 @@ * * Copyright (C) IBM Corporation, 2004 * - * Author: Max Asböck + * Authors: Max Asböck + * Vernon Mauery * */ /* Remote mouse and keyboard event handling functions */ +#include #include "ibmasm.h" #include "remote.h" -int ibmasm_init_remote_queue(struct service_processor *sp) -{ - struct remote_queue *q = &sp->remote_queue; - - disable_mouse_interrupts(sp); +static int xmax = 1600; +static int ymax = 1200; - q->open = 0; - q->size = 0; - q->start = kmalloc(DRIVER_REMOTE_QUEUE_SIZE * sizeof(struct remote_event), GFP_KERNEL); - if (q->start == 0) - return -ENOMEM; +static unsigned short xlate_high[XLATE_SIZE] = { + [KEY_SYM_ENTER & 0xff] = KEY_ENTER, + [KEY_SYM_KPSLASH & 0xff] = KEY_KPSLASH, + [KEY_SYM_KPSTAR & 0xff] = KEY_KPASTERISK, + [KEY_SYM_KPMINUS & 0xff] = KEY_KPMINUS, + [KEY_SYM_KPDOT & 0xff] = KEY_KPDOT, + [KEY_SYM_KPPLUS & 0xff] = KEY_KPPLUS, + [KEY_SYM_KP0 & 0xff] = KEY_KP0, + [KEY_SYM_KP1 & 0xff] = KEY_KP1, + [KEY_SYM_KP2 & 0xff] = KEY_KP2, [KEY_SYM_KPDOWN & 0xff] = KEY_KP2, + [KEY_SYM_KP3 & 0xff] = KEY_KP3, + [KEY_SYM_KP4 & 0xff] = KEY_KP4, [KEY_SYM_KPLEFT & 0xff] = KEY_KP4, + [KEY_SYM_KP5 & 0xff] = KEY_KP5, + [KEY_SYM_KP6 & 0xff] = KEY_KP6, [KEY_SYM_KPRIGHT & 0xff] = KEY_KP6, + [KEY_SYM_KP7 & 0xff] = KEY_KP7, + [KEY_SYM_KP8 & 0xff] = KEY_KP8, [KEY_SYM_KPUP & 0xff] = KEY_KP8, + [KEY_SYM_KP9 & 0xff] = KEY_KP9, + [KEY_SYM_BK_SPC & 0xff] = KEY_BACKSPACE, + [KEY_SYM_TAB & 0xff] = KEY_TAB, + [KEY_SYM_CTRL & 0xff] = KEY_LEFTCTRL, + [KEY_SYM_ALT & 0xff] = KEY_LEFTALT, + [KEY_SYM_INSERT & 0xff] = KEY_INSERT, + [KEY_SYM_DELETE & 0xff] = KEY_DELETE, + [KEY_SYM_SHIFT & 0xff] = KEY_LEFTSHIFT, + [KEY_SYM_UARROW & 0xff] = KEY_UP, + [KEY_SYM_DARROW & 0xff] = KEY_DOWN, + [KEY_SYM_LARROW & 0xff] = KEY_LEFT, + [KEY_SYM_RARROW & 0xff] = KEY_RIGHT, + [KEY_SYM_ESCAPE & 0xff] = KEY_ESC, + [KEY_SYM_PAGEUP & 0xff] = KEY_PAGEUP, + [KEY_SYM_PAGEDOWN & 0xff] = KEY_PAGEDOWN, + [KEY_SYM_HOME & 0xff] = KEY_HOME, + [KEY_SYM_END & 0xff] = KEY_END, + [KEY_SYM_F1 & 0xff] = KEY_F1, + [KEY_SYM_F2 & 0xff] = KEY_F2, + [KEY_SYM_F3 & 0xff] = KEY_F3, + [KEY_SYM_F4 & 0xff] = KEY_F4, + [KEY_SYM_F5 & 0xff] = KEY_F5, + [KEY_SYM_F6 & 0xff] = KEY_F6, + [KEY_SYM_F7 & 0xff] = KEY_F7, + [KEY_SYM_F8 & 0xff] = KEY_F8, + [KEY_SYM_F9 & 0xff] = KEY_F9, + [KEY_SYM_F10 & 0xff] = KEY_F10, + [KEY_SYM_F11 & 0xff] = KEY_F11, + [KEY_SYM_F12 & 0xff] = KEY_F12, + [KEY_SYM_CAP_LOCK & 0xff] = KEY_CAPSLOCK, + [KEY_SYM_NUM_LOCK & 0xff] = KEY_NUMLOCK, + [KEY_SYM_SCR_LOCK & 0xff] = KEY_SCROLLLOCK, +}; +static unsigned short xlate[XLATE_SIZE] = { + [NO_KEYCODE] = KEY_RESERVED, + [KEY_SYM_SPACE] = KEY_SPACE, + [KEY_SYM_TILDE] = KEY_GRAVE, [KEY_SYM_BKTIC] = KEY_GRAVE, + [KEY_SYM_ONE] = KEY_1, [KEY_SYM_BANG] = KEY_1, + [KEY_SYM_TWO] = KEY_2, [KEY_SYM_AT] = KEY_2, + [KEY_SYM_THREE] = KEY_3, [KEY_SYM_POUND] = KEY_3, + [KEY_SYM_FOUR] = KEY_4, [KEY_SYM_DOLLAR] = KEY_4, + [KEY_SYM_FIVE] = KEY_5, [KEY_SYM_PERCENT] = KEY_5, + [KEY_SYM_SIX] = KEY_6, [KEY_SYM_CARAT] = KEY_6, + [KEY_SYM_SEVEN] = KEY_7, [KEY_SYM_AMPER] = KEY_7, + [KEY_SYM_EIGHT] = KEY_8, [KEY_SYM_STAR] = KEY_8, + [KEY_SYM_NINE] = KEY_9, [KEY_SYM_LPAREN] = KEY_9, + [KEY_SYM_ZERO] = KEY_0, [KEY_SYM_RPAREN] = KEY_0, + [KEY_SYM_MINUS] = KEY_MINUS, [KEY_SYM_USCORE] = KEY_MINUS, + [KEY_SYM_EQUAL] = KEY_EQUAL, [KEY_SYM_PLUS] = KEY_EQUAL, + [KEY_SYM_LBRKT] = KEY_LEFTBRACE, [KEY_SYM_LCURLY] = KEY_LEFTBRACE, + [KEY_SYM_RBRKT] = KEY_RIGHTBRACE, [KEY_SYM_RCURLY] = KEY_RIGHTBRACE, + [KEY_SYM_SLASH] = KEY_BACKSLASH, [KEY_SYM_PIPE] = KEY_BACKSLASH, + [KEY_SYM_TIC] = KEY_APOSTROPHE, [KEY_SYM_QUOTE] = KEY_APOSTROPHE, + [KEY_SYM_SEMIC] = KEY_SEMICOLON, [KEY_SYM_COLON] = KEY_SEMICOLON, + [KEY_SYM_COMMA] = KEY_COMMA, [KEY_SYM_LT] = KEY_COMMA, + [KEY_SYM_PERIOD] = KEY_DOT, [KEY_SYM_GT] = KEY_DOT, + [KEY_SYM_BSLASH] = KEY_SLASH, [KEY_SYM_QMARK] = KEY_SLASH, + [KEY_SYM_A] = KEY_A, [KEY_SYM_a] = KEY_A, + [KEY_SYM_B] = KEY_B, [KEY_SYM_b] = KEY_B, + [KEY_SYM_C] = KEY_C, [KEY_SYM_c] = KEY_C, + [KEY_SYM_D] = KEY_D, [KEY_SYM_d] = KEY_D, + [KEY_SYM_E] = KEY_E, [KEY_SYM_e] = KEY_E, + [KEY_SYM_F] = KEY_F, [KEY_SYM_f] = KEY_F, + [KEY_SYM_G] = KEY_G, [KEY_SYM_g] = KEY_G, + [KEY_SYM_H] = KEY_H, [KEY_SYM_h] = KEY_H, + [KEY_SYM_I] = KEY_I, [KEY_SYM_i] = KEY_I, + [KEY_SYM_J] = KEY_J, [KEY_SYM_j] = KEY_J, + [KEY_SYM_K] = KEY_K, [KEY_SYM_k] = KEY_K, + [KEY_SYM_L] = KEY_L, [KEY_SYM_l] = KEY_L, + [KEY_SYM_M] = KEY_M, [KEY_SYM_m] = KEY_M, + [KEY_SYM_N] = KEY_N, [KEY_SYM_n] = KEY_N, + [KEY_SYM_O] = KEY_O, [KEY_SYM_o] = KEY_O, + [KEY_SYM_P] = KEY_P, [KEY_SYM_p] = KEY_P, + [KEY_SYM_Q] = KEY_Q, [KEY_SYM_q] = KEY_Q, + [KEY_SYM_R] = KEY_R, [KEY_SYM_r] = KEY_R, + [KEY_SYM_S] = KEY_S, [KEY_SYM_s] = KEY_S, + [KEY_SYM_T] = KEY_T, [KEY_SYM_t] = KEY_T, + [KEY_SYM_U] = KEY_U, [KEY_SYM_u] = KEY_U, + [KEY_SYM_V] = KEY_V, [KEY_SYM_v] = KEY_V, + [KEY_SYM_W] = KEY_W, [KEY_SYM_w] = KEY_W, + [KEY_SYM_X] = KEY_X, [KEY_SYM_x] = KEY_X, + [KEY_SYM_Y] = KEY_Y, [KEY_SYM_y] = KEY_Y, + [KEY_SYM_Z] = KEY_Z, [KEY_SYM_z] = KEY_Z, +}; - q->end = q->start + DRIVER_REMOTE_QUEUE_SIZE; - q->reader = q->start; - q->writer = q->start; - q->size = DRIVER_REMOTE_QUEUE_SIZE; - init_waitqueue_head(&q->wait); +static char remote_mouse_name[] = "ibmasm RSA I remote mouse"; +static char remote_keybd_name[] = "ibmasm RSA I remote keyboard"; - return 0; -} - -void ibmasm_free_remote_queue(struct service_processor *sp) +static void print_input(struct remote_input *input) { - kfree(sp->remote_queue.start); + if (input->type == INPUT_TYPE_MOUSE) { + unsigned char buttons = input->mouse_buttons; + dbg("remote mouse movement: (x,y)=(%d,%d)%s%s%s%s\n", + input->data.mouse.x, input->data.mouse.y, + (buttons)?" -- buttons:":"", + (buttons & REMOTE_BUTTON_LEFT)?"left ":"", + (buttons & REMOTE_BUTTON_MIDDLE)?"middle ":"", + (buttons & REMOTE_BUTTON_RIGHT)?"right":"" + ); + } else { + dbg("remote keypress (code, flag, down):" + "%d (0x%x) [0x%x] [0x%x]\n", + input->data.keyboard.key_code, + input->data.keyboard.key_code, + input->data.keyboard.key_flag, + input->data.keyboard.key_down + ); + } } -void ibmasm_advance_reader(struct remote_queue *q, unsigned int n) +static void send_mouse_event(struct input_dev *dev, struct pt_regs *regs, + struct remote_input *input) { - q->reader += n; - if (q->reader >= q->end) - q->reader -= q->size; -} + unsigned char buttons = input->mouse_buttons; -size_t ibmasm_events_available(struct remote_queue *q) -{ - ssize_t diff = q->writer - q->reader; - - return (diff >= 0) ? diff : q->end - q->reader; + input_regs(dev, regs); + input_report_abs(dev, ABS_X, input->data.mouse.x); + input_report_abs(dev, ABS_Y, input->data.mouse.y); + input_report_key(dev, BTN_LEFT, buttons & REMOTE_BUTTON_LEFT); + input_report_key(dev, BTN_MIDDLE, buttons & REMOTE_BUTTON_MIDDLE); + input_report_key(dev, BTN_RIGHT, buttons & REMOTE_BUTTON_RIGHT); + input_sync(dev); } - -static int space_free(struct remote_queue *q) +static void send_keyboard_event(struct input_dev *dev, struct pt_regs *regs, + struct remote_input *input) { - if (q->reader == q->writer) - return q->size - 1; + unsigned int key; + unsigned short code = input->data.keyboard.key_code; - return ( (q->reader + q->size - q->writer) % q->size ) - 1; + if (code & 0xff00) + key = xlate_high[code & 0xff]; + else + key = xlate[code]; + input_regs(dev, regs); + input_report_key(dev, key, (input->data.keyboard.key_down) ? 1 : 0); + input_sync(dev); } -static void set_mouse_event(struct remote_input *input, struct mouse_event *mouse) +void ibmasm_handle_mouse_interrupt(struct service_processor *sp, + struct pt_regs *regs) { - static char last_buttons = 0; + unsigned long reader; + unsigned long writer; + struct remote_input input; - mouse->x = input->data.mouse.x; - mouse->y = input->data.mouse.y; + reader = get_queue_reader(sp); + writer = get_queue_writer(sp); - if (input->mouse_buttons == REMOTE_MOUSE_DOUBLE_CLICK) { - mouse->buttons = REMOTE_MOUSE_DOUBLE_CLICK; - last_buttons = 0; - return; - } - mouse->transitions = last_buttons ^ input->mouse_buttons; - mouse->buttons = input->mouse_buttons; + while (reader != writer) { + memcpy_fromio(&input, get_queue_entry(sp, reader), + sizeof(struct remote_input)); - last_buttons = input->mouse_buttons; -} + print_input(&input); + if (input.type == INPUT_TYPE_MOUSE) { + send_mouse_event(&sp->remote->mouse_dev, regs, &input); + } else if (input.type == INPUT_TYPE_KEYBOARD) { + send_keyboard_event(&sp->remote->keybd_dev, regs, &input); + } else + break; -static void set_keyboard_event(struct remote_input *input, struct keyboard_event *keyboard) -{ - keyboard->key_code = input->data.keyboard.key_code; - keyboard->key_down = input->data.keyboard.key_down; + reader = advance_queue_reader(sp, reader); + writer = get_queue_writer(sp); + } } -static int add_to_driver_queue(struct remote_queue *q, struct remote_input *input) +int ibmasm_init_remote_input_dev(struct service_processor *sp) { - struct remote_event *event = q->writer; + /* set up the mouse input device */ + struct ibmasm_remote *remote; + struct pci_dev *pdev = to_pci_dev(sp->dev); + int i; - if (space_free(q) < 1) { - return 1; - } + sp->remote = remote = kmalloc(sizeof(*remote), GFP_KERNEL); + if (!remote) + return -ENOMEM; - switch(input->type) { - case (INPUT_TYPE_MOUSE): - event->type = INPUT_TYPE_MOUSE; - set_mouse_event(input, &event->data.mouse); - break; - case (INPUT_TYPE_KEYBOARD): - event->type = INPUT_TYPE_KEYBOARD; - set_keyboard_event(input, &event->data.keyboard); - break; - default: - return 0; - } - event->type = input->type; + memset(remote, 0, sizeof(*remote)); - q->writer++; - if (q->writer == q->end) - q->writer = q->start; + remote->mouse_dev.private = remote; + init_input_dev(&remote->mouse_dev); + remote->mouse_dev.id.vendor = pdev->vendor; + remote->mouse_dev.id.product = pdev->device; + remote->mouse_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + remote->mouse_dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | + BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); + set_bit(BTN_TOUCH, remote->mouse_dev.keybit); + remote->mouse_dev.name = remote_mouse_name; + input_set_abs_params(&remote->mouse_dev, ABS_X, 0, xmax, 0, 0); + input_set_abs_params(&remote->mouse_dev, ABS_Y, 0, ymax, 0, 0); - return 0; -} - + remote->keybd_dev.private = remote; + init_input_dev(&remote->keybd_dev); + remote->keybd_dev.id.vendor = pdev->vendor; + remote->keybd_dev.id.product = pdev->device; + remote->keybd_dev.evbit[0] = BIT(EV_KEY); + remote->keybd_dev.name = remote_keybd_name; -void ibmasm_handle_mouse_interrupt(struct service_processor *sp) -{ - unsigned long reader; - unsigned long writer; - struct remote_input input; + for (i=0; ikeybd_dev.keybit); + if (xlate[i]) + set_bit(xlate[i], remote->keybd_dev.keybit); + } - reader = get_queue_reader(sp); - writer = get_queue_writer(sp); + input_register_device(&remote->mouse_dev); + input_register_device(&remote->keybd_dev); + enable_mouse_interrupts(sp); - while (reader != writer) { - memcpy(&input, (void *)get_queue_entry(sp, reader), sizeof(struct remote_input)); + printk(KERN_INFO "ibmasm remote responding to events on RSA card %d\n", sp->number); - if (add_to_driver_queue(&sp->remote_queue, &input)) - break; + return 0; +} - reader = advance_queue_reader(sp, reader); - } - wake_up_interruptible(&sp->remote_queue.wait); +void ibmasm_free_remote_input_dev(struct service_processor *sp) +{ + disable_mouse_interrupts(sp); + input_unregister_device(&sp->remote->keybd_dev); + input_unregister_device(&sp->remote->mouse_dev); + kfree(sp->remote); } + diff --git a/drivers/misc/ibmasm/remote.h b/drivers/misc/ibmasm/remote.h index a8eb19f02d3f..b7076a8442d2 100644 --- a/drivers/misc/ibmasm/remote.h +++ b/drivers/misc/ibmasm/remote.h @@ -51,11 +51,13 @@ /* mouse button states received from SP */ -#define REMOTE_MOUSE_DOUBLE_CLICK 0xF0 -#define REMOTE_MOUSE_BUTTON_LEFT 0x01 -#define REMOTE_MOUSE_BUTTON_MIDDLE 0x02 -#define REMOTE_MOUSE_BUTTON_RIGHT 0x04 +#define REMOTE_DOUBLE_CLICK 0xF0 +#define REMOTE_BUTTON_LEFT 0x01 +#define REMOTE_BUTTON_MIDDLE 0x02 +#define REMOTE_BUTTON_RIGHT 0x04 +/* size of keysym/keycode translation matricies */ +#define XLATE_SIZE 256 struct mouse_input { unsigned short y; @@ -83,11 +85,13 @@ struct remote_input { unsigned char pad3; }; -#define mouse_addr(sp) sp->base_address + CONDOR_MOUSE_DATA -#define display_width(sp) mouse_addr(sp) + CONDOR_INPUT_DISPLAY_RESX -#define display_height(sp) mouse_addr(sp) + CONDOR_INPUT_DISPLAY_RESY -#define display_depth(sp) mouse_addr(sp) + CONDOR_INPUT_DISPLAY_BITS -#define vnc_status(sp) mouse_addr(sp) + CONDOR_OUTPUT_VNC_STATUS +#define mouse_addr(sp) (sp->base_address + CONDOR_MOUSE_DATA) +#define display_width(sp) (mouse_addr(sp) + CONDOR_INPUT_DISPLAY_RESX) +#define display_height(sp) (mouse_addr(sp) + CONDOR_INPUT_DISPLAY_RESY) +#define display_depth(sp) (mouse_addr(sp) + CONDOR_INPUT_DISPLAY_BITS) +#define desktop_info(sp) (mouse_addr(sp) + CONDOR_INPUT_DESKTOP_INFO) +#define vnc_status(sp) (mouse_addr(sp) + CONDOR_OUTPUT_VNC_STATUS) +#define isr_control(sp) (mouse_addr(sp) + CONDOR_MOUSE_ISR_CONTROL) #define mouse_interrupt_pending(sp) readl(mouse_addr(sp) + CONDOR_MOUSE_ISR_STATUS) #define clear_mouse_interrupt(sp) writel(0, mouse_addr(sp) + CONDOR_MOUSE_ISR_STATUS) @@ -101,10 +105,10 @@ struct remote_input { #define get_queue_reader(sp) readl(mouse_addr(sp) + CONDOR_MOUSE_Q_READER) #define set_queue_reader(sp, reader) writel(reader, mouse_addr(sp) + CONDOR_MOUSE_Q_READER) -#define queue_begin mouse_addr(sp) + CONDOR_MOUSE_Q_BEGIN +#define queue_begin (mouse_addr(sp) + CONDOR_MOUSE_Q_BEGIN) #define get_queue_entry(sp, read_index) \ - queue_begin + read_index * sizeof(struct remote_input) + ((void*)(queue_begin + read_index * sizeof(struct remote_input))) static inline int advance_queue_reader(struct service_processor *sp, unsigned long reader) { @@ -116,4 +120,151 @@ static inline int advance_queue_reader(struct service_processor *sp, unsigned lo return reader; } +#define NO_KEYCODE 0 +#define KEY_SYM_BK_SPC 0xFF08 +#define KEY_SYM_TAB 0xFF09 +#define KEY_SYM_ENTER 0xFF0D +#define KEY_SYM_SCR_LOCK 0xFF14 +#define KEY_SYM_ESCAPE 0xFF1B +#define KEY_SYM_HOME 0xFF50 +#define KEY_SYM_LARROW 0xFF51 +#define KEY_SYM_UARROW 0xFF52 +#define KEY_SYM_RARROW 0xFF53 +#define KEY_SYM_DARROW 0xFF54 +#define KEY_SYM_PAGEUP 0xFF55 +#define KEY_SYM_PAGEDOWN 0xFF56 +#define KEY_SYM_END 0xFF57 +#define KEY_SYM_INSERT 0xFF63 +#define KEY_SYM_NUM_LOCK 0xFF7F +#define KEY_SYM_KPSTAR 0xFFAA +#define KEY_SYM_KPPLUS 0xFFAB +#define KEY_SYM_KPMINUS 0xFFAD +#define KEY_SYM_KPDOT 0xFFAE +#define KEY_SYM_KPSLASH 0xFFAF +#define KEY_SYM_KPRIGHT 0xFF96 +#define KEY_SYM_KPUP 0xFF97 +#define KEY_SYM_KPLEFT 0xFF98 +#define KEY_SYM_KPDOWN 0xFF99 +#define KEY_SYM_KP0 0xFFB0 +#define KEY_SYM_KP1 0xFFB1 +#define KEY_SYM_KP2 0xFFB2 +#define KEY_SYM_KP3 0xFFB3 +#define KEY_SYM_KP4 0xFFB4 +#define KEY_SYM_KP5 0xFFB5 +#define KEY_SYM_KP6 0xFFB6 +#define KEY_SYM_KP7 0xFFB7 +#define KEY_SYM_KP8 0xFFB8 +#define KEY_SYM_KP9 0xFFB9 +#define KEY_SYM_F1 0xFFBE // 1B 5B 5B 41 +#define KEY_SYM_F2 0xFFBF // 1B 5B 5B 42 +#define KEY_SYM_F3 0xFFC0 // 1B 5B 5B 43 +#define KEY_SYM_F4 0xFFC1 // 1B 5B 5B 44 +#define KEY_SYM_F5 0xFFC2 // 1B 5B 5B 45 +#define KEY_SYM_F6 0xFFC3 // 1B 5B 31 37 7E +#define KEY_SYM_F7 0xFFC4 // 1B 5B 31 38 7E +#define KEY_SYM_F8 0xFFC5 // 1B 5B 31 39 7E +#define KEY_SYM_F9 0xFFC6 // 1B 5B 32 30 7E +#define KEY_SYM_F10 0xFFC7 // 1B 5B 32 31 7E +#define KEY_SYM_F11 0xFFC8 // 1B 5B 32 33 7E +#define KEY_SYM_F12 0xFFC9 // 1B 5B 32 34 7E +#define KEY_SYM_SHIFT 0xFFE1 +#define KEY_SYM_CTRL 0xFFE3 +#define KEY_SYM_ALT 0xFFE9 +#define KEY_SYM_CAP_LOCK 0xFFE5 +#define KEY_SYM_DELETE 0xFFFF +#define KEY_SYM_TILDE 0x60 +#define KEY_SYM_BKTIC 0x7E +#define KEY_SYM_ONE 0x31 +#define KEY_SYM_BANG 0x21 +#define KEY_SYM_TWO 0x32 +#define KEY_SYM_AT 0x40 +#define KEY_SYM_THREE 0x33 +#define KEY_SYM_POUND 0x23 +#define KEY_SYM_FOUR 0x34 +#define KEY_SYM_DOLLAR 0x24 +#define KEY_SYM_FIVE 0x35 +#define KEY_SYM_PERCENT 0x25 +#define KEY_SYM_SIX 0x36 +#define KEY_SYM_CARAT 0x5E +#define KEY_SYM_SEVEN 0x37 +#define KEY_SYM_AMPER 0x26 +#define KEY_SYM_EIGHT 0x38 +#define KEY_SYM_STAR 0x2A +#define KEY_SYM_NINE 0x39 +#define KEY_SYM_LPAREN 0x28 +#define KEY_SYM_ZERO 0x30 +#define KEY_SYM_RPAREN 0x29 +#define KEY_SYM_MINUS 0x2D +#define KEY_SYM_USCORE 0x5F +#define KEY_SYM_EQUAL 0x2B +#define KEY_SYM_PLUS 0x3D +#define KEY_SYM_LBRKT 0x5B +#define KEY_SYM_LCURLY 0x7B +#define KEY_SYM_RBRKT 0x5D +#define KEY_SYM_RCURLY 0x7D +#define KEY_SYM_SLASH 0x5C +#define KEY_SYM_PIPE 0x7C +#define KEY_SYM_TIC 0x27 +#define KEY_SYM_QUOTE 0x22 +#define KEY_SYM_SEMIC 0x3B +#define KEY_SYM_COLON 0x3A +#define KEY_SYM_COMMA 0x2C +#define KEY_SYM_LT 0x3C +#define KEY_SYM_PERIOD 0x2E +#define KEY_SYM_GT 0x3E +#define KEY_SYM_BSLASH 0x2F +#define KEY_SYM_QMARK 0x3F +#define KEY_SYM_A 0x41 +#define KEY_SYM_B 0x42 +#define KEY_SYM_C 0x43 +#define KEY_SYM_D 0x44 +#define KEY_SYM_E 0x45 +#define KEY_SYM_F 0x46 +#define KEY_SYM_G 0x47 +#define KEY_SYM_H 0x48 +#define KEY_SYM_I 0x49 +#define KEY_SYM_J 0x4A +#define KEY_SYM_K 0x4B +#define KEY_SYM_L 0x4C +#define KEY_SYM_M 0x4D +#define KEY_SYM_N 0x4E +#define KEY_SYM_O 0x4F +#define KEY_SYM_P 0x50 +#define KEY_SYM_Q 0x51 +#define KEY_SYM_R 0x52 +#define KEY_SYM_S 0x53 +#define KEY_SYM_T 0x54 +#define KEY_SYM_U 0x55 +#define KEY_SYM_V 0x56 +#define KEY_SYM_W 0x57 +#define KEY_SYM_X 0x58 +#define KEY_SYM_Y 0x59 +#define KEY_SYM_Z 0x5A +#define KEY_SYM_a 0x61 +#define KEY_SYM_b 0x62 +#define KEY_SYM_c 0x63 +#define KEY_SYM_d 0x64 +#define KEY_SYM_e 0x65 +#define KEY_SYM_f 0x66 +#define KEY_SYM_g 0x67 +#define KEY_SYM_h 0x68 +#define KEY_SYM_i 0x69 +#define KEY_SYM_j 0x6A +#define KEY_SYM_k 0x6B +#define KEY_SYM_l 0x6C +#define KEY_SYM_m 0x6D +#define KEY_SYM_n 0x6E +#define KEY_SYM_o 0x6F +#define KEY_SYM_p 0x70 +#define KEY_SYM_q 0x71 +#define KEY_SYM_r 0x72 +#define KEY_SYM_s 0x73 +#define KEY_SYM_t 0x74 +#define KEY_SYM_u 0x75 +#define KEY_SYM_v 0x76 +#define KEY_SYM_w 0x77 +#define KEY_SYM_x 0x78 +#define KEY_SYM_y 0x79 +#define KEY_SYM_z 0x7A +#define KEY_SYM_SPACE 0x20 #endif /* _IBMASM_REMOTE_H_ */ -- cgit v1.2.3-59-g8ed1b From 8818760512424f60ad9fafb7a087b007a9274eb3 Mon Sep 17 00:00:00 2001 From: Max Asbock Date: Tue, 21 Jun 2005 17:16:36 -0700 Subject: [PATCH] ibmasm driver: fix race in command refcount logic This patch fixes a race in the command reference counting logic by putting spinlocks around kobject_put() in the command_put function. - Also added debug messages. - Changed a memcpy to memcpy_fromio since we are reading from io space. Signed-off-by: Max Asbock Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/ibmasm/command.c | 30 ++++++++++++++++++++++++------ drivers/misc/ibmasm/dot_command.c | 10 ++++++++-- drivers/misc/ibmasm/heartbeat.c | 13 +++++++++++-- drivers/misc/ibmasm/ibmasm.h | 7 ++++++- drivers/misc/ibmasm/ibmasmfs.c | 2 +- drivers/misc/ibmasm/r_heartbeat.c | 2 +- 6 files changed, 51 insertions(+), 13 deletions(-) diff --git a/drivers/misc/ibmasm/command.c b/drivers/misc/ibmasm/command.c index 245b0058381d..07a085ccbd5b 100644 --- a/drivers/misc/ibmasm/command.c +++ b/drivers/misc/ibmasm/command.c @@ -23,6 +23,7 @@ */ #include "ibmasm.h" +#include "lowlevel.h" static void exec_next_command(struct service_processor *sp); static void free_command(struct kobject *kobj); @@ -31,8 +32,9 @@ static struct kobj_type ibmasm_cmd_kobj_type = { .release = free_command, }; +static atomic_t command_count = ATOMIC_INIT(0); -struct command *ibmasm_new_command(size_t buffer_size) +struct command *ibmasm_new_command(struct service_processor *sp, size_t buffer_size) { struct command *cmd; @@ -55,11 +57,15 @@ struct command *ibmasm_new_command(size_t buffer_size) kobject_init(&cmd->kobj); cmd->kobj.ktype = &ibmasm_cmd_kobj_type; + cmd->lock = &sp->lock; cmd->status = IBMASM_CMD_PENDING; init_waitqueue_head(&cmd->wait); INIT_LIST_HEAD(&cmd->queue_node); + atomic_inc(&command_count); + dbg("command count: %d\n", atomic_read(&command_count)); + return cmd; } @@ -68,6 +74,8 @@ static void free_command(struct kobject *kobj) struct command *cmd = to_command(kobj); list_del(&cmd->queue_node); + atomic_dec(&command_count); + dbg("command count: %d\n", atomic_read(&command_count)); kfree(cmd->buffer); kfree(cmd); } @@ -94,8 +102,14 @@ static struct command *dequeue_command(struct service_processor *sp) static inline void do_exec_command(struct service_processor *sp) { + char tsbuf[32]; + + dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf)); + if (ibmasm_send_i2o_message(sp)) { sp->current_command->status = IBMASM_CMD_FAILED; + wake_up(&sp->current_command->wait); + command_put(sp->current_command); exec_next_command(sp); } } @@ -111,14 +125,16 @@ static inline void do_exec_command(struct service_processor *sp) void ibmasm_exec_command(struct service_processor *sp, struct command *cmd) { unsigned long flags; + char tsbuf[32]; + + dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf)); spin_lock_irqsave(&sp->lock, flags); if (!sp->current_command) { - command_get(cmd); sp->current_command = cmd; + command_get(sp->current_command); spin_unlock_irqrestore(&sp->lock, flags); - do_exec_command(sp); } else { enqueue_command(sp, cmd); @@ -129,9 +145,9 @@ void ibmasm_exec_command(struct service_processor *sp, struct command *cmd) static void exec_next_command(struct service_processor *sp) { unsigned long flags; + char tsbuf[32]; - wake_up(&sp->current_command->wait); - command_put(sp->current_command); + dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf)); spin_lock_irqsave(&sp->lock, flags); sp->current_command = dequeue_command(sp); @@ -169,7 +185,9 @@ void ibmasm_receive_command_response(struct service_processor *sp, void *respons if (!sp->current_command) return; - memcpy(cmd->buffer, response, min(size, cmd->buffer_size)); + memcpy_fromio(cmd->buffer, response, min(size, cmd->buffer_size)); cmd->status = IBMASM_CMD_COMPLETE; + wake_up(&sp->current_command->wait); + command_put(sp->current_command); exec_next_command(sp); } diff --git a/drivers/misc/ibmasm/dot_command.c b/drivers/misc/ibmasm/dot_command.c index 478a8d898fc1..13c52f866e2e 100644 --- a/drivers/misc/ibmasm/dot_command.c +++ b/drivers/misc/ibmasm/dot_command.c @@ -33,7 +33,13 @@ void ibmasm_receive_message(struct service_processor *sp, void *message, int mes u32 size; struct dot_command_header *header = (struct dot_command_header *)message; + if (message_size == 0) + return; + size = get_dot_command_size(message); + if (size == 0) + return; + if (size > message_size) size = message_size; @@ -67,7 +73,7 @@ int ibmasm_send_driver_vpd(struct service_processor *sp) u8 *vpd_data; int result = 0; - command = ibmasm_new_command(INIT_BUFFER_SIZE); + command = ibmasm_new_command(sp, INIT_BUFFER_SIZE); if (command == NULL) return -ENOMEM; @@ -121,7 +127,7 @@ int ibmasm_send_os_state(struct service_processor *sp, int os_state) struct os_state_command *os_state_cmd; int result = 0; - cmd = ibmasm_new_command(sizeof(struct os_state_command)); + cmd = ibmasm_new_command(sp, sizeof(struct os_state_command)); if (cmd == NULL) return -ENOMEM; diff --git a/drivers/misc/ibmasm/heartbeat.c b/drivers/misc/ibmasm/heartbeat.c index ce09309174d6..f295401fac21 100644 --- a/drivers/misc/ibmasm/heartbeat.c +++ b/drivers/misc/ibmasm/heartbeat.c @@ -25,6 +25,7 @@ #include #include "ibmasm.h" #include "dot_command.h" +#include "lowlevel.h" static int suspend_heartbeats = 0; @@ -62,7 +63,7 @@ void ibmasm_unregister_panic_notifier(void) int ibmasm_heartbeat_init(struct service_processor *sp) { - sp->heartbeat = ibmasm_new_command(HEARTBEAT_BUFFER_SIZE); + sp->heartbeat = ibmasm_new_command(sp, HEARTBEAT_BUFFER_SIZE); if (sp->heartbeat == NULL) return -ENOMEM; @@ -71,6 +72,12 @@ int ibmasm_heartbeat_init(struct service_processor *sp) void ibmasm_heartbeat_exit(struct service_processor *sp) { + char tsbuf[32]; + + dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf)); + ibmasm_wait_for_response(sp->heartbeat, IBMASM_CMD_TIMEOUT_NORMAL); + dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf)); + suspend_heartbeats = 1; command_put(sp->heartbeat); } @@ -78,14 +85,16 @@ void ibmasm_receive_heartbeat(struct service_processor *sp, void *message, size { struct command *cmd = sp->heartbeat; struct dot_command_header *header = (struct dot_command_header *)cmd->buffer; + char tsbuf[32]; + dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf)); if (suspend_heartbeats) return; /* return the received dot command to sender */ cmd->status = IBMASM_CMD_PENDING; size = min(size, cmd->buffer_size); - memcpy(cmd->buffer, message, size); + memcpy_fromio(cmd->buffer, message, size); header->type = sp_write; ibmasm_exec_command(sp, cmd); } diff --git a/drivers/misc/ibmasm/ibmasm.h b/drivers/misc/ibmasm/ibmasm.h index 653a7d096a8b..ecce4ffd3e23 100644 --- a/drivers/misc/ibmasm/ibmasm.h +++ b/drivers/misc/ibmasm/ibmasm.h @@ -95,12 +95,17 @@ struct command { size_t buffer_size; int status; struct kobject kobj; + spinlock_t *lock; }; #define to_command(c) container_of(c, struct command, kobj) static inline void command_put(struct command *cmd) { + unsigned long flags; + + spin_lock_irqsave(cmd->lock, flags); kobject_put(&cmd->kobj); + spin_unlock_irqrestore(cmd->lock, flags); } static inline void command_get(struct command *cmd) @@ -159,7 +164,7 @@ struct service_processor { }; /* command processing */ -extern struct command *ibmasm_new_command(size_t buffer_size); +extern struct command *ibmasm_new_command(struct service_processor *sp, size_t buffer_size); extern void ibmasm_exec_command(struct service_processor *sp, struct command *cmd); extern void ibmasm_wait_for_response(struct command *cmd, int timeout); extern void ibmasm_receive_command_response(struct service_processor *sp, void *response, size_t size); diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c index ca839162e4f7..5c550fcac2c4 100644 --- a/drivers/misc/ibmasm/ibmasmfs.c +++ b/drivers/misc/ibmasm/ibmasmfs.c @@ -321,7 +321,7 @@ static ssize_t command_file_write(struct file *file, const char __user *ubuff, s if (command_data->command) return -EAGAIN; - cmd = ibmasm_new_command(count); + cmd = ibmasm_new_command(command_data->sp, count); if (!cmd) return -ENOMEM; diff --git a/drivers/misc/ibmasm/r_heartbeat.c b/drivers/misc/ibmasm/r_heartbeat.c index 93d9c1b2ad6f..f8fdb2d5417e 100644 --- a/drivers/misc/ibmasm/r_heartbeat.c +++ b/drivers/misc/ibmasm/r_heartbeat.c @@ -63,7 +63,7 @@ int ibmasm_start_reverse_heartbeat(struct service_processor *sp, struct reverse_ int times_failed = 0; int result = 1; - cmd = ibmasm_new_command(sizeof rhb_dot_cmd); + cmd = ibmasm_new_command(sp, sizeof rhb_dot_cmd); if (!cmd) return -ENOMEM; -- cgit v1.2.3-59-g8ed1b From 9b1e3afd6d56937ced3914971621d0f053ea9178 Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Tue, 21 Jun 2005 17:16:38 -0700 Subject: [PATCH] autofs4: avoid panic on bind mount of autofs owned directory While this is not a solution to bind and move mounts on autofs owned directories it is necessary to fix the trady error handling. At least it avoids the kernel panic I observed checking out bug #4589. Signed-off-by: Ian Kent Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/autofs4/autofs_i.h | 13 +++++++++++++ fs/autofs4/expire.c | 5 +---- fs/autofs4/root.c | 6 +++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index c7b2b8890188..9c09641ce907 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h @@ -185,6 +185,19 @@ int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify); int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int); void autofs4_catatonic_mode(struct autofs_sb_info *); +static inline int autofs4_follow_mount(struct vfsmount **mnt, struct dentry **dentry) +{ + int res = 0; + + while (d_mountpoint(*dentry)) { + int followed = follow_down(mnt, dentry); + if (!followed) + break; + res = 1; + } + return res; +} + static inline int simple_positive(struct dentry *dentry) { return dentry->d_inode && !d_unhashed(dentry); diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 500425e24fba..feb6ac427d05 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c @@ -56,12 +56,9 @@ static int autofs4_check_mount(struct vfsmount *mnt, struct dentry *dentry) mntget(mnt); dget(dentry); - if (!follow_down(&mnt, &dentry)) + if (!autofs4_follow_mount(&mnt, &dentry)) goto done; - while (d_mountpoint(dentry) && follow_down(&mnt, &dentry)) - ; - /* This is an autofs submount, we can't expire it */ if (is_autofs4_dentry(dentry)) goto done; diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 3765c047f157..e137acf0543d 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -205,7 +205,11 @@ static int autofs4_dir_open(struct inode *inode, struct file *file) struct vfsmount *fp_mnt = mntget(mnt); struct dentry *fp_dentry = dget(dentry); - while (follow_down(&fp_mnt, &fp_dentry) && d_mountpoint(fp_dentry)); + if (!autofs4_follow_mount(&fp_mnt, &fp_dentry)) { + dput(fp_dentry); + mntput(fp_mnt); + return -ENOENT; + } fp = dentry_open(fp_dentry, fp_mnt, file->f_flags); status = PTR_ERR(fp); -- cgit v1.2.3-59-g8ed1b From cc9acc885819696c0ed00f4f0f0cda0c7583f116 Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Tue, 21 Jun 2005 17:16:39 -0700 Subject: [PATCH] autofs4: post expire race fix At the tail end of an expire it's possible for a process to enter autofs4_wait, with a waitq type of NFY_NONE but find that the expire is finished. In this cause autofs4_wait will try to create a new wait but not notify the daemon leading to a hang. As the wait type is meant to delay mount requests from revalidate or lookup during an expire and the expire is done all we need to do is check if the dentry is a mountpoint. If it's not then we're done. Signed-off-by: Ian Kent Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/autofs4/waitq.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index 5a40d36e5a51..fa2348dcd671 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c @@ -191,6 +191,13 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry, } if ( !wq ) { + /* Can't wait for an expire if there's no mount */ + if (notify == NFY_NONE && !d_mountpoint(dentry)) { + kfree(name); + up(&sbi->wq_sem); + return -ENOENT; + } + /* Create a new wait queue */ wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL); if ( !wq ) { -- cgit v1.2.3-59-g8ed1b From 1684b2bba6972749bc9acee57585acd6c78050b2 Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Tue, 21 Jun 2005 17:16:41 -0700 Subject: [PATCH] autofs4: bad lookup fix For browsable autofs maps, a mount request that arrives at the same time an expire is happening can fail to perform the needed mount. This happens becuase the directory exists and so the revalidate succeeds when we need it to fail so that lookup is called on the same dentry to do the mount. Instead lookup is called on the next path component which should be whithin the mount, but the parent isn't mounted. The solution is to allow the revalidate to continue and perform the mount as no directory creation (at mount time) is needed for browsable mount entries. Signed-off-by: Ian Kent Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/autofs4/root.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index e137acf0543d..2a771ec66956 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -306,7 +306,14 @@ static int try_to_fill_dentry(struct dentry *dentry, DPRINTK("expire done status=%d", status); - return 0; + /* + * If the directory still exists the mount request must + * continue otherwise it can't be followed at the right + * time during the walk. + */ + status = d_invalidate(dentry); + if (status != -EBUSY) + return 0; } DPRINTK("dentry=%p %.*s ino=%p", -- cgit v1.2.3-59-g8ed1b From 8a96619145840c6eb50d85759f72d9337db411f7 Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Tue, 21 Jun 2005 17:16:41 -0700 Subject: [PATCH] autofs4: subversion bump to identify these changes Signed-off-by: Ian Kent Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/auto_fs4.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/auto_fs4.h b/include/linux/auto_fs4.h index a1657fb99516..9343c89d843c 100644 --- a/include/linux/auto_fs4.h +++ b/include/linux/auto_fs4.h @@ -23,7 +23,7 @@ #define AUTOFS_MIN_PROTO_VERSION 3 #define AUTOFS_MAX_PROTO_VERSION 4 -#define AUTOFS_PROTO_SUBVERSION 6 +#define AUTOFS_PROTO_SUBVERSION 7 /* Mask for expire behaviour */ #define AUTOFS_EXP_IMMEDIATE 1 -- cgit v1.2.3-59-g8ed1b From 1d372116383f79e42a3eb010c7d6ec3dd28767b3 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 21 Jun 2005 17:16:42 -0700 Subject: [PATCH] rock: lindent it Trying to turn rock.c into something which humans can read so we can fix some bugs. Start out by feeding it through scripts/Lindent. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/isofs/rock.c | 647 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 356 insertions(+), 291 deletions(-) diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index 089e79c65585..bbc348f0189a 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -20,8 +20,7 @@ * returns a symbolic link name, and a fourth one returns the extent number * for the file. */ -#define SIG(A,B) ((A) | ((B) << 8)) /* isonum_721() */ - +#define SIG(A,B) ((A) | ((B) << 8)) /* isonum_721() */ /* This is a way of ensuring that we have something in the system use fields that is compatible with Rock Ridge */ @@ -54,7 +53,7 @@ CHR+=ISOFS_SB(inode->i_sb)->s_rock_offset; \ if (LEN<0) LEN=0; \ } \ -} +} #define MAYBE_CONTINUE(LABEL,DEV) \ {if (buffer) { kfree(buffer); buffer = NULL; } \ @@ -85,280 +84,348 @@ }} /* return length of name field; 0: not found, -1: to be ignored */ -int get_rock_ridge_filename(struct iso_directory_record * de, - char * retname, struct inode * inode) +int get_rock_ridge_filename(struct iso_directory_record *de, + char *retname, struct inode *inode) { - int len; - unsigned char * chr; - CONTINUE_DECLS; - int retnamlen = 0, truncate=0; - - if (!ISOFS_SB(inode->i_sb)->s_rock) return 0; - *retname = 0; - - SETUP_ROCK_RIDGE(de, chr, len); - repeat: - { - struct rock_ridge * rr; - int sig; - - while (len > 2){ /* There may be one byte for padding somewhere */ - rr = (struct rock_ridge *) chr; - if (rr->len < 3) goto out; /* Something got screwed up here */ - sig = isonum_721(chr); - chr += rr->len; - len -= rr->len; - if (len < 0) goto out; /* corrupted isofs */ - - switch(sig){ - case SIG('R','R'): - if((rr->u.RR.flags[0] & RR_NM) == 0) goto out; - break; - case SIG('S','P'): - CHECK_SP(goto out); - break; - case SIG('C','E'): - CHECK_CE; - break; - case SIG('N','M'): - if (truncate) break; - if (rr->len < 5) break; - /* - * If the flags are 2 or 4, this indicates '.' or '..'. - * We don't want to do anything with this, because it - * screws up the code that calls us. We don't really - * care anyways, since we can just use the non-RR - * name. - */ - if (rr->u.NM.flags & 6) { - break; - } + int len; + unsigned char *chr; + CONTINUE_DECLS; + int retnamlen = 0, truncate = 0; - if (rr->u.NM.flags & ~1) { - printk("Unsupported NM flag settings (%d)\n",rr->u.NM.flags); - break; - } - if((strlen(retname) + rr->len - 5) >= 254) { - truncate = 1; - break; + if (!ISOFS_SB(inode->i_sb)->s_rock) + return 0; + *retname = 0; + + SETUP_ROCK_RIDGE(de, chr, len); + repeat: + { + struct rock_ridge *rr; + int sig; + + while (len > 2) { /* There may be one byte for padding somewhere */ + rr = (struct rock_ridge *)chr; + if (rr->len < 3) + goto out; /* Something got screwed up here */ + sig = isonum_721(chr); + chr += rr->len; + len -= rr->len; + if (len < 0) + goto out; /* corrupted isofs */ + + switch (sig) { + case SIG('R', 'R'): + if ((rr->u.RR.flags[0] & RR_NM) == 0) + goto out; + break; + case SIG('S', 'P'): + CHECK_SP(goto out); + break; + case SIG('C', 'E'): + CHECK_CE; + break; + case SIG('N', 'M'): + if (truncate) + break; + if (rr->len < 5) + break; + /* + * If the flags are 2 or 4, this indicates '.' or '..'. + * We don't want to do anything with this, because it + * screws up the code that calls us. We don't really + * care anyways, since we can just use the non-RR + * name. + */ + if (rr->u.NM.flags & 6) { + break; + } + + if (rr->u.NM.flags & ~1) { + printk + ("Unsupported NM flag settings (%d)\n", + rr->u.NM.flags); + break; + } + if ((strlen(retname) + rr->len - 5) >= 254) { + truncate = 1; + break; + } + strncat(retname, rr->u.NM.name, rr->len - 5); + retnamlen += rr->len - 5; + break; + case SIG('R', 'E'): + if (buffer) + kfree(buffer); + return -1; + default: + break; + } + } } - strncat(retname, rr->u.NM.name, rr->len - 5); - retnamlen += rr->len - 5; - break; - case SIG('R','E'): - if (buffer) kfree(buffer); - return -1; - default: - break; - } - } - } - MAYBE_CONTINUE(repeat,inode); - if (buffer) kfree(buffer); - return retnamlen; /* If 0, this file did not have a NM field */ - out: - if(buffer) kfree(buffer); - return 0; + MAYBE_CONTINUE(repeat, inode); + if (buffer) + kfree(buffer); + return retnamlen; /* If 0, this file did not have a NM field */ + out: + if (buffer) + kfree(buffer); + return 0; } static int parse_rock_ridge_inode_internal(struct iso_directory_record *de, struct inode *inode, int regard_xa) { - int len; - unsigned char * chr; - int symlink_len = 0; - CONTINUE_DECLS; - - if (!ISOFS_SB(inode->i_sb)->s_rock) return 0; - - SETUP_ROCK_RIDGE(de, chr, len); - if (regard_xa) - { - chr+=14; - len-=14; - if (len<0) len=0; - } - - repeat: - { - int cnt, sig; - struct inode * reloc; - struct rock_ridge * rr; - int rootflag; - - while (len > 2){ /* There may be one byte for padding somewhere */ - rr = (struct rock_ridge *) chr; - if (rr->len < 3) goto out; /* Something got screwed up here */ - sig = isonum_721(chr); - chr += rr->len; - len -= rr->len; - if (len < 0) goto out; /* corrupted isofs */ - - switch(sig){ + int len; + unsigned char *chr; + int symlink_len = 0; + CONTINUE_DECLS; + + if (!ISOFS_SB(inode->i_sb)->s_rock) + return 0; + + SETUP_ROCK_RIDGE(de, chr, len); + if (regard_xa) { + chr += 14; + len -= 14; + if (len < 0) + len = 0; + } + + repeat: + { + int cnt, sig; + struct inode *reloc; + struct rock_ridge *rr; + int rootflag; + + while (len > 2) { /* There may be one byte for padding somewhere */ + rr = (struct rock_ridge *)chr; + if (rr->len < 3) + goto out; /* Something got screwed up here */ + sig = isonum_721(chr); + chr += rr->len; + len -= rr->len; + if (len < 0) + goto out; /* corrupted isofs */ + + switch (sig) { #ifndef CONFIG_ZISOFS /* No flag for SF or ZF */ - case SIG('R','R'): - if((rr->u.RR.flags[0] & - (RR_PX | RR_TF | RR_SL | RR_CL)) == 0) goto out; - break; + case SIG('R', 'R'): + if ((rr->u.RR.flags[0] & + (RR_PX | RR_TF | RR_SL | RR_CL)) == 0) + goto out; + break; #endif - case SIG('S','P'): - CHECK_SP(goto out); - break; - case SIG('C','E'): - CHECK_CE; - break; - case SIG('E','R'): - ISOFS_SB(inode->i_sb)->s_rock = 1; - printk(KERN_DEBUG "ISO 9660 Extensions: "); - { int p; - for(p=0;pu.ER.len_id;p++) printk("%c",rr->u.ER.data[p]); - } - printk("\n"); - break; - case SIG('P','X'): - inode->i_mode = isonum_733(rr->u.PX.mode); - inode->i_nlink = isonum_733(rr->u.PX.n_links); - inode->i_uid = isonum_733(rr->u.PX.uid); - inode->i_gid = isonum_733(rr->u.PX.gid); - break; - case SIG('P','N'): - { int high, low; - high = isonum_733(rr->u.PN.dev_high); - low = isonum_733(rr->u.PN.dev_low); - /* - * The Rock Ridge standard specifies that if sizeof(dev_t) <= 4, - * then the high field is unused, and the device number is completely - * stored in the low field. Some writers may ignore this subtlety, - * and as a result we test to see if the entire device number is - * stored in the low field, and use that. - */ - if((low & ~0xff) && high == 0) { - inode->i_rdev = MKDEV(low >> 8, low & 0xff); - } else { - inode->i_rdev = MKDEV(high, low); - } - } - break; - case SIG('T','F'): - /* Some RRIP writers incorrectly place ctime in the TF_CREATE field. - Try to handle this correctly for either case. */ - cnt = 0; /* Rock ridge never appears on a High Sierra disk */ - if(rr->u.TF.flags & TF_CREATE) { - inode->i_ctime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0); - inode->i_ctime.tv_nsec = 0; - } - if(rr->u.TF.flags & TF_MODIFY) { - inode->i_mtime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0); - inode->i_mtime.tv_nsec = 0; - } - if(rr->u.TF.flags & TF_ACCESS) { - inode->i_atime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0); - inode->i_atime.tv_nsec = 0; - } - if(rr->u.TF.flags & TF_ATTRIBUTES) { - inode->i_ctime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0); - inode->i_ctime.tv_nsec = 0; - } - break; - case SIG('S','L'): - {int slen; - struct SL_component * slp; - struct SL_component * oldslp; - slen = rr->len - 5; - slp = &rr->u.SL.link; - inode->i_size = symlink_len; - while (slen > 1){ - rootflag = 0; - switch(slp->flags &~1){ - case 0: - inode->i_size += slp->len; - break; - case 2: - inode->i_size += 1; - break; - case 4: - inode->i_size += 2; - break; - case 8: - rootflag = 1; - inode->i_size += 1; - break; - default: - printk("Symlink component flag not implemented\n"); - } - slen -= slp->len + 2; - oldslp = slp; - slp = (struct SL_component *) (((char *) slp) + slp->len + 2); - - if(slen < 2) { - if( ((rr->u.SL.flags & 1) != 0) - && ((oldslp->flags & 1) == 0) ) inode->i_size += 1; - break; - } - - /* - * If this component record isn't continued, then append a '/'. - */ - if (!rootflag && (oldslp->flags & 1) == 0) - inode->i_size += 1; - } - } - symlink_len = inode->i_size; - break; - case SIG('R','E'): - printk(KERN_WARNING "Attempt to read inode for relocated directory\n"); - goto out; - case SIG('C','L'): - ISOFS_I(inode)->i_first_extent = isonum_733(rr->u.CL.location); - reloc = isofs_iget(inode->i_sb, ISOFS_I(inode)->i_first_extent, 0); - if (!reloc) - goto out; - inode->i_mode = reloc->i_mode; - inode->i_nlink = reloc->i_nlink; - inode->i_uid = reloc->i_uid; - inode->i_gid = reloc->i_gid; - inode->i_rdev = reloc->i_rdev; - inode->i_size = reloc->i_size; - inode->i_blocks = reloc->i_blocks; - inode->i_atime = reloc->i_atime; - inode->i_ctime = reloc->i_ctime; - inode->i_mtime = reloc->i_mtime; - iput(reloc); - break; + case SIG('S', 'P'): + CHECK_SP(goto out); + break; + case SIG('C', 'E'): + CHECK_CE; + break; + case SIG('E', 'R'): + ISOFS_SB(inode->i_sb)->s_rock = 1; + printk(KERN_DEBUG "ISO 9660 Extensions: "); + { + int p; + for (p = 0; p < rr->u.ER.len_id; p++) + printk("%c", rr->u.ER.data[p]); + } + printk("\n"); + break; + case SIG('P', 'X'): + inode->i_mode = isonum_733(rr->u.PX.mode); + inode->i_nlink = isonum_733(rr->u.PX.n_links); + inode->i_uid = isonum_733(rr->u.PX.uid); + inode->i_gid = isonum_733(rr->u.PX.gid); + break; + case SIG('P', 'N'): + { + int high, low; + high = isonum_733(rr->u.PN.dev_high); + low = isonum_733(rr->u.PN.dev_low); + /* + * The Rock Ridge standard specifies that if sizeof(dev_t) <= 4, + * then the high field is unused, and the device number is completely + * stored in the low field. Some writers may ignore this subtlety, + * and as a result we test to see if the entire device number is + * stored in the low field, and use that. + */ + if ((low & ~0xff) && high == 0) { + inode->i_rdev = + MKDEV(low >> 8, low & 0xff); + } else { + inode->i_rdev = + MKDEV(high, low); + } + } + break; + case SIG('T', 'F'): + /* Some RRIP writers incorrectly place ctime in the TF_CREATE field. + Try to handle this correctly for either case. */ + cnt = 0; /* Rock ridge never appears on a High Sierra disk */ + if (rr->u.TF.flags & TF_CREATE) { + inode->i_ctime.tv_sec = + iso_date(rr->u.TF.times[cnt++].time, + 0); + inode->i_ctime.tv_nsec = 0; + } + if (rr->u.TF.flags & TF_MODIFY) { + inode->i_mtime.tv_sec = + iso_date(rr->u.TF.times[cnt++].time, + 0); + inode->i_mtime.tv_nsec = 0; + } + if (rr->u.TF.flags & TF_ACCESS) { + inode->i_atime.tv_sec = + iso_date(rr->u.TF.times[cnt++].time, + 0); + inode->i_atime.tv_nsec = 0; + } + if (rr->u.TF.flags & TF_ATTRIBUTES) { + inode->i_ctime.tv_sec = + iso_date(rr->u.TF.times[cnt++].time, + 0); + inode->i_ctime.tv_nsec = 0; + } + break; + case SIG('S', 'L'): + { + int slen; + struct SL_component *slp; + struct SL_component *oldslp; + slen = rr->len - 5; + slp = &rr->u.SL.link; + inode->i_size = symlink_len; + while (slen > 1) { + rootflag = 0; + switch (slp->flags & ~1) { + case 0: + inode->i_size += + slp->len; + break; + case 2: + inode->i_size += 1; + break; + case 4: + inode->i_size += 2; + break; + case 8: + rootflag = 1; + inode->i_size += 1; + break; + default: + printk + ("Symlink component flag not implemented\n"); + } + slen -= slp->len + 2; + oldslp = slp; + slp = + (struct SL_component + *)(((char *)slp) + + slp->len + 2); + + if (slen < 2) { + if (((rr->u.SL. + flags & 1) != 0) + && + ((oldslp-> + flags & 1) == 0)) + inode->i_size += + 1; + break; + } + + /* + * If this component record isn't continued, then append a '/'. + */ + if (!rootflag + && (oldslp->flags & 1) == 0) + inode->i_size += 1; + } + } + symlink_len = inode->i_size; + break; + case SIG('R', 'E'): + printk(KERN_WARNING + "Attempt to read inode for relocated directory\n"); + goto out; + case SIG('C', 'L'): + ISOFS_I(inode)->i_first_extent = + isonum_733(rr->u.CL.location); + reloc = + isofs_iget(inode->i_sb, + ISOFS_I(inode)->i_first_extent, + 0); + if (!reloc) + goto out; + inode->i_mode = reloc->i_mode; + inode->i_nlink = reloc->i_nlink; + inode->i_uid = reloc->i_uid; + inode->i_gid = reloc->i_gid; + inode->i_rdev = reloc->i_rdev; + inode->i_size = reloc->i_size; + inode->i_blocks = reloc->i_blocks; + inode->i_atime = reloc->i_atime; + inode->i_ctime = reloc->i_ctime; + inode->i_mtime = reloc->i_mtime; + iput(reloc); + break; #ifdef CONFIG_ZISOFS - case SIG('Z','F'): - if ( !ISOFS_SB(inode->i_sb)->s_nocompress ) { - int algo; - algo = isonum_721(rr->u.ZF.algorithm); - if ( algo == SIG('p','z') ) { - int block_shift = isonum_711(&rr->u.ZF.parms[1]); - if ( block_shift < PAGE_CACHE_SHIFT || block_shift > 17 ) { - printk(KERN_WARNING "isofs: Can't handle ZF block size of 2^%d\n", block_shift); - } else { - /* Note: we don't change i_blocks here */ - ISOFS_I(inode)->i_file_format = isofs_file_compressed; - /* Parameters to compression algorithm (header size, block size) */ - ISOFS_I(inode)->i_format_parm[0] = isonum_711(&rr->u.ZF.parms[0]); - ISOFS_I(inode)->i_format_parm[1] = isonum_711(&rr->u.ZF.parms[1]); - inode->i_size = isonum_733(rr->u.ZF.real_size); - } - } else { - printk(KERN_WARNING "isofs: Unknown ZF compression algorithm: %c%c\n", - rr->u.ZF.algorithm[0], rr->u.ZF.algorithm[1]); - } - } - break; + case SIG('Z', 'F'): + if (!ISOFS_SB(inode->i_sb)->s_nocompress) { + int algo; + algo = isonum_721(rr->u.ZF.algorithm); + if (algo == SIG('p', 'z')) { + int block_shift = + isonum_711(&rr->u.ZF. + parms[1]); + if (block_shift < + PAGE_CACHE_SHIFT + || block_shift > 17) { + printk(KERN_WARNING + "isofs: Can't handle ZF block size of 2^%d\n", + block_shift); + } else { + /* Note: we don't change i_blocks here */ + ISOFS_I(inode)-> + i_file_format = + isofs_file_compressed; + /* Parameters to compression algorithm (header size, block size) */ + ISOFS_I(inode)-> + i_format_parm[0] = + isonum_711(&rr->u. + ZF. + parms + [0]); + ISOFS_I(inode)-> + i_format_parm[1] = + isonum_711(&rr->u. + ZF. + parms + [1]); + inode->i_size = + isonum_733(rr->u.ZF. + real_size); + } + } else { + printk(KERN_WARNING + "isofs: Unknown ZF compression algorithm: %c%c\n", + rr->u.ZF.algorithm[0], + rr->u.ZF.algorithm[1]); + } + } + break; #endif - default: - break; - } - } - } - MAYBE_CONTINUE(repeat,inode); - out: - if(buffer) kfree(buffer); - return 0; + default: + break; + } + } + } + MAYBE_CONTINUE(repeat, inode); + out: + if (buffer) + kfree(buffer); + return 0; } static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit) @@ -376,32 +443,32 @@ static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit) if (slp->len > plimit - rpnt) return NULL; memcpy(rpnt, slp->text, slp->len); - rpnt+=slp->len; + rpnt += slp->len; break; case 2: if (rpnt >= plimit) return NULL; - *rpnt++='.'; + *rpnt++ = '.'; break; case 4: if (2 > plimit - rpnt) return NULL; - *rpnt++='.'; - *rpnt++='.'; + *rpnt++ = '.'; + *rpnt++ = '.'; break; case 8: if (rpnt >= plimit) return NULL; rootflag = 1; - *rpnt++='/'; + *rpnt++ = '/'; break; default: printk("Symlink component flag not implemented (%d)\n", - slp->flags); + slp->flags); } slen -= slp->len + 2; oldslp = slp; - slp = (struct SL_component *) ((char *) slp + slp->len + 2); + slp = (struct SL_component *)((char *)slp + slp->len + 2); if (slen < 2) { /* @@ -412,7 +479,7 @@ static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit) !(oldslp->flags & 1)) { if (rpnt >= plimit) return NULL; - *rpnt++='/'; + *rpnt++ = '/'; } break; } @@ -423,24 +490,22 @@ static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit) if (!rootflag && !(oldslp->flags & 1)) { if (rpnt >= plimit) return NULL; - *rpnt++='/'; + *rpnt++ = '/'; } } return rpnt; } -int parse_rock_ridge_inode(struct iso_directory_record * de, - struct inode * inode) +int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode) { - int result=parse_rock_ridge_inode_internal(de,inode,0); - /* if rockridge flag was reset and we didn't look for attributes - * behind eventual XA attributes, have a look there */ - if ((ISOFS_SB(inode->i_sb)->s_rock_offset==-1) - &&(ISOFS_SB(inode->i_sb)->s_rock==2)) - { - result=parse_rock_ridge_inode_internal(de,inode,14); - } - return result; + int result = parse_rock_ridge_inode_internal(de, inode, 0); + /* if rockridge flag was reset and we didn't look for attributes + * behind eventual XA attributes, have a look there */ + if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1) + && (ISOFS_SB(inode->i_sb)->s_rock == 2)) { + result = parse_rock_ridge_inode_internal(de, inode, 14); + } + return result; } /* readpage() for symlinks: reads symlink contents into the page and either @@ -449,7 +514,7 @@ int parse_rock_ridge_inode(struct iso_directory_record * de, static int rock_ridge_symlink_readpage(struct file *file, struct page *page) { struct inode *inode = page->mapping->host; - struct iso_inode_info *ei = ISOFS_I(inode); + struct iso_inode_info *ei = ISOFS_I(inode); char *link = kmap(page); unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); struct buffer_head *bh; @@ -472,10 +537,10 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) if (!bh) goto out_noread; - offset = ei->i_iget5_offset; - pnt = (unsigned char *) bh->b_data + offset; + offset = ei->i_iget5_offset; + pnt = (unsigned char *)bh->b_data + offset; - raw_inode = (struct iso_directory_record *) pnt; + raw_inode = (struct iso_directory_record *)pnt; /* * If we go past the end of the buffer, there is some sort of error. @@ -489,8 +554,8 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) SETUP_ROCK_RIDGE(raw_inode, chr, len); repeat: - while (len > 2) { /* There may be one byte for padding somewhere */ - rr = (struct rock_ridge *) chr; + while (len > 2) { /* There may be one byte for padding somewhere */ + rr = (struct rock_ridge *)chr; if (rr->len < 3) goto out; /* Something got screwed up here */ sig = isonum_721(chr); @@ -555,5 +620,5 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) } struct address_space_operations isofs_symlink_aops = { - .readpage = rock_ridge_symlink_readpage + .readpage = rock_ridge_symlink_readpage }; -- cgit v1.2.3-59-g8ed1b From 7fa393a1d3d9485e428a3c74b5599190c14b13db Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 21 Jun 2005 17:16:43 -0700 Subject: [PATCH] rock: manual tidies Fix stuff which Lindent got wrong, rework a few deeply-nested blocks. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/isofs/rock.c | 571 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 285 insertions(+), 286 deletions(-) diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index bbc348f0189a..e981c040a49b 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -90,82 +90,78 @@ int get_rock_ridge_filename(struct iso_directory_record *de, int len; unsigned char *chr; CONTINUE_DECLS; - int retnamlen = 0, truncate = 0; + struct rock_ridge *rr; + int sig; + int retnamlen = 0; + int truncate = 0; if (!ISOFS_SB(inode->i_sb)->s_rock) return 0; *retname = 0; SETUP_ROCK_RIDGE(de, chr, len); - repeat: - { - struct rock_ridge *rr; - int sig; - - while (len > 2) { /* There may be one byte for padding somewhere */ - rr = (struct rock_ridge *)chr; - if (rr->len < 3) - goto out; /* Something got screwed up here */ - sig = isonum_721(chr); - chr += rr->len; - len -= rr->len; - if (len < 0) - goto out; /* corrupted isofs */ - - switch (sig) { - case SIG('R', 'R'): - if ((rr->u.RR.flags[0] & RR_NM) == 0) - goto out; +repeat: + + while (len > 2) { /* There may be one byte for padding somewhere */ + rr = (struct rock_ridge *)chr; + if (rr->len < 3) + goto out; /* Something got screwed up here */ + sig = isonum_721(chr); + chr += rr->len; + len -= rr->len; + if (len < 0) + goto out; /* corrupted isofs */ + + switch (sig) { + case SIG('R', 'R'): + if ((rr->u.RR.flags[0] & RR_NM) == 0) + goto out; + break; + case SIG('S', 'P'): + CHECK_SP(goto out); + break; + case SIG('C', 'E'): + CHECK_CE; + break; + case SIG('N', 'M'): + if (truncate) break; - case SIG('S', 'P'): - CHECK_SP(goto out); + if (rr->len < 5) break; - case SIG('C', 'E'): - CHECK_CE; + /* + * If the flags are 2 or 4, this indicates '.' or '..'. + * We don't want to do anything with this, because it + * screws up the code that calls us. We don't really + * care anyways, since we can just use the non-RR + * name. + */ + if (rr->u.NM.flags & 6) break; - case SIG('N', 'M'): - if (truncate) - break; - if (rr->len < 5) - break; - /* - * If the flags are 2 or 4, this indicates '.' or '..'. - * We don't want to do anything with this, because it - * screws up the code that calls us. We don't really - * care anyways, since we can just use the non-RR - * name. - */ - if (rr->u.NM.flags & 6) { - break; - } - if (rr->u.NM.flags & ~1) { - printk - ("Unsupported NM flag settings (%d)\n", - rr->u.NM.flags); - break; - } - if ((strlen(retname) + rr->len - 5) >= 254) { - truncate = 1; - break; - } - strncat(retname, rr->u.NM.name, rr->len - 5); - retnamlen += rr->len - 5; + if (rr->u.NM.flags & ~1) { + printk("Unsupported NM flag settings (%d)\n", + rr->u.NM.flags); break; - case SIG('R', 'E'): - if (buffer) - kfree(buffer); - return -1; - default: + } + if ((strlen(retname) + rr->len - 5) >= 254) { + truncate = 1; break; } + strncat(retname, rr->u.NM.name, rr->len - 5); + retnamlen += rr->len - 5; + break; + case SIG('R', 'E'): + if (buffer) + kfree(buffer); + return -1; + default: + break; } } MAYBE_CONTINUE(repeat, inode); - if (buffer) - kfree(buffer); + kfree(buffer); return retnamlen; /* If 0, this file did not have a NM field */ - out: +out: if (buffer) kfree(buffer); return 0; @@ -178,6 +174,11 @@ parse_rock_ridge_inode_internal(struct iso_directory_record *de, int len; unsigned char *chr; int symlink_len = 0; + int cnt, sig; + struct inode *reloc; + struct rock_ridge *rr; + int rootflag; + CONTINUE_DECLS; if (!ISOFS_SB(inode->i_sb)->s_rock) @@ -191,238 +192,237 @@ parse_rock_ridge_inode_internal(struct iso_directory_record *de, len = 0; } - repeat: - { - int cnt, sig; - struct inode *reloc; - struct rock_ridge *rr; - int rootflag; - - while (len > 2) { /* There may be one byte for padding somewhere */ - rr = (struct rock_ridge *)chr; - if (rr->len < 3) - goto out; /* Something got screwed up here */ - sig = isonum_721(chr); - chr += rr->len; - len -= rr->len; - if (len < 0) - goto out; /* corrupted isofs */ - - switch (sig) { +repeat: + while (len > 2) { /* There may be one byte for padding somewhere */ + rr = (struct rock_ridge *)chr; + if (rr->len < 3) + goto out; /* Something got screwed up here */ + sig = isonum_721(chr); + chr += rr->len; + len -= rr->len; + if (len < 0) + goto out; /* corrupted isofs */ + + switch (sig) { #ifndef CONFIG_ZISOFS /* No flag for SF or ZF */ - case SIG('R', 'R'): - if ((rr->u.RR.flags[0] & - (RR_PX | RR_TF | RR_SL | RR_CL)) == 0) - goto out; - break; + case SIG('R', 'R'): + if ((rr->u.RR.flags[0] & + (RR_PX | RR_TF | RR_SL | RR_CL)) == 0) + goto out; + break; #endif - case SIG('S', 'P'): - CHECK_SP(goto out); - break; - case SIG('C', 'E'): - CHECK_CE; - break; - case SIG('E', 'R'): - ISOFS_SB(inode->i_sb)->s_rock = 1; - printk(KERN_DEBUG "ISO 9660 Extensions: "); - { - int p; - for (p = 0; p < rr->u.ER.len_id; p++) - printk("%c", rr->u.ER.data[p]); + case SIG('S', 'P'): + CHECK_SP(goto out); + break; + case SIG('C', 'E'): + CHECK_CE; + break; + case SIG('E', 'R'): + ISOFS_SB(inode->i_sb)->s_rock = 1; + printk(KERN_DEBUG "ISO 9660 Extensions: "); + { + int p; + for (p = 0; p < rr->u.ER.len_id; p++) + printk("%c", rr->u.ER.data[p]); + } + printk("\n"); + break; + case SIG('P', 'X'): + inode->i_mode = isonum_733(rr->u.PX.mode); + inode->i_nlink = isonum_733(rr->u.PX.n_links); + inode->i_uid = isonum_733(rr->u.PX.uid); + inode->i_gid = isonum_733(rr->u.PX.gid); + break; + case SIG('P', 'N'): + { + int high, low; + high = isonum_733(rr->u.PN.dev_high); + low = isonum_733(rr->u.PN.dev_low); + /* + * The Rock Ridge standard specifies that if + * sizeof(dev_t) <= 4, then the high field is + * unused, and the device number is completely + * stored in the low field. Some writers may + * ignore this subtlety, + * and as a result we test to see if the entire + * device number is + * stored in the low field, and use that. + */ + if ((low & ~0xff) && high == 0) { + inode->i_rdev = + MKDEV(low >> 8, low & 0xff); + } else { + inode->i_rdev = + MKDEV(high, low); } - printk("\n"); - break; - case SIG('P', 'X'): - inode->i_mode = isonum_733(rr->u.PX.mode); - inode->i_nlink = isonum_733(rr->u.PX.n_links); - inode->i_uid = isonum_733(rr->u.PX.uid); - inode->i_gid = isonum_733(rr->u.PX.gid); - break; - case SIG('P', 'N'): - { - int high, low; - high = isonum_733(rr->u.PN.dev_high); - low = isonum_733(rr->u.PN.dev_low); - /* - * The Rock Ridge standard specifies that if sizeof(dev_t) <= 4, - * then the high field is unused, and the device number is completely - * stored in the low field. Some writers may ignore this subtlety, - * and as a result we test to see if the entire device number is - * stored in the low field, and use that. - */ - if ((low & ~0xff) && high == 0) { - inode->i_rdev = - MKDEV(low >> 8, low & 0xff); - } else { - inode->i_rdev = - MKDEV(high, low); + } + break; + case SIG('T', 'F'): + /* + * Some RRIP writers incorrectly place ctime in the + * TF_CREATE field. Try to handle this correctly for + * either case. + */ + /* Rock ridge never appears on a High Sierra disk */ + cnt = 0; + if (rr->u.TF.flags & TF_CREATE) { + inode->i_ctime.tv_sec = + iso_date(rr->u.TF.times[cnt++].time, + 0); + inode->i_ctime.tv_nsec = 0; + } + if (rr->u.TF.flags & TF_MODIFY) { + inode->i_mtime.tv_sec = + iso_date(rr->u.TF.times[cnt++].time, + 0); + inode->i_mtime.tv_nsec = 0; + } + if (rr->u.TF.flags & TF_ACCESS) { + inode->i_atime.tv_sec = + iso_date(rr->u.TF.times[cnt++].time, + 0); + inode->i_atime.tv_nsec = 0; + } + if (rr->u.TF.flags & TF_ATTRIBUTES) { + inode->i_ctime.tv_sec = + iso_date(rr->u.TF.times[cnt++].time, + 0); + inode->i_ctime.tv_nsec = 0; + } + break; + case SIG('S', 'L'): + { + int slen; + struct SL_component *slp; + struct SL_component *oldslp; + slen = rr->len - 5; + slp = &rr->u.SL.link; + inode->i_size = symlink_len; + while (slen > 1) { + rootflag = 0; + switch (slp->flags & ~1) { + case 0: + inode->i_size += + slp->len; + break; + case 2: + inode->i_size += 1; + break; + case 4: + inode->i_size += 2; + break; + case 8: + rootflag = 1; + inode->i_size += 1; + break; + default: + printk("Symlink component flag " + "not implemented\n"); } - } - break; - case SIG('T', 'F'): - /* Some RRIP writers incorrectly place ctime in the TF_CREATE field. - Try to handle this correctly for either case. */ - cnt = 0; /* Rock ridge never appears on a High Sierra disk */ - if (rr->u.TF.flags & TF_CREATE) { - inode->i_ctime.tv_sec = - iso_date(rr->u.TF.times[cnt++].time, - 0); - inode->i_ctime.tv_nsec = 0; - } - if (rr->u.TF.flags & TF_MODIFY) { - inode->i_mtime.tv_sec = - iso_date(rr->u.TF.times[cnt++].time, - 0); - inode->i_mtime.tv_nsec = 0; - } - if (rr->u.TF.flags & TF_ACCESS) { - inode->i_atime.tv_sec = - iso_date(rr->u.TF.times[cnt++].time, - 0); - inode->i_atime.tv_nsec = 0; - } - if (rr->u.TF.flags & TF_ATTRIBUTES) { - inode->i_ctime.tv_sec = - iso_date(rr->u.TF.times[cnt++].time, - 0); - inode->i_ctime.tv_nsec = 0; - } - break; - case SIG('S', 'L'): - { - int slen; - struct SL_component *slp; - struct SL_component *oldslp; - slen = rr->len - 5; - slp = &rr->u.SL.link; - inode->i_size = symlink_len; - while (slen > 1) { - rootflag = 0; - switch (slp->flags & ~1) { - case 0: + slen -= slp->len + 2; + oldslp = slp; + slp = (struct SL_component *) + (((char *)slp) + slp->len + 2); + + if (slen < 2) { + if (((rr->u.SL. + flags & 1) != 0) + && + ((oldslp-> + flags & 1) == 0)) inode->i_size += - slp->len; - break; - case 2: - inode->i_size += 1; - break; - case 4: - inode->i_size += 2; - break; - case 8: - rootflag = 1; - inode->i_size += 1; - break; - default: - printk - ("Symlink component flag not implemented\n"); - } - slen -= slp->len + 2; - oldslp = slp; - slp = - (struct SL_component - *)(((char *)slp) + - slp->len + 2); - - if (slen < 2) { - if (((rr->u.SL. - flags & 1) != 0) - && - ((oldslp-> - flags & 1) == 0)) - inode->i_size += - 1; - break; - } - - /* - * If this component record isn't continued, then append a '/'. - */ - if (!rootflag - && (oldslp->flags & 1) == 0) - inode->i_size += 1; + 1; + break; } + + /* + * If this component record isn't + * continued, then append a '/'. + */ + if (!rootflag + && (oldslp->flags & 1) == 0) + inode->i_size += 1; } - symlink_len = inode->i_size; - break; - case SIG('R', 'E'): - printk(KERN_WARNING - "Attempt to read inode for relocated directory\n"); + } + symlink_len = inode->i_size; + break; + case SIG('R', 'E'): + printk(KERN_WARNING "Attempt to read inode for " + "relocated directory\n"); + goto out; + case SIG('C', 'L'): + ISOFS_I(inode)->i_first_extent = + isonum_733(rr->u.CL.location); + reloc = + isofs_iget(inode->i_sb, + ISOFS_I(inode)->i_first_extent, + 0); + if (!reloc) goto out; - case SIG('C', 'L'): - ISOFS_I(inode)->i_first_extent = - isonum_733(rr->u.CL.location); - reloc = - isofs_iget(inode->i_sb, - ISOFS_I(inode)->i_first_extent, - 0); - if (!reloc) - goto out; - inode->i_mode = reloc->i_mode; - inode->i_nlink = reloc->i_nlink; - inode->i_uid = reloc->i_uid; - inode->i_gid = reloc->i_gid; - inode->i_rdev = reloc->i_rdev; - inode->i_size = reloc->i_size; - inode->i_blocks = reloc->i_blocks; - inode->i_atime = reloc->i_atime; - inode->i_ctime = reloc->i_ctime; - inode->i_mtime = reloc->i_mtime; - iput(reloc); - break; + inode->i_mode = reloc->i_mode; + inode->i_nlink = reloc->i_nlink; + inode->i_uid = reloc->i_uid; + inode->i_gid = reloc->i_gid; + inode->i_rdev = reloc->i_rdev; + inode->i_size = reloc->i_size; + inode->i_blocks = reloc->i_blocks; + inode->i_atime = reloc->i_atime; + inode->i_ctime = reloc->i_ctime; + inode->i_mtime = reloc->i_mtime; + iput(reloc); + break; #ifdef CONFIG_ZISOFS - case SIG('Z', 'F'): - if (!ISOFS_SB(inode->i_sb)->s_nocompress) { - int algo; - algo = isonum_721(rr->u.ZF.algorithm); - if (algo == SIG('p', 'z')) { - int block_shift = - isonum_711(&rr->u.ZF. - parms[1]); - if (block_shift < - PAGE_CACHE_SHIFT - || block_shift > 17) { - printk(KERN_WARNING - "isofs: Can't handle ZF block size of 2^%d\n", - block_shift); - } else { - /* Note: we don't change i_blocks here */ - ISOFS_I(inode)-> - i_file_format = - isofs_file_compressed; - /* Parameters to compression algorithm (header size, block size) */ - ISOFS_I(inode)-> - i_format_parm[0] = - isonum_711(&rr->u. - ZF. - parms - [0]); - ISOFS_I(inode)-> - i_format_parm[1] = - isonum_711(&rr->u. - ZF. - parms - [1]); - inode->i_size = - isonum_733(rr->u.ZF. - real_size); - } - } else { - printk(KERN_WARNING - "isofs: Unknown ZF compression algorithm: %c%c\n", - rr->u.ZF.algorithm[0], - rr->u.ZF.algorithm[1]); - } - } - break; -#endif - default: + case SIG('Z', 'F'): { + int algo; + + if (ISOFS_SB(inode->i_sb)->s_nocompress) break; + algo = isonum_721(rr->u.ZF.algorithm); + if (algo == SIG('p', 'z')) { + int block_shift = + isonum_711(&rr->u.ZF.parms[1]); + if (block_shift < PAGE_CACHE_SHIFT + || block_shift > 17) { + printk(KERN_WARNING "isofs: " + "Can't handle ZF block " + "size of 2^%d\n", + block_shift); + } else { + /* + * Note: we don't change + * i_blocks here + */ + ISOFS_I(inode)->i_file_format = + isofs_file_compressed; + /* + * Parameters to compression + * algorithm (header size, + * block size) + */ + ISOFS_I(inode)->i_format_parm[0] = + isonum_711(&rr->u.ZF.parms[0]); + ISOFS_I(inode)->i_format_parm[1] = + isonum_711(&rr->u.ZF.parms[1]); + inode->i_size = + isonum_733(rr->u.ZF. + real_size); + } + } else { + printk(KERN_WARNING + "isofs: Unknown ZF compression " + "algorithm: %c%c\n", + rr->u.ZF.algorithm[0], + rr->u.ZF.algorithm[1]); } + break; + } +#endif + default: + break; } } MAYBE_CONTINUE(repeat, inode); - out: +out: if (buffer) kfree(buffer); return 0; @@ -553,8 +553,8 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) SETUP_ROCK_RIDGE(raw_inode, chr, len); - repeat: - while (len > 2) { /* There may be one byte for padding somewhere */ +repeat: + while (len > 2) { /* There may be one byte for padding somewhere */ rr = (struct rock_ridge *)chr; if (rr->len < 3) goto out; /* Something got screwed up here */ @@ -586,8 +586,7 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) } } MAYBE_CONTINUE(repeat, inode); - if (buffer) - kfree(buffer); + kfree(buffer); if (rpnt == link) goto fail; @@ -600,19 +599,19 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) return 0; /* error exit from macro */ - out: +out: if (buffer) kfree(buffer); goto fail; - out_noread: +out_noread: printk("unable to read i-node block"); goto fail; - out_bad_span: +out_bad_span: printk("symlink spans iso9660 blocks\n"); - fail: +fail: brelse(bh); unlock_kernel(); - error: +error: SetPageError(page); kunmap(page); unlock_page(page); -- cgit v1.2.3-59-g8ed1b From 12121714fbf36023d5892034d0c97df54a451543 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 21 Jun 2005 17:16:44 -0700 Subject: [PATCH] rock: remove CHECK_SP Remove the CHECK_SP macro. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/isofs/rock.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index e981c040a49b..8497c6bd5678 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -22,12 +22,21 @@ #define SIG(A,B) ((A) | ((B) << 8)) /* isonum_721() */ -/* This is a way of ensuring that we have something in the system - use fields that is compatible with Rock Ridge */ -#define CHECK_SP(FAIL) \ - if(rr->u.SP.magic[0] != 0xbe) FAIL; \ - if(rr->u.SP.magic[1] != 0xef) FAIL; \ - ISOFS_SB(inode->i_sb)->s_rock_offset=rr->u.SP.skip; +/* + * This is a way of ensuring that we have something in the system + * use fields that is compatible with Rock Ridge. Return zero on success. + */ + +static int check_sp(struct rock_ridge *rr, struct inode *inode) +{ + if (rr->u.SP.magic[0] != 0xbe) + return -1; + if (rr->u.SP.magic[1] != 0xef) + return -1; + ISOFS_SB(inode->i_sb)->s_rock_offset = rr->u.SP.skip; + return 0; +} + /* We define a series of macros because each function must do exactly the same thing in certain places. We use the macros to ensure that everything is done correctly */ @@ -118,7 +127,8 @@ repeat: goto out; break; case SIG('S', 'P'): - CHECK_SP(goto out); + if (check_sp(rr, inode)) + goto out; break; case SIG('C', 'E'): CHECK_CE; @@ -212,7 +222,8 @@ repeat: break; #endif case SIG('S', 'P'): - CHECK_SP(goto out); + if (check_sp(rr, inode)) + goto out; break; case SIG('C', 'E'): CHECK_CE; @@ -570,7 +581,8 @@ repeat: goto out; break; case SIG('S', 'P'): - CHECK_SP(goto out); + if (check_sp(rr, inode)) + goto out; break; case SIG('S', 'L'): rpnt = get_symlink_chunk(rpnt, rr, -- cgit v1.2.3-59-g8ed1b From a40ea8f22e59c038ffdf219251a67311b9f6e362 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 21 Jun 2005 17:16:44 -0700 Subject: [PATCH] rock: remove CONTINUE_DECLS Remove the CONTINUE_DECLS macro. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/isofs/rock.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index 8497c6bd5678..9f2aaa27f8fa 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -37,14 +37,6 @@ static int check_sp(struct rock_ridge *rr, struct inode *inode) return 0; } -/* We define a series of macros because each function must do exactly the - same thing in certain places. We use the macros to ensure that everything - is done correctly */ - -#define CONTINUE_DECLS \ - int cont_extent = 0, cont_offset = 0, cont_size = 0; \ - void *buffer = NULL - #define CHECK_CE \ {cont_extent = isonum_733(rr->u.CE.extent); \ cont_offset = isonum_733(rr->u.CE.offset); \ @@ -98,7 +90,10 @@ int get_rock_ridge_filename(struct iso_directory_record *de, { int len; unsigned char *chr; - CONTINUE_DECLS; + int cont_extent = 0; + int cont_offset = 0; + int cont_size = 0; + void *buffer = NULL; struct rock_ridge *rr; int sig; int retnamlen = 0; @@ -188,8 +183,10 @@ parse_rock_ridge_inode_internal(struct iso_directory_record *de, struct inode *reloc; struct rock_ridge *rr; int rootflag; - - CONTINUE_DECLS; + int cont_extent = 0; + int cont_offset = 0; + int cont_size = 0; + void *buffer = NULL; if (!ISOFS_SB(inode->i_sb)->s_rock) return 0; @@ -532,7 +529,10 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) char *rpnt = link; unsigned char *pnt; struct iso_directory_record *raw_inode; - CONTINUE_DECLS; + int cont_extent = 0; + int cont_offset = 0; + int cont_size = 0; + void *buffer = NULL; unsigned long block, offset; int sig; int len; -- cgit v1.2.3-59-g8ed1b From 04f7aa9c7dc615c690cede9a80c83625ad2efef7 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 21 Jun 2005 17:16:45 -0700 Subject: [PATCH] rock: remove CHECK_CE Remove the CHECK_CE macro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/isofs/rock.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index 9f2aaa27f8fa..283e92197bb1 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -37,11 +37,6 @@ static int check_sp(struct rock_ridge *rr, struct inode *inode) return 0; } -#define CHECK_CE \ - {cont_extent = isonum_733(rr->u.CE.extent); \ - cont_offset = isonum_733(rr->u.CE.offset); \ - cont_size = isonum_733(rr->u.CE.size);} - #define SETUP_ROCK_RIDGE(DE,CHR,LEN) \ {LEN= sizeof(struct iso_directory_record) + DE->name_len[0]; \ if(LEN & 1) LEN++; \ @@ -126,7 +121,9 @@ repeat: goto out; break; case SIG('C', 'E'): - CHECK_CE; + cont_extent = isonum_733(rr->u.CE.extent); + cont_offset = isonum_733(rr->u.CE.offset); + cont_size = isonum_733(rr->u.CE.size); break; case SIG('N', 'M'): if (truncate) @@ -223,7 +220,9 @@ repeat: goto out; break; case SIG('C', 'E'): - CHECK_CE; + cont_extent = isonum_733(rr->u.CE.extent); + cont_offset = isonum_733(rr->u.CE.offset); + cont_size = isonum_733(rr->u.CE.size); break; case SIG('E', 'R'): ISOFS_SB(inode->i_sb)->s_rock = 1; @@ -592,7 +591,9 @@ repeat: break; case SIG('C', 'E'): /* This tells is if there is a continuation record */ - CHECK_CE; + cont_extent = isonum_733(rr->u.CE.extent); + cont_offset = isonum_733(rr->u.CE.offset); + cont_size = isonum_733(rr->u.CE.size); default: break; } -- cgit v1.2.3-59-g8ed1b From 76ab07ebc3ca69e2f14ccbed0de3a9dda9adc6da Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 21 Jun 2005 17:16:46 -0700 Subject: [PATCH] rock: remove SETUP_ROCK_RIDGE - Remove the SETUP_ROCK_RIDGE macro. - In rock_ridge_symlink_readpage(), rename raw_inode to raw_de. It points at a directory entry, not an inode. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/isofs/rock.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index 283e92197bb1..aafe356ec1b7 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -37,18 +37,23 @@ static int check_sp(struct rock_ridge *rr, struct inode *inode) return 0; } -#define SETUP_ROCK_RIDGE(DE,CHR,LEN) \ - {LEN= sizeof(struct iso_directory_record) + DE->name_len[0]; \ - if(LEN & 1) LEN++; \ - CHR = ((unsigned char *) DE) + LEN; \ - LEN = *((unsigned char *) DE) - LEN; \ - if (LEN<0) LEN=0; \ - if (ISOFS_SB(inode->i_sb)->s_rock_offset!=-1) \ - { \ - LEN-=ISOFS_SB(inode->i_sb)->s_rock_offset; \ - CHR+=ISOFS_SB(inode->i_sb)->s_rock_offset; \ - if (LEN<0) LEN=0; \ - } \ +static void setup_rock_ridge(struct iso_directory_record *de, + struct inode *inode, unsigned char **chr, int *len) +{ + *len = sizeof(struct iso_directory_record) + de->name_len[0]; + if (*len & 1) + (*len)++; + *chr = (unsigned char *)de + *len; + *len = *((unsigned char *)de) - *len; + if (*len < 0) + *len = 0; + + if (ISOFS_SB(inode->i_sb)->s_rock_offset != -1) { + *len -= ISOFS_SB(inode->i_sb)->s_rock_offset; + *chr += ISOFS_SB(inode->i_sb)->s_rock_offset; + if (*len < 0) + *len = 0; + } } #define MAYBE_CONTINUE(LABEL,DEV) \ @@ -98,7 +103,7 @@ int get_rock_ridge_filename(struct iso_directory_record *de, return 0; *retname = 0; - SETUP_ROCK_RIDGE(de, chr, len); + setup_rock_ridge(de, inode, &chr, &len); repeat: while (len > 2) { /* There may be one byte for padding somewhere */ @@ -188,7 +193,7 @@ parse_rock_ridge_inode_internal(struct iso_directory_record *de, if (!ISOFS_SB(inode->i_sb)->s_rock) return 0; - SETUP_ROCK_RIDGE(de, chr, len); + setup_rock_ridge(de, inode, &chr, &len); if (regard_xa) { chr += 14; len -= 14; @@ -527,7 +532,7 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) struct buffer_head *bh; char *rpnt = link; unsigned char *pnt; - struct iso_directory_record *raw_inode; + struct iso_directory_record *raw_de; int cont_extent = 0; int cont_offset = 0; int cont_size = 0; @@ -550,7 +555,7 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) offset = ei->i_iget5_offset; pnt = (unsigned char *)bh->b_data + offset; - raw_inode = (struct iso_directory_record *)pnt; + raw_de = (struct iso_directory_record *)pnt; /* * If we go past the end of the buffer, there is some sort of error. @@ -561,7 +566,7 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) /* Now test for possible Rock Ridge extensions which will override some of these numbers in the inode structure. */ - SETUP_ROCK_RIDGE(raw_inode, chr, len); + setup_rock_ridge(raw_de, inode, &chr, &len); repeat: while (len > 2) { /* There may be one byte for padding somewhere */ -- cgit v1.2.3-59-g8ed1b From ba40aaf04314ec5efd090e69518033fc55f450fa Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 21 Jun 2005 17:16:46 -0700 Subject: [PATCH] rock: remove MAYBE_CONTINUE - remove the MAYBE_CONTINUE macro - kfree(NULL) is OK. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/isofs/rock.c | 237 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 130 insertions(+), 107 deletions(-) diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index aafe356ec1b7..efefbcce4ce9 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -22,6 +22,16 @@ #define SIG(A,B) ((A) | ((B) << 8)) /* isonum_721() */ +struct rock_state { + void *buffer; + unsigned char *chr; + int len; + int cont_size; + int cont_extent; + int cont_offset; + struct inode *inode; +}; + /* * This is a way of ensuring that we have something in the system * use fields that is compatible with Rock Ridge. Return zero on success. @@ -38,82 +48,96 @@ static int check_sp(struct rock_ridge *rr, struct inode *inode) } static void setup_rock_ridge(struct iso_directory_record *de, - struct inode *inode, unsigned char **chr, int *len) + struct inode *inode, struct rock_state *rs) { - *len = sizeof(struct iso_directory_record) + de->name_len[0]; - if (*len & 1) - (*len)++; - *chr = (unsigned char *)de + *len; - *len = *((unsigned char *)de) - *len; - if (*len < 0) - *len = 0; + rs->len = sizeof(struct iso_directory_record) + de->name_len[0]; + if (rs->len & 1) + (rs->len)++; + rs->chr = (unsigned char *)de + rs->len; + rs->len = *((unsigned char *)de) - rs->len; + if (rs->len < 0) + rs->len = 0; if (ISOFS_SB(inode->i_sb)->s_rock_offset != -1) { - *len -= ISOFS_SB(inode->i_sb)->s_rock_offset; - *chr += ISOFS_SB(inode->i_sb)->s_rock_offset; - if (*len < 0) - *len = 0; + rs->len -= ISOFS_SB(inode->i_sb)->s_rock_offset; + rs->chr += ISOFS_SB(inode->i_sb)->s_rock_offset; + if (rs->len < 0) + rs->len = 0; } } -#define MAYBE_CONTINUE(LABEL,DEV) \ - {if (buffer) { kfree(buffer); buffer = NULL; } \ - if (cont_extent){ \ - int block, offset, offset1; \ - struct buffer_head * pbh; \ - buffer = kmalloc(cont_size,GFP_KERNEL); \ - if (!buffer) goto out; \ - block = cont_extent; \ - offset = cont_offset; \ - offset1 = 0; \ - pbh = sb_bread(DEV->i_sb, block); \ - if(pbh){ \ - if (offset > pbh->b_size || offset + cont_size > pbh->b_size){ \ - brelse(pbh); \ - goto out; \ - } \ - memcpy(buffer + offset1, pbh->b_data + offset, cont_size - offset1); \ - brelse(pbh); \ - chr = (unsigned char *) buffer; \ - len = cont_size; \ - cont_extent = 0; \ - cont_size = 0; \ - cont_offset = 0; \ - goto LABEL; \ - } \ - printk("Unable to read rock-ridge attributes\n"); \ - }} +static void init_rock_state(struct rock_state *rs, struct inode *inode) +{ + memset(rs, 0, sizeof(*rs)); + rs->inode = inode; +} + +/* + * Returns 0 if the caller should continue scanning, 1 if the scan must end + * and -ve on error. + */ +static int rock_continue(struct rock_state *rs) +{ + int ret = 1; + + kfree(rs->buffer); + rs->buffer = NULL; + if (rs->cont_extent) { + struct buffer_head *bh; + + rs->buffer = kmalloc(rs->cont_size, GFP_KERNEL); + if (!rs->buffer) { + ret = -ENOMEM; + goto out; + } + ret = -EIO; + bh = sb_bread(rs->inode->i_sb, rs->cont_extent); + if (bh) { + memcpy(rs->buffer, bh->b_data + rs->cont_offset, + rs->cont_size); + put_bh(bh); + rs->chr = rs->buffer; + rs->len = rs->cont_size; + rs->cont_extent = 0; + rs->cont_size = 0; + rs->cont_offset = 0; + return 0; + } + printk("Unable to read rock-ridge attributes\n"); + } +out: + kfree(rs->buffer); + rs->buffer = NULL; + return ret; +} /* return length of name field; 0: not found, -1: to be ignored */ int get_rock_ridge_filename(struct iso_directory_record *de, char *retname, struct inode *inode) { - int len; - unsigned char *chr; - int cont_extent = 0; - int cont_offset = 0; - int cont_size = 0; - void *buffer = NULL; + struct rock_state rs; struct rock_ridge *rr; int sig; int retnamlen = 0; int truncate = 0; + int ret = 0; if (!ISOFS_SB(inode->i_sb)->s_rock) return 0; *retname = 0; - setup_rock_ridge(de, inode, &chr, &len); + init_rock_state(&rs, inode); + setup_rock_ridge(de, inode, &rs); repeat: - while (len > 2) { /* There may be one byte for padding somewhere */ - rr = (struct rock_ridge *)chr; + while (rs.len > 2) { /* There may be one byte for padding somewhere */ + rr = (struct rock_ridge *)rs.chr; if (rr->len < 3) goto out; /* Something got screwed up here */ - sig = isonum_721(chr); - chr += rr->len; - len -= rr->len; - if (len < 0) + sig = isonum_721(rs.chr); + rs.chr += rr->len; + rs.len -= rr->len; + if (rs.len < 0) goto out; /* corrupted isofs */ switch (sig) { @@ -126,9 +150,9 @@ repeat: goto out; break; case SIG('C', 'E'): - cont_extent = isonum_733(rr->u.CE.extent); - cont_offset = isonum_733(rr->u.CE.offset); - cont_size = isonum_733(rr->u.CE.size); + rs.cont_extent = isonum_733(rr->u.CE.extent); + rs.cont_offset = isonum_733(rr->u.CE.offset); + rs.cont_size = isonum_733(rr->u.CE.size); break; case SIG('N', 'M'): if (truncate) @@ -158,58 +182,55 @@ repeat: retnamlen += rr->len - 5; break; case SIG('R', 'E'): - if (buffer) - kfree(buffer); + kfree(rs.buffer); return -1; default: break; } } - MAYBE_CONTINUE(repeat, inode); - kfree(buffer); - return retnamlen; /* If 0, this file did not have a NM field */ + ret = rock_continue(&rs); + if (ret == 0) + goto repeat; + if (ret == 1) + return retnamlen; /* If 0, this file did not have a NM field */ out: - if (buffer) - kfree(buffer); - return 0; + kfree(rs.buffer); + return ret; } static int parse_rock_ridge_inode_internal(struct iso_directory_record *de, struct inode *inode, int regard_xa) { - int len; - unsigned char *chr; int symlink_len = 0; int cnt, sig; struct inode *reloc; struct rock_ridge *rr; int rootflag; - int cont_extent = 0; - int cont_offset = 0; - int cont_size = 0; - void *buffer = NULL; + struct rock_state rs; + int ret = 0; if (!ISOFS_SB(inode->i_sb)->s_rock) return 0; - setup_rock_ridge(de, inode, &chr, &len); + init_rock_state(&rs, inode); + setup_rock_ridge(de, inode, &rs); if (regard_xa) { - chr += 14; - len -= 14; - if (len < 0) - len = 0; + rs.chr += 14; + rs.len -= 14; + if (rs.len < 0) + rs.len = 0; } repeat: - while (len > 2) { /* There may be one byte for padding somewhere */ - rr = (struct rock_ridge *)chr; + while (rs.len > 2) { /* There may be one byte for padding somewhere */ + rr = (struct rock_ridge *)rs.chr; if (rr->len < 3) goto out; /* Something got screwed up here */ - sig = isonum_721(chr); - chr += rr->len; - len -= rr->len; - if (len < 0) + sig = isonum_721(rs.chr); + rs.chr += rr->len; + rs.len -= rr->len; + if (rs.len < 0) goto out; /* corrupted isofs */ switch (sig) { @@ -225,9 +246,9 @@ repeat: goto out; break; case SIG('C', 'E'): - cont_extent = isonum_733(rr->u.CE.extent); - cont_offset = isonum_733(rr->u.CE.offset); - cont_size = isonum_733(rr->u.CE.size); + rs.cont_extent = isonum_733(rr->u.CE.extent); + rs.cont_offset = isonum_733(rr->u.CE.offset); + rs.cont_size = isonum_733(rr->u.CE.size); break; case SIG('E', 'R'): ISOFS_SB(inode->i_sb)->s_rock = 1; @@ -433,11 +454,14 @@ repeat: break; } } - MAYBE_CONTINUE(repeat, inode); + ret = rock_continue(&rs); + if (ret == 0) + goto repeat; + if (ret == 1) + ret = 0; out: - if (buffer) - kfree(buffer); - return 0; + kfree(rs.buffer); + return ret; } static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit) @@ -533,19 +557,16 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) char *rpnt = link; unsigned char *pnt; struct iso_directory_record *raw_de; - int cont_extent = 0; - int cont_offset = 0; - int cont_size = 0; - void *buffer = NULL; unsigned long block, offset; int sig; - int len; - unsigned char *chr; struct rock_ridge *rr; + struct rock_state rs; + int ret; if (!ISOFS_SB(inode->i_sb)->s_rock) goto error; + init_rock_state(&rs, inode); block = ei->i_iget5_block; lock_kernel(); bh = sb_bread(inode->i_sb, block); @@ -566,17 +587,17 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) /* Now test for possible Rock Ridge extensions which will override some of these numbers in the inode structure. */ - setup_rock_ridge(raw_de, inode, &chr, &len); + setup_rock_ridge(raw_de, inode, &rs); repeat: - while (len > 2) { /* There may be one byte for padding somewhere */ - rr = (struct rock_ridge *)chr; + while (rs.len > 2) { /* There may be one byte for padding somewhere */ + rr = (struct rock_ridge *)rs.chr; if (rr->len < 3) goto out; /* Something got screwed up here */ - sig = isonum_721(chr); - chr += rr->len; - len -= rr->len; - if (len < 0) + sig = isonum_721(rs.chr); + rs.chr += rr->len; + rs.len -= rr->len; + if (rs.len < 0) goto out; /* corrupted isofs */ switch (sig) { @@ -596,15 +617,18 @@ repeat: break; case SIG('C', 'E'): /* This tells is if there is a continuation record */ - cont_extent = isonum_733(rr->u.CE.extent); - cont_offset = isonum_733(rr->u.CE.offset); - cont_size = isonum_733(rr->u.CE.size); + rs.cont_extent = isonum_733(rr->u.CE.extent); + rs.cont_offset = isonum_733(rr->u.CE.offset); + rs.cont_size = isonum_733(rr->u.CE.size); default: break; } } - MAYBE_CONTINUE(repeat, inode); - kfree(buffer); + ret = rock_continue(&rs); + if (ret == 0) + goto repeat; + if (ret < 0) + goto fail; if (rpnt == link) goto fail; @@ -618,8 +642,7 @@ repeat: /* error exit from macro */ out: - if (buffer) - kfree(buffer); + kfree(rs.buffer); goto fail; out_noread: printk("unable to read i-node block"); -- cgit v1.2.3-59-g8ed1b From 7373909de403d229979842081c63917452e39402 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 21 Jun 2005 17:16:47 -0700 Subject: [PATCH] rock: comment tidies Be a bit more standard in comment layout. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/isofs/rock.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index efefbcce4ce9..977dd7009c07 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -13,12 +13,14 @@ #include "isofs.h" #include "rock.h" -/* These functions are designed to read the system areas of a directory record +/* + * These functions are designed to read the system areas of a directory record * and extract relevant information. There are different functions provided * depending upon what information we need at the time. One function fills * out an inode structure, a second one extracts a filename, a third one * returns a symbolic link name, and a fourth one returns the extent number - * for the file. */ + * for the file. + */ #define SIG(A,B) ((A) | ((B) << 8)) /* isonum_721() */ @@ -34,7 +36,7 @@ struct rock_state { /* * This is a way of ensuring that we have something in the system - * use fields that is compatible with Rock Ridge. Return zero on success. + * use fields that is compatible with Rock Ridge. Return zero on success. */ static int check_sp(struct rock_ridge *rr, struct inode *inode) @@ -111,7 +113,9 @@ out: return ret; } -/* return length of name field; 0: not found, -1: to be ignored */ +/* + * return length of name field; 0: not found, -1: to be ignored + */ int get_rock_ridge_filename(struct iso_directory_record *de, char *retname, struct inode *inode) { @@ -535,8 +539,11 @@ static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit) int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode) { int result = parse_rock_ridge_inode_internal(de, inode, 0); - /* if rockridge flag was reset and we didn't look for attributes - * behind eventual XA attributes, have a look there */ + + /* + * if rockridge flag was reset and we didn't look for attributes + * behind eventual XA attributes, have a look there + */ if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1) && (ISOFS_SB(inode->i_sb)->s_rock == 2)) { result = parse_rock_ridge_inode_internal(de, inode, 14); @@ -544,9 +551,10 @@ int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode) return result; } -/* readpage() for symlinks: reads symlink contents into the page and either - makes it uptodate and returns 0 or returns error (-EIO) */ - +/* + * readpage() for symlinks: reads symlink contents into the page and either + * makes it uptodate and returns 0 or returns error (-EIO) + */ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) { struct inode *inode = page->mapping->host; @@ -584,8 +592,10 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) if (offset + *pnt > bufsize) goto out_bad_span; - /* Now test for possible Rock Ridge extensions which will override - some of these numbers in the inode structure. */ + /* + * Now test for possible Rock Ridge extensions which will override + * some of these numbers in the inode structure. + */ setup_rock_ridge(raw_de, inode, &rs); -- cgit v1.2.3-59-g8ed1b From a089221c5e8a5ae8d74a919c8c7a4d2f68bd59e5 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 21 Jun 2005 17:16:48 -0700 Subject: [PATCH] rock: lindent rock.h So we have a couple of rock-ridge bugs. First up, rotoroot the poor thing into something which it is possible to work on. Feed rock.h through Lindent, tidy a couple of things by hand. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/isofs/rock.h | 183 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 93 insertions(+), 90 deletions(-) diff --git a/fs/isofs/rock.h b/fs/isofs/rock.h index deaf5c8e8b4a..9d3cbc762380 100644 --- a/fs/isofs/rock.h +++ b/fs/isofs/rock.h @@ -1,85 +1,88 @@ -/* These structs are used by the system-use-sharing protocol, in which the - Rock Ridge extensions are embedded. It is quite possible that other - extensions are present on the disk, and this is fine as long as they - all use SUSP */ - -struct SU_SP{ - unsigned char magic[2]; - unsigned char skip; -} __attribute__((packed)); - -struct SU_CE{ - char extent[8]; - char offset[8]; - char size[8]; +/* + * These structs are used by the system-use-sharing protocol, in which the + * Rock Ridge extensions are embedded. It is quite possible that other + * extensions are present on the disk, and this is fine as long as they + * all use SUSP + */ + +struct SU_SP { + unsigned char magic[2]; + unsigned char skip; +} __attribute__ ((packed)); + +struct SU_CE { + char extent[8]; + char offset[8]; + char size[8]; }; -struct SU_ER{ - unsigned char len_id; - unsigned char len_des; - unsigned char len_src; - unsigned char ext_ver; - char data[0]; -} __attribute__((packed)); - -struct RR_RR{ - char flags[1]; -} __attribute__((packed)); - -struct RR_PX{ - char mode[8]; - char n_links[8]; - char uid[8]; - char gid[8]; +struct SU_ER { + unsigned char len_id; + unsigned char len_des; + unsigned char len_src; + unsigned char ext_ver; + char data[0]; +} __attribute__ ((packed)); + +struct RR_RR { + char flags[1]; +} __attribute__ ((packed)); + +struct RR_PX { + char mode[8]; + char n_links[8]; + char uid[8]; + char gid[8]; }; -struct RR_PN{ - char dev_high[8]; - char dev_low[8]; +struct RR_PN { + char dev_high[8]; + char dev_low[8]; }; +struct SL_component { + unsigned char flags; + unsigned char len; + char text[0]; +} __attribute__ ((packed)); -struct SL_component{ - unsigned char flags; - unsigned char len; - char text[0]; -} __attribute__((packed)); +struct RR_SL { + unsigned char flags; + struct SL_component link; +} __attribute__ ((packed)); -struct RR_SL{ - unsigned char flags; - struct SL_component link; -} __attribute__((packed)); +struct RR_NM { + unsigned char flags; + char name[0]; +} __attribute__ ((packed)); -struct RR_NM{ - unsigned char flags; - char name[0]; -} __attribute__((packed)); - -struct RR_CL{ - char location[8]; +struct RR_CL { + char location[8]; }; -struct RR_PL{ - char location[8]; +struct RR_PL { + char location[8]; }; -struct stamp{ - char time[7]; -} __attribute__((packed)); +struct stamp { + char time[7]; +} __attribute__ ((packed)); -struct RR_TF{ - char flags; - struct stamp times[0]; /* Variable number of these beasts */ -} __attribute__((packed)); +struct RR_TF { + char flags; + struct stamp times[0]; /* Variable number of these beasts */ +} __attribute__ ((packed)); /* Linux-specific extension for transparent decompression */ -struct RR_ZF{ - char algorithm[2]; - char parms[2]; - char real_size[8]; +struct RR_ZF { + char algorithm[2]; + char parms[2]; + char real_size[8]; }; -/* These are the bits and their meanings for flags in the TF structure. */ +/* + * These are the bits and their meanings for flags in the TF structure. + */ #define TF_CREATE 1 #define TF_MODIFY 2 #define TF_ACCESS 4 @@ -89,31 +92,31 @@ struct RR_ZF{ #define TF_EFFECTIVE 64 #define TF_LONG_FORM 128 -struct rock_ridge{ - char signature[2]; - unsigned char len; - unsigned char version; - union{ - struct SU_SP SP; - struct SU_CE CE; - struct SU_ER ER; - struct RR_RR RR; - struct RR_PX PX; - struct RR_PN PN; - struct RR_SL SL; - struct RR_NM NM; - struct RR_CL CL; - struct RR_PL PL; - struct RR_TF TF; - struct RR_ZF ZF; - } u; +struct rock_ridge { + char signature[2]; + unsigned char len; + unsigned char version; + union { + struct SU_SP SP; + struct SU_CE CE; + struct SU_ER ER; + struct RR_RR RR; + struct RR_PX PX; + struct RR_PN PN; + struct RR_SL SL; + struct RR_NM NM; + struct RR_CL CL; + struct RR_PL PL; + struct RR_TF TF; + struct RR_ZF ZF; + } u; }; -#define RR_PX 1 /* POSIX attributes */ -#define RR_PN 2 /* POSIX devices */ -#define RR_SL 4 /* Symbolic link */ -#define RR_NM 8 /* Alternate Name */ -#define RR_CL 16 /* Child link */ -#define RR_PL 32 /* Parent link */ -#define RR_RE 64 /* Relocation directory */ -#define RR_TF 128 /* Timestamps */ +#define RR_PX 1 /* POSIX attributes */ +#define RR_PN 2 /* POSIX devices */ +#define RR_SL 4 /* Symbolic link */ +#define RR_NM 8 /* Alternate Name */ +#define RR_CL 16 /* Child link */ +#define RR_PL 32 /* Parent link */ +#define RR_RE 64 /* Relocation directory */ +#define RR_TF 128 /* Timestamps */ -- cgit v1.2.3-59-g8ed1b From 9eb7f2c67c41d2cd730aedcd23e5baca09211d03 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 21 Jun 2005 17:16:49 -0700 Subject: [PATCH] isofs: remove debug stuff isofs/inode.c: - Remove some crufty leak detection code - coding style cleanups - kfree(NULL) is permitted. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/isofs/inode.c | 109 ++++++++++++++++--------------------------------------- 1 file changed, 32 insertions(+), 77 deletions(-) diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index abd7b12eeca7..72cc9727dc07 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -28,11 +28,6 @@ #define BEQUIET -#ifdef LEAK_CHECK -static int check_malloc; -static int check_bread; -#endif - static int isofs_hashi(struct dentry *parent, struct qstr *qstr); static int isofs_hash(struct dentry *parent, struct qstr *qstr); static int isofs_dentry_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b); @@ -55,11 +50,6 @@ static void isofs_put_super(struct super_block *sb) } #endif -#ifdef LEAK_CHECK - printk("Outstanding mallocs:%d, outstanding buffers: %d\n", - check_malloc, check_bread); -#endif - kfree(sbi); sb->s_fs_info = NULL; return; @@ -73,7 +63,7 @@ static kmem_cache_t *isofs_inode_cachep; static struct inode *isofs_alloc_inode(struct super_block *sb) { struct iso_inode_info *ei; - ei = (struct iso_inode_info *)kmem_cache_alloc(isofs_inode_cachep, SLAB_KERNEL); + ei = kmem_cache_alloc(isofs_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; return &ei->vfs_inode; @@ -84,9 +74,9 @@ static void isofs_destroy_inode(struct inode *inode) kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode)); } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) { - struct iso_inode_info *ei = (struct iso_inode_info *) foo; + struct iso_inode_info *ei = foo; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) @@ -107,7 +97,8 @@ static int init_inodecache(void) static void destroy_inodecache(void) { if (kmem_cache_destroy(isofs_inode_cachep)) - printk(KERN_INFO "iso_inode_cache: not all structures were freed\n"); + printk(KERN_INFO "iso_inode_cache: not all structures were " + "freed\n"); } static int isofs_remount(struct super_block *sb, int *flags, char *data) @@ -144,7 +135,7 @@ static struct dentry_operations isofs_dentry_ops[] = { { .d_hash = isofs_hashi_ms, .d_compare = isofs_dentry_cmpi_ms, - } + }, #endif }; @@ -219,8 +210,8 @@ isofs_hashi_common(struct dentry *dentry, struct qstr *qstr, int ms) /* * Case insensitive compare of two isofs names. */ -static int -isofs_dentry_cmpi_common(struct dentry *dentry,struct qstr *a,struct qstr *b,int ms) +static int isofs_dentry_cmpi_common(struct dentry *dentry, struct qstr *a, + struct qstr *b, int ms) { int alen, blen; @@ -243,8 +234,8 @@ isofs_dentry_cmpi_common(struct dentry *dentry,struct qstr *a,struct qstr *b,int /* * Case sensitive compare of two isofs names. */ -static int -isofs_dentry_cmp_common(struct dentry *dentry,struct qstr *a,struct qstr *b,int ms) +static int isofs_dentry_cmp_common(struct dentry *dentry, struct qstr *a, + struct qstr *b, int ms) { int alen, blen; @@ -356,7 +347,7 @@ static match_table_t tokens = { {Opt_err, NULL} }; -static int parse_options(char *options, struct iso9660_options * popt) +static int parse_options(char *options, struct iso9660_options *popt) { char *p; int option; @@ -493,7 +484,7 @@ static int parse_options(char *options, struct iso9660_options * popt) */ #define WE_OBEY_THE_WRITTEN_STANDARDS 1 -static unsigned int isofs_get_last_session(struct super_block *sb,s32 session ) +static unsigned int isofs_get_last_session(struct super_block *sb, s32 session) { struct cdrom_multisession ms_info; unsigned int vol_desc_start; @@ -518,7 +509,8 @@ static unsigned int isofs_get_last_session(struct super_block *sb,s32 session ) printk(KERN_ERR "Invalid session number or type of track\n"); } i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long) &ms_info); - if(session > 0) printk(KERN_ERR "Invalid session number\n"); + if (session > 0) + printk(KERN_ERR "Invalid session number\n"); #if 0 printk("isofs.inode: CDROMMULTISESSION: rc=%d\n",i); if (i==0) { @@ -557,13 +549,13 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) struct iso9660_options opt; struct isofs_sb_info * sbi; - sbi = kmalloc(sizeof(struct isofs_sb_info), GFP_KERNEL); + sbi = kmalloc(sizeof(*sbi), GFP_KERNEL); if (!sbi) return -ENOMEM; s->s_fs_info = sbi; - memset(sbi, 0, sizeof(struct isofs_sb_info)); + memset(sbi, 0, sizeof(*sbi)); - if (!parse_options((char *) data, &opt)) + if (!parse_options((char *)data, &opt)) goto out_freesbi; /* @@ -1002,7 +994,6 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock_s, rv++; } - abort: unlock_kernel(); return rv; @@ -1014,7 +1005,7 @@ abort: static int isofs_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) { - if ( create ) { + if (create) { printk("isofs_get_block: Kernel tries to allocate a block\n"); return -EROFS; } @@ -1061,19 +1052,17 @@ static struct address_space_operations isofs_aops = { static inline void test_and_set_uid(uid_t *p, uid_t value) { - if(value) { + if (value) *p = value; - } } static inline void test_and_set_gid(gid_t *p, gid_t value) { - if(value) { + if (value) *p = value; - } } -static int isofs_read_level3_size(struct inode * inode) +static int isofs_read_level3_size(struct inode *inode) { unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); int high_sierra = ISOFS_SB(inode->i_sb)->s_high_sierra; @@ -1136,7 +1125,7 @@ static int isofs_read_level3_size(struct inode * inode) bh = sb_bread(inode->i_sb, block); if (!bh) goto out_noread; - memcpy((void *) tmpde + slop, bh->b_data, offset); + memcpy((void *)tmpde+slop, bh->b_data, offset); } de = tmpde; } @@ -1150,12 +1139,11 @@ static int isofs_read_level3_size(struct inode * inode) more_entries = de->flags[-high_sierra] & 0x80; i++; - if(i > 100) + if (i > 100) goto out_toomany; - } while(more_entries); + } while (more_entries); out: - if (tmpde) - kfree(tmpde); + kfree(tmpde); if (bh) brelse(bh); return 0; @@ -1179,7 +1167,7 @@ out_toomany: goto out; } -static void isofs_read_inode(struct inode * inode) +static void isofs_read_inode(struct inode *inode) { struct super_block *sb = inode->i_sb; struct isofs_sb_info *sbi = ISOFS_SB(sb); @@ -1249,7 +1237,7 @@ static void isofs_read_inode(struct inode * inode) ei->i_format_parm[2] = 0; ei->i_section_size = isonum_733 (de->size); - if(de->flags[-high_sierra] & 0x80) { + if (de->flags[-high_sierra] & 0x80) { if(isofs_read_level3_size(inode)) goto fail; } else { ei->i_next_section_block = 0; @@ -1336,16 +1324,16 @@ static void isofs_read_inode(struct inode * inode) /* XXX - parse_rock_ridge_inode() had already set i_rdev. */ init_special_inode(inode, inode->i_mode, inode->i_rdev); - out: +out: if (tmpde) kfree(tmpde); if (bh) brelse(bh); return; - out_badread: +out_badread: printk(KERN_WARNING "ISOFS: unable to read i-node block\n"); - fail: +fail: make_bad_inode(inode); goto out; } @@ -1394,11 +1382,8 @@ struct inode *isofs_iget(struct super_block *sb, hashval = (block << sb->s_blocksize_bits) | offset; - inode = iget5_locked(sb, - hashval, - &isofs_iget5_test, - &isofs_iget5_set, - &data); + inode = iget5_locked(sb, hashval, &isofs_iget5_test, + &isofs_iget5_set, &data); if (inode && (inode->i_state & I_NEW)) { sb->s_op->read_inode(inode); @@ -1408,36 +1393,6 @@ struct inode *isofs_iget(struct super_block *sb, return inode; } -#ifdef LEAK_CHECK -#undef malloc -#undef free_s -#undef sb_bread -#undef brelse - -void * leak_check_malloc(unsigned int size){ - void * tmp; - check_malloc++; - tmp = kmalloc(size, GFP_KERNEL); - return tmp; -} - -void leak_check_free_s(void * obj, int size){ - check_malloc--; - return kfree(obj); -} - -struct buffer_head * leak_check_bread(struct super_block *sb, int block){ - check_bread++; - return sb_bread(sb, block); -} - -void leak_check_brelse(struct buffer_head * bh){ - check_bread--; - return brelse(bh); -} - -#endif - static struct super_block *isofs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { -- cgit v1.2.3-59-g8ed1b From e595447e177b39aa6c96baaa57b30cde2d8b9df7 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 21 Jun 2005 17:16:50 -0700 Subject: [PATCH] rock.c: handle corrupted directories The bug in rock.c is that it's totally trusting of the contents of the directories. If the directory says there's a continuation 10000 bytes into this 4k block then we cheerily poke around in memory we don't own and oops. So change rock_continue() to apply various sanity checks, at least ensuring that the offset+length remain within the bounds for the header part of a struct rock_ridge directory entry. Note that the kernel can still overindex the buffer due to the variable size of the rock-ridge directory entries. We cannot check that in rock_continue() unless we go parse the directory entry's signature and work out its size. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/isofs/rock.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index 977dd7009c07..9a81830abff8 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -81,9 +81,22 @@ static void init_rock_state(struct rock_state *rs, struct inode *inode) static int rock_continue(struct rock_state *rs) { int ret = 1; + int blocksize = 1 << rs->inode->i_blkbits; + const int min_de_size = offsetof(struct rock_ridge, u); kfree(rs->buffer); rs->buffer = NULL; + + if ((unsigned)rs->cont_offset > blocksize - min_de_size || + (unsigned)rs->cont_size > blocksize || + (unsigned)(rs->cont_offset + rs->cont_size) > blocksize) { + printk(KERN_NOTICE "rock: corrupted directory entry. " + "extent=%d, offset=%d, size=%d\n", + rs->cont_extent, rs->cont_offset, rs->cont_size); + ret = -EIO; + goto out; + } + if (rs->cont_extent) { struct buffer_head *bh; -- cgit v1.2.3-59-g8ed1b From 642217c17b9a56c7e4cf48f6a13dfd5e4a4c2e10 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 21 Jun 2005 17:16:51 -0700 Subject: [PATCH] rock: rename union members The silly thing does: struct foo { ... }; ... #define foo 42 so you can no longer refer to `struct foo' in C code. Rename the structures. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/isofs/rock.h | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/fs/isofs/rock.h b/fs/isofs/rock.h index 9d3cbc762380..ed09e2b08637 100644 --- a/fs/isofs/rock.h +++ b/fs/isofs/rock.h @@ -5,18 +5,18 @@ * all use SUSP */ -struct SU_SP { +struct SU_SP_s { unsigned char magic[2]; unsigned char skip; } __attribute__ ((packed)); -struct SU_CE { +struct SU_CE_s { char extent[8]; char offset[8]; char size[8]; }; -struct SU_ER { +struct SU_ER_s { unsigned char len_id; unsigned char len_des; unsigned char len_src; @@ -24,18 +24,18 @@ struct SU_ER { char data[0]; } __attribute__ ((packed)); -struct RR_RR { +struct RR_RR_s { char flags[1]; } __attribute__ ((packed)); -struct RR_PX { +struct RR_PX_s { char mode[8]; char n_links[8]; char uid[8]; char gid[8]; }; -struct RR_PN { +struct RR_PN_s { char dev_high[8]; char dev_low[8]; }; @@ -46,21 +46,21 @@ struct SL_component { char text[0]; } __attribute__ ((packed)); -struct RR_SL { +struct RR_SL_s { unsigned char flags; struct SL_component link; } __attribute__ ((packed)); -struct RR_NM { +struct RR_NM_s { unsigned char flags; char name[0]; } __attribute__ ((packed)); -struct RR_CL { +struct RR_CL_s { char location[8]; }; -struct RR_PL { +struct RR_PL_s { char location[8]; }; @@ -68,13 +68,13 @@ struct stamp { char time[7]; } __attribute__ ((packed)); -struct RR_TF { +struct RR_TF_s { char flags; struct stamp times[0]; /* Variable number of these beasts */ } __attribute__ ((packed)); /* Linux-specific extension for transparent decompression */ -struct RR_ZF { +struct RR_ZF_s { char algorithm[2]; char parms[2]; char real_size[8]; @@ -97,18 +97,18 @@ struct rock_ridge { unsigned char len; unsigned char version; union { - struct SU_SP SP; - struct SU_CE CE; - struct SU_ER ER; - struct RR_RR RR; - struct RR_PX PX; - struct RR_PN PN; - struct RR_SL SL; - struct RR_NM NM; - struct RR_CL CL; - struct RR_PL PL; - struct RR_TF TF; - struct RR_ZF ZF; + struct SU_SP_s SP; + struct SU_CE_s CE; + struct SU_ER_s ER; + struct RR_RR_s RR; + struct RR_PX_s PX; + struct RR_PN_s PN; + struct RR_SL_s SL; + struct RR_NM_s NM; + struct RR_CL_s CL; + struct RR_PL_s PL; + struct RR_TF_s TF; + struct RR_ZF_s ZF; } u; }; -- cgit v1.2.3-59-g8ed1b From f2966632a134e865db3c819346a1dc7d96e05309 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 21 Jun 2005 17:16:51 -0700 Subject: [PATCH] rock: handle directory overflows Handle the case where the variable-sized part of a rock-ridge directory entry overhangs the end of the buffer which we allocated for it. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/isofs/rock.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index 9a81830abff8..4326cb47f8fa 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -126,6 +126,66 @@ out: return ret; } +/* + * We think there's a record of type `sig' at rs->chr. Parse the signature + * and make sure that there's really room for a record of that type. + */ +static int rock_check_overflow(struct rock_state *rs, int sig) +{ + int len; + + switch (sig) { + case SIG('S', 'P'): + len = sizeof(struct SU_SP_s); + break; + case SIG('C', 'E'): + len = sizeof(struct SU_CE_s); + break; + case SIG('E', 'R'): + len = sizeof(struct SU_ER_s); + break; + case SIG('R', 'R'): + len = sizeof(struct RR_RR_s); + break; + case SIG('P', 'X'): + len = sizeof(struct RR_PX_s); + break; + case SIG('P', 'N'): + len = sizeof(struct RR_PN_s); + break; + case SIG('S', 'L'): + len = sizeof(struct RR_SL_s); + break; + case SIG('N', 'M'): + len = sizeof(struct RR_NM_s); + break; + case SIG('C', 'L'): + len = sizeof(struct RR_CL_s); + break; + case SIG('P', 'L'): + len = sizeof(struct RR_PL_s); + break; + case SIG('T', 'F'): + len = sizeof(struct RR_TF_s); + break; + case SIG('Z', 'F'): + len = sizeof(struct RR_ZF_s); + break; + default: + len = 0; + break; + } + len += offsetof(struct rock_ridge, u); + if (len > rs->len) { + printk(KERN_NOTICE "rock: directory entry would overflow " + "storage\n"); + printk(KERN_NOTICE "rock: sig=0x%02x, size=%d, remaining=%d\n", + sig, len, rs->len); + return -EIO; + } + return 0; +} + /* * return length of name field; 0: not found, -1: to be ignored */ @@ -152,10 +212,12 @@ repeat: if (rr->len < 3) goto out; /* Something got screwed up here */ sig = isonum_721(rs.chr); + if (rock_check_overflow(&rs, sig)) + goto eio; rs.chr += rr->len; rs.len -= rr->len; if (rs.len < 0) - goto out; /* corrupted isofs */ + goto eio; /* corrupted isofs */ switch (sig) { case SIG('R', 'R'): @@ -213,6 +275,9 @@ repeat: out: kfree(rs.buffer); return ret; +eio: + ret = -EIO; + goto out; } static int @@ -245,10 +310,12 @@ repeat: if (rr->len < 3) goto out; /* Something got screwed up here */ sig = isonum_721(rs.chr); + if (rock_check_overflow(&rs, sig)) + goto eio; rs.chr += rr->len; rs.len -= rr->len; if (rs.len < 0) - goto out; /* corrupted isofs */ + goto eio; /* corrupted isofs */ switch (sig) { #ifndef CONFIG_ZISOFS /* No flag for SF or ZF */ @@ -479,6 +546,9 @@ repeat: out: kfree(rs.buffer); return ret; +eio: + ret = -EIO; + goto out; } static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit) @@ -618,6 +688,8 @@ repeat: if (rr->len < 3) goto out; /* Something got screwed up here */ sig = isonum_721(rs.chr); + if (rock_check_overflow(&rs, sig)) + goto out; rs.chr += rr->len; rs.len -= rr->len; if (rs.len < 0) -- cgit v1.2.3-59-g8ed1b From 9769f4eb3fad2dd53a5d24c81ee5f7f05450742b Mon Sep 17 00:00:00 2001 From: Jeremy White Date: Tue, 21 Jun 2005 17:16:53 -0700 Subject: [PATCH] isofs: show hidden files, add granularity for assoc/hidden files flags The current isofs treatment of hidden files is flawed in two ways. First, it does not provide sufficient granularity; it hides both 'hidden' files and 'associated' files (resource fork for Mac files). Second, the default behavior to completely strip hidden files, while an admirable implementation of the spec, is a poor choice given the real world use of hidden files as a poor mans copy protection scheme for MSDOS and Windows based systems. A longer description of this is available here: http://www.uwsg.iu.edu/hypermail/linux/kernel/0205.3/0267.html This patch was originally built after a few private conversations with Alan Cox; I shamefully failed to persist in seeing it go forward, I hope to make amends now. This patch introduces granularity by allowing explicit control for both hidden and associated files. It also reverses the default so that by default, hidden files are treated as regular files on the iso9660 file system. This allow Wine to process Windows CDs, including those that are hybrid Mac/Windows CDs properly and completely, without our having to go muck up peoples fstabs as we do now. (I have tested this with such a hybrid + hidden CD and have verified that this patch works as claimed). Signed-off-by: Jeremy White Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/filesystems/isofs.txt | 6 +++++- fs/isofs/dir.c | 17 +++++++++++------ fs/isofs/inode.c | 19 ++++++++++++++----- fs/isofs/isofs.h | 2 ++ fs/isofs/namei.c | 16 +++++++++------- 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/Documentation/filesystems/isofs.txt b/Documentation/filesystems/isofs.txt index f64a10506689..424585ff6ea1 100644 --- a/Documentation/filesystems/isofs.txt +++ b/Documentation/filesystems/isofs.txt @@ -26,7 +26,11 @@ Mount options unique to the isofs filesystem. mode=xxx Sets the permissions on files to xxx nojoliet Ignore Joliet extensions if they are present. norock Ignore Rock Ridge extensions if they are present. - unhide Show hidden files. + hide Completely strip hidden files from the file system. + showassoc Show files marked with the 'associated' bit + unhide Deprecated; showing hidden files is now default; + If given, it is a synonym for 'showassoc' which will + recreate previous unhide behavior session=x Select number of session on multisession CD sbsector=xxx Session begins from sector xxx diff --git a/fs/isofs/dir.c b/fs/isofs/dir.c index 6030956b894b..7901ac9f97ab 100644 --- a/fs/isofs/dir.c +++ b/fs/isofs/dir.c @@ -193,12 +193,17 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp, /* Handle everything else. Do name translation if there is no Rock Ridge NM field. */ - if (sbi->s_unhide == 'n') { - /* Do not report hidden or associated files */ - if (de->flags[-sbi->s_high_sierra] & 5) { - filp->f_pos += de_len; - continue; - } + + /* + * Do not report hidden files if so instructed, or associated + * files unless instructed to do so + */ + if ((sbi->s_hide == 'y' && + (de->flags[-sbi->s_high_sierra] & 1)) || + (sbi->s_showassoc =='n' && + (de->flags[-sbi->s_high_sierra] & 4))) { + filp->f_pos += de_len; + continue; } map = 1; diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 72cc9727dc07..1652de1b6cb9 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -144,7 +144,8 @@ struct iso9660_options{ char rock; char joliet; char cruft; - char unhide; + char hide; + char showassoc; char nocompress; unsigned char check; unsigned int blocksize; @@ -309,13 +310,15 @@ enum { Opt_block, Opt_check_r, Opt_check_s, Opt_cruft, Opt_gid, Opt_ignore, Opt_iocharset, Opt_map_a, Opt_map_n, Opt_map_o, Opt_mode, Opt_nojoliet, Opt_norock, Opt_sb, Opt_session, Opt_uid, Opt_unhide, Opt_utf8, Opt_err, - Opt_nocompress, + Opt_nocompress, Opt_hide, Opt_showassoc, }; static match_table_t tokens = { {Opt_norock, "norock"}, {Opt_nojoliet, "nojoliet"}, {Opt_unhide, "unhide"}, + {Opt_hide, "hide"}, + {Opt_showassoc, "showassoc"}, {Opt_cruft, "cruft"}, {Opt_utf8, "utf8"}, {Opt_iocharset, "iocharset=%s"}, @@ -356,7 +359,8 @@ static int parse_options(char *options, struct iso9660_options *popt) popt->rock = 'y'; popt->joliet = 'y'; popt->cruft = 'n'; - popt->unhide = 'n'; + popt->hide = 'n'; + popt->showassoc = 'n'; popt->check = 'u'; /* unset */ popt->nocompress = 0; popt->blocksize = 1024; @@ -389,8 +393,12 @@ static int parse_options(char *options, struct iso9660_options *popt) case Opt_nojoliet: popt->joliet = 'n'; break; + case Opt_hide: + popt->hide = 'y'; + break; case Opt_unhide: - popt->unhide = 'y'; + case Opt_showassoc: + popt->showassoc = 'y'; break; case Opt_cruft: popt->cruft = 'y'; @@ -784,7 +792,8 @@ root_found: sbi->s_rock = (opt.rock == 'y' ? 2 : 0); sbi->s_rock_offset = -1; /* initial offset, will guess until SP is found*/ sbi->s_cruft = opt.cruft; - sbi->s_unhide = opt.unhide; + sbi->s_hide = opt.hide; + sbi->s_showassoc = opt.showassoc; sbi->s_uid = opt.uid; sbi->s_gid = opt.gid; sbi->s_utf8 = opt.utf8; diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h index 9ce7b51fb614..38c75151fc66 100644 --- a/fs/isofs/isofs.h +++ b/fs/isofs/isofs.h @@ -47,6 +47,8 @@ struct isofs_sb_info { unsigned char s_nosuid; unsigned char s_nodev; unsigned char s_nocompress; + unsigned char s_hide; + unsigned char s_showassoc; mode_t s_mode; gid_t s_gid; diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c index 690edf37173c..e37e82b7cbf0 100644 --- a/fs/isofs/namei.c +++ b/fs/isofs/namei.c @@ -131,14 +131,16 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry, } /* - * Skip hidden or associated files unless unhide is set + * Skip hidden or associated files unless hide or showassoc, + * respectively, is set */ match = 0; if (dlen > 0 && - (!(de->flags[-sbi->s_high_sierra] & 5) - || sbi->s_unhide == 'y')) - { - match = (isofs_cmp(dentry,dpnt,dlen) == 0); + (sbi->s_hide =='n' || + (!(de->flags[-sbi->s_high_sierra] & 1))) && + (sbi->s_showassoc =='y' || + (!(de->flags[-sbi->s_high_sierra] & 4)))) { + match = (isofs_cmp(dentry, dpnt, dlen) == 0); } if (match) { isofs_normalize_block_and_offset(de, @@ -146,11 +148,11 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry, &offset_saved); *block_rv = block_saved; *offset_rv = offset_saved; - if (bh) brelse(bh); + brelse(bh); return 1; } } - if (bh) brelse(bh); + brelse(bh); return 0; } -- cgit v1.2.3-59-g8ed1b From e6afbe59710f65d92d00de1f3adb5514ef634110 Mon Sep 17 00:00:00 2001 From: Keenan Pepper Date: Tue, 21 Jun 2005 17:16:54 -0700 Subject: [PATCH] Bring back Tux on Chips 65550 framebuffer I don't see any reason why the framebuffer should need to be cleared, and it makes Tux vanish. Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/chipsfb.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c index ab98f225fe3e..95e72550d43f 100644 --- a/drivers/video/chipsfb.c +++ b/drivers/video/chipsfb.c @@ -423,9 +423,6 @@ chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent) pmu_register_sleep_notifier(&chips_sleep_notifier); #endif /* CONFIG_PMAC_PBOOK */ - /* Clear the entire framebuffer */ - memset(p->screen_base, 0, 0x100000); - pci_set_drvdata(dp, p); return 0; } -- cgit v1.2.3-59-g8ed1b From 27f931dac93057bbae691f66a49b11ff2f483bee Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 21 Jun 2005 17:16:55 -0700 Subject: [PATCH] s1d13xxxfb linkage fix s1d13xxxfb_remove() is referenced from s1d13xxxfb_probe(), which is marked __devinit(). So s1d13xxxfb_remove() cannot be marked __devexit. Does this all make sense? Clearly the __devexit section will still be in core when the __devinit code is run, if the driver was loaded as a module. But I suppose that if the driver is statically linked, the __devexit section might be dropped early in boot. Still, we wouldn't drop __devexit prior to initcall completion, at which point the __devinit code has all been run anyway. verdict: this code was legal and made sense. Is this a generic problem, or an arm-specific problem? UPD include/linux/compile.h CC init/version.o LD init/built-in.o LD .tmp_vmlinux1 `.exit.text' referenced in section `.init.text' of drivers/built-in.o: defined in discarded section `.exit.text' of drivers/built-in.o Cc: Russell King Cc: Rusty Russell Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/s1d13xxxfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c index b637c389e4f4..789de13f461f 100644 --- a/drivers/video/s1d13xxxfb.c +++ b/drivers/video/s1d13xxxfb.c @@ -493,7 +493,7 @@ s1d13xxxfb_fetch_hw_state(struct fb_info *info) } -static int __devexit +static int s1d13xxxfb_remove(struct device *dev) { struct fb_info *info = dev_get_drvdata(dev); -- cgit v1.2.3-59-g8ed1b From 78c03717c415d81879e4dac2e452d1a0d3738a80 Mon Sep 17 00:00:00 2001 From: Gerd Knorr Date: Tue, 21 Jun 2005 17:16:56 -0700 Subject: [PATCH] some vesafb fixes Fix the size passed to release_mem_region in an error path. Also adjust the message printed when vesafb cannot load; the comment there already says this must not be fatal, so the message should also not mention the word 'abort' otherwise indicating a problem to worry about in the log. Signed-off-by: Jan Beulich Signed-off-by: Gerd Knorr Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/vesafb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 3027841f9c24..f3069b01e248 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c @@ -271,7 +271,7 @@ static int __init vesafb_probe(struct device *device) if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) { printk(KERN_WARNING - "vesafb: abort, cannot reserve video memory at 0x%lx\n", + "vesafb: cannot reserve video memory at 0x%lx\n", vesafb_fix.smem_start); /* We cannot make this fatal. Sometimes this comes from magic spaces our resource handlers simply don't know about */ @@ -279,13 +279,13 @@ static int __init vesafb_probe(struct device *device) info = framebuffer_alloc(sizeof(u32) * 256, &dev->dev); if (!info) { - release_mem_region(vesafb_fix.smem_start, vesafb_fix.smem_len); + release_mem_region(vesafb_fix.smem_start, size_total); return -ENOMEM; } info->pseudo_palette = info->par; info->par = NULL; - info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len); + info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len); if (!info->screen_base) { printk(KERN_ERR "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n", @@ -386,7 +386,7 @@ static int __init vesafb_probe(struct device *device) request_region(0x3c0, 32, "vesafb"); if (mtrr) { - int temp_size = size_total; + unsigned int temp_size = size_total; /* Find the largest power-of-two */ while (temp_size & (temp_size - 1)) temp_size &= (temp_size - 1); -- cgit v1.2.3-59-g8ed1b From 5a3b5899f190a365eed806302f4b58a493233f96 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 21 Jun 2005 17:16:57 -0700 Subject: [PATCH] intelfbdrv naming fix Can't use this fancy name, because it's used to generate a sysfs filename: kobject_register failed for Intel(R) 830M/845G/852GM/855GM/865G/915G Framebuffer Driver (-13) [] kobject_register+0x43/0x70 [] bus_add_driver+0x52/0xa0 [] pci_device_shutdown+0x0/0x20 [] pci_register_driver+0x61/0x80 [] intelfb_init+0x59/0x70 [] do_initcalls+0x2c/0xc0 [] kern_mount+0x15/0x17 [] init+0x0/0x100 [] init+0x2a/0x100 [] kernel_thread_helper+0x0/0x18 [] kernel_thread_helper+0x5/0x18 Cc: "Antonino A. Daplas" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/intelfb/intelfbdrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 25f9a9a65c24..94f35a635ccd 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c @@ -214,7 +214,7 @@ static struct fb_ops intel_fb_ops = { /* PCI driver module table */ static struct pci_driver intelfb_driver = { - .name = "Intel(R) " SUPPORTED_CHIPSETS " Framebuffer Driver", + .name = "intelfb", .id_table = intelfb_pci_table, .probe = intelfb_pci_register, .remove = __devexit_p(intelfb_pci_unregister) -- cgit v1.2.3-59-g8ed1b From f5a9951c94e7a285a3d00648e3d790a7f016bd11 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Tue, 21 Jun 2005 17:16:58 -0700 Subject: [PATCH] fbdev: iomove removal Since no one is using the inbuf, outbuf of struct fb_pixmap I removed their use in the framebuffer console. The idea is instead move the pixmap functionality below the accelerated functions intead of on top as the way it is now. If there is no objection please apply. This is against Linus latestr GIT tree. Thank you. Signed-off-by: James Simmons Cc: "Antonino A. Daplas" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/console/bitblit.c | 18 ++----------- drivers/video/fbmem.c | 57 ++++------------------------------------- drivers/video/softcursor.c | 8 ++---- include/linux/fb.h | 12 +++------ 4 files changed, 12 insertions(+), 83 deletions(-) diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c index b28a4b0e395e..4eef20790c3e 100644 --- a/drivers/video/console/bitblit.c +++ b/drivers/video/console/bitblit.c @@ -107,13 +107,6 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx, int fg, int bg) { - void (*move_unaligned)(struct fb_info *info, struct fb_pixmap *buf, - u8 *dst, u32 d_pitch, u8 *src, u32 idx, - u32 height, u32 shift_high, u32 shift_low, - u32 mod); - void (*move_aligned)(struct fb_info *info, struct fb_pixmap *buf, - u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, - u32 height); unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; unsigned int width = (vc->vc_font.width + 7) >> 3; unsigned int cellsize = vc->vc_font.height * width; @@ -141,13 +134,6 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, image.height = vc->vc_font.height; image.depth = 1; - if (info->pixmap.outbuf && info->pixmap.inbuf) { - move_aligned = fb_iomove_buf_aligned; - move_unaligned = fb_iomove_buf_unaligned; - } else { - move_aligned = fb_sysmove_buf_aligned; - move_unaligned = fb_sysmove_buf_unaligned; - } while (count) { if (count > maxcnt) cnt = k = maxcnt; @@ -171,7 +157,7 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, src = buf; } - move_unaligned(info, &info->pixmap, dst, pitch, + fb_sysmove_buf_unaligned(info, &info->pixmap, dst, pitch, src, idx, image.height, shift_high, shift_low, mod); shift_low += mod; @@ -189,7 +175,7 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, src = buf; } - move_aligned(info, &info->pixmap, dst, pitch, + fb_sysmove_buf_aligned(info, &info->pixmap, dst, pitch, src, idx, image.height); dst += width; } diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 8cef020d1801..78907a873493 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -76,65 +76,21 @@ int fb_get_color_depth(struct fb_var_screeninfo *var) EXPORT_SYMBOL(fb_get_color_depth); /* - * Drawing helpers. + * Data padding functions. */ -void fb_iomove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf, - u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, - u32 height) -{ - int i; - - for (i = height; i--; ) { - buf->outbuf(info, dst, src, s_pitch); - src += s_pitch; - dst += d_pitch; - } -} - void fb_sysmove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf, u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height) { - int i, j; + int i; for (i = height; i--; ) { - for (j = 0; j < s_pitch; j++) - dst[j] = src[j]; + memcpy(dst, src, s_pitch); src += s_pitch; dst += d_pitch; } } - -void fb_iomove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf, - u8 *dst, u32 d_pitch, u8 *src, u32 idx, - u32 height, u32 shift_high, u32 shift_low, - u32 mod) -{ - u8 mask = (u8) (0xfff << shift_high), tmp; - int i, j; - - for (i = height; i--; ) { - for (j = 0; j < idx; j++) { - tmp = buf->inbuf(info, dst+j); - tmp &= mask; - tmp |= *src >> shift_low; - buf->outbuf(info, dst+j, &tmp, 1); - tmp = *src << shift_high; - buf->outbuf(info, dst+j+1, &tmp, 1); - src++; - } - tmp = buf->inbuf(info, dst+idx); - tmp &= mask; - tmp |= *src >> shift_low; - buf->outbuf(info, dst+idx, &tmp, 1); - if (shift_high < mod) { - tmp = *src << shift_high; - buf->outbuf(info, dst+idx+1, &tmp, 1); - } - src++; - dst += d_pitch; - } -} +EXPORT_SYMBOL(fb_sysmove_buf_aligned); void fb_sysmove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf, u8 *dst, u32 d_pitch, u8 *src, u32 idx, @@ -166,6 +122,7 @@ void fb_sysmove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf, dst += d_pitch; } } +EXPORT_SYMBOL(fb_sysmove_buf_unaligned); /* * we need to lock this section since fb_cursor @@ -1357,10 +1314,6 @@ EXPORT_SYMBOL(fb_set_var); EXPORT_SYMBOL(fb_blank); EXPORT_SYMBOL(fb_pan_display); EXPORT_SYMBOL(fb_get_buffer_offset); -EXPORT_SYMBOL(fb_iomove_buf_unaligned); -EXPORT_SYMBOL(fb_iomove_buf_aligned); -EXPORT_SYMBOL(fb_sysmove_buf_unaligned); -EXPORT_SYMBOL(fb_sysmove_buf_aligned); EXPORT_SYMBOL(fb_set_suspend); EXPORT_SYMBOL(fb_register_client); EXPORT_SYMBOL(fb_unregister_client); diff --git a/drivers/video/softcursor.c b/drivers/video/softcursor.c index 13a4511539a1..a6c5ca88d6b0 100644 --- a/drivers/video/softcursor.c +++ b/drivers/video/softcursor.c @@ -58,12 +58,8 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) } else memcpy(src, image->data, dsize); - if (info->pixmap.outbuf) - fb_iomove_buf_aligned(info, &info->pixmap, dst, d_pitch, src, - s_pitch, image->height); - else - fb_sysmove_buf_aligned(info, &info->pixmap, dst, d_pitch, src, - s_pitch, image->height); + fb_sysmove_buf_aligned(info, &info->pixmap, dst, d_pitch, src, + s_pitch, image->height); image->data = dst; info->fbops->fb_imageblit(info, image); diff --git a/include/linux/fb.h b/include/linux/fb.h index b468bf496547..e14942805dbd 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -524,11 +524,11 @@ struct fb_pixmap { u32 offset; /* current offset to buffer */ u32 buf_align; /* byte alignment of each bitmap */ u32 scan_align; /* alignment per scanline */ - u32 access_align; /* alignment per read/write */ + u32 access_align; /* alignment per read/write (bits) */ u32 flags; /* see FB_PIXMAP_* */ /* access methods */ - void (*outbuf)(struct fb_info *info, u8 *addr, u8 *src, unsigned int size); - u8 (*inbuf) (struct fb_info *info, u8 *addr); + void (*writeio)(struct fb_info *info, void __iomem *dst, void *src, unsigned int size); + void (*readio) (struct fb_info *info, void *dst, void __iomem *src, unsigned int size); }; @@ -816,12 +816,6 @@ extern int unregister_framebuffer(struct fb_info *fb_info); extern int fb_prepare_logo(struct fb_info *fb_info); extern int fb_show_logo(struct fb_info *fb_info); extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size); -extern void fb_iomove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf, - u8 *dst, u32 d_pitch, u8 *src, u32 idx, - u32 height, u32 shift_high, u32 shift_low, u32 mod); -extern void fb_iomove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf, - u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, - u32 height); extern void fb_sysmove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf, u8 *dst, u32 d_pitch, u8 *src, u32 idx, u32 height, u32 shift_high, u32 shift_low, u32 mod); -- cgit v1.2.3-59-g8ed1b From 8d7f085342ddf20194b6e00c42b80968f15104db Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Tue, 21 Jun 2005 17:16:59 -0700 Subject: [PATCH] pm3fb typo fix Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/pm3fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c index 8e024aad1b57..e0dad948467b 100644 --- a/drivers/video/pm3fb.c +++ b/drivers/video/pm3fb.c @@ -5,7 +5,7 @@ * Based on code written by: * Sven Luther, * Alan Hourihane, - * Russel King, + * Russell King, * Based on linux/drivers/video/skeletonfb.c: * Copyright (C) 1997 Geert Uytterhoeven * Based on linux/driver/video/pm2fb.c: -- cgit v1.2.3-59-g8ed1b From f18cd8f7053a1e6755d1c1396884b2bfa1577e54 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Tue, 21 Jun 2005 17:17:00 -0700 Subject: [PATCH] VGA to fbcon fix. Currently when going from vgacon to fbcon the VT screenbuffer are often different sizes. In the case when they are different sizes a new VT screenbuffer is allocated and the contents are copied into the new buffer. Currently the amount copied from VGA text memory to the new screenbuf is the size of the framebuffer console. If the framebuffer console new VT screen buffer is greater than the VGA text memory size then we get some of the VGA BIOS contents as well. This patch will only allow you to copy up to the size of VGA text memory now. The rest is filled with erase characters. Initial patch by Jordan Crouse Signed-off-by: James Simmons Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/console/vgacon.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index bcf59b28a14f..d27fa91e5886 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -95,6 +95,7 @@ static unsigned long vgacon_uni_pagedir[2]; /* Description of the hardware situation */ static unsigned long vga_vram_base; /* Base of video memory */ static unsigned long vga_vram_end; /* End of video memory */ +static int vga_vram_size; /* Size of video memory */ static u16 vga_video_port_reg; /* Video register select port */ static u16 vga_video_port_val; /* Video register value port */ static unsigned int vga_video_num_columns; /* Number of text columns */ @@ -288,6 +289,7 @@ static const char __init *vgacon_startup(void) vga_vram_base = VGA_MAP_MEM(vga_vram_base); vga_vram_end = VGA_MAP_MEM(vga_vram_end); + vga_vram_size = vga_vram_end - vga_vram_base; /* * Find out if there is a graphics card present. @@ -504,9 +506,13 @@ static int vgacon_switch(struct vc_data *c) */ vga_video_num_columns = c->vc_cols; vga_video_num_lines = c->vc_rows; + + /* We can only copy out the size of the video buffer here, + * otherwise we get into VGA BIOS */ + if (!vga_is_gfx) scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, - c->vc_screenbuf_size); + c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); return 0; /* Redrawing not needed */ } @@ -961,7 +967,6 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines) if (!lines) /* Turn scrollback off */ c->vc_visible_origin = c->vc_origin; else { - int vram_size = vga_vram_end - vga_vram_base; int margin = c->vc_size_row * 4; int ul, we, p, st; @@ -971,7 +976,7 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines) we = vga_rolled_over + c->vc_size_row; } else { ul = 0; - we = vram_size; + we = vga_vram_size; } p = (c->vc_visible_origin - vga_vram_base - ul + we) % we + lines * c->vc_size_row; @@ -1012,9 +1017,13 @@ static void vgacon_save_screen(struct vc_data *c) c->vc_x = ORIG_X; c->vc_y = ORIG_Y; } + + /* We can't copy in more then the size of the video buffer, + * or we'll be copying in VGA BIOS */ + if (!vga_is_gfx) scr_memcpyw((u16 *) c->vc_screenbuf, (u16 *) c->vc_origin, - c->vc_screenbuf_size); + c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); } static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, -- cgit v1.2.3-59-g8ed1b From 27aef2d49f9d82c58e65d72abcd636168ec19ac9 Mon Sep 17 00:00:00 2001 From: Sylvain Meyer Date: Tue, 21 Jun 2005 17:17:01 -0700 Subject: [PATCH] intelfb: Add voffset option to avoid conficts with Xorg i810 driver - Add voffset option to avoid conficts with Xorg i810 driver Signed-off-by: Sylvain Meyer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/intelfb/intelfbdrv.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 94f35a635ccd..7a5750b449a8 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c @@ -238,12 +238,15 @@ static int noregister = 0; static int probeonly = 0; static int idonly = 0; static int bailearly = 0; +static int voffset = 48; static char *mode = NULL; module_param(accel, bool, S_IRUGO); MODULE_PARM_DESC(accel, "Enable console acceleration"); module_param(vram, int, S_IRUGO); MODULE_PARM_DESC(vram, "System RAM to allocate to framebuffer in MiB"); +module_param(voffset, int, S_IRUGO); +MODULE_PARM_DESC(voffset, "Offset of framebuffer in MiB"); module_param(hwcursor, bool, S_IRUGO); MODULE_PARM_DESC(hwcursor, "Enable HW cursor"); module_param(mtrr, bool, S_IRUGO); @@ -503,6 +506,7 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) struct agp_bridge_data *bridge; int aperture_bar = 0; int mmio_bar = 1; + int offset; DBG_MSG("intelfb_pci_register\n"); @@ -659,17 +663,21 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) return -ENODEV; } + if (MB(voffset) < stolen_size) + offset = (stolen_size >> 12); + else + offset = ROUND_UP_TO_PAGE(MB(voffset))/GTT_PAGE_SIZE; + /* set the mem offsets - set them after the already used pages */ if (dinfo->accel) { - dinfo->ring.offset = (stolen_size >> 12) - + gtt_info.current_memory; + dinfo->ring.offset = offset + gtt_info.current_memory; } if (dinfo->hwcursor) { - dinfo->cursor.offset = (stolen_size >> 12) + + dinfo->cursor.offset = offset + + gtt_info.current_memory + (dinfo->ring.size >> 12); } if (dinfo->fbmem_gart) { - dinfo->fb.offset = (stolen_size >> 12) + + dinfo->fb.offset = offset + + gtt_info.current_memory + (dinfo->ring.size >> 12) + (dinfo->cursor.size >> 12); } -- cgit v1.2.3-59-g8ed1b From df529338d9c5d9329e503955795c89472e1ba6e6 Mon Sep 17 00:00:00 2001 From: Sylvain Meyer Date: Tue, 21 Jun 2005 17:17:02 -0700 Subject: [PATCH] intelfb: fix accel detection when changing video modes Changed the tests in intelfb_set_par to check also the parameter var.accel_flags. If null, do nothing about ring buffers. Now, the DirectFB i830 driver could nicely work even if intelfb is hw accelerated. Just change the /etc/fb.modes file to disable console hw acceleration when starting a DirectFB app. Signed-off-by: Sylvain Meyer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/intelfb/intelfbdrv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 7a5750b449a8..448c90864016 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c @@ -1301,7 +1301,7 @@ intelfb_set_par(struct fb_info *info) intelfb_blank(FB_BLANK_POWERDOWN, info); - if (dinfo->accel) + if (ACCEL(dinfo, info)) intelfbhw_2d_stop(dinfo); memcpy(hw, &dinfo->save_state, sizeof(*hw)); @@ -1317,7 +1317,7 @@ intelfb_set_par(struct fb_info *info) update_dinfo(dinfo, &info->var); - if (dinfo->accel) + if (ACCEL(dinfo, info)) intelfbhw_2d_start(dinfo); intelfb_pan_display(&info->var, info); -- cgit v1.2.3-59-g8ed1b From 4ff45f515144d232c83bf55c53f54deecb750296 Mon Sep 17 00:00:00 2001 From: Sylvain Meyer Date: Tue, 21 Jun 2005 17:17:03 -0700 Subject: [PATCH] intelfb documentation Add a small documentation of the driver parameters. Signed-off-by: Sylvain Meyer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/fb/intelfb.txt | 135 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 Documentation/fb/intelfb.txt diff --git a/Documentation/fb/intelfb.txt b/Documentation/fb/intelfb.txt new file mode 100644 index 000000000000..c12d39a23c3d --- /dev/null +++ b/Documentation/fb/intelfb.txt @@ -0,0 +1,135 @@ +Intel 830M/845G/852GM/855GM/865G/915G Framebuffer driver +================================================================ + +A. Introduction + This is a framebuffer driver for various Intel 810/815 compatible +graphics devices. These would include: + + Intel 830M + Intel 810E845G + Intel 852GM + Intel 855GM + Intel 865G + Intel 915G + +B. List of available options + + a. "video=intelfb" + enables the intelfb driver + + Recommendation: required + + b. "mode=x[-][@]" + select mode + + Recommendation: user preference + (default = 1024x768-32@70) + + c. "vram=" + select amount of system RAM in MB to allocate for the video memory + if not enough RAM was already allocated by the BIOS. + + Recommendation: 1 - 4 MB. + (default = 4 MB) + + d. "voffset=" + select at what offset in MB of the logical memory to allocate the + framebuffer memory. The intent is to avoid the memory blocks + used by standard graphics applications (XFree86). Depending on your + usage, adjust the value up or down, (0 for maximum usage, 63/127 MB + for the least amount). Note, an arbitrary setting may conflict + with XFree86. + + Recommendation: do not set + (default = 48 MB) + + e. "accel" + enable text acceleration. This can be enabled/reenabled anytime + by using 'fbset -accel true/false'. + + Recommendation: enable + (default = set) + + f. "hwcursor" + enable cursor acceleration. + + Recommendation: enable + (default = set) + + g. "mtrr" + enable MTRR. This allows data transfers to the framebuffer memory + to occur in bursts which can significantly increase performance. + Not very helpful with the intel chips because of 'shared memory'. + + Recommendation: set + (default = set) + + h. "fixed" + disable mode switching. + + Recommendation: do not set + (default = not set) + + The binary parameters can be unset with a "no" prefix, example "noaccel". + The default parameter (not named) is the mode. + +C. Kernel booting + +Separate each option/option-pair by commas (,) and the option from its value +with an equals sign (=) as in the following: + +video=i810fb:option1,option2=value2 + +Sample Usage +------------ + +In /etc/lilo.conf, add the line: + +append="video=intelfb:800x600-32@75,accel,hwcursor,vram=8" + +This will initialize the framebuffer to 800x600 at 32bpp and 75Hz. The +framebuffer will use 8 MB of System RAM. hw acceleration of text and cursor +will be enabled. + +D. Module options + + The module parameters are essentially similar to the kernel +parameters. The main difference is that you need to include a Boolean value +(1 for TRUE, and 0 for FALSE) for those options which don't need a value. + +Example, to enable MTRR, include "mtrr=1". + +Sample Usage +------------ + +Using the same setup as described above, load the module like this: + + modprobe intelfb mode=800x600-32@75 vram=8 accel=1 hwcursor=1 + +Or just add the following to /etc/modprobe.conf + + options intelfb mode=800x600-32@75 vram=8 accel=1 hwcursor=1 + +and just do a + + modprobe intelfb + + +E. Acknowledgment: + + 1. Geert Uytterhoeven - his excellent howto and the virtual + framebuffer driver code made this possible. + + 2. Jeff Hartmann for his agpgart code. + + 3. David Dawes for his original kernel 2.4 code. + + 4. The X developers. Insights were provided just by reading the + XFree86 source code. + + 5. Antonino A. Daplas for his inspiring i810fb driver. + + 6. Andrew Morton for his kernel patches maintenance. + +########################### +Sylvain -- cgit v1.2.3-59-g8ed1b From 1154ea7dcd8eed758fb5ec47393a79d5a1f0bc43 Mon Sep 17 00:00:00 2001 From: Jaya Kumar Date: Tue, 21 Jun 2005 17:17:04 -0700 Subject: [PATCH] Framebuffer driver for Arc LCD board Add support for the Arc monochrome LCD board. The board uses KS108 controllers to drive individual 64x64 LCD matrices. The board can be paneled in a variety of setups such as 2x1=128x64, 4x4=256x256 and so on. The board/host interface is through GPIO. Signed-off-by: Jaya Kumar Cc: "Antonino A. Daplas" Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- CREDITS | 7 + MAINTAINERS | 5 + drivers/video/Kconfig | 16 ++ drivers/video/Makefile | 1 + drivers/video/arcfb.c | 684 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/arcfb.h | 8 + 6 files changed, 721 insertions(+) create mode 100644 drivers/video/arcfb.c create mode 100644 include/linux/arcfb.h diff --git a/CREDITS b/CREDITS index d65ffe5a4d08..2993348ce6ce 100644 --- a/CREDITS +++ b/CREDITS @@ -1880,6 +1880,13 @@ S: Schlehenweg 9 S: D-91080 Uttenreuth S: Germany +N: Jaya Kumar +E: jayalk@intworks.biz +W: http://www.intworks.biz +D: Arc monochrome LCD framebuffer driver, x86 reboot fixups +S: Gurgaon, India +S: Kuala Lumpur, Malaysia + N: Gabor Kuti M: seasons@falcon.sch.bme.hu M: seasons@makosteszta.sote.hu diff --git a/MAINTAINERS b/MAINTAINERS index e3f0f3f157c9..0f88a70a15d8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -265,6 +265,11 @@ P: Arnaldo Carvalho de Melo M: acme@conectiva.com.br S: Maintained +ARC FRAMEBUFFER DRIVER +P: Jaya Kumar +M: jayalk@intworks.biz +S: Maintained + ARM26 ARCHITECTURE P: Ian Molton M: spyro@f2s.com diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 6be8fbec0a0e..04d3120f7236 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -322,6 +322,22 @@ config FB_FM2 This is the frame buffer device driver for the Amiga FrameMaster card from BSC (exhibited 1992 but not shipped as a CBM product). +config FB_ARC + tristate "Arc Monochrome LCD board support" + depends on FB && X86 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_SOFT_CURSOR + help + This enables support for the Arc Monochrome LCD board. The board + is based on the KS-108 lcd controller and is typically a matrix + of 2*n chips. This driver was tested with a 128x64 panel. This + driver supports it for use with x86 SBCs through a 16 bit GPIO + interface (8 bit data, 8 bit control). If you anticpate using + this driver, say Y or M; otherwise say N. You must specify the + GPIO IO address to be used for setting control and data. + config FB_ATARI bool "Atari native chipset support" depends on (FB = y) && ATARI && BROKEN diff --git a/drivers/video/Makefile b/drivers/video/Makefile index bd8dc0ffe723..b018df4e95c8 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_FB_MACMODES) += macmodes.o # Hardware specific drivers go first obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o obj-$(CONFIG_FB_AMIGA) += amifb.o c2p.o +obj-$(CONFIG_FB_ARC) += arcfb.o obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o obj-$(CONFIG_FB_CYBER) += cyberfb.o obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c new file mode 100644 index 000000000000..d28457e0c063 --- /dev/null +++ b/drivers/video/arcfb.c @@ -0,0 +1,684 @@ +/* + * linux/drivers/video/arcfb.c -- FB driver for Arc monochrome LCD board + * + * Copyright (C) 2005, Jaya Kumar + * http://www.intworks.biz/arclcd + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + * + * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven. + * + * This driver was written to be used with the Arc LCD board. Arc uses a + * set of KS108 chips that control individual 64x64 LCD matrices. The board + * can be paneled in a variety of setups such as 2x1=128x64, 4x4=256x256 and + * so on. The interface between the board and the host is TTL based GPIO. The + * GPIO requirements are 8 writable data lines and 4+n lines for control. On a + * GPIO-less system, the board can be tested by connecting the respective sigs + * up to a parallel port connector. The driver requires the IO addresses for + * data and control GPIO at load time. It is unable to probe for the + * existence of the LCD so it must be told at load time whether it should + * be enabled or not. + * + * Todo: + * - testing with 4x4 + * - testing with interrupt hw + * + * General notes: + * - User must set tuhold. It's in microseconds. According to the 108 spec, + * the hold time is supposed to be at least 1 microsecond. + * - User must set num_cols=x num_rows=y, eg: x=2 means 128 + * - User must set arcfb_enable=1 to enable it + * - User must set dio_addr=0xIOADDR cio_addr=0xIOADDR + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define floor8(a) (a&(~0x07)) +#define floorXres(a,xres) (a&(~(xres - 1))) +#define iceil8(a) (((int)((a+7)/8))*8) +#define ceil64(a) (a|0x3F) +#define ceilXres(a,xres) (a|(xres - 1)) + +/* ks108 chipset specific defines and code */ + +#define KS_SET_DPY_START_LINE 0xC0 +#define KS_SET_PAGE_NUM 0xB8 +#define KS_SET_X 0x40 +#define KS_CEHI 0x01 +#define KS_CELO 0x00 +#define KS_SEL_CMD 0x08 +#define KS_SEL_DATA 0x00 +#define KS_DPY_ON 0x3F +#define KS_DPY_OFF 0x3E +#define KS_INTACK 0x40 +#define KS_CLRINT 0x02 + +struct arcfb_par { + unsigned long dio_addr; + unsigned long cio_addr; + unsigned long c2io_addr; + atomic_t ref_count; + unsigned char cslut[9]; + struct fb_info *info; + unsigned int irq; + spinlock_t lock; +}; + +static struct fb_fix_screeninfo arcfb_fix __initdata = { + .id = "arcfb", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_MONO01, + .xpanstep = 0, + .ypanstep = 1, + .ywrapstep = 0, + .accel = FB_ACCEL_NONE, +}; + +static struct fb_var_screeninfo arcfb_var __initdata = { + .xres = 128, + .yres = 64, + .xres_virtual = 128, + .yres_virtual = 64, + .bits_per_pixel = 1, + .nonstd = 1, +}; + +static unsigned long num_cols; +static unsigned long num_rows; +static unsigned long dio_addr; +static unsigned long cio_addr; +static unsigned long c2io_addr; +static unsigned long splashval; +static unsigned long tuhold; +static unsigned int nosplash; +static unsigned int arcfb_enable; +static unsigned int irq; + +static DECLARE_WAIT_QUEUE_HEAD(arcfb_waitq); + +static void ks108_writeb_ctl(struct arcfb_par *par, + unsigned int chipindex, unsigned char value) +{ + unsigned char chipselval = par->cslut[chipindex]; + + outb(chipselval|KS_CEHI|KS_SEL_CMD, par->cio_addr); + outb(value, par->dio_addr); + udelay(tuhold); + outb(chipselval|KS_CELO|KS_SEL_CMD, par->cio_addr); +} + +static void ks108_writeb_mainctl(struct arcfb_par *par, unsigned char value) +{ + + outb(value, par->cio_addr); + udelay(tuhold); +} + +static unsigned char ks108_readb_ctl2(struct arcfb_par *par) +{ + return inb(par->c2io_addr); +} + +static void ks108_writeb_data(struct arcfb_par *par, + unsigned int chipindex, unsigned char value) +{ + unsigned char chipselval = par->cslut[chipindex]; + + outb(chipselval|KS_CEHI|KS_SEL_DATA, par->cio_addr); + outb(value, par->dio_addr); + udelay(tuhold); + outb(chipselval|KS_CELO|KS_SEL_DATA, par->cio_addr); +} + +static void ks108_set_start_line(struct arcfb_par *par, + unsigned int chipindex, unsigned char y) +{ + ks108_writeb_ctl(par, chipindex, KS_SET_DPY_START_LINE|y); +} + +static void ks108_set_yaddr(struct arcfb_par *par, + unsigned int chipindex, unsigned char y) +{ + ks108_writeb_ctl(par, chipindex, KS_SET_PAGE_NUM|y); +} + +static void ks108_set_xaddr(struct arcfb_par *par, + unsigned int chipindex, unsigned char x) +{ + ks108_writeb_ctl(par, chipindex, KS_SET_X|x); +} + +static void ks108_clear_lcd(struct arcfb_par *par, unsigned int chipindex) +{ + int i,j; + + for (i = 0; i <= 8; i++) { + ks108_set_yaddr(par, chipindex, i); + ks108_set_xaddr(par, chipindex, 0); + for (j = 0; j < 64; j++) { + ks108_writeb_data(par, chipindex, + (unsigned char) splashval); + } + } +} + +/* main arcfb functions */ + +static int arcfb_open(struct fb_info *info, int user) +{ + struct arcfb_par *par = info->par; + + atomic_inc(&par->ref_count); + return 0; +} + +static int arcfb_release(struct fb_info *info, int user) +{ + struct arcfb_par *par = info->par; + int count = atomic_read(&par->ref_count); + + if (!count) + return -EINVAL; + atomic_dec(&par->ref_count); + return 0; +} + +static int arcfb_pan_display(struct fb_var_screeninfo *var, + struct fb_info *info) +{ + int i; + struct arcfb_par *par = info->par; + + if ((var->vmode & FB_VMODE_YWRAP) && (var->yoffset < 64) + && (info->var.yres <= 64)) { + for (i = 0; i < num_cols; i++) { + ks108_set_start_line(par, i, var->yoffset); + } + info->var.yoffset = var->yoffset; + return 0; + } + + return -EINVAL; +} + +static irqreturn_t arcfb_interrupt(int vec, void *dev_instance, + struct pt_regs *regs) +{ + struct fb_info *info = dev_instance; + unsigned char ctl2status; + struct arcfb_par *par = info->par; + + ctl2status = ks108_readb_ctl2(par); + + if (!(ctl2status & KS_INTACK)) /* not arc generated interrupt */ + return IRQ_NONE; + + ks108_writeb_mainctl(par, KS_CLRINT); + + spin_lock(&par->lock); + if (waitqueue_active(&arcfb_waitq)) { + wake_up(&arcfb_waitq); + } + spin_unlock(&par->lock); + + return IRQ_HANDLED; +} + +/* + * here we handle a specific page on the lcd. the complexity comes from + * the fact that the fb is laidout in 8xX vertical columns. we extract + * each write of 8 vertical pixels. then we shift out as we move along + * X. That's what rightshift does. bitmask selects the desired input bit. + */ +static void arcfb_lcd_update_page(struct arcfb_par *par, unsigned int upper, + unsigned int left, unsigned int right, unsigned int distance) +{ + unsigned char *src; + unsigned int xindex, yindex, chipindex, linesize; + int i, count; + unsigned char val; + unsigned char bitmask, rightshift; + + xindex = left >> 6; + yindex = upper >> 6; + chipindex = (xindex + (yindex*num_cols)); + + ks108_set_yaddr(par, chipindex, upper/8); + + linesize = par->info->var.xres/8; + src = par->info->screen_base + (left/8) + (upper * linesize); + ks108_set_xaddr(par, chipindex, left); + + bitmask=1; + rightshift=0; + while (left <= right) { + val = 0; + for (i = 0; i < 8; i++) { + if ( i > rightshift) { + val |= (*(src + (i*linesize)) & bitmask) + << (i - rightshift); + } else { + val |= (*(src + (i*linesize)) & bitmask) + >> (rightshift - i); + } + } + ks108_writeb_data(par, chipindex, val); + left++; + count++; + if (bitmask == 0x80) { + bitmask = 1; + src++; + rightshift=0; + } else { + bitmask <<= 1; + rightshift++; + } + } +} + +/* + * here we handle the entire vertical page of the update. we write across + * lcd chips. update_page uses the upper/left values to decide which + * chip to select for the right. upper is needed for setting the page + * desired for the write. + */ +static void arcfb_lcd_update_vert(struct arcfb_par *par, unsigned int top, + unsigned int bottom, unsigned int left, unsigned int right) +{ + unsigned int distance, upper, lower; + + distance = (bottom - top) + 1; + upper = top; + lower = top + 7; + + while (distance > 0) { + distance -= 8; + arcfb_lcd_update_page(par, upper, left, right, 8); + upper = lower + 1; + lower = upper + 7; + } +} + +/* + * here we handle horizontal blocks for the update. update_vert will + * handle spaning multiple pages. we break out each horizontal + * block in to individual blocks no taller than 64 pixels. + */ +static void arcfb_lcd_update_horiz(struct arcfb_par *par, unsigned int left, + unsigned int right, unsigned int top, unsigned int h) +{ + unsigned int distance, upper, lower; + + distance = h; + upper = floor8(top); + lower = min(upper + distance - 1, ceil64(upper)); + + while (distance > 0) { + distance -= ((lower - upper) + 1 ); + arcfb_lcd_update_vert(par, upper, lower, left, right); + upper = lower + 1; + lower = min(upper + distance - 1, ceil64(upper)); + } +} + +/* + * here we start the process of spliting out the fb update into + * individual blocks of pixels. we end up spliting into 64x64 blocks + * and finally down to 64x8 pages. + */ +static void arcfb_lcd_update(struct arcfb_par *par, unsigned int dx, + unsigned int dy, unsigned int w, unsigned int h) +{ + unsigned int left, right, distance, y; + + /* align the request first */ + y = floor8(dy); + h += dy - y; + h = iceil8(h); + + distance = w; + left = dx; + right = min(left + w - 1, ceil64(left)); + + while (distance > 0) { + arcfb_lcd_update_horiz(par, left, right, y, h); + distance -= ((right - left) + 1); + left = right + 1; + right = min(left + distance - 1, ceil64(left)); + } +} + +void arcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) +{ + struct arcfb_par *par = info->par; + + cfb_fillrect(info, rect); + + /* update the physical lcd */ + arcfb_lcd_update(par, rect->dx, rect->dy, rect->width, rect->height); +} + +void arcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) +{ + struct arcfb_par *par = info->par; + + cfb_copyarea(info, area); + + /* update the physical lcd */ + arcfb_lcd_update(par, area->dx, area->dy, area->width, area->height); +} + +void arcfb_imageblit(struct fb_info *info, const struct fb_image *image) +{ + struct arcfb_par *par = info->par; + + cfb_imageblit(info, image); + + /* update the physical lcd */ + arcfb_lcd_update(par, image->dx, image->dy, image->width, + image->height); +} + +static int arcfb_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg, + struct fb_info *info) +{ + void __user *argp = (void __user *)arg; + struct arcfb_par *par = info->par; + unsigned long flags; + + switch (cmd) { + case FBIO_WAITEVENT: + { + DEFINE_WAIT(wait); + /* illegal to wait on arc if no irq will occur */ + if (!par->irq) + return -EINVAL; + + /* wait until the Arc has generated an interrupt + * which will wake us up */ + spin_lock_irqsave(&par->lock, flags); + prepare_to_wait(&arcfb_waitq, &wait, + TASK_INTERRUPTIBLE); + spin_unlock_irqrestore(&par->lock, flags); + schedule(); + finish_wait(&arcfb_waitq, &wait); + } + case FBIO_GETCONTROL2: + { + unsigned char ctl2; + + ctl2 = ks108_readb_ctl2(info->par); + if (copy_to_user(argp, &ctl2, sizeof(ctl2))) + return -EFAULT; + return 0; + } + default: + return -EINVAL; + } +} + +/* + * this is the access path from userspace. they can seek and write to + * the fb. it's inefficient for them to do anything less than 64*8 + * writes since we update the lcd in each write() anyway. + */ +static ssize_t arcfb_write(struct file *file, const char *buf, size_t count, + loff_t *ppos) +{ + /* modded from epson 1355 */ + + struct inode *inode; + int fbidx; + struct fb_info *info; + unsigned long p; + int err=-EINVAL; + unsigned int fbmemlength,x,y,w,h, bitppos, startpos, endpos, bitcount; + struct arcfb_par *par; + unsigned int xres; + + p = *ppos; + inode = file->f_dentry->d_inode; + fbidx = iminor(inode); + info = registered_fb[fbidx]; + par = info->par; + + if (!info || !info->screen_base) + return -ENODEV; + + xres = info->var.xres; + fbmemlength = (xres * info->var.yres)/8; + + if (p > fbmemlength) + return -ENOSPC; + + err = 0; + if ((count + p) > fbmemlength) { + count = fbmemlength - p; + err = -ENOSPC; + } + + if (count) { + char *base_addr; + + base_addr = info->screen_base; + count -= copy_from_user(base_addr + p, buf, count); + *ppos += count; + err = -EFAULT; + } + + + bitppos = p*8; + startpos = floorXres(bitppos, xres); + endpos = ceilXres((bitppos + (count*8)), xres); + bitcount = endpos - startpos; + + x = startpos % xres; + y = startpos / xres; + w = xres; + h = bitcount / xres; + arcfb_lcd_update(par, x, y, w, h); + + if (count) + return count; + return err; +} + +static void arcfb_platform_release(struct device *device) +{ +} + +static struct fb_ops arcfb_ops = { + .owner = THIS_MODULE, + .fb_open = arcfb_open, + .fb_write = arcfb_write, + .fb_release = arcfb_release, + .fb_pan_display = arcfb_pan_display, + .fb_fillrect = arcfb_fillrect, + .fb_copyarea = arcfb_copyarea, + .fb_imageblit = arcfb_imageblit, + .fb_cursor = soft_cursor, + .fb_ioctl = arcfb_ioctl, +}; + +static int __init arcfb_probe(struct device *device) +{ + struct platform_device *dev = to_platform_device(device); + struct fb_info *info; + int retval = -ENOMEM; + int videomemorysize; + unsigned char *videomemory; + struct arcfb_par *par; + int i; + + videomemorysize = (((64*64)*num_cols)*num_rows)/8; + + /* We need a flat backing store for the Arc's + less-flat actual paged framebuffer */ + if (!(videomemory = vmalloc(videomemorysize))) + return retval; + + memset(videomemory, 0, videomemorysize); + + info = framebuffer_alloc(sizeof(struct arcfb_par), &dev->dev); + if (!info) + goto err; + + info->screen_base = (char __iomem *)videomemory; + info->fbops = &arcfb_ops; + + info->var = arcfb_var; + info->fix = arcfb_fix; + par = info->par; + par->info = info; + + if (!dio_addr || !cio_addr || !c2io_addr) { + printk(KERN_WARNING "no IO addresses supplied\n"); + goto err1; + } + par->dio_addr = dio_addr; + par->cio_addr = cio_addr; + par->c2io_addr = c2io_addr; + par->cslut[0] = 0x00; + par->cslut[1] = 0x06; + info->flags = FBINFO_FLAG_DEFAULT; + spin_lock_init(&par->lock); + retval = register_framebuffer(info); + if (retval < 0) + goto err1; + dev_set_drvdata(&dev->dev, info); + if (irq) { + par->irq = irq; + if (request_irq(par->irq, &arcfb_interrupt, SA_SHIRQ, + "arcfb", info)) { + printk(KERN_INFO + "arcfb: Failed req IRQ %d\n", par->irq); + goto err1; + } + } + printk(KERN_INFO + "fb%d: Arc frame buffer device, using %dK of video memory\n", + info->node, videomemorysize >> 10); + + /* this inits the lcd but doesn't clear dirty pixels */ + for (i = 0; i < num_cols * num_rows; i++) { + ks108_writeb_ctl(par, i, KS_DPY_OFF); + ks108_set_start_line(par, i, 0); + ks108_set_yaddr(par, i, 0); + ks108_set_xaddr(par, i, 0); + ks108_writeb_ctl(par, i, KS_DPY_ON); + } + + /* if we were told to splash the screen, we just clear it */ + if (!nosplash) { + for (i = 0; i < num_cols * num_rows; i++) { + printk(KERN_INFO "fb%d: splashing lcd %d\n", + info->node, i); + ks108_set_start_line(par, i, 0); + ks108_clear_lcd(par, i); + } + } + + return 0; +err1: + framebuffer_release(info); +err: + vfree(videomemory); + return retval; +} + +static int arcfb_remove(struct device *device) +{ + struct fb_info *info = dev_get_drvdata(device); + + if (info) { + unregister_framebuffer(info); + vfree(info->screen_base); + framebuffer_release(info); + } + return 0; +} + +static struct device_driver arcfb_driver = { + .name = "arcfb", + .bus = &platform_bus_type, + .probe = arcfb_probe, + .remove = arcfb_remove, +}; + +static struct platform_device arcfb_device = { + .name = "arcfb", + .id = 0, + .dev = { + .release = arcfb_platform_release, + } +}; + +static int __init arcfb_init(void) +{ + int ret; + + if (!arcfb_enable) + return -ENXIO; + + ret = driver_register(&arcfb_driver); + if (!ret) { + ret = platform_device_register(&arcfb_device); + if (ret) + driver_unregister(&arcfb_driver); + } + return ret; + +} + +static void __exit arcfb_exit(void) +{ + platform_device_unregister(&arcfb_device); + driver_unregister(&arcfb_driver); +} + +module_param(num_cols, ulong, 0); +MODULE_PARM_DESC(num_cols, "Num horiz panels, eg: 2 = 128 bit wide"); +module_param(num_rows, ulong, 0); +MODULE_PARM_DESC(num_rows, "Num vert panels, eg: 1 = 64 bit high"); +module_param(nosplash, uint, 0); +MODULE_PARM_DESC(nosplash, "Disable doing the splash screen"); +module_param(arcfb_enable, uint, 0); +MODULE_PARM_DESC(arcfb_enable, "Enable communication with Arc board"); +module_param(dio_addr, ulong, 0); +MODULE_PARM_DESC(dio_addr, "IO address for data, eg: 0x480"); +module_param(cio_addr, ulong, 0); +MODULE_PARM_DESC(cio_addr, "IO address for control, eg: 0x400"); +module_param(c2io_addr, ulong, 0); +MODULE_PARM_DESC(c2io_addr, "IO address for secondary control, eg: 0x408"); +module_param(splashval, ulong, 0); +MODULE_PARM_DESC(splashval, "Splash pattern: 0xFF is black, 0x00 is green"); +module_param(tuhold, ulong, 0); +MODULE_PARM_DESC(tuhold, "Time to hold between strobing data to Arc board"); +module_param(irq, uint, 0); +MODULE_PARM_DESC(irq, "IRQ for the Arc board"); + +module_init(arcfb_init); +module_exit(arcfb_exit); + +MODULE_DESCRIPTION("fbdev driver for Arc monochrome LCD board"); +MODULE_AUTHOR("Jaya Kumar"); +MODULE_LICENSE("GPL"); + diff --git a/include/linux/arcfb.h b/include/linux/arcfb.h new file mode 100644 index 000000000000..721e7654daeb --- /dev/null +++ b/include/linux/arcfb.h @@ -0,0 +1,8 @@ +#ifndef __LINUX_ARCFB_H__ +#define __LINUX_ARCFB_H__ + +#define FBIO_WAITEVENT _IO('F', 0x88) +#define FBIO_GETCONTROL2 _IOR('F', 0x89, size_t) + +#endif + -- cgit v1.2.3-59-g8ed1b From d5881eb4883ef7dd28a4dcea237714817c4b2f8e Mon Sep 17 00:00:00 2001 From: James Simmons Date: Tue, 21 Jun 2005 17:17:05 -0700 Subject: [PATCH] fbdev: new pci id for chipsfb Patch adds pci ID for CT 69000 chipset. Signed-off-by: James Simmons Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pci_ids.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index b8b4ebf9abf1..63e89e47b8e9 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -575,6 +575,7 @@ #define PCI_DEVICE_ID_CT_65550 0x00e0 #define PCI_DEVICE_ID_CT_65554 0x00e4 #define PCI_DEVICE_ID_CT_65555 0x00e5 +#define PCI_DEVICE_ID_CT_69000 0x00c0 #define PCI_VENDOR_ID_MIRO 0x1031 #define PCI_DEVICE_ID_MIRO_36050 0x5601 -- cgit v1.2.3-59-g8ed1b From 303b86d9913eca0cbfc3c5cb41e7006f6e13b755 Mon Sep 17 00:00:00 2001 From: Jurriaan Date: Tue, 21 Jun 2005 17:17:06 -0700 Subject: [PATCH] New framebuffer fonts + updated 12x22 font available Improve the fonts for use with the framebuffer. I've added all the characters marked 'FIXME' in the sun12x22 font and created a 10x18 font (based on the sun12x22 font) and a 7x14 font (based on the vga8x16 font). This patch is non-intrusive, no options are enabled by default so most users won't notice a thing. I am placing my changes under the GPL, however, I've not seen any copyright notices on the sun12x22 font and the vga8x16 font which I derived my new fonts from so I don't know what the copyright status is. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/console/Kconfig | 17 + drivers/video/console/Makefile | 2 + drivers/video/console/font_10x18.c | 5146 +++++++++++++++++++++++++++++++++ drivers/video/console/font_7x14.c | 4118 ++++++++++++++++++++++++++ drivers/video/console/font_sun12x22.c | 1579 +++++----- drivers/video/console/fonts.c | 8 + include/linux/font.h | 26 +- 7 files changed, 10068 insertions(+), 828 deletions(-) create mode 100644 drivers/video/console/font_10x18.c create mode 100644 drivers/video/console/font_7x14.c diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index ccf55811d24f..e4b91a4b936c 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -153,6 +153,15 @@ config FONT_6x11 Small console font with Macintosh-style high-half glyphs. Some Mac framebuffer drivers don't support this one at all. +config FONT_7x14 + bool "console 7x14 font (not supported by all drivers)" if FONTS + depends on FRAMEBUFFER_CONSOLE + default y if !SPARC32 && !SPARC64 && !FONTS + help + Console font with characters just a bit smaller than the default. + If the standard 8x16 font is a little too big for you, say Y. + Otherwise, say N. + config FONT_PEARL_8x8 bool "Pearl (old m68k) console 8x8 font" if FONTS depends on FRAMEBUFFER_CONSOLE @@ -187,5 +196,13 @@ config FONT_SUN12x22 big letters (like the letters used in the SPARC PROM). If the standard font is unreadable for you, say Y, otherwise say N. +config FONT_10x18 + bool "console 10x18 font (not supported by all drivers)" + depends on FONTS + help + This is a high resolution console font for machines with very + big letters. It fits between the sun 12x22 and the normal 8x16 font. + If other fonts are too big or too small for you, say Y, otherwise say N. + endmenu diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile index 33516447f9f2..b562f6bb9d31 100644 --- a/drivers/video/console/Makefile +++ b/drivers/video/console/Makefile @@ -10,6 +10,8 @@ font-objs-$(CONFIG_FONT_SUN12x22) += font_sun12x22.o font-objs-$(CONFIG_FONT_8x8) += font_8x8.o font-objs-$(CONFIG_FONT_8x16) += font_8x16.o font-objs-$(CONFIG_FONT_6x11) += font_6x11.o +font-objs-$(CONFIG_FONT_7x14) += font_7x14.o +font-objs-$(CONFIG_FONT_10x18) += font_10x18.o font-objs-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o font-objs-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o font-objs-$(CONFIG_FONT_MINI_4x6) += font_mini_4x6.o diff --git a/drivers/video/console/font_10x18.c b/drivers/video/console/font_10x18.c new file mode 100644 index 000000000000..ff0af96e4dfc --- /dev/null +++ b/drivers/video/console/font_10x18.c @@ -0,0 +1,5146 @@ +/******************************** + * adapted from font_sun12x22.c * + * by Jurriaan Kalkman 06-2005 * + ********************************/ + +#include + +#define FONTDATAMAX 9216 + +static unsigned char fontdata_10x18[FONTDATAMAX] = { + + /* 0 0x00 '^@' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 1 0x01 '^A' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x3f, 0x80, /* 0011111110 */ + 0x40, 0x40, /* 0100000001 */ + 0x5b, 0x40, /* 0101101101 */ + 0x40, 0x40, /* 0100000001 */ + 0x44, 0x40, /* 0100010001 */ + 0x44, 0x40, /* 0100010001 */ + 0x51, 0x40, /* 0101000101 */ + 0x4e, 0x40, /* 0100111001 */ + 0x40, 0x40, /* 0100000001 */ + 0x3f, 0x80, /* 0011111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 2 0x02 '^B' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x3f, 0x80, /* 0011111110 */ + 0x7f, 0xc0, /* 0111111111 */ + 0x64, 0xc0, /* 0110010011 */ + 0x7f, 0xc0, /* 0111111111 */ + 0x7b, 0xc0, /* 0111101111 */ + 0x7b, 0xc0, /* 0111101111 */ + 0x6e, 0xc0, /* 0110111011 */ + 0x71, 0xc0, /* 0111000111 */ + 0x7f, 0xc0, /* 0111111111 */ + 0x3f, 0x80, /* 0011111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 3 0x03 '^C' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x11, 0x00, /* 0001000100 */ + 0x3b, 0x80, /* 0011101110 */ + 0x7f, 0xc0, /* 0111111111 */ + 0x3f, 0x80, /* 0011111110 */ + 0x3f, 0x80, /* 0011111110 */ + 0x1f, 0x00, /* 0001111100 */ + 0x1f, 0x00, /* 0001111100 */ + 0x0e, 0x00, /* 0000111000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x04, 0x00, /* 0000010000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 4 0x04 '^D' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x04, 0x00, /* 0000010000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x1f, 0x00, /* 0001111100 */ + 0x3f, 0x80, /* 0011111110 */ + 0x1f, 0x00, /* 0001111100 */ + 0x1f, 0x00, /* 0001111100 */ + 0x0e, 0x00, /* 0000111000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x04, 0x00, /* 0000010000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 5 0x05 '^E' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x31, 0x80, /* 0011000110 */ + 0x7b, 0xc0, /* 0111101111 */ + 0x35, 0x80, /* 0011010110 */ + 0x04, 0x00, /* 0000010000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 6 0x06 '^F' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x04, 0x00, /* 0000010000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x1f, 0x00, /* 0001111100 */ + 0x3f, 0x80, /* 0011111110 */ + 0x7f, 0xc0, /* 0111111111 */ + 0x7f, 0xc0, /* 0111111111 */ + 0x35, 0x80, /* 0011010110 */ + 0x04, 0x00, /* 0000010000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 7 0x07 '^G' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x3f, 0x00, /* 0011111100 */ + 0x1e, 0x00, /* 0001111000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 8 0x08 '^H' */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xf3, 0xc0, /* 1111001111 */ + 0xe1, 0xc0, /* 1110000111 */ + 0xe1, 0xc0, /* 1110000111 */ + 0xc0, 0xc0, /* 1100000011 */ + 0xc0, 0xc0, /* 1100000011 */ + 0xe1, 0xc0, /* 1110000111 */ + 0xe1, 0xc0, /* 1110000111 */ + 0xf3, 0xc0, /* 1111001111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + + /* 9 0x09 '^I' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x12, 0x00, /* 0001001000 */ + 0x12, 0x00, /* 0001001000 */ + 0x21, 0x00, /* 0010000100 */ + 0x21, 0x00, /* 0010000100 */ + 0x12, 0x00, /* 0001001000 */ + 0x12, 0x00, /* 0001001000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 10 0x0a '^J' */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xf3, 0xc0, /* 1111001111 */ + 0xed, 0xc0, /* 1110110111 */ + 0xed, 0xc0, /* 1110110111 */ + 0xde, 0xc0, /* 1101111011 */ + 0xde, 0xc0, /* 1101111011 */ + 0xed, 0xc0, /* 1110110111 */ + 0xed, 0xc0, /* 1110110111 */ + 0xf3, 0xc0, /* 1111001111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + + /* 11 0x0b '^K' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x03, 0xc0, /* 0000001111 */ + 0x06, 0xc0, /* 0000011011 */ + 0x0c, 0xc0, /* 0000110011 */ + 0x3c, 0x00, /* 0011110000 */ + 0x66, 0x00, /* 0110011000 */ + 0xc3, 0x00, /* 1100001100 */ + 0xc3, 0x00, /* 1100001100 */ + 0xc3, 0x00, /* 1100001100 */ + 0x66, 0x00, /* 0110011000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 12 0x0c '^L' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x33, 0x00, /* 0011001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x33, 0x00, /* 0011001100 */ + 0x1e, 0x00, /* 0001111000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 13 0x0d '^M' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0f, 0x80, /* 0000111110 */ + 0x08, 0x80, /* 0000100010 */ + 0x0f, 0x80, /* 0000111110 */ + 0x08, 0x00, /* 0000100000 */ + 0x08, 0x00, /* 0000100000 */ + 0x08, 0x00, /* 0000100000 */ + 0x08, 0x00, /* 0000100000 */ + 0x08, 0x00, /* 0000100000 */ + 0x08, 0x00, /* 0000100000 */ + 0x38, 0x00, /* 0011100000 */ + 0x78, 0x00, /* 0111100000 */ + 0x30, 0x00, /* 0011000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 14 0x0e '^N' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x1f, 0x80, /* 0001111110 */ + 0x10, 0x80, /* 0001000010 */ + 0x1f, 0x80, /* 0001111110 */ + 0x10, 0x80, /* 0001000010 */ + 0x10, 0x80, /* 0001000010 */ + 0x10, 0x80, /* 0001000010 */ + 0x10, 0x80, /* 0001000010 */ + 0x13, 0x80, /* 0001001110 */ + 0x17, 0x80, /* 0001011110 */ + 0x73, 0x00, /* 0111001100 */ + 0xf0, 0x00, /* 1111000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 15 0x0f '^O' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x04, 0x00, /* 0000010000 */ + 0x24, 0x80, /* 0010010010 */ + 0x15, 0x00, /* 0001010100 */ + 0x55, 0x40, /* 0101010101 */ + 0x3f, 0x80, /* 0011111110 */ + 0x0e, 0x00, /* 0000111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x3f, 0x80, /* 0011111110 */ + 0x55, 0x40, /* 0101010101 */ + 0x15, 0x00, /* 0001010100 */ + 0x24, 0x80, /* 0010010010 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 16 0x10 '^P' */ + 0x00, 0x80, /* 0000000010 */ + 0x01, 0x80, /* 0000000110 */ + 0x03, 0x80, /* 0000001110 */ + 0x07, 0x80, /* 0000011110 */ + 0x0f, 0x80, /* 0000111110 */ + 0x1f, 0x80, /* 0001111110 */ + 0x3f, 0x80, /* 0011111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0xff, 0x80, /* 1111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x3f, 0x80, /* 0011111110 */ + 0x1f, 0x80, /* 0001111110 */ + 0x0f, 0x80, /* 0000111110 */ + 0x07, 0x80, /* 0000011110 */ + 0x03, 0x80, /* 0000001110 */ + 0x01, 0x80, /* 0000000110 */ + 0x00, 0x80, /* 0000000010 */ + 0x00, 0x00, /* 0000000000 */ + + /* 17 0x11 '^Q' */ + 0x40, 0x00, /* 0100000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x70, 0x00, /* 0111000000 */ + 0x78, 0x00, /* 0111100000 */ + 0x7c, 0x00, /* 0111110000 */ + 0x7e, 0x00, /* 0111111000 */ + 0x7f, 0x00, /* 0111111100 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0xc0, /* 0111111111 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x00, /* 0111111100 */ + 0x7e, 0x00, /* 0111111000 */ + 0x7c, 0x00, /* 0111110000 */ + 0x78, 0x00, /* 0111100000 */ + 0x70, 0x00, /* 0111000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x40, 0x00, /* 0100000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 18 0x12 '^R' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x7f, 0x80, /* 0111111110 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x3f, 0x00, /* 0011111100 */ + 0x1e, 0x00, /* 0001111000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 19 0x13 '^S' */ + 0x00, 0x00, /* 0000000000 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 20 0x14 '^T' */ + 0x00, 0x00, /* 0000000000 */ + 0x1f, 0xc0, /* 0001111111 */ + 0x39, 0x80, /* 0011100110 */ + 0x79, 0x80, /* 0111100110 */ + 0x79, 0x80, /* 0111100110 */ + 0x79, 0x80, /* 0111100110 */ + 0x39, 0x80, /* 0011100110 */ + 0x19, 0x80, /* 0001100110 */ + 0x19, 0x80, /* 0001100110 */ + 0x19, 0x80, /* 0001100110 */ + 0x19, 0x80, /* 0001100110 */ + 0x19, 0x80, /* 0001100110 */ + 0x19, 0x80, /* 0001100110 */ + 0x39, 0xc0, /* 0011100111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 21 0x15 '^U' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x3e, 0x00, /* 0011111000 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x3e, 0x00, /* 0011111000 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x3e, 0x00, /* 0011111000 */ + 0x03, 0x00, /* 0000001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x3e, 0x00, /* 0011111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 22 0x16 '^V' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 23 0x17 '^W' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x7f, 0x80, /* 0111111110 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x3f, 0x00, /* 0011111100 */ + 0x1e, 0x00, /* 0001111000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 24 0x18 '^X' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x7f, 0x80, /* 0111111110 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 25 0x19 '^Y' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x3f, 0x00, /* 0011111100 */ + 0x1e, 0x00, /* 0001111000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 26 0x1a '^Z' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x04, 0x00, /* 0000010000 */ + 0x06, 0x00, /* 0000011000 */ + 0x07, 0x00, /* 0000011100 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x07, 0x00, /* 0000011100 */ + 0x06, 0x00, /* 0000011000 */ + 0x04, 0x00, /* 0000010000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 27 0x1b '^[' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x08, 0x00, /* 0000100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x38, 0x00, /* 0011100000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x38, 0x00, /* 0011100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x08, 0x00, /* 0000100000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 28 0x1c '^\' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 29 0x1d '^]' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x12, 0x00, /* 0001001000 */ + 0x33, 0x00, /* 0011001100 */ + 0x73, 0x80, /* 0111001110 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x73, 0x80, /* 0111001110 */ + 0x33, 0x00, /* 0011001100 */ + 0x12, 0x00, /* 0001001000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 30 0x1e '^^' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x04, 0x00, /* 0000010000 */ + 0x04, 0x00, /* 0000010000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x1f, 0x00, /* 0001111100 */ + 0x3f, 0x80, /* 0011111110 */ + 0x3f, 0x80, /* 0011111110 */ + 0x7f, 0xc0, /* 0111111111 */ + 0x7f, 0xc0, /* 0111111111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 31 0x1f '^_' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0xc0, /* 0111111111 */ + 0x7f, 0xc0, /* 0111111111 */ + 0x3f, 0x80, /* 0011111110 */ + 0x3f, 0x80, /* 0011111110 */ + 0x1f, 0x00, /* 0001111100 */ + 0x1f, 0x00, /* 0001111100 */ + 0x0e, 0x00, /* 0000111000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x04, 0x00, /* 0000010000 */ + 0x04, 0x00, /* 0000010000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 32 0x20 ' ' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 33 0x21 '!' */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 34 0x22 '"' */ + 0x00, 0x00, /* 0000000000 */ + 0x63, 0x00, /* 0110001100 */ + 0xf7, 0x80, /* 1111011110 */ + 0xf7, 0x80, /* 1111011110 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x63, 0x00, /* 0110001100 */ + 0x42, 0x00, /* 0100001000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 35 0x23 '#' */ + 0x00, 0x00, /* 0000000000 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 36 0x24 '$' */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x3e, 0x00, /* 0011111000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x6f, 0x80, /* 0110111110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x6c, 0x80, /* 0110110010 */ + 0x3c, 0x00, /* 0011110000 */ + 0x0f, 0x00, /* 0000111100 */ + 0x0d, 0x80, /* 0000110110 */ + 0x4d, 0x80, /* 0100110110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x7f, 0x00, /* 0111111100 */ + 0x3e, 0x00, /* 0011111000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 37 0x25 '%' */ + 0x00, 0x00, /* 0000000000 */ + 0x31, 0x80, /* 0011000110 */ + 0x7b, 0x00, /* 0111101100 */ + 0x7b, 0x00, /* 0111101100 */ + 0x36, 0x00, /* 0011011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x1b, 0x00, /* 0001101100 */ + 0x37, 0x80, /* 0011011110 */ + 0x37, 0x80, /* 0011011110 */ + 0x63, 0x00, /* 0110001100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 38 0x26 '&' */ + 0x00, 0x00, /* 0000000000 */ + 0x07, 0x00, /* 0000011100 */ + 0x0f, 0x80, /* 0000111110 */ + 0x19, 0x80, /* 0001100110 */ + 0x19, 0x80, /* 0001100110 */ + 0x0f, 0x80, /* 0000111110 */ + 0x1e, 0x00, /* 0001111000 */ + 0x3e, 0x00, /* 0011111000 */ + 0x76, 0x00, /* 0111011000 */ + 0x66, 0x40, /* 0110011001 */ + 0x63, 0xc0, /* 0110001111 */ + 0x63, 0x80, /* 0110001110 */ + 0x63, 0x00, /* 0110001100 */ + 0x3f, 0x80, /* 0011111110 */ + 0x1c, 0xc0, /* 0001110011 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 39 0x27 ''' */ + 0x00, 0x00, /* 0000000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x78, 0x00, /* 0111100000 */ + 0x78, 0x00, /* 0111100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x30, 0x00, /* 0011000000 */ + 0x20, 0x00, /* 0010000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 40 0x28 '(' */ + 0x00, 0x00, /* 0000000000 */ + 0x03, 0x00, /* 0000001100 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x06, 0x00, /* 0000011000 */ + 0x03, 0x00, /* 0000001100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 41 0x29 ')' */ + 0x00, 0x00, /* 0000000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x18, 0x00, /* 0001100000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x30, 0x00, /* 0011000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 42 0x2a '*' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x4c, 0x80, /* 0100110010 */ + 0x6d, 0x80, /* 0110110110 */ + 0x3f, 0x00, /* 0011111100 */ + 0x7f, 0x80, /* 0111111110 */ + 0x3f, 0x00, /* 0011111100 */ + 0x6d, 0x80, /* 0110110110 */ + 0x4c, 0x80, /* 0100110010 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 43 0x2b '+' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 44 0x2c ',' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x78, 0x00, /* 0111100000 */ + 0x78, 0x00, /* 0111100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x30, 0x00, /* 0011000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x40, 0x00, /* 0100000000 */ + + /* 45 0x2d '-' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 46 0x2e '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x18, 0x00, /* 0001100000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 47 0x2f '/' */ + 0x00, 0x00, /* 0000000000 */ + 0x01, 0x80, /* 0000000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x03, 0x00, /* 0000001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 48 0x30 '0' */ + 0x00, 0x00, /* 0000000000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x23, 0x00, /* 0010001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x63, 0x80, /* 0110001110 */ + 0x65, 0x80, /* 0110010110 */ + 0x65, 0x80, /* 0110010110 */ + 0x69, 0x80, /* 0110100110 */ + 0x69, 0x80, /* 0110100110 */ + 0x71, 0x80, /* 0111000110 */ + 0x61, 0x00, /* 0110000100 */ + 0x31, 0x00, /* 0011000100 */ + 0x3e, 0x00, /* 0011111000 */ + 0x1c, 0x00, /* 0001110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 49 0x31 '1' */ + 0x00, 0x00, /* 0000000000 */ + 0x04, 0x00, /* 0000010000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x1c, 0x00, /* 0001110000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x6c, 0x00, /* 0110110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 50 0x32 '2' */ + 0x00, 0x00, /* 0000000000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x63, 0x80, /* 0110001110 */ + 0x41, 0x80, /* 0100000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x03, 0x00, /* 0000001100 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x30, 0x80, /* 0011000010 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 51 0x33 '3' */ + 0x00, 0x00, /* 0000000000 */ + 0x1c, 0x00, /* 0001110000 */ + 0x3e, 0x00, /* 0011111000 */ + 0x47, 0x00, /* 0100011100 */ + 0x03, 0x00, /* 0000001100 */ + 0x07, 0x00, /* 0000011100 */ + 0x06, 0x00, /* 0000011000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x07, 0x00, /* 0000011100 */ + 0x03, 0x00, /* 0000001100 */ + 0x01, 0x80, /* 0000000110 */ + 0x41, 0x80, /* 0100000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x3f, 0x00, /* 0011111100 */ + 0x1e, 0x00, /* 0001111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 52 0x34 '4' */ + 0x00, 0x00, /* 0000000000 */ + 0x06, 0x00, /* 0000011000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x36, 0x00, /* 0011011000 */ + 0x36, 0x00, /* 0011011000 */ + 0x66, 0x00, /* 0110011000 */ + 0x66, 0x00, /* 0110011000 */ + 0xc6, 0x00, /* 1100011000 */ + 0xc6, 0x00, /* 1100011000 */ + 0xff, 0x80, /* 1111111110 */ + 0xff, 0x80, /* 1111111110 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 53 0x35 '5' */ + 0x00, 0x00, /* 0000000000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x1f, 0x00, /* 0001111100 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x7e, 0x00, /* 0111111000 */ + 0x67, 0x00, /* 0110011100 */ + 0x03, 0x80, /* 0000001110 */ + 0x01, 0x80, /* 0000000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x41, 0x80, /* 0100000110 */ + 0x63, 0x00, /* 0110001100 */ + 0x3e, 0x00, /* 0011111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 54 0x36 '6' */ + 0x00, 0x00, /* 0000000000 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x6e, 0x00, /* 0110111000 */ + 0x7f, 0x00, /* 0111111100 */ + 0x73, 0x80, /* 0111001110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x71, 0x00, /* 0111000100 */ + 0x3e, 0x00, /* 0011111000 */ + 0x1c, 0x00, /* 0001110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 55 0x37 '7' */ + 0x00, 0x00, /* 0000000000 */ + 0x1f, 0x80, /* 0001111110 */ + 0x3f, 0x80, /* 0011111110 */ + 0x61, 0x80, /* 0110000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x03, 0x00, /* 0000001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 56 0x38 '8' */ + 0x00, 0x00, /* 0000000000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x23, 0x00, /* 0010001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x31, 0x00, /* 0011000100 */ + 0x1a, 0x00, /* 0001101000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x16, 0x00, /* 0001011000 */ + 0x23, 0x00, /* 0010001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x31, 0x00, /* 0011000100 */ + 0x1e, 0x00, /* 0001111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 57 0x39 '9' */ + 0x00, 0x00, /* 0000000000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x17, 0x00, /* 0001011100 */ + 0x23, 0x80, /* 0010001110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x73, 0x80, /* 0111001110 */ + 0x3d, 0x80, /* 0011110110 */ + 0x19, 0x80, /* 0001100110 */ + 0x01, 0x80, /* 0000000110 */ + 0x03, 0x00, /* 0000001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 58 0x3a ':' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x18, 0x00, /* 0001100000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x18, 0x00, /* 0001100000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 59 0x3b ';' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x18, 0x00, /* 0001100000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x00, 0x00, /* 0000000000 */ + 0x18, 0x00, /* 0001100000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x30, 0x00, /* 0011000000 */ + 0x20, 0x00, /* 0010000000 */ + + /* 60 0x3c '<' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x03, 0x00, /* 0000001100 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x30, 0x00, /* 0011000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x18, 0x00, /* 0001100000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x06, 0x00, /* 0000011000 */ + 0x03, 0x00, /* 0000001100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 61 0x3d '=' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 62 0x3e '>' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x18, 0x00, /* 0001100000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x06, 0x00, /* 0000011000 */ + 0x03, 0x00, /* 0000001100 */ + 0x01, 0x80, /* 0000000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x03, 0x00, /* 0000001100 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x30, 0x00, /* 0011000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 63 0x3f '?' */ + 0x00, 0x00, /* 0000000000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x3b, 0x80, /* 0011101110 */ + 0x21, 0x80, /* 0010000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x03, 0x00, /* 0000001100 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 64 0x40 '@' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x31, 0x80, /* 0011000110 */ + 0x65, 0x80, /* 0110010110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x6f, 0x80, /* 0110111110 */ + 0x60, 0x00, /* 0110000000 */ + 0x31, 0x80, /* 0011000110 */ + 0x3f, 0x80, /* 0011111110 */ + 0x0f, 0x00, /* 0000111100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 65 0x41 'A' */ + 0x00, 0x00, /* 0000000000 */ + 0x04, 0x00, /* 0000010000 */ + 0x04, 0x00, /* 0000010000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x19, 0x80, /* 0001100110 */ + 0x31, 0x80, /* 0011000110 */ + 0x3f, 0x80, /* 0011111110 */ + 0x31, 0x80, /* 0011000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x60, 0xc0, /* 0110000011 */ + 0x60, 0xc0, /* 0110000011 */ + 0xf1, 0xc0, /* 1111000111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 66 0x42 'B' */ + 0x00, 0x00, /* 0000000000 */ + 0xfc, 0x00, /* 1111110000 */ + 0x62, 0x00, /* 0110001000 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x66, 0x00, /* 0110011000 */ + 0x7e, 0x00, /* 0111111000 */ + 0x63, 0x00, /* 0110001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x63, 0x00, /* 0110001100 */ + 0xfe, 0x00, /* 1111111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 67 0x43 'C' */ + 0x00, 0x00, /* 0000000000 */ + 0x0f, 0x00, /* 0000111100 */ + 0x11, 0x80, /* 0001000110 */ + 0x20, 0x80, /* 0010000010 */ + 0x20, 0x00, /* 0010000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x20, 0x00, /* 0010000000 */ + 0x30, 0x80, /* 0011000010 */ + 0x19, 0x00, /* 0001100100 */ + 0x0e, 0x00, /* 0000111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 68 0x44 'D' */ + 0x00, 0x00, /* 0000000000 */ + 0xfc, 0x00, /* 1111110000 */ + 0x67, 0x00, /* 0110011100 */ + 0x63, 0x00, /* 0110001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x00, /* 0110000100 */ + 0x66, 0x00, /* 0110011000 */ + 0xf8, 0x00, /* 1111100000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 69 0x45 'E' */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x30, 0x80, /* 0011000010 */ + 0x30, 0x80, /* 0011000010 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x31, 0x00, /* 0011000100 */ + 0x3f, 0x00, /* 0011111100 */ + 0x31, 0x00, /* 0011000100 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x80, /* 0011000010 */ + 0x30, 0x80, /* 0011000010 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 70 0x46 'F' */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x30, 0x80, /* 0011000010 */ + 0x30, 0x80, /* 0011000010 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x31, 0x00, /* 0011000100 */ + 0x3f, 0x00, /* 0011111100 */ + 0x31, 0x00, /* 0011000100 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x78, 0x00, /* 0111100000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 71 0x47 'G' */ + 0x00, 0x00, /* 0000000000 */ + 0x0f, 0x00, /* 0000111100 */ + 0x11, 0x80, /* 0001000110 */ + 0x20, 0x80, /* 0010000010 */ + 0x20, 0x00, /* 0010000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x67, 0xc0, /* 0110011111 */ + 0x61, 0x80, /* 0110000110 */ + 0x21, 0x80, /* 0010000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x19, 0x80, /* 0001100110 */ + 0x0e, 0x00, /* 0000111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 72 0x48 'H' */ + 0x00, 0x00, /* 0000000000 */ + 0xf3, 0xc0, /* 1111001111 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0xf3, 0xc0, /* 1111001111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 73 0x49 'I' */ + 0x00, 0x00, /* 0000000000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 74 0x4a 'J' */ + 0x00, 0x00, /* 0000000000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x08, 0x00, /* 0000100000 */ + 0x70, 0x00, /* 0111000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 75 0x4b 'K' */ + 0x00, 0x00, /* 0000000000 */ + 0xf1, 0x80, /* 1111000110 */ + 0x63, 0x00, /* 0110001100 */ + 0x66, 0x00, /* 0110011000 */ + 0x6c, 0x00, /* 0110110000 */ + 0x78, 0x00, /* 0111100000 */ + 0x70, 0x00, /* 0111000000 */ + 0x70, 0x00, /* 0111000000 */ + 0x78, 0x00, /* 0111100000 */ + 0x78, 0x00, /* 0111100000 */ + 0x6c, 0x00, /* 0110110000 */ + 0x66, 0x00, /* 0110011000 */ + 0x63, 0x00, /* 0110001100 */ + 0x61, 0x80, /* 0110000110 */ + 0xf0, 0xc0, /* 1111000011 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 76 0x4c 'L' */ + 0x00, 0x00, /* 0000000000 */ + 0x78, 0x00, /* 0111100000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x80, /* 0011000010 */ + 0x30, 0x80, /* 0011000010 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 77 0x4d 'M' */ + 0x00, 0x00, /* 0000000000 */ + 0xe0, 0xc0, /* 1110000011 */ + 0x61, 0x80, /* 0110000110 */ + 0x73, 0x80, /* 0111001110 */ + 0x73, 0x80, /* 0111001110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0xf3, 0xc0, /* 1111001111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 78 0x4e 'N' */ + 0x00, 0x00, /* 0000000000 */ + 0xf3, 0xc0, /* 1111001111 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x71, 0x80, /* 0111000110 */ + 0x79, 0x80, /* 0111100110 */ + 0x79, 0x80, /* 0111100110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x67, 0x80, /* 0110011110 */ + 0x67, 0x80, /* 0110011110 */ + 0x63, 0x80, /* 0110001110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0xf3, 0xc0, /* 1111001111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 79 0x4f 'O' */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x17, 0x00, /* 0001011100 */ + 0x23, 0x00, /* 0010001100 */ + 0x21, 0x80, /* 0010000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x21, 0x00, /* 0010000100 */ + 0x31, 0x00, /* 0011000100 */ + 0x1a, 0x00, /* 0001101000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 80 0x50 'P' */ + 0x00, 0x00, /* 0000000000 */ + 0xfe, 0x00, /* 1111111000 */ + 0x63, 0x00, /* 0110001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x63, 0x00, /* 0110001100 */ + 0x7e, 0x00, /* 0111111000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0xf0, 0x00, /* 1111000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 81 0x51 'Q' */ + 0x00, 0x00, /* 0000000000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x13, 0x00, /* 0001001100 */ + 0x23, 0x00, /* 0010001100 */ + 0x21, 0x80, /* 0010000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x3b, 0x00, /* 0011101100 */ + 0x1e, 0x00, /* 0001111000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x26, 0x00, /* 0010011000 */ + 0x03, 0x80, /* 0000001110 */ + 0x00, 0x00, /* 0000000000 */ + + /* 82 0x52 'R' */ + 0x00, 0x00, /* 0000000000 */ + 0xfe, 0x00, /* 1111111000 */ + 0x63, 0x00, /* 0110001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x00, /* 0110000100 */ + 0x7e, 0x00, /* 0111111000 */ + 0x78, 0x00, /* 0111100000 */ + 0x6c, 0x00, /* 0110110000 */ + 0x6e, 0x00, /* 0110111000 */ + 0x67, 0x00, /* 0110011100 */ + 0x63, 0x80, /* 0110001110 */ + 0x61, 0xc0, /* 0110000111 */ + 0xf0, 0xc0, /* 1111000011 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 83 0x53 'S' */ + 0x00, 0x00, /* 0000000000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x31, 0x80, /* 0011000110 */ + 0x60, 0x80, /* 0110000010 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x18, 0x00, /* 0001100000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x06, 0x00, /* 0000011000 */ + 0x03, 0x00, /* 0000001100 */ + 0x01, 0x80, /* 0000000110 */ + 0x41, 0x80, /* 0100000110 */ + 0x63, 0x00, /* 0110001100 */ + 0x3e, 0x00, /* 0011111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 84 0x54 'T' */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x4c, 0x80, /* 0100110010 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 85 0x55 'U' */ + 0x00, 0x00, /* 0000000000 */ + 0xf3, 0xc0, /* 1111001111 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x73, 0x00, /* 0111001100 */ + 0x3f, 0x00, /* 0011111100 */ + 0x1e, 0x00, /* 0001111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 86 0x56 'V' */ + 0x00, 0x00, /* 0000000000 */ + 0xe1, 0xc0, /* 1110000111 */ + 0xc0, 0xc0, /* 1100000011 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x12, 0x00, /* 0001001000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 87 0x57 'W' */ + 0x00, 0x00, /* 0000000000 */ + 0xe1, 0xc0, /* 1110000111 */ + 0xc0, 0xc0, /* 1100000011 */ + 0xc0, 0xc0, /* 1100000011 */ + 0xc0, 0xc0, /* 1100000011 */ + 0xe0, 0xc0, /* 1110000011 */ + 0x61, 0x80, /* 0110000110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x77, 0x00, /* 0111011100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 88 0x58 'X' */ + 0x00, 0x00, /* 0000000000 */ + 0xf7, 0x80, /* 1111011110 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x36, 0x00, /* 0011011000 */ + 0x36, 0x00, /* 0011011000 */ + 0x36, 0x00, /* 0011011000 */ + 0x1c, 0x00, /* 0001110000 */ + 0x1c, 0x00, /* 0001110000 */ + 0x36, 0x00, /* 0011011000 */ + 0x36, 0x00, /* 0011011000 */ + 0x36, 0x00, /* 0011011000 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0xf7, 0x80, /* 1111011110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 89 0x59 'Y' */ + 0x00, 0x00, /* 0000000000 */ + 0xf3, 0xc0, /* 1111001111 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x1e, 0x00, /* 0001111000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 90 0x5a 'Z' */ + 0x00, 0x00, /* 0000000000 */ + 0x3f, 0x80, /* 0011111110 */ + 0x21, 0x80, /* 0010000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x03, 0x00, /* 0000001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x80, /* 0011000010 */ + 0x3f, 0x80, /* 0011111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 91 0x5b '[' */ + 0x00, 0x00, /* 0000000000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x1f, 0x00, /* 0001111100 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x1f, 0x00, /* 0001111100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 92 0x5c '\' */ + 0x00, 0x00, /* 0000000000 */ + 0xc0, 0x00, /* 1100000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x03, 0x00, /* 0000001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x01, 0x80, /* 0000000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x00, 0xc0, /* 0000000011 */ + 0x00, 0x00, /* 0000000000 */ + + /* 93 0x5d ']' */ + 0x00, 0x00, /* 0000000000 */ + 0x3e, 0x00, /* 0011111000 */ + 0x3e, 0x00, /* 0011111000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x3e, 0x00, /* 0011111000 */ + 0x3e, 0x00, /* 0011111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 94 0x5e '^' */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x33, 0x00, /* 0011001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 95 0x5f '_' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x00, 0x00, /* 0000000000 */ + + /* 96 0x60 '`' */ + 0x04, 0x00, /* 0000010000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 97 0x61 'a' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x31, 0x80, /* 0011000110 */ + 0x21, 0x80, /* 0010000110 */ + 0x07, 0x80, /* 0000011110 */ + 0x39, 0x80, /* 0011100110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x73, 0x80, /* 0111001110 */ + 0x3d, 0xc0, /* 0011110111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 98 0x62 'b' */ + 0x20, 0x00, /* 0010000000 */ + 0x60, 0x00, /* 0110000000 */ + 0xe0, 0x00, /* 1110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x66, 0x00, /* 0110011000 */ + 0x6f, 0x00, /* 0110111100 */ + 0x73, 0x80, /* 0111001110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x71, 0x80, /* 0111000110 */ + 0x7b, 0x00, /* 0111101100 */ + 0x4e, 0x00, /* 0100111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 99 0x63 'c' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x37, 0x00, /* 0011011100 */ + 0x23, 0x00, /* 0010001100 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x71, 0x00, /* 0111000100 */ + 0x33, 0x00, /* 0011001100 */ + 0x1e, 0x00, /* 0001111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 100 0x64 'd' */ + 0x01, 0x80, /* 0000000110 */ + 0x03, 0x80, /* 0000001110 */ + 0x01, 0x80, /* 0000000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x0d, 0x80, /* 0000110110 */ + 0x37, 0x80, /* 0011011110 */ + 0x23, 0x80, /* 0010001110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x73, 0x80, /* 0111001110 */ + 0x35, 0x80, /* 0011010110 */ + 0x19, 0xc0, /* 0001100111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 101 0x65 'e' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x33, 0x00, /* 0011001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x19, 0x80, /* 0001100110 */ + 0x0e, 0x00, /* 0000111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 102 0x66 'f' */ + 0x07, 0x00, /* 0000011100 */ + 0x09, 0x80, /* 0000100110 */ + 0x09, 0x80, /* 0000100110 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x7f, 0x00, /* 0111111100 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 103 0x67 'g' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x1c, 0x80, /* 0001110010 */ + 0x37, 0x80, /* 0011011110 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x36, 0x00, /* 0011011000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x60, 0x00, /* 0110000000 */ + 0x7f, 0x00, /* 0111111100 */ + 0x3f, 0x80, /* 0011111110 */ + 0x21, 0x80, /* 0010000110 */ + 0x40, 0x80, /* 0100000010 */ + 0x7f, 0x00, /* 0111111100 */ + 0x3e, 0x00, /* 0011111000 */ + + /* 104 0x68 'h' */ + 0x10, 0x00, /* 0001000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x70, 0x00, /* 0111000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x37, 0x00, /* 0011011100 */ + 0x3b, 0x80, /* 0011101110 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x7b, 0xc0, /* 0111101111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 105 0x69 'i' */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 106 0x6a 'j' */ + 0x00, 0x00, /* 0000000000 */ + 0x01, 0x80, /* 0000000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x07, 0x80, /* 0000011110 */ + 0x01, 0x80, /* 0000000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x41, 0x80, /* 0100000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x71, 0x80, /* 0111000110 */ + 0x3f, 0x00, /* 0011111100 */ + 0x1c, 0x00, /* 0001110000 */ + + /* 107 0x6b 'k' */ + 0x60, 0x00, /* 0110000000 */ + 0xe0, 0x00, /* 1110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x63, 0x80, /* 0110001110 */ + 0x66, 0x00, /* 0110011000 */ + 0x6c, 0x00, /* 0110110000 */ + 0x78, 0x00, /* 0111100000 */ + 0x70, 0x00, /* 0111000000 */ + 0x78, 0x00, /* 0111100000 */ + 0x6c, 0x00, /* 0110110000 */ + 0x6e, 0x00, /* 0110111000 */ + 0x67, 0x00, /* 0110011100 */ + 0xf3, 0x80, /* 1111001110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 108 0x6c 'l' */ + 0x3c, 0x00, /* 0011110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 109 0x6d 'm' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xdb, 0x80, /* 1101101110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x6d, 0x80, /* 0110110110 */ + 0xed, 0xc0, /* 1110110111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 110 0x6e 'n' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x6f, 0x00, /* 0110111100 */ + 0x7b, 0x80, /* 0111101110 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x7b, 0xc0, /* 0111101111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 111 0x6f 'o' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x66, 0x00, /* 0110011000 */ + 0xc3, 0x00, /* 1100001100 */ + 0xc1, 0x80, /* 1100000110 */ + 0xc1, 0x80, /* 1100000110 */ + 0xc1, 0x80, /* 1100000110 */ + 0xc1, 0x80, /* 1100000110 */ + 0xe1, 0x80, /* 1110000110 */ + 0x73, 0x00, /* 0111001100 */ + 0x3c, 0x00, /* 0011110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 112 0x70 'p' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xde, 0x00, /* 1101111000 */ + 0x76, 0x00, /* 0111011000 */ + 0x63, 0x00, /* 0110001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x71, 0x80, /* 0111000110 */ + 0x7b, 0x00, /* 0111101100 */ + 0x7e, 0x00, /* 0111111000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0xf0, 0x00, /* 1111000000 */ + + /* 113 0x71 'q' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0e, 0xc0, /* 0000111011 */ + 0x1b, 0x80, /* 0001101110 */ + 0x33, 0x80, /* 0011001110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x71, 0x80, /* 0111000110 */ + 0x3b, 0x80, /* 0011101110 */ + 0x1f, 0x80, /* 0001111110 */ + 0x01, 0x80, /* 0000000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x03, 0xc0, /* 0000001111 */ + + /* 114 0x72 'r' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x73, 0x00, /* 0111001100 */ + 0x35, 0x80, /* 0011010110 */ + 0x39, 0x80, /* 0011100110 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x78, 0x00, /* 0111100000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 115 0x73 's' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x63, 0x00, /* 0110001100 */ + 0x61, 0x00, /* 0110000100 */ + 0x70, 0x00, /* 0111000000 */ + 0x38, 0x00, /* 0011100000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x07, 0x00, /* 0000011100 */ + 0x43, 0x00, /* 0100001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x7e, 0x00, /* 0111111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 116 0x74 't' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x08, 0x00, /* 0000100000 */ + 0x08, 0x00, /* 0000100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x1c, 0x80, /* 0001110010 */ + 0x0f, 0x00, /* 0000111100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 117 0x75 'u' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xf7, 0x80, /* 1111011110 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x77, 0x00, /* 0111011100 */ + 0x3d, 0x80, /* 0011110110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 118 0x76 'v' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xf1, 0xc0, /* 1111000111 */ + 0x60, 0xc0, /* 0110000011 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x19, 0x80, /* 0001100110 */ + 0x1b, 0x00, /* 0001101100 */ + 0x0f, 0x00, /* 0000111100 */ + 0x0f, 0x00, /* 0000111100 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 119 0x77 'w' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xe3, 0xc0, /* 1110001111 */ + 0xc1, 0x80, /* 1100000110 */ + 0xc1, 0x80, /* 1100000110 */ + 0xc1, 0x80, /* 1100000110 */ + 0xc1, 0x80, /* 1100000110 */ + 0x6b, 0x00, /* 0110101100 */ + 0x6b, 0x00, /* 0110101100 */ + 0x7e, 0x00, /* 0111111000 */ + 0x36, 0x00, /* 0011011000 */ + 0x36, 0x00, /* 0011011000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 120 0x78 'x' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xf7, 0x80, /* 1111011110 */ + 0x63, 0x00, /* 0110001100 */ + 0x36, 0x00, /* 0011011000 */ + 0x36, 0x00, /* 0011011000 */ + 0x1c, 0x00, /* 0001110000 */ + 0x1c, 0x00, /* 0001110000 */ + 0x36, 0x00, /* 0011011000 */ + 0x66, 0x00, /* 0110011000 */ + 0x63, 0x00, /* 0110001100 */ + 0xf7, 0x80, /* 1111011110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 121 0x79 'y' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xf3, 0xc0, /* 1111001111 */ + 0x61, 0x80, /* 0110000110 */ + 0x33, 0x00, /* 0011001100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1e, 0x00, /* 0001111000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x78, 0x00, /* 0111100000 */ + 0x70, 0x00, /* 0111000000 */ + + /* 122 0x7a 'z' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x61, 0x80, /* 0110000110 */ + 0x43, 0x00, /* 0100001100 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x30, 0x00, /* 0011000000 */ + 0x60, 0x80, /* 0110000010 */ + 0x61, 0x80, /* 0110000110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 123 0x7b '{' */ + 0x07, 0x00, /* 0000011100 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x70, 0x00, /* 0111000000 */ + 0x18, 0x00, /* 0001100000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x07, 0x00, /* 0000011100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 124 0x7c '|' */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 125 0x7d '}' */ + 0x38, 0x00, /* 0011100000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x06, 0x00, /* 0000011000 */ + 0x03, 0x80, /* 0000001110 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x38, 0x00, /* 0011100000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 126 0x7e '~' */ + 0x00, 0x00, /* 0000000000 */ + 0x18, 0x80, /* 0001100010 */ + 0x3d, 0x80, /* 0011110110 */ + 0x6f, 0x00, /* 0110111100 */ + 0x46, 0x00, /* 0100011000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 127 0x7f '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x12, 0x00, /* 0001001000 */ + 0x21, 0x00, /* 0010000100 */ + 0x40, 0x80, /* 0100000010 */ + 0x40, 0x80, /* 0100000010 */ + 0x40, 0x80, /* 0100000010 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 128 0x80 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x21, 0x80, /* 0010000110 */ + 0x40, 0x80, /* 0100000010 */ + 0x40, 0x00, /* 0100000000 */ + 0x40, 0x00, /* 0100000000 */ + 0x40, 0x00, /* 0100000000 */ + 0x40, 0x00, /* 0100000000 */ + 0x40, 0x00, /* 0100000000 */ + 0x40, 0x00, /* 0100000000 */ + 0x60, 0x80, /* 0110000010 */ + 0x31, 0x00, /* 0011000100 */ + 0x1e, 0x00, /* 0001111000 */ + 0x08, 0x00, /* 0000100000 */ + 0x04, 0x00, /* 0000010000 */ + 0x02, 0x00, /* 0000001000 */ + 0x02, 0x00, /* 0000001000 */ + 0x1c, 0x00, /* 0001110000 */ + + /* 129 0x81 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x7b, 0x80, /* 0111101110 */ + 0x31, 0x00, /* 0011000100 */ + 0x31, 0x00, /* 0011000100 */ + 0x31, 0x00, /* 0011000100 */ + 0x31, 0x00, /* 0011000100 */ + 0x31, 0x00, /* 0011000100 */ + 0x31, 0x00, /* 0011000100 */ + 0x31, 0x00, /* 0011000100 */ + 0x3b, 0x00, /* 0011101100 */ + 0x1c, 0x80, /* 0001110010 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 130 0x82 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x01, 0x00, /* 0000000100 */ + 0x02, 0x00, /* 0000001000 */ + 0x04, 0x00, /* 0000010000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x33, 0x00, /* 0011001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x19, 0x80, /* 0001100110 */ + 0x0e, 0x00, /* 0000111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 131 0x83 '.' */ + 0x04, 0x00, /* 0000010000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x1b, 0x00, /* 0001101100 */ + 0x31, 0x80, /* 0011000110 */ + 0x00, 0x00, /* 0000000000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x31, 0x80, /* 0011000110 */ + 0x21, 0x80, /* 0010000110 */ + 0x07, 0x80, /* 0000011110 */ + 0x39, 0x80, /* 0011100110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x73, 0x80, /* 0111001110 */ + 0x3d, 0xc0, /* 0011110111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 132 0x84 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x31, 0x80, /* 0011000110 */ + 0x21, 0x80, /* 0010000110 */ + 0x07, 0x80, /* 0000011110 */ + 0x39, 0x80, /* 0011100110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x73, 0x80, /* 0111001110 */ + 0x3d, 0xc0, /* 0011110111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 133 0x85 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x18, 0x00, /* 0001100000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x06, 0x00, /* 0000011000 */ + 0x00, 0x00, /* 0000000000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x31, 0x80, /* 0011000110 */ + 0x21, 0x80, /* 0010000110 */ + 0x07, 0x80, /* 0000011110 */ + 0x39, 0x80, /* 0011100110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x73, 0x80, /* 0111001110 */ + 0x3d, 0xc0, /* 0011110111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 134 0x86 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x1b, 0x00, /* 0001101100 */ + 0x0e, 0x00, /* 0000111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x31, 0x80, /* 0011000110 */ + 0x21, 0x80, /* 0010000110 */ + 0x07, 0x80, /* 0000011110 */ + 0x39, 0x80, /* 0011100110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x73, 0x80, /* 0111001110 */ + 0x3d, 0xc0, /* 0011110111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 135 0x87 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x31, 0x80, /* 0011000110 */ + 0x20, 0x80, /* 0010000010 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x70, 0x80, /* 0111000010 */ + 0x30, 0x80, /* 0011000010 */ + 0x1f, 0x00, /* 0001111100 */ + 0x04, 0x00, /* 0000010000 */ + 0x02, 0x00, /* 0000001000 */ + 0x01, 0x00, /* 0000000100 */ + 0x0e, 0x00, /* 0000111000 */ + + /* 136 0x88 '.' */ + 0x04, 0x00, /* 0000010000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x1b, 0x00, /* 0001101100 */ + 0x31, 0x80, /* 0011000110 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x33, 0x00, /* 0011001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x19, 0x80, /* 0001100110 */ + 0x0e, 0x00, /* 0000111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 137 0x89 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x36, 0x00, /* 0011011000 */ + 0x36, 0x00, /* 0011011000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x33, 0x00, /* 0011001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x19, 0x80, /* 0001100110 */ + 0x0e, 0x00, /* 0000111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 138 0x8a '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x18, 0x00, /* 0001100000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x33, 0x00, /* 0011001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x19, 0x80, /* 0001100110 */ + 0x0e, 0x00, /* 0000111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 139 0x8b '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x36, 0x00, /* 0011011000 */ + 0x36, 0x00, /* 0011011000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 140 0x8c '.' */ + 0x08, 0x00, /* 0000100000 */ + 0x1c, 0x00, /* 0001110000 */ + 0x36, 0x00, /* 0011011000 */ + 0x63, 0x00, /* 0110001100 */ + 0x00, 0x00, /* 0000000000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 141 0x8d '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x18, 0x00, /* 0001100000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 142 0x8e '.' */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x04, 0x00, /* 0000010000 */ + 0x04, 0x00, /* 0000010000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x19, 0x00, /* 0001100100 */ + 0x19, 0x00, /* 0001100100 */ + 0x3f, 0x00, /* 0011111100 */ + 0x31, 0x00, /* 0011000100 */ + 0x31, 0x00, /* 0011000100 */ + 0x60, 0x80, /* 0110000010 */ + 0x60, 0x80, /* 0110000010 */ + 0xf3, 0xc0, /* 1111001111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 143 0x8f '.' */ + 0x04, 0x00, /* 0000010000 */ + 0x0a, 0x00, /* 0000101000 */ + 0x0a, 0x00, /* 0000101000 */ + 0x04, 0x00, /* 0000010000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x19, 0x00, /* 0001100100 */ + 0x19, 0x00, /* 0001100100 */ + 0x3f, 0x00, /* 0011111100 */ + 0x31, 0x00, /* 0011000100 */ + 0x31, 0x00, /* 0011000100 */ + 0x60, 0x80, /* 0110000010 */ + 0x60, 0x80, /* 0110000010 */ + 0xf3, 0xc0, /* 1111001111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 144 0x90 '.' */ + 0x03, 0x00, /* 0000001100 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x30, 0x80, /* 0011000010 */ + 0x30, 0x80, /* 0011000010 */ + 0x30, 0x00, /* 0011000000 */ + 0x31, 0x00, /* 0011000100 */ + 0x3f, 0x00, /* 0011111100 */ + 0x31, 0x00, /* 0011000100 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x80, /* 0011000010 */ + 0x30, 0x80, /* 0011000010 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 145 0x91 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x3b, 0x80, /* 0011101110 */ + 0x6c, 0xc0, /* 0110110011 */ + 0x4c, 0xc0, /* 0100110011 */ + 0x0c, 0xc0, /* 0000110011 */ + 0x3f, 0xc0, /* 0011111111 */ + 0x6c, 0x00, /* 0110110000 */ + 0xcc, 0x00, /* 1100110000 */ + 0xcc, 0x00, /* 1100110000 */ + 0xee, 0xc0, /* 1110111011 */ + 0x7b, 0x80, /* 0111101110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 146 0x92 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x07, 0xc0, /* 0000011111 */ + 0x0e, 0x40, /* 0000111001 */ + 0x0e, 0x40, /* 0000111001 */ + 0x0e, 0x00, /* 0000111000 */ + 0x16, 0x00, /* 0001011000 */ + 0x16, 0x80, /* 0001011010 */ + 0x17, 0x80, /* 0001011110 */ + 0x16, 0x80, /* 0001011010 */ + 0x3e, 0x00, /* 0011111000 */ + 0x26, 0x00, /* 0010011000 */ + 0x26, 0x00, /* 0010011000 */ + 0x46, 0x40, /* 0100011001 */ + 0x46, 0x40, /* 0100011001 */ + 0xef, 0xc0, /* 1110111111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 147 0x93 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x08, 0x00, /* 0000100000 */ + 0x1c, 0x00, /* 0001110000 */ + 0x36, 0x00, /* 0011011000 */ + 0x00, 0x00, /* 0000000000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x66, 0x00, /* 0110011000 */ + 0xc3, 0x00, /* 1100001100 */ + 0xc1, 0x80, /* 1100000110 */ + 0xc1, 0x80, /* 1100000110 */ + 0xc1, 0x80, /* 1100000110 */ + 0xc1, 0x80, /* 1100000110 */ + 0xe1, 0x80, /* 1110000110 */ + 0x73, 0x00, /* 0111001100 */ + 0x3c, 0x00, /* 0011110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 148 0x94 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x00, 0x00, /* 0000000000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x66, 0x00, /* 0110011000 */ + 0xc3, 0x00, /* 1100001100 */ + 0xc1, 0x80, /* 1100000110 */ + 0xc1, 0x80, /* 1100000110 */ + 0xc1, 0x80, /* 1100000110 */ + 0xc1, 0x80, /* 1100000110 */ + 0xe1, 0x80, /* 1110000110 */ + 0x73, 0x00, /* 0111001100 */ + 0x3c, 0x00, /* 0011110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 149 0x95 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x18, 0x00, /* 0001100000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x06, 0x00, /* 0000011000 */ + 0x00, 0x00, /* 0000000000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x66, 0x00, /* 0110011000 */ + 0xc3, 0x00, /* 1100001100 */ + 0xc1, 0x80, /* 1100000110 */ + 0xc1, 0x80, /* 1100000110 */ + 0xc1, 0x80, /* 1100000110 */ + 0xc1, 0x80, /* 1100000110 */ + 0xe1, 0x80, /* 1110000110 */ + 0x73, 0x00, /* 0111001100 */ + 0x3c, 0x00, /* 0011110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 150 0x96 '.' */ + 0x08, 0x00, /* 0000100000 */ + 0x1c, 0x00, /* 0001110000 */ + 0x36, 0x00, /* 0011011000 */ + 0x63, 0x00, /* 0110001100 */ + 0x00, 0x00, /* 0000000000 */ + 0xf7, 0x80, /* 1111011110 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x77, 0x00, /* 0111011100 */ + 0x3d, 0x80, /* 0011110110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 151 0x97 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x18, 0x00, /* 0001100000 */ + 0x00, 0x00, /* 0000000000 */ + 0xf7, 0x80, /* 1111011110 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x77, 0x00, /* 0111011100 */ + 0x3d, 0x80, /* 0011110110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 152 0x98 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xf3, 0xc0, /* 1111001111 */ + 0x61, 0x80, /* 0110000110 */ + 0x33, 0x00, /* 0011001100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1e, 0x00, /* 0001111000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x78, 0x00, /* 0111100000 */ + 0x70, 0x00, /* 0111000000 */ + + /* 153 0x99 '.' */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x0c, 0x00, /* 0000110000 */ + 0x17, 0x00, /* 0001011100 */ + 0x23, 0x00, /* 0010001100 */ + 0x21, 0x80, /* 0010000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x21, 0x00, /* 0010000100 */ + 0x31, 0x00, /* 0011000100 */ + 0x1a, 0x00, /* 0001101000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 154 0x9a '.' */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x00, 0x00, /* 0000000000 */ + 0xf1, 0xc0, /* 1111000111 */ + 0x60, 0x80, /* 0110000010 */ + 0x60, 0x80, /* 0110000010 */ + 0x60, 0x80, /* 0110000010 */ + 0x60, 0x80, /* 0110000010 */ + 0x60, 0x80, /* 0110000010 */ + 0x60, 0x80, /* 0110000010 */ + 0x60, 0x80, /* 0110000010 */ + 0x60, 0x80, /* 0110000010 */ + 0x71, 0x00, /* 0111000100 */ + 0x3f, 0x00, /* 0011111100 */ + 0x1e, 0x00, /* 0001111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 155 0x9b '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x1f, 0x80, /* 0001111110 */ + 0x36, 0x80, /* 0011011010 */ + 0x26, 0x00, /* 0010011000 */ + 0x66, 0x00, /* 0110011000 */ + 0x66, 0x00, /* 0110011000 */ + 0x66, 0x00, /* 0110011000 */ + 0x66, 0x00, /* 0110011000 */ + 0x76, 0x00, /* 0111011000 */ + 0x36, 0x80, /* 0011011010 */ + 0x1f, 0x80, /* 0001111110 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 156 0x9c '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x3b, 0x00, /* 0011101100 */ + 0x33, 0x00, /* 0011001100 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x7e, 0x00, /* 0111111000 */ + 0x7e, 0x00, /* 0111111000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x7c, 0x80, /* 0111110010 */ + 0x7f, 0x80, /* 0111111110 */ + 0x43, 0x00, /* 0100001100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 157 0x9d '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x40, 0x80, /* 0100000010 */ + 0x40, 0x80, /* 0100000010 */ + 0x21, 0x00, /* 0010000100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x1e, 0x00, /* 0001111000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x0c, 0x00, /* 0000110000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 158 0x9e '.' */ + 0x00, 0x00, /* 0000000000 */ + 0xbf, 0x00, /* 1011111100 */ + 0x40, 0x80, /* 0100000010 */ + 0x40, 0x80, /* 0100000010 */ + 0x7f, 0x00, /* 0111111100 */ + 0x40, 0x00, /* 0100000000 */ + 0x48, 0x00, /* 0100100000 */ + 0x48, 0x00, /* 0100100000 */ + 0x5e, 0x00, /* 0101111000 */ + 0x48, 0x00, /* 0100100000 */ + 0x48, 0x00, /* 0100100000 */ + 0x48, 0x00, /* 0100100000 */ + 0x48, 0x80, /* 0100100010 */ + 0x47, 0x00, /* 0100011100 */ + 0xe0, 0x00, /* 1110000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 159 0x9f '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x03, 0x00, /* 0000001100 */ + 0x04, 0x80, /* 0000010010 */ + 0x08, 0x00, /* 0000100000 */ + 0x08, 0x00, /* 0000100000 */ + 0x08, 0x00, /* 0000100000 */ + 0x08, 0x00, /* 0000100000 */ + 0x09, 0x00, /* 0000100100 */ + 0x3e, 0x00, /* 0011111000 */ + 0x48, 0x00, /* 0100100000 */ + 0x08, 0x00, /* 0000100000 */ + 0x08, 0x00, /* 0000100000 */ + 0x08, 0x00, /* 0000100000 */ + 0x08, 0x00, /* 0000100000 */ + 0x08, 0x00, /* 0000100000 */ + 0x90, 0x00, /* 1001000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 160 0xa0 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x03, 0x00, /* 0000001100 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x31, 0x80, /* 0011000110 */ + 0x21, 0x80, /* 0010000110 */ + 0x07, 0x80, /* 0000011110 */ + 0x39, 0x80, /* 0011100110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x73, 0x80, /* 0111001110 */ + 0x3d, 0xc0, /* 0011110111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 161 0xa1 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x03, 0x00, /* 0000001100 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 162 0xa2 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x00, 0x00, /* 0000000000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x66, 0x00, /* 0110011000 */ + 0xc3, 0x00, /* 1100001100 */ + 0xc1, 0x80, /* 1100000110 */ + 0xc1, 0x80, /* 1100000110 */ + 0xc1, 0x80, /* 1100000110 */ + 0xc1, 0x80, /* 1100000110 */ + 0xe1, 0x80, /* 1110000110 */ + 0x73, 0x00, /* 0111001100 */ + 0x3c, 0x00, /* 0011110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 163 0xa3 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x00, 0x00, /* 0000000000 */ + 0xf7, 0x80, /* 1111011110 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x77, 0x00, /* 0111011100 */ + 0x3d, 0x80, /* 0011110110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 164 0xa4 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x38, 0x80, /* 0011100010 */ + 0x7f, 0x80, /* 0111111110 */ + 0x47, 0x00, /* 0100011100 */ + 0x00, 0x00, /* 0000000000 */ + 0x6f, 0x00, /* 0110111100 */ + 0x7b, 0x80, /* 0111101110 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x7b, 0xc0, /* 0111101111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 165 0xa5 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x38, 0x80, /* 0011100010 */ + 0x7f, 0x80, /* 0111111110 */ + 0x47, 0x00, /* 0100011100 */ + 0x00, 0x00, /* 0000000000 */ + 0xe3, 0xc0, /* 1110001111 */ + 0x71, 0x80, /* 0111000110 */ + 0x79, 0x80, /* 0111100110 */ + 0x79, 0x80, /* 0111100110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x67, 0x80, /* 0110011110 */ + 0x63, 0x80, /* 0110001110 */ + 0x61, 0x80, /* 0110000110 */ + 0xf0, 0xc0, /* 1111000011 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 166 0xa6 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x3e, 0x00, /* 0011111000 */ + 0x63, 0x00, /* 0110001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x0f, 0x00, /* 0000111100 */ + 0x33, 0x00, /* 0011001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x67, 0x00, /* 0110011100 */ + 0x3b, 0x80, /* 0011101110 */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 167 0xa7 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x33, 0x00, /* 0011001100 */ + 0x21, 0x80, /* 0010000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x00, /* 0110000100 */ + 0x33, 0x00, /* 0011001100 */ + 0x1c, 0x00, /* 0001110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 168 0xa8 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x00, 0x00, /* 0000000000 */ + 0x06, 0x00, /* 0000011000 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x30, 0x00, /* 0011000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x80, /* 0110000010 */ + 0x73, 0x80, /* 0111001110 */ + 0x3f, 0x00, /* 0011111100 */ + 0x1e, 0x00, /* 0001111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 169 0xa9 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 170 0xaa '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x01, 0x80, /* 0000000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 171 0xab '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x20, 0x00, /* 0010000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x20, 0x00, /* 0010000000 */ + 0x20, 0x80, /* 0010000010 */ + 0x21, 0x00, /* 0010000100 */ + 0x22, 0x00, /* 0010001000 */ + 0x74, 0x00, /* 0111010000 */ + 0x08, 0x00, /* 0000100000 */ + 0x17, 0x00, /* 0001011100 */ + 0x28, 0x80, /* 0010100010 */ + 0x43, 0x00, /* 0100001100 */ + 0x04, 0x00, /* 0000010000 */ + 0x08, 0x00, /* 0000100000 */ + 0x0f, 0x80, /* 0000111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 172 0xac '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x20, 0x00, /* 0010000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x20, 0x00, /* 0010000000 */ + 0x20, 0x80, /* 0010000010 */ + 0x21, 0x00, /* 0010000100 */ + 0x22, 0x00, /* 0010001000 */ + 0x74, 0x00, /* 0111010000 */ + 0x09, 0x00, /* 0000100100 */ + 0x13, 0x00, /* 0001001100 */ + 0x25, 0x00, /* 0010010100 */ + 0x49, 0x00, /* 0100100100 */ + 0x1f, 0x80, /* 0001111110 */ + 0x01, 0x00, /* 0000000100 */ + 0x01, 0x00, /* 0000000100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 173 0xad '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 174 0xae '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0d, 0x80, /* 0000110110 */ + 0x1b, 0x00, /* 0001101100 */ + 0x36, 0x00, /* 0011011000 */ + 0x6c, 0x00, /* 0110110000 */ + 0xd8, 0x00, /* 1101100000 */ + 0x6c, 0x00, /* 0110110000 */ + 0x36, 0x00, /* 0011011000 */ + 0x1b, 0x00, /* 0001101100 */ + 0x0d, 0x80, /* 0000110110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 175 0xaf '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x6c, 0x00, /* 0110110000 */ + 0x36, 0x00, /* 0011011000 */ + 0x1b, 0x00, /* 0001101100 */ + 0x0d, 0x80, /* 0000110110 */ + 0x06, 0xc0, /* 0000011011 */ + 0x0d, 0x80, /* 0000110110 */ + 0x1b, 0x00, /* 0001101100 */ + 0x36, 0x00, /* 0011011000 */ + 0x6c, 0x00, /* 0110110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 176 0xb0 '.' */ + 0xc3, 0x00, /* 1100001100 */ + 0x41, 0x00, /* 0100000100 */ + 0x18, 0x40, /* 0001100001 */ + 0x10, 0x40, /* 0001000001 */ + 0xc3, 0x00, /* 1100001100 */ + 0x41, 0x00, /* 0100000100 */ + 0x18, 0x40, /* 0001100001 */ + 0x10, 0x40, /* 0001000001 */ + 0xc3, 0x00, /* 1100001100 */ + 0x41, 0x00, /* 0100000100 */ + 0x18, 0x40, /* 0001100001 */ + 0x10, 0x40, /* 0001000001 */ + 0xc3, 0x00, /* 1100001100 */ + 0x41, 0x00, /* 0100000100 */ + 0x18, 0x40, /* 0001100001 */ + 0x10, 0x40, /* 0001000001 */ + 0xc3, 0x00, /* 1100001100 */ + 0x41, 0x00, /* 0100000100 */ + + /* 177 0xb1 '.' */ + 0x11, 0x00, /* 0001000100 */ + 0xbb, 0x80, /* 1011101110 */ + 0x11, 0x00, /* 0001000100 */ + 0x44, 0x40, /* 0100010001 */ + 0xee, 0xc0, /* 1110111011 */ + 0x44, 0x40, /* 0100010001 */ + 0x11, 0x00, /* 0001000100 */ + 0xbb, 0x80, /* 1011101110 */ + 0x11, 0x00, /* 0001000100 */ + 0x44, 0x40, /* 0100010001 */ + 0xee, 0xc0, /* 1110111011 */ + 0x44, 0x40, /* 0100010001 */ + 0x11, 0x00, /* 0001000100 */ + 0xbb, 0x80, /* 1011101110 */ + 0x11, 0x00, /* 0001000100 */ + 0x44, 0x40, /* 0100010001 */ + 0xee, 0xc0, /* 1110111011 */ + 0x44, 0x40, /* 0100010001 */ + + /* 178 0xb2 '.' */ + 0x3c, 0xc0, /* 0011110011 */ + 0xbe, 0xc0, /* 1011111011 */ + 0xe7, 0x80, /* 1110011110 */ + 0xef, 0x80, /* 1110111110 */ + 0x3c, 0xc0, /* 0011110011 */ + 0xbe, 0xc0, /* 1011111011 */ + 0xe7, 0x80, /* 1110011110 */ + 0xef, 0x80, /* 1110111110 */ + 0x3c, 0xc0, /* 0011110011 */ + 0xbe, 0xc0, /* 1011111011 */ + 0xe7, 0x80, /* 1110011110 */ + 0xef, 0x80, /* 1110111110 */ + 0x3c, 0xc0, /* 0011110011 */ + 0xbe, 0xc0, /* 1011111011 */ + 0xe7, 0x80, /* 1110011110 */ + 0xef, 0x80, /* 1110111110 */ + 0x3c, 0xc0, /* 0011110011 */ + 0xbe, 0xc0, /* 1011111011 */ + + /* 179 0xb3 '.' */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + + /* 180 0xb4 '.' */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0xfc, 0x00, /* 1111110000 */ + 0xfc, 0x00, /* 1111110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + + /* 181 0xb5 '.' */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0xfc, 0x00, /* 1111110000 */ + 0xfc, 0x00, /* 1111110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0xfc, 0x00, /* 1111110000 */ + 0xfc, 0x00, /* 1111110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + + /* 182 0xb6 '.' */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0xfb, 0x00, /* 1111101100 */ + 0xfb, 0x00, /* 1111101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + + /* 183 0xb7 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xff, 0x00, /* 1111111100 */ + 0xff, 0x00, /* 1111111100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + + /* 184 0xb8 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xfc, 0x00, /* 1111110000 */ + 0xfc, 0x00, /* 1111110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0xfc, 0x00, /* 1111110000 */ + 0xfc, 0x00, /* 1111110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + + /* 185 0xb9 '.' */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0xfb, 0x00, /* 1111101100 */ + 0xfb, 0x00, /* 1111101100 */ + 0x03, 0x00, /* 0000001100 */ + 0xfb, 0x00, /* 1111101100 */ + 0xfb, 0x00, /* 1111101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + + /* 186 0xba '.' */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + + /* 187 0xbb '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xff, 0x00, /* 1111111100 */ + 0xff, 0x00, /* 1111111100 */ + 0x03, 0x00, /* 0000001100 */ + 0xfb, 0x00, /* 1111101100 */ + 0xfb, 0x00, /* 1111101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + + /* 188 0xbc '.' */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0xfb, 0x00, /* 1111101100 */ + 0xfb, 0x00, /* 1111101100 */ + 0x03, 0x00, /* 0000001100 */ + 0xff, 0x00, /* 1111111100 */ + 0xff, 0x00, /* 1111111100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 189 0xbd '.' */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0xff, 0x00, /* 1111111100 */ + 0xff, 0x00, /* 1111111100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 190 0xbe '.' */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0xfc, 0x00, /* 1111110000 */ + 0xfc, 0x00, /* 1111110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0xfc, 0x00, /* 1111110000 */ + 0xfc, 0x00, /* 1111110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 191 0xbf '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xfc, 0x00, /* 1111110000 */ + 0xfc, 0x00, /* 1111110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + + /* 192 0xc0 '.' */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 193 0xc1 '.' */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 194 0xc2 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + + /* 195 0xc3 '.' */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + + /* 196 0xc4 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 197 0xc5 '.' */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + + /* 198 0xc6 '.' */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + + /* 199 0xc7 '.' */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0xc0, /* 0001101111 */ + 0x1b, 0xc0, /* 0001101111 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + + /* 200 0xc8 '.' */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0xc0, /* 0001101111 */ + 0x1b, 0xc0, /* 0001101111 */ + 0x18, 0x00, /* 0001100000 */ + 0x1f, 0xc0, /* 0001111111 */ + 0x1f, 0xc0, /* 0001111111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 201 0xc9 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x1f, 0xc0, /* 0001111111 */ + 0x1f, 0xc0, /* 0001111111 */ + 0x18, 0x00, /* 0001100000 */ + 0x1b, 0xc0, /* 0001101111 */ + 0x1b, 0xc0, /* 0001101111 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + + /* 202 0xca '.' */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0xfb, 0xc0, /* 1111101111 */ + 0xfb, 0xc0, /* 1111101111 */ + 0x00, 0x00, /* 0000000000 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 203 0xcb '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x00, 0x00, /* 0000000000 */ + 0xfb, 0xc0, /* 1111101111 */ + 0xfb, 0xc0, /* 1111101111 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + + /* 204 0xcc '.' */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0xc0, /* 0001101111 */ + 0x1b, 0xc0, /* 0001101111 */ + 0x18, 0x00, /* 0001100000 */ + 0x1b, 0xc0, /* 0001101111 */ + 0x1b, 0xc0, /* 0001101111 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + + /* 205 0xcd '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x00, 0x00, /* 0000000000 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 206 0xce '.' */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0xfb, 0xc0, /* 1111101111 */ + 0xfb, 0xc0, /* 1111101111 */ + 0x00, 0x00, /* 0000000000 */ + 0xfb, 0xc0, /* 1111101111 */ + 0xfb, 0xc0, /* 1111101111 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + + /* 207 0xcf '.' */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x00, 0x00, /* 0000000000 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 208 0xd0 '.' */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 209 0xd1 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x00, 0x00, /* 0000000000 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + + /* 210 0xd2 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + + /* 211 0xd3 '.' */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1f, 0xc0, /* 0001111111 */ + 0x1f, 0xc0, /* 0001111111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 212 0xd4 '.' */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 213 0xd5 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + + /* 214 0xd6 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x1f, 0xc0, /* 0001111111 */ + 0x1f, 0xc0, /* 0001111111 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + + /* 215 0xd7 '.' */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + 0x1b, 0x00, /* 0001101100 */ + + /* 216 0xd8 '.' */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x0c, 0x00, /* 0000110000 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + + /* 217 0xd9 '.' */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0xfc, 0x00, /* 1111110000 */ + 0xfc, 0x00, /* 1111110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 218 0xda '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + + /* 219 0xdb '.' */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + + /* 220 0xdc '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + + /* 221 0xdd '.' */ + 0xf8, 0x00, /* 1111100000 */ + 0xf8, 0x00, /* 1111100000 */ + 0xf8, 0x00, /* 1111100000 */ + 0xf8, 0x00, /* 1111100000 */ + 0xf8, 0x00, /* 1111100000 */ + 0xf8, 0x00, /* 1111100000 */ + 0xf8, 0x00, /* 1111100000 */ + 0xf8, 0x00, /* 1111100000 */ + 0xf8, 0x00, /* 1111100000 */ + 0xf8, 0x00, /* 1111100000 */ + 0xf8, 0x00, /* 1111100000 */ + 0xf8, 0x00, /* 1111100000 */ + 0xf8, 0x00, /* 1111100000 */ + 0xf8, 0x00, /* 1111100000 */ + 0xf8, 0x00, /* 1111100000 */ + 0xf8, 0x00, /* 1111100000 */ + 0xf8, 0x00, /* 1111100000 */ + 0xf8, 0x00, /* 1111100000 */ + + /* 222 0xde '.' */ + 0x07, 0xc0, /* 0000011111 */ + 0x07, 0xc0, /* 0000011111 */ + 0x07, 0xc0, /* 0000011111 */ + 0x07, 0xc0, /* 0000011111 */ + 0x07, 0xc0, /* 0000011111 */ + 0x07, 0xc0, /* 0000011111 */ + 0x07, 0xc0, /* 0000011111 */ + 0x07, 0xc0, /* 0000011111 */ + 0x07, 0xc0, /* 0000011111 */ + 0x07, 0xc0, /* 0000011111 */ + 0x07, 0xc0, /* 0000011111 */ + 0x07, 0xc0, /* 0000011111 */ + 0x07, 0xc0, /* 0000011111 */ + 0x07, 0xc0, /* 0000011111 */ + 0x07, 0xc0, /* 0000011111 */ + 0x07, 0xc0, /* 0000011111 */ + 0x07, 0xc0, /* 0000011111 */ + 0x07, 0xc0, /* 0000011111 */ + + /* 223 0xdf '.' */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0xff, 0xc0, /* 1111111111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 224 0xe0 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x1c, 0x80, /* 0001110010 */ + 0x35, 0x80, /* 0011010110 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x63, 0x00, /* 0110001100 */ + 0x37, 0x80, /* 0011011110 */ + 0x1c, 0x80, /* 0001110010 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 225 0xe1 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x33, 0x00, /* 0011001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x63, 0x00, /* 0110001100 */ + 0x6f, 0x00, /* 0110111100 */ + 0x63, 0x00, /* 0110001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x63, 0x00, /* 0110001100 */ + 0x6e, 0x00, /* 0110111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 226 0xe2 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 227 0xe3 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 228 0xe4 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xff, 0x80, /* 1111111110 */ + 0x60, 0x00, /* 0110000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x80, /* 0011000010 */ + 0x61, 0x80, /* 0110000110 */ + 0xff, 0x80, /* 1111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 229 0xe5 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x1f, 0xc0, /* 0001111111 */ + 0x36, 0x00, /* 0011011000 */ + 0x63, 0x00, /* 0110001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x33, 0x00, /* 0011001100 */ + 0x3e, 0x00, /* 0011111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 230 0xe6 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x73, 0x80, /* 0111001110 */ + 0x6d, 0x80, /* 0110110110 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0xc0, 0x00, /* 1100000000 */ + + /* 231 0xe7 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x01, 0x80, /* 0000000110 */ + 0x36, 0x40, /* 0011011001 */ + 0x5e, 0x00, /* 0101111000 */ + 0x8c, 0x00, /* 1000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 232 0xe8 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x33, 0x00, /* 0011001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x33, 0x00, /* 0011001100 */ + 0x1e, 0x00, /* 0001111000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 233 0xe9 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x1f, 0x00, /* 0001111100 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x60, 0xc0, /* 0110000011 */ + 0x7f, 0xc0, /* 0111111111 */ + 0x7f, 0xc0, /* 0111111111 */ + 0x60, 0xc0, /* 0110000011 */ + 0x31, 0x80, /* 0011000110 */ + 0x31, 0x80, /* 0011000110 */ + 0x1f, 0x00, /* 0001111100 */ + 0x0e, 0x00, /* 0000111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 234 0xea '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x33, 0x00, /* 0011001100 */ + 0x61, 0x80, /* 0110000110 */ + 0xc0, 0xc0, /* 1100000011 */ + 0xc0, 0xc0, /* 1100000011 */ + 0xc0, 0xc0, /* 1100000011 */ + 0x61, 0x80, /* 0110000110 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0xf3, 0xc0, /* 1111001111 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 235 0xeb '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x07, 0x00, /* 0000011100 */ + 0x1f, 0x80, /* 0001111110 */ + 0x30, 0xc0, /* 0011000011 */ + 0x30, 0x00, /* 0011000000 */ + 0x18, 0x00, /* 0001100000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x3e, 0x00, /* 0011111000 */ + 0x66, 0x00, /* 0110011000 */ + 0xc3, 0x00, /* 1100001100 */ + 0xc3, 0x00, /* 1100001100 */ + 0xc3, 0x00, /* 1100001100 */ + 0x66, 0x00, /* 0110011000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 236 0xec '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x33, 0x00, /* 0011001100 */ + 0x6d, 0x80, /* 0110110110 */ + 0xcc, 0xc0, /* 1100110011 */ + 0xcc, 0xc0, /* 1100110011 */ + 0xcc, 0xc0, /* 1100110011 */ + 0xcc, 0xc0, /* 1100110011 */ + 0x6d, 0x80, /* 0110110110 */ + 0x33, 0x00, /* 0011001100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 237 0xed '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x01, 0x80, /* 0000000110 */ + 0x01, 0x80, /* 0000000110 */ + 0x03, 0x00, /* 0000001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x37, 0x00, /* 0011011100 */ + 0x6d, 0x80, /* 0110110110 */ + 0xcc, 0xc0, /* 1100110011 */ + 0xcc, 0xc0, /* 1100110011 */ + 0xcc, 0xc0, /* 1100110011 */ + 0xcc, 0xc0, /* 1100110011 */ + 0x6d, 0x80, /* 0110110110 */ + 0x3b, 0x00, /* 0011101100 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x60, 0x00, /* 0110000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 238 0xee '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x03, 0x80, /* 0000001110 */ + 0x0e, 0x00, /* 0000111000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x3f, 0x80, /* 0011111110 */ + 0x3f, 0x80, /* 0011111110 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x18, 0x00, /* 0001100000 */ + 0x18, 0x00, /* 0001100000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x03, 0x80, /* 0000001110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 239 0xef '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x33, 0x00, /* 0011001100 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x61, 0x80, /* 0110000110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 240 0xf0 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 241 0xf1 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 242 0xf2 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xe0, 0x00, /* 1110000000 */ + 0x38, 0x00, /* 0011100000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x03, 0x80, /* 0000001110 */ + 0x0e, 0x00, /* 0000111000 */ + 0x38, 0x00, /* 0011100000 */ + 0xe0, 0x00, /* 1110000000 */ + 0x00, 0x00, /* 0000000000 */ + 0xff, 0x00, /* 1111111100 */ + 0xff, 0x00, /* 1111111100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 243 0xf3 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x03, 0x80, /* 0000001110 */ + 0x0e, 0x00, /* 0000111000 */ + 0x38, 0x00, /* 0011100000 */ + 0xe0, 0x00, /* 1110000000 */ + 0x38, 0x00, /* 0011100000 */ + 0x0e, 0x00, /* 0000111000 */ + 0x03, 0x80, /* 0000001110 */ + 0x00, 0x00, /* 0000000000 */ + 0xff, 0x80, /* 1111111110 */ + 0xff, 0x80, /* 1111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 244 0xf4 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x30, 0x00, /* 0011000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 245 0xf5 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x03, 0x00, /* 0000001100 */ + 0x00, 0x00, /* 0000000000 */ + + /* 246 0xf6 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 247 0xf7 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x38, 0x00, /* 0011100000 */ + 0x6c, 0x00, /* 0110110000 */ + 0x06, 0xc0, /* 0000011011 */ + 0x03, 0x80, /* 0000001110 */ + 0x38, 0x00, /* 0011100000 */ + 0x6c, 0x00, /* 0110110000 */ + 0x06, 0xc0, /* 0000011011 */ + 0x03, 0x80, /* 0000001110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 248 0xf8 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x33, 0x00, /* 0011001100 */ + 0x33, 0x00, /* 0011001100 */ + 0x1e, 0x00, /* 0001111000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 249 0xf9 '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 250 0xfa '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 251 0xfb '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x0f, 0xc0, /* 0000111111 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0xcc, 0x00, /* 1100110000 */ + 0x6c, 0x00, /* 0110110000 */ + 0x3c, 0x00, /* 0011110000 */ + 0x1c, 0x00, /* 0001110000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 252 0xfc '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x27, 0x00, /* 0010011100 */ + 0x7b, 0x00, /* 0111101100 */ + 0x31, 0x00, /* 0011000100 */ + 0x31, 0x00, /* 0011000100 */ + 0x31, 0x00, /* 0011000100 */ + 0x7b, 0x80, /* 0111101110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 253 0xfd '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x1e, 0x00, /* 0001111000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x63, 0x00, /* 0110001100 */ + 0x43, 0x00, /* 0100001100 */ + 0x06, 0x00, /* 0000011000 */ + 0x0c, 0x00, /* 0000110000 */ + 0x18, 0x00, /* 0001100000 */ + 0x30, 0x80, /* 0011000010 */ + 0x7f, 0x80, /* 0111111110 */ + 0x7f, 0x80, /* 0111111110 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 254 0xfe '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x3f, 0x00, /* 0011111100 */ + 0x3f, 0x00, /* 0011111100 */ + 0x3f, 0x00, /* 0011111100 */ + 0x3f, 0x00, /* 0011111100 */ + 0x3f, 0x00, /* 0011111100 */ + 0x3f, 0x00, /* 0011111100 */ + 0x3f, 0x00, /* 0011111100 */ + 0x3f, 0x00, /* 0011111100 */ + 0x3f, 0x00, /* 0011111100 */ + 0x3f, 0x00, /* 0011111100 */ + 0x3f, 0x00, /* 0011111100 */ + 0x3f, 0x00, /* 0011111100 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + + /* 255 0xff '.' */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + 0x00, 0x00, /* 0000000000 */ + +}; + + +struct font_desc font_10x18 = { + FONT10x18_IDX, + "10x18", + 10, + 18, + fontdata_10x18, +#ifdef __sparc__ + 5 +#else + -1 +#endif +}; diff --git a/drivers/video/console/font_7x14.c b/drivers/video/console/font_7x14.c new file mode 100644 index 000000000000..1fa7fcf2ff72 --- /dev/null +++ b/drivers/video/console/font_7x14.c @@ -0,0 +1,4118 @@ +/**************************************/ +/* this file adapted from font_8x16.c */ +/* by Jurriaan Kalkman 05-2005 */ +/**************************************/ + +#include + +#define FONTDATAMAX 3584 + +static unsigned char fontdata_7x14[FONTDATAMAX] = { + + /* 0 0x00 '^@' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 1 0x01 '^A' */ + 0x00, /* 0000000 */ + 0x7c, /* 0111110 */ + 0x82, /* 1000001 */ + 0xaa, /* 1010101 */ + 0x82, /* 1000001 */ + 0x82, /* 1000001 */ + 0xba, /* 1011101 */ + 0x92, /* 1001001 */ + 0x82, /* 1000001 */ + 0x7c, /* 0111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 2 0x02 '^B' */ + 0x00, /* 0000000 */ + 0x7c, /* 0111110 */ + 0xfe, /* 1111111 */ + 0xd6, /* 1101011 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xc6, /* 1100011 */ + 0xee, /* 1110111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0x7c, /* 0111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 3 0x03 '^C' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x6c, /* 0110110 */ + 0x7c, /* 0111110 */ + 0xfe, /* 1111111 */ + 0x7c, /* 0111110 */ + 0x38, /* 0011100 */ + 0x18, /* 0001100 */ + 0x10, /* 0001000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 4 0x04 '^D' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x10, /* 0001000 */ + 0x38, /* 0011100 */ + 0x7c, /* 0111110 */ + 0xfe, /* 1111111 */ + 0x7c, /* 0111110 */ + 0x38, /* 0011100 */ + 0x10, /* 0001000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 5 0x05 '^E' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x38, /* 0011100 */ + 0x38, /* 0011100 */ + 0x38, /* 0011100 */ + 0xee, /* 1110111 */ + 0xee, /* 1110111 */ + 0xee, /* 1110111 */ + 0x10, /* 0001000 */ + 0x10, /* 0001000 */ + 0x38, /* 0011100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 6 0x06 '^F' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x10, /* 0001000 */ + 0x38, /* 0011100 */ + 0x7c, /* 0111110 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0x7c, /* 0111110 */ + 0x10, /* 0001000 */ + 0x10, /* 0001000 */ + 0x38, /* 0011100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 7 0x07 '^G' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x18, /* 0001100 */ + 0x3c, /* 0011110 */ + 0x3c, /* 0011110 */ + 0x18, /* 0001100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 8 0x08 '^H' */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xe6, /* 1110011 */ + 0xc2, /* 1100001 */ + 0xc2, /* 1100001 */ + 0xe6, /* 1110011 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + + /* 9 0x09 '^I' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x38, /* 0011100 */ + 0x6c, /* 0110110 */ + 0x44, /* 0100010 */ + 0x6c, /* 0110110 */ + 0x38, /* 0011100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 10 0x0a '^J' */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xc6, /* 1100011 */ + 0x92, /* 1001001 */ + 0xba, /* 1011101 */ + 0x92, /* 1001001 */ + 0xc6, /* 1100011 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + + /* 11 0x0b '^K' */ + 0x00, /* 0000000 */ + 0x1e, /* 0001111 */ + 0x0e, /* 0000111 */ + 0x1a, /* 0001101 */ + 0x1a, /* 0001101 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 12 0x0c '^L' */ + 0x00, /* 0000000 */ + 0x3c, /* 0011110 */ + 0x66, /* 0110011 */ + 0x66, /* 0110011 */ + 0x66, /* 0110011 */ + 0x66, /* 0110011 */ + 0x3c, /* 0011110 */ + 0x18, /* 0001100 */ + 0x7e, /* 0111111 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 13 0x0d '^M' */ + 0x00, /* 0000000 */ + 0x3e, /* 0011111 */ + 0x36, /* 0011011 */ + 0x3e, /* 0011111 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x70, /* 0111000 */ + 0xf0, /* 1111000 */ + 0xe0, /* 1110000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 14 0x0e '^N' */ + 0x00, /* 0000000 */ + 0x7e, /* 0111111 */ + 0x66, /* 0110011 */ + 0x7e, /* 0111111 */ + 0x66, /* 0110011 */ + 0x66, /* 0110011 */ + 0x66, /* 0110011 */ + 0x66, /* 0110011 */ + 0x6e, /* 0110111 */ + 0xee, /* 1110111 */ + 0xec, /* 1110110 */ + 0xc0, /* 1100000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 15 0x0f '^O' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x10, /* 0001000 */ + 0x10, /* 0001000 */ + 0xd6, /* 1101011 */ + 0x38, /* 0011100 */ + 0xee, /* 1110111 */ + 0x38, /* 0011100 */ + 0xd6, /* 1101011 */ + 0x10, /* 0001000 */ + 0x10, /* 0001000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 16 0x10 '^P' */ + 0x00, /* 0000000 */ + 0x80, /* 1000000 */ + 0xc0, /* 1100000 */ + 0xe0, /* 1110000 */ + 0xf0, /* 1111000 */ + 0xfc, /* 1111110 */ + 0xf0, /* 1111000 */ + 0xe0, /* 1110000 */ + 0xc0, /* 1100000 */ + 0x80, /* 1000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 17 0x11 '^Q' */ + 0x00, /* 0000000 */ + 0x04, /* 0000010 */ + 0x0c, /* 0000110 */ + 0x1c, /* 0001110 */ + 0x3c, /* 0011110 */ + 0xfc, /* 1111110 */ + 0x3c, /* 0011110 */ + 0x1c, /* 0001110 */ + 0x0c, /* 0000110 */ + 0x04, /* 0000010 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 18 0x12 '^R' */ + 0x00, /* 0000000 */ + 0x18, /* 0001100 */ + 0x3c, /* 0011110 */ + 0x7e, /* 0111111 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x7e, /* 0111111 */ + 0x3c, /* 0011110 */ + 0x18, /* 0001100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 19 0x13 '^S' */ + 0x00, /* 0000000 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x00, /* 0000000 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 20 0x14 '^T' */ + 0x00, /* 0000000 */ + 0x7e, /* 0111111 */ + 0xd4, /* 1101010 */ + 0xd4, /* 1101010 */ + 0xd4, /* 1101010 */ + 0x74, /* 0111010 */ + 0x14, /* 0001010 */ + 0x14, /* 0001010 */ + 0x14, /* 0001010 */ + 0x14, /* 0001010 */ + 0x16, /* 0001011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 21 0x15 '^U' */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0x60, /* 0110000 */ + 0x38, /* 0011100 */ + 0x6c, /* 0110110 */ + 0xc6, /* 1100011 */ + 0xc6, /* 1100011 */ + 0x6c, /* 0110110 */ + 0x38, /* 0011100 */ + 0x18, /* 0001100 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 22 0x16 '^V' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0xfc, /* 1111110 */ + 0xfc, /* 1111110 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 23 0x17 '^W' */ + 0x00, /* 0000000 */ + 0x18, /* 0001100 */ + 0x3c, /* 0011110 */ + 0x7e, /* 0111111 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x7e, /* 0111111 */ + 0x3c, /* 0011110 */ + 0x18, /* 0001100 */ + 0x7e, /* 0111111 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 24 0x18 '^X' */ + 0x00, /* 0000000 */ + 0x18, /* 0001100 */ + 0x3c, /* 0011110 */ + 0x7e, /* 0111111 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 25 0x19 '^Y' */ + 0x00, /* 0000000 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x7e, /* 0111111 */ + 0x3c, /* 0011110 */ + 0x18, /* 0001100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 26 0x1a '^Z' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x18, /* 0001100 */ + 0xfc, /* 1111110 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 27 0x1b '^[' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0xfc, /* 1111110 */ + 0x60, /* 0110000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 28 0x1c '^\' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 29 0x1d '^]' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x28, /* 0010100 */ + 0x6c, /* 0110110 */ + 0xfe, /* 1111111 */ + 0x6c, /* 0110110 */ + 0x28, /* 0010100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 30 0x1e '^^' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x78, /* 0111100 */ + 0x78, /* 0111100 */ + 0xfc, /* 1111110 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 31 0x1f '^_' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0xfc, /* 1111110 */ + 0x78, /* 0111100 */ + 0x78, /* 0111100 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 32 0x20 ' ' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 33 0x21 '!' */ + 0x00, /* 0000000 */ + 0x18, /* 0001100 */ + 0x3c, /* 0011110 */ + 0x3c, /* 0011110 */ + 0x3c, /* 0011110 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x00, /* 0000000 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 34 0x22 '"' */ + 0x00, /* 0000000 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x28, /* 0010100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 35 0x23 '#' */ + 0x00, /* 0000000 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 36 0x24 '$' */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xc4, /* 1100010 */ + 0xc0, /* 1100000 */ + 0x78, /* 0111100 */ + 0x0c, /* 0000110 */ + 0x8c, /* 1000110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + + /* 37 0x25 '%' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xc0, /* 1100000 */ + 0xc4, /* 1100010 */ + 0x0c, /* 0000110 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0xcc, /* 1100110 */ + 0x8c, /* 1000110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 38 0x26 '&' */ + 0x00, /* 0000000 */ + 0x38, /* 0011100 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x38, /* 0011100 */ + 0x78, /* 0111100 */ + 0xde, /* 1101111 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xdc, /* 1101110 */ + 0x76, /* 0111011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 39 0x27 ''' */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 40 0x28 '(' */ + 0x00, /* 0000000 */ + 0x0c, /* 0000110 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x18, /* 0001100 */ + 0x0c, /* 0000110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 41 0x29 ')' */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x18, /* 0001100 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 42 0x2a '*' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x6c, /* 0110110 */ + 0x38, /* 0011100 */ + 0xfe, /* 1111111 */ + 0x38, /* 0011100 */ + 0x6c, /* 0110110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 43 0x2b '+' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x10, /* 0001000 */ + 0x10, /* 0001000 */ + 0x7c, /* 0111110 */ + 0x10, /* 0001000 */ + 0x10, /* 0001000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 44 0x2c ',' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 45 0x2d '-' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 46 0x2e '.' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 47 0x2f '/' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x04, /* 0000010 */ + 0x0c, /* 0000110 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0xc0, /* 1100000 */ + 0x80, /* 1000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 48 0x30 '0' */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xdc, /* 1101110 */ + 0xec, /* 1110110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 49 0x31 '1' */ + 0x00, /* 0000000 */ + 0x18, /* 0001100 */ + 0x38, /* 0011100 */ + 0x78, /* 0111100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x7c, /* 0111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 50 0x32 '2' */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0x0c, /* 0000110 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0xc0, /* 1100000 */ + 0xcc, /* 1100110 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 51 0x33 '3' */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x38, /* 0011100 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 52 0x34 '4' */ + 0x00, /* 0000000 */ + 0x0c, /* 0000110 */ + 0x1c, /* 0001110 */ + 0x3c, /* 0011110 */ + 0x6c, /* 0110110 */ + 0xcc, /* 1100110 */ + 0xfe, /* 1111111 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 53 0x35 '5' */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xf8, /* 1111100 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 54 0x36 '6' */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xf8, /* 1111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 55 0x37 '7' */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0xcc, /* 1100110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 56 0x38 '8' */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 57 0x39 '9' */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x7c, /* 0111110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x18, /* 0001100 */ + 0x70, /* 0111000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 58 0x3a ':' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 59 0x3b ';' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 60 0x3c '<' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x04, /* 0000010 */ + 0x0c, /* 0000110 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0x30, /* 0011000 */ + 0x18, /* 0001100 */ + 0x0c, /* 0000110 */ + 0x04, /* 0000010 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 61 0x3d '=' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x7c, /* 0111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x7c, /* 0111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 62 0x3e '>' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x40, /* 0100000 */ + 0x60, /* 0110000 */ + 0x30, /* 0011000 */ + 0x18, /* 0001100 */ + 0x0c, /* 0000110 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0x40, /* 0100000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 63 0x3f '?' */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 64 0x40 '@' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xdc, /* 1101110 */ + 0xdc, /* 1101110 */ + 0xd8, /* 1101100 */ + 0xc0, /* 1100000 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 65 0x41 'A' */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xfc, /* 1111110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 66 0x42 'B' */ + 0x00, /* 0000000 */ + 0xf8, /* 1111100 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x78, /* 0111100 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0xf8, /* 1111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 67 0x43 'C' */ + 0x00, /* 0000000 */ + 0x38, /* 0011100 */ + 0x6c, /* 0110110 */ + 0xc4, /* 1100010 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc4, /* 1100010 */ + 0x6c, /* 0110110 */ + 0x38, /* 0011100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 68 0x44 'D' */ + 0x00, /* 0000000 */ + 0xf0, /* 1111000 */ + 0xd8, /* 1101100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xd8, /* 1101100 */ + 0xf0, /* 1111000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 69 0x45 'E' */ + 0x00, /* 0000000 */ + 0x7c, /* 0111110 */ + 0x6c, /* 0110110 */ + 0x64, /* 0110010 */ + 0x68, /* 0110100 */ + 0x78, /* 0111100 */ + 0x68, /* 0110100 */ + 0x60, /* 0110000 */ + 0x64, /* 0110010 */ + 0x6c, /* 0110110 */ + 0x7c, /* 0111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 70 0x46 'F' */ + 0x00, /* 0000000 */ + 0x7c, /* 0111110 */ + 0x64, /* 0110010 */ + 0x60, /* 0110000 */ + 0x68, /* 0110100 */ + 0x78, /* 0111100 */ + 0x68, /* 0110100 */ + 0x60, /* 0110000 */ + 0x60, /* 0110000 */ + 0x60, /* 0110000 */ + 0x70, /* 0111000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 71 0x47 'G' */ + 0x00, /* 0000000 */ + 0x38, /* 0011100 */ + 0x6c, /* 0110110 */ + 0xc4, /* 1100010 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xdc, /* 1101110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x6c, /* 0110110 */ + 0x34, /* 0011010 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 72 0x48 'H' */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xfc, /* 1111110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 73 0x49 'I' */ + 0x00, /* 0000000 */ + 0x3c, /* 0011110 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x3c, /* 0011110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 74 0x4a 'J' */ + 0x00, /* 0000000 */ + 0x1c, /* 0001110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 75 0x4b 'K' */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xd8, /* 1101100 */ + 0xf0, /* 1111000 */ + 0xf0, /* 1111000 */ + 0xd8, /* 1101100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 76 0x4c 'L' */ + 0x00, /* 0000000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc4, /* 1100010 */ + 0xcc, /* 1100110 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 77 0x4d 'M' */ + 0x00, /* 0000000 */ + 0xc6, /* 1100011 */ + 0xee, /* 1110111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xd6, /* 1101011 */ + 0xc6, /* 1100011 */ + 0xc6, /* 1100011 */ + 0xc6, /* 1100011 */ + 0xc6, /* 1100011 */ + 0xc6, /* 1100011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 78 0x4e 'N' */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xec, /* 1110110 */ + 0xec, /* 1110110 */ + 0xfc, /* 1111110 */ + 0xdc, /* 1101110 */ + 0xdc, /* 1101110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 79 0x4f 'O' */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 80 0x50 'P' */ + 0x00, /* 0000000 */ + 0xf8, /* 1111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xf8, /* 1111100 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 81 0x51 'Q' */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xdc, /* 1101110 */ + 0x78, /* 0111100 */ + 0x18, /* 0001100 */ + 0x1c, /* 0001110 */ + 0x00, /* 0000000 */ + + /* 82 0x52 'R' */ + 0x00, /* 0000000 */ + 0xf8, /* 1111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xf8, /* 1111100 */ + 0xd8, /* 1101100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 83 0x53 'S' */ + 0x00, /* 0000000 */ + 0x7c, /* 0111110 */ + 0xc4, /* 1100010 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0x60, /* 0110000 */ + 0x38, /* 0011100 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x8c, /* 1000110 */ + 0xf8, /* 1111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 84 0x54 'T' */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0xfc, /* 1111110 */ + 0xb4, /* 1011010 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 85 0x55 'U' */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 86 0x56 'V' */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x78, /* 0111100 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 87 0x57 'W' */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xfc, /* 1111110 */ + 0xfc, /* 1111110 */ + 0x48, /* 0100100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 88 0x58 'X' */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x78, /* 0111100 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x78, /* 0111100 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 89 0x59 'Y' */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 90 0x5a 'Z' */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0xcc, /* 1100110 */ + 0x8c, /* 1000110 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0xc4, /* 1100010 */ + 0xcc, /* 1100110 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 91 0x5b '[' */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0x60, /* 0110000 */ + 0x60, /* 0110000 */ + 0x60, /* 0110000 */ + 0x60, /* 0110000 */ + 0x60, /* 0110000 */ + 0x60, /* 0110000 */ + 0x60, /* 0110000 */ + 0x60, /* 0110000 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 92 0x5c '\' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x80, /* 1000000 */ + 0xc0, /* 1100000 */ + 0xe0, /* 1110000 */ + 0x70, /* 0111000 */ + 0x38, /* 0011100 */ + 0x1c, /* 0001110 */ + 0x0c, /* 0000110 */ + 0x04, /* 0000010 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 93 0x5d ']' */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 94 0x5e '^' */ + 0x10, /* 0001000 */ + 0x38, /* 0011100 */ + 0x6c, /* 0110110 */ + 0xc6, /* 1100011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 95 0x5f '_' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfe, /* 1111111 */ + 0x00, /* 0000000 */ + + /* 96 0x60 '`' */ + 0x00, /* 0000000 */ + 0x60, /* 0110000 */ + 0x30, /* 0011000 */ + 0x18, /* 0001100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 97 0x61 'a' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0x0c, /* 0000110 */ + 0x7c, /* 0111110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x76, /* 0111011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 98 0x62 'b' */ + 0x00, /* 0000000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xf0, /* 1111000 */ + 0xd8, /* 1101100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xf8, /* 1111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 99 0x63 'c' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 100 0x64 'd' */ + 0x00, /* 0000000 */ + 0x1c, /* 0001110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x3c, /* 0011110 */ + 0x6c, /* 0110110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x76, /* 0111011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 101 0x65 'e' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xfc, /* 1111110 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 102 0x66 'f' */ + 0x00, /* 0000000 */ + 0x38, /* 0011100 */ + 0x6c, /* 0110110 */ + 0x64, /* 0110010 */ + 0x60, /* 0110000 */ + 0xf0, /* 1111000 */ + 0x60, /* 0110000 */ + 0x60, /* 0110000 */ + 0x60, /* 0110000 */ + 0x60, /* 0110000 */ + 0xf0, /* 1111000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 103 0x67 'g' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x76, /* 0111011 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x7c, /* 0111110 */ + 0x0c, /* 0000110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + + /* 104 0x68 'h' */ + 0x00, /* 0000000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xd8, /* 1101100 */ + 0xec, /* 1110110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 105 0x69 'i' */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x70, /* 0111000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 106 0x6a 'j' */ + 0x00, /* 0000000 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x00, /* 0000000 */ + 0x1c, /* 0001110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + + /* 107 0x6b 'k' */ + 0x00, /* 0000000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xcc, /* 1100110 */ + 0xd8, /* 1101100 */ + 0xf0, /* 1111000 */ + 0xf0, /* 1111000 */ + 0xd8, /* 1101100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 108 0x6c 'l' */ + 0x00, /* 0000000 */ + 0x70, /* 0111000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 109 0x6d 'm' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xec, /* 1110110 */ + 0xfe, /* 1111111 */ + 0xd6, /* 1101011 */ + 0xd6, /* 1101011 */ + 0xd6, /* 1101011 */ + 0xd6, /* 1101011 */ + 0xd6, /* 1101011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 110 0x6e 'n' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xb8, /* 1011100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 111 0x6f 'o' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 112 0x70 'p' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xb8, /* 1011100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xf8, /* 1111100 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + + /* 113 0x71 'q' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x74, /* 0111010 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x7c, /* 0111110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + + /* 114 0x72 'r' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xb8, /* 1011100 */ + 0xec, /* 1110110 */ + 0xcc, /* 1100110 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 115 0x73 's' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0x60, /* 0110000 */ + 0x30, /* 0011000 */ + 0x18, /* 0001100 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 116 0x74 't' */ + 0x00, /* 0000000 */ + 0x10, /* 0001000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0xfc, /* 1111110 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x36, /* 0011011 */ + 0x1c, /* 0001110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 117 0x75 'u' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x76, /* 0111011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 118 0x76 'v' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 119 0x77 'w' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xc6, /* 1100011 */ + 0xc6, /* 1100011 */ + 0xd6, /* 1101011 */ + 0xd6, /* 1101011 */ + 0xd6, /* 1101011 */ + 0xfe, /* 1111111 */ + 0x6c, /* 0110110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 120 0x78 'x' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x30, /* 0011000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 121 0x79 'y' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x7c, /* 0111110 */ + 0x0c, /* 0000110 */ + 0x18, /* 0001100 */ + 0xf0, /* 1111000 */ + + /* 122 0x7a 'z' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0xcc, /* 1100110 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0xcc, /* 1100110 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 123 0x7b '{' */ + 0x00, /* 0000000 */ + 0x1c, /* 0001110 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0xe0, /* 1110000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x1c, /* 0001110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 124 0x7c '|' */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 125 0x7d '}' */ + 0x00, /* 0000000 */ + 0x70, /* 0111000 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x0e, /* 0000111 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x70, /* 0111000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 126 0x7e '~' */ + 0x00, /* 0000000 */ + 0xec, /* 1110110 */ + 0xb8, /* 1011100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 127 0x7f '' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x10, /* 0001000 */ + 0x38, /* 0011100 */ + 0x6c, /* 0110110 */ + 0xc6, /* 1100011 */ + 0xc6, /* 1100011 */ + 0xc6, /* 1100011 */ + 0xfe, /* 1111111 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 128 0x80 '€' */ + 0x00, /* 0000000 */ + 0x38, /* 0011100 */ + 0x6c, /* 0110110 */ + 0xc4, /* 1100010 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc4, /* 1100010 */ + 0x6c, /* 0110110 */ + 0x38, /* 0011100 */ + 0x18, /* 0001100 */ + 0x70, /* 0111000 */ + 0x00, /* 0000000 */ + + /* 129 0x81 '' */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x76, /* 0111011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 130 0x82 '‚' */ + 0x0c, /* 0000110 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xfc, /* 1111110 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 131 0x83 'ƒ' */ + 0x10, /* 0001000 */ + 0x38, /* 0011100 */ + 0x6c, /* 0110110 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0x0c, /* 0000110 */ + 0x7c, /* 0111110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x76, /* 0111011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 132 0x84 '„' */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0x0c, /* 0000110 */ + 0x7c, /* 0111110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x76, /* 0111011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 133 0x85 '…' */ + 0x60, /* 0110000 */ + 0x30, /* 0011000 */ + 0x18, /* 0001100 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0x0c, /* 0000110 */ + 0x7c, /* 0111110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x76, /* 0111011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 134 0x86 '†' */ + 0x38, /* 0011100 */ + 0x6c, /* 0110110 */ + 0x38, /* 0011100 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0x0c, /* 0000110 */ + 0x7c, /* 0111110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x76, /* 0111011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 135 0x87 '‡' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0xe0, /* 1110000 */ + + /* 136 0x88 'ˆ' */ + 0x10, /* 0001000 */ + 0x38, /* 0011100 */ + 0x6c, /* 0110110 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xfc, /* 1111110 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 137 0x89 '‰' */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xfc, /* 1111110 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 138 0x8a 'Š' */ + 0xc0, /* 1100000 */ + 0x60, /* 0110000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xfc, /* 1111110 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 139 0x8b '‹' */ + 0x00, /* 0000000 */ + 0x6c, /* 0110110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x38, /* 0011100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x3c, /* 0011110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 140 0x8c 'Œ' */ + 0x30, /* 0011000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x70, /* 0111000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 141 0x8d '' */ + 0xc0, /* 1100000 */ + 0x60, /* 0110000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x70, /* 0111000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 142 0x8e 'Ž' */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xfc, /* 1111110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 143 0x8f '' */ + 0x30, /* 0011000 */ + 0x48, /* 0100100 */ + 0x48, /* 0100100 */ + 0x30, /* 0011000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xfc, /* 1111110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 144 0x90 '' */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0xfc, /* 1111110 */ + 0xcc, /* 1100110 */ + 0xc4, /* 1100010 */ + 0xd0, /* 1101000 */ + 0xf0, /* 1111000 */ + 0xd0, /* 1101000 */ + 0xc4, /* 1100010 */ + 0xcc, /* 1100110 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 145 0x91 '‘' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xec, /* 1110110 */ + 0x36, /* 0011011 */ + 0x36, /* 0011011 */ + 0x7e, /* 0111111 */ + 0xd8, /* 1101100 */ + 0xd8, /* 1101100 */ + 0x6e, /* 0110111 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 146 0x92 '’' */ + 0x00, /* 0000000 */ + 0x3e, /* 0011111 */ + 0x6c, /* 0110110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xfe, /* 1111111 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xce, /* 1100111 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 147 0x93 '“' */ + 0x10, /* 0001000 */ + 0x38, /* 0011100 */ + 0x6c, /* 0110110 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 148 0x94 '”' */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 149 0x95 '•' */ + 0xc0, /* 1100000 */ + 0x60, /* 0110000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 150 0x96 '–' */ + 0x30, /* 0011000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x76, /* 0111011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 151 0x97 '—' */ + 0x60, /* 0110000 */ + 0x30, /* 0011000 */ + 0x18, /* 0001100 */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x76, /* 0111011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 152 0x98 '˜' */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x7c, /* 0111110 */ + 0x0c, /* 0000110 */ + 0x18, /* 0001100 */ + 0x70, /* 0111000 */ + + /* 153 0x99 '™' */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 154 0x9a 'š' */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 155 0x9b '›' */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x7c, /* 0111110 */ + 0xcc, /* 1100110 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xcc, /* 1100110 */ + 0x7c, /* 0111110 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 156 0x9c 'œ' */ + 0x38, /* 0011100 */ + 0x6c, /* 0110110 */ + 0x64, /* 0110010 */ + 0x60, /* 0110000 */ + 0xf0, /* 1111000 */ + 0x60, /* 0110000 */ + 0x60, /* 0110000 */ + 0x60, /* 0110000 */ + 0x60, /* 0110000 */ + 0xe6, /* 1110011 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 157 0x9d '' */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x30, /* 0011000 */ + 0xfc, /* 1111110 */ + 0x30, /* 0011000 */ + 0xfc, /* 1111110 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 158 0x9e 'ž' */ + 0xf8, /* 1111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xf8, /* 1111100 */ + 0xc4, /* 1100010 */ + 0xcc, /* 1100110 */ + 0xde, /* 1101111 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xc6, /* 1100011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 159 0x9f 'Ÿ' */ + 0x1c, /* 0001110 */ + 0x36, /* 0011011 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0xfc, /* 1111110 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0xb0, /* 1011000 */ + 0xe0, /* 1110000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 160 0xa0 ' ' */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0x0c, /* 0000110 */ + 0x7c, /* 0111110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x76, /* 0111011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 161 0xa1 '¡' */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0x00, /* 0000000 */ + 0x70, /* 0111000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 162 0xa2 '¢' */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 163 0xa3 '£' */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x76, /* 0111011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 164 0xa4 '€' */ + 0x00, /* 0000000 */ + 0x76, /* 0111011 */ + 0xdc, /* 1101110 */ + 0x00, /* 0000000 */ + 0xb8, /* 1011100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 165 0xa5 '¥' */ + 0x76, /* 0111011 */ + 0xdc, /* 1101110 */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xec, /* 1110110 */ + 0xec, /* 1110110 */ + 0xfc, /* 1111110 */ + 0xdc, /* 1101110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 166 0xa6 'Š' */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xd8, /* 1101100 */ + 0xd8, /* 1101100 */ + 0x7c, /* 0111110 */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 167 0xa7 '§' */ + 0x00, /* 0000000 */ + 0x70, /* 0111000 */ + 0xd8, /* 1101100 */ + 0xd8, /* 1101100 */ + 0x70, /* 0111000 */ + 0x00, /* 0000000 */ + 0xf8, /* 1111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 168 0xa8 'š' */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0xc0, /* 1100000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 169 0xa9 '©' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 170 0xaa 'ª' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 171 0xab '«' */ + 0x60, /* 0110000 */ + 0xe0, /* 1110000 */ + 0x62, /* 0110001 */ + 0x66, /* 0110011 */ + 0x6c, /* 0110110 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0xc0, /* 1100000 */ + 0xb8, /* 1011100 */ + 0x4c, /* 0100110 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x7c, /* 0111110 */ + + /* 172 0xac '¬' */ + 0x60, /* 0110000 */ + 0xe0, /* 1110000 */ + 0x62, /* 0110001 */ + 0x66, /* 0110011 */ + 0x6c, /* 0110110 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x6c, /* 0110110 */ + 0xdc, /* 1101110 */ + 0xb4, /* 1011010 */ + 0x7e, /* 0111111 */ + 0x0c, /* 0000110 */ + 0x0c, /* 0000110 */ + 0x00, /* 0000000 */ + + /* 173 0xad '­' */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x78, /* 0111100 */ + 0x78, /* 0111100 */ + 0x78, /* 0111100 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 174 0xae '®' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x36, /* 0011011 */ + 0x6c, /* 0110110 */ + 0xd8, /* 1101100 */ + 0x6c, /* 0110110 */ + 0x36, /* 0011011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 175 0xaf '¯' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xd8, /* 1101100 */ + 0x6c, /* 0110110 */ + 0x36, /* 0011011 */ + 0x6c, /* 0110110 */ + 0xd8, /* 1101100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 176 0xb0 '°' */ + 0x88, /* 1000100 */ + 0x22, /* 0010001 */ + 0x88, /* 1000100 */ + 0x22, /* 0010001 */ + 0x88, /* 1000100 */ + 0x22, /* 0010001 */ + 0x88, /* 1000100 */ + 0x22, /* 0010001 */ + 0x88, /* 1000100 */ + 0x22, /* 0010001 */ + 0x88, /* 1000100 */ + 0x22, /* 0010001 */ + 0x88, /* 1000100 */ + 0x22, /* 0010001 */ + + /* 177 0xb1 '±' */ + 0x54, /* 0101010 */ + 0xaa, /* 1010101 */ + 0x54, /* 0101010 */ + 0xaa, /* 1010101 */ + 0x54, /* 0101010 */ + 0xaa, /* 1010101 */ + 0x54, /* 0101010 */ + 0xaa, /* 1010101 */ + 0x54, /* 0101010 */ + 0xaa, /* 1010101 */ + 0x54, /* 0101010 */ + 0xaa, /* 1010101 */ + 0x54, /* 0101010 */ + 0xaa, /* 1010101 */ + + /* 178 0xb2 '²' */ + 0xee, /* 1110111 */ + 0xba, /* 1011101 */ + 0xee, /* 1110111 */ + 0xba, /* 1011101 */ + 0xee, /* 1110111 */ + 0xba, /* 1011101 */ + 0xee, /* 1110111 */ + 0xba, /* 1011101 */ + 0xee, /* 1110111 */ + 0xba, /* 1011101 */ + 0xee, /* 1110111 */ + 0xba, /* 1011101 */ + 0xee, /* 1110111 */ + 0xba, /* 1011101 */ + + /* 179 0xb3 '³' */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + + /* 180 0xb4 'Ž' */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0xf0, /* 1111000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + + /* 181 0xb5 'µ' */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0xf0, /* 1111000 */ + 0x30, /* 0011000 */ + 0xf0, /* 1111000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + + /* 182 0xb6 '¶' */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0xec, /* 1110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + + /* 183 0xb7 '·' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + + /* 184 0xb8 'ž' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xf0, /* 1111000 */ + 0x30, /* 0011000 */ + 0xf0, /* 1111000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + + /* 185 0xb9 '¹' */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0xec, /* 1110110 */ + 0x0c, /* 0000110 */ + 0xec, /* 1110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + + /* 186 0xba 'º' */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + + /* 187 0xbb '»' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0x0c, /* 0000110 */ + 0xec, /* 1110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + + /* 188 0xbc 'Œ' */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0xec, /* 1110110 */ + 0x0c, /* 0000110 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 189 0xbd 'œ' */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 190 0xbe 'Ÿ' */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0xf0, /* 1111000 */ + 0x30, /* 0011000 */ + 0xf0, /* 1111000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 191 0xbf '¿' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xf0, /* 1111000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + + /* 192 0xc0 'À' */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x3e, /* 0011111 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 193 0xc1 'Á' */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0xfe, /* 1111111 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 194 0xc2 'Â' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfe, /* 1111111 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + + /* 195 0xc3 'Ã' */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x3e, /* 0011111 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + + /* 196 0xc4 'Ä' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfe, /* 1111111 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 197 0xc5 'Å' */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0xfe, /* 1111111 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + + /* 198 0xc6 'Æ' */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x3e, /* 0011111 */ + 0x30, /* 0011000 */ + 0x3e, /* 0011111 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + + /* 199 0xc7 'Ç' */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6e, /* 0110111 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + + /* 200 0xc8 'È' */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6e, /* 0110111 */ + 0x60, /* 0110000 */ + 0x7e, /* 0111111 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 201 0xc9 'É' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x7e, /* 0111111 */ + 0x60, /* 0110000 */ + 0x6e, /* 0110111 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + + /* 202 0xca 'Ê' */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0xee, /* 1110111 */ + 0x00, /* 0000000 */ + 0xfe, /* 1111111 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 203 0xcb 'Ë' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfe, /* 1111111 */ + 0x00, /* 0000000 */ + 0xee, /* 1110111 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + + /* 204 0xcc 'Ì' */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6e, /* 0110111 */ + 0x60, /* 0110000 */ + 0x6e, /* 0110111 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + + /* 205 0xcd 'Í' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfe, /* 1111111 */ + 0x00, /* 0000000 */ + 0xfe, /* 1111111 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 206 0xce 'Î' */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0xee, /* 1110111 */ + 0x00, /* 0000000 */ + 0xee, /* 1110111 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + + /* 207 0xcf 'Ï' */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0xfe, /* 1111111 */ + 0x00, /* 0000000 */ + 0xfe, /* 1111111 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 208 0xd0 'Ð' */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0xfe, /* 1111111 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 209 0xd1 'Ñ' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfe, /* 1111111 */ + 0x00, /* 0000000 */ + 0xfe, /* 1111111 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + + /* 210 0xd2 'Ò' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfe, /* 1111111 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + + /* 211 0xd3 'Ó' */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x7e, /* 0111111 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 212 0xd4 'Ô' */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x3e, /* 0011111 */ + 0x30, /* 0011000 */ + 0x3e, /* 0011111 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 213 0xd5 'Õ' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x3e, /* 0011111 */ + 0x30, /* 0011000 */ + 0x3e, /* 0011111 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + + /* 214 0xd6 'Ö' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x7e, /* 0111111 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + + /* 215 0xd7 '×' */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0xfe, /* 1111111 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + + /* 216 0xd8 'Ø' */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0xfe, /* 1111111 */ + 0x30, /* 0011000 */ + 0xfe, /* 1111111 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + + /* 217 0xd9 'Ù' */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0xf0, /* 1111000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 218 0xda 'Ú' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x3e, /* 0011111 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + + /* 219 0xdb 'Û' */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + + /* 220 0xdc 'Ü' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + + /* 221 0xdd 'Ý' */ + 0xe0, /* 1110000 */ + 0xe0, /* 1110000 */ + 0xe0, /* 1110000 */ + 0xe0, /* 1110000 */ + 0xe0, /* 1110000 */ + 0xe0, /* 1110000 */ + 0xe0, /* 1110000 */ + 0xe0, /* 1110000 */ + 0xe0, /* 1110000 */ + 0xe0, /* 1110000 */ + 0xe0, /* 1110000 */ + 0xe0, /* 1110000 */ + 0xe0, /* 1110000 */ + 0xe0, /* 1110000 */ + + /* 222 0xde 'Þ' */ + 0x1e, /* 0001111 */ + 0x1e, /* 0001111 */ + 0x1e, /* 0001111 */ + 0x1e, /* 0001111 */ + 0x1e, /* 0001111 */ + 0x1e, /* 0001111 */ + 0x1e, /* 0001111 */ + 0x1e, /* 0001111 */ + 0x1e, /* 0001111 */ + 0x1e, /* 0001111 */ + 0x1e, /* 0001111 */ + 0x1e, /* 0001111 */ + 0x1e, /* 0001111 */ + 0x1e, /* 0001111 */ + + /* 223 0xdf 'ß' */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 224 0xe0 'à' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x76, /* 0111011 */ + 0xdc, /* 1101110 */ + 0xd8, /* 1101100 */ + 0xd8, /* 1101100 */ + 0xd8, /* 1101100 */ + 0xdc, /* 1101110 */ + 0x76, /* 0111011 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 225 0xe1 'á' */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xd8, /* 1101100 */ + 0xcc, /* 1100110 */ + 0xc6, /* 1100011 */ + 0xc6, /* 1100011 */ + 0xc6, /* 1100011 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 226 0xe2 'â' */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 227 0xe3 'ã' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfe, /* 1111111 */ + 0xfe, /* 1111111 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 228 0xe4 'ä' */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0xcc, /* 1100110 */ + 0x60, /* 0110000 */ + 0x30, /* 0011000 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0xcc, /* 1100110 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 229 0xe5 'å' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x7e, /* 0111111 */ + 0xd8, /* 1101100 */ + 0xd8, /* 1101100 */ + 0xd8, /* 1101100 */ + 0xd8, /* 1101100 */ + 0xd8, /* 1101100 */ + 0x70, /* 0111000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 230 0xe6 'æ' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xf8, /* 1111100 */ + 0xc0, /* 1100000 */ + 0xc0, /* 1100000 */ + 0x80, /* 1000000 */ + + /* 231 0xe7 'ç' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x76, /* 0111011 */ + 0xdc, /* 1101110 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 232 0xe8 'è' */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0x30, /* 0011000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x30, /* 0011000 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 233 0xe9 'é' */ + 0x00, /* 0000000 */ + 0x38, /* 0011100 */ + 0x6c, /* 0110110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xfc, /* 1111110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x6c, /* 0110110 */ + 0x38, /* 0011100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 234 0xea 'ê' */ + 0x00, /* 0000000 */ + 0x38, /* 0011100 */ + 0x6c, /* 0110110 */ + 0xc6, /* 1100011 */ + 0xc6, /* 1100011 */ + 0xc6, /* 1100011 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0xee, /* 1110111 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 235 0xeb 'ë' */ + 0x00, /* 0000000 */ + 0x3c, /* 0011110 */ + 0x60, /* 0110000 */ + 0x30, /* 0011000 */ + 0x18, /* 0001100 */ + 0x7c, /* 0111110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x78, /* 0111100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 236 0xec 'ì' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x7c, /* 0111110 */ + 0xd6, /* 1101011 */ + 0xd6, /* 1101011 */ + 0xd6, /* 1101011 */ + 0x7c, /* 0111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 237 0xed 'í' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x06, /* 0000011 */ + 0x0c, /* 0000110 */ + 0x7c, /* 0111110 */ + 0xd6, /* 1101011 */ + 0xd6, /* 1101011 */ + 0xe6, /* 1110011 */ + 0x7c, /* 0111110 */ + 0x60, /* 0110000 */ + 0xc0, /* 1100000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 238 0xee 'î' */ + 0x00, /* 0000000 */ + 0x1c, /* 0001110 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0x60, /* 0110000 */ + 0x7c, /* 0111110 */ + 0x60, /* 0110000 */ + 0x60, /* 0110000 */ + 0x60, /* 0110000 */ + 0x30, /* 0011000 */ + 0x1c, /* 0001110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 239 0xef 'ï' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0xcc, /* 1100110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 240 0xf0 'ð' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 241 0xf1 'ñ' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0xfc, /* 1111110 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 242 0xf2 'ò' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x60, /* 0110000 */ + 0x30, /* 0011000 */ + 0x18, /* 0001100 */ + 0x0c, /* 0000110 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 243 0xf3 'ó' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x60, /* 0110000 */ + 0xc0, /* 1100000 */ + 0x60, /* 0110000 */ + 0x30, /* 0011000 */ + 0x18, /* 0001100 */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 244 0xf4 'ô' */ + 0x00, /* 0000000 */ + 0x1c, /* 0001110 */ + 0x36, /* 0011011 */ + 0x36, /* 0011011 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + + /* 245 0xf5 'õ' */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0xd8, /* 1101100 */ + 0xd8, /* 1101100 */ + 0xd8, /* 1101100 */ + 0x70, /* 0111000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 246 0xf6 'ö' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 247 0xf7 '÷' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x76, /* 0111011 */ + 0xdc, /* 1101110 */ + 0x00, /* 0000000 */ + 0x76, /* 0111011 */ + 0xdc, /* 1101110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 248 0xf8 'ø' */ + 0x38, /* 0011100 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x38, /* 0011100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 249 0xf9 'ù' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 250 0xfa 'ú' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x30, /* 0011000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 251 0xfb 'û' */ + 0x1e, /* 0001111 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0x18, /* 0001100 */ + 0xd8, /* 1101100 */ + 0xd8, /* 1101100 */ + 0xd8, /* 1101100 */ + 0x78, /* 0111100 */ + 0x38, /* 0011100 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 252 0xfc 'ü' */ + 0xd8, /* 1101100 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x6c, /* 0110110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 253 0xfd 'ý' */ + 0x78, /* 0111100 */ + 0xcc, /* 1100110 */ + 0x18, /* 0001100 */ + 0x30, /* 0011000 */ + 0x64, /* 0110010 */ + 0xfc, /* 1111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 254 0xfe 'þ' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x7c, /* 0111110 */ + 0x7c, /* 0111110 */ + 0x7c, /* 0111110 */ + 0x7c, /* 0111110 */ + 0x7c, /* 0111110 */ + 0x7c, /* 0111110 */ + 0x7c, /* 0111110 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + + /* 255 0xff 'ÿ' */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + 0x00, /* 0000000 */ + +}; + + +struct font_desc font_7x14 = { + FONT7x14_IDX, + "7x14", + 7, + 14, + fontdata_7x14, + 0 +}; diff --git a/drivers/video/console/font_sun12x22.c b/drivers/video/console/font_sun12x22.c index 05215d0c3e09..c7bd967ea100 100644 --- a/drivers/video/console/font_sun12x22.c +++ b/drivers/video/console/font_sun12x22.c @@ -29,24 +29,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 1 0x01 '^A' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x1f, 0xc0, /* 000111111100 */ + 0x30, 0x60, /* 001100000110 */ + 0x65, 0x30, /* 011001010011 */ + 0x6d, 0xb0, /* 011011011011 */ + 0x60, 0x30, /* 011000000011 */ + 0x62, 0x30, /* 011000100011 */ + 0x62, 0x30, /* 011000100011 */ + 0x60, 0x30, /* 011000000011 */ + 0x6f, 0xb0, /* 011011111011 */ + 0x67, 0x30, /* 011001110011 */ + 0x30, 0x60, /* 001100000110 */ + 0x1f, 0xc0, /* 000111111100 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -54,24 +53,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 2 0x02 '^B' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x1f, 0xc0, /* 000111111100 */ + 0x3f, 0xe0, /* 001111111110 */ + 0x7a, 0xf0, /* 011110101111 */ + 0x72, 0x70, /* 011100100111 */ + 0x7f, 0xf0, /* 011111111111 */ + 0x7d, 0xf0, /* 011111011111 */ + 0x7d, 0xf0, /* 011111011111 */ + 0x7f, 0xf0, /* 011111111111 */ + 0x70, 0x70, /* 011100000111 */ + 0x78, 0xf0, /* 011110001111 */ + 0x3f, 0xe0, /* 001111111110 */ + 0x1f, 0xc0, /* 000111111100 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -79,24 +77,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 3 0x03 '^C' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x19, 0x80, /* 000110011000 */ 0x3f, 0xc0, /* 001111111100 */ + 0x7f, 0xe0, /* 011111111110 */ 0x3f, 0xc0, /* 001111111100 */ 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ + 0x1f, 0x80, /* 000111111000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -104,24 +101,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 4 0x04 '^D' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x02, 0x00, /* 000000100000 */ + 0x07, 0x00, /* 000001110000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x1f, 0xc0, /* 000111111100 */ + 0x1f, 0xc0, /* 000111111100 */ + 0x3f, 0xe0, /* 001111111110 */ + 0x1f, 0xc0, /* 000111111100 */ + 0x1f, 0xc0, /* 000111111100 */ + 0x0f, 0x80, /* 000011111000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x07, 0x00, /* 000001110000 */ + 0x02, 0x00, /* 000000100000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -129,24 +125,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 5 0x05 '^E' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x02, 0x00, /* 000000100000 */ + 0x07, 0x00, /* 000001110000 */ + 0x07, 0x00, /* 000001110000 */ + 0x02, 0x00, /* 000000100000 */ + 0x18, 0xc0, /* 000110001100 */ + 0x3d, 0xe0, /* 001111011110 */ + 0x3d, 0xe0, /* 001111011110 */ + 0x1a, 0xc0, /* 000110101100 */ + 0x02, 0x00, /* 000000100000 */ + 0x07, 0x00, /* 000001110000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x1f, 0xc0, /* 000111111100 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -154,23 +149,22 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 6 0x06 '^F' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x1f, 0x80, /* 000111111000 */ 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x36, 0xc0, /* 001101101100 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x1f, 0x80, /* 000111111000 */ 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -179,24 +173,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 7 0x07 '^G' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ + 0x06, 0x00, /* 000001100000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x1f, 0x80, /* 000111111000 */ 0x3f, 0xc0, /* 001111111100 */ 0x3f, 0xc0, /* 001111111100 */ + 0x1f, 0x80, /* 000111111000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -204,49 +197,47 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 8 0x08 '^H' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xf9, 0xf0, /* 111110011111 */ + 0xf0, 0xf0, /* 111100001111 */ + 0xf0, 0xf0, /* 111100001111 */ + 0xe0, 0x70, /* 111000000111 */ + 0xe0, 0x70, /* 111000000111 */ + 0xc0, 0x30, /* 110000000011 */ + 0xc0, 0x30, /* 110000000011 */ + 0xe0, 0x70, /* 111000000111 */ + 0xe0, 0x70, /* 111000000111 */ + 0xf0, 0xf0, /* 111100001111 */ + 0xf0, 0xf0, /* 111100001111 */ + 0xf9, 0xf0, /* 111110011111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ /* 9 0x09 '^I' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x06, 0x00, /* 000001100000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -254,74 +245,71 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 10 0x0a '^J' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xf9, 0xf0, /* 111110011111 */ + 0xf0, 0xf0, /* 111100001111 */ + 0xf0, 0xf0, /* 111100001111 */ + 0xe6, 0x70, /* 111001100111 */ + 0xe6, 0x70, /* 111001100111 */ + 0xcf, 0x30, /* 110011110011 */ + 0xcf, 0x30, /* 110011110011 */ + 0xe6, 0x70, /* 111001100111 */ + 0xe6, 0x70, /* 111001100111 */ + 0xf0, 0xf0, /* 111100001111 */ + 0xf0, 0xf0, /* 111100001111 */ + 0xf9, 0xf0, /* 111110011111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ /* 11 0x0b '^K' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x0f, 0xe0, /* 000011111110 */ + 0x0f, 0xe0, /* 000011111110 */ + 0x01, 0xe0, /* 000000011110 */ + 0x03, 0x60, /* 000000110110 */ + 0x06, 0x60, /* 000001100110 */ + 0x1e, 0x00, /* 000111100000 */ + 0x33, 0x00, /* 001100110000 */ + 0x33, 0x00, /* 001100110000 */ + 0x61, 0x80, /* 011000011000 */ + 0x61, 0x80, /* 011000011000 */ + 0x33, 0x00, /* 001100110000 */ + 0x33, 0x00, /* 001100110000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x0c, 0x00, /* 000011000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ /* 12 0x0c '^L' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ + 0x06, 0x00, /* 000001100000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x19, 0x80, /* 000110011000 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x19, 0x80, /* 000110011000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ 0x3f, 0xc0, /* 001111111100 */ 0x3f, 0xc0, /* 001111111100 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -329,149 +317,143 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 13 0x0d '^M' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x0f, 0xe0, /* 000011111110 */ + 0x0c, 0x60, /* 000011000110 */ + 0x0c, 0x60, /* 000011000110 */ + 0x0f, 0xe0, /* 000011111110 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x3c, 0x00, /* 001111000000 */ + 0x7c, 0x00, /* 011111000000 */ + 0x78, 0x00, /* 011110000000 */ + 0x30, 0x00, /* 001100000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ /* 14 0x0e '^N' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x1f, 0xe0, /* 000111111110 */ + 0x18, 0x60, /* 000110000110 */ + 0x18, 0x60, /* 000110000110 */ + 0x1f, 0xe0, /* 000111111110 */ + 0x18, 0x60, /* 000110000110 */ + 0x18, 0x60, /* 000110000110 */ + 0x18, 0x60, /* 000110000110 */ + 0x18, 0x60, /* 000110000110 */ + 0x18, 0x60, /* 000110000110 */ + 0x18, 0x60, /* 000110000110 */ + 0x19, 0xe0, /* 000110011110 */ + 0x1b, 0xe0, /* 000110111110 */ + 0x1b, 0xc0, /* 000110111100 */ + 0x79, 0x80, /* 011110011000 */ + 0xf8, 0x00, /* 111110000000 */ + 0xf0, 0x00, /* 111100000000 */ + 0x60, 0x00, /* 011000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ /* 15 0x0f '^O' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x18, 0xc0, /* 000110001100 */ + 0x0d, 0x80, /* 000011011000 */ + 0x6d, 0xb0, /* 011011011011 */ + 0x3d, 0xe0, /* 001111011110 */ 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - - /* 16 0x10 '^P' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ + 0x3d, 0xe0, /* 001111011110 */ + 0x6d, 0xb0, /* 011011011011 */ + 0x0d, 0x80, /* 000011011000 */ + 0x18, 0xc0, /* 000110001100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + + /* 16 0x10 '^P' */ 0x00, 0x00, /* 000000000000 */ + 0x00, 0x20, /* 000000000010 */ + 0x00, 0x60, /* 000000000110 */ + 0x00, 0xe0, /* 000000001110 */ + 0x01, 0xe0, /* 000000011110 */ + 0x03, 0xe0, /* 000000111110 */ + 0x07, 0xe0, /* 000001111110 */ + 0x0f, 0xe0, /* 000011111110 */ + 0x1f, 0xe0, /* 000111111110 */ + 0x3f, 0xe0, /* 001111111110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x3f, 0xe0, /* 001111111110 */ + 0x1f, 0xe0, /* 000111111110 */ + 0x0f, 0xe0, /* 000011111110 */ + 0x07, 0xe0, /* 000001111110 */ + 0x03, 0xe0, /* 000000111110 */ + 0x01, 0xe0, /* 000000011110 */ + 0x00, 0xe0, /* 000000001110 */ + 0x00, 0x60, /* 000000000110 */ + 0x00, 0x20, /* 000000000010 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ /* 17 0x11 '^Q' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x40, 0x00, /* 010000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x70, 0x00, /* 011100000000 */ + 0x78, 0x00, /* 011110000000 */ + 0x7c, 0x00, /* 011111000000 */ + 0x7e, 0x00, /* 011111100000 */ + 0x7f, 0x00, /* 011111110000 */ + 0x7f, 0x80, /* 011111111000 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x7f, 0x80, /* 011111111000 */ + 0x7f, 0x00, /* 011111110000 */ + 0x7e, 0x00, /* 011111100000 */ + 0x7c, 0x00, /* 011111000000 */ + 0x78, 0x00, /* 011110000000 */ + 0x70, 0x00, /* 011100000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x40, 0x00, /* 010000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ /* 18 0x12 '^R' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x04, 0x00, /* 000001000000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x3f, 0x80, /* 001111111000 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x3f, 0x80, /* 001111111000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x04, 0x00, /* 000001000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -551,99 +533,95 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 22 0x16 '^V' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - - /* 23 0x17 '^W' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - /* 24 0x18 '^X' */ - /* FIXME */ + /* 23 0x17 '^W' */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x04, 0x00, /* 000001000000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x3f, 0x80, /* 001111111000 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x3f, 0x80, /* 001111111000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x04, 0x00, /* 000001000000 */ 0x00, 0x00, /* 000000000000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + + /* 24 0x18 '^X' */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - - /* 25 0x19 '^Y' */ - /* FIXME */ + 0x04, 0x00, /* 000001000000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x3f, 0x80, /* 001111111000 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + + /* 25 0x19 '^Y' */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x3f, 0x80, /* 001111111000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x04, 0x00, /* 000001000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -651,24 +629,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 26 0x1a '^Z' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x08, 0x00, /* 000010000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x38, 0x00, /* 001110000000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0xff, 0xe0, /* 111111111110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x38, 0x00, /* 001110000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x08, 0x00, /* 000010000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -676,24 +653,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 27 0x1b '^[' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x01, 0x00, /* 000000010000 */ + 0x01, 0x80, /* 000000011000 */ + 0x01, 0xc0, /* 000000011100 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xf0, /* 011111111111 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x01, 0xc0, /* 000000011100 */ + 0x01, 0x80, /* 000000011000 */ + 0x01, 0x00, /* 000000010000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -701,24 +677,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 28 0x1c '^\' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x3f, 0xe0, /* 001111111110 */ + 0x3f, 0xe0, /* 001111111110 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -726,24 +701,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 29 0x1d '^]' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x09, 0x00, /* 000010010000 */ + 0x19, 0x80, /* 000110011000 */ + 0x39, 0xc0, /* 001110011100 */ + 0x7f, 0xe0, /* 011111111110 */ + 0xff, 0xf0, /* 111111111111 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x39, 0xc0, /* 001110011100 */ + 0x19, 0x80, /* 000110011000 */ + 0x09, 0x00, /* 000010010000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -751,24 +725,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 30 0x1e '^^' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x04, 0x00, /* 000001000000 */ + 0x04, 0x00, /* 000001000000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x3f, 0x80, /* 001111111000 */ + 0x3f, 0x80, /* 001111111000 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -776,24 +749,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 31 0x1f '^_' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x3f, 0x80, /* 001111111000 */ + 0x3f, 0x80, /* 001111111000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x04, 0x00, /* 000001000000 */ + 0x04, 0x00, /* 000001000000 */ + 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -3081,29 +3053,28 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 127 0x7f '.' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0xff, 0xf0, /* 111111111111 */ + 0xff, 0xf0, /* 111111111111 */ + 0x00, 0x00, /* 000000000000 */ /* 128 0x80 '.' */ 0x00, 0x00, /* 000000000000 */ @@ -3826,24 +3797,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 158 0x9e '.' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x7f, 0x80, /* 011111111000 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0x60, /* 001100000110 */ + 0x30, 0x60, /* 001100000110 */ + 0x30, 0x60, /* 001100000110 */ + 0x30, 0xc0, /* 001100001100 */ + 0x37, 0x80, /* 001101111000 */ + 0x30, 0x00, /* 001100000000 */ + 0x33, 0x00, /* 001100110000 */ + 0x37, 0x80, /* 001101111000 */ + 0x33, 0x00, /* 001100110000 */ + 0x33, 0x00, /* 001100110000 */ + 0x33, 0x30, /* 001100110011 */ + 0x31, 0xe0, /* 001100011110 */ + 0x78, 0xc0, /* 011110001100 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -3851,28 +3821,27 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 159 0x9f '.' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x00, 0xc0, /* 000000001100 */ + 0x01, 0xe0, /* 000000011110 */ + 0x03, 0x30, /* 000000110011 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x3f, 0xe0, /* 001111111110 */ + 0x7f, 0xc0, /* 011111111100 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0xcc, 0x00, /* 110011000000 */ + 0x78, 0x00, /* 011110000000 */ + 0x30, 0x00, /* 001100000000 */ 0x00, 0x00, /* 000000000000 */ /* 160 0xa0 '.' */ @@ -4092,24 +4061,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 169 0xa9 '.' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x3f, 0xc0, /* 001111111100 */ 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -5413,24 +5381,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 224 0xe0 '.' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x60, /* 000011110110 */ + 0x13, 0xe0, /* 000100111110 */ + 0x21, 0xc0, /* 001000011100 */ + 0x60, 0xc0, /* 011000001100 */ + 0x60, 0xc0, /* 011000001100 */ + 0x60, 0xc0, /* 011000001100 */ + 0x60, 0xc0, /* 011000001100 */ + 0x70, 0x80, /* 011100001000 */ + 0x39, 0xc0, /* 001110011100 */ + 0x1f, 0x60, /* 000111110110 */ + 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -5462,24 +5429,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 226 0xe2 '.' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x3f, 0xe0, /* 001111111110 */ + 0x3f, 0xe0, /* 001111111110 */ + 0x30, 0x60, /* 001100000110 */ + 0x30, 0x60, /* 001100000110 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -5487,49 +5453,47 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 227 0xe3 '.' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - - /* 228 0xe4 '.' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + + /* 228 0xe4 '.' */ 0x00, 0x00, /* 000000000000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x60, 0x60, /* 011000000110 */ + 0x30, 0x60, /* 001100000110 */ + 0x30, 0x00, /* 001100000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x60, /* 001100000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -5537,24 +5501,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 229 0xe5 '.' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ + 0x07, 0xe0, /* 000001111110 */ + 0x0f, 0xe0, /* 000011111110 */ + 0x13, 0x80, /* 000100111000 */ + 0x21, 0xc0, /* 001000011100 */ + 0x60, 0xc0, /* 011000001100 */ + 0x60, 0xc0, /* 011000001100 */ + 0x60, 0xc0, /* 011000001100 */ + 0x60, 0xc0, /* 011000001100 */ + 0x70, 0x80, /* 011100001000 */ + 0x39, 0x00, /* 001110010000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -5586,24 +5549,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 231 0xe7 '.' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ + 0x19, 0x80, /* 000110011000 */ 0x3f, 0xc0, /* 001111111100 */ + 0x66, 0x60, /* 011001100110 */ + 0x66, 0x60, /* 011001100110 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -5611,24 +5573,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 232 0xe8 '.' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x19, 0x80, /* 000110011000 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x19, 0x80, /* 000110011000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -5636,24 +5597,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 233 0xe9 '.' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x0f, 0x00, /* 000011110000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x30, 0xc0, /* 001100001100 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x30, 0xc0, /* 001100001100 */ + 0x1f, 0x80, /* 000111111000 */ + 0x0f, 0x00, /* 000011110000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -5661,24 +5621,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 234 0xea '.' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x1f, 0x00, /* 000111110000 */ + 0x31, 0x80, /* 001100011000 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x19, 0x80, /* 000110011000 */ + 0x19, 0x80, /* 000110011000 */ + 0xd9, 0xb0, /* 110110011011 */ + 0x79, 0xe0, /* 011110011110 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -5686,24 +5645,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 235 0xeb '.' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x07, 0x80, /* 000001111000 */ + 0x0c, 0xc0, /* 000011001100 */ + 0x18, 0x60, /* 000110000110 */ + 0x18, 0x00, /* 000110000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x03, 0x00, /* 000000110000 */ + 0x0f, 0x80, /* 000011111000 */ + 0x11, 0xc0, /* 000100011100 */ + 0x20, 0xe0, /* 001000001110 */ + 0x60, 0x60, /* 011000000110 */ + 0x60, 0x60, /* 011000000110 */ + 0x70, 0x40, /* 011100000100 */ + 0x38, 0x80, /* 001110001000 */ + 0x1f, 0x00, /* 000111110000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -5711,74 +5669,71 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 236 0xec '.' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x39, 0xc0, /* 001110011100 */ + 0x6f, 0x60, /* 011011110110 */ + 0x66, 0x60, /* 011001100110 */ + 0xc6, 0x30, /* 110001100011 */ + 0xc6, 0x30, /* 110001100011 */ + 0x66, 0x60, /* 011001100110 */ + 0x6f, 0x60, /* 011011110110 */ + 0x39, 0xc0, /* 001110011100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - - /* 237 0xed '.' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + + /* 237 0xed '.' */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x00, 0xc0, /* 000000001100 */ + 0x00, 0xc0, /* 000000001100 */ + 0x01, 0x80, /* 000000011000 */ + 0x01, 0x80, /* 000000011000 */ + 0x3b, 0xc0, /* 001110111100 */ + 0x6f, 0x60, /* 011011110110 */ + 0x66, 0x60, /* 011001100110 */ + 0xc6, 0x30, /* 110001100011 */ + 0xc6, 0x30, /* 110001100011 */ + 0x66, 0x60, /* 011001100110 */ + 0x6f, 0x60, /* 011011110110 */ + 0x3d, 0xc0, /* 001111011100 */ + 0x18, 0x00, /* 000110000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x30, 0x00, /* 001100000000 */ + 0x30, 0x00, /* 001100000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ /* 238 0xee '.' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x01, 0xc0, /* 000000011100 */ + 0x03, 0x00, /* 000000110000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x1f, 0xc0, /* 000111111100 */ + 0x18, 0x00, /* 000110000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x03, 0x00, /* 000000110000 */ + 0x01, 0xc0, /* 000000011100 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -5786,24 +5741,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 239 0xef '.' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ + 0x0f, 0x00, /* 000011110000 */ + 0x1f, 0x80, /* 000111111000 */ + 0x39, 0xc0, /* 001110011100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ + 0x30, 0xc0, /* 001100001100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -5811,24 +5765,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 240 0xf0 '.' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -5860,24 +5813,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 242 0xf2 '.' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x60, 0x00, /* 011000000000 */ + 0x38, 0x00, /* 001110000000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x03, 0x80, /* 000000111000 */ + 0x00, 0xe0, /* 000000001110 */ + 0x00, 0xe0, /* 000000001110 */ + 0x03, 0x80, /* 000000111000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x38, 0x00, /* 001110000000 */ + 0x60, 0x00, /* 011000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -5885,24 +5837,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 243 0xf3 '.' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x00, 0x60, /* 000000000110 */ + 0x01, 0xc0, /* 000000011100 */ + 0x07, 0x00, /* 000001110000 */ + 0x1c, 0x00, /* 000111000000 */ + 0x70, 0x00, /* 011100000000 */ + 0x70, 0x00, /* 011100000000 */ + 0x1c, 0x00, /* 000111000000 */ + 0x07, 0x00, /* 000001110000 */ + 0x01, 0xc0, /* 000000011100 */ + 0x00, 0x60, /* 000000000110 */ 0x00, 0x00, /* 000000000000 */ + 0x7f, 0xe0, /* 011111111110 */ + 0x7f, 0xe0, /* 011111111110 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -5910,54 +5861,52 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 244 0xf4 '.' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x03, 0x80, /* 000000111000 */ + 0x07, 0xc0, /* 000001111100 */ + 0x0c, 0x60, /* 000011000110 */ + 0x0c, 0x60, /* 000011000110 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ + 0x0c, 0x00, /* 000011000000 */ /* 245 0xf5 '.' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ - 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x1c, 0x00, /* 000111000000 */ + 0x3e, 0x00, /* 001111100000 */ + 0x63, 0x00, /* 011000110000 */ + 0x63, 0x00, /* 011000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ + 0x03, 0x00, /* 000000110000 */ /* 246 0xf6 '.' */ 0x00, 0x00, /* 000000000000 */ @@ -5984,24 +5933,23 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 247 0xf7 '.' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x38, 0x00, /* 001110000000 */ + 0x6c, 0x00, /* 011011000000 */ + 0x06, 0x30, /* 000001100011 */ + 0x03, 0x60, /* 000000110110 */ + 0x39, 0xc0, /* 001110011100 */ + 0x6c, 0x00, /* 011011000000 */ + 0x06, 0x30, /* 000001100011 */ + 0x03, 0x60, /* 000000110110 */ + 0x01, 0xc0, /* 000000011100 */ + 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -6033,44 +5981,31 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ /* 249 0xf9 '.' */ - /* FIXME */ - 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - - /* 250 0xfa '.' */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x1c, 0x00, /* 000111000000 */ + 0x3e, 0x00, /* 001111100000 */ + 0x3e, 0x00, /* 001111100000 */ + 0x3e, 0x00, /* 001111100000 */ + 0x1c, 0x00, /* 000111000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + + /* 250 0xfa '.' */ 0x00, 0x00, /* 000000000000 */ - 0x06, 0x00, /* 000001100000 */ - 0x0f, 0x00, /* 000011110000 */ - 0x0f, 0x00, /* 000011110000 */ - 0x06, 0x00, /* 000001100000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ @@ -6080,51 +6015,61 @@ static unsigned char fontdata_sun12x22[FONTDATAMAX] = { 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - - /* 251 0xfb '.' */ - /* FIXME */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + 0x18, 0x00, /* 000110000000 */ + 0x3c, 0x00, /* 001111000000 */ + 0x3c, 0x00, /* 001111000000 */ + 0x18, 0x00, /* 000110000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ + + /* 251 0xfb '.' */ 0x00, 0x00, /* 000000000000 */ + 0x07, 0xe0, /* 000001111110 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x06, 0x00, /* 000001100000 */ + 0xc6, 0x00, /* 110001100000 */ + 0x66, 0x00, /* 011001100000 */ + 0x36, 0x00, /* 001101100000 */ + 0x1e, 0x00, /* 000111100000 */ + 0x0e, 0x00, /* 000011100000 */ + 0x06, 0x00, /* 000001100000 */ + 0x02, 0x00, /* 000000100000 */ 0x00, 0x00, /* 000000000000 */ /* 252 0xfc '.' */ - /* FIXME */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x13, 0x80, /* 000100111000 */ + 0x3d, 0xc0, /* 001111011100 */ + 0x18, 0xc0, /* 000110001100 */ + 0x18, 0xc0, /* 000110001100 */ + 0x18, 0xc0, /* 000110001100 */ + 0x18, 0xc0, /* 000110001100 */ + 0x3d, 0xe0, /* 001111011110 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ + 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ - 0x3f, 0xc0, /* 001111111100 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */ diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c index 465d678230ae..e79b29702649 100644 --- a/drivers/video/console/fonts.c +++ b/drivers/video/console/fonts.c @@ -36,6 +36,10 @@ static struct font_desc *fonts[] = { #undef NO_FONTS &font_vga_6x11, #endif +#ifdef CONFIG_FONT_7x14 +#undef NO_FONTS + &font_7x14, +#endif #ifdef CONFIG_FONT_SUN8x16 #undef NO_FONTS &font_sun_8x16, @@ -44,6 +48,10 @@ static struct font_desc *fonts[] = { #undef NO_FONTS &font_sun_12x22, #endif +#ifdef CONFIG_FONT_10x18 +#undef NO_FONTS + &font_10x18, +#endif #ifdef CONFIG_FONT_ACORN_8x8 #undef NO_FONTS &font_acorn_8x8, diff --git a/include/linux/font.h b/include/linux/font.h index fc2d690c9d5f..8fc80a7d78ac 100644 --- a/include/linux/font.h +++ b/include/linux/font.h @@ -25,19 +25,23 @@ struct font_desc { #define VGA8x16_IDX 1 #define PEARL8x8_IDX 2 #define VGA6x11_IDX 3 -#define SUN8x16_IDX 4 -#define SUN12x22_IDX 5 -#define ACORN8x8_IDX 6 -#define MINI4x6_IDX 7 +#define FONT7x14_IDX 4 +#define FONT10x18_IDX 5 +#define SUN8x16_IDX 6 +#define SUN12x22_IDX 7 +#define ACORN8x8_IDX 8 +#define MINI4x6_IDX 9 extern struct font_desc font_vga_8x8, - font_vga_8x16, - font_pearl_8x8, - font_vga_6x11, - font_sun_8x16, - font_sun_12x22, - font_acorn_8x8, - font_mini_4x6; + font_vga_8x16, + font_pearl_8x8, + font_vga_6x11, + font_7x14, + font_10x18, + font_sun_8x16, + font_sun_12x22, + font_acorn_8x8, + font_mini_4x6; /* Find a font with a specific name */ -- cgit v1.2.3-59-g8ed1b From f1ab5dac251bb4514607918b0019a3b3f5f5fb48 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Tue, 21 Jun 2005 17:17:07 -0700 Subject: [PATCH] fbdev: stack reduction Shrink the stack when calling the drawing alignment functions. Signed-off-by: James Simmons Cc: "Antonino A. Daplas" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/console/bitblit.c | 9 ++++----- drivers/video/fbmem.c | 14 +++++--------- drivers/video/nvidia/nvidia.c | 17 +++++++---------- drivers/video/riva/fbdev.c | 18 +++++++----------- drivers/video/softcursor.c | 5 +---- include/linux/fb.h | 7 ++----- 6 files changed, 26 insertions(+), 44 deletions(-) diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c index 4eef20790c3e..3c731577fed6 100644 --- a/drivers/video/console/bitblit.c +++ b/drivers/video/console/bitblit.c @@ -157,9 +157,9 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, src = buf; } - fb_sysmove_buf_unaligned(info, &info->pixmap, dst, pitch, - src, idx, image.height, - shift_high, shift_low, mod); + fb_pad_unaligned_buffer(dst, pitch, src, idx, + image.height, shift_high, + shift_low, mod); shift_low += mod; dst += (shift_low >= 8) ? width : width - 1; shift_low &= 7; @@ -175,8 +175,7 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, src = buf; } - fb_sysmove_buf_aligned(info, &info->pixmap, dst, pitch, - src, idx, image.height); + fb_pad_aligned_buffer(dst, pitch, src, idx, image.height); dst += width; } } diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 78907a873493..6f871a8b9058 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -78,9 +78,7 @@ EXPORT_SYMBOL(fb_get_color_depth); /* * Data padding functions. */ -void fb_sysmove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf, - u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, - u32 height) +void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height) { int i; @@ -90,12 +88,10 @@ void fb_sysmove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf, dst += d_pitch; } } -EXPORT_SYMBOL(fb_sysmove_buf_aligned); +EXPORT_SYMBOL(fb_pad_aligned_buffer); -void fb_sysmove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf, - u8 *dst, u32 d_pitch, u8 *src, u32 idx, - u32 height, u32 shift_high, u32 shift_low, - u32 mod) +void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx, u32 height, + u32 shift_high, u32 shift_low, u32 mod) { u8 mask = (u8) (0xfff << shift_high), tmp; int i, j; @@ -122,7 +118,7 @@ void fb_sysmove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf, dst += d_pitch; } } -EXPORT_SYMBOL(fb_sysmove_buf_unaligned); +EXPORT_SYMBOL(fb_pad_unaligned_buffer); /* * we need to lock this section since fb_cursor diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index 47733f58153b..266ff5d7ac36 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c @@ -516,9 +516,9 @@ static struct backlight_controller nvidia_backlight_controller = { static void nvidiafb_load_cursor_image(struct nvidia_par *par, u8 * data8, u16 bg, u16 fg, u32 w, u32 h) { + u32 *data = (u32 *) data8; int i, j, k = 0; u32 b, tmp; - u32 *data = (u32 *) data8; w = (w + 1) & ~1; @@ -890,11 +890,11 @@ static int nvidiafb_cursor(struct fb_info *info, struct fb_cursor *cursor) { struct nvidia_par *par = info->par; u8 data[MAX_CURS * MAX_CURS / 8]; - u16 fg, bg; int i, set = cursor->set; + u16 fg, bg; if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS) - return soft_cursor(info, cursor); + return -ENXIO; NVShowHideCursor(par, 0); @@ -931,21 +931,18 @@ static int nvidiafb_cursor(struct fb_info *info, struct fb_cursor *cursor) if (src) { switch (cursor->rop) { case ROP_XOR: - for (i = 0; i < s_pitch * cursor->image.height; - i++) + for (i = 0; i < s_pitch * cursor->image.height; i++) src[i] = dat[i] ^ msk[i]; break; case ROP_COPY: default: - for (i = 0; i < s_pitch * cursor->image.height; - i++) + for (i = 0; i < s_pitch * cursor->image.height; i++) src[i] = dat[i] & msk[i]; break; } - fb_sysmove_buf_aligned(info, &info->pixmap, data, - d_pitch, src, s_pitch, - cursor->image.height); + fb_pad_aligned_buffer(data, d_pitch, src, s_pitch, + cursor->image.height); bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) | ((info->cmap.green[bg_idx] & 0xf8) << 2) | diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index b0c886de0404..7540f60af948 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c @@ -1582,12 +1582,11 @@ static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor) { struct riva_par *par = (struct riva_par *) info->par; u8 data[MAX_CURS * MAX_CURS/8]; - u16 fg, bg; int i, set = cursor->set; + u16 fg, bg; - if (cursor->image.width > MAX_CURS || - cursor->image.height > MAX_CURS) - return soft_cursor(info, cursor); + if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS) + return -ENXIO; par->riva.ShowHideCursor(&par->riva, 0); @@ -1625,21 +1624,18 @@ static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor) if (src) { switch (cursor->rop) { case ROP_XOR: - for (i = 0; i < s_pitch * cursor->image.height; - i++) + for (i = 0; i < s_pitch * cursor->image.height; i++) src[i] = dat[i] ^ msk[i]; break; case ROP_COPY: default: - for (i = 0; i < s_pitch * cursor->image.height; - i++) + for (i = 0; i < s_pitch * cursor->image.height; i++) src[i] = dat[i] & msk[i]; break; } - fb_sysmove_buf_aligned(info, &info->pixmap, data, - d_pitch, src, s_pitch, - cursor->image.height); + fb_pad_aligned_buffer(data, d_pitch, src, s_pitch, + cursor->image.height); bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) | ((info->cmap.green[bg_idx] & 0xf8) << 2) | diff --git a/drivers/video/softcursor.c b/drivers/video/softcursor.c index a6c5ca88d6b0..229c4bc35079 100644 --- a/drivers/video/softcursor.c +++ b/drivers/video/softcursor.c @@ -58,13 +58,10 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) } else memcpy(src, image->data, dsize); - fb_sysmove_buf_aligned(info, &info->pixmap, dst, d_pitch, src, - s_pitch, image->height); - + fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height); image->data = dst; info->fbops->fb_imageblit(info, image); kfree(src); - return 0; } diff --git a/include/linux/fb.h b/include/linux/fb.h index e14942805dbd..bc24beeed971 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -816,12 +816,9 @@ extern int unregister_framebuffer(struct fb_info *fb_info); extern int fb_prepare_logo(struct fb_info *fb_info); extern int fb_show_logo(struct fb_info *fb_info); extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size); -extern void fb_sysmove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf, - u8 *dst, u32 d_pitch, u8 *src, u32 idx, +extern void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx, u32 height, u32 shift_high, u32 shift_low, u32 mod); -extern void fb_sysmove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf, - u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, - u32 height); +extern void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height); extern void fb_set_suspend(struct fb_info *info, int state); extern int fb_get_color_depth(struct fb_var_screeninfo *var); extern int fb_get_options(char *name, char **option); -- cgit v1.2.3-59-g8ed1b From 58a606431a704b5c240c1429a5526fac81c9800a Mon Sep 17 00:00:00 2001 From: James Simmons Date: Tue, 21 Jun 2005 17:17:08 -0700 Subject: [PATCH] fbdev: fill in the access_align field. Several drivers miss filling in the access_align field. So this patch has them fill it in. Signed-off-by: James Simmons Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/fbmem.c | 2 +- drivers/video/i810/i810_main.c | 1 + drivers/video/intelfb/intelfbdrv.c | 1 + drivers/video/nvidia/nvidia.c | 1 + drivers/video/riva/fbdev.c | 1 + drivers/video/savage/savagefb_driver.c | 2 +- 6 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 6f871a8b9058..2222de6ad844 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1034,7 +1034,7 @@ register_framebuffer(struct fb_info *fb_info) fb_info->pixmap.size = FBPIXMAPSIZE; fb_info->pixmap.buf_align = 1; fb_info->pixmap.scan_align = 1; - fb_info->pixmap.access_align = 4; + fb_info->pixmap.access_align = 32; fb_info->pixmap.flags = FB_PIXMAP_DEFAULT; } } diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c index a9a618f2aa6a..7513fb9b19cf 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/i810/i810_main.c @@ -1885,6 +1885,7 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev, memset(info->pixmap.addr, 0, 8*1024); info->pixmap.size = 8*1024; info->pixmap.buf_align = 8; + info->pixmap.access_align = 32; info->pixmap.flags = FB_PIXMAP_SYSTEM; if ((err = i810_allocate_pci_resource(par, entry))) { diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 448c90864016..298bc9cd99e7 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c @@ -1091,6 +1091,7 @@ intelfb_set_fbinfo(struct intelfb_info *dinfo) info->pixmap.size = 64*1024; info->pixmap.buf_align = 8; + info->pixmap.access_align = 32; info->pixmap.flags = FB_PIXMAP_SYSTEM; if (intelfb_init_var(dinfo)) diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index 266ff5d7ac36..b2e6b2407869 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c @@ -1345,6 +1345,7 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info) info->pixmap.scan_align = 4; info->pixmap.buf_align = 4; + info->pixmap.access_align = 32; info->pixmap.size = 8 * 1024; info->pixmap.flags = FB_PIXMAP_SYSTEM; diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index 7540f60af948..6a9e183be41b 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c @@ -1723,6 +1723,7 @@ static int __devinit riva_set_fbinfo(struct fb_info *info) info->pixmap.size = 8 * 1024; info->pixmap.buf_align = 4; + info->pixmap.access_align = 32; info->pixmap.flags = FB_PIXMAP_SYSTEM; info->var.yres_virtual = -1; NVTRACE_LEAVE(); diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c index 03d74e8ee067..8fadcdae6f42 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/savage/savagefb_driver.c @@ -1897,7 +1897,7 @@ static int __devinit savage_init_fb_info (struct fb_info *info, info->pixmap.size = 8*1024; info->pixmap.scan_align = 4; info->pixmap.buf_align = 4; - info->pixmap.access_align = 4; + info->pixmap.access_align = 32; fb_alloc_cmap (&info->cmap, NR_PALETTE, 0); info->flags |= FBINFO_HWACCEL_COPYAREA | -- cgit v1.2.3-59-g8ed1b From 6ea9c07c6c6d1c14d9757dd8470dc4c85bbe9f28 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:09 -0700 Subject: [PATCH] md: cause md/raid1 to "repack" working devices when number of drives is changed i.e. missing or failed drives are moved to the end of the list. The means a 3 drive md array with the first drive missing can be shrunk to a two drive array. Currently that isn't possible. Also, the "last_used" device number might be out-of-range after the number of devices is reduced, so we set it to 0. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/raid1.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 1db5de52d376..4947f599b652 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1349,17 +1349,26 @@ static int raid1_reshape(mddev_t *mddev, int raid_disks) * We allocate a new r1bio_pool if we can. * Then raise a device barrier and wait until all IO stops. * Then resize conf->mirrors and swap in the new r1bio pool. + * + * At the same time, we "pack" the devices so that all the missing + * devices have the higher raid_disk numbers. */ mempool_t *newpool, *oldpool; struct pool_info *newpoolinfo; mirror_info_t *newmirrors; conf_t *conf = mddev_to_conf(mddev); + int cnt; - int d; + int d, d2; - for (d= raid_disks; d < conf->raid_disks; d++) - if (conf->mirrors[d].rdev) + if (raid_disks < conf->raid_disks) { + cnt=0; + for (d= 0; d < conf->raid_disks; d++) + if (conf->mirrors[d].rdev) + cnt++; + if (cnt > raid_disks) return -EBUSY; + } newpoolinfo = kmalloc(sizeof(*newpoolinfo), GFP_KERNEL); if (!newpoolinfo) @@ -1390,8 +1399,12 @@ static int raid1_reshape(mddev_t *mddev, int raid_disks) /* ok, everything is stopped */ oldpool = conf->r1bio_pool; conf->r1bio_pool = newpool; - for (d=0; d < raid_disks && d < conf->raid_disks; d++) - newmirrors[d] = conf->mirrors[d]; + + for (d=d2=0; d < conf->raid_disks; d++) + if (conf->mirrors[d].rdev) { + conf->mirrors[d].rdev->raid_disk = d2; + newmirrors[d2++].rdev = conf->mirrors[d].rdev; + } kfree(conf->mirrors); conf->mirrors = newmirrors; kfree(conf->poolinfo); @@ -1400,6 +1413,7 @@ static int raid1_reshape(mddev_t *mddev, int raid_disks) mddev->degraded += (raid_disks - conf->raid_disks); conf->raid_disks = mddev->raid_disks = raid_disks; + conf->last_used = 0; /* just make sure it is in-range */ spin_lock_irq(&conf->resync_lock); conf->barrier--; spin_unlock_irq(&conf->resync_lock); -- cgit v1.2.3-59-g8ed1b From c361777fb9347a4d16b82272f7d3b234e94bef2d Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:10 -0700 Subject: [PATCH] md: make sure recovery happens when add_new_disk is used for hot_add Currently if add_new_disk is used to hot-add a drive to a degraded array, recovery doesn't start ... because we didn't tell it to. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/md/md.c b/drivers/md/md.c index d899204d3743..60835dfd058e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2083,6 +2083,8 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) err = bind_rdev_to_array(rdev, mddev); if (err) export_rdev(rdev); + + set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); if (mddev->thread) md_wakeup_thread(mddev->thread); return err; -- cgit v1.2.3-59-g8ed1b From fca4d848f0e6fafdc2b25f8a0cf1e76935f13ac2 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:11 -0700 Subject: [PATCH] md: merge md_enter_safemode into md_check_recovery md_enter_safemode checks if it is time to mark the md superblock as 'clean'. i.e. if all writes have completed and a suitable delay has passed. This is currently called from md_handle_safemode which in-turn is called (almost) every time md_check_recovery is called, and from the end of md_do_sync which causes the mddev->thread to run, which will always call md_check_recovery as well. So it doesn't need to be a separate function and fits quite well into md_check_recovery. The "almost" is because multipathd calls md_check_recovery but not md_handle_safemode. This is OK because the code from md_enter_safemode is a no-op if mddev->safemode == 0, which it always is for a multipathd (providing we don't allow it to be set to 2 on a signal...) Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 58 +++++++++++++++++++++----------------------------- drivers/md/raid1.c | 1 - drivers/md/raid10.c | 1 - drivers/md/raid5.c | 1 - drivers/md/raid6main.c | 1 - 5 files changed, 24 insertions(+), 38 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 60835dfd058e..c842e34d850e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3203,37 +3203,6 @@ void md_write_end(mddev_t *mddev) } } -static inline void md_enter_safemode(mddev_t *mddev) -{ - if (!mddev->safemode) return; - if (mddev->safemode == 2 && - (atomic_read(&mddev->writes_pending) || mddev->in_sync || - mddev->recovery_cp != MaxSector)) - return; /* avoid the lock */ - mddev_lock_uninterruptible(mddev); - if (mddev->safemode && !atomic_read(&mddev->writes_pending) && - !mddev->in_sync && mddev->recovery_cp == MaxSector) { - mddev->in_sync = 1; - md_update_sb(mddev); - } - mddev_unlock(mddev); - - if (mddev->safemode == 1) - mddev->safemode = 0; -} - -void md_handle_safemode(mddev_t *mddev) -{ - if (signal_pending(current)) { - printk(KERN_INFO "md: %s in immediate safe mode\n", - mdname(mddev)); - mddev->safemode = 2; - flush_signals(current); - } - md_enter_safemode(mddev); -} - - static DECLARE_WAIT_QUEUE_HEAD(resync_wait); #define SYNC_MARKS 10 @@ -3449,7 +3418,6 @@ static void md_do_sync(mddev_t *mddev) mddev->recovery_cp = MaxSector; } - md_enter_safemode(mddev); skip: mddev->curr_resync = 0; wake_up(&resync_wait); @@ -3490,14 +3458,37 @@ void md_check_recovery(mddev_t *mddev) if (mddev->ro) return; + + if (signal_pending(current)) { + if (mddev->pers->sync_request) { + printk(KERN_INFO "md: %s in immediate safe mode\n", + mdname(mddev)); + mddev->safemode = 2; + } + flush_signals(current); + } + if ( ! ( mddev->sb_dirty || test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || - test_bit(MD_RECOVERY_DONE, &mddev->recovery) + test_bit(MD_RECOVERY_DONE, &mddev->recovery) || + (mddev->safemode == 1) || + (mddev->safemode == 2 && ! atomic_read(&mddev->writes_pending) + && !mddev->in_sync && mddev->recovery_cp == MaxSector) )) return; + if (mddev_trylock(mddev)==0) { int spares =0; + + if (mddev->safemode && !atomic_read(&mddev->writes_pending) && + !mddev->in_sync && mddev->recovery_cp == MaxSector) { + mddev->in_sync = 1; + mddev->sb_dirty = 1; + } + if (mddev->safemode == 1) + mddev->safemode = 0; + if (mddev->sb_dirty) md_update_sb(mddev); if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && @@ -3741,7 +3732,6 @@ EXPORT_SYMBOL(md_error); EXPORT_SYMBOL(md_done_sync); EXPORT_SYMBOL(md_write_start); EXPORT_SYMBOL(md_write_end); -EXPORT_SYMBOL(md_handle_safemode); EXPORT_SYMBOL(md_register_thread); EXPORT_SYMBOL(md_unregister_thread); EXPORT_SYMBOL(md_wakeup_thread); diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 4947f599b652..b34ad56362df 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -931,7 +931,6 @@ static void raid1d(mddev_t *mddev) mdk_rdev_t *rdev; md_check_recovery(mddev); - md_handle_safemode(mddev); for (;;) { char b[BDEVNAME_SIZE]; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 3c37be6423d7..9ae21504db8a 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1216,7 +1216,6 @@ static void raid10d(mddev_t *mddev) mdk_rdev_t *rdev; md_check_recovery(mddev); - md_handle_safemode(mddev); for (;;) { char b[BDEVNAME_SIZE]; diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 3cb11ac232fa..63b1c59d36ff 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -1546,7 +1546,6 @@ static void raid5d (mddev_t *mddev) PRINTK("+++ raid5d active\n"); md_check_recovery(mddev); - md_handle_safemode(mddev); handled = 0; spin_lock_irq(&conf->device_lock); diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c index 908edd78a792..9d0e0e42a3be 100644 --- a/drivers/md/raid6main.c +++ b/drivers/md/raid6main.c @@ -1705,7 +1705,6 @@ static void raid6d (mddev_t *mddev) PRINTK("+++ raid6d active\n"); md_check_recovery(mddev); - md_handle_safemode(mddev); handled = 0; spin_lock_irq(&conf->device_lock); -- cgit v1.2.3-59-g8ed1b From 06d91a5fe0b50c9060e70bdf7786f8a3c66249db Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:12 -0700 Subject: [PATCH] md: improve locking on 'safemode' and move superblock writes When md marks the superblock dirty before a write, it calls generic_make_request (to write the superblock) from within generic_make_request (to write the first dirty block), which could cause problems later. With this patch, the superblock write is always done by the helper thread, and write request are delayed until that write completes. Also, the locking around marking the array dirty and writing the superblock is improved to avoid possible races. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 73 ++++++++++++++++++++++++++++++++++++++--------- drivers/md/raid1.c | 4 ++- drivers/md/raid10.c | 5 +++- drivers/md/raid5.c | 6 ++-- drivers/md/raid6main.c | 6 ++-- include/linux/raid/md.h | 2 +- include/linux/raid/md_k.h | 7 +++++ 7 files changed, 82 insertions(+), 21 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index c842e34d850e..177d2a7d7cea 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -218,6 +218,8 @@ static mddev_t * mddev_find(dev_t unit) INIT_LIST_HEAD(&new->all_mddevs); init_timer(&new->safemode_timer); atomic_set(&new->active, 1); + bio_list_init(&new->write_list); + spin_lock_init(&new->write_lock); new->queue = blk_alloc_queue(GFP_KERNEL); if (!new->queue) { @@ -1251,9 +1253,11 @@ static void md_update_sb(mddev_t * mddev) int err, count = 100; struct list_head *tmp; mdk_rdev_t *rdev; + int sync_req; - mddev->sb_dirty = 0; repeat: + spin_lock(&mddev->write_lock); + sync_req = mddev->in_sync; mddev->utime = get_seconds(); mddev->events ++; @@ -1272,8 +1276,12 @@ repeat: * do not write anything to disk if using * nonpersistent superblocks */ - if (!mddev->persistent) + if (!mddev->persistent) { + mddev->sb_dirty = 0; + spin_unlock(&mddev->write_lock); return; + } + spin_unlock(&mddev->write_lock); dprintk(KERN_INFO "md: updating %s RAID superblock on device (in sync %d)\n", @@ -1304,6 +1312,15 @@ repeat: printk(KERN_ERR \ "md: excessive errors occurred during superblock update, exiting\n"); } + spin_lock(&mddev->write_lock); + if (mddev->in_sync != sync_req) { + /* have to write it out again */ + spin_unlock(&mddev->write_lock); + goto repeat; + } + mddev->sb_dirty = 0; + spin_unlock(&mddev->write_lock); + } /* @@ -3178,19 +3195,31 @@ void md_done_sync(mddev_t *mddev, int blocks, int ok) } -void md_write_start(mddev_t *mddev) +/* md_write_start(mddev, bi) + * If we need to update some array metadata (e.g. 'active' flag + * in superblock) before writing, queue bi for later writing + * and return 0, else return 1 and it will be written now + */ +int md_write_start(mddev_t *mddev, struct bio *bi) { - if (!atomic_read(&mddev->writes_pending)) { - mddev_lock_uninterruptible(mddev); - if (mddev->in_sync) { - mddev->in_sync = 0; - del_timer(&mddev->safemode_timer); - md_update_sb(mddev); - } - atomic_inc(&mddev->writes_pending); - mddev_unlock(mddev); - } else - atomic_inc(&mddev->writes_pending); + if (bio_data_dir(bi) != WRITE) + return 1; + + atomic_inc(&mddev->writes_pending); + spin_lock(&mddev->write_lock); + if (mddev->in_sync == 0 && mddev->sb_dirty == 0) { + spin_unlock(&mddev->write_lock); + return 1; + } + bio_list_add(&mddev->write_list, bi); + + if (mddev->in_sync) { + mddev->in_sync = 0; + mddev->sb_dirty = 1; + } + spin_unlock(&mddev->write_lock); + md_wakeup_thread(mddev->thread); + return 0; } void md_write_end(mddev_t *mddev) @@ -3472,6 +3501,7 @@ void md_check_recovery(mddev_t *mddev) mddev->sb_dirty || test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || test_bit(MD_RECOVERY_DONE, &mddev->recovery) || + mddev->write_list.head || (mddev->safemode == 1) || (mddev->safemode == 2 && ! atomic_read(&mddev->writes_pending) && !mddev->in_sync && mddev->recovery_cp == MaxSector) @@ -3480,7 +3510,9 @@ void md_check_recovery(mddev_t *mddev) if (mddev_trylock(mddev)==0) { int spares =0; + struct bio *blist; + spin_lock(&mddev->write_lock); if (mddev->safemode && !atomic_read(&mddev->writes_pending) && !mddev->in_sync && mddev->recovery_cp == MaxSector) { mddev->in_sync = 1; @@ -3488,9 +3520,22 @@ void md_check_recovery(mddev_t *mddev) } if (mddev->safemode == 1) mddev->safemode = 0; + blist = bio_list_get(&mddev->write_list); + spin_unlock(&mddev->write_lock); if (mddev->sb_dirty) md_update_sb(mddev); + + while (blist) { + struct bio *b = blist; + blist = blist->bi_next; + b->bi_next = NULL; + generic_make_request(b); + /* we already counted this, so need to un-count */ + md_write_end(mddev); + } + + if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && !test_bit(MD_RECOVERY_DONE, &mddev->recovery)) { /* resync/recovery still happening */ diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index b34ad56362df..3f1280bbaf39 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -530,6 +530,8 @@ static int make_request(request_queue_t *q, struct bio * bio) * thread has put up a bar for new requests. * Continue immediately if no resync is active currently. */ + if (md_write_start(mddev, bio)==0) + return 0; spin_lock_irq(&conf->resync_lock); wait_event_lock_irq(conf->wait_resume, !conf->barrier, conf->resync_lock, ); conf->nr_pending++; @@ -611,7 +613,7 @@ static int make_request(request_queue_t *q, struct bio * bio) rcu_read_unlock(); atomic_set(&r1_bio->remaining, 1); - md_write_start(mddev); + for (i = 0; i < disks; i++) { struct bio *mbio; if (!r1_bio->bios[i]) diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 9ae21504db8a..bfc9f52f0ecf 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -700,6 +700,9 @@ static int make_request(request_queue_t *q, struct bio * bio) return 0; } + if (md_write_start(mddev, bio) == 0) + return 0; + /* * Register the new request and wait if the reconstruction * thread has put up a bar for new requests. @@ -774,7 +777,7 @@ static int make_request(request_queue_t *q, struct bio * bio) rcu_read_unlock(); atomic_set(&r10_bio->remaining, 1); - md_write_start(mddev); + for (i = 0; i < conf->copies; i++) { struct bio *mbio; int d = r10_bio->devs[i].devnum; diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 63b1c59d36ff..677ce49078da 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -1411,6 +1411,9 @@ static int make_request (request_queue_t *q, struct bio * bi) sector_t logical_sector, last_sector; struct stripe_head *sh; + if (md_write_start(mddev, bi)==0) + return 0; + if (bio_data_dir(bi)==WRITE) { disk_stat_inc(mddev->gendisk, writes); disk_stat_add(mddev->gendisk, write_sectors, bio_sectors(bi)); @@ -1423,8 +1426,7 @@ static int make_request (request_queue_t *q, struct bio * bi) last_sector = bi->bi_sector + (bi->bi_size>>9); bi->bi_next = NULL; bi->bi_phys_segments = 1; /* over-loaded to count active stripes */ - if ( bio_data_dir(bi) == WRITE ) - md_write_start(mddev); + for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) { DEFINE_WAIT(w); diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c index 9d0e0e42a3be..fede16c4e8f3 100644 --- a/drivers/md/raid6main.c +++ b/drivers/md/raid6main.c @@ -1570,6 +1570,9 @@ static int make_request (request_queue_t *q, struct bio * bi) sector_t logical_sector, last_sector; struct stripe_head *sh; + if (md_write_start(mddev, bi)==0) + return 0; + if (bio_data_dir(bi)==WRITE) { disk_stat_inc(mddev->gendisk, writes); disk_stat_add(mddev->gendisk, write_sectors, bio_sectors(bi)); @@ -1583,8 +1586,7 @@ static int make_request (request_queue_t *q, struct bio * bi) bi->bi_next = NULL; bi->bi_phys_segments = 1; /* over-loaded to count active stripes */ - if ( bio_data_dir(bi) == WRITE ) - md_write_start(mddev); + for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) { DEFINE_WAIT(w); diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h index a6a67d102bfa..cfde8f497d6d 100644 --- a/include/linux/raid/md.h +++ b/include/linux/raid/md.h @@ -69,7 +69,7 @@ extern mdk_thread_t * md_register_thread (void (*run) (mddev_t *mddev), extern void md_unregister_thread (mdk_thread_t *thread); extern void md_wakeup_thread(mdk_thread_t *thread); extern void md_check_recovery(mddev_t *mddev); -extern void md_write_start(mddev_t *mddev); +extern int md_write_start(mddev_t *mddev, struct bio *bi); extern void md_write_end(mddev_t *mddev); extern void md_handle_safemode(mddev_t *mddev); extern void md_done_sync(mddev_t *mddev, int blocks, int ok); diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index c9a0d4013be7..d92db54255a3 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h @@ -15,6 +15,9 @@ #ifndef _MD_K_H #define _MD_K_H +/* and dm-bio-list.h is not under include/linux because.... ??? */ +#include "../../../drivers/md/dm-bio-list.h" + #define MD_RESERVED 0UL #define LINEAR 1UL #define RAID0 2UL @@ -252,6 +255,10 @@ struct mddev_s atomic_t recovery_active; /* blocks scheduled, but not written */ wait_queue_head_t recovery_wait; sector_t recovery_cp; + + spinlock_t write_lock; + struct bio_list write_list; + unsigned int safemode; /* if set, update "clean" superblock * when no writes pending. */ -- cgit v1.2.3-59-g8ed1b From 57afd89f98a990747445f01c458ecae64263b2f8 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:13 -0700 Subject: [PATCH] md: improve the interface to sync_request 1/ change the return value (which is number-of-sectors synced) from 'int' to 'sector_t'. The number of sectors is usually easily small enough to fit in an int, but if resync needs to abort, it may want to return the total number of remaining sectors, which could be large. Also errors cannot be returned as negative numbers now, so use 0 instead 2/ Add a 'skipped' return parameter to allow the array to report that it skipped the sectors. This allows md to take this into account in the speed calculations. Currently there is no important skipping, but the bitmap-based-resync that is coming will use this. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 35 +++++++++++++++++++++++------------ drivers/md/raid1.c | 8 ++++---- drivers/md/raid10.c | 19 ++++++++++++------- drivers/md/raid5.c | 6 +++--- drivers/md/raid6main.c | 6 +++--- include/linux/raid/md_k.h | 2 +- 6 files changed, 46 insertions(+), 30 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 177d2a7d7cea..fa608a1a5c20 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3241,12 +3241,13 @@ static void md_do_sync(mddev_t *mddev) mddev_t *mddev2; unsigned int currspeed = 0, window; - sector_t max_sectors,j; + sector_t max_sectors,j, io_sectors; unsigned long mark[SYNC_MARKS]; sector_t mark_cnt[SYNC_MARKS]; int last_mark,m; struct list_head *tmp; sector_t last_check; + int skipped = 0; /* just incase thread restarts... */ if (test_bit(MD_RECOVERY_DONE, &mddev->recovery)) @@ -3312,7 +3313,7 @@ static void md_do_sync(mddev_t *mddev) if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) /* resync follows the size requested by the personality, - * which default to physical size, but can be virtual size + * which defaults to physical size, but can be virtual size */ max_sectors = mddev->resync_max_sectors; else @@ -3331,9 +3332,10 @@ static void md_do_sync(mddev_t *mddev) j = mddev->recovery_cp; else j = 0; + io_sectors = 0; for (m = 0; m < SYNC_MARKS; m++) { mark[m] = jiffies; - mark_cnt[m] = j; + mark_cnt[m] = io_sectors; } last_mark = 0; mddev->resync_mark = mark[last_mark]; @@ -3358,21 +3360,29 @@ static void md_do_sync(mddev_t *mddev) } while (j < max_sectors) { - int sectors; + sector_t sectors; - sectors = mddev->pers->sync_request(mddev, j, currspeed < sysctl_speed_limit_min); - if (sectors < 0) { + skipped = 0; + sectors = mddev->pers->sync_request(mddev, j, &skipped, + currspeed < sysctl_speed_limit_min); + if (sectors == 0) { set_bit(MD_RECOVERY_ERR, &mddev->recovery); goto out; } - atomic_add(sectors, &mddev->recovery_active); + + if (!skipped) { /* actual IO requested */ + io_sectors += sectors; + atomic_add(sectors, &mddev->recovery_active); + } + j += sectors; if (j>1) mddev->curr_resync = j; - if (last_check + window > j || j == max_sectors) + + if (last_check + window > io_sectors || j == max_sectors) continue; - last_check = j; + last_check = io_sectors; if (test_bit(MD_RECOVERY_INTR, &mddev->recovery) || test_bit(MD_RECOVERY_ERR, &mddev->recovery)) @@ -3386,7 +3396,7 @@ static void md_do_sync(mddev_t *mddev) mddev->resync_mark = mark[next]; mddev->resync_mark_cnt = mark_cnt[next]; mark[next] = jiffies; - mark_cnt[next] = j - atomic_read(&mddev->recovery_active); + mark_cnt[next] = io_sectors - atomic_read(&mddev->recovery_active); last_mark = next; } @@ -3413,7 +3423,8 @@ static void md_do_sync(mddev_t *mddev) mddev->queue->unplug_fn(mddev->queue); cond_resched(); - currspeed = ((unsigned long)(j-mddev->resync_mark_cnt))/2/((jiffies-mddev->resync_mark)/HZ +1) +1; + currspeed = ((unsigned long)(io_sectors-mddev->resync_mark_cnt))/2 + /((jiffies-mddev->resync_mark)/HZ +1) +1; if (currspeed > sysctl_speed_limit_min) { if ((currspeed > sysctl_speed_limit_max) || @@ -3433,7 +3444,7 @@ static void md_do_sync(mddev_t *mddev) wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active)); /* tell personality that we are finished */ - mddev->pers->sync_request(mddev, max_sectors, 1); + mddev->pers->sync_request(mddev, max_sectors, &skipped, 1); if (!test_bit(MD_RECOVERY_ERR, &mddev->recovery) && mddev->curr_resync > 2 && diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 3f1280bbaf39..3c5c916cb09e 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1010,7 +1010,7 @@ static int init_resync(conf_t *conf) * that can be installed to exclude normal IO requests. */ -static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster) +static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster) { conf_t *conf = mddev_to_conf(mddev); mirror_info_t *mirror; @@ -1023,7 +1023,7 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster) if (!conf->r1buf_pool) if (init_resync(conf)) - return -ENOMEM; + return 0; max_sector = mddev->size << 1; if (sector_nr >= max_sector) { @@ -1107,8 +1107,8 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster) /* There is nowhere to write, so all non-sync * drives must be failed - so we are finished */ - int rv = max_sector - sector_nr; - md_done_sync(mddev, rv, 1); + sector_t rv = max_sector - sector_nr; + *skipped = 1; put_buf(r1_bio); rdev_dec_pending(conf->mirrors[disk].rdev, mddev); return rv; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index bfc9f52f0ecf..8476515bfdc7 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1321,7 +1321,7 @@ static int init_resync(conf_t *conf) * */ -static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster) +static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster) { conf_t *conf = mddev_to_conf(mddev); r10bio_t *r10_bio; @@ -1335,7 +1335,7 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster) if (!conf->r10buf_pool) if (init_resync(conf)) - return -ENOMEM; + return 0; skipped: max_sector = mddev->size << 1; @@ -1343,15 +1343,15 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster) max_sector = mddev->resync_max_sectors; if (sector_nr >= max_sector) { close_sync(conf); + *skipped = 1; return sectors_skipped; } if (chunks_skipped >= conf->raid_disks) { /* if there has been nothing to do on any drive, * then there is nothing to do at all.. */ - sector_t sec = max_sector - sector_nr; - md_done_sync(mddev, sec, 1); - return sec + sectors_skipped; + *skipped = 1; + return (max_sector - sector_nr) + sectors_skipped; } /* make sure whole request will fit in a chunk - if chunks @@ -1565,17 +1565,22 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster) } } + if (sectors_skipped) + /* pretend they weren't skipped, it makes + * no important difference in this case + */ + md_done_sync(mddev, sectors_skipped, 1); + return sectors_skipped + nr_sectors; giveup: /* There is nowhere to write, so all non-sync * drives must be failed, so try the next chunk... */ { - int sec = max_sector - sector_nr; + sector_t sec = max_sector - sector_nr; sectors_skipped += sec; chunks_skipped ++; sector_nr = max_sector; - md_done_sync(mddev, sec, 1); goto skipped; } } diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 677ce49078da..1ce3f5aaa984 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -1477,7 +1477,7 @@ static int make_request (request_queue_t *q, struct bio * bi) } /* FIXME go_faster isn't used */ -static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster) +static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster) { raid5_conf_t *conf = (raid5_conf_t *) mddev->private; struct stripe_head *sh; @@ -1500,8 +1500,8 @@ static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster) * nothing we can do. */ if (mddev->degraded >= 1 && test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { - int rv = (mddev->size << 1) - sector_nr; - md_done_sync(mddev, rv, 1); + sector_t rv = (mddev->size << 1) - sector_nr; + *skipped = 1; return rv; } diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c index fede16c4e8f3..d9c385496dc5 100644 --- a/drivers/md/raid6main.c +++ b/drivers/md/raid6main.c @@ -1636,7 +1636,7 @@ static int make_request (request_queue_t *q, struct bio * bi) } /* FIXME go_faster isn't used */ -static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster) +static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster) { raid6_conf_t *conf = (raid6_conf_t *) mddev->private; struct stripe_head *sh; @@ -1659,8 +1659,8 @@ static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster) * nothing we can do. */ if (mddev->degraded >= 2 && test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { - int rv = (mddev->size << 1) - sector_nr; - md_done_sync(mddev, rv, 1); + sector_t rv = (mddev->size << 1) - sector_nr; + *skipped = 1; return rv; } diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index d92db54255a3..bce0032decff 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h @@ -298,7 +298,7 @@ struct mdk_personality_s int (*hot_add_disk) (mddev_t *mddev, mdk_rdev_t *rdev); int (*hot_remove_disk) (mddev_t *mddev, int number); int (*spare_active) (mddev_t *mddev); - int (*sync_request)(mddev_t *mddev, sector_t sector_nr, int go_faster); + sector_t (*sync_request)(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster); int (*resize) (mddev_t *mddev, sector_t sectors); int (*reshape) (mddev_t *mddev, int raid_disks); int (*reconfig) (mddev_t *mddev, int layout, int chunk_size); -- cgit v1.2.3-59-g8ed1b From 32a7627cf3a35396a8e834faf34e38ae9f3b1309 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:14 -0700 Subject: [PATCH] md: optimised resync using Bitmap based intent logging With this patch, the intent to write to some block in the array can be logged to a bitmap file. Each bit represents some number of sectors and is set before any update happens, and only cleared when all writes relating to all sectors are complete. After an unclean shutdown, information in this bitmap can be used to optimise resync - only sectors which could be out-of-sync need to be updated. Also if a drive is removed and then added back into an array, the recovery can make use of the bitmap to optimise reconstruction. This is not implemented in this patch. Currently the bitmap is stored in a file which must (obviously) be stored on a separate device. The patch only provided infrastructure. It does not update any personalities to bitmap intent logging. Md arrays can still be used with no bitmap file. This patch has minimal impact on such arrays. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/Makefile | 3 +- drivers/md/bitmap.c | 1519 +++++++++++++++++++++++++++++++++++++++++++ drivers/md/md.c | 172 ++++- include/linux/raid/bitmap.h | 280 ++++++++ include/linux/raid/md_k.h | 4 + include/linux/raid/md_u.h | 7 + 6 files changed, 1970 insertions(+), 15 deletions(-) create mode 100644 drivers/md/bitmap.c create mode 100644 include/linux/raid/bitmap.h diff --git a/drivers/md/Makefile b/drivers/md/Makefile index 90de9c146a5f..d3efedf6a6ad 100644 --- a/drivers/md/Makefile +++ b/drivers/md/Makefile @@ -7,6 +7,7 @@ dm-mod-objs := dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \ dm-multipath-objs := dm-hw-handler.o dm-path-selector.o dm-mpath.o dm-snapshot-objs := dm-snap.o dm-exception-store.o dm-mirror-objs := dm-log.o dm-raid1.o +md-mod-objs := md.o bitmap.o raid6-objs := raid6main.o raid6algos.o raid6recov.o raid6tables.o \ raid6int1.o raid6int2.o raid6int4.o \ raid6int8.o raid6int16.o raid6int32.o \ @@ -28,7 +29,7 @@ obj-$(CONFIG_MD_RAID5) += raid5.o xor.o obj-$(CONFIG_MD_RAID6) += raid6.o xor.o obj-$(CONFIG_MD_MULTIPATH) += multipath.o obj-$(CONFIG_MD_FAULTY) += faulty.o -obj-$(CONFIG_BLK_DEV_MD) += md.o +obj-$(CONFIG_BLK_DEV_MD) += md-mod.o obj-$(CONFIG_BLK_DEV_DM) += dm-mod.o obj-$(CONFIG_DM_CRYPT) += dm-crypt.o obj-$(CONFIG_DM_MULTIPATH) += dm-multipath.o dm-round-robin.o diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c new file mode 100644 index 000000000000..34ffc133db05 --- /dev/null +++ b/drivers/md/bitmap.c @@ -0,0 +1,1519 @@ +/* + * bitmap.c two-level bitmap (C) Peter T. Breuer (ptb@ot.uc3m.es) 2003 + * + * bitmap_create - sets up the bitmap structure + * bitmap_destroy - destroys the bitmap structure + * + * additions, Copyright (C) 2003-2004, Paul Clements, SteelEye Technology, Inc.: + * - added disk storage for bitmap + * - changes to allow various bitmap chunk sizes + * - added bitmap daemon (to asynchronously clear bitmap bits from disk) + */ + +/* + * Still to do: + * + * flush after percent set rather than just time based. (maybe both). + * wait if count gets too high, wake when it drops to half. + * allow bitmap to be mirrored with superblock (before or after...) + * allow hot-add to re-instate a current device. + * allow hot-add of bitmap after quiessing device + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* debug macros */ + +#define DEBUG 0 + +#if DEBUG +/* these are for debugging purposes only! */ + +/* define one and only one of these */ +#define INJECT_FAULTS_1 0 /* cause bitmap_alloc_page to fail always */ +#define INJECT_FAULTS_2 0 /* cause bitmap file to be kicked when first bit set*/ +#define INJECT_FAULTS_3 0 /* treat bitmap file as kicked at init time */ +#define INJECT_FAULTS_4 0 /* undef */ +#define INJECT_FAULTS_5 0 /* undef */ +#define INJECT_FAULTS_6 0 + +/* if these are defined, the driver will fail! debug only */ +#define INJECT_FATAL_FAULT_1 0 /* fail kmalloc, causing bitmap_create to fail */ +#define INJECT_FATAL_FAULT_2 0 /* undef */ +#define INJECT_FATAL_FAULT_3 0 /* undef */ +#endif + +//#define DPRINTK PRINTK /* set this NULL to avoid verbose debug output */ +#define DPRINTK(x...) do { } while(0) + +#ifndef PRINTK +# if DEBUG > 0 +# define PRINTK(x...) printk(KERN_DEBUG x) +# else +# define PRINTK(x...) +# endif +#endif + +static inline char * bmname(struct bitmap *bitmap) +{ + return bitmap->mddev ? mdname(bitmap->mddev) : "mdX"; +} + + +/* + * test if the bitmap is active + */ +int bitmap_active(struct bitmap *bitmap) +{ + unsigned long flags; + int res = 0; + + if (!bitmap) + return res; + spin_lock_irqsave(&bitmap->lock, flags); + res = bitmap->flags & BITMAP_ACTIVE; + spin_unlock_irqrestore(&bitmap->lock, flags); + return res; +} + +#define WRITE_POOL_SIZE 256 +/* mempool for queueing pending writes on the bitmap file */ +static void *write_pool_alloc(unsigned int gfp_flags, void *data) +{ + return kmalloc(sizeof(struct page_list), gfp_flags); +} + +static void write_pool_free(void *ptr, void *data) +{ + kfree(ptr); +} + +/* + * just a placeholder - calls kmalloc for bitmap pages + */ +static unsigned char *bitmap_alloc_page(struct bitmap *bitmap) +{ + unsigned char *page; + +#if INJECT_FAULTS_1 + page = NULL; +#else + page = kmalloc(PAGE_SIZE, GFP_NOIO); +#endif + if (!page) + printk("%s: bitmap_alloc_page FAILED\n", bmname(bitmap)); + else + printk("%s: bitmap_alloc_page: allocated page at %p\n", + bmname(bitmap), page); + return page; +} + +/* + * for now just a placeholder -- just calls kfree for bitmap pages + */ +static void bitmap_free_page(struct bitmap *bitmap, unsigned char *page) +{ + PRINTK("%s: bitmap_free_page: free page %p\n", bmname(bitmap), page); + kfree(page); +} + +/* + * check a page and, if necessary, allocate it (or hijack it if the alloc fails) + * + * 1) check to see if this page is allocated, if it's not then try to alloc + * 2) if the alloc fails, set the page's hijacked flag so we'll use the + * page pointer directly as a counter + * + * if we find our page, we increment the page's refcount so that it stays + * allocated while we're using it + */ +static int bitmap_checkpage(struct bitmap *bitmap, unsigned long page, int create) +{ + unsigned char *mappage; + + if (page >= bitmap->pages) { + printk(KERN_ALERT + "%s: invalid bitmap page request: %lu (> %lu)\n", + bmname(bitmap), page, bitmap->pages-1); + return -EINVAL; + } + + + if (bitmap->bp[page].hijacked) /* it's hijacked, don't try to alloc */ + return 0; + + if (bitmap->bp[page].map) /* page is already allocated, just return */ + return 0; + + if (!create) + return -ENOENT; + + spin_unlock_irq(&bitmap->lock); + + /* this page has not been allocated yet */ + + if ((mappage = bitmap_alloc_page(bitmap)) == NULL) { + PRINTK("%s: bitmap map page allocation failed, hijacking\n", + bmname(bitmap)); + /* failed - set the hijacked flag so that we can use the + * pointer as a counter */ + spin_lock_irq(&bitmap->lock); + if (!bitmap->bp[page].map) + bitmap->bp[page].hijacked = 1; + goto out; + } + + /* got a page */ + + spin_lock_irq(&bitmap->lock); + + /* recheck the page */ + + if (bitmap->bp[page].map || bitmap->bp[page].hijacked) { + /* somebody beat us to getting the page */ + bitmap_free_page(bitmap, mappage); + return 0; + } + + /* no page was in place and we have one, so install it */ + + memset(mappage, 0, PAGE_SIZE); + bitmap->bp[page].map = mappage; + bitmap->missing_pages--; +out: + return 0; +} + + +/* if page is completely empty, put it back on the free list, or dealloc it */ +/* if page was hijacked, unmark the flag so it might get alloced next time */ +/* Note: lock should be held when calling this */ +static inline void bitmap_checkfree(struct bitmap *bitmap, unsigned long page) +{ + char *ptr; + + if (bitmap->bp[page].count) /* page is still busy */ + return; + + /* page is no longer in use, it can be released */ + + if (bitmap->bp[page].hijacked) { /* page was hijacked, undo this now */ + bitmap->bp[page].hijacked = 0; + bitmap->bp[page].map = NULL; + return; + } + + /* normal case, free the page */ + +#if 0 +/* actually ... let's not. We will probably need the page again exactly when + * memory is tight and we are flusing to disk + */ + return; +#else + ptr = bitmap->bp[page].map; + bitmap->bp[page].map = NULL; + bitmap->missing_pages++; + bitmap_free_page(bitmap, ptr); + return; +#endif +} + + +/* + * bitmap file handling - read and write the bitmap file and its superblock + */ + +/* copy the pathname of a file to a buffer */ +char *file_path(struct file *file, char *buf, int count) +{ + struct dentry *d; + struct vfsmount *v; + + if (!buf) + return NULL; + + d = file->f_dentry; + v = file->f_vfsmnt; + + buf = d_path(d, v, buf, count); + + return IS_ERR(buf) ? NULL : buf; +} + +/* + * basic page I/O operations + */ + +/* + * write out a page + */ +static int write_page(struct page *page, int wait) +{ + int ret = -ENOMEM; + + lock_page(page); + + if (page->mapping == NULL) + goto unlock_out; + else if (i_size_read(page->mapping->host) < page->index << PAGE_SHIFT) { + ret = -ENOENT; + goto unlock_out; + } + + ret = page->mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE); + if (!ret) + ret = page->mapping->a_ops->commit_write(NULL, page, 0, + PAGE_SIZE); + if (ret) { +unlock_out: + unlock_page(page); + return ret; + } + + set_page_dirty(page); /* force it to be written out */ + return write_one_page(page, wait); +} + +/* read a page from a file, pinning it into cache, and return bytes_read */ +static struct page *read_page(struct file *file, unsigned long index, + unsigned long *bytes_read) +{ + struct inode *inode = file->f_mapping->host; + struct page *page = NULL; + loff_t isize = i_size_read(inode); + unsigned long end_index = isize >> PAGE_CACHE_SHIFT; + + PRINTK("read bitmap file (%dB @ %Lu)\n", (int)PAGE_CACHE_SIZE, + (unsigned long long)index << PAGE_CACHE_SHIFT); + + page = read_cache_page(inode->i_mapping, index, + (filler_t *)inode->i_mapping->a_ops->readpage, file); + if (IS_ERR(page)) + goto out; + wait_on_page_locked(page); + if (!PageUptodate(page) || PageError(page)) { + page_cache_release(page); + page = ERR_PTR(-EIO); + goto out; + } + + if (index > end_index) /* we have read beyond EOF */ + *bytes_read = 0; + else if (index == end_index) /* possible short read */ + *bytes_read = isize & ~PAGE_CACHE_MASK; + else + *bytes_read = PAGE_CACHE_SIZE; /* got a full page */ +out: + if (IS_ERR(page)) + printk(KERN_ALERT "md: bitmap read error: (%dB @ %Lu): %ld\n", + (int)PAGE_CACHE_SIZE, + (unsigned long long)index << PAGE_CACHE_SHIFT, + PTR_ERR(page)); + return page; +} + +/* + * bitmap file superblock operations + */ + +/* update the event counter and sync the superblock to disk */ +int bitmap_update_sb(struct bitmap *bitmap) +{ + bitmap_super_t *sb; + unsigned long flags; + + if (!bitmap || !bitmap->mddev) /* no bitmap for this array */ + return 0; + spin_lock_irqsave(&bitmap->lock, flags); + if (!bitmap->sb_page) { /* no superblock */ + spin_unlock_irqrestore(&bitmap->lock, flags); + return 0; + } + page_cache_get(bitmap->sb_page); + spin_unlock_irqrestore(&bitmap->lock, flags); + sb = (bitmap_super_t *)kmap(bitmap->sb_page); + sb->events = cpu_to_le64(bitmap->mddev->events); + if (!bitmap->mddev->degraded) + sb->events_cleared = cpu_to_le64(bitmap->mddev->events); + kunmap(bitmap->sb_page); + write_page(bitmap->sb_page, 0); + return 0; +} + +/* print out the bitmap file superblock */ +void bitmap_print_sb(struct bitmap *bitmap) +{ + bitmap_super_t *sb; + + if (!bitmap || !bitmap->sb_page) + return; + sb = (bitmap_super_t *)kmap(bitmap->sb_page); + printk(KERN_DEBUG "%s: bitmap file superblock:\n", bmname(bitmap)); + printk(KERN_DEBUG " magic: %08x\n", le32_to_cpu(sb->magic)); + printk(KERN_DEBUG " version: %d\n", le32_to_cpu(sb->version)); + printk(KERN_DEBUG " uuid: %08x.%08x.%08x.%08x\n", + *(__u32 *)(sb->uuid+0), + *(__u32 *)(sb->uuid+4), + *(__u32 *)(sb->uuid+8), + *(__u32 *)(sb->uuid+12)); + printk(KERN_DEBUG " events: %llu\n", + (unsigned long long) le64_to_cpu(sb->events)); + printk(KERN_DEBUG "events_clred: %llu\n", + (unsigned long long) le64_to_cpu(sb->events_cleared)); + printk(KERN_DEBUG " state: %08x\n", le32_to_cpu(sb->state)); + printk(KERN_DEBUG " chunksize: %d B\n", le32_to_cpu(sb->chunksize)); + printk(KERN_DEBUG "daemon sleep: %ds\n", le32_to_cpu(sb->daemon_sleep)); + printk(KERN_DEBUG " sync size: %llu KB\n", le64_to_cpu(sb->sync_size)); + kunmap(bitmap->sb_page); +} + +/* read the superblock from the bitmap file and initialize some bitmap fields */ +static int bitmap_read_sb(struct bitmap *bitmap) +{ + char *reason = NULL; + bitmap_super_t *sb; + unsigned long chunksize, daemon_sleep; + unsigned long bytes_read; + unsigned long long events; + int err = -EINVAL; + + /* page 0 is the superblock, read it... */ + bitmap->sb_page = read_page(bitmap->file, 0, &bytes_read); + if (IS_ERR(bitmap->sb_page)) { + err = PTR_ERR(bitmap->sb_page); + bitmap->sb_page = NULL; + return err; + } + + sb = (bitmap_super_t *)kmap(bitmap->sb_page); + + if (bytes_read < sizeof(*sb)) { /* short read */ + printk(KERN_INFO "%s: bitmap file superblock truncated\n", + bmname(bitmap)); + err = -ENOSPC; + goto out; + } + + chunksize = le32_to_cpu(sb->chunksize); + daemon_sleep = le32_to_cpu(sb->daemon_sleep); + + /* verify that the bitmap-specific fields are valid */ + if (sb->magic != cpu_to_le32(BITMAP_MAGIC)) + reason = "bad magic"; + else if (sb->version != cpu_to_le32(BITMAP_MAJOR)) + reason = "unrecognized superblock version"; + else if (chunksize < 512 || chunksize > (1024 * 1024 * 4)) + reason = "bitmap chunksize out of range (512B - 4MB)"; + else if ((1 << ffz(~chunksize)) != chunksize) + reason = "bitmap chunksize not a power of 2"; + else if (daemon_sleep < 1 || daemon_sleep > 15) + reason = "daemon sleep period out of range"; + if (reason) { + printk(KERN_INFO "%s: invalid bitmap file superblock: %s\n", + bmname(bitmap), reason); + goto out; + } + + /* keep the array size field of the bitmap superblock up to date */ + sb->sync_size = cpu_to_le64(bitmap->mddev->resync_max_sectors); + + if (!bitmap->mddev->persistent) + goto success; + + /* + * if we have a persistent array superblock, compare the + * bitmap's UUID and event counter to the mddev's + */ + if (memcmp(sb->uuid, bitmap->mddev->uuid, 16)) { + printk(KERN_INFO "%s: bitmap superblock UUID mismatch\n", + bmname(bitmap)); + goto out; + } + events = le64_to_cpu(sb->events); + if (events < bitmap->mddev->events) { + printk(KERN_INFO "%s: bitmap file is out of date (%llu < %llu) " + "-- forcing full recovery\n", bmname(bitmap), events, + (unsigned long long) bitmap->mddev->events); + sb->state |= BITMAP_STALE; + } +success: + /* assign fields using values from superblock */ + bitmap->chunksize = chunksize; + bitmap->daemon_sleep = daemon_sleep; + bitmap->flags |= sb->state; + bitmap->events_cleared = le64_to_cpu(sb->events_cleared); + err = 0; +out: + kunmap(bitmap->sb_page); + if (err) + bitmap_print_sb(bitmap); + return err; +} + +enum bitmap_mask_op { + MASK_SET, + MASK_UNSET +}; + +/* record the state of the bitmap in the superblock */ +static void bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits, + enum bitmap_mask_op op) +{ + bitmap_super_t *sb; + unsigned long flags; + + spin_lock_irqsave(&bitmap->lock, flags); + if (!bitmap || !bitmap->sb_page) { /* can't set the state */ + spin_unlock_irqrestore(&bitmap->lock, flags); + return; + } + page_cache_get(bitmap->sb_page); + spin_unlock_irqrestore(&bitmap->lock, flags); + sb = (bitmap_super_t *)kmap(bitmap->sb_page); + switch (op) { + case MASK_SET: sb->state |= bits; + break; + case MASK_UNSET: sb->state &= ~bits; + break; + default: BUG(); + } + kunmap(bitmap->sb_page); + page_cache_release(bitmap->sb_page); +} + +/* + * general bitmap file operations + */ + +/* calculate the index of the page that contains this bit */ +static inline unsigned long file_page_index(unsigned long chunk) +{ + return CHUNK_BIT_OFFSET(chunk) >> PAGE_BIT_SHIFT; +} + +/* calculate the (bit) offset of this bit within a page */ +static inline unsigned long file_page_offset(unsigned long chunk) +{ + return CHUNK_BIT_OFFSET(chunk) & (PAGE_BITS - 1); +} + +/* + * return a pointer to the page in the filemap that contains the given bit + * + * this lookup is complicated by the fact that the bitmap sb might be exactly + * 1 page (e.g., x86) or less than 1 page -- so the bitmap might start on page + * 0 or page 1 + */ +static inline struct page *filemap_get_page(struct bitmap *bitmap, + unsigned long chunk) +{ + return bitmap->filemap[file_page_index(chunk) - file_page_index(0)]; +} + + +static void bitmap_file_unmap(struct bitmap *bitmap) +{ + struct page **map, *sb_page; + unsigned long *attr; + int pages; + unsigned long flags; + + spin_lock_irqsave(&bitmap->lock, flags); + map = bitmap->filemap; + bitmap->filemap = NULL; + attr = bitmap->filemap_attr; + bitmap->filemap_attr = NULL; + pages = bitmap->file_pages; + bitmap->file_pages = 0; + sb_page = bitmap->sb_page; + bitmap->sb_page = NULL; + spin_unlock_irqrestore(&bitmap->lock, flags); + + while (pages--) + if (map[pages]->index != 0) /* 0 is sb_page, release it below */ + page_cache_release(map[pages]); + kfree(map); + kfree(attr); + + if (sb_page) + page_cache_release(sb_page); +} + +static void bitmap_stop_daemons(struct bitmap *bitmap); + +/* dequeue the next item in a page list -- don't call from irq context */ +static struct page_list *dequeue_page(struct bitmap *bitmap, + struct list_head *head) +{ + struct page_list *item = NULL; + + spin_lock(&bitmap->write_lock); + if (list_empty(head)) + goto out; + item = list_entry(head->prev, struct page_list, list); + list_del(head->prev); +out: + spin_unlock(&bitmap->write_lock); + return item; +} + +static void drain_write_queues(struct bitmap *bitmap) +{ + struct list_head *queues[] = { &bitmap->complete_pages, NULL }; + struct list_head *head; + struct page_list *item; + int i; + + for (i = 0; queues[i]; i++) { + head = queues[i]; + while ((item = dequeue_page(bitmap, head))) { + page_cache_release(item->page); + mempool_free(item, bitmap->write_pool); + } + } + + spin_lock(&bitmap->write_lock); + bitmap->writes_pending = 0; /* make sure waiters continue */ + wake_up(&bitmap->write_wait); + spin_unlock(&bitmap->write_lock); +} + +static void bitmap_file_put(struct bitmap *bitmap) +{ + struct file *file; + struct inode *inode; + unsigned long flags; + + spin_lock_irqsave(&bitmap->lock, flags); + file = bitmap->file; + bitmap->file = NULL; + spin_unlock_irqrestore(&bitmap->lock, flags); + + bitmap_stop_daemons(bitmap); + + drain_write_queues(bitmap); + + bitmap_file_unmap(bitmap); + + if (file) { + inode = file->f_mapping->host; + spin_lock(&inode->i_lock); + atomic_set(&inode->i_writecount, 1); /* allow writes again */ + spin_unlock(&inode->i_lock); + fput(file); + } +} + + +/* + * bitmap_file_kick - if an error occurs while manipulating the bitmap file + * then it is no longer reliable, so we stop using it and we mark the file + * as failed in the superblock + */ +static void bitmap_file_kick(struct bitmap *bitmap) +{ + char *path, *ptr = NULL; + + bitmap_mask_state(bitmap, BITMAP_STALE, MASK_SET); + bitmap_update_sb(bitmap); + + path = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (path) + ptr = file_path(bitmap->file, path, PAGE_SIZE); + + printk(KERN_ALERT "%s: kicking failed bitmap file %s from array!\n", + bmname(bitmap), ptr ? ptr : ""); + + kfree(path); + + bitmap_file_put(bitmap); + + return; +} + +enum bitmap_page_attr { + BITMAP_PAGE_DIRTY = 1, // there are set bits that need to be synced + BITMAP_PAGE_CLEAN = 2, // there are bits that might need to be cleared + BITMAP_PAGE_NEEDWRITE=4, // there are cleared bits that need to be synced +}; + +static inline void set_page_attr(struct bitmap *bitmap, struct page *page, + enum bitmap_page_attr attr) +{ + bitmap->filemap_attr[page->index] |= attr; +} + +static inline void clear_page_attr(struct bitmap *bitmap, struct page *page, + enum bitmap_page_attr attr) +{ + bitmap->filemap_attr[page->index] &= ~attr; +} + +static inline unsigned long get_page_attr(struct bitmap *bitmap, struct page *page) +{ + return bitmap->filemap_attr[page->index]; +} + +/* + * bitmap_file_set_bit -- called before performing a write to the md device + * to set (and eventually sync) a particular bit in the bitmap file + * + * we set the bit immediately, then we record the page number so that + * when an unplug occurs, we can flush the dirty pages out to disk + */ +static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block) +{ + unsigned long bit; + struct page *page; + void *kaddr; + unsigned long chunk = block >> CHUNK_BLOCK_SHIFT(bitmap); + + if (!bitmap->file || !bitmap->filemap) { + return; + } + + page = filemap_get_page(bitmap, chunk); + bit = file_page_offset(chunk); + + + /* make sure the page stays cached until it gets written out */ + if (! (get_page_attr(bitmap, page) & BITMAP_PAGE_DIRTY)) + page_cache_get(page); + + /* set the bit */ + kaddr = kmap_atomic(page, KM_USER0); + set_bit(bit, kaddr); + kunmap_atomic(kaddr, KM_USER0); + PRINTK("set file bit %lu page %lu\n", bit, page->index); + + /* record page number so it gets flushed to disk when unplug occurs */ + set_page_attr(bitmap, page, BITMAP_PAGE_DIRTY); + +} + +/* this gets called when the md device is ready to unplug its underlying + * (slave) device queues -- before we let any writes go down, we need to + * sync the dirty pages of the bitmap file to disk */ +int bitmap_unplug(struct bitmap *bitmap) +{ + unsigned long i, attr, flags; + struct page *page; + int wait = 0; + + if (!bitmap) + return 0; + + /* look at each page to see if there are any set bits that need to be + * flushed out to disk */ + for (i = 0; i < bitmap->file_pages; i++) { + spin_lock_irqsave(&bitmap->lock, flags); + if (!bitmap->file || !bitmap->filemap) { + spin_unlock_irqrestore(&bitmap->lock, flags); + return 0; + } + page = bitmap->filemap[i]; + attr = get_page_attr(bitmap, page); + clear_page_attr(bitmap, page, BITMAP_PAGE_DIRTY); + clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE); + if ((attr & BITMAP_PAGE_DIRTY)) + wait = 1; + spin_unlock_irqrestore(&bitmap->lock, flags); + + if (attr & (BITMAP_PAGE_DIRTY | BITMAP_PAGE_NEEDWRITE)) + write_page(page, 0); + } + if (wait) { /* if any writes were performed, we need to wait on them */ + spin_lock_irq(&bitmap->write_lock); + wait_event_lock_irq(bitmap->write_wait, + bitmap->writes_pending == 0, bitmap->write_lock, + wake_up_process(bitmap->writeback_daemon->tsk)); + spin_unlock_irq(&bitmap->write_lock); + } + return 0; +} + +static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, + unsigned long sectors, int set); +/* * bitmap_init_from_disk -- called at bitmap_create time to initialize + * the in-memory bitmap from the on-disk bitmap -- also, sets up the + * memory mapping of the bitmap file + * Special cases: + * if there's no bitmap file, or if the bitmap file had been + * previously kicked from the array, we mark all the bits as + * 1's in order to cause a full resync. + */ +static int bitmap_init_from_disk(struct bitmap *bitmap) +{ + unsigned long i, chunks, index, oldindex, bit; + struct page *page = NULL, *oldpage = NULL; + unsigned long num_pages, bit_cnt = 0; + struct file *file; + unsigned long bytes, offset, dummy; + int outofdate; + int ret = -ENOSPC; + + chunks = bitmap->chunks; + file = bitmap->file; + + if (!file) { /* no file, dirty all the in-memory bits */ + printk(KERN_INFO "%s: no bitmap file, doing full recovery\n", + bmname(bitmap)); + bitmap_set_memory_bits(bitmap, 0, + chunks << CHUNK_BLOCK_SHIFT(bitmap), 1); + return 0; + } + +#if INJECT_FAULTS_3 + outofdate = 1; +#else + outofdate = bitmap->flags & BITMAP_STALE; +#endif + if (outofdate) + printk(KERN_INFO "%s: bitmap file is out of date, doing full " + "recovery\n", bmname(bitmap)); + + bytes = (chunks + 7) / 8; + num_pages = (bytes + PAGE_SIZE - 1) / PAGE_SIZE; + if (i_size_read(file->f_mapping->host) < bytes + sizeof(bitmap_super_t)) { + printk(KERN_INFO "%s: bitmap file too short %lu < %lu\n", + bmname(bitmap), + (unsigned long) i_size_read(file->f_mapping->host), + bytes + sizeof(bitmap_super_t)); + goto out; + } + num_pages++; + bitmap->filemap = kmalloc(sizeof(struct page *) * num_pages, GFP_KERNEL); + if (!bitmap->filemap) { + ret = -ENOMEM; + goto out; + } + + bitmap->filemap_attr = kmalloc(sizeof(long) * num_pages, GFP_KERNEL); + if (!bitmap->filemap_attr) { + ret = -ENOMEM; + goto out; + } + + memset(bitmap->filemap_attr, 0, sizeof(long) * num_pages); + + oldindex = ~0L; + + for (i = 0; i < chunks; i++) { + index = file_page_index(i); + bit = file_page_offset(i); + if (index != oldindex) { /* this is a new page, read it in */ + /* unmap the old page, we're done with it */ + if (oldpage != NULL) + kunmap(oldpage); + if (index == 0) { + /* + * if we're here then the superblock page + * contains some bits (PAGE_SIZE != sizeof sb) + * we've already read it in, so just use it + */ + page = bitmap->sb_page; + offset = sizeof(bitmap_super_t); + } else { + page = read_page(file, index, &dummy); + if (IS_ERR(page)) { /* read error */ + ret = PTR_ERR(page); + goto out; + } + offset = 0; + } + oldindex = index; + oldpage = page; + kmap(page); + + if (outofdate) { + /* + * if bitmap is out of date, dirty the + * whole page and write it out + */ + memset(page_address(page) + offset, 0xff, + PAGE_SIZE - offset); + ret = write_page(page, 1); + if (ret) { + kunmap(page); + /* release, page not in filemap yet */ + page_cache_release(page); + goto out; + } + } + + bitmap->filemap[bitmap->file_pages++] = page; + } + if (test_bit(bit, page_address(page))) { + /* if the disk bit is set, set the memory bit */ + bitmap_set_memory_bits(bitmap, + i << CHUNK_BLOCK_SHIFT(bitmap), 1, 1); + bit_cnt++; + } +#if 0 + else + bitmap_set_memory_bits(bitmap, + i << CHUNK_BLOCK_SHIFT(bitmap), 1, 0); +#endif + } + + /* everything went OK */ + ret = 0; + bitmap_mask_state(bitmap, BITMAP_STALE, MASK_UNSET); + + if (page) /* unmap the last page */ + kunmap(page); + + if (bit_cnt) { /* Kick recovery if any bits were set */ + set_bit(MD_RECOVERY_NEEDED, &bitmap->mddev->recovery); + md_wakeup_thread(bitmap->mddev->thread); + } + +out: + printk(KERN_INFO "%s: bitmap initialized from disk: " + "read %lu/%lu pages, set %lu bits, status: %d\n", + bmname(bitmap), bitmap->file_pages, num_pages, bit_cnt, ret); + + return ret; +} + + +static void bitmap_count_page(struct bitmap *bitmap, sector_t offset, int inc) +{ + sector_t chunk = offset >> CHUNK_BLOCK_SHIFT(bitmap); + unsigned long page = chunk >> PAGE_COUNTER_SHIFT; + bitmap->bp[page].count += inc; +/* + if (page == 0) printk("count page 0, offset %llu: %d gives %d\n", + (unsigned long long)offset, inc, bitmap->bp[page].count); +*/ + bitmap_checkfree(bitmap, page); +} +static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, + sector_t offset, int *blocks, + int create); + +/* + * bitmap daemon -- periodically wakes up to clean bits and flush pages + * out to disk + */ + +int bitmap_daemon_work(struct bitmap *bitmap) +{ + unsigned long bit, j; + unsigned long flags; + struct page *page = NULL, *lastpage = NULL; + int err = 0; + int blocks; + int attr; + + if (bitmap == NULL) + return 0; + if (time_before(jiffies, bitmap->daemon_lastrun + bitmap->daemon_sleep*HZ)) + return 0; + bitmap->daemon_lastrun = jiffies; + + for (j = 0; j < bitmap->chunks; j++) { + bitmap_counter_t *bmc; + spin_lock_irqsave(&bitmap->lock, flags); + if (!bitmap->file || !bitmap->filemap) { + /* error or shutdown */ + spin_unlock_irqrestore(&bitmap->lock, flags); + break; + } + + page = filemap_get_page(bitmap, j); + /* skip this page unless it's marked as needing cleaning */ + if (!((attr=get_page_attr(bitmap, page)) & BITMAP_PAGE_CLEAN)) { + if (attr & BITMAP_PAGE_NEEDWRITE) { + page_cache_get(page); + clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE); + } + spin_unlock_irqrestore(&bitmap->lock, flags); + if (attr & BITMAP_PAGE_NEEDWRITE) { + if (write_page(page, 0)) + bitmap_file_kick(bitmap); + page_cache_release(page); + } + continue; + } + + bit = file_page_offset(j); + + if (page != lastpage) { + /* grab the new page, sync and release the old */ + page_cache_get(page); + if (lastpage != NULL) { + if (get_page_attr(bitmap, lastpage) & BITMAP_PAGE_NEEDWRITE) { + clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); + spin_unlock_irqrestore(&bitmap->lock, flags); + write_page(lastpage, 0); + } else { + set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); + spin_unlock_irqrestore(&bitmap->lock, flags); + } + kunmap(lastpage); + page_cache_release(lastpage); + if (err) + bitmap_file_kick(bitmap); + } else + spin_unlock_irqrestore(&bitmap->lock, flags); + lastpage = page; + kmap(page); +/* + printk("bitmap clean at page %lu\n", j); +*/ + spin_lock_irqsave(&bitmap->lock, flags); + clear_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); + } + bmc = bitmap_get_counter(bitmap, j << CHUNK_BLOCK_SHIFT(bitmap), + &blocks, 0); + if (bmc) { +/* + if (j < 100) printk("bitmap: j=%lu, *bmc = 0x%x\n", j, *bmc); +*/ + if (*bmc == 2) { + *bmc=1; /* maybe clear the bit next time */ + set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); + } else if (*bmc == 1) { + /* we can clear the bit */ + *bmc = 0; + bitmap_count_page(bitmap, j << CHUNK_BLOCK_SHIFT(bitmap), + -1); + + /* clear the bit */ + clear_bit(bit, page_address(page)); + } + } + spin_unlock_irqrestore(&bitmap->lock, flags); + } + + /* now sync the final page */ + if (lastpage != NULL) { + kunmap(lastpage); + spin_lock_irqsave(&bitmap->lock, flags); + if (get_page_attr(bitmap, lastpage) &BITMAP_PAGE_NEEDWRITE) { + clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); + spin_unlock_irqrestore(&bitmap->lock, flags); + write_page(lastpage, 0); + } else { + set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); + spin_unlock_irqrestore(&bitmap->lock, flags); + } + + page_cache_release(lastpage); + } + + return err; +} + +static void daemon_exit(struct bitmap *bitmap, mdk_thread_t **daemon) +{ + mdk_thread_t *dmn; + unsigned long flags; + + /* if no one is waiting on us, we'll free the md thread struct + * and exit, otherwise we let the waiter clean things up */ + spin_lock_irqsave(&bitmap->lock, flags); + if ((dmn = *daemon)) { /* no one is waiting, cleanup and exit */ + *daemon = NULL; + spin_unlock_irqrestore(&bitmap->lock, flags); + kfree(dmn); + complete_and_exit(NULL, 0); /* do_exit not exported */ + } + spin_unlock_irqrestore(&bitmap->lock, flags); +} + +static void bitmap_writeback_daemon(mddev_t *mddev) +{ + struct bitmap *bitmap = mddev->bitmap; + struct page *page; + struct page_list *item; + int err = 0; + + while (1) { + PRINTK("%s: bitmap writeback daemon waiting...\n", bmname(bitmap)); + down_interruptible(&bitmap->write_done); + if (signal_pending(current)) { + printk(KERN_INFO + "%s: bitmap writeback daemon got signal, exiting...\n", + bmname(bitmap)); + break; + } + + PRINTK("%s: bitmap writeback daemon woke up...\n", bmname(bitmap)); + /* wait on bitmap page writebacks */ + while ((item = dequeue_page(bitmap, &bitmap->complete_pages))) { + page = item->page; + mempool_free(item, bitmap->write_pool); + PRINTK("wait on page writeback: %p %lu\n", page, bitmap->writes_pending); + wait_on_page_writeback(page); + PRINTK("finished page writeback: %p %lu\n", page, bitmap->writes_pending); + spin_lock(&bitmap->write_lock); + if (!--bitmap->writes_pending) + wake_up(&bitmap->write_wait); + spin_unlock(&bitmap->write_lock); + err = PageError(page); + page_cache_release(page); + if (err) { + printk(KERN_WARNING "%s: bitmap file writeback " + "failed (page %lu): %d\n", + bmname(bitmap), page->index, err); + bitmap_file_kick(bitmap); + goto out; + } + } + } +out: + if (err) { + printk(KERN_INFO "%s: bitmap writeback daemon exiting (%d)\n", + bmname(bitmap), err); + daemon_exit(bitmap, &bitmap->writeback_daemon); + } + return; +} + +static int bitmap_start_daemon(struct bitmap *bitmap, mdk_thread_t **ptr, + void (*func)(mddev_t *), char *name) +{ + mdk_thread_t *daemon; + unsigned long flags; + char namebuf[32]; + + spin_lock_irqsave(&bitmap->lock, flags); + *ptr = NULL; + if (!bitmap->file) /* no need for daemon if there's no backing file */ + goto out_unlock; + + spin_unlock_irqrestore(&bitmap->lock, flags); + +#if INJECT_FATAL_FAULT_2 + daemon = NULL; +#else + sprintf(namebuf, "%%s_%s", name); + daemon = md_register_thread(func, bitmap->mddev, namebuf); +#endif + if (!daemon) { + printk(KERN_ERR "%s: failed to start bitmap daemon\n", + bmname(bitmap)); + return -ECHILD; + } + + spin_lock_irqsave(&bitmap->lock, flags); + *ptr = daemon; + + md_wakeup_thread(daemon); /* start it running */ + + PRINTK("%s: %s daemon (pid %d) started...\n", + bmname(bitmap), name, bitmap->daemon->tsk->pid); +out_unlock: + spin_unlock_irqrestore(&bitmap->lock, flags); + return 0; +} + +static int bitmap_start_daemons(struct bitmap *bitmap) +{ + int err = bitmap_start_daemon(bitmap, &bitmap->writeback_daemon, + bitmap_writeback_daemon, "bitmap_wb"); + return err; +} + +static void bitmap_stop_daemon(struct bitmap *bitmap, mdk_thread_t **ptr) +{ + mdk_thread_t *daemon; + unsigned long flags; + + spin_lock_irqsave(&bitmap->lock, flags); + daemon = *ptr; + *ptr = NULL; + spin_unlock_irqrestore(&bitmap->lock, flags); + if (daemon) + md_unregister_thread(daemon); /* destroy the thread */ +} + +static void bitmap_stop_daemons(struct bitmap *bitmap) +{ + /* the daemons can't stop themselves... they'll just exit instead... */ + if (bitmap->writeback_daemon && + current->pid != bitmap->writeback_daemon->tsk->pid) + bitmap_stop_daemon(bitmap, &bitmap->writeback_daemon); +} + +static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, + sector_t offset, int *blocks, + int create) +{ + /* If 'create', we might release the lock and reclaim it. + * The lock must have been taken with interrupts enabled. + * If !create, we don't release the lock. + */ + sector_t chunk = offset >> CHUNK_BLOCK_SHIFT(bitmap); + unsigned long page = chunk >> PAGE_COUNTER_SHIFT; + unsigned long pageoff = (chunk & PAGE_COUNTER_MASK) << COUNTER_BYTE_SHIFT; + sector_t csize; + + if (bitmap_checkpage(bitmap, page, create) < 0) { + csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap)); + *blocks = csize - (offset & (csize- 1)); + return NULL; + } + /* now locked ... */ + + if (bitmap->bp[page].hijacked) { /* hijacked pointer */ + /* should we use the first or second counter field + * of the hijacked pointer? */ + int hi = (pageoff > PAGE_COUNTER_MASK); + csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap) + + PAGE_COUNTER_SHIFT - 1); + *blocks = csize - (offset & (csize- 1)); + return &((bitmap_counter_t *) + &bitmap->bp[page].map)[hi]; + } else { /* page is allocated */ + csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap)); + *blocks = csize - (offset & (csize- 1)); + return (bitmap_counter_t *) + &(bitmap->bp[page].map[pageoff]); + } +} + +int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors) +{ + if (!bitmap) return 0; + while (sectors) { + int blocks; + bitmap_counter_t *bmc; + + spin_lock_irq(&bitmap->lock); + bmc = bitmap_get_counter(bitmap, offset, &blocks, 1); + if (!bmc) { + spin_unlock_irq(&bitmap->lock); + return 0; + } + + switch(*bmc) { + case 0: + bitmap_file_set_bit(bitmap, offset); + bitmap_count_page(bitmap,offset, 1); + blk_plug_device(bitmap->mddev->queue); + /* fall through */ + case 1: + *bmc = 2; + } + if ((*bmc & COUNTER_MAX) == COUNTER_MAX) BUG(); + (*bmc)++; + + spin_unlock_irq(&bitmap->lock); + + offset += blocks; + if (sectors > blocks) + sectors -= blocks; + else sectors = 0; + } + return 0; +} + +void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, + int success) +{ + if (!bitmap) return; + while (sectors) { + int blocks; + unsigned long flags; + bitmap_counter_t *bmc; + + spin_lock_irqsave(&bitmap->lock, flags); + bmc = bitmap_get_counter(bitmap, offset, &blocks, 0); + if (!bmc) { + spin_unlock_irqrestore(&bitmap->lock, flags); + return; + } + + if (!success && ! (*bmc & NEEDED_MASK)) + *bmc |= NEEDED_MASK; + + (*bmc)--; + if (*bmc <= 2) { + set_page_attr(bitmap, + filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap)), + BITMAP_PAGE_CLEAN); + } + spin_unlock_irqrestore(&bitmap->lock, flags); + offset += blocks; + if (sectors > blocks) + sectors -= blocks; + else sectors = 0; + } +} + +int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks) +{ + bitmap_counter_t *bmc; + int rv; + if (bitmap == NULL) {/* FIXME or bitmap set as 'failed' */ + *blocks = 1024; + return 1; /* always resync if no bitmap */ + } + spin_lock_irq(&bitmap->lock); + bmc = bitmap_get_counter(bitmap, offset, blocks, 0); + rv = 0; + if (bmc) { + /* locked */ + if (RESYNC(*bmc)) + rv = 1; + else if (NEEDED(*bmc)) { + rv = 1; + *bmc |= RESYNC_MASK; + *bmc &= ~NEEDED_MASK; + } + } + spin_unlock_irq(&bitmap->lock); + return rv; +} + +void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted) +{ + bitmap_counter_t *bmc; + unsigned long flags; +/* + if (offset == 0) printk("bitmap_end_sync 0 (%d)\n", aborted); +*/ if (bitmap == NULL) { + *blocks = 1024; + return; + } + spin_lock_irqsave(&bitmap->lock, flags); + bmc = bitmap_get_counter(bitmap, offset, blocks, 0); + if (bmc == NULL) + goto unlock; + /* locked */ +/* + if (offset == 0) printk("bitmap_end sync found 0x%x, blocks %d\n", *bmc, *blocks); +*/ + if (RESYNC(*bmc)) { + *bmc &= ~RESYNC_MASK; + + if (!NEEDED(*bmc) && aborted) + *bmc |= NEEDED_MASK; + else { + if (*bmc <= 2) { + set_page_attr(bitmap, + filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap)), + BITMAP_PAGE_CLEAN); + } + } + } + unlock: + spin_unlock_irqrestore(&bitmap->lock, flags); +} + +void bitmap_close_sync(struct bitmap *bitmap) +{ + /* Sync has finished, and any bitmap chunks that weren't synced + * properly have been aborted. It remains to us to clear the + * RESYNC bit wherever it is still on + */ + sector_t sector = 0; + int blocks; + if (!bitmap) return; + while (sector < bitmap->mddev->resync_max_sectors) { + bitmap_end_sync(bitmap, sector, &blocks, 0); +/* + if (sector < 500) printk("bitmap_close_sync: sec %llu blks %d\n", + (unsigned long long)sector, blocks); +*/ sector += blocks; + } +} + +static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, + unsigned long sectors, int set) +{ + /* For each chunk covered by any of these sectors, set the + * resync needed bit, and the counter to 1. They should all + * be 0 at this point + */ + while (sectors) { + int secs; + bitmap_counter_t *bmc; + spin_lock_irq(&bitmap->lock); + bmc = bitmap_get_counter(bitmap, offset, &secs, 1); + if (!bmc) { + spin_unlock_irq(&bitmap->lock); + return; + } + if (set && !NEEDED(*bmc)) { + BUG_ON(*bmc); + *bmc = NEEDED_MASK | 1; + bitmap_count_page(bitmap, offset, 1); + } + spin_unlock_irq(&bitmap->lock); + if (sectors > secs) + sectors -= secs; + else + sectors = 0; + } +} + +/* dirty the entire bitmap */ +int bitmap_setallbits(struct bitmap *bitmap) +{ + unsigned long flags; + unsigned long j; + + /* dirty the in-memory bitmap */ + bitmap_set_memory_bits(bitmap, 0, bitmap->chunks << CHUNK_BLOCK_SHIFT(bitmap), 1); + + /* dirty the bitmap file */ + for (j = 0; j < bitmap->file_pages; j++) { + struct page *page = bitmap->filemap[j]; + + spin_lock_irqsave(&bitmap->lock, flags); + page_cache_get(page); + spin_unlock_irqrestore(&bitmap->lock, flags); + memset(kmap(page), 0xff, PAGE_SIZE); + kunmap(page); + write_page(page, 0); + } + + return 0; +} + +/* + * free memory that was allocated + */ +void bitmap_destroy(mddev_t *mddev) +{ + unsigned long k, pages; + struct bitmap_page *bp; + struct bitmap *bitmap = mddev->bitmap; + + if (!bitmap) /* there was no bitmap */ + return; + + mddev->bitmap = NULL; /* disconnect from the md device */ + + /* release the bitmap file and kill the daemon */ + bitmap_file_put(bitmap); + + bp = bitmap->bp; + pages = bitmap->pages; + + /* free all allocated memory */ + + mempool_destroy(bitmap->write_pool); + + if (bp) /* deallocate the page memory */ + for (k = 0; k < pages; k++) + if (bp[k].map && !bp[k].hijacked) + kfree(bp[k].map); + kfree(bp); + kfree(bitmap); +} + +/* + * initialize the bitmap structure + * if this returns an error, bitmap_destroy must be called to do clean up + */ +int bitmap_create(mddev_t *mddev) +{ + struct bitmap *bitmap; + unsigned long blocks = mddev->resync_max_sectors; + unsigned long chunks; + unsigned long pages; + struct file *file = mddev->bitmap_file; + int err; + + BUG_ON(sizeof(bitmap_super_t) != 256); + + if (!file) /* bitmap disabled, nothing to do */ + return 0; + + bitmap = kmalloc(sizeof(*bitmap), GFP_KERNEL); + if (!bitmap) + return -ENOMEM; + + memset(bitmap, 0, sizeof(*bitmap)); + + spin_lock_init(&bitmap->lock); + bitmap->mddev = mddev; + mddev->bitmap = bitmap; + + spin_lock_init(&bitmap->write_lock); + init_MUTEX_LOCKED(&bitmap->write_done); + INIT_LIST_HEAD(&bitmap->complete_pages); + init_waitqueue_head(&bitmap->write_wait); + bitmap->write_pool = mempool_create(WRITE_POOL_SIZE, write_pool_alloc, + write_pool_free, NULL); + if (!bitmap->write_pool) + return -ENOMEM; + + bitmap->file = file; + get_file(file); + /* read superblock from bitmap file (this sets bitmap->chunksize) */ + err = bitmap_read_sb(bitmap); + if (err) + return err; + + bitmap->chunkshift = find_first_bit(&bitmap->chunksize, + sizeof(bitmap->chunksize)); + + /* now that chunksize and chunkshift are set, we can use these macros */ + chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) / + CHUNK_BLOCK_RATIO(bitmap); + pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO; + + BUG_ON(!pages); + + bitmap->chunks = chunks; + bitmap->pages = pages; + bitmap->missing_pages = pages; + bitmap->counter_bits = COUNTER_BITS; + + bitmap->syncchunk = ~0UL; + +#if INJECT_FATAL_FAULT_1 + bitmap->bp = NULL; +#else + bitmap->bp = kmalloc(pages * sizeof(*bitmap->bp), GFP_KERNEL); +#endif + if (!bitmap->bp) + return -ENOMEM; + memset(bitmap->bp, 0, pages * sizeof(*bitmap->bp)); + + bitmap->flags |= BITMAP_ACTIVE; + + /* now that we have some pages available, initialize the in-memory + * bitmap from the on-disk bitmap */ + err = bitmap_init_from_disk(bitmap); + if (err) + return err; + + printk(KERN_INFO "created bitmap (%lu pages) for device %s\n", + pages, bmname(bitmap)); + + /* kick off the bitmap daemons */ + err = bitmap_start_daemons(bitmap); + if (err) + return err; + return bitmap_update_sb(bitmap); +} + +/* the bitmap API -- for raid personalities */ +EXPORT_SYMBOL(bitmap_startwrite); +EXPORT_SYMBOL(bitmap_endwrite); +EXPORT_SYMBOL(bitmap_start_sync); +EXPORT_SYMBOL(bitmap_end_sync); +EXPORT_SYMBOL(bitmap_unplug); +EXPORT_SYMBOL(bitmap_close_sync); +EXPORT_SYMBOL(bitmap_daemon_work); diff --git a/drivers/md/md.c b/drivers/md/md.c index fa608a1a5c20..c402f6cc7047 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -19,6 +19,9 @@ Neil Brown . + - persistent bitmap code + Copyright (C) 2003-2004, Paul Clements, SteelEye Technology, 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, or (at your option) @@ -33,6 +36,7 @@ #include #include #include +#include #include #include #include /* for invalidate_bdev */ @@ -40,6 +44,8 @@ #include +#include + #ifdef CONFIG_KMOD #include #endif @@ -1198,8 +1204,11 @@ void md_print_devices(void) printk("md: * *\n"); printk("md: **********************************\n"); ITERATE_MDDEV(mddev,tmp) { - printk("%s: ", mdname(mddev)); + if (mddev->bitmap) + bitmap_print_sb(mddev->bitmap); + else + printk("%s: ", mdname(mddev)); ITERATE_RDEV(mddev,rdev,tmp2) printk("<%s>", bdevname(rdev->bdev,b)); printk("\n"); @@ -1287,7 +1296,7 @@ repeat: "md: updating %s RAID superblock on device (in sync %d)\n", mdname(mddev),mddev->in_sync); - err = 0; + err = bitmap_update_sb(mddev->bitmap); ITERATE_RDEV(mddev,rdev,tmp) { char b[BDEVNAME_SIZE]; dprintk(KERN_INFO "md: "); @@ -1624,12 +1633,19 @@ static int do_md_run(mddev_t * mddev) mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */ - err = mddev->pers->run(mddev); + /* before we start the array running, initialise the bitmap */ + err = bitmap_create(mddev); + if (err) + printk(KERN_ERR "%s: failed to create bitmap (%d)\n", + mdname(mddev), err); + else + err = mddev->pers->run(mddev); if (err) { printk(KERN_ERR "md: pers->run() failed ...\n"); module_put(mddev->pers->owner); mddev->pers = NULL; - return -EINVAL; + bitmap_destroy(mddev); + return err; } atomic_set(&mddev->writes_pending,0); mddev->safemode = 0; @@ -1742,6 +1758,14 @@ static int do_md_stop(mddev_t * mddev, int ro) if (ro) set_disk_ro(disk, 1); } + + bitmap_destroy(mddev); + if (mddev->bitmap_file) { + atomic_set(&mddev->bitmap_file->f_dentry->d_inode->i_writecount, 1); + fput(mddev->bitmap_file); + mddev->bitmap_file = NULL; + } + /* * Free resources if final stop */ @@ -2000,6 +2024,42 @@ static int get_array_info(mddev_t * mddev, void __user * arg) return 0; } +static int get_bitmap_file(mddev_t * mddev, void * arg) +{ + mdu_bitmap_file_t *file = NULL; /* too big for stack allocation */ + char *ptr, *buf = NULL; + int err = -ENOMEM; + + file = kmalloc(sizeof(*file), GFP_KERNEL); + if (!file) + goto out; + + /* bitmap disabled, zero the first byte and copy out */ + if (!mddev->bitmap || !mddev->bitmap->file) { + file->pathname[0] = '\0'; + goto copy_out; + } + + buf = kmalloc(sizeof(file->pathname), GFP_KERNEL); + if (!buf) + goto out; + + ptr = file_path(mddev->bitmap->file, buf, sizeof(file->pathname)); + if (!ptr) + goto out; + + strcpy(file->pathname, ptr); + +copy_out: + err = 0; + if (copy_to_user(arg, file, sizeof(*file))) + err = -EFAULT; +out: + kfree(buf); + kfree(file); + return err; +} + static int get_disk_info(mddev_t * mddev, void __user * arg) { mdu_disk_info_t info; @@ -2275,6 +2335,48 @@ abort_export: return err; } +/* similar to deny_write_access, but accounts for our holding a reference + * to the file ourselves */ +static int deny_bitmap_write_access(struct file * file) +{ + struct inode *inode = file->f_mapping->host; + + spin_lock(&inode->i_lock); + if (atomic_read(&inode->i_writecount) > 1) { + spin_unlock(&inode->i_lock); + return -ETXTBSY; + } + atomic_set(&inode->i_writecount, -1); + spin_unlock(&inode->i_lock); + + return 0; +} + +static int set_bitmap_file(mddev_t *mddev, int fd) +{ + int err; + + if (mddev->pers) + return -EBUSY; + + mddev->bitmap_file = fget(fd); + + if (mddev->bitmap_file == NULL) { + printk(KERN_ERR "%s: error: failed to get bitmap file\n", + mdname(mddev)); + return -EBADF; + } + + err = deny_bitmap_write_access(mddev->bitmap_file); + if (err) { + printk(KERN_ERR "%s: error: bitmap file is already in use\n", + mdname(mddev)); + fput(mddev->bitmap_file); + mddev->bitmap_file = NULL; + } + return err; +} + /* * set_array_info is used two different ways * The original usage is when creating a new array. @@ -2586,8 +2688,10 @@ static int md_ioctl(struct inode *inode, struct file *file, /* * Commands querying/configuring an existing array: */ - /* if we are initialised yet, only ADD_NEW_DISK or STOP_ARRAY is allowed */ - if (!mddev->raid_disks && cmd != ADD_NEW_DISK && cmd != STOP_ARRAY && cmd != RUN_ARRAY) { + /* if we are not initialised yet, only ADD_NEW_DISK, STOP_ARRAY, + * RUN_ARRAY, and SET_BITMAP_FILE are allowed */ + if (!mddev->raid_disks && cmd != ADD_NEW_DISK && cmd != STOP_ARRAY + && cmd != RUN_ARRAY && cmd != SET_BITMAP_FILE) { err = -ENODEV; goto abort_unlock; } @@ -2601,6 +2705,10 @@ static int md_ioctl(struct inode *inode, struct file *file, err = get_array_info(mddev, argp); goto done_unlock; + case GET_BITMAP_FILE: + err = get_bitmap_file(mddev, (void *)arg); + goto done_unlock; + case GET_DISK_INFO: err = get_disk_info(mddev, argp); goto done_unlock; @@ -2681,6 +2789,10 @@ static int md_ioctl(struct inode *inode, struct file *file, err = do_md_run (mddev); goto done_unlock; + case SET_BITMAP_FILE: + err = set_bitmap_file(mddev, (int)arg); + goto done_unlock; + default: if (_IOC_TYPE(cmd) == MD_MAJOR) printk(KERN_WARNING "md: %s(pid %d) used" @@ -2792,8 +2904,9 @@ static int md_thread(void * arg) while (thread->run) { void (*run)(mddev_t *); - wait_event_interruptible(thread->wqueue, - test_bit(THREAD_WAKEUP, &thread->flags)); + wait_event_interruptible_timeout(thread->wqueue, + test_bit(THREAD_WAKEUP, &thread->flags), + thread->timeout); if (current->flags & PF_FREEZE) refrigerator(PF_FREEZE); @@ -2839,6 +2952,7 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev, thread->run = run; thread->mddev = mddev; thread->name = name; + thread->timeout = MAX_SCHEDULE_TIMEOUT; ret = kernel_thread(md_thread, thread, 0); if (ret < 0) { kfree(thread); @@ -2877,13 +2991,13 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev) if (!rdev || rdev->faulty) return; - +/* dprintk("md_error dev:%s, rdev:(%d:%d), (caller: %p,%p,%p,%p).\n", mdname(mddev), MAJOR(rdev->bdev->bd_dev), MINOR(rdev->bdev->bd_dev), __builtin_return_address(0),__builtin_return_address(1), __builtin_return_address(2),__builtin_return_address(3)); - +*/ if (!mddev->pers->error_handler) return; mddev->pers->error_handler(mddev,rdev); @@ -3037,6 +3151,7 @@ static int md_seq_show(struct seq_file *seq, void *v) struct list_head *tmp2; mdk_rdev_t *rdev; int i; + struct bitmap *bitmap; if (v == (void*)1) { seq_printf(seq, "Personalities : "); @@ -3089,10 +3204,36 @@ static int md_seq_show(struct seq_file *seq, void *v) if (mddev->pers) { mddev->pers->status (seq, mddev); seq_printf(seq, "\n "); - if (mddev->curr_resync > 2) + if (mddev->curr_resync > 2) { status_resync (seq, mddev); - else if (mddev->curr_resync == 1 || mddev->curr_resync == 2) - seq_printf(seq, " resync=DELAYED"); + seq_printf(seq, "\n "); + } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2) + seq_printf(seq, " resync=DELAYED\n "); + } else + seq_printf(seq, "\n "); + + if ((bitmap = mddev->bitmap)) { + char *buf, *path; + unsigned long chunk_kb; + unsigned long flags; + buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + spin_lock_irqsave(&bitmap->lock, flags); + chunk_kb = bitmap->chunksize >> 10; + seq_printf(seq, "bitmap: %lu/%lu pages [%luKB], " + "%lu%s chunk", + bitmap->pages - bitmap->missing_pages, + bitmap->pages, + (bitmap->pages - bitmap->missing_pages) + << (PAGE_SHIFT - 10), + chunk_kb ? chunk_kb : bitmap->chunksize, + chunk_kb ? "KB" : "B"); + if (bitmap->file && buf) { + path = file_path(bitmap->file, buf, PAGE_SIZE); + seq_printf(seq, ", file: %s", path ? path : ""); + } + seq_printf(seq, "\n"); + spin_unlock_irqrestore(&bitmap->lock, flags); + kfree(buf); } seq_printf(seq, "\n"); @@ -3328,7 +3469,8 @@ static void md_do_sync(mddev_t *mddev) sysctl_speed_limit_max); is_mddev_idle(mddev); /* this also initializes IO event counters */ - if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) + /* we don't use the checkpoint if there's a bitmap */ + if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && !mddev->bitmap) j = mddev->recovery_cp; else j = 0; @@ -3673,6 +3815,8 @@ static int __init md_init(void) " MD_SB_DISKS=%d\n", MD_MAJOR_VERSION, MD_MINOR_VERSION, MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS); + printk(KERN_INFO "md: bitmap version %d.%d\n", BITMAP_MAJOR, + BITMAP_MINOR); if (register_blkdev(MAJOR_NR, "md")) return -1; diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h new file mode 100644 index 000000000000..f785cf26cbad --- /dev/null +++ b/include/linux/raid/bitmap.h @@ -0,0 +1,280 @@ +/* + * bitmap.h: Copyright (C) Peter T. Breuer (ptb@ot.uc3m.es) 2003 + * + * additions: Copyright (C) 2003-2004, Paul Clements, SteelEye Technology, Inc. + */ +#ifndef BITMAP_H +#define BITMAP_H 1 + +#define BITMAP_MAJOR 3 +#define BITMAP_MINOR 38 + +/* + * in-memory bitmap: + * + * Use 16 bit block counters to track pending writes to each "chunk". + * The 2 high order bits are special-purpose, the first is a flag indicating + * whether a resync is needed. The second is a flag indicating whether a + * resync is active. + * This means that the counter is actually 14 bits: + * + * +--------+--------+------------------------------------------------+ + * | resync | resync | counter | + * | needed | active | | + * | (0-1) | (0-1) | (0-16383) | + * +--------+--------+------------------------------------------------+ + * + * The "resync needed" bit is set when: + * a '1' bit is read from storage at startup. + * a write request fails on some drives + * a resync is aborted on a chunk with 'resync active' set + * It is cleared (and resync-active set) when a resync starts across all drives + * of the chunk. + * + * + * The "resync active" bit is set when: + * a resync is started on all drives, and resync_needed is set. + * resync_needed will be cleared (as long as resync_active wasn't already set). + * It is cleared when a resync completes. + * + * The counter counts pending write requests, plus the on-disk bit. + * When the counter is '1' and the resync bits are clear, the on-disk + * bit can be cleared aswell, thus setting the counter to 0. + * When we set a bit, or in the counter (to start a write), if the fields is + * 0, we first set the disk bit and set the counter to 1. + * + * If the counter is 0, the on-disk bit is clear and the stipe is clean + * Anything that dirties the stipe pushes the counter to 2 (at least) + * and sets the on-disk bit (lazily). + * If a periodic sweep find the counter at 2, it is decremented to 1. + * If the sweep find the counter at 1, the on-disk bit is cleared and the + * counter goes to zero. + * + * Also, we'll hijack the "map" pointer itself and use it as two 16 bit block + * counters as a fallback when "page" memory cannot be allocated: + * + * Normal case (page memory allocated): + * + * page pointer (32-bit) + * + * [ ] ------+ + * | + * +-------> [ ][ ]..[ ] (4096 byte page == 2048 counters) + * c1 c2 c2048 + * + * Hijacked case (page memory allocation failed): + * + * hijacked page pointer (32-bit) + * + * [ ][ ] (no page memory allocated) + * counter #1 (16-bit) counter #2 (16-bit) + * + */ + +#ifdef __KERNEL__ + +#define PAGE_BITS (PAGE_SIZE << 3) +#define PAGE_BIT_SHIFT (PAGE_SHIFT + 3) + +typedef __u16 bitmap_counter_t; +#define COUNTER_BITS 16 +#define COUNTER_BIT_SHIFT 4 +#define COUNTER_BYTE_RATIO (COUNTER_BITS / 8) +#define COUNTER_BYTE_SHIFT (COUNTER_BIT_SHIFT - 3) + +#define NEEDED_MASK ((bitmap_counter_t) (1 << (COUNTER_BITS - 1))) +#define RESYNC_MASK ((bitmap_counter_t) (1 << (COUNTER_BITS - 2))) +#define COUNTER_MAX ((bitmap_counter_t) RESYNC_MASK - 1) +#define NEEDED(x) (((bitmap_counter_t) x) & NEEDED_MASK) +#define RESYNC(x) (((bitmap_counter_t) x) & RESYNC_MASK) +#define COUNTER(x) (((bitmap_counter_t) x) & COUNTER_MAX) + +/* how many counters per page? */ +#define PAGE_COUNTER_RATIO (PAGE_BITS / COUNTER_BITS) +/* same, except a shift value for more efficient bitops */ +#define PAGE_COUNTER_SHIFT (PAGE_BIT_SHIFT - COUNTER_BIT_SHIFT) +/* same, except a mask value for more efficient bitops */ +#define PAGE_COUNTER_MASK (PAGE_COUNTER_RATIO - 1) + +#define BITMAP_BLOCK_SIZE 512 +#define BITMAP_BLOCK_SHIFT 9 + +/* how many blocks per chunk? (this is variable) */ +#define CHUNK_BLOCK_RATIO(bitmap) ((bitmap)->chunksize >> BITMAP_BLOCK_SHIFT) +#define CHUNK_BLOCK_SHIFT(bitmap) ((bitmap)->chunkshift - BITMAP_BLOCK_SHIFT) +#define CHUNK_BLOCK_MASK(bitmap) (CHUNK_BLOCK_RATIO(bitmap) - 1) + +/* when hijacked, the counters and bits represent even larger "chunks" */ +/* there will be 1024 chunks represented by each counter in the page pointers */ +#define PAGEPTR_BLOCK_RATIO(bitmap) \ + (CHUNK_BLOCK_RATIO(bitmap) << PAGE_COUNTER_SHIFT >> 1) +#define PAGEPTR_BLOCK_SHIFT(bitmap) \ + (CHUNK_BLOCK_SHIFT(bitmap) + PAGE_COUNTER_SHIFT - 1) +#define PAGEPTR_BLOCK_MASK(bitmap) (PAGEPTR_BLOCK_RATIO(bitmap) - 1) + +/* + * on-disk bitmap: + * + * Use one bit per "chunk" (block set). We do the disk I/O on the bitmap + * file a page at a time. There's a superblock at the start of the file. + */ + +/* map chunks (bits) to file pages - offset by the size of the superblock */ +#define CHUNK_BIT_OFFSET(chunk) ((chunk) + (sizeof(bitmap_super_t) << 3)) + +#endif + +/* + * bitmap structures: + */ + +#define BITMAP_MAGIC 0x6d746962 + +/* use these for bitmap->flags and bitmap->sb->state bit-fields */ +enum bitmap_state { + BITMAP_ACTIVE = 0x001, /* the bitmap is in use */ + BITMAP_STALE = 0x002 /* the bitmap file is out of date or had -EIO */ +}; + +/* the superblock at the front of the bitmap file -- little endian */ +typedef struct bitmap_super_s { + __u32 magic; /* 0 BITMAP_MAGIC */ + __u32 version; /* 4 the bitmap major for now, could change... */ + __u8 uuid[16]; /* 8 128 bit uuid - must match md device uuid */ + __u64 events; /* 24 event counter for the bitmap (1)*/ + __u64 events_cleared;/*32 event counter when last bit cleared (2) */ + __u64 sync_size; /* 40 the size of the md device's sync range(3) */ + __u32 state; /* 48 bitmap state information */ + __u32 chunksize; /* 52 the bitmap chunk size in bytes */ + __u32 daemon_sleep; /* 56 seconds between disk flushes */ + + __u8 pad[256 - 60]; /* set to zero */ +} bitmap_super_t; + +/* notes: + * (1) This event counter is updated before the eventcounter in the md superblock + * When a bitmap is loaded, it is only accepted if this event counter is equal + * to, or one greater than, the event counter in the superblock. + * (2) This event counter is updated when the other one is *if*and*only*if* the + * array is not degraded. As bits are not cleared when the array is degraded, + * this represents the last time that any bits were cleared. + * If a device is being added that has an event count with this value or + * higher, it is accepted as conforming to the bitmap. + * (3)This is the number of sectors represented by the bitmap, and is the range that + * resync happens across. For raid1 and raid5/6 it is the size of individual + * devices. For raid10 it is the size of the array. + */ + +#ifdef __KERNEL__ + +/* the in-memory bitmap is represented by bitmap_pages */ +struct bitmap_page { + /* + * map points to the actual memory page + */ + char *map; + /* + * in emergencies (when map cannot be alloced), hijack the map + * pointer and use it as two counters itself + */ + unsigned int hijacked:1; + /* + * count of dirty bits on the page + */ + unsigned int count:31; +}; + +/* keep track of bitmap file pages that have pending writes on them */ +struct page_list { + struct list_head list; + struct page *page; +}; + +/* the main bitmap structure - one per mddev */ +struct bitmap { + struct bitmap_page *bp; + unsigned long pages; /* total number of pages in the bitmap */ + unsigned long missing_pages; /* number of pages not yet allocated */ + + mddev_t *mddev; /* the md device that the bitmap is for */ + + int counter_bits; /* how many bits per block counter */ + + /* bitmap chunksize -- how much data does each bit represent? */ + unsigned long chunksize; + unsigned long chunkshift; /* chunksize = 2^chunkshift (for bitops) */ + unsigned long chunks; /* total number of data chunks for the array */ + + /* We hold a count on the chunk currently being synced, and drop + * it when the last block is started. If the resync is aborted + * midway, we need to be able to drop that count, so we remember + * the counted chunk.. + */ + unsigned long syncchunk; + + __u64 events_cleared; + + /* bitmap spinlock */ + spinlock_t lock; + + struct file *file; /* backing disk file */ + struct page *sb_page; /* cached copy of the bitmap file superblock */ + struct page **filemap; /* list of cache pages for the file */ + unsigned long *filemap_attr; /* attributes associated w/ filemap pages */ + unsigned long file_pages; /* number of pages in the file */ + + unsigned long flags; + + /* + * the bitmap daemon - periodically wakes up and sweeps the bitmap + * file, cleaning up bits and flushing out pages to disk as necessary + */ + unsigned long daemon_lastrun; /* jiffies of last run */ + unsigned long daemon_sleep; /* how many seconds between updates? */ + + /* + * bitmap write daemon - this daemon performs writes to the bitmap file + * this thread is only needed because of a limitation in ext3 (jbd) + * that does not allow a task to have two journal transactions ongoing + * simultaneously (even if the transactions are for two different + * filesystems) -- in the case of bitmap, that would be the filesystem + * that the bitmap file resides on and the filesystem that is mounted + * on the md device -- see current->journal_info in jbd/transaction.c + */ + mdk_thread_t *writeback_daemon; + spinlock_t write_lock; + struct semaphore write_ready; + struct semaphore write_done; + unsigned long writes_pending; + wait_queue_head_t write_wait; + struct list_head write_pages; + struct list_head complete_pages; + mempool_t *write_pool; +}; + +/* the bitmap API */ + +/* these are used only by md/bitmap */ +int bitmap_create(mddev_t *mddev); +void bitmap_destroy(mddev_t *mddev); +int bitmap_active(struct bitmap *bitmap); + +char *file_path(struct file *file, char *buf, int count); +void bitmap_print_sb(struct bitmap *bitmap); +int bitmap_update_sb(struct bitmap *bitmap); + +int bitmap_setallbits(struct bitmap *bitmap); + +/* these are exported */ +int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors); +void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, + int success); +int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks); +void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted); +void bitmap_close_sync(struct bitmap *bitmap); + +int bitmap_unplug(struct bitmap *bitmap); +int bitmap_daemon_work(struct bitmap *bitmap); +#endif + +#endif diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index bce0032decff..16e94a9f0f8c 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h @@ -267,6 +267,9 @@ struct mddev_s atomic_t writes_pending; request_queue_t *queue; /* for plugging ... */ + struct bitmap *bitmap; /* the bitmap for the device */ + struct file *bitmap_file; /* the bitmap file */ + struct list_head all_mddevs; }; @@ -341,6 +344,7 @@ typedef struct mdk_thread_s { unsigned long flags; struct completion *event; struct task_struct *tsk; + unsigned long timeout; const char *name; } mdk_thread_t; diff --git a/include/linux/raid/md_u.h b/include/linux/raid/md_u.h index a2df5c2a42af..81da20ccec4d 100644 --- a/include/linux/raid/md_u.h +++ b/include/linux/raid/md_u.h @@ -23,6 +23,7 @@ #define GET_DISK_INFO _IOR (MD_MAJOR, 0x12, mdu_disk_info_t) #define PRINT_RAID_DEBUG _IO (MD_MAJOR, 0x13) #define RAID_AUTORUN _IO (MD_MAJOR, 0x14) +#define GET_BITMAP_FILE _IOR (MD_MAJOR, 0x15, mdu_bitmap_file_t) /* configuration */ #define CLEAR_ARRAY _IO (MD_MAJOR, 0x20) @@ -36,6 +37,7 @@ #define HOT_ADD_DISK _IO (MD_MAJOR, 0x28) #define SET_DISK_FAULTY _IO (MD_MAJOR, 0x29) #define HOT_GENERATE_ERROR _IO (MD_MAJOR, 0x2a) +#define SET_BITMAP_FILE _IOW (MD_MAJOR, 0x2b, int) /* usage */ #define RUN_ARRAY _IOW (MD_MAJOR, 0x30, mdu_param_t) @@ -106,6 +108,11 @@ typedef struct mdu_start_info_s { } mdu_start_info_t; +typedef struct mdu_bitmap_file_s +{ + char pathname[4096]; +} mdu_bitmap_file_t; + typedef struct mdu_param_s { int personality; /* 1,2,3,4 */ -- cgit v1.2.3-59-g8ed1b From 78d742d876bdf7263d0d966fbe9593559fd904a7 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:15 -0700 Subject: [PATCH] md: a couple of tidyups relating to the bitmap file. 1/ When init from disk, it is a BUG if there is nowhere to init from, 2/ use seq_path to print path in /proc/mdstat Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/bitmap.c | 8 +------- drivers/md/md.c | 11 +++++------ 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 34ffc133db05..b43bdb2c7e64 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -769,13 +769,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap) chunks = bitmap->chunks; file = bitmap->file; - if (!file) { /* no file, dirty all the in-memory bits */ - printk(KERN_INFO "%s: no bitmap file, doing full recovery\n", - bmname(bitmap)); - bitmap_set_memory_bits(bitmap, 0, - chunks << CHUNK_BLOCK_SHIFT(bitmap), 1); - return 0; - } + BUG_ON(!file); #if INJECT_FAULTS_3 outofdate = 1; diff --git a/drivers/md/md.c b/drivers/md/md.c index c402f6cc7047..52fafb820f74 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3213,10 +3213,8 @@ static int md_seq_show(struct seq_file *seq, void *v) seq_printf(seq, "\n "); if ((bitmap = mddev->bitmap)) { - char *buf, *path; unsigned long chunk_kb; unsigned long flags; - buf = kmalloc(PAGE_SIZE, GFP_KERNEL); spin_lock_irqsave(&bitmap->lock, flags); chunk_kb = bitmap->chunksize >> 10; seq_printf(seq, "bitmap: %lu/%lu pages [%luKB], " @@ -3227,13 +3225,14 @@ static int md_seq_show(struct seq_file *seq, void *v) << (PAGE_SHIFT - 10), chunk_kb ? chunk_kb : bitmap->chunksize, chunk_kb ? "KB" : "B"); - if (bitmap->file && buf) { - path = file_path(bitmap->file, buf, PAGE_SIZE); - seq_printf(seq, ", file: %s", path ? path : ""); + if (bitmap->file) { + seq_printf(seq, ", file: "); + seq_path(seq, bitmap->file->f_vfsmnt, + bitmap->file->f_dentry," \t\n"); } + seq_printf(seq, "\n"); spin_unlock_irqrestore(&bitmap->lock, flags); - kfree(buf); } seq_printf(seq, "\n"); -- cgit v1.2.3-59-g8ed1b From 5f40402d96cb21df912e5bbb3fffa5e1afc81e98 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:16 -0700 Subject: [PATCH] md: call bitmap_daemon_work regularly bitmap_daemon_work clears bits in the bitmap for blocks that haven't been written to for a while. It needs to be called regularly to make sure the bitmap doesn't endup full of ones .... but it wasn't. So call it from the increasingly-inaptly-named md_check_recovery Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 52fafb820f74..b02f8d1d77e7 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3635,7 +3635,8 @@ void md_check_recovery(mddev_t *mddev) struct list_head *rtmp; - dprintk(KERN_INFO "md: recovery thread got woken up ...\n"); + if (mddev->bitmap) + bitmap_daemon_work(mddev->bitmap); if (mddev->ro) return; -- cgit v1.2.3-59-g8ed1b From d80a138c013f81c1b9383c83983934e34e380a2d Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:17 -0700 Subject: [PATCH] md: print correct pid for newly created bitmap-writeback-daemon. The debugging message printed the wrong pid, which didn't help remove bugs.... Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/bitmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index b43bdb2c7e64..c43fd031aafe 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -1112,7 +1112,7 @@ static int bitmap_start_daemon(struct bitmap *bitmap, mdk_thread_t **ptr, md_wakeup_thread(daemon); /* start it running */ PRINTK("%s: %s daemon (pid %d) started...\n", - bmname(bitmap), name, bitmap->daemon->tsk->pid); + bmname(bitmap), name, daemon->tsk->pid); out_unlock: spin_unlock_irqrestore(&bitmap->lock, flags); return 0; -- cgit v1.2.3-59-g8ed1b From bc7f77de2cd81718dd789a2cfe68a7cf1b48f016 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:17 -0700 Subject: [PATCH] md: minor code rearrangement in bitmap_init_from_disk Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/bitmap.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index c43fd031aafe..62fac2b38000 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -781,7 +781,9 @@ static int bitmap_init_from_disk(struct bitmap *bitmap) "recovery\n", bmname(bitmap)); bytes = (chunks + 7) / 8; - num_pages = (bytes + PAGE_SIZE - 1) / PAGE_SIZE; + + num_pages = (bytes + sizeof(bitmap_super_t) + PAGE_SIZE - 1) / PAGE_SIZE + 1; + if (i_size_read(file->f_mapping->host) < bytes + sizeof(bitmap_super_t)) { printk(KERN_INFO "%s: bitmap file too short %lu < %lu\n", bmname(bitmap), @@ -789,18 +791,16 @@ static int bitmap_init_from_disk(struct bitmap *bitmap) bytes + sizeof(bitmap_super_t)); goto out; } - num_pages++; + + ret = -ENOMEM; + bitmap->filemap = kmalloc(sizeof(struct page *) * num_pages, GFP_KERNEL); - if (!bitmap->filemap) { - ret = -ENOMEM; + if (!bitmap->filemap) goto out; - } bitmap->filemap_attr = kmalloc(sizeof(long) * num_pages, GFP_KERNEL); - if (!bitmap->filemap_attr) { - ret = -ENOMEM; + if (!bitmap->filemap_attr) goto out; - } memset(bitmap->filemap_attr, 0, sizeof(long) * num_pages); -- cgit v1.2.3-59-g8ed1b From cdbb4cc2e5c30895709163d8544057db21ee23e0 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:18 -0700 Subject: [PATCH] md: make sure md bitmap is cleared on a clean start. As the array-wide clean bit (in the superblock) is set more agressively than the bits in the bitmap are cleared, it is possible to have an array which is clean despite there being bits set in the bitmap. These bits will currently never get cleared, as they can only be cleared by a resync pass, which never happens. No, when reading bits from disk, be aware of whether the whole array is known to be in sync, and act accordingly. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/bitmap.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 62fac2b38000..275a2aa79b79 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -747,7 +747,7 @@ int bitmap_unplug(struct bitmap *bitmap) } static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, - unsigned long sectors, int set); + unsigned long sectors, int in_sync); /* * bitmap_init_from_disk -- called at bitmap_create time to initialize * the in-memory bitmap from the on-disk bitmap -- also, sets up the * memory mapping of the bitmap file @@ -756,7 +756,7 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, * previously kicked from the array, we mark all the bits as * 1's in order to cause a full resync. */ -static int bitmap_init_from_disk(struct bitmap *bitmap) +static int bitmap_init_from_disk(struct bitmap *bitmap, int in_sync) { unsigned long i, chunks, index, oldindex, bit; struct page *page = NULL, *oldpage = NULL; @@ -782,7 +782,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap) bytes = (chunks + 7) / 8; - num_pages = (bytes + sizeof(bitmap_super_t) + PAGE_SIZE - 1) / PAGE_SIZE + 1; + num_pages = (bytes + sizeof(bitmap_super_t) + PAGE_SIZE - 1) / PAGE_SIZE; if (i_size_read(file->f_mapping->host) < bytes + sizeof(bitmap_super_t)) { printk(KERN_INFO "%s: bitmap file too short %lu < %lu\n", @@ -854,14 +854,9 @@ static int bitmap_init_from_disk(struct bitmap *bitmap) if (test_bit(bit, page_address(page))) { /* if the disk bit is set, set the memory bit */ bitmap_set_memory_bits(bitmap, - i << CHUNK_BLOCK_SHIFT(bitmap), 1, 1); + i << CHUNK_BLOCK_SHIFT(bitmap), 1, in_sync); bit_cnt++; } -#if 0 - else - bitmap_set_memory_bits(bitmap, - i << CHUNK_BLOCK_SHIFT(bitmap), 1, 0); -#endif } /* everything went OK */ @@ -1331,10 +1326,10 @@ void bitmap_close_sync(struct bitmap *bitmap) } static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, - unsigned long sectors, int set) + unsigned long sectors, int in_sync) { /* For each chunk covered by any of these sectors, set the - * resync needed bit, and the counter to 1. They should all + * counter to 1 and set resync_needed unless in_sync. They should all * be 0 at this point */ while (sectors) { @@ -1346,10 +1341,12 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, spin_unlock_irq(&bitmap->lock); return; } - if (set && !NEEDED(*bmc)) { - BUG_ON(*bmc); - *bmc = NEEDED_MASK | 1; + if (! *bmc) { + struct page *page; + *bmc = 1 | (in_sync? 0 : NEEDED_MASK); bitmap_count_page(bitmap, offset, 1); + page = filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap)); + set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); } spin_unlock_irq(&bitmap->lock); if (sectors > secs) @@ -1489,7 +1486,7 @@ int bitmap_create(mddev_t *mddev) /* now that we have some pages available, initialize the in-memory * bitmap from the on-disk bitmap */ - err = bitmap_init_from_disk(bitmap); + err = bitmap_init_from_disk(bitmap, mddev->recovery_cp == MaxSector); if (err) return err; -- cgit v1.2.3-59-g8ed1b From fc7ca163a448dfb23f44c9a47ebc8cbe52cf49df Mon Sep 17 00:00:00 2001 From: "akpm@osdl.org" Date: Tue, 21 Jun 2005 17:17:19 -0700 Subject: [PATCH] md printk fix A u64 is not an unsigned long long. On power4 it is `long', and printk warns. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/bitmap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 275a2aa79b79..dd84e15fcaea 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -377,7 +377,8 @@ void bitmap_print_sb(struct bitmap *bitmap) printk(KERN_DEBUG " state: %08x\n", le32_to_cpu(sb->state)); printk(KERN_DEBUG " chunksize: %d B\n", le32_to_cpu(sb->chunksize)); printk(KERN_DEBUG "daemon sleep: %ds\n", le32_to_cpu(sb->daemon_sleep)); - printk(KERN_DEBUG " sync size: %llu KB\n", le64_to_cpu(sb->sync_size)); + printk(KERN_DEBUG " sync size: %llu KB\n", + (unsigned long long)le64_to_cpu(sb->sync_size)); kunmap(bitmap->sb_page); } -- cgit v1.2.3-59-g8ed1b From a2cff26ad18a8794722fb0d3c019d93e14fce3f1 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:20 -0700 Subject: [PATCH] md: improve debug-printing of bitmap superblock. - report sync_size properly - need /2 to convert sectors to KB - move everything over 2 spaces to allow proper spelling of "events cleared". Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/bitmap.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index dd84e15fcaea..f197db2ef92d 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -363,22 +363,22 @@ void bitmap_print_sb(struct bitmap *bitmap) return; sb = (bitmap_super_t *)kmap(bitmap->sb_page); printk(KERN_DEBUG "%s: bitmap file superblock:\n", bmname(bitmap)); - printk(KERN_DEBUG " magic: %08x\n", le32_to_cpu(sb->magic)); - printk(KERN_DEBUG " version: %d\n", le32_to_cpu(sb->version)); - printk(KERN_DEBUG " uuid: %08x.%08x.%08x.%08x\n", + printk(KERN_DEBUG " magic: %08x\n", le32_to_cpu(sb->magic)); + printk(KERN_DEBUG " version: %d\n", le32_to_cpu(sb->version)); + printk(KERN_DEBUG " uuid: %08x.%08x.%08x.%08x\n", *(__u32 *)(sb->uuid+0), *(__u32 *)(sb->uuid+4), *(__u32 *)(sb->uuid+8), *(__u32 *)(sb->uuid+12)); - printk(KERN_DEBUG " events: %llu\n", + printk(KERN_DEBUG " events: %llu\n", (unsigned long long) le64_to_cpu(sb->events)); - printk(KERN_DEBUG "events_clred: %llu\n", + printk(KERN_DEBUG "events cleared: %llu\n", (unsigned long long) le64_to_cpu(sb->events_cleared)); - printk(KERN_DEBUG " state: %08x\n", le32_to_cpu(sb->state)); - printk(KERN_DEBUG " chunksize: %d B\n", le32_to_cpu(sb->chunksize)); - printk(KERN_DEBUG "daemon sleep: %ds\n", le32_to_cpu(sb->daemon_sleep)); - printk(KERN_DEBUG " sync size: %llu KB\n", - (unsigned long long)le64_to_cpu(sb->sync_size)); + printk(KERN_DEBUG " state: %08x\n", le32_to_cpu(sb->state)); + printk(KERN_DEBUG " chunksize: %d B\n", le32_to_cpu(sb->chunksize)); + printk(KERN_DEBUG " daemon sleep: %ds\n", le32_to_cpu(sb->daemon_sleep)); + printk(KERN_DEBUG " sync size: %llu KB\n", + (unsigned long long)le64_to_cpu(sb->sync_size)/2); kunmap(bitmap->sb_page); } -- cgit v1.2.3-59-g8ed1b From bfb39fba4e8cdda091f9ebee29fbb8331c4bb605 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:20 -0700 Subject: [PATCH] md: check return value of write_page, rather than ignore it Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/bitmap.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index f197db2ef92d..9462fdd517c0 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -350,8 +350,7 @@ int bitmap_update_sb(struct bitmap *bitmap) if (!bitmap->mddev->degraded) sb->events_cleared = cpu_to_le64(bitmap->mddev->events); kunmap(bitmap->sb_page); - write_page(bitmap->sb_page, 0); - return 0; + return write_page(bitmap->sb_page, 0); } /* print out the bitmap file superblock */ @@ -735,7 +734,8 @@ int bitmap_unplug(struct bitmap *bitmap) spin_unlock_irqrestore(&bitmap->lock, flags); if (attr & (BITMAP_PAGE_DIRTY | BITMAP_PAGE_NEEDWRITE)) - write_page(page, 0); + if (write_page(page, 0)) + return 1; } if (wait) { /* if any writes were performed, we need to wait on them */ spin_lock_irq(&bitmap->write_lock); @@ -950,7 +950,7 @@ int bitmap_daemon_work(struct bitmap *bitmap) if (get_page_attr(bitmap, lastpage) & BITMAP_PAGE_NEEDWRITE) { clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); spin_unlock_irqrestore(&bitmap->lock, flags); - write_page(lastpage, 0); + err = write_page(lastpage, 0); } else { set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); spin_unlock_irqrestore(&bitmap->lock, flags); @@ -998,7 +998,7 @@ int bitmap_daemon_work(struct bitmap *bitmap) if (get_page_attr(bitmap, lastpage) &BITMAP_PAGE_NEEDWRITE) { clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); spin_unlock_irqrestore(&bitmap->lock, flags); - write_page(lastpage, 0); + err = write_page(lastpage, 0); } else { set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); spin_unlock_irqrestore(&bitmap->lock, flags); @@ -1375,7 +1375,8 @@ int bitmap_setallbits(struct bitmap *bitmap) spin_unlock_irqrestore(&bitmap->lock, flags); memset(kmap(page), 0xff, PAGE_SIZE); kunmap(page); - write_page(page, 0); + if (write_page(page, 0)) + return 1; } return 0; -- cgit v1.2.3-59-g8ed1b From 77ad4bc706fe6c52ab953f31c287a6af712d080c Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:21 -0700 Subject: [PATCH] md: enable the bitmap write-back daemon and wait for it. Currently we don't wait for updates to the bitmap to be flushed to disk properly. The infrastructure all there, but it isn't being used.... A separate kernel thread (bitmap_writeback_daemon) is needed to wait for each page as we cannot get callbacks when a page write completes. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/bitmap.c | 119 ++++++++++++++++++++------------------------ include/linux/raid/bitmap.h | 13 +---- 2 files changed, 55 insertions(+), 77 deletions(-) diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 9462fdd517c0..86b6b037fa44 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -261,30 +261,33 @@ char *file_path(struct file *file, char *buf, int count) /* * write out a page */ -static int write_page(struct page *page, int wait) +static int write_page(struct bitmap *bitmap, struct page *page, int wait) { int ret = -ENOMEM; lock_page(page); - if (page->mapping == NULL) - goto unlock_out; - else if (i_size_read(page->mapping->host) < page->index << PAGE_SHIFT) { - ret = -ENOENT; - goto unlock_out; - } - ret = page->mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE); if (!ret) ret = page->mapping->a_ops->commit_write(NULL, page, 0, PAGE_SIZE); if (ret) { -unlock_out: unlock_page(page); return ret; } set_page_dirty(page); /* force it to be written out */ + + if (!wait) { + /* add to list to be waited for by daemon */ + struct page_list *item = mempool_alloc(bitmap->write_pool, GFP_NOIO); + item->page = page; + page_cache_get(page); + spin_lock(&bitmap->write_lock); + list_add(&item->list, &bitmap->complete_pages); + spin_unlock(&bitmap->write_lock); + md_wakeup_thread(bitmap->writeback_daemon); + } return write_one_page(page, wait); } @@ -343,14 +346,13 @@ int bitmap_update_sb(struct bitmap *bitmap) spin_unlock_irqrestore(&bitmap->lock, flags); return 0; } - page_cache_get(bitmap->sb_page); spin_unlock_irqrestore(&bitmap->lock, flags); sb = (bitmap_super_t *)kmap(bitmap->sb_page); sb->events = cpu_to_le64(bitmap->mddev->events); if (!bitmap->mddev->degraded) sb->events_cleared = cpu_to_le64(bitmap->mddev->events); kunmap(bitmap->sb_page); - return write_page(bitmap->sb_page, 0); + return write_page(bitmap, bitmap->sb_page, 0); } /* print out the bitmap file superblock */ @@ -556,10 +558,10 @@ static void bitmap_file_unmap(struct bitmap *bitmap) static void bitmap_stop_daemons(struct bitmap *bitmap); /* dequeue the next item in a page list -- don't call from irq context */ -static struct page_list *dequeue_page(struct bitmap *bitmap, - struct list_head *head) +static struct page_list *dequeue_page(struct bitmap *bitmap) { struct page_list *item = NULL; + struct list_head *head = &bitmap->complete_pages; spin_lock(&bitmap->write_lock); if (list_empty(head)) @@ -573,23 +575,15 @@ out: static void drain_write_queues(struct bitmap *bitmap) { - struct list_head *queues[] = { &bitmap->complete_pages, NULL }; - struct list_head *head; struct page_list *item; - int i; - for (i = 0; queues[i]; i++) { - head = queues[i]; - while ((item = dequeue_page(bitmap, head))) { - page_cache_release(item->page); - mempool_free(item, bitmap->write_pool); - } + while ((item = dequeue_page(bitmap))) { + /* don't bother to wait */ + page_cache_release(item->page); + mempool_free(item, bitmap->write_pool); } - spin_lock(&bitmap->write_lock); - bitmap->writes_pending = 0; /* make sure waiters continue */ wake_up(&bitmap->write_wait); - spin_unlock(&bitmap->write_lock); } static void bitmap_file_put(struct bitmap *bitmap) @@ -734,13 +728,13 @@ int bitmap_unplug(struct bitmap *bitmap) spin_unlock_irqrestore(&bitmap->lock, flags); if (attr & (BITMAP_PAGE_DIRTY | BITMAP_PAGE_NEEDWRITE)) - if (write_page(page, 0)) + if (write_page(bitmap, page, 0)) return 1; } if (wait) { /* if any writes were performed, we need to wait on them */ spin_lock_irq(&bitmap->write_lock); wait_event_lock_irq(bitmap->write_wait, - bitmap->writes_pending == 0, bitmap->write_lock, + list_empty(&bitmap->complete_pages), bitmap->write_lock, wake_up_process(bitmap->writeback_daemon->tsk)); spin_unlock_irq(&bitmap->write_lock); } @@ -841,7 +835,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, int in_sync) */ memset(page_address(page) + offset, 0xff, PAGE_SIZE - offset); - ret = write_page(page, 1); + ret = write_page(bitmap, page, 1); if (ret) { kunmap(page); /* release, page not in filemap yet */ @@ -934,7 +928,7 @@ int bitmap_daemon_work(struct bitmap *bitmap) } spin_unlock_irqrestore(&bitmap->lock, flags); if (attr & BITMAP_PAGE_NEEDWRITE) { - if (write_page(page, 0)) + if (write_page(bitmap, page, 0)) bitmap_file_kick(bitmap); page_cache_release(page); } @@ -950,7 +944,7 @@ int bitmap_daemon_work(struct bitmap *bitmap) if (get_page_attr(bitmap, lastpage) & BITMAP_PAGE_NEEDWRITE) { clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); spin_unlock_irqrestore(&bitmap->lock, flags); - err = write_page(lastpage, 0); + err = write_page(bitmap, lastpage, 0); } else { set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); spin_unlock_irqrestore(&bitmap->lock, flags); @@ -998,7 +992,7 @@ int bitmap_daemon_work(struct bitmap *bitmap) if (get_page_attr(bitmap, lastpage) &BITMAP_PAGE_NEEDWRITE) { clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); spin_unlock_irqrestore(&bitmap->lock, flags); - err = write_page(lastpage, 0); + err = write_page(bitmap, lastpage, 0); } else { set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); spin_unlock_irqrestore(&bitmap->lock, flags); @@ -1034,46 +1028,40 @@ static void bitmap_writeback_daemon(mddev_t *mddev) struct page_list *item; int err = 0; - while (1) { - PRINTK("%s: bitmap writeback daemon waiting...\n", bmname(bitmap)); - down_interruptible(&bitmap->write_done); - if (signal_pending(current)) { - printk(KERN_INFO - "%s: bitmap writeback daemon got signal, exiting...\n", - bmname(bitmap)); - break; - } + if (signal_pending(current)) { + printk(KERN_INFO + "%s: bitmap writeback daemon got signal, exiting...\n", + bmname(bitmap)); + err = -EINTR; + goto out; + } - PRINTK("%s: bitmap writeback daemon woke up...\n", bmname(bitmap)); - /* wait on bitmap page writebacks */ - while ((item = dequeue_page(bitmap, &bitmap->complete_pages))) { - page = item->page; - mempool_free(item, bitmap->write_pool); - PRINTK("wait on page writeback: %p %lu\n", page, bitmap->writes_pending); - wait_on_page_writeback(page); - PRINTK("finished page writeback: %p %lu\n", page, bitmap->writes_pending); - spin_lock(&bitmap->write_lock); - if (!--bitmap->writes_pending) - wake_up(&bitmap->write_wait); - spin_unlock(&bitmap->write_lock); - err = PageError(page); - page_cache_release(page); - if (err) { - printk(KERN_WARNING "%s: bitmap file writeback " - "failed (page %lu): %d\n", - bmname(bitmap), page->index, err); - bitmap_file_kick(bitmap); - goto out; - } + PRINTK("%s: bitmap writeback daemon woke up...\n", bmname(bitmap)); + /* wait on bitmap page writebacks */ + while ((item = dequeue_page(bitmap))) { + page = item->page; + mempool_free(item, bitmap->write_pool); + PRINTK("wait on page writeback: %p\n", page); + wait_on_page_writeback(page); + PRINTK("finished page writeback: %p\n", page); + + err = PageError(page); + page_cache_release(page); + if (err) { + printk(KERN_WARNING "%s: bitmap file writeback " + "failed (page %lu): %d\n", + bmname(bitmap), page->index, err); + bitmap_file_kick(bitmap); + goto out; } } -out: + out: + wake_up(&bitmap->write_wait); if (err) { printk(KERN_INFO "%s: bitmap writeback daemon exiting (%d)\n", - bmname(bitmap), err); + bmname(bitmap), err); daemon_exit(bitmap, &bitmap->writeback_daemon); } - return; } static int bitmap_start_daemon(struct bitmap *bitmap, mdk_thread_t **ptr, @@ -1375,7 +1363,7 @@ int bitmap_setallbits(struct bitmap *bitmap) spin_unlock_irqrestore(&bitmap->lock, flags); memset(kmap(page), 0xff, PAGE_SIZE); kunmap(page); - if (write_page(page, 0)) + if (write_page(bitmap, page, 0)) return 1; } @@ -1443,7 +1431,6 @@ int bitmap_create(mddev_t *mddev) mddev->bitmap = bitmap; spin_lock_init(&bitmap->write_lock); - init_MUTEX_LOCKED(&bitmap->write_done); INIT_LIST_HEAD(&bitmap->complete_pages); init_waitqueue_head(&bitmap->write_wait); bitmap->write_pool = mempool_create(WRITE_POOL_SIZE, write_pool_alloc, diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h index f785cf26cbad..cfe60cfc8f3d 100644 --- a/include/linux/raid/bitmap.h +++ b/include/linux/raid/bitmap.h @@ -233,21 +233,12 @@ struct bitmap { unsigned long daemon_sleep; /* how many seconds between updates? */ /* - * bitmap write daemon - this daemon performs writes to the bitmap file - * this thread is only needed because of a limitation in ext3 (jbd) - * that does not allow a task to have two journal transactions ongoing - * simultaneously (even if the transactions are for two different - * filesystems) -- in the case of bitmap, that would be the filesystem - * that the bitmap file resides on and the filesystem that is mounted - * on the md device -- see current->journal_info in jbd/transaction.c + * bitmap_writeback_daemon waits for file-pages that have been written, + * as there is no way to get a call-back when a page write completes. */ mdk_thread_t *writeback_daemon; spinlock_t write_lock; - struct semaphore write_ready; - struct semaphore write_done; - unsigned long writes_pending; wait_queue_head_t write_wait; - struct list_head write_pages; struct list_head complete_pages; mempool_t *write_pool; }; -- cgit v1.2.3-59-g8ed1b From aa3163f81654fa057039258e32a6811147bf0c14 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:22 -0700 Subject: [PATCH] md: don't skip bitmap pages due to lack of bit that we just cleared. When looking for pages that need cleaning we skip pages that don't have BITMAP_PAGE_CLEAN set. But if it is the 'current' page we will have cleared that bit ourselves, so skipping it is wrong. So: move the 'skip this page' inside 'if page != lastpage'. Also fold call of file_page_offset into the one place where the value (bit) is used. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/bitmap.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 86b6b037fa44..204564dc6a0d 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -897,7 +897,7 @@ static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, int bitmap_daemon_work(struct bitmap *bitmap) { - unsigned long bit, j; + unsigned long j; unsigned long flags; struct page *page = NULL, *lastpage = NULL; int err = 0; @@ -920,24 +920,23 @@ int bitmap_daemon_work(struct bitmap *bitmap) } page = filemap_get_page(bitmap, j); - /* skip this page unless it's marked as needing cleaning */ - if (!((attr=get_page_attr(bitmap, page)) & BITMAP_PAGE_CLEAN)) { - if (attr & BITMAP_PAGE_NEEDWRITE) { - page_cache_get(page); - clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE); - } - spin_unlock_irqrestore(&bitmap->lock, flags); - if (attr & BITMAP_PAGE_NEEDWRITE) { - if (write_page(bitmap, page, 0)) - bitmap_file_kick(bitmap); - page_cache_release(page); - } - continue; - } - - bit = file_page_offset(j); if (page != lastpage) { + /* skip this page unless it's marked as needing cleaning */ + if (!((attr=get_page_attr(bitmap, page)) & BITMAP_PAGE_CLEAN)) { + if (attr & BITMAP_PAGE_NEEDWRITE) { + page_cache_get(page); + clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE); + } + spin_unlock_irqrestore(&bitmap->lock, flags); + if (attr & BITMAP_PAGE_NEEDWRITE) { + if (write_page(bitmap, page, 0)) + bitmap_file_kick(bitmap); + page_cache_release(page); + } + continue; + } + /* grab the new page, sync and release the old */ page_cache_get(page); if (lastpage != NULL) { @@ -979,7 +978,7 @@ int bitmap_daemon_work(struct bitmap *bitmap) -1); /* clear the bit */ - clear_bit(bit, page_address(page)); + clear_bit(file_page_offset(j), page_address(page)); } } spin_unlock_irqrestore(&bitmap->lock, flags); -- cgit v1.2.3-59-g8ed1b From 191ea9b2c7cc3ebbe0678834ab710d7d95ad3f9a Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:23 -0700 Subject: [PATCH] md: raid1 support for bitmap intent logging Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/raid1.c | 182 ++++++++++++++++++++++++++++++++++++++------- include/linux/raid/raid1.h | 16 +++- 2 files changed, 168 insertions(+), 30 deletions(-) diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 3c5c916cb09e..0fd4c3bfc851 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -12,6 +12,15 @@ * Fixes to reconstruction by Jakob Østergaard" * Various fixes by Neil Brown * + * Changes by Peter T. Breuer 31/1/2003 to support + * bitmapped intelligence in resync: + * + * - bitmap marked during normal i/o + * - bitmap used to skip nondirty blocks during sync + * + * Additions to bitmap code, (C) 2003-2004 Paul Clements, SteelEye Technology: + * - persistent bitmap code + * * 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) @@ -22,7 +31,16 @@ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "dm-bio-list.h" #include +#include + +#define DEBUG 0 +#if DEBUG +#define PRINTK(x...) printk(x) +#else +#define PRINTK(x...) +#endif /* * Number of guaranteed r1bios in case of extreme VM load: @@ -287,9 +305,11 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int /* * this branch is our 'one mirror IO has finished' event handler: */ - if (!uptodate) + if (!uptodate) { md_error(r1_bio->mddev, conf->mirrors[mirror].rdev); - else + /* an I/O failed, we can't clear the bitmap */ + set_bit(R1BIO_Degraded, &r1_bio->state); + } else /* * Set R1BIO_Uptodate in our master bio, so that * we will return a good error code for to the higher @@ -309,6 +329,10 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int * already. */ if (atomic_dec_and_test(&r1_bio->remaining)) { + /* clear the bitmap if all writes complete successfully */ + bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector, + r1_bio->sectors, + !test_bit(R1BIO_Degraded, &r1_bio->state)); md_write_end(r1_bio->mddev); raid_end_bio_io(r1_bio); } @@ -458,7 +482,10 @@ static void unplug_slaves(mddev_t *mddev) static void raid1_unplug(request_queue_t *q) { - unplug_slaves(q->queuedata); + mddev_t *mddev = q->queuedata; + + unplug_slaves(mddev); + md_wakeup_thread(mddev->thread); } static int raid1_issue_flush(request_queue_t *q, struct gendisk *disk, @@ -501,16 +528,16 @@ static void device_barrier(conf_t *conf, sector_t sect) { spin_lock_irq(&conf->resync_lock); wait_event_lock_irq(conf->wait_idle, !waitqueue_active(&conf->wait_resume), - conf->resync_lock, unplug_slaves(conf->mddev)); + conf->resync_lock, raid1_unplug(conf->mddev->queue)); if (!conf->barrier++) { wait_event_lock_irq(conf->wait_idle, !conf->nr_pending, - conf->resync_lock, unplug_slaves(conf->mddev)); + conf->resync_lock, raid1_unplug(conf->mddev->queue)); if (conf->nr_pending) BUG(); } wait_event_lock_irq(conf->wait_resume, conf->barrier < RESYNC_DEPTH, - conf->resync_lock, unplug_slaves(conf->mddev)); + conf->resync_lock, raid1_unplug(conf->mddev->queue)); conf->next_resync = sect; spin_unlock_irq(&conf->resync_lock); } @@ -522,8 +549,12 @@ static int make_request(request_queue_t *q, struct bio * bio) mirror_info_t *mirror; r1bio_t *r1_bio; struct bio *read_bio; - int i, disks; + int i, targets = 0, disks; mdk_rdev_t *rdev; + struct bitmap *bitmap = mddev->bitmap; + unsigned long flags; + struct bio_list bl; + /* * Register the new request and wait if the reconstruction @@ -554,7 +585,7 @@ static int make_request(request_queue_t *q, struct bio * bio) r1_bio->master_bio = bio; r1_bio->sectors = bio->bi_size >> 9; - + r1_bio->state = 0; r1_bio->mddev = mddev; r1_bio->sector = bio->bi_sector; @@ -597,6 +628,13 @@ static int make_request(request_queue_t *q, struct bio * bio) * bios[x] to bio */ disks = conf->raid_disks; +#if 0 + { static int first=1; + if (first) printk("First Write sector %llu disks %d\n", + (unsigned long long)r1_bio->sector, disks); + first = 0; + } +#endif rcu_read_lock(); for (i = 0; i < disks; i++) { if ((rdev=conf->mirrors[i].rdev) != NULL && @@ -607,13 +645,21 @@ static int make_request(request_queue_t *q, struct bio * bio) r1_bio->bios[i] = NULL; } else r1_bio->bios[i] = bio; + targets++; } else r1_bio->bios[i] = NULL; } rcu_read_unlock(); - atomic_set(&r1_bio->remaining, 1); + if (targets < conf->raid_disks) { + /* array is degraded, we will not clear the bitmap + * on I/O completion (see raid1_end_write_request) */ + set_bit(R1BIO_Degraded, &r1_bio->state); + } + + atomic_set(&r1_bio->remaining, 0); + bio_list_init(&bl); for (i = 0; i < disks; i++) { struct bio *mbio; if (!r1_bio->bios[i]) @@ -629,14 +675,23 @@ static int make_request(request_queue_t *q, struct bio * bio) mbio->bi_private = r1_bio; atomic_inc(&r1_bio->remaining); - generic_make_request(mbio); - } - if (atomic_dec_and_test(&r1_bio->remaining)) { - md_write_end(mddev); - raid_end_bio_io(r1_bio); + bio_list_add(&bl, mbio); } + bitmap_startwrite(bitmap, bio->bi_sector, r1_bio->sectors); + spin_lock_irqsave(&conf->device_lock, flags); + bio_list_merge(&conf->pending_bio_list, &bl); + bio_list_init(&bl); + + blk_plug_device(mddev->queue); + spin_unlock_irqrestore(&conf->device_lock, flags); + +#if 0 + while ((bio = bio_list_pop(&bl)) != NULL) + generic_make_request(bio); +#endif + return 0; } @@ -716,7 +771,7 @@ static void close_sync(conf_t *conf) { spin_lock_irq(&conf->resync_lock); wait_event_lock_irq(conf->wait_resume, !conf->barrier, - conf->resync_lock, unplug_slaves(conf->mddev)); + conf->resync_lock, raid1_unplug(conf->mddev->queue)); spin_unlock_irq(&conf->resync_lock); if (conf->barrier) BUG(); @@ -830,10 +885,11 @@ static int end_sync_read(struct bio *bio, unsigned int bytes_done, int error) * or re-read if the read failed. * We don't do much here, just schedule handling by raid1d */ - if (!uptodate) + if (!uptodate) { md_error(r1_bio->mddev, conf->mirrors[r1_bio->read_disk].rdev); - else + set_bit(R1BIO_Degraded, &r1_bio->state); + } else set_bit(R1BIO_Uptodate, &r1_bio->state); rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev); reschedule_retry(r1_bio); @@ -857,8 +913,10 @@ static int end_sync_write(struct bio *bio, unsigned int bytes_done, int error) mirror = i; break; } - if (!uptodate) + if (!uptodate) { md_error(mddev, conf->mirrors[mirror].rdev); + set_bit(R1BIO_Degraded, &r1_bio->state); + } update_head_pos(mirror, r1_bio); if (atomic_dec_and_test(&r1_bio->remaining)) { @@ -878,6 +936,9 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) bio = r1_bio->bios[r1_bio->read_disk]; +/* + if (r1_bio->sector == 0) printk("First sync write startss\n"); +*/ /* * schedule writes */ @@ -905,10 +966,12 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) atomic_inc(&conf->mirrors[i].rdev->nr_pending); atomic_inc(&r1_bio->remaining); md_sync_acct(conf->mirrors[i].rdev->bdev, wbio->bi_size >> 9); + generic_make_request(wbio); } if (atomic_dec_and_test(&r1_bio->remaining)) { + /* if we're here, all write(s) have completed, so clean up */ md_done_sync(mddev, r1_bio->sectors, 1); put_buf(r1_bio); } @@ -937,6 +1000,26 @@ static void raid1d(mddev_t *mddev) for (;;) { char b[BDEVNAME_SIZE]; spin_lock_irqsave(&conf->device_lock, flags); + + if (conf->pending_bio_list.head) { + bio = bio_list_get(&conf->pending_bio_list); + blk_remove_plug(mddev->queue); + spin_unlock_irqrestore(&conf->device_lock, flags); + /* flush any pending bitmap writes to disk before proceeding w/ I/O */ + if (bitmap_unplug(mddev->bitmap) != 0) + printk("%s: bitmap file write failed!\n", mdname(mddev)); + + while (bio) { /* submit pending writes */ + struct bio *next = bio->bi_next; + bio->bi_next = NULL; + generic_make_request(bio); + bio = next; + } + unplug = 1; + + continue; + } + if (list_empty(head)) break; r1_bio = list_entry(head->prev, r1bio_t, retry_list); @@ -1020,17 +1103,43 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i int disk; int i; int write_targets = 0; + int sync_blocks; if (!conf->r1buf_pool) + { +/* + printk("sync start - bitmap %p\n", mddev->bitmap); +*/ if (init_resync(conf)) return 0; + } max_sector = mddev->size << 1; if (sector_nr >= max_sector) { + /* If we aborted, we need to abort the + * sync on the 'current' bitmap chunk (there will + * only be one in raid1 resync. + * We can find the current addess in mddev->curr_resync + */ + if (!conf->fullsync) { + if (mddev->curr_resync < max_sector) + bitmap_end_sync(mddev->bitmap, + mddev->curr_resync, + &sync_blocks, 1); + bitmap_close_sync(mddev->bitmap); + } + if (mddev->curr_resync >= max_sector) + conf->fullsync = 0; close_sync(conf); return 0; } + if (!conf->fullsync && + !bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks)) { + /* We can skip this block, and probably several more */ + *skipped = 1; + return sync_blocks; + } /* * If there is non-resync activity waiting for us then * put in a delay to throttle resync. @@ -1069,6 +1178,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i r1_bio->mddev = mddev; r1_bio->sector = sector_nr; + r1_bio->state = 0; set_bit(R1BIO_IsSync, &r1_bio->state); r1_bio->read_disk = disk; @@ -1103,6 +1213,11 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i bio->bi_bdev = conf->mirrors[i].rdev->bdev; bio->bi_private = r1_bio; } + + if (write_targets + 1 < conf->raid_disks) + /* array degraded, can't clear bitmap */ + set_bit(R1BIO_Degraded, &r1_bio->state); + if (write_targets == 0) { /* There is nowhere to write, so all non-sync * drives must be failed - so we are finished @@ -1122,6 +1237,14 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i len = (max_sector - sector_nr) << 9; if (len == 0) break; + if (!conf->fullsync && sync_blocks == 0) + if (!bitmap_start_sync(mddev->bitmap, + sector_nr, &sync_blocks)) + break; + if (sync_blocks < (PAGE_SIZE>>9)) + BUG(); + if (len > (sync_blocks<<9)) len = sync_blocks<<9; + for (i=0 ; i < conf->raid_disks; i++) { bio = r1_bio->bios[i]; if (bio->bi_end_io) { @@ -1144,6 +1267,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i } nr_sectors += len>>9; sector_nr += len>>9; + sync_blocks -= (len>>9); } while (r1_bio->bios[disk]->bi_vcnt < RESYNC_PAGES); bio_full: bio = r1_bio->bios[disk]; @@ -1232,6 +1356,9 @@ static int run(mddev_t *mddev) init_waitqueue_head(&conf->wait_idle); init_waitqueue_head(&conf->wait_resume); + bio_list_init(&conf->pending_bio_list); + bio_list_init(&conf->flushing_bio_list); + if (!conf->working_disks) { printk(KERN_ERR "raid1: no operational mirrors for %s\n", mdname(mddev)); @@ -1260,16 +1387,15 @@ static int run(mddev_t *mddev) conf->last_used = j; - - { - mddev->thread = md_register_thread(raid1d, mddev, "%s_raid1"); - if (!mddev->thread) { - printk(KERN_ERR - "raid1: couldn't allocate thread for %s\n", - mdname(mddev)); - goto out_free_conf; - } + mddev->thread = md_register_thread(raid1d, mddev, "%s_raid1"); + if (!mddev->thread) { + printk(KERN_ERR + "raid1: couldn't allocate thread for %s\n", + mdname(mddev)); + goto out_free_conf; } + if (mddev->bitmap) mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ; + printk(KERN_INFO "raid1: raid set %s active with %d out of %d mirrors\n", mdname(mddev), mddev->raid_disks - mddev->degraded, @@ -1394,7 +1520,7 @@ static int raid1_reshape(mddev_t *mddev, int raid_disks) spin_lock_irq(&conf->resync_lock); conf->barrier++; wait_event_lock_irq(conf->wait_idle, !conf->nr_pending, - conf->resync_lock, unplug_slaves(mddev)); + conf->resync_lock, raid1_unplug(mddev->queue)); spin_unlock_irq(&conf->resync_lock); /* ok, everything is stopped */ diff --git a/include/linux/raid/raid1.h b/include/linux/raid/raid1.h index abbfdd9afe1e..9d93cf12e890 100644 --- a/include/linux/raid/raid1.h +++ b/include/linux/raid/raid1.h @@ -36,12 +36,21 @@ struct r1_private_data_s { spinlock_t device_lock; struct list_head retry_list; + /* queue pending writes and submit them on unplug */ + struct bio_list pending_bio_list; + /* queue of writes that have been unplugged */ + struct bio_list flushing_bio_list; + /* for use when syncing mirrors: */ spinlock_t resync_lock; - int nr_pending; - int barrier; + int nr_pending; + int barrier; sector_t next_resync; + int fullsync; /* set to 1 if a full sync is needed, + * (fresh device added). + * Cleared when a sync completes. + */ wait_queue_head_t wait_idle; wait_queue_head_t wait_resume; @@ -85,14 +94,17 @@ struct r1bio_s { int read_disk; struct list_head retry_list; + struct bitmap_update *bitmap_update; /* * if the IO is in WRITE direction, then multiple bios are used. * We choose the number when they are allocated. */ struct bio *bios[0]; + /* DO NOT PUT ANY NEW FIELDS HERE - bios array is contiguously alloced*/ }; /* bits for r1bio.state */ #define R1BIO_Uptodate 0 #define R1BIO_IsSync 1 +#define R1BIO_Degraded 2 #endif -- cgit v1.2.3-59-g8ed1b From ab7a30c7051ee32d0d72415fe0a16d60eba38a0d Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:23 -0700 Subject: [PATCH] md: fix bug when raid1 attempts a partial reconstruct. The logic here is wrong. if fullsync is 0, it WILL BUG. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/raid1.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 0fd4c3bfc851..9d9acc3e51a7 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1237,13 +1237,16 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i len = (max_sector - sector_nr) << 9; if (len == 0) break; - if (!conf->fullsync && sync_blocks == 0) - if (!bitmap_start_sync(mddev->bitmap, - sector_nr, &sync_blocks)) - break; - if (sync_blocks < (PAGE_SIZE>>9)) - BUG(); - if (len > (sync_blocks<<9)) len = sync_blocks<<9; + if (!conf->fullsync) { + if (sync_blocks == 0) { + if (!bitmap_start_sync(mddev->bitmap, + sector_nr, &sync_blocks)) + break; + if (sync_blocks < (PAGE_SIZE>>9)) + BUG(); + if (len > (sync_blocks<<9)) len = sync_blocks<<9; + } + } for (i=0 ; i < conf->raid_disks; i++) { bio = r1_bio->bios[i]; -- cgit v1.2.3-59-g8ed1b From 289e99e8ed8f36e386bf7de49947311c17ae1482 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:24 -0700 Subject: [PATCH] md: initialise sync_blocks in raid1 resync Otherwise it could have a random value and might BUG. This fixes a BUG during resync problem in raid1 introduced by the bitmap-based-intent-loggin patches. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/raid1.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 9d9acc3e51a7..c3b4772cfaea 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1230,6 +1230,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i } nr_sectors = 0; + sync_blocks = 0; do { struct page *page; int len = PAGE_SIZE; -- cgit v1.2.3-59-g8ed1b From 41158c7eb22312cfaa256744e1553bb4042ff085 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:25 -0700 Subject: [PATCH] md: optimise reconstruction when re-adding a recently failed drive. When an array is degraded, bit in the intent-bitmap are never cleared. So if a recently failed drive is re-added, we only need to reconstruct the block that are still reflected in the bitmap. This patch adds support for this re-adding. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 71 ++++++++++++++++++++++++++++++++++++----------- drivers/md/raid1.c | 7 ++++- include/linux/raid/md_k.h | 4 +++ 3 files changed, 65 insertions(+), 17 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index b02f8d1d77e7..789b114f860a 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -577,6 +577,8 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) mdp_disk_t *desc; mdp_super_t *sb = (mdp_super_t *)page_address(rdev->sb_page); + rdev->raid_disk = -1; + rdev->in_sync = 0; if (mddev->raid_disks == 0) { mddev->major_version = 0; mddev->minor_version = sb->minor_version; @@ -607,16 +609,24 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) memcpy(mddev->uuid+12,&sb->set_uuid3, 4); mddev->max_disks = MD_SB_DISKS; - } else { - __u64 ev1; - ev1 = md_event(sb); + } else if (mddev->pers == NULL) { + /* Insist on good event counter while assembling */ + __u64 ev1 = md_event(sb); ++ev1; if (ev1 < mddev->events) return -EINVAL; - } + } else if (mddev->bitmap) { + /* if adding to array with a bitmap, then we can accept an + * older device ... but not too old. + */ + __u64 ev1 = md_event(sb); + if (ev1 < mddev->bitmap->events_cleared) + return 0; + } else /* just a hot-add of a new device, leave raid_disk at -1 */ + return 0; + if (mddev->level != LEVEL_MULTIPATH) { - rdev->raid_disk = -1; - rdev->in_sync = rdev->faulty = 0; + rdev->faulty = 0; desc = sb->disks + rdev->desc_nr; if (desc->state & (1<in_sync = 1; rdev->raid_disk = desc->raid_disk; } - } + } else /* MULTIPATH are always insync */ + rdev->in_sync = 1; return 0; } @@ -868,6 +879,8 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) { struct mdp_superblock_1 *sb = (struct mdp_superblock_1*)page_address(rdev->sb_page); + rdev->raid_disk = -1; + rdev->in_sync = 0; if (mddev->raid_disks == 0) { mddev->major_version = 1; mddev->patch_version = 0; @@ -885,13 +898,21 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) memcpy(mddev->uuid, sb->set_uuid, 16); mddev->max_disks = (4096-256)/2; - } else { - __u64 ev1; - ev1 = le64_to_cpu(sb->events); + } else if (mddev->pers == NULL) { + /* Insist of good event counter while assembling */ + __u64 ev1 = le64_to_cpu(sb->events); ++ev1; if (ev1 < mddev->events) return -EINVAL; - } + } else if (mddev->bitmap) { + /* If adding to array with a bitmap, then we can accept an + * older device, but not too old. + */ + __u64 ev1 = le64_to_cpu(sb->events); + if (ev1 < mddev->bitmap->events_cleared) + return 0; + } else /* just a hot-add of a new device, leave raid_disk at -1 */ + return 0; if (mddev->level != LEVEL_MULTIPATH) { int role; @@ -899,14 +920,10 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]); switch(role) { case 0xffff: /* spare */ - rdev->in_sync = 0; rdev->faulty = 0; - rdev->raid_disk = -1; break; case 0xfffe: /* faulty */ - rdev->in_sync = 0; rdev->faulty = 1; - rdev->raid_disk = -1; break; default: rdev->in_sync = 1; @@ -914,7 +931,9 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) rdev->raid_disk = role; break; } - } + } else /* MULTIPATH are always insync */ + rdev->in_sync = 1; + return 0; } @@ -2155,6 +2174,18 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) PTR_ERR(rdev)); return PTR_ERR(rdev); } + /* set save_raid_disk if appropriate */ + if (!mddev->persistent) { + if (info->state & (1<raid_disk < mddev->raid_disks) + rdev->raid_disk = info->raid_disk; + else + rdev->raid_disk = -1; + } else + super_types[mddev->major_version]. + validate_super(mddev, rdev); + rdev->saved_raid_disk = rdev->raid_disk; + rdev->in_sync = 0; /* just to be sure */ rdev->raid_disk = -1; err = bind_rdev_to_array(rdev, mddev); @@ -3706,6 +3737,14 @@ void md_check_recovery(mddev_t *mddev) mddev->pers->spare_active(mddev); } md_update_sb(mddev); + + /* if array is no-longer degraded, then any saved_raid_disk + * information must be scrapped + */ + if (!mddev->degraded) + ITERATE_RDEV(mddev,rdev,rtmp) + rdev->saved_raid_disk = -1; + mddev->recovery = 0; /* flag recovery needed just to double check */ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index c3b4772cfaea..3f5234fe3593 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -811,9 +811,12 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) { conf_t *conf = mddev->private; int found = 0; - int mirror; + int mirror = 0; mirror_info_t *p; + if (rdev->saved_raid_disk >= 0 && + conf->mirrors[rdev->saved_raid_disk].rdev == NULL) + mirror = rdev->saved_raid_disk; for (mirror=0; mirror < mddev->raid_disks; mirror++) if ( !(p=conf->mirrors+mirror)->rdev) { @@ -830,6 +833,8 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) p->head_position = 0; rdev->raid_disk = mirror; found = 1; + if (rdev->saved_raid_disk != mirror) + conf->fullsync = 1; p->rdev = rdev; break; } diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index 16e94a9f0f8c..6cdcb4434c6c 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h @@ -183,6 +183,10 @@ struct mdk_rdev_s int desc_nr; /* descriptor index in the superblock */ int raid_disk; /* role of device in array */ + int saved_raid_disk; /* role that device used to have in the + * array and could again if we did a partial + * resync from the bitmap + */ atomic_t nr_pending; /* number of pending requests. * only maintained for arrays that -- cgit v1.2.3-59-g8ed1b From 3d310eb7b3df1252e8595d059d982b0a9825a137 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:26 -0700 Subject: [PATCH] md: fix deadlock due to md thread processing delayed requests. Before completing a 'write' the md superblock might need to be updated. This is best done by the md_thread. The current code schedules this up and queues the write request for later handling by the md_thread. However some personalities (Raid5/raid6) will deadlock if the md_thread tries to submit requests to its own array. So this patch changes things so the processes submitting the request waits for the superblock to be written and then submits the request itself. This fixes a recently-created deadlock in raid5/raid6 Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 45 ++++++++++++++++----------------------------- drivers/md/raid1.c | 4 ++-- drivers/md/raid10.c | 3 +-- drivers/md/raid5.c | 3 +-- drivers/md/raid6main.c | 3 +-- include/linux/raid/md.h | 2 +- include/linux/raid/md_k.h | 2 +- 7 files changed, 23 insertions(+), 39 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 789b114f860a..7075bebb7f37 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -224,8 +224,8 @@ static mddev_t * mddev_find(dev_t unit) INIT_LIST_HEAD(&new->all_mddevs); init_timer(&new->safemode_timer); atomic_set(&new->active, 1); - bio_list_init(&new->write_list); spin_lock_init(&new->write_lock); + init_waitqueue_head(&new->sb_wait); new->queue = blk_alloc_queue(GFP_KERNEL); if (!new->queue) { @@ -1307,6 +1307,7 @@ repeat: if (!mddev->persistent) { mddev->sb_dirty = 0; spin_unlock(&mddev->write_lock); + wake_up(&mddev->sb_wait); return; } spin_unlock(&mddev->write_lock); @@ -1348,6 +1349,7 @@ repeat: } mddev->sb_dirty = 0; spin_unlock(&mddev->write_lock); + wake_up(&mddev->sb_wait); } @@ -3368,29 +3370,26 @@ void md_done_sync(mddev_t *mddev, int blocks, int ok) /* md_write_start(mddev, bi) * If we need to update some array metadata (e.g. 'active' flag - * in superblock) before writing, queue bi for later writing - * and return 0, else return 1 and it will be written now + * in superblock) before writing, schedule a superblock update + * and wait for it to complete. */ -int md_write_start(mddev_t *mddev, struct bio *bi) +void md_write_start(mddev_t *mddev, struct bio *bi) { + DEFINE_WAIT(w); if (bio_data_dir(bi) != WRITE) - return 1; + return; atomic_inc(&mddev->writes_pending); - spin_lock(&mddev->write_lock); - if (mddev->in_sync == 0 && mddev->sb_dirty == 0) { - spin_unlock(&mddev->write_lock); - return 1; - } - bio_list_add(&mddev->write_list, bi); - if (mddev->in_sync) { - mddev->in_sync = 0; - mddev->sb_dirty = 1; + spin_lock(&mddev->write_lock); + if (mddev->in_sync) { + mddev->in_sync = 0; + mddev->sb_dirty = 1; + md_wakeup_thread(mddev->thread); + } + spin_unlock(&mddev->write_lock); } - spin_unlock(&mddev->write_lock); - md_wakeup_thread(mddev->thread); - return 0; + wait_event(mddev->sb_wait, mddev->sb_dirty==0); } void md_write_end(mddev_t *mddev) @@ -3685,7 +3684,6 @@ void md_check_recovery(mddev_t *mddev) mddev->sb_dirty || test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || test_bit(MD_RECOVERY_DONE, &mddev->recovery) || - mddev->write_list.head || (mddev->safemode == 1) || (mddev->safemode == 2 && ! atomic_read(&mddev->writes_pending) && !mddev->in_sync && mddev->recovery_cp == MaxSector) @@ -3694,7 +3692,6 @@ void md_check_recovery(mddev_t *mddev) if (mddev_trylock(mddev)==0) { int spares =0; - struct bio *blist; spin_lock(&mddev->write_lock); if (mddev->safemode && !atomic_read(&mddev->writes_pending) && @@ -3704,21 +3701,11 @@ void md_check_recovery(mddev_t *mddev) } if (mddev->safemode == 1) mddev->safemode = 0; - blist = bio_list_get(&mddev->write_list); spin_unlock(&mddev->write_lock); if (mddev->sb_dirty) md_update_sb(mddev); - while (blist) { - struct bio *b = blist; - blist = blist->bi_next; - b->bi_next = NULL; - generic_make_request(b); - /* we already counted this, so need to un-count */ - md_write_end(mddev); - } - if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && !test_bit(MD_RECOVERY_DONE, &mddev->recovery)) { diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 3f5234fe3593..98b09773e79e 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -561,8 +561,8 @@ static int make_request(request_queue_t *q, struct bio * bio) * thread has put up a bar for new requests. * Continue immediately if no resync is active currently. */ - if (md_write_start(mddev, bio)==0) - return 0; + md_write_start(mddev, bio); /* wait on superblock update early */ + spin_lock_irq(&conf->resync_lock); wait_event_lock_irq(conf->wait_resume, !conf->barrier, conf->resync_lock, ); conf->nr_pending++; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 8476515bfdc7..fd7324a86d13 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -700,8 +700,7 @@ static int make_request(request_queue_t *q, struct bio * bio) return 0; } - if (md_write_start(mddev, bio) == 0) - return 0; + md_write_start(mddev, bio); /* * Register the new request and wait if the reconstruction diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 1ce3f5aaa984..93a9726cc2d6 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -1411,8 +1411,7 @@ static int make_request (request_queue_t *q, struct bio * bi) sector_t logical_sector, last_sector; struct stripe_head *sh; - if (md_write_start(mddev, bi)==0) - return 0; + md_write_start(mddev, bi); if (bio_data_dir(bi)==WRITE) { disk_stat_inc(mddev->gendisk, writes); diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c index d9c385496dc5..f62ea1a73d0d 100644 --- a/drivers/md/raid6main.c +++ b/drivers/md/raid6main.c @@ -1570,8 +1570,7 @@ static int make_request (request_queue_t *q, struct bio * bi) sector_t logical_sector, last_sector; struct stripe_head *sh; - if (md_write_start(mddev, bi)==0) - return 0; + md_write_start(mddev, bi); if (bio_data_dir(bi)==WRITE) { disk_stat_inc(mddev->gendisk, writes); diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h index cfde8f497d6d..75f41d8faed2 100644 --- a/include/linux/raid/md.h +++ b/include/linux/raid/md.h @@ -69,7 +69,7 @@ extern mdk_thread_t * md_register_thread (void (*run) (mddev_t *mddev), extern void md_unregister_thread (mdk_thread_t *thread); extern void md_wakeup_thread(mdk_thread_t *thread); extern void md_check_recovery(mddev_t *mddev); -extern int md_write_start(mddev_t *mddev, struct bio *bi); +extern void md_write_start(mddev_t *mddev, struct bio *bi); extern void md_write_end(mddev_t *mddev); extern void md_handle_safemode(mddev_t *mddev); extern void md_done_sync(mddev_t *mddev, int blocks, int ok); diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index 6cdcb4434c6c..3e977025cf43 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h @@ -261,7 +261,7 @@ struct mddev_s sector_t recovery_cp; spinlock_t write_lock; - struct bio_list write_list; + wait_queue_head_t sb_wait; /* for waiting on superblock updates */ unsigned int safemode; /* if set, update "clean" superblock * when no writes pending. -- cgit v1.2.3-59-g8ed1b From a654b9d8f851f4ca02649d5825cbe6c608adb10c Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:27 -0700 Subject: [PATCH] md: allow md intent bitmap to be stored near the superblock. This provides an alternate to storing the bitmap in a separate file. The bitmap can be stored at a given offset from the superblock. Obviously the creator of the array must make sure this doesn't intersect with data.... After is good for version-0.90 superblocks. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/bitmap.c | 132 +++++++++++++++++++++++++++++++++++--------- drivers/md/md.c | 40 +++++++++++++- include/linux/raid/bitmap.h | 2 + include/linux/raid/md.h | 15 ++++- include/linux/raid/md_k.h | 4 ++ include/linux/raid/md_p.h | 7 ++- 6 files changed, 170 insertions(+), 30 deletions(-) diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 204564dc6a0d..030d6861051a 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -116,7 +116,7 @@ static unsigned char *bitmap_alloc_page(struct bitmap *bitmap) if (!page) printk("%s: bitmap_alloc_page FAILED\n", bmname(bitmap)); else - printk("%s: bitmap_alloc_page: allocated page at %p\n", + PRINTK("%s: bitmap_alloc_page: allocated page at %p\n", bmname(bitmap), page); return page; } @@ -258,13 +258,61 @@ char *file_path(struct file *file, char *buf, int count) * basic page I/O operations */ +/* IO operations when bitmap is stored near all superblocks */ +static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long index) +{ + /* choose a good rdev and read the page from there */ + + mdk_rdev_t *rdev; + struct list_head *tmp; + struct page *page = alloc_page(GFP_KERNEL); + sector_t target; + + if (!page) + return ERR_PTR(-ENOMEM); + do { + ITERATE_RDEV(mddev, rdev, tmp) + if (rdev->in_sync && !rdev->faulty) + goto found; + return ERR_PTR(-EIO); + + found: + target = (rdev->sb_offset << 1) + offset + index * (PAGE_SIZE/512); + + } while (!sync_page_io(rdev->bdev, target, PAGE_SIZE, page, READ)); + + page->index = index; + return page; +} + +static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wait) +{ + mdk_rdev_t *rdev; + struct list_head *tmp; + + ITERATE_RDEV(mddev, rdev, tmp) + if (rdev->in_sync && !rdev->faulty) + md_super_write(mddev, rdev, + (rdev->sb_offset<<1) + offset + + page->index * (PAGE_SIZE/512), + PAGE_SIZE, + page); + + if (wait) + wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0); + return 0; +} + /* - * write out a page + * write out a page to a file */ static int write_page(struct bitmap *bitmap, struct page *page, int wait) { int ret = -ENOMEM; + if (bitmap->file == NULL) + return write_sb_page(bitmap->mddev, bitmap->offset, page, wait); + lock_page(page); ret = page->mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE); @@ -394,7 +442,12 @@ static int bitmap_read_sb(struct bitmap *bitmap) int err = -EINVAL; /* page 0 is the superblock, read it... */ - bitmap->sb_page = read_page(bitmap->file, 0, &bytes_read); + if (bitmap->file) + bitmap->sb_page = read_page(bitmap->file, 0, &bytes_read); + else { + bitmap->sb_page = read_sb_page(bitmap->mddev, bitmap->offset, 0); + bytes_read = PAGE_SIZE; + } if (IS_ERR(bitmap->sb_page)) { err = PTR_ERR(bitmap->sb_page); bitmap->sb_page = NULL; @@ -625,14 +678,16 @@ static void bitmap_file_kick(struct bitmap *bitmap) bitmap_mask_state(bitmap, BITMAP_STALE, MASK_SET); bitmap_update_sb(bitmap); - path = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (path) - ptr = file_path(bitmap->file, path, PAGE_SIZE); + if (bitmap->file) { + path = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (path) + ptr = file_path(bitmap->file, path, PAGE_SIZE); - printk(KERN_ALERT "%s: kicking failed bitmap file %s from array!\n", - bmname(bitmap), ptr ? ptr : ""); + printk(KERN_ALERT "%s: kicking failed bitmap file %s from array!\n", + bmname(bitmap), ptr ? ptr : ""); - kfree(path); + kfree(path); + } bitmap_file_put(bitmap); @@ -676,7 +731,7 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block) void *kaddr; unsigned long chunk = block >> CHUNK_BLOCK_SHIFT(bitmap); - if (!bitmap->file || !bitmap->filemap) { + if (!bitmap->filemap) { return; } @@ -715,7 +770,7 @@ int bitmap_unplug(struct bitmap *bitmap) * flushed out to disk */ for (i = 0; i < bitmap->file_pages; i++) { spin_lock_irqsave(&bitmap->lock, flags); - if (!bitmap->file || !bitmap->filemap) { + if (!bitmap->filemap) { spin_unlock_irqrestore(&bitmap->lock, flags); return 0; } @@ -732,11 +787,15 @@ int bitmap_unplug(struct bitmap *bitmap) return 1; } if (wait) { /* if any writes were performed, we need to wait on them */ - spin_lock_irq(&bitmap->write_lock); - wait_event_lock_irq(bitmap->write_wait, - list_empty(&bitmap->complete_pages), bitmap->write_lock, - wake_up_process(bitmap->writeback_daemon->tsk)); - spin_unlock_irq(&bitmap->write_lock); + if (bitmap->file) { + spin_lock_irq(&bitmap->write_lock); + wait_event_lock_irq(bitmap->write_wait, + list_empty(&bitmap->complete_pages), bitmap->write_lock, + wake_up_process(bitmap->writeback_daemon->tsk)); + spin_unlock_irq(&bitmap->write_lock); + } else + wait_event(bitmap->mddev->sb_wait, + atomic_read(&bitmap->mddev->pending_writes)==0); } return 0; } @@ -764,7 +823,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, int in_sync) chunks = bitmap->chunks; file = bitmap->file; - BUG_ON(!file); + BUG_ON(!file && !bitmap->offset); #if INJECT_FAULTS_3 outofdate = 1; @@ -779,7 +838,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, int in_sync) num_pages = (bytes + sizeof(bitmap_super_t) + PAGE_SIZE - 1) / PAGE_SIZE; - if (i_size_read(file->f_mapping->host) < bytes + sizeof(bitmap_super_t)) { + if (file && i_size_read(file->f_mapping->host) < bytes + sizeof(bitmap_super_t)) { printk(KERN_INFO "%s: bitmap file too short %lu < %lu\n", bmname(bitmap), (unsigned long) i_size_read(file->f_mapping->host), @@ -816,14 +875,18 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, int in_sync) */ page = bitmap->sb_page; offset = sizeof(bitmap_super_t); - } else { + } else if (file) { page = read_page(file, index, &dummy); - if (IS_ERR(page)) { /* read error */ - ret = PTR_ERR(page); - goto out; - } + offset = 0; + } else { + page = read_sb_page(bitmap->mddev, bitmap->offset, index); offset = 0; } + if (IS_ERR(page)) { /* read error */ + ret = PTR_ERR(page); + goto out; + } + oldindex = index; oldpage = page; kmap(page); @@ -874,6 +937,19 @@ out: return ret; } +void bitmap_write_all(struct bitmap *bitmap) +{ + /* We don't actually write all bitmap blocks here, + * just flag them as needing to be written + */ + + unsigned long chunks = bitmap->chunks; + unsigned long bytes = (chunks+7)/8 + sizeof(bitmap_super_t); + unsigned long num_pages = (bytes + PAGE_SIZE-1) / PAGE_SIZE; + while (num_pages--) + bitmap->filemap_attr[num_pages] |= BITMAP_PAGE_NEEDWRITE; +} + static void bitmap_count_page(struct bitmap *bitmap, sector_t offset, int inc) { @@ -913,7 +989,7 @@ int bitmap_daemon_work(struct bitmap *bitmap) for (j = 0; j < bitmap->chunks; j++) { bitmap_counter_t *bmc; spin_lock_irqsave(&bitmap->lock, flags); - if (!bitmap->file || !bitmap->filemap) { + if (!bitmap->filemap) { /* error or shutdown */ spin_unlock_irqrestore(&bitmap->lock, flags); break; @@ -1072,6 +1148,7 @@ static int bitmap_start_daemon(struct bitmap *bitmap, mdk_thread_t **ptr, spin_lock_irqsave(&bitmap->lock, flags); *ptr = NULL; + if (!bitmap->file) /* no need for daemon if there's no backing file */ goto out_unlock; @@ -1416,9 +1493,11 @@ int bitmap_create(mddev_t *mddev) BUG_ON(sizeof(bitmap_super_t) != 256); - if (!file) /* bitmap disabled, nothing to do */ + if (!file && !mddev->bitmap_offset) /* bitmap disabled, nothing to do */ return 0; + BUG_ON(file && mddev->bitmap_offset); + bitmap = kmalloc(sizeof(*bitmap), GFP_KERNEL); if (!bitmap) return -ENOMEM; @@ -1438,7 +1517,8 @@ int bitmap_create(mddev_t *mddev) return -ENOMEM; bitmap->file = file; - get_file(file); + bitmap->offset = mddev->bitmap_offset; + if (file) get_file(file); /* read superblock from bitmap file (this sets bitmap->chunksize) */ err = bitmap_read_sb(bitmap); if (err) diff --git a/drivers/md/md.c b/drivers/md/md.c index 7075bebb7f37..fde8acfac320 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -337,7 +337,7 @@ static int bi_complete(struct bio *bio, unsigned int bytes_done, int error) return 0; } -static int sync_page_io(struct block_device *bdev, sector_t sector, int size, +int sync_page_io(struct block_device *bdev, sector_t sector, int size, struct page *page, int rw) { struct bio *bio = bio_alloc(GFP_NOIO, 1); @@ -609,6 +609,17 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) memcpy(mddev->uuid+12,&sb->set_uuid3, 4); mddev->max_disks = MD_SB_DISKS; + + if (sb->state & (1<bitmap_file == NULL) { + if (mddev->level != 1) { + /* FIXME use a better test */ + printk(KERN_WARNING "md: bitmaps only support for raid1\n"); + return -EINVAL; + } + mddev->bitmap_offset = (MD_SB_BYTES >> 9); + } + } else if (mddev->pers == NULL) { /* Insist on good event counter while assembling */ __u64 ev1 = md_event(sb); @@ -702,6 +713,9 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) sb->layout = mddev->layout; sb->chunk_size = mddev->chunk_size; + if (mddev->bitmap && mddev->bitmap_file == NULL) + sb->state |= (1<disks[0].state = (1<uuid, sb->set_uuid, 16); mddev->max_disks = (4096-256)/2; + + if ((le32_to_cpu(sb->feature_map) & 1) && + mddev->bitmap_file == NULL ) { + if (mddev->level != 1) { + printk(KERN_WARNING "md: bitmaps only supported for raid1\n"); + return -EINVAL; + } + mddev->bitmap_offset = (__s32)le32_to_cpu(sb->bitmap_offset); + } } else if (mddev->pers == NULL) { /* Insist of good event counter while assembling */ __u64 ev1 = le64_to_cpu(sb->events); @@ -960,6 +983,11 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) else sb->resync_offset = cpu_to_le64(0); + if (mddev->bitmap && mddev->bitmap_file == NULL) { + sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset); + sb->feature_map = cpu_to_le32(1); + } + max_dev = 0; ITERATE_RDEV(mddev,rdev2,tmp) if (rdev2->desc_nr+1 > max_dev) @@ -2406,7 +2434,8 @@ static int set_bitmap_file(mddev_t *mddev, int fd) mdname(mddev)); fput(mddev->bitmap_file); mddev->bitmap_file = NULL; - } + } else + mddev->bitmap_offset = 0; /* file overrides offset */ return err; } @@ -3774,6 +3803,13 @@ void md_check_recovery(mddev_t *mddev) set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); if (!spares) set_bit(MD_RECOVERY_SYNC, &mddev->recovery); + if (spares && mddev->bitmap && ! mddev->bitmap->file) { + /* We are adding a device or devices to an array + * which has the bitmap stored on all devices. + * So make sure all bitmap pages get written + */ + bitmap_write_all(mddev->bitmap); + } mddev->sync_thread = md_register_thread(md_do_sync, mddev, "%s_resync"); diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h index cfe60cfc8f3d..e24b74b11150 100644 --- a/include/linux/raid/bitmap.h +++ b/include/linux/raid/bitmap.h @@ -217,6 +217,7 @@ struct bitmap { /* bitmap spinlock */ spinlock_t lock; + long offset; /* offset from superblock if file is NULL */ struct file *file; /* backing disk file */ struct page *sb_page; /* cached copy of the bitmap file superblock */ struct page **filemap; /* list of cache pages for the file */ @@ -255,6 +256,7 @@ void bitmap_print_sb(struct bitmap *bitmap); int bitmap_update_sb(struct bitmap *bitmap); int bitmap_setallbits(struct bitmap *bitmap); +void bitmap_write_all(struct bitmap *bitmap); /* these are exported */ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors); diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h index 75f41d8faed2..ffa316ce4dc8 100644 --- a/include/linux/raid/md.h +++ b/include/linux/raid/md.h @@ -60,7 +60,14 @@ */ #define MD_MAJOR_VERSION 0 #define MD_MINOR_VERSION 90 -#define MD_PATCHLEVEL_VERSION 1 +/* + * MD_PATCHLEVEL_VERSION indicates kernel functionality. + * >=1 means different superblock formats are selectable using SET_ARRAY_INFO + * and major_version/minor_version accordingly + * >=2 means that Internal bitmaps are supported by setting MD_SB_BITMAP_PRESENT + * in the super status byte + */ +#define MD_PATCHLEVEL_VERSION 2 extern int register_md_personality (int p_num, mdk_personality_t *p); extern int unregister_md_personality (int p_num); @@ -78,6 +85,12 @@ extern void md_unplug_mddev(mddev_t *mddev); extern void md_print_devices (void); +extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, + sector_t sector, int size, struct page *page); +extern int sync_page_io(struct block_device *bdev, sector_t sector, int size, + struct page *page, int rw); + + #define MD_BUG(x...) { printk("md: bug in file %s, line %d\n", __FILE__, __LINE__); md_print_devices(); } #endif diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index 3e977025cf43..a3725b57fb7d 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h @@ -273,6 +273,10 @@ struct mddev_s struct bitmap *bitmap; /* the bitmap for the device */ struct file *bitmap_file; /* the bitmap file */ + long bitmap_offset; /* offset from superblock of + * start of bitmap. May be + * negative, but not '0' + */ struct list_head all_mddevs; }; diff --git a/include/linux/raid/md_p.h b/include/linux/raid/md_p.h index 8ba95d67329f..8e592a25a8b5 100644 --- a/include/linux/raid/md_p.h +++ b/include/linux/raid/md_p.h @@ -96,6 +96,7 @@ typedef struct mdp_device_descriptor_s { #define MD_SB_CLEAN 0 #define MD_SB_ERRORS 1 +#define MD_SB_BITMAP_PRESENT 8 /* bitmap may be present nearby */ typedef struct mdp_superblock_s { /* * Constant generic information @@ -184,7 +185,7 @@ struct mdp_superblock_1 { /* constant array information - 128 bytes */ __u32 magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian */ __u32 major_version; /* 1 */ - __u32 feature_map; /* 0 for now */ + __u32 feature_map; /* bit 0 set if 'bitmap_offset' is meaningful */ __u32 pad0; /* always set to 0 when writing */ __u8 set_uuid[16]; /* user-space generated. */ @@ -197,6 +198,10 @@ struct mdp_superblock_1 { __u32 chunksize; /* in 512byte sectors */ __u32 raid_disks; + __u32 bitmap_offset; /* sectors after start of superblock that bitmap starts + * NOTE: signed, so bitmap can be before superblock + * only meaningful of feature_map[0] is set. + */ __u8 pad1[128-96]; /* set to 0 when written */ /* constant this-device information - 64 bytes */ -- cgit v1.2.3-59-g8ed1b From 7bfa19f2748000d646dbdf8f48258cfe1d257b52 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:28 -0700 Subject: [PATCH] md: allow md to update multiple superblocks in parallel. currently, md updates all superblocks (one on each device) in series. It waits for one write to complete before starting the next. This isn't a big problem as superblock updates don't happen that often. However it is neater to do it in parallel, and if the drives in the array have gone to "sleep" after a period of idleness, then waking them is parallel is faster (and someone else should be worrying about power drain). Futher, we will need parallel superblock updates for a future patch which keeps the intent-logging bitmap near the superblock. Also remove the silly code that retired superblock updates 100 times. This simply never made sense. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 85 ++++++++++++++++++++++++++--------------------- include/linux/raid/md_k.h | 1 + 2 files changed, 49 insertions(+), 37 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index fde8acfac320..ef3ad99562c1 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -328,6 +328,40 @@ static void free_disk_sb(mdk_rdev_t * rdev) } +static int super_written(struct bio *bio, unsigned int bytes_done, int error) +{ + mdk_rdev_t *rdev = bio->bi_private; + if (bio->bi_size) + return 1; + + if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags)) + md_error(rdev->mddev, rdev); + + if (atomic_dec_and_test(&rdev->mddev->pending_writes)) + wake_up(&rdev->mddev->sb_wait); + return 0; +} + +void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, + sector_t sector, int size, struct page *page) +{ + /* write first size bytes of page to sector of rdev + * Increment mddev->pending_writes before returning + * and decrement it on completion, waking up sb_wait + * if zero is reached. + * If an error occurred, call md_error + */ + struct bio *bio = bio_alloc(GFP_NOIO, 1); + + bio->bi_bdev = rdev->bdev; + bio->bi_sector = sector; + bio_add_page(bio, page, size, 0); + bio->bi_private = rdev; + bio->bi_end_io = super_written; + atomic_inc(&mddev->pending_writes); + submit_bio((1<bi_size) @@ -1268,30 +1302,6 @@ void md_print_devices(void) } -static int write_disk_sb(mdk_rdev_t * rdev) -{ - char b[BDEVNAME_SIZE]; - if (!rdev->sb_loaded) { - MD_BUG(); - return 1; - } - if (rdev->faulty) { - MD_BUG(); - return 1; - } - - dprintk(KERN_INFO "(write) %s's sb offset: %llu\n", - bdevname(rdev->bdev,b), - (unsigned long long)rdev->sb_offset); - - if (sync_page_io(rdev->bdev, rdev->sb_offset<<1, MD_SB_BYTES, rdev->sb_page, WRITE)) - return 0; - - printk("md: write_disk_sb failed for device %s\n", - bdevname(rdev->bdev,b)); - return 1; -} - static void sync_sbs(mddev_t * mddev) { mdk_rdev_t *rdev; @@ -1306,7 +1316,7 @@ static void sync_sbs(mddev_t * mddev) static void md_update_sb(mddev_t * mddev) { - int err, count = 100; + int err; struct list_head *tmp; mdk_rdev_t *rdev; int sync_req; @@ -1326,6 +1336,7 @@ repeat: MD_BUG(); mddev->events --; } + mddev->sb_dirty = 2; sync_sbs(mddev); /* @@ -1353,24 +1364,24 @@ repeat: dprintk("%s ", bdevname(rdev->bdev,b)); if (!rdev->faulty) { - err += write_disk_sb(rdev); + md_super_write(mddev,rdev, + rdev->sb_offset<<1, MD_SB_BYTES, + rdev->sb_page); + dprintk(KERN_INFO "(write) %s's sb offset: %llu\n", + bdevname(rdev->bdev,b), + (unsigned long long)rdev->sb_offset); + } else dprintk(")\n"); - if (!err && mddev->level == LEVEL_MULTIPATH) + if (mddev->level == LEVEL_MULTIPATH) /* only need to write one superblock... */ break; } - if (err) { - if (--count) { - printk(KERN_ERR "md: errors occurred during superblock" - " update, repeating\n"); - goto repeat; - } - printk(KERN_ERR \ - "md: excessive errors occurred during superblock update, exiting\n"); - } + wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0); + /* if there was a failure, sb_dirty was set to 1, and we re-write super */ + spin_lock(&mddev->write_lock); - if (mddev->in_sync != sync_req) { + if (mddev->in_sync != sync_req|| mddev->sb_dirty == 1) { /* have to write it out again */ spin_unlock(&mddev->write_lock); goto repeat; diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index a3725b57fb7d..8c14ba565a45 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h @@ -262,6 +262,7 @@ struct mddev_s spinlock_t write_lock; wait_queue_head_t sb_wait; /* for waiting on superblock updates */ + atomic_t pending_writes; /* number of active superblock writes */ unsigned int safemode; /* if set, update "clean" superblock * when no writes pending. -- cgit v1.2.3-59-g8ed1b From 39730960d94306d7be414e8d54f4e5c071af1278 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:28 -0700 Subject: [PATCH] Two small fixes for md verion-1 superblocks. 1/ Must typecast int to (sector_t) before inverting or we might not invert enough bits. 2/ When "bitmap_offset" was added to mdp_superblock_1, we didn't increase the count of words-used (96 to 100). Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 2 +- include/linux/raid/md_p.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index ef3ad99562c1..65fab74ad737 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -847,7 +847,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) case 0: sb_offset = rdev->bdev->bd_inode->i_size >> 9; sb_offset -= 8*2; - sb_offset &= ~(4*2-1); + sb_offset &= ~(sector_t)(4*2-1); /* convert from sectors to K */ sb_offset /= 2; break; diff --git a/include/linux/raid/md_p.h b/include/linux/raid/md_p.h index 8e592a25a8b5..dc65cd435494 100644 --- a/include/linux/raid/md_p.h +++ b/include/linux/raid/md_p.h @@ -202,7 +202,7 @@ struct mdp_superblock_1 { * NOTE: signed, so bitmap can be before superblock * only meaningful of feature_map[0] is set. */ - __u8 pad1[128-96]; /* set to 0 when written */ + __u8 pad1[128-100]; /* set to 0 when written */ /* constant this-device information - 64 bytes */ __u64 data_offset; /* sector start of data, often 0 */ -- cgit v1.2.3-59-g8ed1b From 8a5e9cf1d6626586ff08e49f400a006a9f0c3275 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Jun 2005 17:17:29 -0700 Subject: [PATCH] md: make sure md/bitmap doesn't try to write a page with active writeback Due to the use of write-behind, it is possible for md to write a page to the bitmap file that is still completing writeback. This is not allowed. With this patch, we detect those cases and either force a sync write, or back off and try later, as appropriate. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/bitmap.c | 68 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 030d6861051a..95980ad6b27b 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -313,7 +313,16 @@ static int write_page(struct bitmap *bitmap, struct page *page, int wait) if (bitmap->file == NULL) return write_sb_page(bitmap->mddev, bitmap->offset, page, wait); - lock_page(page); + if (wait) + lock_page(page); + else { + if (TestSetPageLocked(page)) + return -EAGAIN; /* already locked */ + if (PageWriteback(page)) { + unlock_page(page); + return -EAGAIN; + } + } ret = page->mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE); if (!ret) @@ -400,7 +409,7 @@ int bitmap_update_sb(struct bitmap *bitmap) if (!bitmap->mddev->degraded) sb->events_cleared = cpu_to_le64(bitmap->mddev->events); kunmap(bitmap->sb_page); - return write_page(bitmap, bitmap->sb_page, 0); + return write_page(bitmap, bitmap->sb_page, 1); } /* print out the bitmap file superblock */ @@ -762,6 +771,7 @@ int bitmap_unplug(struct bitmap *bitmap) unsigned long i, attr, flags; struct page *page; int wait = 0; + int err; if (!bitmap) return 0; @@ -782,9 +792,17 @@ int bitmap_unplug(struct bitmap *bitmap) wait = 1; spin_unlock_irqrestore(&bitmap->lock, flags); - if (attr & (BITMAP_PAGE_DIRTY | BITMAP_PAGE_NEEDWRITE)) - if (write_page(bitmap, page, 0)) + if (attr & (BITMAP_PAGE_DIRTY | BITMAP_PAGE_NEEDWRITE)) { + err = write_page(bitmap, page, 0); + if (err == -EAGAIN) { + if (attr & BITMAP_PAGE_DIRTY) + err = write_page(bitmap, page, 1); + else + err = 0; + } + if (err) return 1; + } } if (wait) { /* if any writes were performed, we need to wait on them */ if (bitmap->file) { @@ -1006,8 +1024,15 @@ int bitmap_daemon_work(struct bitmap *bitmap) } spin_unlock_irqrestore(&bitmap->lock, flags); if (attr & BITMAP_PAGE_NEEDWRITE) { - if (write_page(bitmap, page, 0)) + switch (write_page(bitmap, page, 0)) { + case -EAGAIN: + set_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE); + break; + case 0: + break; + default: bitmap_file_kick(bitmap); + } page_cache_release(page); } continue; @@ -1020,6 +1045,10 @@ int bitmap_daemon_work(struct bitmap *bitmap) clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); spin_unlock_irqrestore(&bitmap->lock, flags); err = write_page(bitmap, lastpage, 0); + if (err == -EAGAIN) { + err = 0; + set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); + } } else { set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); spin_unlock_irqrestore(&bitmap->lock, flags); @@ -1068,6 +1097,10 @@ int bitmap_daemon_work(struct bitmap *bitmap) clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); spin_unlock_irqrestore(&bitmap->lock, flags); err = write_page(bitmap, lastpage, 0); + if (err == -EAGAIN) { + set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); + err = 0; + } } else { set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE); spin_unlock_irqrestore(&bitmap->lock, flags); @@ -1421,31 +1454,6 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, } } -/* dirty the entire bitmap */ -int bitmap_setallbits(struct bitmap *bitmap) -{ - unsigned long flags; - unsigned long j; - - /* dirty the in-memory bitmap */ - bitmap_set_memory_bits(bitmap, 0, bitmap->chunks << CHUNK_BLOCK_SHIFT(bitmap), 1); - - /* dirty the bitmap file */ - for (j = 0; j < bitmap->file_pages; j++) { - struct page *page = bitmap->filemap[j]; - - spin_lock_irqsave(&bitmap->lock, flags); - page_cache_get(page); - spin_unlock_irqrestore(&bitmap->lock, flags); - memset(kmap(page), 0xff, PAGE_SIZE); - kunmap(page); - if (write_page(bitmap, page, 0)) - return 1; - } - - return 0; -} - /* * free memory that was allocated */ -- cgit v1.2.3-59-g8ed1b From 990a8baf568ca1d0ae65e59783ff821794118d07 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Tue, 21 Jun 2005 17:17:30 -0700 Subject: [PATCH] md: remove unneeded NULL checks before kfree This patch removes some unneeded checks of pointers being NULL before calling kfree() on them. kfree() handles NULL pointers just fine, checking first is pointless. Signed-off-by: Jesper Juhl Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/dm-crypt.c | 3 +-- drivers/md/linear.c | 3 +-- drivers/md/md.c | 10 +++------- drivers/md/multipath.c | 3 +-- drivers/md/raid0.c | 12 +++++------- drivers/md/raid1.c | 12 ++++-------- drivers/md/raid10.c | 6 ++---- 7 files changed, 17 insertions(+), 32 deletions(-) diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 0dd6c2b5391b..d0a4bab220e5 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -704,8 +704,7 @@ static void crypt_dtr(struct dm_target *ti) mempool_destroy(cc->page_pool); mempool_destroy(cc->io_pool); - if (cc->iv_mode) - kfree(cc->iv_mode); + kfree(cc->iv_mode); if (cc->iv_gen_ops && cc->iv_gen_ops->dtr) cc->iv_gen_ops->dtr(cc); crypto_free_tfm(cc->tfm); diff --git a/drivers/md/linear.c b/drivers/md/linear.c index b1941b887f46..8d740013d74d 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -217,8 +217,7 @@ static int linear_run (mddev_t *mddev) return 0; out: - if (conf) - kfree(conf); + kfree(conf); return 1; } diff --git a/drivers/md/md.c b/drivers/md/md.c index 65fab74ad737..0c6b5b6baff6 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -195,8 +195,7 @@ static mddev_t * mddev_find(dev_t unit) if (mddev->unit == unit) { mddev_get(mddev); spin_unlock(&all_mddevs_lock); - if (new) - kfree(new); + kfree(new); return mddev; } @@ -458,11 +457,8 @@ static int sb_equal(mdp_super_t *sb1, mdp_super_t *sb2) ret = 1; abort: - if (tmp1) - kfree(tmp1); - if (tmp2) - kfree(tmp2); - + kfree(tmp1); + kfree(tmp2); return ret; } diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 2ae2d709cb15..2d2ca7fa0265 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -533,8 +533,7 @@ static int multipath_run (mddev_t *mddev) out_free_conf: if (conf->pool) mempool_destroy(conf->pool); - if (conf->multipaths) - kfree(conf->multipaths); + kfree(conf->multipaths); kfree(conf); mddev->private = NULL; out: diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index e7d934eca06f..e11dd14d0b43 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -371,10 +371,8 @@ static int raid0_run (mddev_t *mddev) return 0; out_free_conf: - if (conf->strip_zone) - kfree(conf->strip_zone); - if (conf->devlist) - kfree (conf->devlist); + kfree(conf->strip_zone); + kfree(conf->devlist); kfree(conf); mddev->private = NULL; out: @@ -386,11 +384,11 @@ static int raid0_stop (mddev_t *mddev) raid0_conf_t *conf = mddev_to_conf(mddev); blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ - kfree (conf->hash_table); + kfree(conf->hash_table); conf->hash_table = NULL; - kfree (conf->strip_zone); + kfree(conf->strip_zone); conf->strip_zone = NULL; - kfree (conf); + kfree(conf); mddev->private = NULL; return 0; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 98b09773e79e..ff1dbec864af 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1427,10 +1427,8 @@ out_free_conf: if (conf) { if (conf->r1bio_pool) mempool_destroy(conf->r1bio_pool); - if (conf->mirrors) - kfree(conf->mirrors); - if (conf->poolinfo) - kfree(conf->poolinfo); + kfree(conf->mirrors); + kfree(conf->poolinfo); kfree(conf); mddev->private = NULL; } @@ -1447,10 +1445,8 @@ static int stop(mddev_t *mddev) blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ if (conf->r1bio_pool) mempool_destroy(conf->r1bio_pool); - if (conf->mirrors) - kfree(conf->mirrors); - if (conf->poolinfo) - kfree(conf->poolinfo); + kfree(conf->mirrors); + kfree(conf->poolinfo); kfree(conf); mddev->private = NULL; return 0; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index fd7324a86d13..62ebb1bc72be 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1737,8 +1737,7 @@ static int run(mddev_t *mddev) out_free_conf: if (conf->r10bio_pool) mempool_destroy(conf->r10bio_pool); - if (conf->mirrors) - kfree(conf->mirrors); + kfree(conf->mirrors); kfree(conf); mddev->private = NULL; out: @@ -1754,8 +1753,7 @@ static int stop(mddev_t *mddev) blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ if (conf->r10bio_pool) mempool_destroy(conf->r10bio_pool); - if (conf->mirrors) - kfree(conf->mirrors); + kfree(conf->mirrors); kfree(conf); mddev->private = NULL; return 0; -- cgit v1.2.3-59-g8ed1b